1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +00:00

fix: account for error rules in mutation webhook (#5264)

* fix: account for error rules in mutation webhook

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

* add test

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2022-11-08 12:36:13 +01:00 committed by GitHub
parent 060f7bb873
commit b71c0004d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 121 additions and 5 deletions

View file

@ -196,12 +196,12 @@ func (er EngineResponse) GetPatches() [][]byte {
// GetFailedRules returns failed rules // GetFailedRules returns failed rules
func (er EngineResponse) GetFailedRules() []string { func (er EngineResponse) GetFailedRules() []string {
return er.getRules(RuleStatusFail) return er.getRules(func(status RuleStatus) bool { return status == RuleStatusFail || status == RuleStatusError })
} }
// GetSuccessRules returns success rules // GetSuccessRules returns success rules
func (er EngineResponse) GetSuccessRules() []string { func (er EngineResponse) GetSuccessRules() []string {
return er.getRules(RuleStatusPass) return er.getRules(func(status RuleStatus) bool { return status == RuleStatusPass })
} }
// GetResourceSpec returns resourceSpec of er // GetResourceSpec returns resourceSpec of er
@ -215,10 +215,10 @@ func (er EngineResponse) GetResourceSpec() ResourceSpec {
} }
} }
func (er EngineResponse) getRules(status RuleStatus) []string { func (er EngineResponse) getRules(predicate func(RuleStatus) bool) []string {
var rules []string var rules []string
for _, r := range er.PolicyResponse.Rules { for _, r := range er.PolicyResponse.Rules {
if r.Status == status { if predicate(r.Status) {
rules = append(rules, r.Name) rules = append(rules, r.Name)
} }
} }

View file

@ -152,7 +152,7 @@ func (h *mutationHandler) applyMutation(request *admissionv1.AdmissionRequest, p
engineResponse := engine.Mutate(policyContext) engineResponse := engine.Mutate(policyContext)
policyPatches := engineResponse.GetPatches() policyPatches := engineResponse.GetPatches()
if !engineResponse.IsSuccessful() && len(engineResponse.GetFailedRules()) > 0 { if !engineResponse.IsSuccessful() {
return nil, nil, fmt.Errorf("failed to apply policy %s rules %v", policyContext.Policy.GetName(), engineResponse.GetFailedRules()) return nil, nil, fmt.Errorf("failed to apply policy %s rules %v", policyContext.Policy.GetName(), engineResponse.GetFailedRules())
} }

View file

@ -0,0 +1,9 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: propagate-cost-labels-from-namespace
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

View file

@ -0,0 +1,29 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: propagate-cost-labels-from-namespace
spec:
failurePolicy: Ignore
rules:
- name: add-cost-labels
context:
- name: namespaceLabels
apiCall:
urlPath: "/api/v1/namespaces/{{request.namespace}}"
jmesPath: metadata.labels
match:
any:
- resources:
kinds:
- Pod
- Deployment
- StatefulSet
- DaemonSet
- Job
- CronJob
mutate:
patchStrategicMerge:
metadata:
labels:
cost.starfleet.evtech/project: "{{namespaceLabels.\"cost.starfleet.evtech/project\"}}"
cost.starfleet.evtech/application: "{{request.object.metadata.labels.\"cost.starfleet.evtech/application\" || namespaceLabels.\"cost.starfleet.evtech/application\"}}"

View file

@ -0,0 +1,14 @@
## Checks that the manifests.yaml file CANNOT be successfully created. If it can, fail the test as this is incorrect.
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- script: |
if kubectl apply -f resource.yaml
then
echo "Tested failed. Resource was allowed."
exit 1
else
echo "Test succeeded. Resource was blocked."
exit 0
fi

View file

@ -0,0 +1,4 @@
apiVersion: v1
kind: Pod
metadata:
name: webserver

View file

@ -0,0 +1,29 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: propagate-cost-labels-from-namespace
spec:
failurePolicy: Ignore
rules:
- name: add-cost-labels
context:
- name: namespaceLabels
apiCall:
urlPath: "/api/v1/namespaces/{{request.namespace}}"
jmesPath: metadata.labels
match:
any:
- resources:
kinds:
- Pod
- Deployment
- StatefulSet
- DaemonSet
- Job
- CronJob
mutate:
patchStrategicMerge:
metadata:
labels:
cost.starfleet.evtech/project: "{{namespaceLabels.\"cost.starfleet.evtech/project\" || 'empty'}}"
cost.starfleet.evtech/application: "{{request.object.metadata.labels.\"cost.starfleet.evtech/application\" || namespaceLabels.\"cost.starfleet.evtech/application\" || 'empty'}}"

View file

@ -0,0 +1,7 @@
apiVersion: v1
kind: Pod
metadata:
name: webserver
labels:
cost.starfleet.evtech/project: empty
cost.starfleet.evtech/application: empty

View file

@ -0,0 +1,10 @@
apiVersion: v1
kind: Pod
metadata:
name: webserver
spec:
containers:
- name: webserver
image: nginx:latest
ports:
- containerPort: 80

View file

@ -0,0 +1,4 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- command: kubectl delete -f 01-manifests.yaml,resource.yaml,05-pod.yaml --force --wait=true --ignore-not-found=true

View file

@ -0,0 +1,10 @@
apiVersion: v1
kind: Pod
metadata:
name: webserver
spec:
containers:
- name: webserver
image: nginx:latest
ports:
- containerPort: 80