From 1ae856484b8a827b7ce6018ddfa103493a2cb97d Mon Sep 17 00:00:00 2001 From: David Eads Date: Wed, 14 Feb 2018 09:27:25 -0500 Subject: [PATCH] add an admission decorator chain --- .../src/k8s.io/apiserver/pkg/admission/BUILD | 1 + .../apiserver/pkg/admission/decorator.go | 39 +++++++++++++++++++ .../k8s.io/apiserver/pkg/admission/plugins.go | 4 +- .../apiserver/pkg/server/options/admission.go | 2 +- 4 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 staging/src/k8s.io/apiserver/pkg/admission/decorator.go diff --git a/staging/src/k8s.io/apiserver/pkg/admission/BUILD b/staging/src/k8s.io/apiserver/pkg/admission/BUILD index 4af97de951a..e0f0a5bbf99 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/admission/BUILD @@ -32,6 +32,7 @@ go_library( "attributes.go", "chain.go", "config.go", + "decorator.go", "errors.go", "handler.go", "interfaces.go", diff --git a/staging/src/k8s.io/apiserver/pkg/admission/decorator.go b/staging/src/k8s.io/apiserver/pkg/admission/decorator.go new file mode 100644 index 00000000000..a4b0b28b552 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/admission/decorator.go @@ -0,0 +1,39 @@ +/* +Copyright 2018 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 admission + +type Decorator interface { + Decorate(handler Interface, name string) Interface +} + +type DecoratorFunc func(handler Interface, name string) Interface + +func (d DecoratorFunc) Decorate(handler Interface, name string) Interface { + return d(handler, name) +} + +type Decorators []Decorator + +// Decorate applies the decorator in inside-out order, i.e. the first decorator in the slice is first applied to the given handler. +func (d Decorators) Decorate(handler Interface, name string) Interface { + result := handler + for _, d := range d { + result = d.Decorate(result, name) + } + + return result +} diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugins.go b/staging/src/k8s.io/apiserver/pkg/admission/plugins.go index 05e321ffc17..8369a684a45 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugins.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugins.go @@ -122,8 +122,6 @@ func splitStream(config io.Reader) (io.Reader, io.Reader, error) { return bytes.NewBuffer(configBytes), bytes.NewBuffer(configBytes), nil } -type Decorator func(handler Interface, name string) Interface - // NewFromPlugins returns an admission.Interface that will enforce admission control decisions of all // the given plugins. func (ps *Plugins) NewFromPlugins(pluginNames []string, configProvider ConfigProvider, pluginInitializer PluginInitializer, decorator Decorator) (Interface, error) { @@ -140,7 +138,7 @@ func (ps *Plugins) NewFromPlugins(pluginNames []string, configProvider ConfigPro } if plugin != nil { if decorator != nil { - handlers = append(handlers, decorator(plugin, pluginName)) + handlers = append(handlers, decorator.Decorate(plugin, pluginName)) } else { handlers = append(handlers, plugin) } diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/admission.go b/staging/src/k8s.io/apiserver/pkg/server/options/admission.go index 180ba4ffdc3..7dd0b641c57 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/admission.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/admission.go @@ -141,7 +141,7 @@ func (a *AdmissionOptions) ApplyTo( pluginInitializers = append(pluginInitializers, genericInitializer) initializersChain = append(initializersChain, pluginInitializers...) - admissionChain, err := a.Plugins.NewFromPlugins(pluginNames, pluginsConfigProvider, initializersChain, admissionmetrics.WithControllerMetrics) + admissionChain, err := a.Plugins.NewFromPlugins(pluginNames, pluginsConfigProvider, initializersChain, admission.DecoratorFunc(admissionmetrics.WithControllerMetrics)) if err != nil { return err }