From 75c448dbc75b3efacdc5b4749c80038eda90a620 Mon Sep 17 00:00:00 2001 From: David Eads Date: Thu, 2 Nov 2017 10:23:13 -0400 Subject: [PATCH] make easy validation admission plugins into validators --- plugin/pkg/admission/admit/admission.go | 3 ++ plugin/pkg/admission/alwayspullimages/BUILD | 1 + .../admission/alwayspullimages/admission.go | 48 ++++++++++++++++++- .../alwayspullimages/admission_test.go | 30 ++++++++++++ .../pkg/admission/antiaffinity/admission.go | 6 ++- .../admission/antiaffinity/admission_test.go | 4 +- plugin/pkg/admission/deny/admission.go | 8 ++++ .../pkg/admission/eventratelimit/admission.go | 6 ++- .../eventratelimit/admission_test.go | 2 +- plugin/pkg/admission/exec/admission.go | 6 ++- plugin/pkg/admission/exec/admission_test.go | 4 +- plugin/pkg/admission/gc/gc_admission.go | 4 +- plugin/pkg/admission/gc/gc_admission_test.go | 4 +- plugin/pkg/admission/imagepolicy/admission.go | 6 ++- .../admission/imagepolicy/admission_test.go | 12 ++--- .../admission/namespace/exists/admission.go | 5 +- .../namespace/exists/admission_test.go | 6 +-- .../persistentvolume/resize/admission.go | 3 +- .../persistentvolume/resize/admission_test.go | 2 +- .../pkg/admission/resourcequota/admission.go | 5 +- .../admission/resourcequota/admission_test.go | 48 +++++++++---------- .../securitycontext/scdeny/admission.go | 6 ++- .../securitycontext/scdeny/admission_test.go | 6 +-- 23 files changed, 164 insertions(+), 61 deletions(-) diff --git a/plugin/pkg/admission/admit/admission.go b/plugin/pkg/admission/admit/admission.go index 9c33855f52c..3c428d9136f 100644 --- a/plugin/pkg/admission/admit/admission.go +++ b/plugin/pkg/admission/admit/admission.go @@ -33,6 +33,9 @@ func Register(plugins *admission.Plugins) { // It is useful in tests and when using kubernetes in an open manner. type AlwaysAdmit struct{} +var _ admission.MutationInterface = AlwaysAdmit{} +var _ admission.ValidationInterface = AlwaysAdmit{} + // Admit makes an admission decision based on the request attributes func (AlwaysAdmit) Admit(a admission.Attributes) (err error) { return nil diff --git a/plugin/pkg/admission/alwayspullimages/BUILD b/plugin/pkg/admission/alwayspullimages/BUILD index 5005a88ab87..24dd34728ad 100644 --- a/plugin/pkg/admission/alwayspullimages/BUILD +++ b/plugin/pkg/admission/alwayspullimages/BUILD @@ -13,6 +13,7 @@ go_library( deps = [ "//pkg/api:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", ], ) diff --git a/plugin/pkg/admission/alwayspullimages/admission.go b/plugin/pkg/admission/alwayspullimages/admission.go index af46c84732a..c9e07aa4310 100644 --- a/plugin/pkg/admission/alwayspullimages/admission.go +++ b/plugin/pkg/admission/alwayspullimages/admission.go @@ -28,6 +28,7 @@ import ( "io" apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apiserver/pkg/admission" "k8s.io/kubernetes/pkg/api" ) @@ -45,10 +46,13 @@ type AlwaysPullImages struct { *admission.Handler } +var _ admission.MutationInterface = &AlwaysPullImages{} +var _ admission.ValidationInterface = &AlwaysPullImages{} + // Admit makes an admission decision based on the request attributes func (a *AlwaysPullImages) Admit(attributes admission.Attributes) (err error) { // Ignore all calls to subresources or resources other than pods. - if len(attributes.GetSubresource()) != 0 || attributes.GetResource().GroupResource() != api.Resource("pods") { + if shouldIgnore(attributes) { return nil } pod, ok := attributes.GetObject().(*api.Pod) @@ -67,6 +71,48 @@ func (a *AlwaysPullImages) Admit(attributes admission.Attributes) (err error) { return nil } +// Validate makes sure that all containers are set to always pull images +func (*AlwaysPullImages) Validate(attributes admission.Attributes) (err error) { + if shouldIgnore(attributes) { + return nil + } + + pod, ok := attributes.GetObject().(*api.Pod) + if !ok { + return apierrors.NewBadRequest("Resource was marked with kind Pod but was unable to be converted") + } + + for i := range pod.Spec.InitContainers { + if pod.Spec.InitContainers[i].ImagePullPolicy != api.PullAlways { + return admission.NewForbidden(attributes, + field.NotSupported(field.NewPath("spec", "initContainers").Index(i).Child("imagePullPolicy"), + pod.Spec.InitContainers[i].ImagePullPolicy, []string{string(api.PullAlways)}, + ), + ) + } + } + for i := range pod.Spec.Containers { + if pod.Spec.Containers[i].ImagePullPolicy != api.PullAlways { + return admission.NewForbidden(attributes, + field.NotSupported(field.NewPath("spec", "containers").Index(i).Child("imagePullPolicy"), + pod.Spec.Containers[i].ImagePullPolicy, []string{string(api.PullAlways)}, + ), + ) + } + } + + return nil +} + +func shouldIgnore(attributes admission.Attributes) bool { + // Ignore all calls to subresources or resources other than pods. + if len(attributes.GetSubresource()) != 0 || attributes.GetResource().GroupResource() != api.Resource("pods") { + return true + } + + return false +} + // NewAlwaysPullImages creates a new always pull images admission control handler func NewAlwaysPullImages() *AlwaysPullImages { return &AlwaysPullImages{ diff --git a/plugin/pkg/admission/alwayspullimages/admission_test.go b/plugin/pkg/admission/alwayspullimages/admission_test.go index 7376f449f86..518fd811077 100644 --- a/plugin/pkg/admission/alwayspullimages/admission_test.go +++ b/plugin/pkg/admission/alwayspullimages/admission_test.go @@ -63,6 +63,36 @@ func TestAdmission(t *testing.T) { } } +func TestValidate(t *testing.T) { + namespace := "test" + handler := &AlwaysPullImages{} + pod := api.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "123", Namespace: namespace}, + Spec: api.PodSpec{ + InitContainers: []api.Container{ + {Name: "init1", Image: "image"}, + {Name: "init2", Image: "image", ImagePullPolicy: api.PullNever}, + {Name: "init3", Image: "image", ImagePullPolicy: api.PullIfNotPresent}, + {Name: "init4", Image: "image", ImagePullPolicy: api.PullAlways}, + }, + Containers: []api.Container{ + {Name: "ctr1", Image: "image"}, + {Name: "ctr2", Image: "image", ImagePullPolicy: api.PullNever}, + {Name: "ctr3", Image: "image", ImagePullPolicy: api.PullIfNotPresent}, + {Name: "ctr4", Image: "image", ImagePullPolicy: api.PullAlways}, + }, + }, + } + expectedError := `pods "123" is forbidden: spec.initContainers[0].imagePullPolicy: Unsupported value: "": supported values: "Always"` + err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + if err == nil { + t.Fatal("missing expected error") + } + if err.Error() != expectedError { + t.Fatal(err) + } +} + // TestOtherResources ensures that this admission controller is a no-op for other resources, // subresources, and non-pods. func TestOtherResources(t *testing.T) { diff --git a/plugin/pkg/admission/antiaffinity/admission.go b/plugin/pkg/admission/antiaffinity/admission.go index fd3cf54fdec..c126e5cffeb 100644 --- a/plugin/pkg/admission/antiaffinity/admission.go +++ b/plugin/pkg/admission/antiaffinity/admission.go @@ -38,6 +38,8 @@ type Plugin struct { *admission.Handler } +var _ admission.ValidationInterface = &Plugin{} + // NewInterPodAntiAffinity creates a new instance of the LimitPodHardAntiAffinityTopology admission controller func NewInterPodAntiAffinity() *Plugin { return &Plugin{ @@ -45,9 +47,9 @@ func NewInterPodAntiAffinity() *Plugin { } } -// Admit will deny any pod that defines AntiAffinity topology key other than kubeletapis.LabelHostname i.e. "kubernetes.io/hostname" +// Validate will deny any pod that defines AntiAffinity topology key other than kubeletapis.LabelHostname i.e. "kubernetes.io/hostname" // in requiredDuringSchedulingRequiredDuringExecution and requiredDuringSchedulingIgnoredDuringExecution. -func (p *Plugin) Admit(attributes admission.Attributes) (err error) { +func (p *Plugin) Validate(attributes admission.Attributes) (err error) { // Ignore all calls to subresources or resources other than pods. if len(attributes.GetSubresource()) != 0 || attributes.GetResource().GroupResource() != api.Resource("pods") { return nil diff --git a/plugin/pkg/admission/antiaffinity/admission_test.go b/plugin/pkg/admission/antiaffinity/admission_test.go index 114c39766b6..dac46930d70 100644 --- a/plugin/pkg/admission/antiaffinity/admission_test.go +++ b/plugin/pkg/admission/antiaffinity/admission_test.go @@ -199,7 +199,7 @@ func TestInterPodAffinityAdmission(t *testing.T) { } for _, test := range tests { pod.Spec.Affinity = test.affinity - err := handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil)) + err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil)) if test.errorExpected && err == nil { t.Errorf("Expected error for Anti Affinity %+v but did not get an error", test.affinity) @@ -267,7 +267,7 @@ func TestOtherResources(t *testing.T) { for _, tc := range tests { handler := &Plugin{} - err := handler.Admit(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, nil)) if tc.expectError { if err == nil { diff --git a/plugin/pkg/admission/deny/admission.go b/plugin/pkg/admission/deny/admission.go index 671f1909963..f6f4951bed7 100644 --- a/plugin/pkg/admission/deny/admission.go +++ b/plugin/pkg/admission/deny/admission.go @@ -34,11 +34,19 @@ func Register(plugins *admission.Plugins) { // It is useful in unit tests to force an operation to be forbidden. type AlwaysDeny struct{} +var _ admission.MutationInterface = AlwaysDeny{} +var _ admission.ValidationInterface = AlwaysDeny{} + // Admit makes an admission decision based on the request attributes. func (AlwaysDeny) Admit(a admission.Attributes) (err error) { return admission.NewForbidden(a, errors.New("Admission control is denying all modifications")) } +// Validate makes an admission decision based on the request attributes. It is NOT allowed to mutate. +func (AlwaysDeny) Validate(a admission.Attributes) (err error) { + return admission.NewForbidden(a, errors.New("Admission control is denying all modifications")) +} + // Handles returns true if this admission controller can handle the given operation // where operation can be one of CREATE, UPDATE, DELETE, or CONNECT func (AlwaysDeny) Handles(operation admission.Operation) bool { diff --git a/plugin/pkg/admission/eventratelimit/admission.go b/plugin/pkg/admission/eventratelimit/admission.go index d3fa062e220..c2691cf6048 100644 --- a/plugin/pkg/admission/eventratelimit/admission.go +++ b/plugin/pkg/admission/eventratelimit/admission.go @@ -54,6 +54,8 @@ type Plugin struct { limitEnforcers []*limitEnforcer } +var _ admission.ValidationInterface = &Plugin{} + // newEventRateLimit configures an admission controller that can enforce event rate limits func newEventRateLimit(config *eventratelimitapi.Configuration, clock flowcontrol.Clock) (*Plugin, error) { limitEnforcers := make([]*limitEnforcer, 0, len(config.Limits)) @@ -73,8 +75,8 @@ func newEventRateLimit(config *eventratelimitapi.Configuration, clock flowcontro return eventRateLimitAdmission, nil } -// Admit makes admission decisions while enforcing event rate limits -func (a *Plugin) Admit(attr admission.Attributes) (err error) { +// Validate makes admission decisions while enforcing event rate limits +func (a *Plugin) Validate(attr admission.Attributes) (err error) { // ignore all operations that do not correspond to an Event kind if attr.GetKind().GroupKind() != api.Kind("Event") { return nil diff --git a/plugin/pkg/admission/eventratelimit/admission_test.go b/plugin/pkg/admission/eventratelimit/admission_test.go index 579ab36fb1c..72a5ff88898 100644 --- a/plugin/pkg/admission/eventratelimit/admission_test.go +++ b/plugin/pkg/admission/eventratelimit/admission_test.go @@ -482,7 +482,7 @@ func TestEventRateLimiting(t *testing.T) { clock.Step(rq.delay) } attributes := attributesForRequest(rq) - err = eventratelimit.Admit(attributes) + err = eventratelimit.Validate(attributes) if rq.accepted != (err == nil) { expectedAction := "admitted" if !rq.accepted { diff --git a/plugin/pkg/admission/exec/admission.go b/plugin/pkg/admission/exec/admission.go index b5bea35de4a..405a9928050 100644 --- a/plugin/pkg/admission/exec/admission.go +++ b/plugin/pkg/admission/exec/admission.go @@ -54,6 +54,8 @@ type DenyExec struct { privileged bool } +var _ admission.ValidationInterface = &DenyExec{} + var _ = kubeapiserveradmission.WantsInternalKubeClientSet(&DenyExec{}) // NewDenyEscalatingExec creates a new admission controller that denies an exec operation on a pod @@ -79,8 +81,8 @@ func NewDenyExecOnPrivileged() *DenyExec { } } -// Admit makes an admission decision based on the request attributes -func (d *DenyExec) Admit(a admission.Attributes) (err error) { +// Validate makes an admission decision based on the request attributes +func (d *DenyExec) Validate(a admission.Attributes) (err error) { connectRequest, ok := a.GetObject().(*rest.ConnectRequest) if !ok { return errors.NewBadRequest("a connect request was received, but could not convert the request object.") diff --git a/plugin/pkg/admission/exec/admission_test.go b/plugin/pkg/admission/exec/admission_test.go index 4a178f412fd..56a6ca43439 100644 --- a/plugin/pkg/admission/exec/admission_test.go +++ b/plugin/pkg/admission/exec/admission_test.go @@ -123,7 +123,7 @@ func testAdmission(t *testing.T, pod *api.Pod, handler *DenyExec, shouldAccept b // pods/exec { req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/exec"} - err := handler.Admit(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "exec", admission.Connect, nil)) + err := handler.Validate(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "exec", admission.Connect, nil)) if shouldAccept && err != nil { t.Errorf("Unexpected error returned from admission handler: %v", err) } @@ -135,7 +135,7 @@ func testAdmission(t *testing.T, pod *api.Pod, handler *DenyExec, shouldAccept b // pods/attach { req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/attach"} - err := handler.Admit(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "attach", admission.Connect, nil)) + err := handler.Validate(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "attach", admission.Connect, nil)) if shouldAccept && err != nil { t.Errorf("Unexpected error returned from admission handler: %v", err) } diff --git a/plugin/pkg/admission/gc/gc_admission.go b/plugin/pkg/admission/gc/gc_admission.go index 2963fad05d2..2e1a53306c1 100644 --- a/plugin/pkg/admission/gc/gc_admission.go +++ b/plugin/pkg/admission/gc/gc_admission.go @@ -63,6 +63,8 @@ type gcPermissionsEnforcement struct { whiteList []whiteListItem } +var _ admission.ValidationInterface = &gcPermissionsEnforcement{} + // whiteListItem describes an entry in a whitelist ignored by gc permission enforcement. type whiteListItem struct { groupResource schema.GroupResource @@ -79,7 +81,7 @@ func (a *gcPermissionsEnforcement) isWhiteListed(groupResource schema.GroupResou return false } -func (a *gcPermissionsEnforcement) Admit(attributes admission.Attributes) (err error) { +func (a *gcPermissionsEnforcement) Validate(attributes admission.Attributes) (err error) { // // if the request is in the whitelist, we skip mutation checks for this resource. if a.isWhiteListed(attributes.GetResource().GroupResource(), attributes.GetSubresource()) { return nil diff --git a/plugin/pkg/admission/gc/gc_admission_test.go b/plugin/pkg/admission/gc/gc_admission_test.go index e1d8914ef9a..9cc118fba85 100644 --- a/plugin/pkg/admission/gc/gc_admission_test.go +++ b/plugin/pkg/admission/gc/gc_admission_test.go @@ -269,7 +269,7 @@ func TestGCAdmission(t *testing.T) { user := &user.DefaultInfo{Name: tc.username} attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, user) - err := gcAdmit.Admit(attributes) + err := gcAdmit.Validate(attributes) if !tc.checkError(err) { t.Errorf("%v: unexpected err: %v", tc.name, err) } @@ -517,7 +517,7 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) { user := &user.DefaultInfo{Name: tc.username} attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, user) - err := gcAdmit.Admit(attributes) + err := gcAdmit.Validate(attributes) if !tc.checkError(err) { t.Errorf("%v: unexpected err: %v", tc.name, err) } diff --git a/plugin/pkg/admission/imagepolicy/admission.go b/plugin/pkg/admission/imagepolicy/admission.go index 9da95a2c365..2be89631e97 100644 --- a/plugin/pkg/admission/imagepolicy/admission.go +++ b/plugin/pkg/admission/imagepolicy/admission.go @@ -69,6 +69,8 @@ type Plugin struct { defaultAllow bool } +var _ admission.ValidationInterface = &Plugin{} + func (a *Plugin) statusTTL(status v1alpha1.ImageReviewStatus) time.Duration { if status.Allowed { return a.allowTTL @@ -107,8 +109,8 @@ func (a *Plugin) webhookError(pod *api.Pod, attributes admission.Attributes, err return nil } -// Admit makes an admission decision based on the request attributes -func (a *Plugin) Admit(attributes admission.Attributes) (err error) { +// Validate makes an admission decision based on the request attributes +func (a *Plugin) Validate(attributes admission.Attributes) (err error) { // Ignore all calls to subresources or resources other than pods. if attributes.GetSubresource() != "" || attributes.GetResource().GroupResource() != api.Resource("pods") { return nil diff --git a/plugin/pkg/admission/imagepolicy/admission_test.go b/plugin/pkg/admission/imagepolicy/admission_test.go index bd5a183cee5..08f13e86cb9 100644 --- a/plugin/pkg/admission/imagepolicy/admission_test.go +++ b/plugin/pkg/admission/imagepolicy/admission_test.go @@ -477,7 +477,7 @@ func TestTLSConfig(t *testing.T) { // Allow all and see if we get an error. service.Allow() - err = wh.Admit(attr) + err = wh.Validate(attr) if tt.wantAllowed { if err != nil { t.Errorf("expected successful admission") @@ -499,7 +499,7 @@ func TestTLSConfig(t *testing.T) { } service.Deny() - if err := wh.Admit(attr); err == nil { + if err := wh.Validate(attr); err == nil { t.Errorf("%s: incorrectly admitted with DenyAll policy", tt.test) } }() @@ -516,7 +516,7 @@ type webhookCacheTestCase struct { func testWebhookCacheCases(t *testing.T, serv *mockService, wh *Plugin, attr admission.Attributes, tests []webhookCacheTestCase) { for _, test := range tests { serv.statusCode = test.statusCode - err := wh.Admit(attr) + err := wh.Validate(attr) authorized := err == nil if test.expectedErr && err == nil { @@ -749,7 +749,7 @@ func TestContainerCombinations(t *testing.T) { attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{}) - err = wh.Admit(attr) + err = wh.Validate(attr) if tt.wantAllowed { if err != nil { t.Errorf("expected successful admission: %s", tt.test) @@ -827,7 +827,7 @@ func TestDefaultAllow(t *testing.T) { attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{}) - err = wh.Admit(attr) + err = wh.Validate(attr) if tt.wantAllowed { if err != nil { t.Errorf("expected successful admission") @@ -919,7 +919,7 @@ func TestAnnotationFiltering(t *testing.T) { attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &user.DefaultInfo{}) - err = wh.Admit(attr) + err = wh.Validate(attr) if err != nil { t.Errorf("expected successful admission") } diff --git a/plugin/pkg/admission/namespace/exists/admission.go b/plugin/pkg/admission/namespace/exists/admission.go index 5a6c29751e3..7138a0f13f3 100644 --- a/plugin/pkg/admission/namespace/exists/admission.go +++ b/plugin/pkg/admission/namespace/exists/admission.go @@ -46,11 +46,12 @@ type Exists struct { namespaceLister corelisters.NamespaceLister } +var _ admission.ValidationInterface = &Exists{} var _ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&Exists{}) var _ = kubeapiserveradmission.WantsInternalKubeClientSet(&Exists{}) -// Admit makes an admission decision based on the request attributes -func (e *Exists) Admit(a admission.Attributes) error { +// Validate makes an admission decision based on the request attributes +func (e *Exists) Validate(a admission.Attributes) error { // if we're here, then we've already passed authentication, so we're allowed to do what we're trying to do // if we're here, then the API server has found a route, which means that if we have a non-empty namespace // its a namespaced resource. diff --git a/plugin/pkg/admission/namespace/exists/admission_test.go b/plugin/pkg/admission/namespace/exists/admission_test.go index 4b8d54c025a..9119cf878ab 100644 --- a/plugin/pkg/admission/namespace/exists/admission_test.go +++ b/plugin/pkg/admission/namespace/exists/admission_test.go @@ -34,7 +34,7 @@ import ( ) // newHandlerForTest returns the admission controller configured for testing. -func newHandlerForTest(c clientset.Interface) (admission.MutationInterface, informers.SharedInformerFactory, error) { +func newHandlerForTest(c clientset.Interface) (admission.ValidationInterface, informers.SharedInformerFactory, error) { f := informers.NewSharedInformerFactory(c, 5*time.Minute) handler := NewExists() pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil, nil, nil, nil) @@ -87,7 +87,7 @@ func TestAdmissionNamespaceExists(t *testing.T) { informerFactory.Start(wait.NeverStop) pod := newPod(namespace) - err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Errorf("unexpected error returned from admission handler") } @@ -107,7 +107,7 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) { informerFactory.Start(wait.NeverStop) pod := newPod(namespace) - err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err == nil { actions := "" for _, action := range mockClient.Actions() { diff --git a/plugin/pkg/admission/persistentvolume/resize/admission.go b/plugin/pkg/admission/persistentvolume/resize/admission.go index 4b3ea07d5b5..97687353264 100644 --- a/plugin/pkg/admission/persistentvolume/resize/admission.go +++ b/plugin/pkg/admission/persistentvolume/resize/admission.go @@ -43,6 +43,7 @@ func Register(plugins *admission.Plugins) { } var _ admission.Interface = &persistentVolumeClaimResize{} +var _ admission.ValidationInterface = &persistentVolumeClaimResize{} var _ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&persistentVolumeClaimResize{}) type persistentVolumeClaimResize struct { @@ -79,7 +80,7 @@ func (pvcr *persistentVolumeClaimResize) ValidateInitialization() error { return nil } -func (pvcr *persistentVolumeClaimResize) Admit(a admission.Attributes) error { +func (pvcr *persistentVolumeClaimResize) Validate(a admission.Attributes) error { if a.GetResource().GroupResource() != api.Resource("persistentvolumeclaims") { return nil } diff --git a/plugin/pkg/admission/persistentvolume/resize/admission_test.go b/plugin/pkg/admission/persistentvolume/resize/admission_test.go index f30e53af917..25c4227cb1c 100644 --- a/plugin/pkg/admission/persistentvolume/resize/admission_test.go +++ b/plugin/pkg/admission/persistentvolume/resize/admission_test.go @@ -323,7 +323,7 @@ func TestPVCResizeAdmission(t *testing.T) { operation := admission.Update attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, nil) - err := ctrl.Admit(attributes) + err := ctrl.Validate(attributes) fmt.Println(tc.name) fmt.Println(err) if !tc.checkError(err) { diff --git a/plugin/pkg/admission/resourcequota/admission.go b/plugin/pkg/admission/resourcequota/admission.go index 0cffb684ffb..97de60454dc 100644 --- a/plugin/pkg/admission/resourcequota/admission.go +++ b/plugin/pkg/admission/resourcequota/admission.go @@ -61,6 +61,7 @@ type QuotaAdmission struct { evaluator Evaluator } +var _ admission.ValidationInterface = &QuotaAdmission{} var _ = kubeapiserveradmission.WantsInternalKubeClientSet(&QuotaAdmission{}) var _ = kubeapiserveradmission.WantsQuotaConfiguration(&QuotaAdmission{}) @@ -120,8 +121,8 @@ func (a *QuotaAdmission) ValidateInitialization() error { return nil } -// Admit makes admission decisions while enforcing quota -func (a *QuotaAdmission) Admit(attr admission.Attributes) (err error) { +// Validate makes admission decisions while enforcing quota +func (a *QuotaAdmission) Validate(attr admission.Attributes) (err error) { // ignore all operations that correspond to sub-resource actions if attr.GetSubresource() != "" { return nil diff --git a/plugin/pkg/admission/resourcequota/admission_test.go b/plugin/pkg/admission/resourcequota/admission_test.go index bcf7573ea4d..71b7a74722c 100644 --- a/plugin/pkg/admission/resourcequota/admission_test.go +++ b/plugin/pkg/admission/resourcequota/admission_test.go @@ -140,7 +140,7 @@ func TestAdmissionIgnoresDelete(t *testing.T) { evaluator: evaluator, } namespace := "default" - err := handler.Admit(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), namespace, "name", api.Resource("pods").WithVersion("version"), "", admission.Delete, nil)) + err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), namespace, "name", api.Resource("pods").WithVersion("version"), "", admission.Delete, nil)) if err != nil { t.Errorf("ResourceQuota should admit all deletes: %v", err) } @@ -177,11 +177,11 @@ func TestAdmissionIgnoresSubresources(t *testing.T) { } informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) newPod := validPod("123", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", ""))) - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err == nil { t.Errorf("Expected an error because the pod exceeded allowed quota") } - err = handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "subresource", admission.Create, nil)) + err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "subresource", admission.Create, nil)) if err != nil { t.Errorf("Did not expect an error because the action went to a subresource: %v", err) } @@ -222,7 +222,7 @@ func TestAdmitBelowQuotaLimit(t *testing.T) { } informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", ""))) - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -318,7 +318,7 @@ func TestAdmitHandlesOldObjects(t *testing.T) { Ports: []api.ServicePort{{Port: 1234}}, }, } - err := handler.Admit(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, api.Resource("services").WithVersion("version"), "", admission.Update, nil)) + err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, api.Resource("services").WithVersion("version"), "", admission.Update, nil)) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -427,7 +427,7 @@ func TestAdmitHandlesNegativePVCUpdates(t *testing.T) { }, } - err = handler.Admit(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, nil)) + err = handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, nil)) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -494,7 +494,7 @@ func TestAdmitHandlesPVCUpdates(t *testing.T) { }, } - err = handler.Admit(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, nil)) + err = handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, nil)) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -591,7 +591,7 @@ func TestAdmitHandlesCreatingUpdates(t *testing.T) { Ports: []api.ServicePort{{Port: 1234}}, }, } - err := handler.Admit(admission.NewAttributesRecord(newService, oldService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, api.Resource("services").WithVersion("version"), "", admission.Update, nil)) + err := handler.Validate(admission.NewAttributesRecord(newService, oldService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, api.Resource("services").WithVersion("version"), "", admission.Update, nil)) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -674,7 +674,7 @@ func TestAdmitExceedQuotaLimit(t *testing.T) { } informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", ""))) - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err == nil { t.Errorf("Expected an error exceeding quota") } @@ -720,13 +720,13 @@ func TestAdmitEnforceQuotaConstraints(t *testing.T) { informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) // verify all values are specified as required on the quota newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", ""))) - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err == nil { t.Errorf("Expected an error because the pod does not specify a memory limit") } // verify the requests and limits are actually valid (in this case, we fail because the limits < requests) newPod = validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("200m", "2Gi"), getResourceList("100m", "1Gi"))) - err = handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err == nil { t.Errorf("Expected an error because the pod does not specify a memory limit") } @@ -777,7 +777,7 @@ func TestAdmitPodInNamespaceWithoutQuota(t *testing.T) { newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", ""))) // Add to the lru cache so we do not do a live client lookup liveLookupCache.Add(newPod.Namespace, liveLookupEntry{expiry: time.Now().Add(time.Duration(30 * time.Second)), items: []*api.ResourceQuota{}}) - err = handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Errorf("Did not expect an error because the pod is in a different namespace than the quota") } @@ -846,7 +846,7 @@ func TestAdmitBelowTerminatingQuotaLimit(t *testing.T) { newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", ""))) activeDeadlineSeconds := int64(30) newPod.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -950,7 +950,7 @@ func TestAdmitBelowBestEffortQuotaLimit(t *testing.T) { // create a pod that is best effort because it does not make a request for anything newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", ""))) - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1040,7 +1040,7 @@ func TestAdmitBestEffortQuotaLimitIgnoresBurstable(t *testing.T) { } informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "1Gi"), getResourceList("", ""))) - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1130,7 +1130,7 @@ func TestAdmissionSetsMissingNamespace(t *testing.T) { // unset the namespace newPod.ObjectMeta.Namespace = "" - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Errorf("Got unexpected error: %v", err) } @@ -1173,14 +1173,14 @@ func TestAdmitRejectsNegativeUsage(t *testing.T) { informerFactory.Core().InternalVersion().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota) // verify quota rejects negative pvc storage requests newPvc := validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("-1Gi")}, api.ResourceList{})) - err := handler.Admit(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, nil)) if err == nil { t.Errorf("Expected an error because the pvc has negative storage usage") } // verify quota accepts non-negative pvc storage requests newPvc = validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("1Gi")}, api.ResourceList{})) - err = handler.Admit(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, nil)) + err = handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, api.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1221,7 +1221,7 @@ func TestAdmitWhenUnrelatedResourceExceedsQuota(t *testing.T) { // create a pod that should pass existing quota newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", ""))) - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1255,7 +1255,7 @@ func TestAdmitLimitedResourceNoQuota(t *testing.T) { evaluator: evaluator, } newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", ""))) - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err == nil { t.Errorf("Expected an error for consuming a limited resource without quota.") } @@ -1289,7 +1289,7 @@ func TestAdmitLimitedResourceNoQuotaIgnoresNonMatchingResources(t *testing.T) { evaluator: evaluator, } newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", ""))) - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Fatalf("Unexpected error: %v", err) } @@ -1337,7 +1337,7 @@ func TestAdmitLimitedResourceWithQuota(t *testing.T) { } indexer.Add(resourceQuota) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", ""))) - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -1397,7 +1397,7 @@ func TestAdmitLimitedResourceWithMultipleQuota(t *testing.T) { indexer.Add(resourceQuota1) indexer.Add(resourceQuota2) newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", ""))) - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -1445,7 +1445,7 @@ func TestAdmitLimitedResourceWithQuotaThatDoesNotCover(t *testing.T) { } indexer.Add(resourceQuota) newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", ""))) - err := handler.Admit(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) + err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, nil)) if err == nil { t.Fatalf("Expected an error since the quota did not cover cpu") } diff --git a/plugin/pkg/admission/securitycontext/scdeny/admission.go b/plugin/pkg/admission/securitycontext/scdeny/admission.go index 92e265e9fd4..91a89c263b0 100644 --- a/plugin/pkg/admission/securitycontext/scdeny/admission.go +++ b/plugin/pkg/admission/securitycontext/scdeny/admission.go @@ -37,6 +37,8 @@ type Plugin struct { *admission.Handler } +var _ admission.ValidationInterface = &Plugin{} + // NewSecurityContextDeny creates a new instance of the SecurityContextDeny admission controller func NewSecurityContextDeny() *Plugin { return &Plugin{ @@ -44,8 +46,8 @@ func NewSecurityContextDeny() *Plugin { } } -// Admit will deny any pod that defines SELinuxOptions or RunAsUser. -func (p *Plugin) Admit(a admission.Attributes) (err error) { +// Validate will deny any pod that defines SELinuxOptions or RunAsUser. +func (p *Plugin) Validate(a admission.Attributes) (err error) { if a.GetSubresource() != "" || a.GetResource().GroupResource() != api.Resource("pods") { return nil } diff --git a/plugin/pkg/admission/securitycontext/scdeny/admission_test.go b/plugin/pkg/admission/securitycontext/scdeny/admission_test.go index f3c498a1bfd..f80c4760b60 100644 --- a/plugin/pkg/admission/securitycontext/scdeny/admission_test.go +++ b/plugin/pkg/admission/securitycontext/scdeny/admission_test.go @@ -82,7 +82,7 @@ func TestAdmission(t *testing.T) { p.Spec.SecurityContext = tc.podSc p.Spec.Containers[0].SecurityContext = tc.sc - err := handler.Admit(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil)) + err := handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil)) if err != nil && !tc.expectError { t.Errorf("%v: unexpected error: %v", tc.name, err) } else if err == nil && tc.expectError { @@ -96,7 +96,7 @@ func TestAdmission(t *testing.T) { p.Spec.InitContainers = p.Spec.Containers p.Spec.Containers = nil - err = handler.Admit(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil)) + err = handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil)) if err != nil && !tc.expectError { t.Errorf("%v: unexpected error: %v", tc.name, err) } else if err == nil && tc.expectError { @@ -140,7 +140,7 @@ func TestPodSecurityContextAdmission(t *testing.T) { } for _, test := range tests { pod.Spec.SecurityContext = &test.securityContext - err := handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil)) + err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", nil)) if test.errorExpected && err == nil { t.Errorf("Expected error for security context %+v but did not get an error", test.securityContext)