-
Notifications
You must be signed in to change notification settings - Fork 809
/
context.go
119 lines (100 loc) · 3.38 KB
/
context.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package common
import (
"encoding/json"
"fmt"
"reflect"
"github.com/go-logr/logr"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
urkyverno "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/config"
dclient "github.com/kyverno/kyverno/pkg/dclient"
"github.com/kyverno/kyverno/pkg/engine"
"github.com/kyverno/kyverno/pkg/engine/context"
utils "github.com/kyverno/kyverno/pkg/utils"
"github.com/pkg/errors"
admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func NewBackgroundContext(dclient dclient.Interface, ur *urkyverno.UpdateRequest,
policy kyverno.PolicyInterface, trigger *unstructured.Unstructured,
cfg config.Configuration, namespaceLabels map[string]string, logger logr.Logger) (*engine.PolicyContext, bool, error) {
ctx := context.NewContext()
requestString := ur.Spec.Context.AdmissionRequestInfo.AdmissionRequest
var request admissionv1.AdmissionRequest
var new, old unstructured.Unstructured
if requestString != "" {
err := json.Unmarshal([]byte(requestString), &request)
if err != nil {
return nil, false, errors.Wrap(err, "error parsing the request string")
}
if err := ctx.AddRequest(&request); err != nil {
return nil, false, errors.Wrap(err, "failed to load request in context")
}
new, old, err = utils.ExtractResources(nil, &request)
if err != nil {
return nil, false, errors.Wrap(err, "failed to load request in context")
}
if !reflect.DeepEqual(new, unstructured.Unstructured{}) {
if !check(&new, trigger) {
err := fmt.Errorf("resources don't match")
return nil, false, errors.Wrapf(err, "resource %v", ur.Spec.Resource)
}
}
}
if trigger == nil {
trigger = &old
}
if trigger == nil {
return nil, false, errors.New("trigger resource does not exist")
}
err := ctx.AddResource(trigger.Object)
if err != nil {
return nil, false, errors.Wrap(err, "failed to load resource in context")
}
err = ctx.AddOldResource(old.Object)
if err != nil {
return nil, false, errors.Wrap(err, "failed to load resource in context")
}
err = ctx.AddUserInfo(ur.Spec.Context.UserRequestInfo)
if err != nil {
return nil, false, errors.Wrapf(err, "failed to load SA in context")
}
err = ctx.AddServiceAccount(ur.Spec.Context.UserRequestInfo.AdmissionUserInfo.Username)
if err != nil {
return nil, false, errors.Wrapf(err, "failed to load UserInfo in context")
}
if err := ctx.AddImageInfos(trigger); err != nil {
logger.Error(err, "unable to add image info to variables context")
}
policyContext := &engine.PolicyContext{
NewResource: *trigger,
OldResource: old,
Policy: policy,
AdmissionInfo: ur.Spec.Context.UserRequestInfo,
ExcludeGroupRole: cfg.GetExcludeGroupRole(),
ExcludeResourceFunc: cfg.ToFilter,
JSONContext: ctx,
NamespaceLabels: namespaceLabels,
Client: dclient,
AdmissionOperation: false,
}
return policyContext, false, nil
}
func check(admissionRsc, existingRsc *unstructured.Unstructured) bool {
if existingRsc == nil {
return admissionRsc == nil
}
if admissionRsc.GetName() != existingRsc.GetName() {
return false
}
if admissionRsc.GetNamespace() != existingRsc.GetNamespace() {
return false
}
if admissionRsc.GetKind() != existingRsc.GetKind() {
return false
}
if admissionRsc.GetAPIVersion() != existingRsc.GetAPIVersion() {
return false
}
return true
}