[Enhancement] Better documentation on variable shortcuts
Description
I was attempting to do what I thought would be a simple task of annotating any mutated objects with the policy and rule that caused the annotation. (I realize this could have issues with cascaded mutations).
However, I found that the shortcuts documentation for relative variables $(./../../foo/bar) seems to be lacking a bit. I spent an unnecessary amount of time trying to do the simple task of annotating mutated records with the policy and rule name, and in the end was unable to figure out how to obtain the policy name. I feel like some of this should be accessible in a more general name.
- The documentation only mentions relative URLs, does not mention that absolute References also work $(/name)
- The number of levels that you have to go "UP" does not make sense to me given the rule spec.
- The whole Policy does not appear to be available, since
/nameis the rule. I was attempting to accessmetadata/namefor the policy -- Is there any way to gain access to this in the mutation?
I dug into the code a little to look at some of the tests because there appeared to be more examples there than in the docs..
Thanks!
Examples:
apiVersion: v1
kind: Service
metadata:
name: httpbin-lb
namespace: test
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
selector:
app: httpbin
sessionAffinity: None
type: LoadBalancer
Policy:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: test-policy
annotations:
foo: bar
spec:
rules:
- name: test-rule
match:
any:
- resources:
kinds:
- Service
mutate:
patchStrategicMerge:
metadata:
annotations:
# This fails, tried numerous different ./../../../ etc
# my.io/kyverno-policy: "$(./../../../../../../../../../metadata/name)"
my.io/kyverno-rule: "$(./../../../../../../../../name)"
# The above depth is confusing based on the rule spec.
# error="policy contains invalid variables: variable substitution failed for rule test-rule: got nil resolved variable $(./../../../../name) at path /mutate/patchStrategicMerge/metadata/annotations/my.io\\/kyverno-rule2: <nil>"
# my.io/kyverno-rule2: "$(./../../../../name)"
my.io/kyverno-rule-absolute: "$(/name)"
Results:
policy test-policy applied to test/Service/httpbin-lb:
apiVersion: v1
kind: Service
metadata:
annotations:
my.io/kyverno-rule: test-rule
my.io/kyverno-rule-absolute: test-rule
name: httpbin-lb
namespace: test
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
selector:
app: httpbin
sessionAffinity: None
type: LoadBalancer
Slack discussion
No response
For reference regarding item 2, here's the flattened policy rule:
% yq -o json <test-relative.yaml|gron
json = {};
json.apiVersion = "kyverno.io/v1";
json.kind = "ClusterPolicy";
json.metadata.annotations = {};
json.metadata.annotations.foo = "bar";
json.metadata.name = "test-policy";
...
json.spec.rules[0].match.any[0].resources = {};
json.spec.rules[0].match.any[0].resources.kinds = [];
json.spec.rules[0].match.any[0].resources.kinds[0] = "Service";
json.spec.rules[0].mutate = {};
json.spec.rules[0].mutate.patchStrategicMerge = {};
json.spec.rules[0].mutate.patchStrategicMerge.metadata = {};
json.spec.rules[0].mutate.patchStrategicMerge.metadata.annotations = {};
json.spec.rules[0].mutate.patchStrategicMerge.metadata.annotations["my.io/kyverno-rule"] = "$(./../../../../../../../../name)";
json.spec.rules[0].mutate.patchStrategicMerge.metadata.annotations["my.io/kyverno-rule-absolute"] = "$(/name)";
json.spec.rules[0].name = "test-rule";
Given that, I would expect from the "annotations" that the rule2 annotation would go back 4 dots/levels to reach /name, but as shown in my example, that is not the case.
# error="policy contains invalid variables: variable substitution failed for rule test-rule: got nil resolved variable $(./../../../../name) at path /mutate/patchStrategicMerge/metadata/annotations/my.io\\/kyverno-rule2: <nil>"
my.io/kyverno-rule2: "$(./../../../../name)"