From a98af4267eb63bdec9b1cb5c217e0aad2a4f0836 Mon Sep 17 00:00:00 2001 From: David Eads Date: Mon, 2 Oct 2017 11:06:05 -0400 Subject: [PATCH 1/2] UPSTREAM: : allow a filter function on admission registration --- .../staging/src/k8s.io/apiserver/pkg/admission/patch.go | 9 +++++++++ .../src/k8s.io/apiserver/pkg/admission/plugins.go | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 vendor/k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/admission/patch.go diff --git a/vendor/k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/admission/patch.go b/vendor/k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/admission/patch.go new file mode 100644 index 000000000000..748bed00fbb1 --- /dev/null +++ b/vendor/k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/admission/patch.go @@ -0,0 +1,9 @@ +package admission + +var ( + // FactoryFilterFn allows the injection of a global filter on all admission factory function. This allows + // us to inject a filtering function for things like config rewriting just before construction. + FactoryFilterFn func(Factory) Factory = func(delegate Factory) Factory { + return delegate + } +) diff --git a/vendor/k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/admission/plugins.go b/vendor/k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/admission/plugins.go index dd1368d4ddd9..0e422f990c1c 100644 --- a/vendor/k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/admission/plugins.go +++ b/vendor/k8s.io/kubernetes/staging/src/k8s.io/apiserver/pkg/admission/plugins.go @@ -98,7 +98,7 @@ func (ps *Plugins) getPlugin(name string, config io.Reader) (Interface, bool, er return nil, true, nil } - ret, err := f(config2) + ret, err := FactoryFilterFn(f)(config2) return ret, true, err } From e357b7dc702ca7b56e0887125d887fbb5e56285b Mon Sep 17 00:00:00 2001 From: David Eads Date: Mon, 2 Oct 2017 11:23:47 -0400 Subject: [PATCH 2/2] filter out 'turn this on' config structs --- .../server/origin/admission/chain_builder.go | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/pkg/cmd/server/origin/admission/chain_builder.go b/pkg/cmd/server/origin/admission/chain_builder.go index 99f9147846dd..08e0c277b158 100644 --- a/pkg/cmd/server/origin/admission/chain_builder.go +++ b/pkg/cmd/server/origin/admission/chain_builder.go @@ -1,6 +1,9 @@ package admission import ( + "bytes" + "io" + "io/ioutil" "net" "reflect" "strings" @@ -16,6 +19,7 @@ import ( oadmission "github.com/openshift/origin/pkg/cmd/server/admission" configapi "github.com/openshift/origin/pkg/cmd/server/api" + configlatest "github.com/openshift/origin/pkg/cmd/server/api/latest" "github.com/openshift/origin/pkg/cmd/util/pluginconfig" imageadmission "github.com/openshift/origin/pkg/image/admission" imagepolicy "github.com/openshift/origin/pkg/image/admission/imagepolicy/api" @@ -351,3 +355,50 @@ func dedupe(input []string) []string { } return result } + +func init() { + // add a filter that will remove DefaultAdmissionConfig + admission.FactoryFilterFn = filterEnableAdmissionConfigs +} + +func filterEnableAdmissionConfigs(delegate admission.Factory) admission.Factory { + return func(config io.Reader) (admission.Interface, error) { + config1, config2, err := splitStream(config) + if err != nil { + return nil, err + } + // if the config isn't a DefaultAdmissionConfig, then assume we're enabled (we were called after all) + // if the config *is* a DefaultAdmissionConfig and it explicitly said + obj, err := configlatest.ReadYAML(config1) + // if we can't read it, let the plugin deal with it + if err != nil { + return delegate(config2) + } + // if nothing was there, let the plugin deal with it + if obj == nil { + return delegate(config2) + } + // if it wasn't a DefaultAdmissionConfig object, let the plugin deal with it + if _, ok := obj.(*configapi.DefaultAdmissionConfig); !ok { + return delegate(config2) + } + + // if it was a DefaultAdmissionConfig, then it must have said "enabled" and it wasn't really meant for the + // admission plugin + return delegate(nil) + } +} + +// splitStream reads the stream bytes and constructs two copies of it. +func splitStream(config io.Reader) (io.Reader, io.Reader, error) { + if config == nil || reflect.ValueOf(config).IsNil() { + return nil, nil, nil + } + + configBytes, err := ioutil.ReadAll(config) + if err != nil { + return nil, nil, err + } + + return bytes.NewBuffer(configBytes), bytes.NewBuffer(configBytes), nil +}