...

Source file src/k8s.io/kubernetes/pkg/registry/admissionregistration/validatingadmissionpolicybinding/authz_test.go

Documentation: k8s.io/kubernetes/pkg/registry/admissionregistration/validatingadmissionpolicybinding

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    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, // success despite always-denying authorizer
    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