Merge pull request #118644 from alexzielenski/apiserver/policy/namespaceParamRef

KEP-3488: Promote ValidatingAdmissionPolicy to Beta
This commit is contained in:
Kubernetes Prow Robot
2023-07-21 17:44:08 -07:00
committed by GitHub
77 changed files with 18326 additions and 716 deletions

View File

@@ -21,15 +21,15 @@ import (
"fmt"
"time"
"k8s.io/api/admissionregistration/v1alpha1"
"k8s.io/api/admissionregistration/v1beta1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy"
admissionregistrationv1alpha1apply "k8s.io/client-go/applyconfigurations/admissionregistration/v1alpha1"
informerv1alpha1 "k8s.io/client-go/informers/admissionregistration/v1alpha1"
admissionregistrationv1alpha1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1"
admissionregistrationv1beta1apply "k8s.io/client-go/applyconfigurations/admissionregistration/v1beta1"
informerv1beta1 "k8s.io/client-go/informers/admissionregistration/v1beta1"
admissionregistrationv1beta1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/workqueue"
)
@@ -40,10 +40,10 @@ const ControllerName = "validatingadmissionpolicy-status"
// Controller is the ValidatingAdmissionPolicy Status controller that reconciles the Status field of each policy object.
// This controller runs type checks against referred types for each policy definition.
type Controller struct {
policyInformer informerv1alpha1.ValidatingAdmissionPolicyInformer
policyInformer informerv1beta1.ValidatingAdmissionPolicyInformer
policyQueue workqueue.RateLimitingInterface
policySynced cache.InformerSynced
policyClient admissionregistrationv1alpha1.ValidatingAdmissionPolicyInterface
policyClient admissionregistrationv1beta1.ValidatingAdmissionPolicyInterface
// typeChecker checks the policy's expressions for type errors.
// Type of params is defined in policy.Spec.ParamsKind
@@ -66,7 +66,7 @@ func (c *Controller) Run(ctx context.Context, workers int) {
<-ctx.Done()
}
func NewController(policyInformer informerv1alpha1.ValidatingAdmissionPolicyInformer, policyClient admissionregistrationv1alpha1.ValidatingAdmissionPolicyInterface, typeChecker *validatingadmissionpolicy.TypeChecker) (*Controller, error) {
func NewController(policyInformer informerv1beta1.ValidatingAdmissionPolicyInformer, policyClient admissionregistrationv1beta1.ValidatingAdmissionPolicyInterface, typeChecker *validatingadmissionpolicy.TypeChecker) (*Controller, error) {
c := &Controller{
policyInformer: policyInformer,
policyQueue: workqueue.NewRateLimitingQueueWithConfig(workqueue.DefaultControllerRateLimiter(), workqueue.RateLimitingQueueConfig{Name: ControllerName}),
@@ -89,7 +89,7 @@ func NewController(policyInformer informerv1alpha1.ValidatingAdmissionPolicyInfo
}
func (c *Controller) enqueuePolicy(policy any) {
if policy, ok := policy.(*v1alpha1.ValidatingAdmissionPolicy); ok {
if policy, ok := policy.(*v1beta1.ValidatingAdmissionPolicy); ok {
// policy objects are cluster-scoped, no point include its namespace.
key := policy.ObjectMeta.Name
if key == "" {
@@ -138,7 +138,7 @@ func (c *Controller) processNextWorkItem(ctx context.Context) bool {
return true
}
func (c *Controller) reconcile(ctx context.Context, policy *v1alpha1.ValidatingAdmissionPolicy) error {
func (c *Controller) reconcile(ctx context.Context, policy *v1beta1.ValidatingAdmissionPolicy) error {
if policy == nil {
return nil
}
@@ -146,16 +146,16 @@ func (c *Controller) reconcile(ctx context.Context, policy *v1alpha1.ValidatingA
return nil
}
warnings := c.typeChecker.Check(policy)
warningsConfig := make([]*admissionregistrationv1alpha1apply.ExpressionWarningApplyConfiguration, 0, len(warnings))
warningsConfig := make([]*admissionregistrationv1beta1apply.ExpressionWarningApplyConfiguration, 0, len(warnings))
for _, warning := range warnings {
warningsConfig = append(warningsConfig, admissionregistrationv1alpha1apply.ExpressionWarning().
warningsConfig = append(warningsConfig, admissionregistrationv1beta1apply.ExpressionWarning().
WithFieldRef(warning.FieldRef).
WithWarning(warning.Warning))
}
applyConfig := admissionregistrationv1alpha1apply.ValidatingAdmissionPolicy(policy.Name).
WithStatus(admissionregistrationv1alpha1apply.ValidatingAdmissionPolicyStatus().
applyConfig := admissionregistrationv1beta1apply.ValidatingAdmissionPolicy(policy.Name).
WithStatus(admissionregistrationv1beta1apply.ValidatingAdmissionPolicyStatus().
WithObservedGeneration(policy.Generation).
WithTypeChecking(admissionregistrationv1alpha1apply.TypeChecking().
WithTypeChecking(admissionregistrationv1beta1apply.TypeChecking().
WithExpressionWarnings(warningsConfig...)))
_, err := c.policyClient.ApplyStatus(ctx, applyConfig, metav1.ApplyOptions{FieldManager: ControllerName, Force: true})
return err

View File

@@ -23,7 +23,7 @@ import (
"time"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
@@ -38,13 +38,13 @@ import (
func TestTypeChecking(t *testing.T) {
for _, tc := range []struct {
name string
policy *admissionregistrationv1alpha1.ValidatingAdmissionPolicy
assertFieldRef func(warnings []admissionregistrationv1alpha1.ExpressionWarning, t *testing.T) // warning.fieldRef
assertWarnings func(warnings []admissionregistrationv1alpha1.ExpressionWarning, t *testing.T) // warning.warning
policy *admissionregistrationv1beta1.ValidatingAdmissionPolicy
assertFieldRef func(warnings []admissionregistrationv1beta1.ExpressionWarning, t *testing.T) // warning.fieldRef
assertWarnings func(warnings []admissionregistrationv1beta1.ExpressionWarning, t *testing.T) // warning.warning
}{
{
name: "deployment with correct expression",
policy: withGVRMatch([]string{"apps"}, []string{"v1"}, []string{"deployments"}, withValidations([]admissionregistrationv1alpha1.Validation{
policy: withGVRMatch([]string{"apps"}, []string{"v1"}, []string{"deployments"}, withValidations([]admissionregistrationv1beta1.Validation{
{
Expression: "object.spec.replicas > 1",
},
@@ -54,7 +54,7 @@ func TestTypeChecking(t *testing.T) {
},
{
name: "deployment with type confusion",
policy: withGVRMatch([]string{"apps"}, []string{"v1"}, []string{"deployments"}, withValidations([]admissionregistrationv1alpha1.Validation{
policy: withGVRMatch([]string{"apps"}, []string{"v1"}, []string{"deployments"}, withValidations([]admissionregistrationv1beta1.Validation{
{
Expression: "object.spec.replicas < 100", // this one passes
},
@@ -67,7 +67,7 @@ func TestTypeChecking(t *testing.T) {
},
{
name: "two expressions different type checking errors",
policy: withGVRMatch([]string{"apps"}, []string{"v1"}, []string{"deployments"}, withValidations([]admissionregistrationv1alpha1.Validation{
policy: withGVRMatch([]string{"apps"}, []string{"v1"}, []string{"deployments"}, withValidations([]admissionregistrationv1beta1.Validation{
{
Expression: "object.spec.nonExistingFirst > 1",
},
@@ -83,7 +83,7 @@ func TestTypeChecking(t *testing.T) {
},
{
name: "one expression, two warnings",
policy: withGVRMatch([]string{"apps"}, []string{"v1"}, []string{"deployments"}, withValidations([]admissionregistrationv1alpha1.Validation{
policy: withGVRMatch([]string{"apps"}, []string{"v1"}, []string{"deployments"}, withValidations([]admissionregistrationv1beta1.Validation{
{
Expression: "object.spec.replicas < 100", // this one passes
},
@@ -107,8 +107,8 @@ func TestTypeChecking(t *testing.T) {
RestMapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme),
}
controller, err := NewController(
informerFactory.Admissionregistration().V1alpha1().ValidatingAdmissionPolicies(),
client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies(),
informerFactory.Admissionregistration().V1beta1().ValidatingAdmissionPolicies(),
client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicies(),
typeChecker,
)
if err != nil {
@@ -120,7 +120,7 @@ func TestTypeChecking(t *testing.T) {
name := policy.Name
// wait until the typeChecking is set, which means the type checking
// is complete.
updated, err := client.AdmissionregistrationV1alpha1().ValidatingAdmissionPolicies().Get(ctx, name, metav1.GetOptions{})
updated, err := client.AdmissionregistrationV1beta1().ValidatingAdmissionPolicies().Get(ctx, name, metav1.GetOptions{})
if err != nil {
return false, err
}
@@ -143,8 +143,8 @@ func TestTypeChecking(t *testing.T) {
}
func toBe(expected ...string) func(warnings []admissionregistrationv1alpha1.ExpressionWarning, t *testing.T) {
return func(warnings []admissionregistrationv1alpha1.ExpressionWarning, t *testing.T) {
func toBe(expected ...string) func(warnings []admissionregistrationv1beta1.ExpressionWarning, t *testing.T) {
return func(warnings []admissionregistrationv1beta1.ExpressionWarning, t *testing.T) {
if len(expected) != len(warnings) {
t.Fatalf("mismatched length, expect %d, got %d", len(expected), len(warnings))
}
@@ -156,8 +156,8 @@ func toBe(expected ...string) func(warnings []admissionregistrationv1alpha1.Expr
}
}
func toHaveSubstring(substrings ...string) func(warnings []admissionregistrationv1alpha1.ExpressionWarning, t *testing.T) {
return func(warnings []admissionregistrationv1alpha1.ExpressionWarning, t *testing.T) {
func toHaveSubstring(substrings ...string) func(warnings []admissionregistrationv1beta1.ExpressionWarning, t *testing.T) {
return func(warnings []admissionregistrationv1beta1.ExpressionWarning, t *testing.T) {
if len(substrings) != len(warnings) {
t.Fatalf("mismatched length, expect %d, got %d", len(substrings), len(warnings))
}
@@ -169,8 +169,8 @@ func toHaveSubstring(substrings ...string) func(warnings []admissionregistration
}
}
func toHaveMultipleSubstrings(substrings ...[]string) func(warnings []admissionregistrationv1alpha1.ExpressionWarning, t *testing.T) {
return func(warnings []admissionregistrationv1alpha1.ExpressionWarning, t *testing.T) {
func toHaveMultipleSubstrings(substrings ...[]string) func(warnings []admissionregistrationv1beta1.ExpressionWarning, t *testing.T) {
return func(warnings []admissionregistrationv1beta1.ExpressionWarning, t *testing.T) {
if len(substrings) != len(warnings) {
t.Fatalf("mismatched length, expect %d, got %d", len(substrings), len(warnings))
}
@@ -184,19 +184,19 @@ func toHaveMultipleSubstrings(substrings ...[]string) func(warnings []admissionr
}
}
func toHaveLengthOf(n int) func(warnings []admissionregistrationv1alpha1.ExpressionWarning, t *testing.T) {
return func(warnings []admissionregistrationv1alpha1.ExpressionWarning, t *testing.T) {
func toHaveLengthOf(n int) func(warnings []admissionregistrationv1beta1.ExpressionWarning, t *testing.T) {
return func(warnings []admissionregistrationv1beta1.ExpressionWarning, t *testing.T) {
if n != len(warnings) {
t.Fatalf("mismatched length, expect %d, got %d", n, len(warnings))
}
}
}
func withGVRMatch(groups []string, versions []string, resources []string, policy *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) *admissionregistrationv1alpha1.ValidatingAdmissionPolicy {
policy.Spec.MatchConstraints = &admissionregistrationv1alpha1.MatchResources{
ResourceRules: []admissionregistrationv1alpha1.NamedRuleWithOperations{
func withGVRMatch(groups []string, versions []string, resources []string, policy *admissionregistrationv1beta1.ValidatingAdmissionPolicy) *admissionregistrationv1beta1.ValidatingAdmissionPolicy {
policy.Spec.MatchConstraints = &admissionregistrationv1beta1.MatchResources{
ResourceRules: []admissionregistrationv1beta1.NamedRuleWithOperations{
{
RuleWithOperations: admissionregistrationv1alpha1.RuleWithOperations{
RuleWithOperations: admissionregistrationv1beta1.RuleWithOperations{
Operations: []admissionregistrationv1.OperationType{
"*",
},
@@ -212,13 +212,13 @@ func withGVRMatch(groups []string, versions []string, resources []string, policy
return policy
}
func withValidations(validations []admissionregistrationv1alpha1.Validation, policy *admissionregistrationv1alpha1.ValidatingAdmissionPolicy) *admissionregistrationv1alpha1.ValidatingAdmissionPolicy {
func withValidations(validations []admissionregistrationv1beta1.Validation, policy *admissionregistrationv1beta1.ValidatingAdmissionPolicy) *admissionregistrationv1beta1.ValidatingAdmissionPolicy {
policy.Spec.Validations = validations
return policy
}
func makePolicy(name string) *admissionregistrationv1alpha1.ValidatingAdmissionPolicy {
return &admissionregistrationv1alpha1.ValidatingAdmissionPolicy{
func makePolicy(name string) *admissionregistrationv1beta1.ValidatingAdmissionPolicy {
return &admissionregistrationv1beta1.ValidatingAdmissionPolicy{
ObjectMeta: metav1.ObjectMeta{Name: name},
}
}