gatekeeper
gatekeeper copied to clipboard
Delete functionality in mutations
I would like to see a feature that enables us to delete certain values instead of assign. For instance, to replace the RequireDropCapabilities functionality of PodSecurityPolicies, you not only need to add a value to the "spec.containers[].securityContext.capabilities.drop" array, but you also need to remove it specifically from the "spec.containers[].securityContext.capabilities.add" array.
For instance:
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
name: drop-all-capabilities-but
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
match:
scope: Namespaced
kinds:
- apiGroups: ["*"]
kinds: ["Pod"]
location: "spec.containers[name:*].securityContext.capabilities"
parameters:
assignIf:
add:
in: CAP_SETUID
delete:
add: CAP_SETUID
Environment:
- Gatekeeper version: 3.4.0
- Kubernetes version: 1.20.2
I'd like to think through whether this could be used to create a divergent system, but support the idea in principle.
I think it's likely fine, as I don't see much difference between deleting a field and assigning it, say null or and empty object.
@maxsmythe Thanks for your reply! My request is about deleting a specific value from an array though, not a complete field.
Understood -- if Assign can do one, it can do both.
Although capabilities is not a keyed array... that is different
This sounds like the inverse of the ListInjector proposed mutator:
https://github.com/open-policy-agent/gatekeeper/issues/1358#issuecomment-864324114
instead of "append only if missing", it's "remove if present"
I'd like to think through whether this could be used to create a divergent system
Though the example and capability that @maartenvdezz requested here is about set membership, being able to remove fields in general seems like you could create oscillation.
Consider:
- Assign A
If field "x" does not exist, assign 1 to field "y." - Assign B
If field "y" exists, assign 1 to field "x." - Assign C
If field "x" exists, remove field "x."
If that's possible with Gatekeeper, we'd wind up with the following sequence:
{}{"y": 1}by virtue of A{"x": 1, "y": 1}by virtue of B{"y": 1}by virtue of C{"x": 1, "y": 1}by virtue of B{"y": 1}by virtue of C- ...
Is my analysis correct?
Currently we don't allow for cross-field checking, so if you're assigning to field x you can only test x (or its parents). This means Assign A and Assign B can't currently be written.
I think the system above would converge, since convergence is about whether the system eventually reaches a stable value. In this case, the final value after Assign C converges to {"y": 1}
Currently we don't allow for cross-field checking, so if you're assigning to field
xyou can only testx(or its parents). This means Assign A and Assign B can't currently be written.
Oh, I missed that in the documentation. It doesn't mention which fields one can inspect.
I think the system above would converge, since convergence is about whether the system eventually reaches a stable value. In this case, the final value after Assign C converges to
{"y": 1}
Would'n Assign B and Assign C keep duking it out, alternately inserting field "x" and then removing it again, or would Assign B not run again after Assign A adds field "x" back in?
If you keep iterating, you'll always get {"y": 1} after the third mutator is applied.
In order to get infinite mutations, you'd need a cycle:
- A: if x, unset z
- B: if z, unset y
- C: if y, unset x
- D: if z, set x
- E: if y, set z
- F: if x, set y
iterations:
- input: {x, z}
- 1st output of F: {x, y}
- 2nd output of F: {y, z}
- 3rd output of F: {x, z}
Here the output bounces between {x, z}, {x, y}, and {y, z}
the sets are a bit of a metaphor, you can replace "add to set" with set spec.x = 1, or similar, and "unset" with delete spec.x or similar.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.
We also have a need for this.
Does ModifySet work for you?
It can either add or remove strings from a list:
https://open-policy-agent.github.io/gatekeeper/website/docs/mutation#modifyset
We looked at it but based on our understanding of the docs it can only remove values from a list, not keys (that are optional) from an object.
Ah, yeah. The ability to remove keys from an object should be added to Assign
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.
/active
Looking to use this to delete/remove/null .spec.containers[].resources.limits.cpu
I need this.
+1 Would be helpful for us as well
+1 Removing the CPU limit is also my use case.