1
16
17 package validatingadmissionpolicybinding
18
19 import (
20 "context"
21 "testing"
22
23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24 "k8s.io/apimachinery/pkg/runtime/schema"
25 "k8s.io/apiserver/pkg/authentication/user"
26 "k8s.io/apiserver/pkg/authorization/authorizer"
27 "k8s.io/apiserver/pkg/endpoints/request"
28 "k8s.io/kubernetes/pkg/apis/admissionregistration"
29 "k8s.io/kubernetes/pkg/registry/admissionregistration/resolver"
30 )
31
32 func TestAuthorization(t *testing.T) {
33 for _, tc := range []struct {
34 name string
35 userInfo user.Info
36 auth AuthFunc
37 policyGetter PolicyGetterFunc
38 resourceResolver resolver.ResourceResolverFunc
39 expectErr bool
40 }{
41 {
42 name: "superuser",
43 userInfo: &user.DefaultInfo{Groups: []string{user.SystemPrivilegedGroup}},
44 expectErr: false,
45 auth: func(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
46 return authorizer.DecisionDeny, "", nil
47 },
48 },
49 {
50 name: "authorized",
51 userInfo: &user.DefaultInfo{Groups: []string{user.AllAuthenticated}},
52 auth: func(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
53 if a.GetResource() == "configmaps" {
54 return authorizer.DecisionAllow, "", nil
55 }
56 return authorizer.DecisionDeny, "", nil
57 },
58 policyGetter: func(ctx context.Context, name string) (*admissionregistration.ValidatingAdmissionPolicy, error) {
59 return &admissionregistration.ValidatingAdmissionPolicy{
60 ObjectMeta: metav1.ObjectMeta{Name: "replicalimit-policy.example.com"},
61 Spec: admissionregistration.ValidatingAdmissionPolicySpec{
62 ParamKind: &admissionregistration.ParamKind{Kind: "ConfigMap", APIVersion: "v1"},
63 },
64 }, nil
65 },
66 resourceResolver: func(gvk schema.GroupVersionKind) (schema.GroupVersionResource, error) {
67 return schema.GroupVersionResource{
68 Group: "",
69 Version: "v1",
70 Resource: "configmaps",
71 }, nil
72 },
73 expectErr: false,
74 },
75 {
76 name: "denied",
77 userInfo: &user.DefaultInfo{Groups: []string{user.AllAuthenticated}},
78 auth: func(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
79 if a.GetResource() == "configmaps" {
80 return authorizer.DecisionAllow, "", nil
81 }
82 return authorizer.DecisionDeny, "", nil
83 },
84 policyGetter: func(ctx context.Context, name string) (*admissionregistration.ValidatingAdmissionPolicy, error) {
85 return &admissionregistration.ValidatingAdmissionPolicy{
86 ObjectMeta: metav1.ObjectMeta{Name: "replicalimit-policy.example.com"},
87 Spec: admissionregistration.ValidatingAdmissionPolicySpec{
88 ParamKind: &admissionregistration.ParamKind{Kind: "Params", APIVersion: "foo.example.com/v1"},
89 },
90 }, nil
91 },
92 resourceResolver: func(gvk schema.GroupVersionKind) (schema.GroupVersionResource, error) {
93 return schema.GroupVersionResource{
94 Group: "foo.example.com",
95 Version: "v1",
96 Resource: "params",
97 }, nil
98 },
99 expectErr: true,
100 },
101 } {
102 t.Run(tc.name, func(t *testing.T) {
103 strategy := NewStrategy(tc.auth, tc.policyGetter, tc.resourceResolver)
104 t.Run("create", func(t *testing.T) {
105 ctx := request.WithUser(context.Background(), tc.userInfo)
106 for _, obj := range validPolicyBindings() {
107 errs := strategy.Validate(ctx, obj)
108 if len(errs) > 0 != tc.expectErr {
109 t.Errorf("expected error: %v but got error: %v", tc.expectErr, errs)
110 }
111 }
112 })
113 t.Run("update", func(t *testing.T) {
114 ctx := request.WithUser(context.Background(), tc.userInfo)
115 for _, obj := range validPolicyBindings() {
116 objWithChangedParamRef := obj.DeepCopy()
117 if pr := objWithChangedParamRef.Spec.ParamRef; pr != nil {
118 if len(pr.Name) > 0 {
119 pr.Name = "changed"
120 }
121
122 if pr.Selector != nil {
123 pr.Selector = &metav1.LabelSelector{
124 MatchLabels: map[string]string{
125 "changed": "value",
126 },
127 }
128 }
129
130 if len(pr.Namespace) > 0 {
131 pr.Namespace = "othernamespace"
132 }
133
134 if pr.ParameterNotFoundAction == nil || *pr.ParameterNotFoundAction == admissionregistration.AllowAction {
135 v := admissionregistration.DenyAction
136 pr.ParameterNotFoundAction = &v
137 } else {
138 v := admissionregistration.AllowAction
139 pr.ParameterNotFoundAction = &v
140 }
141 }
142 errs := strategy.ValidateUpdate(ctx, obj, objWithChangedParamRef)
143 if len(errs) > 0 != tc.expectErr {
144 t.Errorf("expected error: %v but got error: %v", tc.expectErr, errs)
145 }
146 }
147 })
148 })
149 }
150 }
151
152 type AuthFunc func(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error)
153
154 func (f AuthFunc) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
155 return f(ctx, a)
156 }
157
158 type PolicyGetterFunc func(ctx context.Context, name string) (*admissionregistration.ValidatingAdmissionPolicy, error)
159
160 func (f PolicyGetterFunc) GetValidatingAdmissionPolicy(ctx context.Context, name string) (*admissionregistration.ValidatingAdmissionPolicy, error) {
161 return f(ctx, name)
162 }
163
View as plain text