New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New operators #2543
New operators #2543
Conversation
Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>
Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>
Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>
Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>
Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>
@anushkamittal20 This is great to see you're adding support for these. At some point, please provide proof manifests which demonstrate their operation so it's in accordance with the proposal here or if it deviates at all. |
Hey @chipzoller I have taken reference from your comment here to build these operators. I will try to add some proof manifest for the same, I have added some test cases too, I will add more from the examples you have provided. |
Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@anushkamittal20 - we also need to update the OpenAPIv3 schema and generate CRDs for these changes:
https://github.com/kyverno/kyverno/blob/main/pkg/api/kyverno/v1/policy_types.go#L211
Thank you @JimBugwadia I will make the suggested changes. |
Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @anushkamittal20 - a few comments regarding this PR:
- please check and address e2e test failure
- looks like there are additional changes in the manifests, can you merge latest main to sync up?
- It would be good to attach the results for real policy application in a live cluster
Please use the label to track the milestone for a PR if the fixing issue is already included in a specific milestone. |
Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>
Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>
Signed-off-by: anushkamittal20 <anumittal4641@gmail.com>
Is this planned for 1.5.1 now? If so, need to update corresponding docs PR and issue to match. |
Typically, enhancements should go to the next |
I agree, this seems more appropriate for 1.6.0. |
Sure. I'm currently using label milestone 1.5.1 to track all PRs. We can update the label once finalize it. |
@anushkamittal20 - the intent is to support multiple types, as documented in the code comment: // anysetExistsInArray checks if any key is a subset of value
// The value can be a string, an array of strings, or a JSON format
// array of strings (e.g. ["val1", "val2", "val3"].
// notIn argument if set to true will check for NotIn
func anySetExistsInArray(key []string, value interface{}, log logr.Logger, anyNotIn bool) (invalidType bool, keyExists bool) {
The line you referenced seems to be trying to handle the JSON Map as a string case, and line 84 above is for the single string case. However, there is a potential bug here - I think we should be comparing to https://github.com/kyverno/kyverno/blob/main/pkg/engine/variables/operator/anyin.go#L82 Please add a unit test case for this. |
Hey @chipzoller I was going through this and I think this behaviour is right. |
Hi @anushkamittal20, the scenario you're describing would be of So, basically, any time there is a key with more than one string being compared in |
@chipzoller understood, so I should add some sort of count to check all present.
here |
Yes, wildcard in value is a bit of a different situation. In those case it may be possible for all the strings in the key to be found in the value if the value contains a glob which is common to ALL the entries in the key. Like this: Many-to-one Source: ["gray","green","grass"] compare that to this next one where the glob is different Source: ["gray","green","grass"] |
Understood @chipzoller |
@anushkamittal20 based on the latest tag after #2704 was committed, I don't see the wildcard case working properly. I'm not sure if this was supposed to be part of that PR or not. EDIT: I see that's covered separately here. apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: operator-test
spec:
validationFailureAction: enforce
background: false
rules:
- name: operator-test
match:
resources:
kinds:
- Pod
validate:
deny:
conditions:
any:
- key: ["gray","green","grass"]
operator: AllNotIn
value: "gr*" Submitting a Pod (regardless of its contents) should result in a pass because the destination value is a wildcard and all entries in the key begin with |
@anushkamittal20 I am seeing that in a Test policy: apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-cap-add
spec:
validationFailureAction: enforce
background: false
rules:
# Checks initContainers to ensure they don't add anything other than "something".
- name: check-cap-add-initcontainers
match:
resources:
kinds:
- Pod
preconditions:
all:
- key: "{{request.operation}}"
operator: In
value:
- CREATE
- UPDATE
# Check if initContainers even exist in the Pod
- key: "{{ request.object.spec.initContainers[] | length(@) }}"
operator: GreaterThanOrEquals
value: 1
validate:
message: The only capability that may be explicitly added is `something`.
foreach:
- list: "request.object.spec.initContainers[].securityContext.capabilities"
deny:
conditions:
any:
# Loop over the `add[]` array in each container and deny if anything other than the "something" capability has been added.
- key: "{{ element.add }}"
operator: AnyNotIn
value: something
# Checks containers to ensure they don't add anything other than "something".
- name: check-cap-add-containers
match:
resources:
kinds:
- Pod
preconditions:
all:
- key: "{{request.operation}}"
operator: In
value:
- CREATE
- UPDATE
validate:
message: The only capability that may be explicitly added is `something`.
foreach:
- list: "request.object.spec.containers[].securityContext.capabilities"
deny:
conditions:
any:
# Loop over the `add[]` array in each container and deny if anything other than the "something" capability has been added.
- key: "{{ element.add }}"
operator: AnyNotIn
value: something Pod which should be allowed:
# This is good because it adds only the "something" capability.
apiVersion: v1
kind: Pod
metadata:
name: goodpod01
spec:
containers:
- name: busybox
image: something:tag
securityContext:
capabilities:
add:
- something See this is blocked. $ k apply -f add-cap-goodpod01.yaml
Error from server: error when creating "add-cap-goodpod01.yaml": admission webhook "validate.kyverno.svc-fail" denied the request:
resource Pod/default/goodpod01 was blocked due to the following policies
check-cap-add:
check-cap-add-containers: validation failed in foreach rule for The only capability
that may be explicitly added is `something`.
check-cap-add-initcontainers: preconditions not met Change $ k apply -f add-cap-goodpod01.yaml
pod/goodpod01 created This is a one-to-one comparison in this case, but the same problem is exhibited where the value should be specifiable as both a string and array/string. |
@anushkamittal20 and @JimBugwadia I am still seeing the same results here in a This does not work. foreach:
- list: "request.object.spec.rules"
deny:
conditions:
all:
- key: "{{ request.object.spec.tls[].hosts[] }}"
operator: AnyNotIn
value: "{{ element.host }}" This works. foreach:
- list: "request.object.spec.rules"
deny:
conditions:
all:
- key: "{{ request.object.spec.tls[].hosts[] }}"
operator: AnyNotIn
value:
- "{{ element.host }}" |
Does @anushkamittal20 - do we accept the list only for |
I want to implement one-to-many, many-to-many, and many-to-one conditional judgments with these operators in some conditions. But I find the logic of
I think the situation you described here should use the In my opinion, the prefix |
But that's exactly how this works @Danny-Wei : apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: anynotin
spec:
validationFailureAction: enforce
rules:
- name: anynotintest
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Denied"
deny:
conditions:
any:
- key:
- orange
- green
- blue
operator: AllNotIn
value: green apiVersion: v1
kind: Pod
metadata:
annotations:
annotation.corp.com/restrict1: foo1
labels:
app: busybox
name: mypod
spec:
schedulerName: nothing
containers:
- name: busybox
image: nothingtoseehere:latest
args:
- sleep
- "9999" $ k apply -f pod.yaml
Error from server: error when creating "pod.yaml": admission webhook "validate.kyverno.svc-fail" denied the request:
resource Pod/default/mypod was blocked due to the following policies
anynotin:
anynotintest: Denied |
If we define these operators as follows (Note: the key and value are treated as lists)
, then we can achieve your use case in the following way
|
|
I see, I found the logic of AllNotIn doesn't match what the documentation describes and what I thought. |
I see what you mean. You're referring to this statement:
The parenthetical clause isn't correct here. |
It seems that I must split the condition if I want to check "all items in the key are NOT IN the value", just like as follows
|
- key: ["NET_RAW","net_raw"]
operator: AnyNotIn
value: "{{ element.securityContext.capabilities.drop || [''] }}" |
I already tried it but the result is not as expected. I'll look into it tomorrow. |
This is what you should use: - key: NET_RAW
operator: AnyNotIn
value: "{{ element.securityContext.capabilities.drop[].to_upper(@) || [''] }}" |
Thanks. It works. |
Related issue
Support AnyIn, AllIn, AnyNotIn, AllNotIn operators #1837
Closes #2813
Milestone of this PR
What type of PR is this
Proposed Changes
Added 4 new operators
Proof Manifests
I have added tests to check these in the
evaluate_test.go
pod.yaml
We can apply the following policies to test the new operators
pol-anyin.yaml
The request is denied as some values in
key
are present invalue
pol-allin.yaml
The Pod is not denied as All values of
key
arent present invalue
pol-anynotin.yaml
The condition returns
true
asCAP_SOMETHING
is not present invalue
and so the Pod is blocked.pol-anynotin.yaml
The pod is not blocked as the condition in this case returns
false
. If the condition wasthen the condition would return
true
as no value fromkey
is present invalue
.Checklist