From 45dc4adcc3bb8fa67350e8a6e9cf513b11970a67 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 Kubernetes-commit: e19257f2ec87d8091defb7935bb3a161fbb229d0 --- pkg/admission/BUILD | 1 + .../plugin/webhook/initializer/BUILD | 37 +++++++++ .../plugin/webhook/initializer/initializer.go | 76 +++++++++++++++++++ .../webhook/initializer/initializer_test.go | 54 +++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 pkg/admission/plugin/webhook/initializer/BUILD create mode 100644 pkg/admission/plugin/webhook/initializer/initializer.go create mode 100644 pkg/admission/plugin/webhook/initializer/initializer_test.go diff --git a/pkg/admission/BUILD b/pkg/admission/BUILD index 90b3fd250..4fe6fd143 100644 --- a/pkg/admission/BUILD +++ b/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/pkg/admission/plugin/webhook/initializer/BUILD b/pkg/admission/plugin/webhook/initializer/BUILD new file mode 100644 index 000000000..14fa71007 --- /dev/null +++ b/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/pkg/admission/plugin/webhook/initializer/initializer.go b/pkg/admission/plugin/webhook/initializer/initializer.go new file mode 100644 index 000000000..398200b92 --- /dev/null +++ b/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/pkg/admission/plugin/webhook/initializer/initializer_test.go b/pkg/admission/plugin/webhook/initializer/initializer_test.go new file mode 100644 index 000000000..553690d9a --- /dev/null +++ b/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) + } +}