From 2c54877cbaafaa88de440369aad4f46467937410 Mon Sep 17 00:00:00 2001 From: Andy Goldstein Date: Mon, 24 Apr 2023 14:41:13 -0400 Subject: [PATCH] Finish wiring validating admission policy Signed-off-by: Andy Goldstein --- pkg/admission/initializers/initializer.go | 17 +++++++++++++ pkg/admission/initializers/interfaces.go | 7 ++++++ .../validating_admission_policy.go | 24 +++++++++++++++---- pkg/server/config.go | 1 + pkg/server/options/options.go | 5 ++++ 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/pkg/admission/initializers/initializer.go b/pkg/admission/initializers/initializer.go index 82acba70cfc..b4853d0dac3 100644 --- a/pkg/admission/initializers/initializer.go +++ b/pkg/admission/initializers/initializer.go @@ -17,6 +17,7 @@ limitations under the License. package initializers import ( + kcpdynamic "github.com/kcp-dev/client-go/dynamic" kcpkubernetesinformers "github.com/kcp-dev/client-go/informers" kcpkubernetesclientset "github.com/kcp-dev/client-go/kubernetes" @@ -165,3 +166,19 @@ func (i *serverShutdownChannelInitializer) Initialize(plugin admission.Interface wants.SetServerShutdownChannel(i.ch) } } + +type dynamicClusterClientInitializer struct { + dynamicClusterClient kcpdynamic.ClusterInterface +} + +func NewDynamicClusterClientInitializer(dynamicClusterClient kcpdynamic.ClusterInterface) *dynamicClusterClientInitializer { + return &dynamicClusterClientInitializer{ + dynamicClusterClient: dynamicClusterClient, + } +} + +func (i *dynamicClusterClientInitializer) Initialize(plugin admission.Interface) { + if wants, ok := plugin.(WantsDynamicClusterClient); ok { + wants.SetDynamicClusterClient(i.dynamicClusterClient) + } +} diff --git a/pkg/admission/initializers/interfaces.go b/pkg/admission/initializers/interfaces.go index 7985c686536..37cfe381622 100644 --- a/pkg/admission/initializers/interfaces.go +++ b/pkg/admission/initializers/interfaces.go @@ -17,6 +17,7 @@ limitations under the License. package initializers import ( + kcpdynamic "github.com/kcp-dev/client-go/dynamic" kcpkubernetesinformers "github.com/kcp-dev/client-go/informers" kcpkubernetesclientset "github.com/kcp-dev/client-go/kubernetes" @@ -60,3 +61,9 @@ type WantsDeepSARClient interface { type WantsServerShutdownChannel interface { SetServerShutdownChannel(<-chan struct{}) } + +// WantsDynamicClusterClient is an interface that should be implemented by admission plugins that need a dynamic cluster +// client. +type WantsDynamicClusterClient interface { + SetDynamicClusterClient(clusterInterface kcpdynamic.ClusterInterface) +} diff --git a/pkg/admission/validatingadmissionpolicy/validating_admission_policy.go b/pkg/admission/validatingadmissionpolicy/validating_admission_policy.go index 579ed17eb00..00d72885416 100644 --- a/pkg/admission/validatingadmissionpolicy/validating_admission_policy.go +++ b/pkg/admission/validatingadmissionpolicy/validating_admission_policy.go @@ -27,11 +27,10 @@ import ( "github.com/kcp-dev/logicalcluster/v3" "k8s.io/apiserver/pkg/admission" + "k8s.io/apiserver/pkg/admission/initializer" "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy" - "k8s.io/apiserver/pkg/dynamichack" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/client-go/discovery/cached/memory" - "k8s.io/client-go/dynamic" "k8s.io/client-go/restmapper" "k8s.io/component-base/featuregate" "k8s.io/klog/v2" @@ -53,7 +52,10 @@ func Register(plugins *admission.Plugins) { } func NewKubeValidatingAdmissionPolicy() *KubeValidatingAdmissionPolicy { - return &KubeValidatingAdmissionPolicy{} + return &KubeValidatingAdmissionPolicy{ + Handler: admission.NewHandler(admission.Connect, admission.Create, admission.Delete, admission.Update), + delegates: make(map[logicalcluster.Name]*stoppableValidatingAdmissionPolicy), + } } type KubeValidatingAdmissionPolicy struct { @@ -77,6 +79,9 @@ var _ admission.ValidationInterface = &KubeValidatingAdmissionPolicy{} var _ = initializers.WantsKcpInformers(&KubeValidatingAdmissionPolicy{}) var _ = initializers.WantsKubeClusterClient(&KubeValidatingAdmissionPolicy{}) var _ = initializers.WantsServerShutdownChannel(&KubeValidatingAdmissionPolicy{}) +var _ = initializers.WantsDynamicClusterClient(&KubeValidatingAdmissionPolicy{}) +var _ = initializer.WantsFeatures(&KubeValidatingAdmissionPolicy{}) +var _ = admission.InitializationValidator(&KubeValidatingAdmissionPolicy{}) func (k *KubeValidatingAdmissionPolicy) SetKubeClusterClient(kubeClusterClient kcpkubernetesclientset.ClusterInterface) { k.kubeClusterClient = kubeClusterClient @@ -87,14 +92,23 @@ func (k *KubeValidatingAdmissionPolicy) SetKcpInformers(local, global kcpinforme } func (k *KubeValidatingAdmissionPolicy) SetKubeInformers(local, global kcpkubernetesinformers.SharedInformerFactory) { + k.kubeSharedInformerFactory = local } func (k *KubeValidatingAdmissionPolicy) SetServerShutdownChannel(ch <-chan struct{}) { k.serverDone = ch } -func (k *KubeValidatingAdmissionPolicy) SetDynamicClient(c dynamic.Interface) { - k.dynamicClusterClient = dynamichack.Unwrap(c) +func (k *KubeValidatingAdmissionPolicy) SetDynamicClusterClient(c kcpdynamic.ClusterInterface) { + k.dynamicClusterClient = c +} + +func (k *KubeValidatingAdmissionPolicy) InspectFeatureGates(featureGates featuregate.FeatureGate) { + k.featureGates = featureGates +} + +func (k *KubeValidatingAdmissionPolicy) ValidateInitialization() error { + return nil } func (k *KubeValidatingAdmissionPolicy) Validate(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error { diff --git a/pkg/server/config.go b/pkg/server/config.go index def1fcddec7..46d59f8ef39 100644 --- a/pkg/server/config.go +++ b/pkg/server/config.go @@ -480,6 +480,7 @@ func NewConfig(opts kcpserveroptions.CompletedOptions) (*Config, error) { // with the default secure port, when the config is later completed. kcpadmissioninitializers.NewKubeQuotaConfigurationInitializer(quotaConfiguration), kcpadmissioninitializers.NewServerShutdownInitializer(c.quotaAdmissionStopCh), + kcpadmissioninitializers.NewDynamicClusterClientInitializer(c.DynamicClusterClient), } c.ShardBaseURL = func() string { diff --git a/pkg/server/options/options.go b/pkg/server/options/options.go index 0398f3e27ec..d9a6166b328 100644 --- a/pkg/server/options/options.go +++ b/pkg/server/options/options.go @@ -136,6 +136,11 @@ func NewOptions(rootDir string) *Options { // turn on the watch cache o.GenericControlPlane.Etcd.EnableWatchCache = true + // Turn on admissionregistration for validating admission policy + if err := o.GenericControlPlane.APIEnablement.RuntimeConfig.Set("admissionregistration.k8s.io/v1alpha1=true"); err != nil { + panic(fmt.Errorf("error setting APIEnablement: %w", err)) + } + return o }