mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-18 04:54:54 +00:00
promote MutatingAdmissionPolicy to v1: update plugin implementation
- Update MutatingAdmissionPolicy plugin to use v1 types.
This commit is contained in:
@@ -2006,6 +2006,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
|
||||
genericfeatures.MutatingAdmissionPolicy: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.34"), Default: false, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA},
|
||||
},
|
||||
|
||||
genericfeatures.OpenAPIEnums: {
|
||||
|
||||
@@ -18,7 +18,6 @@ package mutating
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/admissionregistration/v1"
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apiserver/pkg/admission/plugin/policy/generic"
|
||||
)
|
||||
@@ -59,19 +58,11 @@ func (v *mutatingAdmissionPolicyAccessor) GetParamKind() *v1.ParamKind {
|
||||
}
|
||||
|
||||
func (v *mutatingAdmissionPolicyAccessor) GetMatchConstraints() *v1.MatchResources {
|
||||
return convertV1alpha1ResourceRulesToV1(v.Spec.MatchConstraints)
|
||||
return v.Spec.MatchConstraints
|
||||
}
|
||||
|
||||
func (v *mutatingAdmissionPolicyAccessor) GetFailurePolicy() *v1.FailurePolicyType {
|
||||
return toV1FailurePolicy(v.Spec.FailurePolicy)
|
||||
}
|
||||
|
||||
func toV1FailurePolicy(failurePolicy *v1beta1.FailurePolicyType) *v1.FailurePolicyType {
|
||||
if failurePolicy == nil {
|
||||
return nil
|
||||
}
|
||||
fp := v1.FailurePolicyType(*failurePolicy)
|
||||
return &fp
|
||||
return v.Spec.FailurePolicy
|
||||
}
|
||||
|
||||
type mutatingAdmissionPolicyBindingAccessor struct {
|
||||
@@ -94,7 +85,7 @@ func (v *mutatingAdmissionPolicyBindingAccessor) GetPolicyName() types.Namespace
|
||||
}
|
||||
|
||||
func (v *mutatingAdmissionPolicyBindingAccessor) GetMatchResources() *v1.MatchResources {
|
||||
return convertV1alpha1ResourceRulesToV1(v.Spec.MatchResources)
|
||||
return v.Spec.MatchResources
|
||||
}
|
||||
|
||||
func (v *mutatingAdmissionPolicyBindingAccessor) GetParamRef() *v1.ParamRef {
|
||||
@@ -115,30 +106,3 @@ func (v *mutatingAdmissionPolicyBindingAccessor) GetParamRef() *v1.ParamRef {
|
||||
ParameterNotFoundAction: nfa,
|
||||
}
|
||||
}
|
||||
|
||||
func convertV1alpha1ResourceRulesToV1(mc *v1beta1.MatchResources) *v1.MatchResources {
|
||||
if mc == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var res v1.MatchResources
|
||||
res.NamespaceSelector = mc.NamespaceSelector
|
||||
res.ObjectSelector = mc.ObjectSelector
|
||||
for _, ex := range mc.ExcludeResourceRules {
|
||||
res.ExcludeResourceRules = append(res.ExcludeResourceRules, v1.NamedRuleWithOperations{
|
||||
ResourceNames: ex.ResourceNames,
|
||||
RuleWithOperations: ex.RuleWithOperations,
|
||||
})
|
||||
}
|
||||
for _, ex := range mc.ResourceRules {
|
||||
res.ResourceRules = append(res.ResourceRules, v1.NamedRuleWithOperations{
|
||||
ResourceNames: ex.ResourceNames,
|
||||
RuleWithOperations: ex.RuleWithOperations,
|
||||
})
|
||||
}
|
||||
if mc.MatchPolicy != nil {
|
||||
mp := v1.MatchPolicyType(*mc.MatchPolicy)
|
||||
res.MatchPolicy = &mp
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
@@ -19,9 +19,10 @@ package mutating
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
"k8s.io/api/admissionregistration/v1"
|
||||
plugincel "k8s.io/apiserver/pkg/admission/plugin/cel"
|
||||
"k8s.io/apiserver/pkg/admission/plugin/policy/mutating/patch"
|
||||
"k8s.io/apiserver/pkg/admission/plugin/policy/validating"
|
||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions"
|
||||
apiservercel "k8s.io/apiserver/pkg/cel"
|
||||
"k8s.io/apiserver/pkg/cel/environment"
|
||||
@@ -32,7 +33,7 @@ import (
|
||||
//
|
||||
// Each individual mutation is compiled into MutationEvaluationFunc and
|
||||
// returned is a PolicyEvaluator in the same order as the mutations appeared in the policy.
|
||||
func compilePolicy(policy *Policy) PolicyEvaluator {
|
||||
func compilePolicy(policy *v1.MutatingAdmissionPolicy) PolicyEvaluator {
|
||||
opts := plugincel.OptionalVariableDeclarations{HasParams: policy.Spec.ParamKind != nil, HasAuthorizer: true}
|
||||
compiler, err := plugincel.NewCompositedCompiler(environment.MustBaseEnvSet(environment.DefaultCompatibilityVersion()))
|
||||
if err != nil {
|
||||
@@ -43,7 +44,7 @@ func compilePolicy(policy *Policy) PolicyEvaluator {
|
||||
}
|
||||
|
||||
// Compile and store variables
|
||||
compiler.CompileAndStoreVariables(convertv1alpha1Variables(policy.Spec.Variables), opts, environment.StoredExpressions)
|
||||
compiler.CompileAndStoreVariables(convertV1Variables(policy.Spec.Variables), opts, environment.StoredExpressions)
|
||||
|
||||
// Compile matchers
|
||||
var matcher matchconditions.Matcher = nil
|
||||
@@ -53,7 +54,7 @@ func compilePolicy(policy *Policy) PolicyEvaluator {
|
||||
for i := range matchConditions {
|
||||
matchExpressionAccessors[i] = (*matchconditions.MatchCondition)(&matchConditions[i])
|
||||
}
|
||||
matcher = matchconditions.NewMatcher(compiler.CompileCondition(matchExpressionAccessors, opts, environment.StoredExpressions), toV1FailurePolicy(policy.Spec.FailurePolicy), "policy", "validate", policy.Name)
|
||||
matcher = matchconditions.NewMatcher(compiler.CompileCondition(matchExpressionAccessors, opts, environment.StoredExpressions), policy.Spec.FailurePolicy, "policy", "validate", policy.Name)
|
||||
}
|
||||
|
||||
// Compiler patchers
|
||||
@@ -62,13 +63,13 @@ func compilePolicy(policy *Policy) PolicyEvaluator {
|
||||
patchOptions.HasPatchTypes = true
|
||||
for _, m := range policy.Spec.Mutations {
|
||||
switch m.PatchType {
|
||||
case v1beta1.PatchTypeJSONPatch:
|
||||
case v1.PatchTypeJSONPatch:
|
||||
if m.JSONPatch != nil {
|
||||
accessor := &patch.JSONPatchCondition{Expression: m.JSONPatch.Expression}
|
||||
compileResult := compiler.CompileMutatingEvaluator(accessor, patchOptions, environment.StoredExpressions)
|
||||
patchers = append(patchers, patch.NewJSONPatcher(compileResult))
|
||||
}
|
||||
case v1beta1.PatchTypeApplyConfiguration:
|
||||
case v1.PatchTypeApplyConfiguration:
|
||||
if m.ApplyConfiguration != nil {
|
||||
accessor := &patch.ApplyConfigurationCondition{Expression: m.ApplyConfiguration.Expression}
|
||||
compileResult := compiler.CompileMutatingEvaluator(accessor, patchOptions, environment.StoredExpressions)
|
||||
@@ -79,3 +80,17 @@ func compilePolicy(policy *Policy) PolicyEvaluator {
|
||||
|
||||
return PolicyEvaluator{Matcher: matcher, Mutators: patchers, CompositedCompiler: compiler}
|
||||
}
|
||||
|
||||
func convertV1Variables(variables []v1.Variable) []plugincel.NamedExpressionAccessor {
|
||||
if variables == nil {
|
||||
return nil
|
||||
}
|
||||
res := make([]plugincel.NamedExpressionAccessor, len(variables))
|
||||
for i, v := range variables {
|
||||
res[i] = &validating.Variable{
|
||||
Name: v.Name,
|
||||
Expression: v.Expression,
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
v1 "k8s.io/api/admissionregistration/v1"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
@@ -50,7 +50,7 @@ func TestCompilation(t *testing.T) {
|
||||
deploymentGVK := schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"}
|
||||
testCases := []struct {
|
||||
name string
|
||||
policy *Policy
|
||||
policy *v1.MutatingAdmissionPolicy
|
||||
gvr schema.GroupVersionResource
|
||||
object runtime.Object
|
||||
oldObject runtime.Object
|
||||
@@ -61,9 +61,9 @@ func TestCompilation(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "applyConfiguration then jsonPatch",
|
||||
policy: mutations(policy("d1"), v1beta1.Mutation{
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
policy: mutations(policy("d1"), v1.Mutation{
|
||||
PatchType: v1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &v1.ApplyConfiguration{
|
||||
Expression: `Object{
|
||||
spec: Object.spec{
|
||||
replicas: object.spec.replicas + 100
|
||||
@@ -71,9 +71,9 @@ func TestCompilation(t *testing.T) {
|
||||
}`,
|
||||
},
|
||||
},
|
||||
v1beta1.Mutation{
|
||||
PatchType: v1beta1.PatchTypeJSONPatch,
|
||||
JSONPatch: &v1beta1.JSONPatch{
|
||||
v1.Mutation{
|
||||
PatchType: v1.PatchTypeJSONPatch,
|
||||
JSONPatch: &v1.JSONPatch{
|
||||
Expression: `[
|
||||
JSONPatch{op: "replace", path: "/spec/replicas", value: object.spec.replicas + 10}
|
||||
]`,
|
||||
@@ -86,17 +86,17 @@ func TestCompilation(t *testing.T) {
|
||||
{
|
||||
name: "jsonPatch then applyConfiguration",
|
||||
policy: mutations(policy("d1"),
|
||||
v1beta1.Mutation{
|
||||
PatchType: v1beta1.PatchTypeJSONPatch,
|
||||
JSONPatch: &v1beta1.JSONPatch{
|
||||
v1.Mutation{
|
||||
PatchType: v1.PatchTypeJSONPatch,
|
||||
JSONPatch: &v1.JSONPatch{
|
||||
Expression: `[
|
||||
JSONPatch{op: "replace", path: "/spec/replicas", value: object.spec.replicas + 10}
|
||||
]`,
|
||||
},
|
||||
},
|
||||
v1beta1.Mutation{
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
v1.Mutation{
|
||||
PatchType: v1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &v1.ApplyConfiguration{
|
||||
Expression: `Object{
|
||||
spec: Object.spec{
|
||||
replicas: object.spec.replicas + 100
|
||||
@@ -110,7 +110,7 @@ func TestCompilation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "jsonPatch with variable",
|
||||
policy: jsonPatches(variables(policy("d1"), v1beta1.Variable{Name: "desired", Expression: "10"}), v1beta1.JSONPatch{
|
||||
policy: jsonPatches(variables(policy("d1"), v1.Variable{Name: "desired", Expression: "10"}), v1.JSONPatch{
|
||||
Expression: `[
|
||||
JSONPatch{op: "replace", path: "/spec/replicas", value: variables.desired + 1},
|
||||
]`,
|
||||
@@ -121,7 +121,7 @@ func TestCompilation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "apply configuration with variable",
|
||||
policy: applyConfigurations(variables(policy("d1"), v1beta1.Variable{Name: "desired", Expression: "10"}),
|
||||
policy: applyConfigurations(variables(policy("d1"), v1.Variable{Name: "desired", Expression: "10"}),
|
||||
`Object{
|
||||
spec: Object.spec{
|
||||
replicas: variables.desired + 1
|
||||
@@ -138,7 +138,7 @@ func TestCompilation(t *testing.T) {
|
||||
spec: Object.spec{
|
||||
replicas: int(params.data['k1'])
|
||||
}
|
||||
}`), &v1beta1.ParamKind{Kind: "ConfigMap", APIVersion: "v1"}),
|
||||
}`), &v1.ParamKind{Kind: "ConfigMap", APIVersion: "v1"}),
|
||||
params: &corev1.ConfigMap{Data: map[string]string{"k1": "100"}},
|
||||
gvr: deploymentGVR,
|
||||
object: &appsv1.Deployment{Spec: appsv1.DeploymentSpec{Replicas: ptr.To[int32](1)}},
|
||||
@@ -146,7 +146,7 @@ func TestCompilation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "jsonPatch with excessive cost",
|
||||
policy: jsonPatches(variables(policy("d1"), v1beta1.Variable{Name: "list", Expression: "[0,1,2,3,4,5,6,7,8,9]"}), v1beta1.JSONPatch{
|
||||
policy: jsonPatches(variables(policy("d1"), v1.Variable{Name: "list", Expression: "[0,1,2,3,4,5,6,7,8,9]"}), v1.JSONPatch{
|
||||
Expression: `[
|
||||
JSONPatch{op: "replace", path: "/spec/replicas",
|
||||
value: variables.list.all(x1, variables.list.all(x2, variables.list.all(x3, variables.list.all(x4, variables.list.all(x5, variables.list.all(x5, "0123456789" == "0123456789"))))))? 1 : 0
|
||||
@@ -164,14 +164,14 @@ func TestCompilation(t *testing.T) {
|
||||
spec: Object.spec{
|
||||
replicas: variables.list.all(x1, variables.list.all(x2, variables.list.all(x3, variables.list.all(x4, variables.list.all(x5, variables.list.all(x5, "0123456789" == "0123456789"))))))? 1 : 0
|
||||
}
|
||||
}`), v1beta1.Variable{Name: "list", Expression: "[0,1,2,3,4,5,6,7,8,9]"}),
|
||||
}`), v1.Variable{Name: "list", Expression: "[0,1,2,3,4,5,6,7,8,9]"}),
|
||||
gvr: deploymentGVR,
|
||||
object: &appsv1.Deployment{Spec: appsv1.DeploymentSpec{Replicas: ptr.To[int32](1)}},
|
||||
expectedErr: "operation cancelled: actual cost limit exceeded",
|
||||
},
|
||||
{
|
||||
name: "request variable",
|
||||
policy: jsonPatches(policy("d1"), v1beta1.JSONPatch{
|
||||
policy: jsonPatches(policy("d1"), v1.JSONPatch{
|
||||
Expression: `[
|
||||
JSONPatch{op: "replace", path: "/spec/replicas",
|
||||
value: request.kind.group == 'apps' && request.kind.version == 'v1' && request.kind.kind == 'Deployment' ? 10 : 0
|
||||
@@ -183,7 +183,7 @@ func TestCompilation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "namespace request variable",
|
||||
policy: jsonPatches(policy("d1"), v1beta1.JSONPatch{
|
||||
policy: jsonPatches(policy("d1"), v1.JSONPatch{
|
||||
Expression: `[
|
||||
JSONPatch{op: "replace", path: "/spec/replicas",
|
||||
value: namespaceObject.metadata.name == 'ns1' ? 10 : 0
|
||||
@@ -196,7 +196,7 @@ func TestCompilation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "authorizer check",
|
||||
policy: jsonPatches(policy("d1"), v1beta1.JSONPatch{
|
||||
policy: jsonPatches(policy("d1"), v1.JSONPatch{
|
||||
Expression: `[
|
||||
JSONPatch{op: "replace", path: "/spec/replicas",
|
||||
value: authorizer.group('').resource('endpoints').check('create').allowed() ? 10 : 0
|
||||
@@ -209,7 +209,7 @@ func TestCompilation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "object type has field access",
|
||||
policy: jsonPatches(policy("d1"), v1beta1.JSONPatch{
|
||||
policy: jsonPatches(policy("d1"), v1.JSONPatch{
|
||||
Expression: `[
|
||||
JSONPatch{
|
||||
op: "add", path: "/metadata/labels",
|
||||
@@ -227,7 +227,7 @@ func TestCompilation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "object type has field testing",
|
||||
policy: jsonPatches(policy("d1"), v1beta1.JSONPatch{
|
||||
policy: jsonPatches(policy("d1"), v1.JSONPatch{
|
||||
Expression: `[
|
||||
JSONPatch{
|
||||
op: "add", path: "/metadata/labels",
|
||||
@@ -247,7 +247,7 @@ func TestCompilation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "object type equality",
|
||||
policy: jsonPatches(policy("d1"), v1beta1.JSONPatch{
|
||||
policy: jsonPatches(policy("d1"), v1.JSONPatch{
|
||||
Expression: `[
|
||||
JSONPatch{
|
||||
op: "add", path: "/metadata/labels",
|
||||
@@ -275,7 +275,7 @@ func TestCompilation(t *testing.T) {
|
||||
// recompile all expressions with fully bound types before evaluation and report
|
||||
// errors if invalid Object types like this are initialized.
|
||||
name: "object types are not fully type checked",
|
||||
policy: jsonPatches(policy("d1"), v1beta1.JSONPatch{
|
||||
policy: jsonPatches(policy("d1"), v1.JSONPatch{
|
||||
Expression: `[
|
||||
JSONPatch{
|
||||
op: "add", path: "/spec",
|
||||
@@ -401,52 +401,52 @@ func TestCompilation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func policy(name string) *v1beta1.MutatingAdmissionPolicy {
|
||||
return &v1beta1.MutatingAdmissionPolicy{
|
||||
func policy(name string) *v1.MutatingAdmissionPolicy {
|
||||
return &v1.MutatingAdmissionPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
},
|
||||
Spec: v1beta1.MutatingAdmissionPolicySpec{},
|
||||
Spec: v1.MutatingAdmissionPolicySpec{},
|
||||
}
|
||||
}
|
||||
|
||||
func variables(policy *v1beta1.MutatingAdmissionPolicy, variables ...v1beta1.Variable) *v1beta1.MutatingAdmissionPolicy {
|
||||
func variables(policy *v1.MutatingAdmissionPolicy, variables ...v1.Variable) *v1.MutatingAdmissionPolicy {
|
||||
policy.Spec.Variables = append(policy.Spec.Variables, variables...)
|
||||
return policy
|
||||
}
|
||||
|
||||
func jsonPatches(policy *v1beta1.MutatingAdmissionPolicy, jsonPatches ...v1beta1.JSONPatch) *v1beta1.MutatingAdmissionPolicy {
|
||||
func jsonPatches(policy *v1.MutatingAdmissionPolicy, jsonPatches ...v1.JSONPatch) *v1.MutatingAdmissionPolicy {
|
||||
for _, jsonPatch := range jsonPatches {
|
||||
policy.Spec.Mutations = append(policy.Spec.Mutations, v1beta1.Mutation{
|
||||
policy.Spec.Mutations = append(policy.Spec.Mutations, v1.Mutation{
|
||||
JSONPatch: &jsonPatch,
|
||||
PatchType: v1beta1.PatchTypeJSONPatch,
|
||||
PatchType: v1.PatchTypeJSONPatch,
|
||||
})
|
||||
}
|
||||
|
||||
return policy
|
||||
}
|
||||
|
||||
func applyConfigurations(policy *v1beta1.MutatingAdmissionPolicy, expressions ...string) *v1beta1.MutatingAdmissionPolicy {
|
||||
func applyConfigurations(policy *v1.MutatingAdmissionPolicy, expressions ...string) *v1.MutatingAdmissionPolicy {
|
||||
for _, expression := range expressions {
|
||||
policy.Spec.Mutations = append(policy.Spec.Mutations, v1beta1.Mutation{
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{Expression: expression},
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
policy.Spec.Mutations = append(policy.Spec.Mutations, v1.Mutation{
|
||||
ApplyConfiguration: &v1.ApplyConfiguration{Expression: expression},
|
||||
PatchType: v1.PatchTypeApplyConfiguration,
|
||||
})
|
||||
}
|
||||
return policy
|
||||
}
|
||||
|
||||
func paramKind(policy *v1beta1.MutatingAdmissionPolicy, paramKind *v1beta1.ParamKind) *v1beta1.MutatingAdmissionPolicy {
|
||||
func paramKind(policy *v1.MutatingAdmissionPolicy, paramKind *v1.ParamKind) *v1.MutatingAdmissionPolicy {
|
||||
policy.Spec.ParamKind = paramKind
|
||||
return policy
|
||||
}
|
||||
|
||||
func mutations(policy *v1beta1.MutatingAdmissionPolicy, mutations ...v1beta1.Mutation) *v1beta1.MutatingAdmissionPolicy {
|
||||
func mutations(policy *v1.MutatingAdmissionPolicy, mutations ...v1.Mutation) *v1.MutatingAdmissionPolicy {
|
||||
policy.Spec.Mutations = append(policy.Spec.Mutations, mutations...)
|
||||
return policy
|
||||
}
|
||||
|
||||
func matchConstraints(policy *v1beta1.MutatingAdmissionPolicy, matchConstraints *v1beta1.MatchResources) *v1beta1.MutatingAdmissionPolicy {
|
||||
func matchConstraints(policy *v1.MutatingAdmissionPolicy, matchConstraints *v1.MatchResources) *v1.MutatingAdmissionPolicy {
|
||||
policy.Spec.MatchConstraints = matchConstraints
|
||||
return policy
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -49,7 +49,7 @@ func NewDispatcher(a authorizer.Authorizer, m *matching.Matcher, tcm patch.TypeC
|
||||
authz: a,
|
||||
typeConverterManager: tcm,
|
||||
}
|
||||
res.Dispatcher = generic.NewPolicyDispatcher(
|
||||
res.Dispatcher = generic.NewPolicyDispatcher[*Policy, *PolicyBinding, PolicyEvaluator](
|
||||
NewMutatingAdmissionPolicyAccessor,
|
||||
NewMutatingAdmissionPolicyBindingAccessor,
|
||||
m,
|
||||
@@ -210,7 +210,7 @@ func (d *dispatcher) dispatchInvocations(
|
||||
policyReinvokeCtx.RequireReinvokingPreviouslyInvokedPlugins()
|
||||
reinvokeCtx.SetShouldReinvoke()
|
||||
}
|
||||
if invocation.Policy.Spec.ReinvocationPolicy == v1beta1.IfNeededReinvocationPolicy {
|
||||
if invocation.Policy.Spec.ReinvocationPolicy == admissionregistrationv1.IfNeededReinvocationPolicy {
|
||||
policyReinvokeCtx.AddReinvocablePolicyToPreviouslyInvoked(invocationKey)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"time"
|
||||
|
||||
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
@@ -33,7 +32,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/admission/plugin/policy/generic"
|
||||
"k8s.io/apiserver/pkg/admission/plugin/policy/matching"
|
||||
"k8s.io/apiserver/pkg/admission/plugin/policy/mutating/patch"
|
||||
"k8s.io/client-go/informers"
|
||||
@@ -75,16 +73,16 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}},
|
||||
policyHooks: []generic.PolicyHook[*Policy, *PolicyBinding, PolicyEvaluator]{
|
||||
policyHooks: []PolicyHook{
|
||||
{
|
||||
Policy: mutations(matchConstraints(policy("policy1"), &v1beta1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1beta1.Equivalent),
|
||||
Policy: mutations(matchConstraints(policy("policy1"), &admissionregistrationv1.MatchResources{
|
||||
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
ResourceRules: []admissionregistrationv1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: admissionregistrationv1.RuleWithOperations{
|
||||
Rule: admissionregistrationv1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
@@ -93,18 +91,18 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
}), v1beta1.Mutation{
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
}), admissionregistrationv1.Mutation{
|
||||
PatchType: admissionregistrationv1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &admissionregistrationv1.ApplyConfiguration{
|
||||
Expression: `Object{
|
||||
spec: Object.spec{
|
||||
replicas: object.spec.replicas + 100
|
||||
}
|
||||
}`,
|
||||
}}),
|
||||
Bindings: []*PolicyBinding{{
|
||||
Bindings: []*admissionregistrationv1.MutatingAdmissionPolicyBinding{{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "binding"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.MutatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: "policy1",
|
||||
},
|
||||
}},
|
||||
@@ -166,16 +164,16 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
policyHooks: []generic.PolicyHook[*Policy, *PolicyBinding, PolicyEvaluator]{
|
||||
policyHooks: []PolicyHook{
|
||||
{
|
||||
Policy: paramKind(mutations(matchConstraints(policy("policy1"), &v1beta1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1beta1.Equivalent),
|
||||
Policy: paramKind(mutations(matchConstraints(policy("policy1"), &admissionregistrationv1.MatchResources{
|
||||
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
ResourceRules: []admissionregistrationv1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: admissionregistrationv1.RuleWithOperations{
|
||||
Rule: admissionregistrationv1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
@@ -184,24 +182,24 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}}),
|
||||
v1beta1.Mutation{
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
admissionregistrationv1.Mutation{
|
||||
PatchType: admissionregistrationv1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &admissionregistrationv1.ApplyConfiguration{
|
||||
Expression: `Object{
|
||||
spec: Object.spec{
|
||||
replicas: object.spec.replicas + int(params.data['key'])
|
||||
}
|
||||
}`,
|
||||
}}),
|
||||
&v1beta1.ParamKind{
|
||||
&admissionregistrationv1.ParamKind{
|
||||
APIVersion: "v1",
|
||||
Kind: "ConfigMap",
|
||||
}),
|
||||
Bindings: []*PolicyBinding{{
|
||||
Bindings: []*admissionregistrationv1.MutatingAdmissionPolicyBinding{{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "binding"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.MutatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: "policy1",
|
||||
ParamRef: &v1beta1.ParamRef{Name: "cm1", Namespace: "default"},
|
||||
ParamRef: &admissionregistrationv1.ParamRef{Name: "cm1", Namespace: "default"},
|
||||
},
|
||||
}},
|
||||
},
|
||||
@@ -246,16 +244,16 @@ func TestDispatcher(t *testing.T) {
|
||||
Type: appsv1.RollingUpdateDeploymentStrategyType,
|
||||
},
|
||||
}},
|
||||
policyHooks: []generic.PolicyHook[*Policy, *PolicyBinding, PolicyEvaluator]{
|
||||
policyHooks: []PolicyHook{
|
||||
{
|
||||
Policy: mutations(matchConstraints(policy("policy1"), &v1beta1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1beta1.Equivalent),
|
||||
Policy: mutations(matchConstraints(policy("policy1"), &admissionregistrationv1.MatchResources{
|
||||
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
ResourceRules: []admissionregistrationv1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: admissionregistrationv1.RuleWithOperations{
|
||||
Rule: admissionregistrationv1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
@@ -264,31 +262,31 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
}), v1beta1.Mutation{
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
}), admissionregistrationv1.Mutation{
|
||||
PatchType: admissionregistrationv1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &admissionregistrationv1.ApplyConfiguration{
|
||||
Expression: `Object{
|
||||
metadata: Object.metadata{
|
||||
labels: {"policy1": string(int(object.?metadata.labels["count"].orValue("1")) + 1)}
|
||||
}
|
||||
}`,
|
||||
}}),
|
||||
Bindings: []*PolicyBinding{{
|
||||
Bindings: []*admissionregistrationv1.MutatingAdmissionPolicyBinding{{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "binding"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.MutatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: "policy1",
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
Policy: mutations(matchConstraints(policy("policy2"), &v1beta1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1beta1.Equivalent),
|
||||
Policy: mutations(matchConstraints(policy("policy2"), &admissionregistrationv1.MatchResources{
|
||||
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
ResourceRules: []admissionregistrationv1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: admissionregistrationv1.RuleWithOperations{
|
||||
Rule: admissionregistrationv1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
@@ -297,18 +295,18 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
}), v1beta1.Mutation{
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
}), admissionregistrationv1.Mutation{
|
||||
PatchType: admissionregistrationv1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &admissionregistrationv1.ApplyConfiguration{
|
||||
Expression: `Object{
|
||||
metadata: Object.metadata{
|
||||
labels: {"policy2": string(int(object.?metadata.labels["count"].orValue("1")) + 1)}
|
||||
}
|
||||
}`,
|
||||
}}),
|
||||
Bindings: []*PolicyBinding{{
|
||||
Bindings: []*admissionregistrationv1.MutatingAdmissionPolicyBinding{{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "binding"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.MutatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: "policy2",
|
||||
},
|
||||
}},
|
||||
@@ -357,21 +355,21 @@ func TestDispatcher(t *testing.T) {
|
||||
Type: appsv1.RollingUpdateDeploymentStrategyType,
|
||||
},
|
||||
}},
|
||||
policyHooks: []generic.PolicyHook[*Policy, *PolicyBinding, PolicyEvaluator]{
|
||||
policyHooks: []PolicyHook{
|
||||
{
|
||||
Policy: &v1beta1.MutatingAdmissionPolicy{
|
||||
Policy: &admissionregistrationv1.MutatingAdmissionPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "policy1",
|
||||
},
|
||||
Spec: v1beta1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1beta1.Equivalent),
|
||||
Spec: admissionregistrationv1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &admissionregistrationv1.MatchResources{
|
||||
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
ResourceRules: []admissionregistrationv1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: admissionregistrationv1.RuleWithOperations{
|
||||
Rule: admissionregistrationv1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
@@ -381,9 +379,9 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
Mutations: []v1beta1.Mutation{{
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
Mutations: []admissionregistrationv1.Mutation{{
|
||||
PatchType: admissionregistrationv1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &admissionregistrationv1.ApplyConfiguration{
|
||||
Expression: `Object{
|
||||
metadata: Object.metadata{
|
||||
labels: {"environment": "production"}
|
||||
@@ -392,27 +390,27 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
Bindings: []*PolicyBinding{{
|
||||
Bindings: []*admissionregistrationv1.MutatingAdmissionPolicyBinding{{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "binding"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.MutatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: "policy1",
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
Policy: &v1beta1.MutatingAdmissionPolicy{
|
||||
Policy: &admissionregistrationv1.MutatingAdmissionPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "policy2",
|
||||
},
|
||||
Spec: v1beta1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1beta1.Equivalent),
|
||||
Spec: admissionregistrationv1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &admissionregistrationv1.MatchResources{
|
||||
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
ResourceRules: []admissionregistrationv1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: admissionregistrationv1.RuleWithOperations{
|
||||
Rule: admissionregistrationv1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
@@ -422,15 +420,15 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
MatchConditions: []v1beta1.MatchCondition{
|
||||
MatchConditions: []admissionregistrationv1.MatchCondition{
|
||||
{
|
||||
Name: "prodonly",
|
||||
Expression: `object.?metadata.labels["environment"].orValue("") == "production"`,
|
||||
},
|
||||
},
|
||||
Mutations: []v1beta1.Mutation{{
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
Mutations: []admissionregistrationv1.Mutation{{
|
||||
PatchType: admissionregistrationv1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &admissionregistrationv1.ApplyConfiguration{
|
||||
Expression: `Object{
|
||||
metadata: Object.metadata{
|
||||
labels: {"policy1invoked": "true"}
|
||||
@@ -439,9 +437,9 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
Bindings: []*PolicyBinding{{
|
||||
Bindings: []*admissionregistrationv1.MutatingAdmissionPolicyBinding{{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "binding"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.MutatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: "policy2",
|
||||
},
|
||||
}},
|
||||
@@ -491,21 +489,21 @@ func TestDispatcher(t *testing.T) {
|
||||
Type: appsv1.RollingUpdateDeploymentStrategyType,
|
||||
},
|
||||
}},
|
||||
policyHooks: []generic.PolicyHook[*Policy, *PolicyBinding, PolicyEvaluator]{
|
||||
policyHooks: []PolicyHook{
|
||||
{
|
||||
Policy: &v1beta1.MutatingAdmissionPolicy{
|
||||
Policy: &admissionregistrationv1.MutatingAdmissionPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "policy1",
|
||||
},
|
||||
Spec: v1beta1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1beta1.Equivalent),
|
||||
Spec: admissionregistrationv1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &admissionregistrationv1.MatchResources{
|
||||
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
ResourceRules: []admissionregistrationv1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: admissionregistrationv1.RuleWithOperations{
|
||||
Rule: admissionregistrationv1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
@@ -515,15 +513,15 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
MatchConditions: []v1beta1.MatchCondition{
|
||||
MatchConditions: []admissionregistrationv1.MatchCondition{
|
||||
{
|
||||
Name: "prodonly",
|
||||
Expression: `object.?metadata.labels["environment"].orValue("") == "production"`,
|
||||
},
|
||||
},
|
||||
Mutations: []v1beta1.Mutation{{
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
Mutations: []admissionregistrationv1.Mutation{{
|
||||
PatchType: admissionregistrationv1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &admissionregistrationv1.ApplyConfiguration{
|
||||
Expression: `Object{
|
||||
metadata: Object.metadata{
|
||||
labels: {"policy1invoked": "true"}
|
||||
@@ -532,27 +530,27 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
Bindings: []*PolicyBinding{{
|
||||
Bindings: []*admissionregistrationv1.MutatingAdmissionPolicyBinding{{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "binding"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.MutatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: "policy1",
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
Policy: &v1beta1.MutatingAdmissionPolicy{
|
||||
Policy: &admissionregistrationv1.MutatingAdmissionPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "policy2",
|
||||
},
|
||||
Spec: v1beta1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1beta1.Equivalent),
|
||||
Spec: admissionregistrationv1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &admissionregistrationv1.MatchResources{
|
||||
MatchPolicy: ptr.To(admissionregistrationv1.Equivalent),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
ResourceRules: []v1beta1.NamedRuleWithOperations{
|
||||
ResourceRules: []admissionregistrationv1.NamedRuleWithOperations{
|
||||
{
|
||||
RuleWithOperations: v1beta1.RuleWithOperations{
|
||||
Rule: v1beta1.Rule{
|
||||
RuleWithOperations: admissionregistrationv1.RuleWithOperations{
|
||||
Rule: admissionregistrationv1.Rule{
|
||||
APIGroups: []string{"apps"},
|
||||
APIVersions: []string{"v1"},
|
||||
Resources: []string{"deployments"},
|
||||
@@ -562,9 +560,9 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
Mutations: []v1beta1.Mutation{{
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
Mutations: []admissionregistrationv1.Mutation{{
|
||||
PatchType: admissionregistrationv1.PatchTypeApplyConfiguration,
|
||||
ApplyConfiguration: &admissionregistrationv1.ApplyConfiguration{
|
||||
Expression: `Object{
|
||||
metadata: Object.metadata{
|
||||
labels: {"environment": "production"}
|
||||
@@ -573,9 +571,9 @@ func TestDispatcher(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
Bindings: []*PolicyBinding{{
|
||||
Bindings: []*admissionregistrationv1.MutatingAdmissionPolicyBinding{{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "binding"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicyBindingSpec{
|
||||
Spec: admissionregistrationv1.MutatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: "policy2",
|
||||
},
|
||||
}},
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
|
||||
celgo "github.com/google/cel-go/cel"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
v1 "k8s.io/api/admissionregistration/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -54,9 +54,9 @@ func Register(plugins *admission.Plugins) {
|
||||
})
|
||||
}
|
||||
|
||||
type Policy = v1beta1.MutatingAdmissionPolicy
|
||||
type PolicyBinding = v1beta1.MutatingAdmissionPolicyBinding
|
||||
type PolicyMutation = v1beta1.Mutation
|
||||
type Policy = v1.MutatingAdmissionPolicy
|
||||
type PolicyBinding = v1.MutatingAdmissionPolicyBinding
|
||||
|
||||
type PolicyHook = generic.PolicyHook[*Policy, *PolicyBinding, PolicyEvaluator]
|
||||
|
||||
type Mutator struct {
|
||||
@@ -97,8 +97,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().MutatingAdmissionPolicies().Informer(),
|
||||
f.Admissionregistration().V1beta1().MutatingAdmissionPolicyBindings().Informer(),
|
||||
f.Admissionregistration().V1().MutatingAdmissionPolicies().Informer(),
|
||||
f.Admissionregistration().V1().MutatingAdmissionPolicyBindings().Informer(),
|
||||
NewMutatingAdmissionPolicyAccessor,
|
||||
NewMutatingAdmissionPolicyBindingAccessor,
|
||||
compilePolicy,
|
||||
@@ -142,11 +142,3 @@ func (v *Variable) ReturnTypes() []*celgo.Type {
|
||||
func (v *Variable) GetName() string {
|
||||
return v.Name
|
||||
}
|
||||
|
||||
func convertv1alpha1Variables(variables []v1beta1.Variable) []cel.NamedExpressionAccessor {
|
||||
namedExpressions := make([]cel.NamedExpressionAccessor, len(variables))
|
||||
for i, variable := range variables {
|
||||
namedExpressions[i] = &Variable{Name: variable.Name, Expression: variable.Expression}
|
||||
}
|
||||
return namedExpressions
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
v1 "k8s.io/api/admissionregistration/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -42,10 +42,10 @@ import (
|
||||
|
||||
func setupTest(
|
||||
t *testing.T,
|
||||
compiler func(*mutating.Policy) mutating.PolicyEvaluator,
|
||||
) *generic.PolicyTestContext[*mutating.Policy, *mutating.PolicyBinding, mutating.PolicyEvaluator] {
|
||||
compiler func(*v1.MutatingAdmissionPolicy) mutating.PolicyEvaluator,
|
||||
) *generic.PolicyTestContext[*v1.MutatingAdmissionPolicy, *v1.MutatingAdmissionPolicyBinding, mutating.PolicyEvaluator] {
|
||||
|
||||
testContext, testCancel, err := generic.NewPolicyTestContext[*mutating.Policy, *mutating.PolicyBinding, mutating.PolicyEvaluator](
|
||||
testContext, testCancel, err := generic.NewPolicyTestContext[*v1.MutatingAdmissionPolicy, *v1.MutatingAdmissionPolicyBinding, mutating.PolicyEvaluator](
|
||||
t,
|
||||
mutating.NewMutatingAdmissionPolicyAccessor,
|
||||
mutating.NewMutatingAdmissionPolicyBindingAccessor,
|
||||
@@ -81,33 +81,33 @@ func TestBasicPatch(t *testing.T) {
|
||||
expectedAnnotations := map[string]string{"foo": "bar"}
|
||||
|
||||
// Treat all policies as setting foo annotation to bar
|
||||
testContext := setupTest(t, func(p *mutating.Policy) mutating.PolicyEvaluator {
|
||||
testContext := setupTest(t, func(p *v1.MutatingAdmissionPolicy) mutating.PolicyEvaluator {
|
||||
return mutating.PolicyEvaluator{Mutators: []patch.Patcher{annotationPatcher{expectedAnnotations}}}
|
||||
})
|
||||
|
||||
// Set up a policy and binding that match, no params
|
||||
require.NoError(t, testContext.UpdateAndWait(
|
||||
&mutating.Policy{
|
||||
&v1.MutatingAdmissionPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "policy"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1beta1.Equivalent),
|
||||
Spec: v1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1.Equivalent),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
},
|
||||
Mutations: []v1beta1.Mutation{
|
||||
Mutations: []v1.Mutation{
|
||||
{
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
ApplyConfiguration: &v1.ApplyConfiguration{
|
||||
Expression: "ignored, but required",
|
||||
},
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
PatchType: v1.PatchTypeApplyConfiguration,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&mutating.PolicyBinding{
|
||||
&v1.MutatingAdmissionPolicyBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "binding"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicyBindingSpec{
|
||||
Spec: v1.MutatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: "policy",
|
||||
},
|
||||
},
|
||||
@@ -136,7 +136,7 @@ func TestJSONPatch(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
testContext := setupTest(t, func(p *mutating.Policy) mutating.PolicyEvaluator {
|
||||
testContext := setupTest(t, func(p *v1.MutatingAdmissionPolicy) mutating.PolicyEvaluator {
|
||||
return mutating.PolicyEvaluator{
|
||||
Mutators: []patch.Patcher{smdPatcher{patch: patchObj}},
|
||||
}
|
||||
@@ -144,27 +144,27 @@ func TestJSONPatch(t *testing.T) {
|
||||
|
||||
// Set up a policy and binding that match, no params
|
||||
require.NoError(t, testContext.UpdateAndWait(
|
||||
&mutating.Policy{
|
||||
&v1.MutatingAdmissionPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "policy"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1beta1.Equivalent),
|
||||
Spec: v1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1.Equivalent),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
},
|
||||
Mutations: []v1beta1.Mutation{
|
||||
Mutations: []v1.Mutation{
|
||||
{
|
||||
JSONPatch: &v1beta1.JSONPatch{
|
||||
JSONPatch: &v1.JSONPatch{
|
||||
Expression: "ignored, but required",
|
||||
},
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
PatchType: v1.PatchTypeApplyConfiguration,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&mutating.PolicyBinding{
|
||||
&v1.MutatingAdmissionPolicyBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "binding"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicyBindingSpec{
|
||||
Spec: v1.MutatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: "policy",
|
||||
},
|
||||
},
|
||||
@@ -198,7 +198,7 @@ func TestSSAPatch(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
testContext := setupTest(t, func(p *mutating.Policy) mutating.PolicyEvaluator {
|
||||
testContext := setupTest(t, func(p *v1.MutatingAdmissionPolicy) mutating.PolicyEvaluator {
|
||||
return mutating.PolicyEvaluator{
|
||||
Mutators: []patch.Patcher{smdPatcher{patch: patchObj}},
|
||||
}
|
||||
@@ -206,27 +206,27 @@ func TestSSAPatch(t *testing.T) {
|
||||
|
||||
// Set up a policy and binding that match, no params
|
||||
require.NoError(t, testContext.UpdateAndWait(
|
||||
&mutating.Policy{
|
||||
&v1.MutatingAdmissionPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "policy"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1beta1.Equivalent),
|
||||
Spec: v1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1.Equivalent),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
},
|
||||
Mutations: []v1beta1.Mutation{
|
||||
Mutations: []v1.Mutation{
|
||||
{
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
ApplyConfiguration: &v1.ApplyConfiguration{
|
||||
Expression: "ignored, but required",
|
||||
},
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
PatchType: v1.PatchTypeApplyConfiguration,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&mutating.PolicyBinding{
|
||||
&v1.MutatingAdmissionPolicyBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "binding"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicyBindingSpec{
|
||||
Spec: v1.MutatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: "policy",
|
||||
},
|
||||
},
|
||||
@@ -265,7 +265,7 @@ func TestSSAMapList(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
testContext := setupTest(t, func(p *mutating.Policy) mutating.PolicyEvaluator {
|
||||
testContext := setupTest(t, func(p *v1.MutatingAdmissionPolicy) mutating.PolicyEvaluator {
|
||||
return mutating.PolicyEvaluator{
|
||||
Mutators: []patch.Patcher{smdPatcher{patch: patchObj}},
|
||||
}
|
||||
@@ -273,27 +273,27 @@ func TestSSAMapList(t *testing.T) {
|
||||
|
||||
// Set up a policy and binding that match, no params
|
||||
require.NoError(t, testContext.UpdateAndWait(
|
||||
&mutating.Policy{
|
||||
&v1.MutatingAdmissionPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "policy"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1beta1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1beta1.Equivalent),
|
||||
Spec: v1.MutatingAdmissionPolicySpec{
|
||||
MatchConstraints: &v1.MatchResources{
|
||||
MatchPolicy: ptr.To(v1.Equivalent),
|
||||
NamespaceSelector: &metav1.LabelSelector{},
|
||||
ObjectSelector: &metav1.LabelSelector{},
|
||||
},
|
||||
Mutations: []v1beta1.Mutation{
|
||||
Mutations: []v1.Mutation{
|
||||
{
|
||||
ApplyConfiguration: &v1beta1.ApplyConfiguration{
|
||||
ApplyConfiguration: &v1.ApplyConfiguration{
|
||||
Expression: "ignored, but required",
|
||||
},
|
||||
PatchType: v1beta1.PatchTypeApplyConfiguration,
|
||||
PatchType: v1.PatchTypeApplyConfiguration,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&mutating.PolicyBinding{
|
||||
&v1.MutatingAdmissionPolicyBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "binding"},
|
||||
Spec: v1beta1.MutatingAdmissionPolicyBindingSpec{
|
||||
Spec: v1.MutatingAdmissionPolicyBindingSpec{
|
||||
PolicyName: "policy",
|
||||
},
|
||||
},
|
||||
|
||||
@@ -421,6 +421,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
|
||||
MutatingAdmissionPolicy: {
|
||||
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
|
||||
{Version: version.MustParse("1.34"), Default: false, PreRelease: featuregate.Beta},
|
||||
{Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA},
|
||||
},
|
||||
|
||||
OpenAPIEnums: {
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
| MutablePVNodeAffinity | | | 1.35– | | | | | [code](https://cs.k8s.io/?q=%5CbMutablePVNodeAffinity%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbMutablePVNodeAffinity%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
|
||||
| MutablePodResourcesForSuspendedJobs | :ballot_box_with_check: 1.36+ | | 1.35 | 1.36– | | | | [code](https://cs.k8s.io/?q=%5CbMutablePodResourcesForSuspendedJobs%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbMutablePodResourcesForSuspendedJobs%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
|
||||
| MutableSchedulingDirectivesForSuspendedJobs | :ballot_box_with_check: 1.36+ | | 1.35 | 1.36– | | | | [code](https://cs.k8s.io/?q=%5CbMutableSchedulingDirectivesForSuspendedJobs%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbMutableSchedulingDirectivesForSuspendedJobs%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
|
||||
| MutatingAdmissionPolicy | | | 1.32–1.33 | 1.34– | | | | [code](https://cs.k8s.io/?q=%5CbMutatingAdmissionPolicy%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbMutatingAdmissionPolicy%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
|
||||
| MutatingAdmissionPolicy | :ballot_box_with_check: 1.36+ | | 1.32–1.33 | 1.34–1.35 | 1.36– | | | [code](https://cs.k8s.io/?q=%5CbMutatingAdmissionPolicy%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbMutatingAdmissionPolicy%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
|
||||
| NFTablesProxyMode | :ballot_box_with_check: 1.31+ | :closed_lock_with_key: 1.33+ | 1.29–1.30 | 1.31–1.32 | 1.33– | | | [code](https://cs.k8s.io/?q=%5CbNFTablesProxyMode%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbNFTablesProxyMode%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
|
||||
| NodeDeclaredFeatures | | | 1.35– | | | | | [code](https://cs.k8s.io/?q=%5CbNodeDeclaredFeatures%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbNodeDeclaredFeatures%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
|
||||
| NodeInclusionPolicyInPodTopologySpread | :ballot_box_with_check: 1.26+ | :closed_lock_with_key: 1.33+ | 1.25 | 1.26–1.32 | 1.33– | | | [code](https://cs.k8s.io/?q=%5CbNodeInclusionPolicyInPodTopologySpread%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbNodeInclusionPolicyInPodTopologySpread%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
|
||||
|
||||
@@ -1141,6 +1141,10 @@
|
||||
lockToDefault: false
|
||||
preRelease: Beta
|
||||
version: "1.34"
|
||||
- default: true
|
||||
lockToDefault: false
|
||||
preRelease: GA
|
||||
version: "1.36"
|
||||
- name: NFTablesProxyMode
|
||||
versionedSpecs:
|
||||
- default: false
|
||||
|
||||
@@ -157,6 +157,8 @@ var (
|
||||
gvr("admissionregistration.k8s.io", "v1alpha1", "mutatingadmissionpolicybindings"): true,
|
||||
gvr("admissionregistration.k8s.io", "v1beta1", "mutatingadmissionpolicies"): true,
|
||||
gvr("admissionregistration.k8s.io", "v1beta1", "mutatingadmissionpolicybindings"): true,
|
||||
gvr("admissionregistration.k8s.io", "v1", "mutatingadmissionpolicies"): true,
|
||||
gvr("admissionregistration.k8s.io", "v1", "mutatingadmissionpolicybindings"): true,
|
||||
}
|
||||
|
||||
parentResources = map[schema.GroupVersionResource]schema.GroupVersionResource{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user