Promote ValidatingAdmissionPolicy to GA.
Kubernetes-commit: de506ce7ac9981c8253b2f818478bb4093fb7bb6
This commit is contained in:
parent
ccdc9f3ae6
commit
be9c733e9d
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package initializer
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/client-go/dynamic"
|
||||
|
@ -32,6 +33,7 @@ type pluginInitializer struct {
|
|||
authorizer authorizer.Authorizer
|
||||
featureGates featuregate.FeatureGate
|
||||
stopCh <-chan struct{}
|
||||
restMapper meta.RESTMapper
|
||||
}
|
||||
|
||||
// New creates an instance of admission plugins initializer.
|
||||
|
@ -44,6 +46,7 @@ func New(
|
|||
authz authorizer.Authorizer,
|
||||
featureGates featuregate.FeatureGate,
|
||||
stopCh <-chan struct{},
|
||||
restMapper meta.RESTMapper,
|
||||
) pluginInitializer {
|
||||
return pluginInitializer{
|
||||
externalClient: extClientset,
|
||||
|
@ -52,6 +55,7 @@ func New(
|
|||
authorizer: authz,
|
||||
featureGates: featureGates,
|
||||
stopCh: stopCh,
|
||||
restMapper: restMapper,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,6 +87,9 @@ func (i pluginInitializer) Initialize(plugin admission.Interface) {
|
|||
if wants, ok := plugin.(WantsAuthorizer); ok {
|
||||
wants.SetAuthorizer(i.authorizer)
|
||||
}
|
||||
if wants, ok := plugin.(WantsRESTMapper); ok {
|
||||
wants.SetRESTMapper(i.restMapper)
|
||||
}
|
||||
}
|
||||
|
||||
var _ admission.PluginInitializer = pluginInitializer{}
|
||||
|
|
|
@ -21,6 +21,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/admission/initializer"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
|
@ -32,7 +34,7 @@ import (
|
|||
// TestWantsAuthorizer ensures that the authorizer is injected
|
||||
// when the WantsAuthorizer interface is implemented by a plugin.
|
||||
func TestWantsAuthorizer(t *testing.T) {
|
||||
target := initializer.New(nil, nil, nil, &TestAuthorizer{}, nil, nil)
|
||||
target := initializer.New(nil, nil, nil, &TestAuthorizer{}, nil, nil, nil)
|
||||
wantAuthorizerAdmission := &WantAuthorizerAdmission{}
|
||||
target.Initialize(wantAuthorizerAdmission)
|
||||
if wantAuthorizerAdmission.auth == nil {
|
||||
|
@ -44,7 +46,7 @@ func TestWantsAuthorizer(t *testing.T) {
|
|||
// when the WantsExternalKubeClientSet interface is implemented by a plugin.
|
||||
func TestWantsExternalKubeClientSet(t *testing.T) {
|
||||
cs := &fake.Clientset{}
|
||||
target := initializer.New(cs, nil, nil, &TestAuthorizer{}, nil, nil)
|
||||
target := initializer.New(cs, nil, nil, &TestAuthorizer{}, nil, nil, nil)
|
||||
wantExternalKubeClientSet := &WantExternalKubeClientSet{}
|
||||
target.Initialize(wantExternalKubeClientSet)
|
||||
if wantExternalKubeClientSet.cs != cs {
|
||||
|
@ -57,7 +59,7 @@ func TestWantsExternalKubeClientSet(t *testing.T) {
|
|||
func TestWantsExternalKubeInformerFactory(t *testing.T) {
|
||||
cs := &fake.Clientset{}
|
||||
sf := informers.NewSharedInformerFactory(cs, time.Duration(1)*time.Second)
|
||||
target := initializer.New(cs, nil, sf, &TestAuthorizer{}, nil, nil)
|
||||
target := initializer.New(cs, nil, sf, &TestAuthorizer{}, nil, nil, nil)
|
||||
wantExternalKubeInformerFactory := &WantExternalKubeInformerFactory{}
|
||||
target.Initialize(wantExternalKubeInformerFactory)
|
||||
if wantExternalKubeInformerFactory.sf != sf {
|
||||
|
@ -69,7 +71,7 @@ func TestWantsExternalKubeInformerFactory(t *testing.T) {
|
|||
// when the WantsShutdownSignal interface is implemented by a plugin.
|
||||
func TestWantsShutdownNotification(t *testing.T) {
|
||||
stopCh := make(chan struct{})
|
||||
target := initializer.New(nil, nil, nil, &TestAuthorizer{}, nil, stopCh)
|
||||
target := initializer.New(nil, nil, nil, &TestAuthorizer{}, nil, stopCh, nil)
|
||||
wantDrainedNotification := &WantDrainedNotification{}
|
||||
target.Initialize(wantDrainedNotification)
|
||||
if wantDrainedNotification.stopCh == nil {
|
||||
|
@ -149,3 +151,59 @@ type TestAuthorizer struct{}
|
|||
func (t *TestAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
}
|
||||
|
||||
func TestRESTMapperAdmissionPlugin(t *testing.T) {
|
||||
initializer := initializer.New(nil, nil, nil, &TestAuthorizer{}, nil, nil, &doNothingRESTMapper{})
|
||||
wantsRESTMapperAdmission := &WantsRESTMapperAdmissionPlugin{}
|
||||
initializer.Initialize(wantsRESTMapperAdmission)
|
||||
|
||||
if wantsRESTMapperAdmission.mapper == nil {
|
||||
t.Errorf("Expected REST mapper to be initialized but found nil")
|
||||
}
|
||||
}
|
||||
|
||||
type WantsRESTMapperAdmissionPlugin struct {
|
||||
doNothingAdmission
|
||||
doNothingPluginInitialization
|
||||
mapper meta.RESTMapper
|
||||
}
|
||||
|
||||
func (p *WantsRESTMapperAdmissionPlugin) SetRESTMapper(mapper meta.RESTMapper) {
|
||||
p.mapper = mapper
|
||||
}
|
||||
|
||||
type doNothingRESTMapper struct{}
|
||||
|
||||
func (doNothingRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
|
||||
return schema.GroupVersionKind{}, nil
|
||||
}
|
||||
func (doNothingRESTMapper) KindsFor(resource schema.GroupVersionResource) ([]schema.GroupVersionKind, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (doNothingRESTMapper) ResourceFor(input schema.GroupVersionResource) (schema.GroupVersionResource, error) {
|
||||
return schema.GroupVersionResource{}, nil
|
||||
}
|
||||
func (doNothingRESTMapper) ResourcesFor(input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (doNothingRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*meta.RESTMapping, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (doNothingRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*meta.RESTMapping, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (doNothingRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
type doNothingAdmission struct{}
|
||||
|
||||
func (doNothingAdmission) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
return nil
|
||||
}
|
||||
func (doNothingAdmission) Handles(o admission.Operation) bool { return false }
|
||||
func (doNothingAdmission) Validate() error { return nil }
|
||||
|
||||
type doNothingPluginInitialization struct{}
|
||||
|
||||
func (doNothingPluginInitialization) ValidateInitialization() error { return nil }
|
||||
|
|
|
@ -53,7 +53,7 @@ func newHandlerForTestWithClock(c clientset.Interface, cacheClock clock.Clock) (
|
|||
if err != nil {
|
||||
return nil, f, err
|
||||
}
|
||||
pluginInitializer := kubeadmission.New(c, nil, f, nil, nil, nil)
|
||||
pluginInitializer := kubeadmission.New(c, nil, f, nil, nil, nil, nil)
|
||||
pluginInitializer.Initialize(handler)
|
||||
err = admission.ValidateInitialization(handler)
|
||||
return handler, f, err
|
||||
|
|
|
@ -17,15 +17,15 @@ limitations under the License.
|
|||
package generic
|
||||
|
||||
import (
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
"k8s.io/api/admissionregistration/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
type PolicyAccessor interface {
|
||||
GetName() string
|
||||
GetNamespace() string
|
||||
GetParamKind() *v1beta1.ParamKind
|
||||
GetMatchConstraints() *v1beta1.MatchResources
|
||||
GetParamKind() *v1.ParamKind
|
||||
GetMatchConstraints() *v1.MatchResources
|
||||
}
|
||||
|
||||
type BindingAccessor interface {
|
||||
|
@ -36,7 +36,7 @@ type BindingAccessor interface {
|
|||
// which is cluster-scoped, so namespace is usually left blank.
|
||||
// But we leave the door open to add a namespaced vesion in the future
|
||||
GetPolicyName() types.NamespacedName
|
||||
GetParamRef() *v1beta1.ParamRef
|
||||
GetParamRef() *v1.ParamRef
|
||||
|
||||
GetMatchResources() *v1beta1.MatchResources
|
||||
GetMatchResources() *v1.MatchResources
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
"k8s.io/api/admissionregistration/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -217,10 +217,10 @@ func (d *policyDispatcher[P, B, E]) Dispatch(ctx context.Context, a admission.At
|
|||
// configuration. If the policy-binding has no param configuration, it
|
||||
// returns a single-element list with a nil param.
|
||||
func CollectParams(
|
||||
paramKind *v1beta1.ParamKind,
|
||||
paramKind *v1.ParamKind,
|
||||
paramInformer informers.GenericInformer,
|
||||
paramScope meta.RESTScope,
|
||||
paramRef *v1beta1.ParamRef,
|
||||
paramRef *v1.ParamRef,
|
||||
namespace string,
|
||||
) ([]runtime.Object, error) {
|
||||
// If definition has paramKind, paramRef is required in binding.
|
||||
|
@ -326,7 +326,7 @@ func CollectParams(
|
|||
}
|
||||
|
||||
// Apply fail action for params not found case
|
||||
if len(params) == 0 && paramRef.ParameterNotFoundAction != nil && *paramRef.ParameterNotFoundAction == v1beta1.DenyAction {
|
||||
if len(params) == 0 && paramRef.ParameterNotFoundAction != nil && *paramRef.ParameterNotFoundAction == v1.DenyAction {
|
||||
return nil, errors.New("no params found for policy binding with `Deny` parameterNotFoundAction")
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ package generic
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
|
@ -89,7 +89,7 @@ func (c *matcher) GetNamespace(name string) (*corev1.Namespace, error) {
|
|||
var _ matching.MatchCriteria = &matchCriteria{}
|
||||
|
||||
type matchCriteria struct {
|
||||
constraints *v1beta1.MatchResources
|
||||
constraints *admissionregistrationv1.MatchResources
|
||||
}
|
||||
|
||||
// GetParsedNamespaceSelector returns the converted LabelSelector which implements labels.Selector
|
||||
|
@ -103,6 +103,6 @@ func (m *matchCriteria) GetParsedObjectSelector() (labels.Selector, error) {
|
|||
}
|
||||
|
||||
// GetMatchResources returns the matchConstraints
|
||||
func (m *matchCriteria) GetMatchResources() v1beta1.MatchResources {
|
||||
func (m *matchCriteria) GetMatchResources() admissionregistrationv1.MatchResources {
|
||||
return *m.constraints
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
"k8s.io/api/admissionregistration/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
@ -110,7 +110,7 @@ func TestPolicySourceHasSyncedInitialList(t *testing.T) {
|
|||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "policy2",
|
||||
},
|
||||
ParamKind: &v1beta1.ParamKind{
|
||||
ParamKind: &v1.ParamKind{
|
||||
APIVersion: "policy.example.com/v1",
|
||||
Kind: "FakeParam",
|
||||
},
|
||||
|
@ -177,7 +177,7 @@ type FakePolicy struct {
|
|||
metav1.TypeMeta
|
||||
metav1.ObjectMeta
|
||||
|
||||
ParamKind *v1beta1.ParamKind
|
||||
ParamKind *v1.ParamKind
|
||||
}
|
||||
|
||||
var _ generic.PolicyAccessor = &FakePolicy{}
|
||||
|
@ -199,11 +199,11 @@ func (fp *FakePolicy) GetNamespace() string {
|
|||
return fp.Namespace
|
||||
}
|
||||
|
||||
func (fp *FakePolicy) GetParamKind() *v1beta1.ParamKind {
|
||||
func (fp *FakePolicy) GetParamKind() *v1.ParamKind {
|
||||
return fp.ParamKind
|
||||
}
|
||||
|
||||
func (fb *FakePolicy) GetMatchConstraints() *v1beta1.MatchResources {
|
||||
func (fb *FakePolicy) GetMatchConstraints() *v1.MatchResources {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -221,11 +221,11 @@ func (fb *FakeBinding) GetPolicyName() types.NamespacedName {
|
|||
}
|
||||
}
|
||||
|
||||
func (fb *FakeBinding) GetMatchResources() *v1beta1.MatchResources {
|
||||
func (fb *FakeBinding) GetMatchResources() *v1.MatchResources {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fb *FakeBinding) GetParamRef() *v1beta1.ParamRef {
|
||||
func (fb *FakeBinding) GetParamRef() *v1.ParamRef {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -216,6 +216,7 @@ func NewPolicyTestContext[P, B runtime.Object, E Evaluator](
|
|||
fakeAuthorizer{},
|
||||
featureGate,
|
||||
testContext.Done(),
|
||||
fakeRestMapper,
|
||||
)
|
||||
genericInitializer.Initialize(plugin)
|
||||
plugin.SetRESTMapper(fakeRestMapper)
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
v1 "k8s.io/api/admissionregistration/v1"
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
|
@ -36,7 +35,7 @@ type MatchCriteria interface {
|
|||
namespace.NamespaceSelectorProvider
|
||||
object.ObjectSelectorProvider
|
||||
|
||||
GetMatchResources() v1beta1.MatchResources
|
||||
GetMatchResources() v1.MatchResources
|
||||
}
|
||||
|
||||
// Matcher decides if a request matches against matchCriteria
|
||||
|
@ -121,7 +120,7 @@ func (m *Matcher) Matches(attr admission.Attributes, o admission.ObjectInterface
|
|||
return true, matchResource, matchKind, nil
|
||||
}
|
||||
|
||||
func matchesResourceRules(namedRules []v1beta1.NamedRuleWithOperations, matchPolicy *v1beta1.MatchPolicyType, attr admission.Attributes, o admission.ObjectInterfaces) (bool, schema.GroupVersionResource, schema.GroupVersionKind, error) {
|
||||
func matchesResourceRules(namedRules []v1.NamedRuleWithOperations, matchPolicy *v1.MatchPolicyType, attr admission.Attributes, o admission.ObjectInterfaces) (bool, schema.GroupVersionResource, schema.GroupVersionKind, error) {
|
||||
matchKind := attr.GetKind()
|
||||
matchResource := attr.GetResource()
|
||||
|
||||
|
@ -150,7 +149,7 @@ func matchesResourceRules(namedRules []v1beta1.NamedRuleWithOperations, matchPol
|
|||
|
||||
// if match policy is undefined or exact, don't perform fuzzy matching
|
||||
// note that defaulting to fuzzy matching is set by the API
|
||||
if matchPolicy == nil || *matchPolicy == v1beta1.Exact {
|
||||
if matchPolicy == nil || *matchPolicy == v1.Exact {
|
||||
return false, schema.GroupVersionResource{}, schema.GroupVersionKind{}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
"testing"
|
||||
|
||||
v1 "k8s.io/api/admissionregistration/v1"
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -38,10 +37,10 @@ import (
|
|||
var _ MatchCriteria = &fakeCriteria{}
|
||||
|
||||
type fakeCriteria struct {
|
||||
matchResources v1beta1.MatchResources
|
||||
matchResources v1.MatchResources
|
||||
}
|
||||
|
||||
func (fc *fakeCriteria) GetMatchResources() v1beta1.MatchResources {
|
||||
func (fc *fakeCriteria) GetMatchResources() v1.MatchResources {
|
||||
return fc.matchResources
|
||||
}
|
||||
|
||||
|
@ -65,8 +64,8 @@ func TestMatcher(t *testing.T) {
|
|||
a := &Matcher{namespaceMatcher: &namespace.Matcher{}, objectMatcher: &object.Matcher{}}
|
||||
|
||||
allScopes := v1.AllScopes
|
||||
exactMatch := v1beta1.Exact
|
||||
equivalentMatch := v1beta1.Equivalent
|
||||
exactMatch := v1.Exact
|
||||
equivalentMatch := v1.Equivalent
|
||||
|
||||
mapper := runtime.NewEquivalentResourceRegistryWithIdentity(func(resource schema.GroupResource) string {
|
||||
if resource.Resource == "deployments" {
|
||||
|
@ -95,7 +94,7 @@ func TestMatcher(t *testing.T) {
|
|||
testcases := []struct {
|
||||
name string
|
||||
|
||||
criteria *v1beta1.MatchResources
|
||||
criteria *v1.MatchResources
|
||||
attrs admission.Attributes
|
||||
|
||||
expectMatches bool
|
||||
|
@ -105,17 +104,17 @@ func TestMatcher(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
name: "no rules (just write)",
|
||||
criteria: &v1beta1.MatchResources{NamespaceSelector: &metav1.LabelSelector{}, ResourceRules: []v1beta1.NamedRuleWithOperations{}},
|
||||
criteria: &v1.MatchResources{NamespaceSelector: &metav1.LabelSelector{}, ResourceRules: []v1.NamedRuleWithOperations{}},
|
||||
attrs: admission.NewAttributesRecord(nil, nil, gvk("apps", "v1", "Deployment"), "ns", "name", gvr("apps", "v1", "deployments"), "", admission.Create, &metav1.CreateOptions{}, false, nil),
|
||||
expectMatches: false,
|
||||
},
|
||||
{
|
||||
name: "wildcard rule, match as requested",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"*"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -126,21 +125,21 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, prefer exact match",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -151,16 +150,16 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, match miss",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -170,17 +169,17 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, exact match miss",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
MatchPolicy: &exactMatch,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -190,17 +189,17 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, equivalent match, prefer extensions",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
MatchPolicy: &equivalentMatch,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -212,17 +211,17 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, equivalent match, prefer apps",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
MatchPolicy: &equivalentMatch,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -235,21 +234,21 @@ func TestMatcher(t *testing.T) {
|
|||
|
||||
{
|
||||
name: "specific rules, subresource prefer exact match",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -260,16 +259,16 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, subresource match miss",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -279,17 +278,17 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, subresource exact match miss",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
MatchPolicy: &exactMatch,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -299,17 +298,17 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, subresource equivalent match, prefer extensions",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
MatchPolicy: &equivalentMatch,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -321,17 +320,17 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, subresource equivalent match, prefer apps",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
MatchPolicy: &equivalentMatch,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -343,12 +342,12 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, prefer exact match and name match",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
ResourceNames: []string{"name"},
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -359,12 +358,12 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, prefer exact match and name match miss",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
ResourceNames: []string{"wrong-name"},
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -374,13 +373,13 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, subresource equivalent match, prefer extensions and name match",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
MatchPolicy: &equivalentMatch,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
ResourceNames: []string{"name"},
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -392,13 +391,13 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "specific rules, subresource equivalent match, prefer extensions and name match miss",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
MatchPolicy: &equivalentMatch,
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
ResourceNames: []string{"wrong-name"},
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -408,17 +407,17 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "exclude resource match on miss",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"*"}, Scope: &allScopes},
|
||||
},
|
||||
}},
|
||||
ExcludeResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ExcludeResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -430,17 +429,17 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "exclude resource miss on match",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"*"}, Scope: &allScopes},
|
||||
},
|
||||
}},
|
||||
ExcludeResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ExcludeResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -451,11 +450,11 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "treat empty ResourceRules as match",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ExcludeResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
ExcludeResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -466,23 +465,23 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "treat non-empty ResourceRules as no match",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{}},
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{}},
|
||||
},
|
||||
attrs: admission.NewAttributesRecord(nil, nil, gvk("autoscaling", "v1", "Scale"), "ns", "name", gvr("apps", "v1", "deployments"), "", admission.Create, &metav1.CreateOptions{}, false, nil),
|
||||
expectMatches: false,
|
||||
},
|
||||
{
|
||||
name: "erroring namespace selector on otherwise non-matching rule doesn't error",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{MatchExpressions: []metav1.LabelSelectorRequirement{{Key: "key ", Operator: "In", Values: []string{"bad value"}}}},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"deployments"}},
|
||||
Operations: []v1beta1.OperationType{"*"},
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"deployments"}},
|
||||
Operations: []v1.OperationType{"*"},
|
||||
},
|
||||
}},
|
||||
},
|
||||
|
@ -492,13 +491,13 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "erroring namespace selector on otherwise matching rule errors",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{MatchExpressions: []metav1.LabelSelectorRequirement{{Key: "key", Operator: "In", Values: []string{"bad value"}}}},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"pods"}},
|
||||
Operations: []v1beta1.OperationType{"*"},
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"pods"}},
|
||||
Operations: []v1.OperationType{"*"},
|
||||
},
|
||||
}},
|
||||
},
|
||||
|
@ -508,13 +507,13 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "erroring object selector on otherwise non-matching rule doesn't error",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{MatchExpressions: []metav1.LabelSelectorRequirement{{Key: "key", Operator: "In", Values: []string{"bad value"}}}},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"deployments"}},
|
||||
Operations: []v1beta1.OperationType{"*"},
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"deployments"}},
|
||||
Operations: []v1.OperationType{"*"},
|
||||
},
|
||||
}},
|
||||
},
|
||||
|
@ -524,13 +523,13 @@ func TestMatcher(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "erroring object selector on otherwise matching rule errors",
|
||||
criteria: &v1beta1.MatchResources{
|
||||
criteria: &v1.MatchResources{
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{MatchExpressions: []metav1.LabelSelectorRequirement{{Key: "key", Operator: "In", Values: []string{"bad value"}}}},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"pods"}},
|
||||
Operations: []v1beta1.OperationType{"*"},
|
||||
ResourceRules: []v1.NamedRuleWithOperations{{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{APIGroups: []string{"*"}, APIVersions: []string{"*"}, Resources: []string{"pods"}},
|
||||
Operations: []v1.OperationType{"*"},
|
||||
},
|
||||
}},
|
||||
},
|
||||
|
@ -601,7 +600,7 @@ func (f fakeNamespaceLister) Get(name string) (*corev1.Namespace, error) {
|
|||
|
||||
func BenchmarkMatcher(b *testing.B) {
|
||||
allScopes := v1.AllScopes
|
||||
equivalentMatch := v1beta1.Equivalent
|
||||
equivalentMatch := v1.Equivalent
|
||||
|
||||
namespace1Labels := map[string]string{"ns": "ns1"}
|
||||
namespace1 := corev1.Namespace{
|
||||
|
@ -642,19 +641,19 @@ func BenchmarkMatcher(b *testing.B) {
|
|||
nsSelector[fmt.Sprintf("key-%d", i)] = fmt.Sprintf("val-%d", i)
|
||||
}
|
||||
|
||||
mr := v1beta1.MatchResources{
|
||||
mr := v1.MatchResources{
|
||||
MatchPolicy: &equivalentMatch,
|
||||
NamespaceSelector: &metav1.LabelSelector{MatchLabels: nsSelector},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
ResourceRules: []v1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"apps"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
},
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{APIGroups: []string{"extensions"}, APIVersions: []string{"v1beta1"}, Resources: []string{"deployments", "deployments/scale"}, Scope: &allScopes},
|
||||
},
|
||||
|
@ -674,7 +673,7 @@ func BenchmarkMatcher(b *testing.B) {
|
|||
|
||||
func BenchmarkShouldCallHookWithComplexRule(b *testing.B) {
|
||||
allScopes := v1.AllScopes
|
||||
equivalentMatch := v1beta1.Equivalent
|
||||
equivalentMatch := v1.Equivalent
|
||||
|
||||
namespace1Labels := map[string]string{"ns": "ns1"}
|
||||
namespace1 := corev1.Namespace{
|
||||
|
@ -710,16 +709,16 @@ func BenchmarkShouldCallHookWithComplexRule(b *testing.B) {
|
|||
mapper.RegisterKindFor(gvr("apps", "v1beta1", "statefulset"), "scale", gvk("apps", "v1beta1", "Scale"))
|
||||
mapper.RegisterKindFor(gvr("apps", "v1alpha2", "statefulset"), "scale", gvk("apps", "v1beta2", "Scale"))
|
||||
|
||||
mr := v1beta1.MatchResources{
|
||||
mr := v1.MatchResources{
|
||||
MatchPolicy: &equivalentMatch,
|
||||
NamespaceSelector: &metav1.LabelSelector{MatchLabels: map[string]string{"a": "b"}},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{},
|
||||
ResourceRules: []v1.NamedRuleWithOperations{},
|
||||
}
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
rule := v1beta1.NamedRuleWithOperations{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
rule := v1.NamedRuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{fmt.Sprintf("app-%d", i)},
|
||||
|
@ -744,7 +743,7 @@ func BenchmarkShouldCallHookWithComplexRule(b *testing.B) {
|
|||
|
||||
func BenchmarkShouldCallHookWithComplexSelectorAndRule(b *testing.B) {
|
||||
allScopes := v1.AllScopes
|
||||
equivalentMatch := v1beta1.Equivalent
|
||||
equivalentMatch := v1.Equivalent
|
||||
|
||||
namespace1Labels := map[string]string{"ns": "ns1"}
|
||||
namespace1 := corev1.Namespace{
|
||||
|
@ -785,16 +784,16 @@ func BenchmarkShouldCallHookWithComplexSelectorAndRule(b *testing.B) {
|
|||
nsSelector[fmt.Sprintf("key-%d", i)] = fmt.Sprintf("val-%d", i)
|
||||
}
|
||||
|
||||
mr := v1beta1.MatchResources{
|
||||
mr := v1.MatchResources{
|
||||
MatchPolicy: &equivalentMatch,
|
||||
NamespaceSelector: &metav1.LabelSelector{MatchLabels: nsSelector},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{},
|
||||
ResourceRules: []v1.NamedRuleWithOperations{},
|
||||
}
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
rule := v1beta1.NamedRuleWithOperations{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
rule := v1.NamedRuleWithOperations{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Operations: []v1.OperationType{"*"},
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{fmt.Sprintf("app-%d", i)},
|
||||
|
|
|
@ -17,25 +17,25 @@ limitations under the License.
|
|||
package validating
|
||||
|
||||
import (
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
"k8s.io/api/admissionregistration/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apiserver/pkg/admission/plugin/policy/generic"
|
||||
)
|
||||
|
||||
func NewValidatingAdmissionPolicyAccessor(obj *v1beta1.ValidatingAdmissionPolicy) generic.PolicyAccessor {
|
||||
func NewValidatingAdmissionPolicyAccessor(obj *v1.ValidatingAdmissionPolicy) generic.PolicyAccessor {
|
||||
return &validatingAdmissionPolicyAccessor{
|
||||
ValidatingAdmissionPolicy: obj,
|
||||
}
|
||||
}
|
||||
|
||||
func NewValidatingAdmissionPolicyBindingAccessor(obj *v1beta1.ValidatingAdmissionPolicyBinding) generic.BindingAccessor {
|
||||
func NewValidatingAdmissionPolicyBindingAccessor(obj *v1.ValidatingAdmissionPolicyBinding) generic.BindingAccessor {
|
||||
return &validatingAdmissionPolicyBindingAccessor{
|
||||
ValidatingAdmissionPolicyBinding: obj,
|
||||
}
|
||||
}
|
||||
|
||||
type validatingAdmissionPolicyAccessor struct {
|
||||
*v1beta1.ValidatingAdmissionPolicy
|
||||
*v1.ValidatingAdmissionPolicy
|
||||
}
|
||||
|
||||
func (v *validatingAdmissionPolicyAccessor) GetNamespace() string {
|
||||
|
@ -46,16 +46,16 @@ func (v *validatingAdmissionPolicyAccessor) GetName() string {
|
|||
return v.Name
|
||||
}
|
||||
|
||||
func (v *validatingAdmissionPolicyAccessor) GetParamKind() *v1beta1.ParamKind {
|
||||
func (v *validatingAdmissionPolicyAccessor) GetParamKind() *v1.ParamKind {
|
||||
return v.Spec.ParamKind
|
||||
}
|
||||
|
||||
func (v *validatingAdmissionPolicyAccessor) GetMatchConstraints() *v1beta1.MatchResources {
|
||||
func (v *validatingAdmissionPolicyAccessor) GetMatchConstraints() *v1.MatchResources {
|
||||
return v.Spec.MatchConstraints
|
||||
}
|
||||
|
||||
type validatingAdmissionPolicyBindingAccessor struct {
|
||||
*v1beta1.ValidatingAdmissionPolicyBinding
|
||||
*v1.ValidatingAdmissionPolicyBinding
|
||||
}
|
||||
|
||||
func (v *validatingAdmissionPolicyBindingAccessor) GetNamespace() string {
|
||||
|
@ -73,10 +73,10 @@ func (v *validatingAdmissionPolicyBindingAccessor) GetPolicyName() types.Namespa
|
|||
}
|
||||
}
|
||||
|
||||
func (v *validatingAdmissionPolicyBindingAccessor) GetMatchResources() *v1beta1.MatchResources {
|
||||
func (v *validatingAdmissionPolicyBindingAccessor) GetMatchResources() *v1.MatchResources {
|
||||
return v.Spec.MatchResources
|
||||
}
|
||||
|
||||
func (v *validatingAdmissionPolicyBindingAccessor) GetParamRef() *v1beta1.ParamRef {
|
||||
func (v *validatingAdmissionPolicyBindingAccessor) GetParamRef() *v1.ParamRef {
|
||||
return v.Spec.ParamRef
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -61,18 +61,18 @@ var (
|
|||
}
|
||||
|
||||
// Common objects
|
||||
denyPolicy *v1beta1.ValidatingAdmissionPolicy = &v1beta1.ValidatingAdmissionPolicy{
|
||||
denyPolicy *admissionregistrationv1.ValidatingAdmissionPolicy = &admissionregistrationv1.ValidatingAdmissionPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "denypolicy.example.com",
|
||||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
ParamKind: &v1beta1.ParamKind{
|
||||
Spec: admissionregistrationv1.ValidatingAdmissionPolicySpec{
|
||||
ParamKind: &admissionregistrationv1.ParamKind{
|
||||
APIVersion: paramsGVK.GroupVersion().String(),
|
||||
Kind: paramsGVK.Kind,
|
||||
},
|
||||
FailurePolicy: ptrTo(v1beta1.Fail),
|
||||
Validations: []v1beta1.Validation{
|
||||
FailurePolicy: ptrTo(admissionregistrationv1.Fail),
|
||||
Validations: []admissionregistrationv1.Validation{
|
||||
{
|
||||
Expression: "messageId for deny policy",
|
||||
},
|
||||
|
@ -93,61 +93,61 @@ var (
|
|||
},
|
||||
}
|
||||
|
||||
denyBinding *v1beta1.ValidatingAdmissionPolicyBinding = &v1beta1.ValidatingAdmissionPolicyBinding{
|
||||
denyBinding *admissionregistrationv1.ValidatingAdmissionPolicyBinding = &admissionregistrationv1.ValidatingAdmissionPolicyBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "denybinding.example.com",
|
||||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: v1beta1.ValidatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.ValidatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: denyPolicy.Name,
|
||||
ParamRef: &v1beta1.ParamRef{
|
||||
ParamRef: &admissionregistrationv1.ParamRef{
|
||||
Name: fakeParams.GetName(),
|
||||
Namespace: fakeParams.GetNamespace(),
|
||||
// fake object tracker does not populate defaults
|
||||
ParameterNotFoundAction: ptrTo(v1beta1.DenyAction),
|
||||
ParameterNotFoundAction: ptrTo(admissionregistrationv1.DenyAction),
|
||||
},
|
||||
ValidationActions: []v1beta1.ValidationAction{v1beta1.Deny},
|
||||
ValidationActions: []admissionregistrationv1.ValidationAction{admissionregistrationv1.Deny},
|
||||
},
|
||||
}
|
||||
denyBindingWithNoParamRef *v1beta1.ValidatingAdmissionPolicyBinding = &v1beta1.ValidatingAdmissionPolicyBinding{
|
||||
denyBindingWithNoParamRef *admissionregistrationv1.ValidatingAdmissionPolicyBinding = &admissionregistrationv1.ValidatingAdmissionPolicyBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "denybinding.example.com",
|
||||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: v1beta1.ValidatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.ValidatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: denyPolicy.Name,
|
||||
ValidationActions: []v1beta1.ValidationAction{v1beta1.Deny},
|
||||
ValidationActions: []admissionregistrationv1.ValidationAction{admissionregistrationv1.Deny},
|
||||
},
|
||||
}
|
||||
|
||||
denyBindingWithAudit = &v1beta1.ValidatingAdmissionPolicyBinding{
|
||||
denyBindingWithAudit = &admissionregistrationv1.ValidatingAdmissionPolicyBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "denybinding.example.com",
|
||||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: v1beta1.ValidatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.ValidatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: denyPolicy.Name,
|
||||
ValidationActions: []v1beta1.ValidationAction{v1beta1.Audit},
|
||||
ValidationActions: []admissionregistrationv1.ValidationAction{admissionregistrationv1.Audit},
|
||||
},
|
||||
}
|
||||
denyBindingWithWarn = &v1beta1.ValidatingAdmissionPolicyBinding{
|
||||
denyBindingWithWarn = &admissionregistrationv1.ValidatingAdmissionPolicyBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "denybinding.example.com",
|
||||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: v1beta1.ValidatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.ValidatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: denyPolicy.Name,
|
||||
ValidationActions: []v1beta1.ValidationAction{v1beta1.Warn},
|
||||
ValidationActions: []admissionregistrationv1.ValidationAction{admissionregistrationv1.Warn},
|
||||
},
|
||||
}
|
||||
denyBindingWithAll = &v1beta1.ValidatingAdmissionPolicyBinding{
|
||||
denyBindingWithAll = &admissionregistrationv1.ValidatingAdmissionPolicyBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "denybinding.example.com",
|
||||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: v1beta1.ValidatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.ValidatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: denyPolicy.Name,
|
||||
ValidationActions: []v1beta1.ValidationAction{v1beta1.Deny, v1beta1.Warn, v1beta1.Audit},
|
||||
ValidationActions: []admissionregistrationv1.ValidationAction{admissionregistrationv1.Deny, admissionregistrationv1.Warn, admissionregistrationv1.Audit},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
@ -277,7 +277,7 @@ type fakeMatcher struct {
|
|||
BindingMatchFuncs map[types.NamespacedName]func(generic.BindingAccessor, admission.Attributes) bool
|
||||
}
|
||||
|
||||
func (f *fakeMatcher) RegisterDefinition(definition *v1beta1.ValidatingAdmissionPolicy, matchFunc func(generic.PolicyAccessor, admission.Attributes) bool) {
|
||||
func (f *fakeMatcher) RegisterDefinition(definition *admissionregistrationv1.ValidatingAdmissionPolicy, matchFunc func(generic.PolicyAccessor, admission.Attributes) bool) {
|
||||
namespace, name := definition.Namespace, definition.Name
|
||||
key := types.NamespacedName{
|
||||
Name: name,
|
||||
|
@ -292,7 +292,7 @@ func (f *fakeMatcher) RegisterDefinition(definition *v1beta1.ValidatingAdmission
|
|||
}
|
||||
}
|
||||
|
||||
func (f *fakeMatcher) RegisterBinding(binding *v1beta1.ValidatingAdmissionPolicyBinding, matchFunc func(generic.BindingAccessor, admission.Attributes) bool) {
|
||||
func (f *fakeMatcher) RegisterBinding(binding *admissionregistrationv1.ValidatingAdmissionPolicyBinding, matchFunc func(generic.BindingAccessor, admission.Attributes) bool) {
|
||||
namespace, name := binding.Namespace, binding.Name
|
||||
key := types.NamespacedName{
|
||||
Name: name,
|
||||
|
@ -644,19 +644,19 @@ func TestReconfigureBinding(t *testing.T) {
|
|||
}
|
||||
})
|
||||
|
||||
denyBinding2 := &v1beta1.ValidatingAdmissionPolicyBinding{
|
||||
denyBinding2 := &admissionregistrationv1.ValidatingAdmissionPolicyBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "denybinding.example.com",
|
||||
ResourceVersion: "2",
|
||||
},
|
||||
Spec: v1beta1.ValidatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.ValidatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: denyPolicy.Name,
|
||||
ParamRef: &v1beta1.ParamRef{
|
||||
ParamRef: &admissionregistrationv1.ParamRef{
|
||||
Name: fakeParams2.GetName(),
|
||||
Namespace: fakeParams2.GetNamespace(),
|
||||
ParameterNotFoundAction: ptrTo(v1beta1.DenyAction),
|
||||
ParameterNotFoundAction: ptrTo(admissionregistrationv1.DenyAction),
|
||||
},
|
||||
ValidationActions: []v1beta1.ValidationAction{v1beta1.Deny},
|
||||
ValidationActions: []admissionregistrationv1.ValidationAction{admissionregistrationv1.Deny},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -805,7 +805,7 @@ func TestInvalidParamSourceGVK(t *testing.T) {
|
|||
passedParams := make(chan *unstructured.Unstructured)
|
||||
|
||||
badPolicy := *denyPolicy
|
||||
badPolicy.Spec.ParamKind = &v1beta1.ParamKind{
|
||||
badPolicy.Spec.ParamKind = &admissionregistrationv1.ParamKind{
|
||||
APIVersion: paramsGVK.GroupVersion().String(),
|
||||
Kind: "BadParamKind",
|
||||
}
|
||||
|
@ -985,13 +985,13 @@ func TestMultiplePoliciesSharedParamType(t *testing.T) {
|
|||
// Use ConfigMap native-typed param
|
||||
policy1 := *denyPolicy
|
||||
policy1.Name = "denypolicy1.example.com"
|
||||
policy1.Spec = v1beta1.ValidatingAdmissionPolicySpec{
|
||||
ParamKind: &v1beta1.ParamKind{
|
||||
policy1.Spec = admissionregistrationv1.ValidatingAdmissionPolicySpec{
|
||||
ParamKind: &admissionregistrationv1.ParamKind{
|
||||
APIVersion: paramsGVK.GroupVersion().String(),
|
||||
Kind: paramsGVK.Kind,
|
||||
},
|
||||
FailurePolicy: ptrTo(v1beta1.Fail),
|
||||
Validations: []v1beta1.Validation{
|
||||
FailurePolicy: ptrTo(admissionregistrationv1.Fail),
|
||||
Validations: []admissionregistrationv1.Validation{
|
||||
{
|
||||
Expression: "policy1",
|
||||
},
|
||||
|
@ -1000,13 +1000,13 @@ func TestMultiplePoliciesSharedParamType(t *testing.T) {
|
|||
|
||||
policy2 := *denyPolicy
|
||||
policy2.Name = "denypolicy2.example.com"
|
||||
policy2.Spec = v1beta1.ValidatingAdmissionPolicySpec{
|
||||
ParamKind: &v1beta1.ParamKind{
|
||||
policy2.Spec = admissionregistrationv1.ValidatingAdmissionPolicySpec{
|
||||
ParamKind: &admissionregistrationv1.ParamKind{
|
||||
APIVersion: paramsGVK.GroupVersion().String(),
|
||||
Kind: paramsGVK.Kind,
|
||||
},
|
||||
FailurePolicy: ptrTo(v1beta1.Fail),
|
||||
Validations: []v1beta1.Validation{
|
||||
FailurePolicy: ptrTo(admissionregistrationv1.Fail),
|
||||
Validations: []admissionregistrationv1.Validation{
|
||||
{
|
||||
Expression: "policy2",
|
||||
},
|
||||
|
@ -1106,7 +1106,7 @@ func TestNativeTypeParam(t *testing.T) {
|
|||
|
||||
// Use ConfigMap native-typed param
|
||||
nativeTypeParamPolicy := *denyPolicy
|
||||
nativeTypeParamPolicy.Spec.ParamKind = &v1beta1.ParamKind{
|
||||
nativeTypeParamPolicy.Spec.ParamKind = &admissionregistrationv1.ParamKind{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
}
|
||||
|
@ -1208,7 +1208,7 @@ func TestAuditValidationAction(t *testing.T) {
|
|||
expected := []validating.ValidationFailureValue{{
|
||||
ExpressionIndex: 0,
|
||||
Message: "I'm sorry Dave",
|
||||
ValidationActions: []v1beta1.ValidationAction{v1beta1.Audit},
|
||||
ValidationActions: []admissionregistrationv1.ValidationAction{admissionregistrationv1.Audit},
|
||||
Binding: "denybinding.example.com",
|
||||
Policy: noParamSourcePolicy.Name,
|
||||
}}
|
||||
|
@ -1305,7 +1305,7 @@ func TestAllValidationActions(t *testing.T) {
|
|||
expected := []validating.ValidationFailureValue{{
|
||||
ExpressionIndex: 0,
|
||||
Message: "I'm sorry Dave",
|
||||
ValidationActions: []v1beta1.ValidationAction{v1beta1.Deny, v1beta1.Warn, v1beta1.Audit},
|
||||
ValidationActions: []admissionregistrationv1.ValidationAction{admissionregistrationv1.Deny, admissionregistrationv1.Warn, admissionregistrationv1.Audit},
|
||||
Binding: "denybinding.example.com",
|
||||
Policy: noParamSourcePolicy.Name,
|
||||
}}
|
||||
|
@ -1325,13 +1325,13 @@ func TestNamespaceParamRefName(t *testing.T) {
|
|||
|
||||
// Use ConfigMap native-typed param
|
||||
nativeTypeParamPolicy := *denyPolicy
|
||||
nativeTypeParamPolicy.Spec.ParamKind = &v1beta1.ParamKind{
|
||||
nativeTypeParamPolicy.Spec.ParamKind = &admissionregistrationv1.ParamKind{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
}
|
||||
|
||||
namespaceParamBinding := *denyBinding
|
||||
namespaceParamBinding.Spec.ParamRef = &v1beta1.ParamRef{
|
||||
namespaceParamBinding.Spec.ParamRef = &admissionregistrationv1.ParamRef{
|
||||
Name: "replicas-test.example.com",
|
||||
}
|
||||
lock := sync.Mutex{}
|
||||
|
@ -1543,7 +1543,7 @@ func testParamRefCase(t *testing.T, paramIsClusterScoped, nameIsSet, namespaceIs
|
|||
// Create a cluster scoped and a namespace scoped CRD
|
||||
policy := *denyPolicy
|
||||
binding := *denyBinding
|
||||
binding.Spec.ParamRef = &v1beta1.ParamRef{}
|
||||
binding.Spec.ParamRef = &admissionregistrationv1.ParamRef{}
|
||||
paramRef := binding.Spec.ParamRef
|
||||
|
||||
shouldErrorOnClusterScopedRequests := !namespaceIsSet && !paramIsClusterScoped
|
||||
|
@ -1557,12 +1557,12 @@ func testParamRefCase(t *testing.T, paramIsClusterScoped, nameIsSet, namespaceIs
|
|||
otherNonmatchingLabels := labels.Set{"notaffiliated": "no"}
|
||||
|
||||
if paramIsClusterScoped {
|
||||
policy.Spec.ParamKind = &v1beta1.ParamKind{
|
||||
policy.Spec.ParamKind = &admissionregistrationv1.ParamKind{
|
||||
APIVersion: clusterScopedParamsGVK.GroupVersion().String(),
|
||||
Kind: clusterScopedParamsGVK.Kind,
|
||||
}
|
||||
} else {
|
||||
policy.Spec.ParamKind = &v1beta1.ParamKind{
|
||||
policy.Spec.ParamKind = &admissionregistrationv1.ParamKind{
|
||||
APIVersion: paramsGVK.GroupVersion().String(),
|
||||
Kind: paramsGVK.Kind,
|
||||
}
|
||||
|
@ -1581,9 +1581,9 @@ func testParamRefCase(t *testing.T, paramIsClusterScoped, nameIsSet, namespaceIs
|
|||
}
|
||||
|
||||
if denyNotFound {
|
||||
paramRef.ParameterNotFoundAction = ptrTo(v1beta1.DenyAction)
|
||||
paramRef.ParameterNotFoundAction = ptrTo(admissionregistrationv1.DenyAction)
|
||||
} else {
|
||||
paramRef.ParameterNotFoundAction = ptrTo(v1beta1.AllowAction)
|
||||
paramRef.ParameterNotFoundAction = ptrTo(admissionregistrationv1.AllowAction)
|
||||
}
|
||||
|
||||
compiler := &fakeCompiler{}
|
||||
|
@ -1815,20 +1815,20 @@ func TestNamespaceParamRefClusterScopedParamError(t *testing.T) {
|
|||
|
||||
// Use ValidatingAdmissionPolicy for param type since it is cluster-scoped
|
||||
nativeTypeParamPolicy := *denyPolicy
|
||||
nativeTypeParamPolicy.Spec.ParamKind = &v1beta1.ParamKind{
|
||||
nativeTypeParamPolicy.Spec.ParamKind = &admissionregistrationv1.ParamKind{
|
||||
APIVersion: "admissionregistration.k8s.io/v1beta1",
|
||||
Kind: "ValidatingAdmissionPolicy",
|
||||
}
|
||||
|
||||
namespaceParamBinding := *denyBinding
|
||||
namespaceParamBinding.Spec.ParamRef = &v1beta1.ParamRef{
|
||||
namespaceParamBinding.Spec.ParamRef = &admissionregistrationv1.ParamRef{
|
||||
Name: "other-param-to-use-with-no-label.example.com",
|
||||
Namespace: "mynamespace",
|
||||
}
|
||||
|
||||
compiler.RegisterDefinition(&nativeTypeParamPolicy, func(ctx context.Context, matchedResource schema.GroupVersionResource, versionedAttr *admission.VersionedAttributes, versionedParams runtime.Object, namespace *v1.Namespace, runtimeCELCostBudget int64, authz authorizer.Authorizer) validating.ValidateResult {
|
||||
evaluations.Add(1)
|
||||
if _, ok := versionedParams.(*v1beta1.ValidatingAdmissionPolicy); ok {
|
||||
if _, ok := versionedParams.(*admissionregistrationv1.ValidatingAdmissionPolicy); ok {
|
||||
return validating.ValidateResult{
|
||||
Decisions: []validating.PolicyDecision{
|
||||
{
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -59,8 +59,8 @@ func NewDispatcher(
|
|||
// that determined the decision
|
||||
type policyDecisionWithMetadata struct {
|
||||
PolicyDecision
|
||||
Definition *v1beta1.ValidatingAdmissionPolicy
|
||||
Binding *v1beta1.ValidatingAdmissionPolicyBinding
|
||||
Definition *admissionregistrationv1.ValidatingAdmissionPolicy
|
||||
Binding *admissionregistrationv1.ValidatingAdmissionPolicyBinding
|
||||
}
|
||||
|
||||
// Dispatch implements generic.Dispatcher.
|
||||
|
@ -68,21 +68,21 @@ func (c *dispatcher) Dispatch(ctx context.Context, a admission.Attributes, o adm
|
|||
|
||||
var deniedDecisions []policyDecisionWithMetadata
|
||||
|
||||
addConfigError := func(err error, definition *v1beta1.ValidatingAdmissionPolicy, binding *v1beta1.ValidatingAdmissionPolicyBinding) {
|
||||
addConfigError := func(err error, definition *admissionregistrationv1.ValidatingAdmissionPolicy, binding *admissionregistrationv1.ValidatingAdmissionPolicyBinding) {
|
||||
// we always default the FailurePolicy if it is unset and validate it in API level
|
||||
var policy v1beta1.FailurePolicyType
|
||||
var policy admissionregistrationv1.FailurePolicyType
|
||||
if definition.Spec.FailurePolicy == nil {
|
||||
policy = v1beta1.Fail
|
||||
policy = admissionregistrationv1.Fail
|
||||
} else {
|
||||
policy = *definition.Spec.FailurePolicy
|
||||
}
|
||||
|
||||
// apply FailurePolicy specified in ValidatingAdmissionPolicy, the default would be Fail
|
||||
switch policy {
|
||||
case v1beta1.Ignore:
|
||||
case admissionregistrationv1.Ignore:
|
||||
// TODO: add metrics for ignored error here
|
||||
return
|
||||
case v1beta1.Fail:
|
||||
case admissionregistrationv1.Fail:
|
||||
var message string
|
||||
if binding == nil {
|
||||
message = fmt.Errorf("failed to configure policy: %w", err).Error()
|
||||
|
@ -228,17 +228,17 @@ func (c *dispatcher) Dispatch(ctx context.Context, a admission.Attributes, o adm
|
|||
case ActionDeny:
|
||||
for _, action := range binding.Spec.ValidationActions {
|
||||
switch action {
|
||||
case v1beta1.Deny:
|
||||
case admissionregistrationv1.Deny:
|
||||
deniedDecisions = append(deniedDecisions, policyDecisionWithMetadata{
|
||||
Definition: definition,
|
||||
Binding: binding,
|
||||
PolicyDecision: decision,
|
||||
})
|
||||
celmetrics.Metrics.ObserveRejection(ctx, decision.Elapsed, definition.Name, binding.Name, "active")
|
||||
case v1beta1.Audit:
|
||||
case admissionregistrationv1.Audit:
|
||||
publishValidationFailureAnnotation(binding, i, decision, versionedAttr)
|
||||
celmetrics.Metrics.ObserveAudit(ctx, decision.Elapsed, definition.Name, binding.Name, "active")
|
||||
case v1beta1.Warn:
|
||||
case admissionregistrationv1.Warn:
|
||||
warning.AddWarning(ctx, "", fmt.Sprintf("Validation failed for ValidatingAdmissionPolicy '%s' with binding '%s': %s", definition.Name, binding.Name, decision.Message))
|
||||
celmetrics.Metrics.ObserveWarn(ctx, decision.Elapsed, definition.Name, binding.Name, "active")
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ func (c *dispatcher) Dispatch(ctx context.Context, a admission.Attributes, o adm
|
|||
return nil
|
||||
}
|
||||
|
||||
func publishValidationFailureAnnotation(binding *v1beta1.ValidatingAdmissionPolicyBinding, expressionIndex int, decision PolicyDecision, attributes admission.Attributes) {
|
||||
func publishValidationFailureAnnotation(binding *admissionregistrationv1.ValidatingAdmissionPolicyBinding, expressionIndex int, decision PolicyDecision, attributes admission.Attributes) {
|
||||
key := "validation.policy.admission.k8s.io/validation_failure"
|
||||
// Marshal to a list of failures since, in the future, we may need to support multiple failures
|
||||
valueJSON, err := utiljson.Marshal([]ValidationFailureValue{{
|
||||
|
@ -326,11 +326,11 @@ const maxAuditAnnotationValueLength = 10 * 1024
|
|||
// validationFailureValue defines the JSON format of a "validation.policy.admission.k8s.io/validation_failure" audit
|
||||
// annotation value.
|
||||
type ValidationFailureValue struct {
|
||||
Message string `json:"message"`
|
||||
Policy string `json:"policy"`
|
||||
Binding string `json:"binding"`
|
||||
ExpressionIndex int `json:"expressionIndex"`
|
||||
ValidationActions []v1beta1.ValidationAction `json:"validationActions"`
|
||||
Message string `json:"message"`
|
||||
Policy string `json:"policy"`
|
||||
Binding string `json:"binding"`
|
||||
ExpressionIndex int `json:"expressionIndex"`
|
||||
ValidationActions []admissionregistrationv1.ValidationAction `json:"validationActions"`
|
||||
}
|
||||
|
||||
type auditAnnotationCollector struct {
|
||||
|
|
|
@ -21,7 +21,6 @@ import (
|
|||
"io"
|
||||
|
||||
v1 "k8s.io/api/admissionregistration/v1"
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/admission/initializer"
|
||||
|
@ -62,8 +61,8 @@ func Register(plugins *admission.Plugins) {
|
|||
}
|
||||
|
||||
// Plugin is an implementation of admission.Interface.
|
||||
type Policy = v1beta1.ValidatingAdmissionPolicy
|
||||
type PolicyBinding = v1beta1.ValidatingAdmissionPolicyBinding
|
||||
type Policy = v1.ValidatingAdmissionPolicy
|
||||
type PolicyBinding = v1.ValidatingAdmissionPolicyBinding
|
||||
type PolicyEvaluator = Validator
|
||||
type PolicyHook = generic.PolicyHook[*Policy, *PolicyBinding, PolicyEvaluator]
|
||||
|
||||
|
@ -84,8 +83,8 @@ func NewPlugin(_ io.Reader) *Plugin {
|
|||
handler,
|
||||
func(f informers.SharedInformerFactory, client kubernetes.Interface, dynamicClient dynamic.Interface, restMapper meta.RESTMapper) generic.Source[PolicyHook] {
|
||||
return generic.NewPolicySource(
|
||||
f.Admissionregistration().V1beta1().ValidatingAdmissionPolicies().Informer(),
|
||||
f.Admissionregistration().V1beta1().ValidatingAdmissionPolicyBindings().Informer(),
|
||||
f.Admissionregistration().V1().ValidatingAdmissionPolicies().Informer(),
|
||||
f.Admissionregistration().V1().ValidatingAdmissionPolicyBindings().Informer(),
|
||||
NewValidatingAdmissionPolicyAccessor,
|
||||
NewValidatingAdmissionPolicyBindingAccessor,
|
||||
compilePolicy,
|
||||
|
@ -117,7 +116,7 @@ func compilePolicy(policy *Policy) Validator {
|
|||
}
|
||||
optionalVars := cel.OptionalVariableDeclarations{HasParams: hasParam, HasAuthorizer: true}
|
||||
expressionOptionalVars := cel.OptionalVariableDeclarations{HasParams: hasParam, HasAuthorizer: false}
|
||||
failurePolicy := convertv1beta1FailurePolicyTypeTov1FailurePolicyType(policy.Spec.FailurePolicy)
|
||||
failurePolicy := policy.Spec.FailurePolicy
|
||||
var matcher matchconditions.Matcher = nil
|
||||
matchConditions := policy.Spec.MatchConditions
|
||||
|
||||
|
@ -132,31 +131,17 @@ func compilePolicy(policy *Policy) Validator {
|
|||
matcher = matchconditions.NewMatcher(filterCompiler.Compile(matchExpressionAccessors, optionalVars, environment.StoredExpressions), failurePolicy, "policy", "validate", policy.Name)
|
||||
}
|
||||
res := NewValidator(
|
||||
filterCompiler.Compile(convertv1beta1Validations(policy.Spec.Validations), optionalVars, environment.StoredExpressions),
|
||||
filterCompiler.Compile(convertv1Validations(policy.Spec.Validations), optionalVars, environment.StoredExpressions),
|
||||
matcher,
|
||||
filterCompiler.Compile(convertv1beta1AuditAnnotations(policy.Spec.AuditAnnotations), optionalVars, environment.StoredExpressions),
|
||||
filterCompiler.Compile(convertv1beta1MessageExpressions(policy.Spec.Validations), expressionOptionalVars, environment.StoredExpressions),
|
||||
filterCompiler.Compile(convertv1AuditAnnotations(policy.Spec.AuditAnnotations), optionalVars, environment.StoredExpressions),
|
||||
filterCompiler.Compile(convertv1MessageExpressions(policy.Spec.Validations), expressionOptionalVars, environment.StoredExpressions),
|
||||
failurePolicy,
|
||||
)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func convertv1beta1FailurePolicyTypeTov1FailurePolicyType(policyType *v1beta1.FailurePolicyType) *v1.FailurePolicyType {
|
||||
if policyType == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var v1FailPolicy v1.FailurePolicyType
|
||||
if *policyType == v1beta1.Fail {
|
||||
v1FailPolicy = v1.Fail
|
||||
} else if *policyType == v1beta1.Ignore {
|
||||
v1FailPolicy = v1.Ignore
|
||||
}
|
||||
return &v1FailPolicy
|
||||
}
|
||||
|
||||
func convertv1beta1Validations(inputValidations []v1beta1.Validation) []cel.ExpressionAccessor {
|
||||
func convertv1Validations(inputValidations []v1.Validation) []cel.ExpressionAccessor {
|
||||
celExpressionAccessor := make([]cel.ExpressionAccessor, len(inputValidations))
|
||||
for i, validation := range inputValidations {
|
||||
validation := ValidationCondition{
|
||||
|
@ -169,7 +154,7 @@ func convertv1beta1Validations(inputValidations []v1beta1.Validation) []cel.Expr
|
|||
return celExpressionAccessor
|
||||
}
|
||||
|
||||
func convertv1beta1MessageExpressions(inputValidations []v1beta1.Validation) []cel.ExpressionAccessor {
|
||||
func convertv1MessageExpressions(inputValidations []v1.Validation) []cel.ExpressionAccessor {
|
||||
celExpressionAccessor := make([]cel.ExpressionAccessor, len(inputValidations))
|
||||
for i, validation := range inputValidations {
|
||||
if validation.MessageExpression != "" {
|
||||
|
@ -182,7 +167,7 @@ func convertv1beta1MessageExpressions(inputValidations []v1beta1.Validation) []c
|
|||
return celExpressionAccessor
|
||||
}
|
||||
|
||||
func convertv1beta1AuditAnnotations(inputValidations []v1beta1.AuditAnnotation) []cel.ExpressionAccessor {
|
||||
func convertv1AuditAnnotations(inputValidations []v1.AuditAnnotation) []cel.ExpressionAccessor {
|
||||
celExpressionAccessor := make([]cel.ExpressionAccessor, len(inputValidations))
|
||||
for i, validation := range inputValidations {
|
||||
validation := AuditAnnotationCondition{
|
||||
|
@ -194,7 +179,7 @@ func convertv1beta1AuditAnnotations(inputValidations []v1beta1.AuditAnnotation)
|
|||
return celExpressionAccessor
|
||||
}
|
||||
|
||||
func convertv1beta1Variables(variables []v1beta1.Variable) []cel.NamedExpressionAccessor {
|
||||
func convertv1beta1Variables(variables []v1.Variable) []cel.NamedExpressionAccessor {
|
||||
namedExpressions := make([]cel.NamedExpressionAccessor, len(variables))
|
||||
for i, variable := range variables {
|
||||
namedExpressions[i] = &Variable{Name: variable.Name, Expression: variable.Expression}
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
|
||||
"github.com/google/cel-go/cel"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
"k8s.io/api/admissionregistration/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
|
@ -57,7 +57,7 @@ type TypeCheckingContext struct {
|
|||
paramGVK schema.GroupVersionKind
|
||||
paramDeclType *apiservercel.DeclType
|
||||
|
||||
variables []v1beta1.Variable
|
||||
variables []v1.Variable
|
||||
}
|
||||
|
||||
type typeOverwrite struct {
|
||||
|
@ -105,18 +105,18 @@ func (r *TypeCheckingResult) String() string {
|
|||
// as []ExpressionWarning that is ready to be set in policy.Status
|
||||
// The result is nil if type checking returns no warning.
|
||||
// The policy object is NOT mutated. The caller should update Status accordingly
|
||||
func (c *TypeChecker) Check(policy *v1beta1.ValidatingAdmissionPolicy) []v1beta1.ExpressionWarning {
|
||||
func (c *TypeChecker) Check(policy *v1.ValidatingAdmissionPolicy) []v1.ExpressionWarning {
|
||||
ctx := c.CreateContext(policy)
|
||||
|
||||
// warnings to return, note that the capacity is optimistically set to zero
|
||||
var warnings []v1beta1.ExpressionWarning // intentionally not setting capacity
|
||||
var warnings []v1.ExpressionWarning // intentionally not setting capacity
|
||||
|
||||
// check main validation expressions and their message expressions, located in spec.validations[*]
|
||||
fieldRef := field.NewPath("spec", "validations")
|
||||
for i, v := range policy.Spec.Validations {
|
||||
results := c.CheckExpression(ctx, v.Expression)
|
||||
if len(results) != 0 {
|
||||
warnings = append(warnings, v1beta1.ExpressionWarning{
|
||||
warnings = append(warnings, v1.ExpressionWarning{
|
||||
FieldRef: fieldRef.Index(i).Child("expression").String(),
|
||||
Warning: results.String(),
|
||||
})
|
||||
|
@ -127,7 +127,7 @@ func (c *TypeChecker) Check(policy *v1beta1.ValidatingAdmissionPolicy) []v1beta1
|
|||
}
|
||||
results = c.CheckExpression(ctx, v.MessageExpression)
|
||||
if len(results) != 0 {
|
||||
warnings = append(warnings, v1beta1.ExpressionWarning{
|
||||
warnings = append(warnings, v1.ExpressionWarning{
|
||||
FieldRef: fieldRef.Index(i).Child("messageExpression").String(),
|
||||
Warning: results.String(),
|
||||
})
|
||||
|
@ -138,7 +138,7 @@ func (c *TypeChecker) Check(policy *v1beta1.ValidatingAdmissionPolicy) []v1beta1
|
|||
}
|
||||
|
||||
// CreateContext resolves all types and their schemas from a policy definition and creates the context.
|
||||
func (c *TypeChecker) CreateContext(policy *v1beta1.ValidatingAdmissionPolicy) *TypeCheckingContext {
|
||||
func (c *TypeChecker) CreateContext(policy *v1.ValidatingAdmissionPolicy) *TypeCheckingContext {
|
||||
ctx := new(TypeCheckingContext)
|
||||
allGvks := c.typesToCheck(policy)
|
||||
gvks := make([]schema.GroupVersionKind, 0, len(allGvks))
|
||||
|
@ -250,7 +250,7 @@ func (c *TypeChecker) declType(gvk schema.GroupVersionKind) (*apiservercel.DeclT
|
|||
return common.SchemaDeclType(&openapi.Schema{Schema: s}, true).MaybeAssignTypeName(generateUniqueTypeName(gvk.Kind)), nil
|
||||
}
|
||||
|
||||
func (c *TypeChecker) paramsGVK(policy *v1beta1.ValidatingAdmissionPolicy) schema.GroupVersionKind {
|
||||
func (c *TypeChecker) paramsGVK(policy *v1.ValidatingAdmissionPolicy) schema.GroupVersionKind {
|
||||
if policy.Spec.ParamKind == nil {
|
||||
return schema.GroupVersionKind{}
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ func (c *TypeChecker) paramsGVK(policy *v1beta1.ValidatingAdmissionPolicy) schem
|
|||
|
||||
// typesToCheck extracts a list of GVKs that needs type checking from the policy
|
||||
// the result is sorted in the order of Group, Version, and Kind
|
||||
func (c *TypeChecker) typesToCheck(p *v1beta1.ValidatingAdmissionPolicy) []schema.GroupVersionKind {
|
||||
func (c *TypeChecker) typesToCheck(p *v1.ValidatingAdmissionPolicy) []schema.GroupVersionKind {
|
||||
gvks := sets.New[schema.GroupVersionKind]()
|
||||
if p.Spec.MatchConstraints == nil || len(p.Spec.MatchConstraints.ResourceRules) == 0 {
|
||||
return nil
|
||||
|
@ -333,7 +333,7 @@ func (c *TypeChecker) typesToCheck(p *v1beta1.ValidatingAdmissionPolicy) []schem
|
|||
return sortGVKList(gvks.UnsortedList())
|
||||
}
|
||||
|
||||
func extractGroups(rule *v1beta1.Rule) []string {
|
||||
func extractGroups(rule *v1.Rule) []string {
|
||||
groups := make([]string, 0, len(rule.APIGroups))
|
||||
for _, group := range rule.APIGroups {
|
||||
// give up if wildcard
|
||||
|
@ -345,7 +345,7 @@ func extractGroups(rule *v1beta1.Rule) []string {
|
|||
return groups
|
||||
}
|
||||
|
||||
func extractVersions(rule *v1beta1.Rule) []string {
|
||||
func extractVersions(rule *v1.Rule) []string {
|
||||
versions := make([]string, 0, len(rule.APIVersions))
|
||||
for _, version := range rule.APIVersions {
|
||||
if strings.ContainsAny(version, "*") {
|
||||
|
@ -356,7 +356,7 @@ func extractVersions(rule *v1beta1.Rule) []string {
|
|||
return versions
|
||||
}
|
||||
|
||||
func extractResources(rule *v1beta1.Rule) []string {
|
||||
func extractResources(rule *v1.Rule) []string {
|
||||
resources := make([]string, 0, len(rule.Resources))
|
||||
for _, resource := range rule.Resources {
|
||||
// skip wildcard and subresources
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
"k8s.io/api/admissionregistration/v1"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
|
@ -36,7 +36,7 @@ import (
|
|||
var (
|
||||
scheme *runtime.Scheme = func() *runtime.Scheme {
|
||||
res := runtime.NewScheme()
|
||||
if err := v1beta1.AddToScheme(res); err != nil {
|
||||
if err := v1.AddToScheme(res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
@ -58,21 +58,21 @@ func must3[T any, I any](val T, _ I, err error) T {
|
|||
func TestExtractTypeNames(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
policy *v1beta1.ValidatingAdmissionPolicy
|
||||
policy *v1.ValidatingAdmissionPolicy
|
||||
expected []schema.GroupVersionKind // must be sorted
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
policy: &v1beta1.ValidatingAdmissionPolicy{},
|
||||
policy: &v1.ValidatingAdmissionPolicy{},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "specific",
|
||||
policy: &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
policy: &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1.MatchResources{ResourceRules: []v1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
|
@ -89,19 +89,19 @@ func TestExtractTypeNames(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "multiple",
|
||||
policy: &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
policy: &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1.MatchResources{ResourceRules: []v1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{""},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"pods"},
|
||||
|
@ -122,11 +122,11 @@ func TestExtractTypeNames(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "all resources",
|
||||
policy: &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
policy: &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1.MatchResources{ResourceRules: []v1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"*"},
|
||||
|
@ -139,11 +139,11 @@ func TestExtractTypeNames(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "sub resources",
|
||||
policy: &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
policy: &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1.MatchResources{ResourceRules: []v1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"pods/*"},
|
||||
|
@ -156,11 +156,11 @@ func TestExtractTypeNames(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "mixtures",
|
||||
policy: &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
policy: &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1.MatchResources{ResourceRules: []v1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
|
@ -168,8 +168,8 @@ func TestExtractTypeNames(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"*"},
|
||||
Resources: []string{"deployments"},
|
||||
|
@ -196,16 +196,16 @@ func TestExtractTypeNames(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTypeCheck(t *testing.T) {
|
||||
deploymentPolicy := &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
Validations: []v1beta1.Validation{
|
||||
deploymentPolicy := &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
Validations: []v1.Validation{
|
||||
{
|
||||
Expression: "object.foo == 'bar'",
|
||||
},
|
||||
},
|
||||
MatchConstraints: &v1beta1.MatchResources{ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
MatchConstraints: &v1.MatchResources{ResourceRules: []v1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
|
@ -218,8 +218,8 @@ func TestTypeCheck(t *testing.T) {
|
|||
deploymentPolicyWithBadMessageExpression := deploymentPolicy.DeepCopy()
|
||||
deploymentPolicyWithBadMessageExpression.Spec.Validations[0].MessageExpression = "object.foo + 114514" // confusion
|
||||
|
||||
multiExpressionPolicy := &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
Validations: []v1beta1.Validation{
|
||||
multiExpressionPolicy := &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
Validations: []v1.Validation{
|
||||
{
|
||||
Expression: "object.foo == 'bar'",
|
||||
},
|
||||
|
@ -227,10 +227,10 @@ func TestTypeCheck(t *testing.T) {
|
|||
Expression: "object.bar == 'foo'",
|
||||
},
|
||||
},
|
||||
MatchConstraints: &v1beta1.MatchResources{ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
MatchConstraints: &v1.MatchResources{ResourceRules: []v1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
|
@ -239,20 +239,20 @@ func TestTypeCheck(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
}}
|
||||
paramsRefPolicy := &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
ParamKind: &v1beta1.ParamKind{
|
||||
paramsRefPolicy := &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
ParamKind: &v1.ParamKind{
|
||||
APIVersion: "v1",
|
||||
Kind: "DoesNotMatter",
|
||||
},
|
||||
Validations: []v1beta1.Validation{
|
||||
Validations: []v1.Validation{
|
||||
{
|
||||
Expression: "object.foo == params.bar",
|
||||
},
|
||||
},
|
||||
MatchConstraints: &v1beta1.MatchResources{ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
MatchConstraints: &v1.MatchResources{ResourceRules: []v1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
|
@ -261,16 +261,16 @@ func TestTypeCheck(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
}}
|
||||
authorizerPolicy := &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
Validations: []v1beta1.Validation{
|
||||
authorizerPolicy := &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
Validations: []v1.Validation{
|
||||
{
|
||||
Expression: "authorizer.group('').resource('endpoints').check('create').allowed()",
|
||||
},
|
||||
},
|
||||
MatchConstraints: &v1beta1.MatchResources{ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
MatchConstraints: &v1.MatchResources{ResourceRules: []v1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
|
@ -279,16 +279,16 @@ func TestTypeCheck(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
}}
|
||||
authorizerInvalidPolicy := &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
Validations: []v1beta1.Validation{
|
||||
authorizerInvalidPolicy := &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
Validations: []v1.Validation{
|
||||
{
|
||||
Expression: "authorizer.allowed()",
|
||||
},
|
||||
},
|
||||
MatchConstraints: &v1beta1.MatchResources{ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
MatchConstraints: &v1.MatchResources{ResourceRules: []v1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: v1.RuleWithOperations{
|
||||
Rule: v1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
|
@ -300,12 +300,12 @@ func TestTypeCheck(t *testing.T) {
|
|||
for _, tc := range []struct {
|
||||
name string
|
||||
schemaToReturn *spec.Schema
|
||||
policy *v1beta1.ValidatingAdmissionPolicy
|
||||
policy *v1.ValidatingAdmissionPolicy
|
||||
assertions []assertionFunc
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
policy: &v1beta1.ValidatingAdmissionPolicy{},
|
||||
policy: &v1.ValidatingAdmissionPolicy{},
|
||||
assertions: []assertionFunc{toBeEmpty},
|
||||
},
|
||||
{
|
||||
|
@ -439,14 +439,14 @@ func TestTypeCheck(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "variables valid",
|
||||
policy: &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
Variables: []v1beta1.Variable{
|
||||
policy: &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
Variables: []v1.Variable{
|
||||
{
|
||||
Name: "works",
|
||||
Expression: "true",
|
||||
},
|
||||
},
|
||||
Validations: []v1beta1.Validation{
|
||||
Validations: []v1.Validation{
|
||||
{
|
||||
Expression: "variables.works",
|
||||
},
|
||||
|
@ -466,14 +466,14 @@ func TestTypeCheck(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "variables missing field",
|
||||
policy: &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
Variables: []v1beta1.Variable{
|
||||
policy: &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
Variables: []v1.Variable{
|
||||
{
|
||||
Name: "works",
|
||||
Expression: "true",
|
||||
},
|
||||
},
|
||||
Validations: []v1beta1.Validation{
|
||||
Validations: []v1.Validation{
|
||||
{
|
||||
Expression: "variables.nonExisting",
|
||||
},
|
||||
|
@ -497,14 +497,14 @@ func TestTypeCheck(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "variables field wrong type",
|
||||
policy: &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
Variables: []v1beta1.Variable{
|
||||
policy: &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
Variables: []v1.Variable{
|
||||
{
|
||||
Name: "name",
|
||||
Expression: "'something'",
|
||||
},
|
||||
},
|
||||
Validations: []v1beta1.Validation{
|
||||
Validations: []v1.Validation{
|
||||
{
|
||||
Expression: "variables.name == object.foo", // foo is int64
|
||||
},
|
||||
|
@ -528,14 +528,14 @@ func TestTypeCheck(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "error in variables, not reported during type checking.",
|
||||
policy: &v1beta1.ValidatingAdmissionPolicy{Spec: v1beta1.ValidatingAdmissionPolicySpec{
|
||||
Variables: []v1beta1.Variable{
|
||||
policy: &v1.ValidatingAdmissionPolicy{Spec: v1.ValidatingAdmissionPolicySpec{
|
||||
Variables: []v1.Variable{
|
||||
{
|
||||
Name: "name",
|
||||
Expression: "object.foo == 'str'",
|
||||
},
|
||||
},
|
||||
Validations: []v1beta1.Validation{
|
||||
Validations: []v1.Validation{
|
||||
{
|
||||
Expression: "variables.name == object.foo", // foo is int64
|
||||
},
|
||||
|
@ -593,14 +593,14 @@ func (r *fakeSchemaResolver) ResolveSchema(gvk schema.GroupVersionKind) (*spec.S
|
|||
return r.schemaToReturn, nil
|
||||
}
|
||||
|
||||
func toBeEmpty(warnings []v1beta1.ExpressionWarning, t *testing.T) {
|
||||
func toBeEmpty(warnings []v1.ExpressionWarning, t *testing.T) {
|
||||
if len(warnings) != 0 {
|
||||
t.Fatalf("expected empty but got %v", warnings)
|
||||
}
|
||||
}
|
||||
|
||||
func toContain(substring string) func(warnings []v1beta1.ExpressionWarning, t *testing.T) {
|
||||
return func(warnings []v1beta1.ExpressionWarning, t *testing.T) {
|
||||
func toContain(substring string) func(warnings []v1.ExpressionWarning, t *testing.T) {
|
||||
return func(warnings []v1.ExpressionWarning, t *testing.T) {
|
||||
if len(warnings) == 0 {
|
||||
t.Errorf("expected containing %q but got empty", substring)
|
||||
}
|
||||
|
@ -612,8 +612,8 @@ func toContain(substring string) func(warnings []v1beta1.ExpressionWarning, t *t
|
|||
}
|
||||
}
|
||||
|
||||
func toHaveLengthOf(expected int) func(warnings []v1beta1.ExpressionWarning, t *testing.T) {
|
||||
return func(warnings []v1beta1.ExpressionWarning, t *testing.T) {
|
||||
func toHaveLengthOf(expected int) func(warnings []v1.ExpressionWarning, t *testing.T) {
|
||||
return func(warnings []v1.ExpressionWarning, t *testing.T) {
|
||||
got := len(warnings)
|
||||
if expected != got {
|
||||
t.Errorf("expect warnings to have length of %d, but got %d", expected, got)
|
||||
|
@ -621,8 +621,8 @@ func toHaveLengthOf(expected int) func(warnings []v1beta1.ExpressionWarning, t *
|
|||
}
|
||||
}
|
||||
|
||||
func toHaveFieldRef(paths ...string) func(warnings []v1beta1.ExpressionWarning, t *testing.T) {
|
||||
return func(warnings []v1beta1.ExpressionWarning, t *testing.T) {
|
||||
func toHaveFieldRef(paths ...string) func(warnings []v1.ExpressionWarning, t *testing.T) {
|
||||
return func(warnings []v1.ExpressionWarning, t *testing.T) {
|
||||
if len(paths) != len(warnings) {
|
||||
t.Errorf("expect warnings to have length of %d, but got %d", len(paths), len(warnings))
|
||||
}
|
||||
|
@ -634,4 +634,4 @@ func toHaveFieldRef(paths ...string) func(warnings []v1beta1.ExpressionWarning,
|
|||
}
|
||||
}
|
||||
|
||||
type assertionFunc func(warnings []v1beta1.ExpressionWarning, t *testing.T)
|
||||
type assertionFunc func(warnings []v1.ExpressionWarning, t *testing.T)
|
||||
|
|
|
@ -101,7 +101,10 @@ const (
|
|||
// owner: @cici37 @jpbetz
|
||||
// kep: http://kep.k8s.io/3488
|
||||
// alpha: v1.26
|
||||
// beta: v1.28
|
||||
// stable: v1.30
|
||||
//
|
||||
// Note: the feature gate can be removed in 1.32
|
||||
// Enables expression validation in Admission Control
|
||||
ValidatingAdmissionPolicy featuregate.Feature = "ValidatingAdmissionPolicy"
|
||||
|
||||
|
@ -309,7 +312,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||
|
||||
APIServingWithRoutine: {Default: true, PreRelease: featuregate.Beta},
|
||||
|
||||
ValidatingAdmissionPolicy: {Default: false, PreRelease: featuregate.Beta},
|
||||
ValidatingAdmissionPolicy: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.32
|
||||
|
||||
CustomResourceValidationExpressions: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31
|
||||
|
||||
|
|
|
@ -19,12 +19,14 @@ package options
|
|||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
utilwait "k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/admission/initializer"
|
||||
admissionmetrics "k8s.io/apiserver/pkg/admission/metrics"
|
||||
|
@ -36,9 +38,11 @@ import (
|
|||
apiserverapiv1 "k8s.io/apiserver/pkg/apis/apiserver/v1"
|
||||
apiserverapiv1alpha1 "k8s.io/apiserver/pkg/apis/apiserver/v1alpha1"
|
||||
"k8s.io/apiserver/pkg/server"
|
||||
cacheddiscovery "k8s.io/client-go/discovery/cached/memory"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/restmapper"
|
||||
"k8s.io/component-base/featuregate"
|
||||
)
|
||||
|
||||
|
@ -143,11 +147,24 @@ func (a *AdmissionOptions) ApplyTo(
|
|||
return fmt.Errorf("failed to read plugin config: %v", err)
|
||||
}
|
||||
|
||||
discoveryClient := cacheddiscovery.NewMemCacheClient(kubeClient.Discovery())
|
||||
discoveryRESTMapper := restmapper.NewDeferredDiscoveryRESTMapper(discoveryClient)
|
||||
genericInitializer := initializer.New(kubeClient, dynamicClient, informers, c.Authorization.Authorizer, features,
|
||||
c.DrainedNotify())
|
||||
c.DrainedNotify(), discoveryRESTMapper)
|
||||
initializersChain := admission.PluginInitializers{genericInitializer}
|
||||
initializersChain = append(initializersChain, pluginInitializers...)
|
||||
|
||||
admissionPostStartHook := func(context server.PostStartHookContext) error {
|
||||
discoveryRESTMapper.Reset()
|
||||
go utilwait.Until(discoveryRESTMapper.Reset, 30*time.Second, context.StopCh)
|
||||
return nil
|
||||
}
|
||||
|
||||
err = c.AddPostStartHook("start-apiserver-admission-initializer", admissionPostStartHook)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add post start hook for policy admission: %w", err)
|
||||
}
|
||||
|
||||
admissionChain, err := a.Plugins.NewFromPlugins(pluginNames, pluginsConfigProvider, initializersChain, a.Decorators)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in New Issue