update to inject only the list of excluded resources.

Kubernetes-commit: 6b03166beda6e550ebcbed1bb7d9ca2cc1d94df4
This commit is contained in:
Jiahui Feng 2024-03-05 10:27:35 -08:00 committed by Kubernetes Publisher
parent a86b013fb6
commit 8f8266ef89
4 changed files with 38 additions and 58 deletions

View File

@ -18,8 +18,8 @@ package initializer
import (
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/admission/resourcefilter"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/cel/openapi/resolver"
quota "k8s.io/apiserver/pkg/quota/v1"
@ -91,9 +91,9 @@ type WantsSchemaResolver interface {
admission.InitializationValidator
}
// WantsResourceFilter defines a function which sets the ResourceFilter for
// an admission plugin that needs it.
type WantsResourceFilter interface {
SetResourceFilter(filter resourcefilter.Interface)
// WantsExcludedAdmissionResources defines a function which sets the ExcludedAdmissionResources
// for an admission plugin that needs it.
type WantsExcludedAdmissionResources interface {
SetExcludedAdmissionResources(excludedAdmissionResources []schema.GroupResource)
admission.InitializationValidator
}

View File

@ -21,12 +21,14 @@ import (
"errors"
"fmt"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime/schema"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/admission/initializer"
"k8s.io/apiserver/pkg/admission/plugin/policy/matching"
"k8s.io/apiserver/pkg/admission/resourcefilter"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/informers"
@ -37,6 +39,15 @@ import (
type sourceFactory[H any] func(informers.SharedInformerFactory, kubernetes.Interface, dynamic.Interface, meta.RESTMapper) Source[H]
type dispatcherFactory[H any] func(authorizer.Authorizer, *matching.Matcher) Dispatcher[H]
// admissionResources is the list of resources related to CEL-based admission
// features.
var admissionResources = []schema.GroupResource{
{Group: admissionregistrationv1.GroupName, Resource: "validatingadmissionpolicies"},
{Group: admissionregistrationv1.GroupName, Resource: "validatingadmissionpolicybindings"},
{Group: admissionregistrationv1.GroupName, Resource: "mutatingadmissionpolicies"},
{Group: admissionregistrationv1.GroupName, Resource: "mutatingadmissionpolicybindings"},
}
// AdmissionPolicyManager is an abstract admission plugin with all the
// infrastructure to define Admit or Validate on-top.
type Plugin[H any] struct {
@ -49,14 +60,14 @@ type Plugin[H any] struct {
dispatcher Dispatcher[H]
matcher *matching.Matcher
informerFactory informers.SharedInformerFactory
client kubernetes.Interface
restMapper meta.RESTMapper
dynamicClient dynamic.Interface
resourceFilter resourcefilter.Interface // optional
stopCh <-chan struct{}
authorizer authorizer.Authorizer
enabled bool
informerFactory informers.SharedInformerFactory
client kubernetes.Interface
restMapper meta.RESTMapper
dynamicClient dynamic.Interface
excludedResources sets.Set[schema.GroupResource]
stopCh <-chan struct{}
authorizer authorizer.Authorizer
enabled bool
}
var (
@ -66,7 +77,7 @@ var (
_ initializer.WantsDynamicClient = &Plugin[any]{}
_ initializer.WantsDrainedNotification = &Plugin[any]{}
_ initializer.WantsAuthorizer = &Plugin[any]{}
_ initializer.WantsResourceFilter = &Plugin[any]{}
_ initializer.WantsExcludedAdmissionResources = &Plugin[any]{}
_ admission.InitializationValidator = &Plugin[any]{}
)
@ -79,6 +90,9 @@ func NewPlugin[H any](
Handler: handler,
sourceFactory: sourceFactory,
dispatcherFactory: dispatcherFactory,
// always exclude admission/mutating policies and bindings
excludedResources: sets.New(admissionResources...),
}
}
@ -114,8 +128,8 @@ func (c *Plugin[H]) SetEnabled(enabled bool) {
c.enabled = enabled
}
func (c *Plugin[H]) SetResourceFilter(filter resourcefilter.Interface) {
c.resourceFilter = filter
func (c *Plugin[H]) SetExcludedAdmissionResources(excludedResources []schema.GroupResource) {
c.excludedResources.Insert(excludedResources...)
}
// ValidateInitialization - once clientset and informer factory are provided, creates and starts the admission controller
@ -184,7 +198,7 @@ func (c *Plugin[H]) Dispatch(
) (err error) {
if !c.enabled {
return nil
} else if isPolicyResource(a) || (c.resourceFilter != nil && !c.resourceFilter.ShouldHandle(a)) {
} else if c.shouldIgnoreResource(a) {
return nil
} else if !c.WaitForReady() {
return admission.NewForbidden(a, fmt.Errorf("not yet ready to handle request"))
@ -193,14 +207,9 @@ func (c *Plugin[H]) Dispatch(
return c.dispatcher.Dispatch(ctx, a, o, c.source.Hooks())
}
func isPolicyResource(attr admission.Attributes) bool {
gvk := attr.GetResource()
if gvk.Group == "admissionregistration.k8s.io" {
if gvk.Resource == "validatingadmissionpolicies" || gvk.Resource == "validatingadmissionpolicybindings" {
return true
} else if gvk.Resource == "mutatingadmissionpolicies" || gvk.Resource == "mutatingadmissionpolicybindings" {
return true
}
}
return false
func (c *Plugin[H]) shouldIgnoreResource(attr admission.Attributes) bool {
gvr := attr.GetResource()
// exclusion decision ignores the version.
gr := gvr.GroupResource()
return c.excludedResources.Has(gr)
}

View File

@ -74,7 +74,7 @@ type Plugin struct {
var _ admission.Interface = &Plugin{}
var _ admission.ValidationInterface = &Plugin{}
var _ initializer.WantsFeatures = &Plugin{}
var _ initializer.WantsResourceFilter = &Plugin{}
var _ initializer.WantsExcludedAdmissionResources = &Plugin{}
func NewPlugin(_ io.Reader) *Plugin {
handler := admission.NewHandler(admission.Connect, admission.Create, admission.Delete, admission.Update)

View File

@ -1,29 +0,0 @@
/*
Copyright 2024 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 resourcefilter
import (
"k8s.io/apiserver/pkg/admission"
)
// Interface is a resource filter that takes an Attributes and
// check if it should be handled or ignored by the admission plugin.
type Interface interface {
// ShouldHandle returns true if the admission plugin should handle the request,
// considering the given Attributes, or false otherwise.
ShouldHandle(admission.Attributes) bool
}