k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/pkg/registry/admissionregistration/validatingadmissionpolicybinding/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  
    31  	"k8s.io/kubernetes/pkg/apis/admissionregistration"
    32  	"k8s.io/kubernetes/pkg/registry/admissionregistration/resolver"
    33  	"k8s.io/kubernetes/pkg/registry/registrytest"
    34  
    35  	// Ensure that admissionregistration package is initialized.
    36  	_ "k8s.io/kubernetes/pkg/apis/admissionregistration/install"
    37  )
    38  
    39  func TestCreate(t *testing.T) {
    40  	for _, configuration := range validPolicyBindings() {
    41  		t.Run(configuration.Name, func(t *testing.T) {
    42  			storage, server := newInsecureStorage(t)
    43  			defer server.Terminate(t)
    44  			defer storage.Store.DestroyFunc()
    45  			test := genericregistrytest.New(t, storage.Store).ClusterScope()
    46  
    47  			test.TestCreate(
    48  				// valid
    49  				configuration,
    50  				// invalid
    51  				newPolicyBinding(""),
    52  			)
    53  		})
    54  	}
    55  }
    56  
    57  func TestUpdate(t *testing.T) {
    58  	for _, b := range validPolicyBindings() {
    59  		storage, server := newInsecureStorage(t)
    60  		defer server.Terminate(t)
    61  		defer storage.Store.DestroyFunc()
    62  		t.Run(b.Name, func(t *testing.T) {
    63  			test := genericregistrytest.New(t, storage.Store).ClusterScope()
    64  			test.TestUpdate(
    65  				// valid
    66  				b,
    67  				// updateFunc
    68  				func(obj runtime.Object) runtime.Object {
    69  					object := obj.(*admissionregistration.ValidatingAdmissionPolicyBinding)
    70  					object.Labels = map[string]string{"c": "d"}
    71  					return object
    72  				},
    73  				// invalid updateFunc
    74  				func(obj runtime.Object) runtime.Object {
    75  					object := obj.(*admissionregistration.ValidatingAdmissionPolicyBinding)
    76  					object.Name = ""
    77  					return object
    78  				},
    79  			)
    80  		})
    81  	}
    82  }
    83  
    84  func TestGet(t *testing.T) {
    85  	for _, b := range validPolicyBindings() {
    86  		t.Run(b.Name, func(t *testing.T) {
    87  			storage, server := newInsecureStorage(t)
    88  			defer server.Terminate(t)
    89  			defer storage.Store.DestroyFunc()
    90  
    91  			test := genericregistrytest.New(t, storage.Store).ClusterScope()
    92  			test.TestGet(b)
    93  		})
    94  	}
    95  }
    96  
    97  func TestList(t *testing.T) {
    98  	for _, b := range validPolicyBindings() {
    99  		t.Run(b.Name, func(t *testing.T) {
   100  			storage, server := newInsecureStorage(t)
   101  			defer server.Terminate(t)
   102  			defer storage.Store.DestroyFunc()
   103  			test := genericregistrytest.New(t, storage.Store).ClusterScope()
   104  			test.TestList(b)
   105  		})
   106  	}
   107  }
   108  
   109  func TestDelete(t *testing.T) {
   110  	for _, b := range validPolicyBindings() {
   111  		t.Run(b.Name, func(t *testing.T) {
   112  			storage, server := newInsecureStorage(t)
   113  			defer server.Terminate(t)
   114  			defer storage.Store.DestroyFunc()
   115  
   116  			test := genericregistrytest.New(t, storage.Store).ClusterScope()
   117  			test.TestDelete(b)
   118  		})
   119  	}
   120  }
   121  
   122  func TestWatch(t *testing.T) {
   123  	for _, b := range validPolicyBindings() {
   124  		t.Run(b.Name, func(t *testing.T) {
   125  			storage, server := newInsecureStorage(t)
   126  			defer server.Terminate(t)
   127  			defer storage.Store.DestroyFunc()
   128  			test := genericregistrytest.New(t, storage.Store).ClusterScope()
   129  			test.TestWatch(
   130  				b,
   131  				[]labels.Set{},
   132  				[]labels.Set{
   133  					{"hoo": "bar"},
   134  				},
   135  				[]fields.Set{
   136  					{"metadata.name": b.Name},
   137  				},
   138  				[]fields.Set{
   139  					{"metadata.name": "nomatch"},
   140  				},
   141  			)
   142  		})
   143  	}
   144  }
   145  
   146  func validPolicyBindings() []*admissionregistration.ValidatingAdmissionPolicyBinding {
   147  	denyAction := admissionregistration.DenyAction
   148  	return []*admissionregistration.ValidatingAdmissionPolicyBinding{
   149  		{
   150  			ObjectMeta: metav1.ObjectMeta{
   151  				Name: "foo",
   152  			},
   153  			Spec: admissionregistration.ValidatingAdmissionPolicyBindingSpec{
   154  				PolicyName: "replicalimit-policy.example.com",
   155  				ParamRef: &admissionregistration.ParamRef{
   156  					Name:                    "replica-limit-test.example.com",
   157  					ParameterNotFoundAction: &denyAction,
   158  				},
   159  				ValidationActions: []admissionregistration.ValidationAction{admissionregistration.Deny},
   160  			},
   161  		},
   162  		{
   163  			ObjectMeta: metav1.ObjectMeta{
   164  				Name: "foo-clusterwide",
   165  			},
   166  			Spec: admissionregistration.ValidatingAdmissionPolicyBindingSpec{
   167  				PolicyName: "replicalimit-policy.example.com",
   168  				ParamRef: &admissionregistration.ParamRef{
   169  					Name:                    "replica-limit-test.example.com",
   170  					Namespace:               "default",
   171  					ParameterNotFoundAction: &denyAction,
   172  				},
   173  				ValidationActions: []admissionregistration.ValidationAction{admissionregistration.Deny},
   174  			},
   175  		},
   176  		{
   177  			ObjectMeta: metav1.ObjectMeta{
   178  				Name: "foo-selector",
   179  			},
   180  			Spec: admissionregistration.ValidatingAdmissionPolicyBindingSpec{
   181  				PolicyName: "replicalimit-policy.example.com",
   182  				ParamRef: &admissionregistration.ParamRef{
   183  					Selector: &metav1.LabelSelector{
   184  						MatchLabels: map[string]string{
   185  							"label": "value",
   186  						},
   187  					},
   188  					ParameterNotFoundAction: &denyAction,
   189  				},
   190  				ValidationActions: []admissionregistration.ValidationAction{admissionregistration.Deny},
   191  			},
   192  		},
   193  		{
   194  			ObjectMeta: metav1.ObjectMeta{
   195  				Name: "foo-selector-clusterwide",
   196  			},
   197  			Spec: admissionregistration.ValidatingAdmissionPolicyBindingSpec{
   198  				PolicyName: "replicalimit-policy.example.com",
   199  				ParamRef: &admissionregistration.ParamRef{
   200  					Namespace: "mynamespace",
   201  					Selector: &metav1.LabelSelector{
   202  						MatchLabels: map[string]string{
   203  							"label": "value",
   204  						},
   205  					},
   206  					ParameterNotFoundAction: &denyAction,
   207  				},
   208  				ValidationActions: []admissionregistration.ValidationAction{admissionregistration.Deny},
   209  			},
   210  		},
   211  	}
   212  }
   213  
   214  func newPolicyBinding(name string) *admissionregistration.ValidatingAdmissionPolicyBinding {
   215  	return &admissionregistration.ValidatingAdmissionPolicyBinding{
   216  		ObjectMeta: metav1.ObjectMeta{
   217  			Name:   name,
   218  			Labels: map[string]string{"foo": "bar"},
   219  		},
   220  		Spec: admissionregistration.ValidatingAdmissionPolicyBindingSpec{
   221  			PolicyName: "replicalimit-policy.example.com",
   222  			ParamRef: &admissionregistration.ParamRef{
   223  				Name:      "param-test",
   224  				Namespace: "default",
   225  			},
   226  			ValidationActions: []admissionregistration.ValidationAction{admissionregistration.Deny},
   227  			MatchResources:    &admissionregistration.MatchResources{},
   228  		},
   229  	}
   230  }
   231  
   232  func newInsecureStorage(t *testing.T) (*REST, *etcd3testing.EtcdTestServer) {
   233  	return newStorage(t, nil, nil, nil)
   234  }
   235  
   236  func newStorage(t *testing.T, authorizer authorizer.Authorizer, policyGetter PolicyGetter, resourceResolver resolver.ResourceResolver) (*REST, *etcd3testing.EtcdTestServer) {
   237  	etcdStorage, server := registrytest.NewEtcdStorageForResource(t, admissionregistration.Resource("validatingadmissionpolicybindings"))
   238  	restOptions := generic.RESTOptions{
   239  		StorageConfig:           etcdStorage,
   240  		Decorator:               generic.UndecoratedStorage,
   241  		DeleteCollectionWorkers: 1,
   242  		ResourcePrefix:          "validatingadmissionpolicybindings"}
   243  	storage, err := NewREST(restOptions, authorizer, policyGetter, resourceResolver)
   244  	if err != nil {
   245  		t.Fatalf("unexpected error from REST storage: %v", err)
   246  	}
   247  	return storage, server
   248  }
   249  
   250  func TestCategories(t *testing.T) {
   251  	storage, server := newInsecureStorage(t)
   252  	defer server.Terminate(t)
   253  	defer storage.Store.DestroyFunc()
   254  	expected := []string{"api-extensions"}
   255  	registrytest.AssertCategories(t, storage, expected)
   256  }