From 3846cb803e00949cea53088f52b9d02db7117cfc Mon Sep 17 00:00:00 2001 From: mbohlool Date: Tue, 7 Nov 2017 12:46:54 -0800 Subject: [PATCH 1/4] Rename ExternalAdmissionHookConfiguration to ValidatingWebhookConfiguration Kubernetes-commit: 9ddea83a2ce0937cf0fc8f8c35614bb18e74cfad --- .../external_admission_hook_manager.go | 83 ------------------ .../validating_webhook_manager.go | 84 +++++++++++++++++++ ....go => validating_webhook_manager_test.go} | 10 +-- pkg/admission/plugin/webhook/admission.go | 26 +++--- .../plugin/webhook/admission_test.go | 24 +++--- 5 files changed, 114 insertions(+), 113 deletions(-) delete mode 100644 pkg/admission/configuration/external_admission_hook_manager.go create mode 100644 pkg/admission/configuration/validating_webhook_manager.go rename pkg/admission/configuration/{external_admission_hook_manager_test.go => validating_webhook_manager_test.go} (72%) diff --git a/pkg/admission/configuration/external_admission_hook_manager.go b/pkg/admission/configuration/external_admission_hook_manager.go deleted file mode 100644 index 024f5fae0..000000000 --- a/pkg/admission/configuration/external_admission_hook_manager.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package configuration - -import ( - "fmt" - "reflect" - - "github.com/golang/glog" - - "k8s.io/api/admissionregistration/v1alpha1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" -) - -type ExternalAdmissionHookConfigurationLister interface { - List(opts metav1.ListOptions) (*v1alpha1.ExternalAdmissionHookConfigurationList, error) -} - -type ExternalAdmissionHookConfigurationManager struct { - *poller -} - -func NewExternalAdmissionHookConfigurationManager(c ExternalAdmissionHookConfigurationLister) *ExternalAdmissionHookConfigurationManager { - getFn := func() (runtime.Object, error) { - list, err := c.List(metav1.ListOptions{}) - if err != nil { - if errors.IsNotFound(err) || errors.IsForbidden(err) { - glog.V(5).Infof("ExternalAdmissionHookConfiguration are disabled due to an error: %v", err) - return nil, ErrDisabled - } - return nil, err - } - return mergeExternalAdmissionHookConfigurations(list), nil - } - - return &ExternalAdmissionHookConfigurationManager{ - newPoller(getFn), - } -} - -// ExternalAdmissionHooks returns the merged ExternalAdmissionHookConfiguration. -func (im *ExternalAdmissionHookConfigurationManager) ExternalAdmissionHooks() (*v1alpha1.ExternalAdmissionHookConfiguration, error) { - configuration, err := im.poller.configuration() - if err != nil { - return nil, err - } - externalAdmissionHookConfiguration, ok := configuration.(*v1alpha1.ExternalAdmissionHookConfiguration) - if !ok { - return nil, fmt.Errorf("expected type %v, got type %v", reflect.TypeOf(externalAdmissionHookConfiguration), reflect.TypeOf(configuration)) - } - return externalAdmissionHookConfiguration, nil -} - -func (im *ExternalAdmissionHookConfigurationManager) Run(stopCh <-chan struct{}) { - im.poller.Run(stopCh) -} - -func mergeExternalAdmissionHookConfigurations( - list *v1alpha1.ExternalAdmissionHookConfigurationList, -) *v1alpha1.ExternalAdmissionHookConfiguration { - configurations := list.Items - var ret v1alpha1.ExternalAdmissionHookConfiguration - for _, c := range configurations { - ret.ExternalAdmissionHooks = append(ret.ExternalAdmissionHooks, c.ExternalAdmissionHooks...) - } - return &ret -} diff --git a/pkg/admission/configuration/validating_webhook_manager.go b/pkg/admission/configuration/validating_webhook_manager.go new file mode 100644 index 000000000..e3287ce4e --- /dev/null +++ b/pkg/admission/configuration/validating_webhook_manager.go @@ -0,0 +1,84 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package configuration + +import ( + "fmt" + "reflect" + + "github.com/golang/glog" + + "k8s.io/api/admissionregistration/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type ValidatingWebhookConfigurationLister interface { + List(opts metav1.ListOptions) (*v1alpha1.ValidatingWebhookConfigurationList, error) +} + +// ValidatingWebhookConfigurationManager collects the validating webhook objects so that they can be called. +type ValidatingWebhookConfigurationManager struct { + *poller +} + +func NewValidatingWebhookConfigurationManager(c ValidatingWebhookConfigurationLister) *ValidatingWebhookConfigurationManager { + getFn := func() (runtime.Object, error) { + list, err := c.List(metav1.ListOptions{}) + if err != nil { + if errors.IsNotFound(err) || errors.IsForbidden(err) { + glog.V(5).Infof("ValidatingWebhookConfiguration are disabled due to an error: %v", err) + return nil, ErrDisabled + } + return nil, err + } + return mergeValidatingWebhookConfigurations(list), nil + } + + return &ValidatingWebhookConfigurationManager{ + newPoller(getFn), + } +} + +// Webhooks returns the merged ValidatingWebhookConfiguration. +func (im *ValidatingWebhookConfigurationManager) Webhooks() (*v1alpha1.ValidatingWebhookConfiguration, error) { + configuration, err := im.poller.configuration() + if err != nil { + return nil, err + } + validatingWebhookConfiguration, ok := configuration.(*v1alpha1.ValidatingWebhookConfiguration) + if !ok { + return nil, fmt.Errorf("expected type %v, got type %v", reflect.TypeOf(validatingWebhookConfiguration), reflect.TypeOf(configuration)) + } + return validatingWebhookConfiguration, nil +} + +func (im *ValidatingWebhookConfigurationManager) Run(stopCh <-chan struct{}) { + im.poller.Run(stopCh) +} + +func mergeValidatingWebhookConfigurations( + list *v1alpha1.ValidatingWebhookConfigurationList, +) *v1alpha1.ValidatingWebhookConfiguration { + configurations := list.Items + var ret v1alpha1.ValidatingWebhookConfiguration + for _, c := range configurations { + ret.Webhooks = append(ret.Webhooks, c.Webhooks...) + } + return &ret +} diff --git a/pkg/admission/configuration/external_admission_hook_manager_test.go b/pkg/admission/configuration/validating_webhook_manager_test.go similarity index 72% rename from pkg/admission/configuration/external_admission_hook_manager_test.go rename to pkg/admission/configuration/validating_webhook_manager_test.go index 1b849b1d2..946747150 100644 --- a/pkg/admission/configuration/external_admission_hook_manager_test.go +++ b/pkg/admission/configuration/validating_webhook_manager_test.go @@ -25,15 +25,15 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) -type disabledWebhookConfigLister struct{} +type disabledValidatingWebhookConfigLister struct{} -func (l *disabledWebhookConfigLister) List(options metav1.ListOptions) (*v1alpha1.ExternalAdmissionHookConfigurationList, error) { - return nil, errors.NewNotFound(schema.GroupResource{Group: "admissionregistration", Resource: "externalAdmissionHookConfigurations"}, "") +func (l *disabledValidatingWebhookConfigLister) List(options metav1.ListOptions) (*v1alpha1.ValidatingWebhookConfigurationList, error) { + return nil, errors.NewNotFound(schema.GroupResource{Group: "admissionregistration", Resource: "ValidatingWebhookConfigurations"}, "") } func TestWebhookConfigDisabled(t *testing.T) { - manager := NewExternalAdmissionHookConfigurationManager(&disabledWebhookConfigLister{}) + manager := NewValidatingWebhookConfigurationManager(&disabledValidatingWebhookConfigLister{}) manager.sync() - _, err := manager.ExternalAdmissionHooks() + _, err := manager.Webhooks() if err.Error() != ErrDisabled.Error() { t.Errorf("expected %v, got %v", ErrDisabled, err) } diff --git a/pkg/admission/plugin/webhook/admission.go b/pkg/admission/plugin/webhook/admission.go index ab12ba896..1238f4a5c 100644 --- a/pkg/admission/plugin/webhook/admission.go +++ b/pkg/admission/plugin/webhook/admission.go @@ -75,7 +75,7 @@ func Register(plugins *admission.Plugins) { // WebhookSource can list dynamic webhook plugins. type WebhookSource interface { Run(stopCh <-chan struct{}) - ExternalAdmissionHooks() (*v1alpha1.ExternalAdmissionHookConfiguration, error) + Webhooks() (*v1alpha1.ValidatingWebhookConfiguration, error) } // NewGenericAdmissionWebhook returns a generic admission webhook plugin. @@ -153,7 +153,7 @@ func (a *GenericAdmissionWebhook) SetScheme(scheme *runtime.Scheme) { // WantsExternalKubeClientSet defines a function which sets external ClientSet for admission plugins that need it func (a *GenericAdmissionWebhook) SetExternalKubeClientSet(client clientset.Interface) { - a.hookSource = configuration.NewExternalAdmissionHookConfigurationManager(client.AdmissionregistrationV1alpha1().ExternalAdmissionHookConfigurations()) + a.hookSource = configuration.NewValidatingWebhookConfigurationManager(client.AdmissionregistrationV1alpha1().ValidatingWebhookConfigurations()) } // ValidateInitialization implements the InitializationValidator interface. @@ -168,19 +168,19 @@ func (a *GenericAdmissionWebhook) ValidateInitialization() error { return nil } -func (a *GenericAdmissionWebhook) loadConfiguration(attr admission.Attributes) (*v1alpha1.ExternalAdmissionHookConfiguration, error) { - hookConfig, err := a.hookSource.ExternalAdmissionHooks() - // if ExternalAdmissionHook configuration is disabled, fail open +func (a *GenericAdmissionWebhook) loadConfiguration(attr admission.Attributes) (*v1alpha1.ValidatingWebhookConfiguration, error) { + hookConfig, err := a.hookSource.Webhooks() + // if Webhook configuration is disabled, fail open if err == configuration.ErrDisabled { - return &v1alpha1.ExternalAdmissionHookConfiguration{}, nil + return &v1alpha1.ValidatingWebhookConfiguration{}, nil } if err != nil { e := apierrors.NewServerTimeout(attr.GetResource().GroupResource(), string(attr.GetOperation()), 1) - e.ErrStatus.Message = fmt.Sprintf("Unable to refresh the ExternalAdmissionHook configuration: %v", err) + e.ErrStatus.Message = fmt.Sprintf("Unable to refresh the Webhook configuration: %v", err) e.ErrStatus.Reason = "LoadingConfiguration" e.ErrStatus.Details.Causes = append(e.ErrStatus.Details.Causes, metav1.StatusCause{ - Type: "ExternalAdmissionHookConfigurationFailure", - Message: "An error has occurred while refreshing the externalAdmissionHook configuration, no resources can be created/updated/deleted/connected until a refresh succeeds.", + Type: "ValidatingWebhookConfigurationFailure", + Message: "An error has occurred while refreshing the ValidatingWebhook configuration, no resources can be created/updated/deleted/connected until a refresh succeeds.", }) return nil, e } @@ -193,14 +193,14 @@ func (a *GenericAdmissionWebhook) Admit(attr admission.Attributes) error { if err != nil { return err } - hooks := hookConfig.ExternalAdmissionHooks + hooks := hookConfig.Webhooks ctx := context.TODO() errCh := make(chan error, len(hooks)) wg := sync.WaitGroup{} wg.Add(len(hooks)) for i := range hooks { - go func(hook *v1alpha1.ExternalAdmissionHook) { + go func(hook *v1alpha1.Webhook) { defer wg.Done() err := a.callHook(ctx, hook, attr) @@ -245,7 +245,7 @@ func (a *GenericAdmissionWebhook) Admit(attr admission.Attributes) error { return errs[0] } -func (a *GenericAdmissionWebhook) callHook(ctx context.Context, h *v1alpha1.ExternalAdmissionHook, attr admission.Attributes) error { +func (a *GenericAdmissionWebhook) callHook(ctx context.Context, h *v1alpha1.Webhook, attr admission.Attributes) error { matches := false for _, r := range h.Rules { m := RuleMatcher{Rule: r, Attr: attr} @@ -299,7 +299,7 @@ func toStatusErr(name string, result *metav1.Status) *apierrors.StatusError { } } -func (a *GenericAdmissionWebhook) hookClient(h *v1alpha1.ExternalAdmissionHook) (*rest.RESTClient, error) { +func (a *GenericAdmissionWebhook) hookClient(h *v1alpha1.Webhook) (*rest.RESTClient, error) { serverName := h.ClientConfig.Service.Name + "." + h.ClientConfig.Service.Namespace + ".svc" u, err := a.serviceResolver.ResolveEndpoint(h.ClientConfig.Service.Namespace, h.ClientConfig.Service.Name) if err != nil { diff --git a/pkg/admission/plugin/webhook/admission_test.go b/pkg/admission/plugin/webhook/admission_test.go index 5124cb3a0..ae4205bb7 100644 --- a/pkg/admission/plugin/webhook/admission_test.go +++ b/pkg/admission/plugin/webhook/admission_test.go @@ -39,15 +39,15 @@ import ( ) type fakeHookSource struct { - hooks []registrationv1alpha1.ExternalAdmissionHook + hooks []registrationv1alpha1.Webhook err error } -func (f *fakeHookSource) ExternalAdmissionHooks() (*registrationv1alpha1.ExternalAdmissionHookConfiguration, error) { +func (f *fakeHookSource) Webhooks() (*registrationv1alpha1.ValidatingWebhookConfiguration, error) { if f.err != nil { return nil, f.err } - return ®istrationv1alpha1.ExternalAdmissionHookConfiguration{ExternalAdmissionHooks: f.hooks}, nil + return ®istrationv1alpha1.ValidatingWebhookConfiguration{Webhooks: f.hooks}, nil } func (f *fakeHookSource) Run(stopCh <-chan struct{}) {} @@ -137,8 +137,8 @@ func TestAdmit(t *testing.T) { expectAllow bool errorContains string } - ccfg := func(urlPath string) registrationv1alpha1.AdmissionHookClientConfig { - return registrationv1alpha1.AdmissionHookClientConfig{ + ccfg := func(urlPath string) registrationv1alpha1.WebhookClientConfig { + return registrationv1alpha1.WebhookClientConfig{ Service: registrationv1alpha1.ServiceReference{ Name: "webhook-test", Namespace: "default", @@ -163,7 +163,7 @@ func TestAdmit(t *testing.T) { table := map[string]test{ "no match": { hookSource: fakeHookSource{ - hooks: []registrationv1alpha1.ExternalAdmissionHook{{ + hooks: []registrationv1alpha1.Webhook{{ Name: "nomatch", ClientConfig: ccfg("disallow"), Rules: []registrationv1alpha1.RuleWithOperations{{ @@ -175,7 +175,7 @@ func TestAdmit(t *testing.T) { }, "match & allow": { hookSource: fakeHookSource{ - hooks: []registrationv1alpha1.ExternalAdmissionHook{{ + hooks: []registrationv1alpha1.Webhook{{ Name: "allow", ClientConfig: ccfg("allow"), Rules: matchEverythingRules, @@ -185,7 +185,7 @@ func TestAdmit(t *testing.T) { }, "match & disallow": { hookSource: fakeHookSource{ - hooks: []registrationv1alpha1.ExternalAdmissionHook{{ + hooks: []registrationv1alpha1.Webhook{{ Name: "disallow", ClientConfig: ccfg("disallow"), Rules: matchEverythingRules, @@ -195,7 +195,7 @@ func TestAdmit(t *testing.T) { }, "match & disallow ii": { hookSource: fakeHookSource{ - hooks: []registrationv1alpha1.ExternalAdmissionHook{{ + hooks: []registrationv1alpha1.Webhook{{ Name: "disallowReason", ClientConfig: ccfg("disallowReason"), Rules: matchEverythingRules, @@ -205,7 +205,7 @@ func TestAdmit(t *testing.T) { }, "match & fail (but allow because fail open)": { hookSource: fakeHookSource{ - hooks: []registrationv1alpha1.ExternalAdmissionHook{{ + hooks: []registrationv1alpha1.Webhook{{ Name: "internalErr A", ClientConfig: ccfg("internalErr"), Rules: matchEverythingRules, @@ -226,7 +226,7 @@ func TestAdmit(t *testing.T) { }, "match & fail (but disallow because fail closed on nil)": { hookSource: fakeHookSource{ - hooks: []registrationv1alpha1.ExternalAdmissionHook{{ + hooks: []registrationv1alpha1.Webhook{{ Name: "internalErr A", ClientConfig: ccfg("internalErr"), Rules: matchEverythingRules, @@ -244,7 +244,7 @@ func TestAdmit(t *testing.T) { }, "match & fail (but fail because fail closed)": { hookSource: fakeHookSource{ - hooks: []registrationv1alpha1.ExternalAdmissionHook{{ + hooks: []registrationv1alpha1.Webhook{{ Name: "internalErr A", ClientConfig: ccfg("internalErr"), Rules: matchEverythingRules, From e57a4d504db34837b9cbb543ed6cc23d3f4dbee5 Mon Sep 17 00:00:00 2001 From: mbohlool Date: Tue, 7 Nov 2017 12:42:06 -0800 Subject: [PATCH 2/4] Update generated files Kubernetes-commit: cb43840492b383f4e1b87d7108d51c6439e1dad5 --- pkg/admission/configuration/BUILD | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/admission/configuration/BUILD b/pkg/admission/configuration/BUILD index d2cb75d9f..e7702b9b0 100644 --- a/pkg/admission/configuration/BUILD +++ b/pkg/admission/configuration/BUILD @@ -10,8 +10,8 @@ go_test( name = "go_default_test", srcs = [ "configuration_manager_test.go", - "external_admission_hook_manager_test.go", "initializer_manager_test.go", + "validating_webhook_manager_test.go", ], importpath = "k8s.io/apiserver/pkg/admission/configuration", library = ":go_default_library", @@ -29,8 +29,8 @@ go_library( name = "go_default_library", srcs = [ "configuration_manager.go", - "external_admission_hook_manager.go", "initializer_manager.go", + "validating_webhook_manager.go", ], importpath = "k8s.io/apiserver/pkg/admission/configuration", deps = [ From 2aa55c4d47f3c95f467dae77edb6d9cd518b4fff Mon Sep 17 00:00:00 2001 From: mbohlool Date: Tue, 7 Nov 2017 12:49:19 -0800 Subject: [PATCH 3/4] Add MutatingWebhookConfiguration type Kubernetes-commit: fc5a613c17c81fdda54158d58a19bd6089ae9882 --- .../configuration/mutating_webhook_manager.go | 101 ++++++++++++++++++ .../mutating_webhook_manager_test.go | 40 +++++++ 2 files changed, 141 insertions(+) create mode 100644 pkg/admission/configuration/mutating_webhook_manager.go create mode 100644 pkg/admission/configuration/mutating_webhook_manager_test.go diff --git a/pkg/admission/configuration/mutating_webhook_manager.go b/pkg/admission/configuration/mutating_webhook_manager.go new file mode 100644 index 000000000..0f5b7bd91 --- /dev/null +++ b/pkg/admission/configuration/mutating_webhook_manager.go @@ -0,0 +1,101 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package configuration + +import ( + "fmt" + "reflect" + "sort" + + "github.com/golang/glog" + + "k8s.io/api/admissionregistration/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type MutatingWebhookConfigurationLister interface { + List(opts metav1.ListOptions) (*v1alpha1.MutatingWebhookConfigurationList, error) +} + +// MutatingWebhookConfigurationManager collects the mutating webhook objects so that they can be called. +type MutatingWebhookConfigurationManager struct { + *poller +} + +func NewMutatingWebhookConfigurationManager(c MutatingWebhookConfigurationLister) *MutatingWebhookConfigurationManager { + getFn := func() (runtime.Object, error) { + list, err := c.List(metav1.ListOptions{}) + if err != nil { + if errors.IsNotFound(err) || errors.IsForbidden(err) { + glog.V(5).Infof("MutatingWebhookConfiguration are disabled due to an error: %v", err) + return nil, ErrDisabled + } + return nil, err + } + return mergeMutatingWebhookConfigurations(list), nil + } + + return &MutatingWebhookConfigurationManager{ + newPoller(getFn), + } +} + +// Webhooks returns the merged MutatingWebhookConfiguration. +func (im *MutatingWebhookConfigurationManager) Webhooks() (*v1alpha1.MutatingWebhookConfiguration, error) { + configuration, err := im.poller.configuration() + if err != nil { + return nil, err + } + mutatingWebhookConfiguration, ok := configuration.(*v1alpha1.MutatingWebhookConfiguration) + if !ok { + return nil, fmt.Errorf("expected type %v, got type %v", reflect.TypeOf(mutatingWebhookConfiguration), reflect.TypeOf(configuration)) + } + return mutatingWebhookConfiguration, nil +} + +func (im *MutatingWebhookConfigurationManager) Run(stopCh <-chan struct{}) { + im.poller.Run(stopCh) +} + +func mergeMutatingWebhookConfigurations( + list *v1alpha1.MutatingWebhookConfigurationList, +) *v1alpha1.MutatingWebhookConfiguration { + configurations := append([]v1alpha1.MutatingWebhookConfiguration{}, list.Items...) + var ret v1alpha1.MutatingWebhookConfiguration + // The internal order of webhooks for each configuration is provided by the user + // but configurations themselves can be in any order. As we are going to run these + // webhooks in serial, they are sorted here to have a deterministic order. + sort.Sort(byName(configurations)) + for _, c := range configurations { + ret.Webhooks = append(ret.Webhooks, c.Webhooks...) + } + return &ret +} + +// byName sorts MutatingWebhookConfiguration by name. These objects are all in +// cluster namespace (aka no namespace) thus they all have unique names. +type byName []v1alpha1.MutatingWebhookConfiguration + +func (x byName) Len() int { return len(x) } + +func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } + +func (x byName) Less(i, j int) bool { + return x[i].ObjectMeta.Name < x[j].ObjectMeta.Name +} diff --git a/pkg/admission/configuration/mutating_webhook_manager_test.go b/pkg/admission/configuration/mutating_webhook_manager_test.go new file mode 100644 index 000000000..1cbf2d0d1 --- /dev/null +++ b/pkg/admission/configuration/mutating_webhook_manager_test.go @@ -0,0 +1,40 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package configuration + +import ( + "testing" + + "k8s.io/api/admissionregistration/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +type disabledMutatingWebhookConfigLister struct{} + +func (l *disabledMutatingWebhookConfigLister) List(options metav1.ListOptions) (*v1alpha1.MutatingWebhookConfigurationList, error) { + return nil, errors.NewNotFound(schema.GroupResource{Group: "admissionregistration", Resource: "MutatingWebhookConfigurations"}, "") +} +func TestMutatingWebhookConfigDisabled(t *testing.T) { + manager := NewMutatingWebhookConfigurationManager(&disabledMutatingWebhookConfigLister{}) + manager.sync() + _, err := manager.Webhooks() + if err.Error() != ErrDisabled.Error() { + t.Errorf("expected %v, got %v", ErrDisabled, err) + } +} From db766abbf74239ab2d5692df341866fa670a8d0c Mon Sep 17 00:00:00 2001 From: mbohlool Date: Tue, 7 Nov 2017 17:29:01 -0800 Subject: [PATCH 4/4] Update generated files for MutatingWebhookConfiguration Kubernetes-commit: 4568e0530c53df81d1bbd5e700daca041a1d8439 --- pkg/admission/configuration/BUILD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/admission/configuration/BUILD b/pkg/admission/configuration/BUILD index e7702b9b0..5d1242a41 100644 --- a/pkg/admission/configuration/BUILD +++ b/pkg/admission/configuration/BUILD @@ -11,6 +11,7 @@ go_test( srcs = [ "configuration_manager_test.go", "initializer_manager_test.go", + "mutating_webhook_manager_test.go", "validating_webhook_manager_test.go", ], importpath = "k8s.io/apiserver/pkg/admission/configuration", @@ -30,6 +31,7 @@ go_library( srcs = [ "configuration_manager.go", "initializer_manager.go", + "mutating_webhook_manager.go", "validating_webhook_manager.go", ], importpath = "k8s.io/apiserver/pkg/admission/configuration",