From e19257f2ec87d8091defb7935bb3a161fbb229d0 Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Wed, 15 Nov 2017 13:00:24 +0100 Subject: [PATCH] admission/webhook: move webhook initializer into plugin --- cmd/kube-apiserver/app/BUILD | 1 + cmd/kube-apiserver/app/server.go | 18 +++-- pkg/kubeapiserver/admission/BUILD | 7 +- pkg/kubeapiserver/admission/initializer.go | 46 ++--------- .../{init_test.go => initializer_test.go} | 27 +------ plugin/pkg/admission/gc/gc_admission_test.go | 2 +- .../admission/limitranger/admission_test.go | 2 +- .../namespace/autoprovision/admission_test.go | 2 +- .../namespace/exists/admission_test.go | 2 +- .../podnodeselector/admission_test.go | 2 +- .../admission_test.go | 2 +- .../src/k8s.io/apiserver/pkg/admission/BUILD | 1 + .../plugin/webhook/initializer/BUILD | 37 +++++++++ .../plugin/webhook/initializer/initializer.go | 76 +++++++++++++++++++ .../webhook/initializer/initializer_test.go | 54 +++++++++++++ 15 files changed, 194 insertions(+), 85 deletions(-) rename pkg/kubeapiserver/admission/{init_test.go => initializer_test.go} (69%) create mode 100644 staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer/BUILD create mode 100644 staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer/initializer.go create mode 100644 staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer/initializer_test.go diff --git a/cmd/kube-apiserver/app/BUILD b/cmd/kube-apiserver/app/BUILD index eef2ad11751..ffb9d520c30 100644 --- a/cmd/kube-apiserver/app/BUILD +++ b/cmd/kube-apiserver/app/BUILD @@ -61,6 +61,7 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", "//vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library", + "//vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer:go_default_library", "//vendor/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", "//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//vendor/k8s.io/apiserver/pkg/server:go_default_library", diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index e3450aea48b..c327f48bb2e 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -55,13 +55,16 @@ import ( aggregatorapiserver "k8s.io/kube-aggregator/pkg/apiserver" openapi "k8s.io/kube-openapi/pkg/common" + webhookinit "k8s.io/apiserver/pkg/admission/plugin/webhook/initializer" "k8s.io/apiserver/pkg/storage/etcd3/preflight" clientgoinformers "k8s.io/client-go/informers" clientgoclientset "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" "k8s.io/kubernetes/cmd/kube-apiserver/app/options" "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/batch" + api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/networking" "k8s.io/kubernetes/pkg/apis/storage" @@ -86,8 +89,6 @@ import ( "k8s.io/kubernetes/pkg/version" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap" - "k8s.io/client-go/rest" - api "k8s.io/kubernetes/pkg/apis/core" _ "k8s.io/kubernetes/pkg/util/reflector/prometheus" // for reflector metric registration _ "k8s.io/kubernetes/pkg/util/workqueue/prometheus" // for workqueue metric registration ) @@ -462,7 +463,7 @@ func BuildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transp return ret, err }) } - pluginInitializer, err := BuildAdmissionPluginInitializer( + pluginInitializers, err := BuildAdmissionPluginInitializers( s, client, sharedInformers, @@ -478,7 +479,7 @@ func BuildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transp versionedInformers, kubeClientConfig, legacyscheme.Scheme, - pluginInitializer) + pluginInitializers...) if err != nil { return nil, nil, nil, nil, nil, fmt.Errorf("failed to initialize admission: %v", err) } @@ -486,8 +487,8 @@ func BuildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transp return genericConfig, sharedInformers, versionedInformers, insecureServingOptions, serviceResolver, nil } -// BuildAdmissionPluginInitializer constructs the admission plugin initializer -func BuildAdmissionPluginInitializer(s *options.ServerRunOptions, client internalclientset.Interface, sharedInformers informers.SharedInformerFactory, serviceResolver aggregatorapiserver.ServiceResolver, webhookAuthWrapper webhookconfig.AuthenticationInfoResolverWrapper) (admission.PluginInitializer, error) { +// BuildAdmissionPluginInitializers constructs the admission plugin initializer +func BuildAdmissionPluginInitializers(s *options.ServerRunOptions, client internalclientset.Interface, sharedInformers informers.SharedInformerFactory, serviceResolver aggregatorapiserver.ServiceResolver, webhookAuthWrapper webhookconfig.AuthenticationInfoResolverWrapper) ([]admission.PluginInitializer, error) { var cloudConfig []byte if s.CloudProvider.CloudConfigFile != "" { @@ -503,9 +504,10 @@ func BuildAdmissionPluginInitializer(s *options.ServerRunOptions, client interna quotaConfiguration := quotainstall.NewQuotaConfigurationForAdmission() - pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, cloudConfig, restMapper, quotaConfiguration, webhookAuthWrapper, serviceResolver) + kubePluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, sharedInformers, cloudConfig, restMapper, quotaConfiguration) + webhookPluginInitializer := webhookinit.NewPluginInitializer(webhookAuthWrapper, serviceResolver) - return pluginInitializer, nil + return []admission.PluginInitializer{webhookPluginInitializer, kubePluginInitializer}, nil } // BuildAuthenticator constructs the authenticator diff --git a/pkg/kubeapiserver/admission/BUILD b/pkg/kubeapiserver/admission/BUILD index ec2d84cafcd..b3ec0cb6f9f 100644 --- a/pkg/kubeapiserver/admission/BUILD +++ b/pkg/kubeapiserver/admission/BUILD @@ -8,13 +8,10 @@ load( go_test( name = "go_default_test", - srcs = ["init_test.go"], + srcs = ["initializer_test.go"], importpath = "k8s.io/kubernetes/pkg/kubeapiserver/admission", library = ":go_default_library", - deps = [ - "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", - "//vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library", - ], + deps = ["//vendor/k8s.io/apiserver/pkg/admission:go_default_library"], ) go_library( diff --git a/pkg/kubeapiserver/admission/initializer.go b/pkg/kubeapiserver/admission/initializer.go index 826ce74322f..0a7903227c7 100644 --- a/pkg/kubeapiserver/admission/initializer.go +++ b/pkg/kubeapiserver/admission/initializer.go @@ -17,8 +17,6 @@ limitations under the License. package admission import ( - "net/url" - "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apiserver/pkg/admission" webhookconfig "k8s.io/apiserver/pkg/admission/plugin/webhook/config" @@ -59,25 +57,7 @@ type WantsQuotaConfiguration interface { admission.InitializationValidator } -// WantsServiceResolver defines a fuction that accepts a ServiceResolver for -// admission plugins that need to make calls to services. -type WantsServiceResolver interface { - SetServiceResolver(webhookconfig.ServiceResolver) -} - -// ServiceResolver knows how to convert a service reference into an actual -// location. -type ServiceResolver interface { - ResolveEndpoint(namespace, name string) (*url.URL, error) -} - -// WantsAuthenticationInfoResolverWrapper defines a function that wraps the standard AuthenticationInfoResolver -// to allow the apiserver to control what is returned as auth info -type WantsAuthenticationInfoResolverWrapper interface { - SetAuthenticationInfoResolverWrapper(webhookconfig.AuthenticationInfoResolverWrapper) - admission.InitializationValidator -} - +// PluginInitializer is used for initialization of the Kubernetes specific admission plugins. type PluginInitializer struct { internalClient internalclientset.Interface externalClient clientset.Interface @@ -101,17 +81,13 @@ func NewPluginInitializer( cloudConfig []byte, restMapper meta.RESTMapper, quotaConfiguration quota.Configuration, - authenticationInfoResolverWrapper webhookconfig.AuthenticationInfoResolverWrapper, - serviceResolver webhookconfig.ServiceResolver, ) *PluginInitializer { return &PluginInitializer{ - internalClient: internalClient, - informers: sharedInformers, - cloudConfig: cloudConfig, - restMapper: restMapper, - quotaConfiguration: quotaConfiguration, - authenticationInfoResolverWrapper: authenticationInfoResolverWrapper, - serviceResolver: serviceResolver, + internalClient: internalClient, + informers: sharedInformers, + cloudConfig: cloudConfig, + restMapper: restMapper, + quotaConfiguration: quotaConfiguration, } } @@ -137,14 +113,4 @@ func (i *PluginInitializer) Initialize(plugin admission.Interface) { if wants, ok := plugin.(WantsQuotaConfiguration); ok { wants.SetQuotaConfiguration(i.quotaConfiguration) } - - if wants, ok := plugin.(WantsServiceResolver); ok { - wants.SetServiceResolver(i.serviceResolver) - } - - if wants, ok := plugin.(WantsAuthenticationInfoResolverWrapper); ok { - if i.authenticationInfoResolverWrapper != nil { - wants.SetAuthenticationInfoResolverWrapper(i.authenticationInfoResolverWrapper) - } - } } diff --git a/pkg/kubeapiserver/admission/init_test.go b/pkg/kubeapiserver/admission/initializer_test.go similarity index 69% rename from pkg/kubeapiserver/admission/init_test.go rename to pkg/kubeapiserver/admission/initializer_test.go index 910f03f94a2..b88021d8a69 100644 --- a/pkg/kubeapiserver/admission/init_test.go +++ b/pkg/kubeapiserver/admission/initializer_test.go @@ -17,11 +17,9 @@ limitations under the License. package admission import ( - "net/url" "testing" "k8s.io/apiserver/pkg/admission" - "k8s.io/apiserver/pkg/admission/plugin/webhook/config" ) type doNothingAdmission struct{} @@ -41,7 +39,7 @@ func (self *WantsCloudConfigAdmissionPlugin) SetCloudConfig(cloudConfig []byte) func TestCloudConfigAdmissionPlugin(t *testing.T) { cloudConfig := []byte("cloud-configuration") - initializer := NewPluginInitializer(nil, nil, cloudConfig, nil, nil, nil, nil) + initializer := NewPluginInitializer(nil, nil, cloudConfig, nil, nil) wantsCloudConfigAdmission := &WantsCloudConfigAdmissionPlugin{} initializer.Initialize(wantsCloudConfigAdmission) @@ -49,26 +47,3 @@ func TestCloudConfigAdmissionPlugin(t *testing.T) { t.Errorf("Expected cloud config to be initialized but found nil") } } - -type fakeServiceResolver struct{} - -func (f *fakeServiceResolver) ResolveEndpoint(namespace, name string) (*url.URL, error) { - return nil, nil -} - -type serviceWanter struct { - doNothingAdmission - got ServiceResolver -} - -func (s *serviceWanter) SetServiceResolver(sr config.ServiceResolver) { s.got = sr } - -func TestWantsServiceResolver(t *testing.T) { - sw := &serviceWanter{} - fsr := &fakeServiceResolver{} - i := NewPluginInitializer(nil, nil, nil, nil, nil, nil, fsr) - i.Initialize(sw) - if got, ok := sw.got.(*fakeServiceResolver); !ok || got != fsr { - t.Errorf("plumbing fail - %v %v#", ok, got) - } -} diff --git a/plugin/pkg/admission/gc/gc_admission_test.go b/plugin/pkg/admission/gc/gc_admission_test.go index 818220f3d27..db805c9b704 100644 --- a/plugin/pkg/admission/gc/gc_admission_test.go +++ b/plugin/pkg/admission/gc/gc_admission_test.go @@ -87,7 +87,7 @@ func newGCPermissionsEnforcement() (*gcPermissionsEnforcement, error) { } genericPluginInitializer := initializer.New(nil, nil, fakeAuthorizer{}, nil) - pluginInitializer := kubeadmission.NewPluginInitializer(nil, nil, nil, legacyscheme.Registry.RESTMapper(), nil, nil, nil) + pluginInitializer := kubeadmission.NewPluginInitializer(nil, nil, nil, legacyscheme.Registry.RESTMapper(), nil) initializersChain := admission.PluginInitializers{} initializersChain = append(initializersChain, genericPluginInitializer) initializersChain = append(initializersChain, pluginInitializer) diff --git a/plugin/pkg/admission/limitranger/admission_test.go b/plugin/pkg/admission/limitranger/admission_test.go index 2e864ba36d7..a19930b6856 100644 --- a/plugin/pkg/admission/limitranger/admission_test.go +++ b/plugin/pkg/admission/limitranger/admission_test.go @@ -760,7 +760,7 @@ func newHandlerForTest(c clientset.Interface) (*LimitRanger, informers.SharedInf if err != nil { return nil, f, err } - pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil, nil, nil, nil) + pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil, nil) pluginInitializer.Initialize(handler) err = admission.ValidateInitialization(handler) return handler, f, err diff --git a/plugin/pkg/admission/namespace/autoprovision/admission_test.go b/plugin/pkg/admission/namespace/autoprovision/admission_test.go index 57e444b6946..5ec7cdf2fe6 100644 --- a/plugin/pkg/admission/namespace/autoprovision/admission_test.go +++ b/plugin/pkg/admission/namespace/autoprovision/admission_test.go @@ -38,7 +38,7 @@ import ( func newHandlerForTest(c clientset.Interface) (admission.MutationInterface, informers.SharedInformerFactory, error) { f := informers.NewSharedInformerFactory(c, 5*time.Minute) handler := NewProvision() - pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil, nil, nil, nil) + pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil, nil) pluginInitializer.Initialize(handler) err := admission.ValidateInitialization(handler) return handler, f, err diff --git a/plugin/pkg/admission/namespace/exists/admission_test.go b/plugin/pkg/admission/namespace/exists/admission_test.go index d040b7e2135..6cfc2d96e8b 100644 --- a/plugin/pkg/admission/namespace/exists/admission_test.go +++ b/plugin/pkg/admission/namespace/exists/admission_test.go @@ -37,7 +37,7 @@ import ( 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) + pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil, nil) pluginInitializer.Initialize(handler) err := admission.ValidateInitialization(handler) return handler, f, err diff --git a/plugin/pkg/admission/podnodeselector/admission_test.go b/plugin/pkg/admission/podnodeselector/admission_test.go index cc2c730e03a..2f77359317c 100644 --- a/plugin/pkg/admission/podnodeselector/admission_test.go +++ b/plugin/pkg/admission/podnodeselector/admission_test.go @@ -253,7 +253,7 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) { func newHandlerForTest(c clientset.Interface) (*podNodeSelector, informers.SharedInformerFactory, error) { f := informers.NewSharedInformerFactory(c, 5*time.Minute) handler := NewPodNodeSelector(nil) - pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil, nil, nil, nil) + pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil, nil) pluginInitializer.Initialize(handler) err := admission.ValidateInitialization(handler) return handler, f, err diff --git a/plugin/pkg/admission/podtolerationrestriction/admission_test.go b/plugin/pkg/admission/podtolerationrestriction/admission_test.go index 4a669c62ce3..45b1cb9478a 100644 --- a/plugin/pkg/admission/podtolerationrestriction/admission_test.go +++ b/plugin/pkg/admission/podtolerationrestriction/admission_test.go @@ -361,7 +361,7 @@ func newHandlerForTest(c clientset.Interface) (*podTolerationsPlugin, informers. return nil, nil, err } handler := NewPodTolerationsPlugin(pluginConfig) - pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil, nil, nil, nil) + pluginInitializer := kubeadmission.NewPluginInitializer(c, f, nil, nil, nil) pluginInitializer.Initialize(handler) err = admission.ValidateInitialization(handler) return handler, f, err diff --git a/staging/src/k8s.io/apiserver/pkg/admission/BUILD b/staging/src/k8s.io/apiserver/pkg/admission/BUILD index 90b3fd250ed..4fe6fd14395 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/admission/BUILD @@ -80,6 +80,7 @@ filegroup( "//staging/src/k8s.io/apiserver/pkg/admission/plugin/namespace/lifecycle:all-srcs", "//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/config:all-srcs", "//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/errors:all-srcs", + "//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer:all-srcs", "//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating:all-srcs", "//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/namespace:all-srcs", "//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/request:all-srcs", diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer/BUILD b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer/BUILD new file mode 100644 index 00000000000..14fa71007c7 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer/BUILD @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = ["initializer.go"], + importpath = "k8s.io/apiserver/pkg/admission/plugin/webhook/initializer", + visibility = ["//visibility:public"], + deps = [ + "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", + "//vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["initializer_test.go"], + importpath = "k8s.io/apiserver/pkg/admission/plugin/webhook/initializer", + library = ":go_default_library", + deps = [ + "//vendor/k8s.io/apiserver/pkg/admission:go_default_library", + "//vendor/k8s.io/apiserver/pkg/admission/plugin/webhook/config:go_default_library", + ], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer/initializer.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer/initializer.go new file mode 100644 index 00000000000..398200b92ca --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer/initializer.go @@ -0,0 +1,76 @@ +/* +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 initializer + +import ( + "net/url" + + "k8s.io/apiserver/pkg/admission" + webhookconfig "k8s.io/apiserver/pkg/admission/plugin/webhook/config" +) + +// WantsServiceResolver defines a fuction that accepts a ServiceResolver for +// admission plugins that need to make calls to services. +type WantsServiceResolver interface { + SetServiceResolver(webhookconfig.ServiceResolver) +} + +// ServiceResolver knows how to convert a service reference into an actual +// location. +type ServiceResolver interface { + ResolveEndpoint(namespace, name string) (*url.URL, error) +} + +// WantsAuthenticationInfoResolverWrapper defines a function that wraps the standard AuthenticationInfoResolver +// to allow the apiserver to control what is returned as auth info +type WantsAuthenticationInfoResolverWrapper interface { + SetAuthenticationInfoResolverWrapper(webhookconfig.AuthenticationInfoResolverWrapper) + admission.InitializationValidator +} + +// PluginInitializer is used for initialization of the webhook admission plugin. +type PluginInitializer struct { + serviceResolver webhookconfig.ServiceResolver + authenticationInfoResolverWrapper webhookconfig.AuthenticationInfoResolverWrapper +} + +var _ admission.PluginInitializer = &PluginInitializer{} + +// NewPluginInitializer constructs new instance of PluginInitializer +func NewPluginInitializer( + authenticationInfoResolverWrapper webhookconfig.AuthenticationInfoResolverWrapper, + serviceResolver webhookconfig.ServiceResolver, +) *PluginInitializer { + return &PluginInitializer{ + authenticationInfoResolverWrapper: authenticationInfoResolverWrapper, + serviceResolver: serviceResolver, + } +} + +// Initialize checks the initialization interfaces implemented by each plugin +// and provide the appropriate initialization data +func (i *PluginInitializer) Initialize(plugin admission.Interface) { + if wants, ok := plugin.(WantsServiceResolver); ok { + wants.SetServiceResolver(i.serviceResolver) + } + + if wants, ok := plugin.(WantsAuthenticationInfoResolverWrapper); ok { + if i.authenticationInfoResolverWrapper != nil { + wants.SetAuthenticationInfoResolverWrapper(i.authenticationInfoResolverWrapper) + } + } +} diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer/initializer_test.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer/initializer_test.go new file mode 100644 index 00000000000..553690d9a58 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/initializer/initializer_test.go @@ -0,0 +1,54 @@ +/* +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 initializer + +import ( + "net/url" + "testing" + + "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/admission/plugin/webhook/config" +) + +type doNothingAdmission struct{} + +func (doNothingAdmission) Admit(a admission.Attributes) error { return nil } +func (doNothingAdmission) Handles(o admission.Operation) bool { return false } +func (doNothingAdmission) Validate() error { return nil } + +type fakeServiceResolver struct{} + +func (f *fakeServiceResolver) ResolveEndpoint(namespace, name string) (*url.URL, error) { + return nil, nil +} + +type serviceWanter struct { + doNothingAdmission + got ServiceResolver +} + +func (s *serviceWanter) SetServiceResolver(sr config.ServiceResolver) { s.got = sr } + +func TestWantsServiceResolver(t *testing.T) { + sw := &serviceWanter{} + fsr := &fakeServiceResolver{} + i := NewPluginInitializer(nil, fsr) + i.Initialize(sw) + if got, ok := sw.got.(*fakeServiceResolver); !ok || got != fsr { + t.Errorf("plumbing fail - %v %v#", ok, got) + } +}