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 }