k8s.io/kubernetes@v1.29.3/pkg/registry/admissionregistration/validatingadmissionpolicy/storage/storage_test.go (about)

     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 storage
    18  
    19  import (
    20  	"testing"
    21  
    22  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    23  	"k8s.io/apimachinery/pkg/fields"
    24  	"k8s.io/apimachinery/pkg/labels"
    25  	"k8s.io/apimachinery/pkg/runtime"
    26  	"k8s.io/apiserver/pkg/authorization/authorizer"
    27  	"k8s.io/apiserver/pkg/registry/generic"
    28  	genericregistrytest "k8s.io/apiserver/pkg/registry/generic/testing"
    29  	etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing"
    30  	"k8s.io/kubernetes/pkg/apis/admissionregistration"
    31  	"k8s.io/kubernetes/pkg/registry/admissionregistration/resolver"
    32  	"k8s.io/kubernetes/pkg/registry/registrytest"
    33  
    34  	// Ensure that admissionregistration package is initialized.
    35  	_ "k8s.io/kubernetes/pkg/apis/admissionregistration/install"
    36  )
    37  
    38  func TestCreate(t *testing.T) {
    39  	storage, server := newInsecureStorage(t)
    40  	defer server.Terminate(t)
    41  	defer storage.Store.DestroyFunc()
    42  	test := genericregistrytest.New(t, storage.Store).ClusterScope()
    43  	configuration := validValidatingAdmissionPolicy()
    44  	test.TestCreate(
    45  		// valid
    46  		configuration,
    47  		// invalid
    48  		newValidatingAdmissionPolicy(""),
    49  	)
    50  }
    51  
    52  func TestUpdate(t *testing.T) {
    53  	storage, server := newInsecureStorage(t)
    54  	defer server.Terminate(t)
    55  	defer storage.Store.DestroyFunc()
    56  	test := genericregistrytest.New(t, storage.Store).ClusterScope()
    57  
    58  	test.TestUpdate(
    59  		// valid
    60  		validValidatingAdmissionPolicy(),
    61  		// updateFunc
    62  		func(obj runtime.Object) runtime.Object {
    63  			object := obj.(*admissionregistration.ValidatingAdmissionPolicy)
    64  			object.Labels = map[string]string{"c": "d"}
    65  			return object
    66  		},
    67  		// invalid updateFunc
    68  		func(obj runtime.Object) runtime.Object {
    69  			object := obj.(*admissionregistration.ValidatingAdmissionPolicy)
    70  			object.Name = ""
    71  			return object
    72  		},
    73  	)
    74  }
    75  
    76  func TestGet(t *testing.T) {
    77  	storage, server := newInsecureStorage(t)
    78  	defer server.Terminate(t)
    79  	defer storage.Store.DestroyFunc()
    80  	test := genericregistrytest.New(t, storage.Store).ClusterScope()
    81  	test.TestGet(validValidatingAdmissionPolicy())
    82  }
    83  
    84  func TestList(t *testing.T) {
    85  	storage, server := newInsecureStorage(t)
    86  	defer server.Terminate(t)
    87  	defer storage.Store.DestroyFunc()
    88  	test := genericregistrytest.New(t, storage.Store).ClusterScope()
    89  	test.TestList(validValidatingAdmissionPolicy())
    90  }
    91  
    92  func TestDelete(t *testing.T) {
    93  	storage, server := newInsecureStorage(t)
    94  	defer server.Terminate(t)
    95  	defer storage.Store.DestroyFunc()
    96  	test := genericregistrytest.New(t, storage.Store).ClusterScope()
    97  	test.TestDelete(validValidatingAdmissionPolicy())
    98  }
    99  
   100  func TestWatch(t *testing.T) {
   101  	storage, server := newInsecureStorage(t)
   102  	defer server.Terminate(t)
   103  	defer storage.Store.DestroyFunc()
   104  	test := genericregistrytest.New(t, storage.Store).ClusterScope()
   105  	test.TestWatch(
   106  		validValidatingAdmissionPolicy(),
   107  		[]labels.Set{},
   108  		[]labels.Set{
   109  			{"hoo": "bar"},
   110  		},
   111  		[]fields.Set{
   112  			{"metadata.name": "foo"},
   113  		},
   114  		[]fields.Set{
   115  			{"metadata.name": "nomatch"},
   116  		},
   117  	)
   118  }
   119  
   120  func validValidatingAdmissionPolicy() *admissionregistration.ValidatingAdmissionPolicy {
   121  	return &admissionregistration.ValidatingAdmissionPolicy{
   122  		ObjectMeta: metav1.ObjectMeta{
   123  			Name: "foo",
   124  		},
   125  		Spec: admissionregistration.ValidatingAdmissionPolicySpec{
   126  			FailurePolicy: func() *admissionregistration.FailurePolicyType {
   127  				r := admissionregistration.FailurePolicyType("Fail")
   128  				return &r
   129  			}(),
   130  			ParamKind: &admissionregistration.ParamKind{
   131  				APIVersion: "rules.example.com/v1",
   132  				Kind:       "ReplicaLimit",
   133  			},
   134  			Validations: []admissionregistration.Validation{
   135  				{
   136  					Expression: "object.spec.replicas <= params.maxReplicas",
   137  				},
   138  			},
   139  			MatchConstraints: &admissionregistration.MatchResources{
   140  				MatchPolicy: func() *admissionregistration.MatchPolicyType {
   141  					r := admissionregistration.MatchPolicyType("Exact")
   142  					return &r
   143  				}(),
   144  				ResourceRules: []admissionregistration.NamedRuleWithOperations{
   145  					{
   146  						RuleWithOperations: admissionregistration.RuleWithOperations{
   147  							Operations: []admissionregistration.OperationType{"CREATE"},
   148  							Rule: admissionregistration.Rule{
   149  								APIGroups:   []string{"a"},
   150  								APIVersions: []string{"a"},
   151  								Resources:   []string{"a"},
   152  							},
   153  						},
   154  					},
   155  				},
   156  				ObjectSelector: &metav1.LabelSelector{
   157  					MatchLabels: map[string]string{"a": "b"},
   158  				},
   159  				NamespaceSelector: &metav1.LabelSelector{
   160  					MatchLabels: map[string]string{"a": "b"},
   161  				},
   162  			},
   163  		},
   164  	}
   165  }
   166  
   167  func newValidatingAdmissionPolicy(name string) *admissionregistration.ValidatingAdmissionPolicy {
   168  	ignore := admissionregistration.Ignore
   169  	return &admissionregistration.ValidatingAdmissionPolicy{
   170  		ObjectMeta: metav1.ObjectMeta{
   171  			Name:   name,
   172  			Labels: map[string]string{"foo": "bar"},
   173  		},
   174  		Spec: admissionregistration.ValidatingAdmissionPolicySpec{
   175  			ParamKind: &admissionregistration.ParamKind{
   176  				APIVersion: "rules.example.com/v1",
   177  				Kind:       "ReplicaLimit",
   178  			},
   179  			Validations: []admissionregistration.Validation{
   180  				{
   181  					Expression: "object.spec.replicas <= params.maxReplicas",
   182  				},
   183  			},
   184  			MatchConstraints: &admissionregistration.MatchResources{
   185  				ResourceRules: []admissionregistration.NamedRuleWithOperations{
   186  					{
   187  						RuleWithOperations: admissionregistration.RuleWithOperations{
   188  							Operations: []admissionregistration.OperationType{"CREATE"},
   189  							Rule: admissionregistration.Rule{
   190  								APIGroups:   []string{"a"},
   191  								APIVersions: []string{"a"},
   192  								Resources:   []string{"a"},
   193  							},
   194  						},
   195  					},
   196  				},
   197  			},
   198  			FailurePolicy: &ignore,
   199  		},
   200  	}
   201  }
   202  
   203  func newInsecureStorage(t *testing.T) (*REST, *etcd3testing.EtcdTestServer) {
   204  	return newStorage(t, nil, nil)
   205  }
   206  
   207  func newStorage(t *testing.T, authorizer authorizer.Authorizer, resourceResolver resolver.ResourceResolver) (*REST, *etcd3testing.EtcdTestServer) {
   208  	etcdStorage, server := registrytest.NewEtcdStorageForResource(t, admissionregistration.Resource("validatingadmissionpolicies"))
   209  	restOptions := generic.RESTOptions{
   210  		StorageConfig:           etcdStorage,
   211  		Decorator:               generic.UndecoratedStorage,
   212  		DeleteCollectionWorkers: 1,
   213  		ResourcePrefix:          "validatingadmissionpolicies"}
   214  	storage, _, err := NewREST(restOptions, authorizer, resourceResolver)
   215  	if err != nil {
   216  		t.Fatalf("unexpected error from REST storage: %v", err)
   217  	}
   218  	return storage, server
   219  }
   220  
   221  func TestCategories(t *testing.T) {
   222  	storage, server := newInsecureStorage(t)
   223  	defer server.Terminate(t)
   224  	defer storage.Store.DestroyFunc()
   225  	expected := []string{"api-extensions"}
   226  	registrytest.AssertCategories(t, storage, expected)
   227  }