promote MutatingAdmissionPolicy to v1: api wiring and validation

- Register v1 MutatingAdmissionPolicy and Binding in apiserver storage.
- Add defaults and validation for v1 types.
- Update storage version hash data.
- Add API testdata.
This commit is contained in:
Lalit Chauhan
2026-01-05 21:10:57 +00:00
committed by Your Name
parent 5505c010fd
commit b7c4f21d41
12 changed files with 531 additions and 5 deletions

View File

@@ -25,6 +25,7 @@ import (
"github.com/google/go-cmp/cmp"
"sigs.k8s.io/randfill"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
apiv1 "k8s.io/api/core/v1"
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
"k8s.io/apimachinery/pkg/api/apitesting/roundtrip"
@@ -191,6 +192,10 @@ func TestDefaulting(t *testing.T) {
{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "ValidatingWebhookConfigurationList"}: {},
{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingWebhookConfiguration"}: {},
{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingWebhookConfigurationList"}: {},
{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingAdmissionPolicy"}: {},
{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingAdmissionPolicyBinding"}: {},
{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingAdmissionPolicyBindingList"}: {},
{Group: "admissionregistration.k8s.io", Version: "v1", Kind: "MutatingAdmissionPolicyList"}: {},
{Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicy"}: {},
{Group: "networking.k8s.io", Version: "v1", Kind: "NetworkPolicyList"}: {},
{Group: "networking.k8s.io", Version: "v1beta1", Kind: "Ingress"}: {},
@@ -259,6 +264,26 @@ func TestDefaulting(t *testing.T) {
c.FillNoCustom(s)
s.TargetSelector = "" // need to fuzz requirement strings specially
},
// Custom fuzzer functions for admissionregistration.k8s.io/v1 types
func(s *admissionregistrationv1.MutatingAdmissionPolicySpec, c randfill.Continue) {
c.FillNoCustom(s)
s.FailurePolicy = nil // Ensure FailurePolicy is nil to trigger defaulting
s.ReinvocationPolicy = "" // Ensure ReinvocationPolicy is empty to trigger defaulting
},
func(s *admissionregistrationv1.ValidatingAdmissionPolicySpec, c randfill.Continue) {
c.FillNoCustom(s)
s.FailurePolicy = nil // Ensure FailurePolicy is nil to trigger defaulting
},
func(s *admissionregistrationv1.MatchResources, c randfill.Continue) {
c.FillNoCustom(s)
s.MatchPolicy = nil // Ensure MatchPolicy is nil to trigger defaulting
s.NamespaceSelector = nil // Ensure NamespaceSelector is nil to trigger defaulting
s.ObjectSelector = nil // Ensure ObjectSelector is nil to trigger defaulting
},
func(s *admissionregistrationv1.Rule, c randfill.Continue) {
c.FillNoCustom(s)
s.Scope = nil // Ensure Scope is nil to trigger defaulting
},
)
_, expectedChanged := typesWithDefaulting[gvk]

View File

@@ -117,3 +117,11 @@ func SetDefaults_MatchResources(obj *admissionregistrationv1.MatchResources) {
obj.ObjectSelector = &selector
}
}
// SetDefaults_MutatingAdmissionPolicySpec sets defaults for MutatingAdmissionPolicySpec
func SetDefaults_MutatingAdmissionPolicySpec(obj *admissionregistrationv1.MutatingAdmissionPolicySpec) {
if obj.FailurePolicy == nil {
policy := admissionregistrationv1.Fail
obj.FailurePolicy = &policy
}
}

View File

@@ -70,6 +70,7 @@ func RegisterDefaults(scheme *runtime.Scheme) error {
}
func SetObjectDefaults_MutatingAdmissionPolicy(in *admissionregistrationv1.MutatingAdmissionPolicy) {
SetDefaults_MutatingAdmissionPolicySpec(&in.Spec)
if in.Spec.MatchConstraints != nil {
SetDefaults_MatchResources(in.Spec.MatchConstraints)
for i := range in.Spec.MatchConstraints.ResourceRules {

View File

@@ -328,12 +328,12 @@ func findMutatingPolicyPreexistingExpressions(mutatingPolicy *admissionregistrat
for _, mc := range mutatingPolicy.Spec.MatchConditions {
preexisting.matchConditionExpressions.Insert(mc.Expression)
}
for _, v := range mutatingPolicy.Spec.Mutations {
if v.ApplyConfiguration != nil {
preexisting.applyConfigurationExpressions.Insert(v.ApplyConfiguration.Expression)
for _, m := range mutatingPolicy.Spec.Mutations {
if m.ApplyConfiguration != nil {
preexisting.applyConfigurationExpressions.Insert(m.ApplyConfiguration.Expression)
}
if v.JSONPatch != nil {
preexisting.jsonPatchExpressions.Insert(v.JSONPatch.Expression)
if m.JSONPatch != nil {
preexisting.jsonPatchExpressions.Insert(m.JSONPatch.Expression)
}
}
return preexisting

View File

@@ -88,6 +88,8 @@ var GVRToStorageVersionHash = map[string]string{
"apps/v1/statefulsets": "H+vl74LkKdo=",
"admissionregistration.k8s.io/v1/mutatingwebhookconfigurations": "Sqi0GUgDaX0=",
"admissionregistration.k8s.io/v1/validatingwebhookconfigurations": "B0wHjQmsGNk=",
"admissionregistration.k8s.io/v1/mutatingadmissionpolicies": "LYmCf+UMVdg=",
"admissionregistration.k8s.io/v1/mutatingadmissionpolicybindings": "90V5FRZZ3Zg=",
"admissionregistration.k8s.io/v1/validatingadmissionpolicies": "6OxvlMmQ6is=",
"admissionregistration.k8s.io/v1/validatingadmissionpolicybindings": "v9715VZqakg=",
"events.k8s.io/v1/events": "r2yiGXH7wu8=",

View File

@@ -116,6 +116,25 @@ func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.API
storage[resource] = policyBindingStorage
}
// mutatingadmissionpolicies
if resource := "mutatingadmissionpolicies"; apiResourceConfigSource.ResourceEnabled(admissionregistrationv1.SchemeGroupVersion.WithResource(resource)) {
policyStorage, err := mutatingadmissionpolicystorage.NewREST(restOptionsGetter, p.Authorizer, r)
if err != nil {
return storage, err
}
policyGetter = policyStorage
storage[resource] = policyStorage
}
// mutatingadmissionpolicybindings
if resource := "mutatingadmissionpolicybindings"; apiResourceConfigSource.ResourceEnabled(admissionregistrationv1.SchemeGroupVersion.WithResource(resource)) {
mutationpolicybindingstorage, err := mutationpolicybindingstorage.NewREST(restOptionsGetter, p.Authorizer, &mutationpolicybindingstorage.DefaultPolicyGetter{Getter: policyGetter}, r)
if err != nil {
return storage, err
}
storage[resource] = mutationpolicybindingstorage
}
return storage, nil
}

View File

@@ -0,0 +1,148 @@
{
"kind": "MutatingAdmissionPolicy",
"apiVersion": "admissionregistration.k8s.io/v1",
"metadata": {
"name": "nameValue",
"generateName": "generateNameValue",
"namespace": "namespaceValue",
"selfLink": "selfLinkValue",
"uid": "uidValue",
"resourceVersion": "resourceVersionValue",
"generation": 7,
"creationTimestamp": "2008-01-01T01:01:01Z",
"deletionTimestamp": "2009-01-01T01:01:01Z",
"deletionGracePeriodSeconds": 10,
"labels": {
"labelsKey": "labelsValue"
},
"annotations": {
"annotationsKey": "annotationsValue"
},
"ownerReferences": [
{
"apiVersion": "apiVersionValue",
"kind": "kindValue",
"name": "nameValue",
"uid": "uidValue",
"controller": true,
"blockOwnerDeletion": true
}
],
"finalizers": [
"finalizersValue"
],
"managedFields": [
{
"manager": "managerValue",
"operation": "operationValue",
"apiVersion": "apiVersionValue",
"time": "2004-01-01T01:01:01Z",
"fieldsType": "fieldsTypeValue",
"fieldsV1": {},
"subresource": "subresourceValue"
}
]
},
"spec": {
"paramKind": {
"apiVersion": "apiVersionValue",
"kind": "kindValue"
},
"matchConstraints": {
"namespaceSelector": {
"matchLabels": {
"matchLabelsKey": "matchLabelsValue"
},
"matchExpressions": [
{
"key": "keyValue",
"operator": "operatorValue",
"values": [
"valuesValue"
]
}
]
},
"objectSelector": {
"matchLabels": {
"matchLabelsKey": "matchLabelsValue"
},
"matchExpressions": [
{
"key": "keyValue",
"operator": "operatorValue",
"values": [
"valuesValue"
]
}
]
},
"resourceRules": [
{
"resourceNames": [
"resourceNamesValue"
],
"operations": [
"operationsValue"
],
"apiGroups": [
"apiGroupsValue"
],
"apiVersions": [
"apiVersionsValue"
],
"resources": [
"resourcesValue"
],
"scope": "scopeValue"
}
],
"excludeResourceRules": [
{
"resourceNames": [
"resourceNamesValue"
],
"operations": [
"operationsValue"
],
"apiGroups": [
"apiGroupsValue"
],
"apiVersions": [
"apiVersionsValue"
],
"resources": [
"resourcesValue"
],
"scope": "scopeValue"
}
],
"matchPolicy": "matchPolicyValue"
},
"variables": [
{
"name": "nameValue",
"expression": "expressionValue"
}
],
"mutations": [
{
"patchType": "patchTypeValue",
"applyConfiguration": {
"expression": "expressionValue"
},
"jsonPatch": {
"expression": "expressionValue"
}
}
],
"failurePolicy": "failurePolicyValue",
"matchConditions": [
{
"name": "nameValue",
"expression": "expressionValue"
}
],
"reinvocationPolicy": "reinvocationPolicyValue"
}
}

View File

@@ -0,0 +1,94 @@
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicy
metadata:
annotations:
annotationsKey: annotationsValue
creationTimestamp: "2008-01-01T01:01:01Z"
deletionGracePeriodSeconds: 10
deletionTimestamp: "2009-01-01T01:01:01Z"
finalizers:
- finalizersValue
generateName: generateNameValue
generation: 7
labels:
labelsKey: labelsValue
managedFields:
- apiVersion: apiVersionValue
fieldsType: fieldsTypeValue
fieldsV1: {}
manager: managerValue
operation: operationValue
subresource: subresourceValue
time: "2004-01-01T01:01:01Z"
name: nameValue
namespace: namespaceValue
ownerReferences:
- apiVersion: apiVersionValue
blockOwnerDeletion: true
controller: true
kind: kindValue
name: nameValue
uid: uidValue
resourceVersion: resourceVersionValue
selfLink: selfLinkValue
uid: uidValue
spec:
failurePolicy: failurePolicyValue
matchConditions:
- expression: expressionValue
name: nameValue
matchConstraints:
excludeResourceRules:
- apiGroups:
- apiGroupsValue
apiVersions:
- apiVersionsValue
operations:
- operationsValue
resourceNames:
- resourceNamesValue
resources:
- resourcesValue
scope: scopeValue
matchPolicy: matchPolicyValue
namespaceSelector:
matchExpressions:
- key: keyValue
operator: operatorValue
values:
- valuesValue
matchLabels:
matchLabelsKey: matchLabelsValue
objectSelector:
matchExpressions:
- key: keyValue
operator: operatorValue
values:
- valuesValue
matchLabels:
matchLabelsKey: matchLabelsValue
resourceRules:
- apiGroups:
- apiGroupsValue
apiVersions:
- apiVersionsValue
operations:
- operationsValue
resourceNames:
- resourceNamesValue
resources:
- resourcesValue
scope: scopeValue
mutations:
- applyConfiguration:
expression: expressionValue
jsonPatch:
expression: expressionValue
patchType: patchTypeValue
paramKind:
apiVersion: apiVersionValue
kind: kindValue
reinvocationPolicy: reinvocationPolicyValue
variables:
- expression: expressionValue
name: nameValue

View File

@@ -0,0 +1,139 @@
{
"kind": "MutatingAdmissionPolicyBinding",
"apiVersion": "admissionregistration.k8s.io/v1",
"metadata": {
"name": "nameValue",
"generateName": "generateNameValue",
"namespace": "namespaceValue",
"selfLink": "selfLinkValue",
"uid": "uidValue",
"resourceVersion": "resourceVersionValue",
"generation": 7,
"creationTimestamp": "2008-01-01T01:01:01Z",
"deletionTimestamp": "2009-01-01T01:01:01Z",
"deletionGracePeriodSeconds": 10,
"labels": {
"labelsKey": "labelsValue"
},
"annotations": {
"annotationsKey": "annotationsValue"
},
"ownerReferences": [
{
"apiVersion": "apiVersionValue",
"kind": "kindValue",
"name": "nameValue",
"uid": "uidValue",
"controller": true,
"blockOwnerDeletion": true
}
],
"finalizers": [
"finalizersValue"
],
"managedFields": [
{
"manager": "managerValue",
"operation": "operationValue",
"apiVersion": "apiVersionValue",
"time": "2004-01-01T01:01:01Z",
"fieldsType": "fieldsTypeValue",
"fieldsV1": {},
"subresource": "subresourceValue"
}
]
},
"spec": {
"policyName": "policyNameValue",
"paramRef": {
"name": "nameValue",
"namespace": "namespaceValue",
"selector": {
"matchLabels": {
"matchLabelsKey": "matchLabelsValue"
},
"matchExpressions": [
{
"key": "keyValue",
"operator": "operatorValue",
"values": [
"valuesValue"
]
}
]
},
"parameterNotFoundAction": "parameterNotFoundActionValue"
},
"matchResources": {
"namespaceSelector": {
"matchLabels": {
"matchLabelsKey": "matchLabelsValue"
},
"matchExpressions": [
{
"key": "keyValue",
"operator": "operatorValue",
"values": [
"valuesValue"
]
}
]
},
"objectSelector": {
"matchLabels": {
"matchLabelsKey": "matchLabelsValue"
},
"matchExpressions": [
{
"key": "keyValue",
"operator": "operatorValue",
"values": [
"valuesValue"
]
}
]
},
"resourceRules": [
{
"resourceNames": [
"resourceNamesValue"
],
"operations": [
"operationsValue"
],
"apiGroups": [
"apiGroupsValue"
],
"apiVersions": [
"apiVersionsValue"
],
"resources": [
"resourcesValue"
],
"scope": "scopeValue"
}
],
"excludeResourceRules": [
{
"resourceNames": [
"resourceNamesValue"
],
"operations": [
"operationsValue"
],
"apiGroups": [
"apiGroupsValue"
],
"apiVersions": [
"apiVersionsValue"
],
"resources": [
"resourcesValue"
],
"scope": "scopeValue"
}
],
"matchPolicy": "matchPolicyValue"
}
}
}

View File

@@ -0,0 +1,90 @@
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingAdmissionPolicyBinding
metadata:
annotations:
annotationsKey: annotationsValue
creationTimestamp: "2008-01-01T01:01:01Z"
deletionGracePeriodSeconds: 10
deletionTimestamp: "2009-01-01T01:01:01Z"
finalizers:
- finalizersValue
generateName: generateNameValue
generation: 7
labels:
labelsKey: labelsValue
managedFields:
- apiVersion: apiVersionValue
fieldsType: fieldsTypeValue
fieldsV1: {}
manager: managerValue
operation: operationValue
subresource: subresourceValue
time: "2004-01-01T01:01:01Z"
name: nameValue
namespace: namespaceValue
ownerReferences:
- apiVersion: apiVersionValue
blockOwnerDeletion: true
controller: true
kind: kindValue
name: nameValue
uid: uidValue
resourceVersion: resourceVersionValue
selfLink: selfLinkValue
uid: uidValue
spec:
matchResources:
excludeResourceRules:
- apiGroups:
- apiGroupsValue
apiVersions:
- apiVersionsValue
operations:
- operationsValue
resourceNames:
- resourceNamesValue
resources:
- resourcesValue
scope: scopeValue
matchPolicy: matchPolicyValue
namespaceSelector:
matchExpressions:
- key: keyValue
operator: operatorValue
values:
- valuesValue
matchLabels:
matchLabelsKey: matchLabelsValue
objectSelector:
matchExpressions:
- key: keyValue
operator: operatorValue
values:
- valuesValue
matchLabels:
matchLabelsKey: matchLabelsValue
resourceRules:
- apiGroups:
- apiGroupsValue
apiVersions:
- apiVersionsValue
operations:
- operationsValue
resourceNames:
- resourceNamesValue
resources:
- resourcesValue
scope: scopeValue
paramRef:
name: nameValue
namespace: namespaceValue
parameterNotFoundAction: parameterNotFoundActionValue
selector:
matchExpressions:
- key: keyValue
operator: operatorValue
values:
- valuesValue
matchLabels:
matchLabelsKey: matchLabelsValue
policyName: policyNameValue