diff --git a/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/customizations.yaml b/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/customizations.yaml new file mode 100644 index 000000000..13903f22d --- /dev/null +++ b/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/customizations.yaml @@ -0,0 +1,87 @@ +apiVersion: config.karmada.io/v1alpha1 +kind: ResourceInterpreterCustomization +metadata: + name: declarative-configuration-policy +spec: + target: + apiVersion: kyverno.io/v1 + kind: Policy + customizations: + healthInterpretation: + luaScript: > + function InterpretHealth(observedObj) + if observedObj.status ~= nil and observedObj.status.ready ~= nil then + return observedObj.status.ready + end + if observedObj.status ~= nil and observedObj.status.conditions ~= nil then + for conditionIndex = 1, #observedObj.status.conditions do + if observedObj.status.conditions[conditionIndex].type == 'Ready' and observedObj.status.conditions[conditionIndex].status == 'True' and observedObj.status.conditions[conditionIndex].reason == 'Succeeded' then + return true + end + end + end + return false + end + statusAggregation: + luaScript: > + function AggregateStatus(desiredObj, statusItems) + if statusItems == nil then + return desiredObj + end + desiredObj.status = {} + desiredObj.status.conditions = {} + rulecount = {} + rulecount.validate = 0 + rulecount.generate = 0 + rulecount.mutate = 0 + rulecount.verifyimages = 0 + conditions = {} + local conditionsIndex = 1 + for i = 1, #statusItems do + if statusItems[i].status ~= nil and statusItems[i].status.autogen ~= nil then + desiredObj.status.autogen = statusItems[i].status.autogen + end + if statusItems[i].status ~= nil and statusItems[i].status.ready ~= nil then + desiredObj.status.ready = statusItems[i].status.ready + end + if statusItems[i].status ~= nil and statusItems[i].status.rulecount ~= nil then + rulecount.validate = rulecount.validate + statusItems[i].status.rulecount.validate + rulecount.generate = rulecount.generate + statusItems[i].status.rulecount.generate + rulecount.mutate = rulecount.mutate + statusItems[i].status.rulecount.mutate + rulecount.verifyimages = rulecount.verifyimages + statusItems[i].status.rulecount.verifyimages + end + if statusItems[i].status ~= nil and statusItems[i].status.conditions ~= nil then + for conditionIndex = 1, #statusItems[i].status.conditions do + statusItems[i].status.conditions[conditionIndex].message = statusItems[i].clusterName..'='..statusItems[i].status.conditions[conditionIndex].message + hasCondition = false + for index = 1, #conditions do + if conditions[index].type == statusItems[i].status.conditions[conditionIndex].type and conditions[index].status == statusItems[i].status.conditions[conditionIndex].status and conditions[index].reason == statusItems[i].status.conditions[conditionIndex].reason then + conditions[index].message = conditions[index].message..', '..statusItems[i].status.conditions[conditionIndex].message + hasCondition = true + break + end + end + if not hasCondition then + conditions[conditionsIndex] = statusItems[i].status.conditions[conditionIndex] + conditionsIndex = conditionsIndex + 1 + end + end + end + end + desiredObj.status.rulecount = rulecount + desiredObj.status.conditions = conditions + return desiredObj + end + statusReflection: + luaScript: > + function ReflectStatus (observedObj) + status = {} + if observedObj == nil or observedObj.status == nil then + return status + end + status.autogen = observedObj.status.autogen + status.conditions = observedObj.status.conditions + status.ready = observedObj.status.ready + status.rulecount = observedObj.status.rulecount + return status + end diff --git a/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/customizations_tests.yaml b/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/customizations_tests.yaml new file mode 100644 index 000000000..dec129d7e --- /dev/null +++ b/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/customizations_tests.yaml @@ -0,0 +1,8 @@ +tests: + - desiredInputPath: testdata/desired-policy.yaml + statusInputPath: testdata/status-file.yaml + operation: AggregateStatus + - observedInputPath: testdata/observed-policy.yaml + operation: InterpretHealth + - observedInputPath: testdata/observed-policy.yaml + operation: InterpretStatus diff --git a/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/testdata/desired-policy.yaml b/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/testdata/desired-policy.yaml new file mode 100644 index 000000000..f69acb336 --- /dev/null +++ b/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/testdata/desired-policy.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: sample + namespace: test-policy +spec: + validationFailureAction: Enforce + rules: + - name: require-pod-purpose-label + match: + any: + - resources: + kinds: + - Pod + validate: + message: "You must have label `purpose` with value `production` set on all new Pod in test-policy Namespace." + pattern: + metadata: + labels: + purpose: production diff --git a/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/testdata/observed-policy.yaml b/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/testdata/observed-policy.yaml new file mode 100644 index 000000000..b972ee980 --- /dev/null +++ b/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/testdata/observed-policy.yaml @@ -0,0 +1,86 @@ +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: sample + namespace: test-policy +spec: + validationFailureAction: Enforce + rules: + - name: require-pod-purpose-label + match: + any: + - resources: + kinds: + - Pod + validate: + message: "You must have label `purpose` with value `production` set on all new Pod in test-policy Namespace." + pattern: + metadata: + labels: + purpose: production +status: + autogen: + rules: + - exclude: + resources: {} + generate: + clone: {} + cloneList: {} + match: + any: + - resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + - ReplicaSet + - ReplicationController + resources: {} + mutate: {} + name: autogen-require-pod-purpose-label + validate: + message: You must have label `purpose` with value `production` set on all + new Pod in test-policy Namespace. + pattern: + spec: + template: + metadata: + labels: + purpose: production + - exclude: + resources: {} + generate: + clone: {} + cloneList: {} + match: + any: + - resources: + kinds: + - CronJob + resources: {} + mutate: {} + name: autogen-cronjob-require-pod-purpose-label + validate: + message: You must have label `purpose` with value `production` set on all + new Pod in test-policy Namespace. + pattern: + spec: + jobTemplate: + spec: + template: + metadata: + labels: + purpose: production + conditions: + - lastTransitionTime: "2023-05-07T09:19:06Z" + message: "" + reason: Succeeded + status: "True" + type: Ready + ready: true + rulecount: + generate: 0 + mutate: 0 + validate: 1 + verifyimages: 0 diff --git a/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/testdata/status-file.yaml b/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/testdata/status-file.yaml new file mode 100644 index 000000000..17cda3cd4 --- /dev/null +++ b/pkg/resourceinterpreter/default/thirdparty/resourcecustomizations/kyverno.io/v1/Policy/testdata/status-file.yaml @@ -0,0 +1,119 @@ +applied: true +clusterName: member2 +health: Healthy +status: + autogen: + rules: + - exclude: [] + generate: [] + match: + any: + - resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + - ReplicaSet + - ReplicationController + name: autogen-require-pod-purpose-label + validate: + message: You must have label `purpose` with value `production` set on + all new Pod in test-policy Namespace. + pattern: + spec: + template: + metadata: + labels: + purpose: production + - exclude: [] + generate: [] + match: + any: + - resources: + kinds: + - CronJob + name: autogen-cronjob-require-pod-purpose-label + validate: + message: You must have label `purpose` with value `production` set on + all new Pod in test-policy Namespace. + pattern: + spec: + jobTemplate: + spec: + template: + metadata: + labels: + purpose: production + conditions: + - lastTransitionTime: "2023-05-07T09:19:06Z" + message: "" + reason: Succeeded + status: "True" + type: Ready + ready: true + rulecount: + generate: 0 + mutate: 0 + validate: 1 + verifyimages: 0 +--- +applied: true +clusterName: member3 +health: Healthy +status: + autogen: + rules: + - exclude: [] + generate: [] + match: + any: + - resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + - ReplicaSet + - ReplicationController + name: autogen-require-pod-purpose-label + validate: + message: You must have label `purpose` with value `production` set on + all new Pod in test-policy Namespace. + pattern: + spec: + template: + metadata: + labels: + purpose: production + - exclude: [] + generate: [] + match: + any: + - resources: + kinds: + - CronJob + name: autogen-cronjob-require-pod-purpose-label + validate: + message: You must have label `purpose` with value `production` set on + all new Pod in test-policy Namespace. + pattern: + spec: + jobTemplate: + spec: + template: + metadata: + labels: + purpose: production + conditions: + - lastTransitionTime: "2023-05-07T09:19:06Z" + message: "" + reason: Succeeded + status: "True" + type: Ready + ready: true + rulecount: + generate: 0 + mutate: 0 + validate: 1 + verifyimages: 0