From 949ffa68ce86642a835fb0b0f20c9bc33fb03f8f Mon Sep 17 00:00:00 2001 From: aerosouund Date: Sun, 22 Sep 2024 16:19:40 +0300 Subject: [PATCH] docs: Add high level description for mutation feature Signed-off-by: aerosouund --- proposals/mutation-support-cli.md | 167 +++++++++++++++++++++++++++--- 1 file changed, 154 insertions(+), 13 deletions(-) diff --git a/proposals/mutation-support-cli.md b/proposals/mutation-support-cli.md index 2ecefaf..1757db7 100644 --- a/proposals/mutation-support-cli.md +++ b/proposals/mutation-support-cli.md @@ -63,17 +63,165 @@ The introduction of this error message was required as a guardrail for when the ## Proposal -The CLI isn't going to mutate actual resources, its only required to output the changes that will be made by a mutation rather than the original resource in case of a mutation +### apply -## Example +The apply command will receive an additional flag `--target-resource`. this flag can be passed multiple times for single resources. e.g: -This example adds the label `foo=bar` to deployments in the `secure` namespace +```bash +kyverno apply policy-with-mutate-existing.yaml --resource=trigger1.yaml --resource=trigger2.yaml --target-resource=resource1.yaml --target-resource=resource2.yaml +``` + +Or given a directory containing resources + +```bash +kyverno apply policy-with-mutate-existing.yaml /path/to/trigger/resources --target-resource=/path/to/resources +``` + +When this flag is passed but the policy or policies have no mutate existing, the behavior should be to ignore the flag. +When this flag is not passed but the policy has mutate existing rules, it should not error. but should generate a warning that no resources have been passed. and the rule evaluation should be **SKIPPED**. +The target resource flag being passed here maps to the unchanged resource, the apply command will output the mutated resource if succeded + + +### test + +two extra keys will be added to the test yaml definition to define the behavior of mutate existing with the test command + +```yaml +apiVersion: cli.kyverno.io/v1alpha1 +kind: Test +metadata: + name: kyverno-test +policies: + - + - +resources: + - + - +exceptions: + - + - +targetResources: # This will be added + - +variables: variables.yaml # This will receive a new key for mutation target variables +userinfo: user_info.yaml +results: +- policy: + isValidatingAdmissionPolicy: false + rule: + resources: + - + - + patchedResources: # Mutated resources will be specified here, separated by --- + generatedResource: + - + - + cloneSourceResource: + kind: + result: pass +``` + +The schema of the variables file will be changed as follows: + +```yaml +apiVersion: cli.kyverno.io/v1alpha1 +kind: Values +metadata: + name: values +# existing keys +targetResources: + - name: nginx-demo1 + values: + request.operation: CREATE + - name: nginx-demo2 + values: + request.operation: UPDATE +``` + +The key `targetResources` will be added and its type is an array of object containing two keys: `name` of type string and values of type `map[string]interface{}` or a mapping of string to anything. + +These additions will be optional, all of them will be ignored (whatever value being put to them will not be accounted for) if the policy passed has no mutate existing + +### Examples +This example adds data to a `ConfigMap` on namespace creation + +`pol.yaml` ```yaml apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: policy + name: configmap-policy +spec: + mutateExistingOnPolicyUpdate: true + rules: + - name: configmap-update + match: + any: + - resources: + kinds: + - Namespace + operations: + - "CREATE" + mutate: + targets: + - apiVersion: v1 + kind: ConfigMap + namespace: "test" + name: "cm1" + patchStrategicMerge: + data: + monitored-ns: "{{ request.object.metadata.name }}" +``` + +`ns.yaml` +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: staging +``` + +`cm.yaml` +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm + namespace: test +data: {} +``` + +Invocation: +`kyverno apply pol.yaml --resource=ns.yaml --target-resource=cm.yaml` + +Should output: + +``` +Applying 1 policy rule(s) to 1 resource(s)... + +mutate policy policy applied to test/ConfigMap/cm: +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm + namespace: test +data: + monitored-ns: staging +--- + +pass: 1, fail: 0, warn: 0, error: 0, skip: 0 +``` + +--- + +This example adds the label `foo=bar` to deployments in the `secure` namespace in cluster mode + +`pol.yaml` +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: deployment-policy spec: mutateExistingOnPolicyUpdate: true rules: @@ -97,7 +245,7 @@ spec: ``` Invocation: -`kyverno apply ~/policies/pol.yaml --cluster -n secure` +`kyverno apply pol.yaml --cluster -n secure` Should output: @@ -109,12 +257,7 @@ apiVersion: apps/v1 kind: Deployment metadata: annotations: - foo: bar <<< SHOULD REFLECT THE MODIFIED RESOURCE - deployment.kubernetes.io/revision: "1" - kubectl.kubernetes.io/last-applied-configuration: | - {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"nginx-deployment","namespace":"secure"},"spec":{"replicas":3,"selector":{"matchLabels":{"app":"nginx"}},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx:1.21.1","name":"nginx","ports":[{"containerPort":80}]}]}}}} - creationTimestamp: "2024-07-29T13:18:13Z" - generation: 2 + foo: bar <<< The mutated cluster resource // omitted fields spec: progressDeadlineSeconds: 600 @@ -164,13 +307,11 @@ status: status: "True" type: Available observedGeneration: 2 - --- pass: 1, fail: 0, warn: 0, error: 0, skip: 0 ``` - ## Implementation There are two scenarios that need to be supported in the implementation: