1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

fix: clean up URs if the trigger doesn't exist (#9355)

* clean up URs if trigger is not present

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* add chainsaw tests

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* increase timeout

Signed-off-by: ShutingZhao <shuting@nirmata.com>

* chore: clarify user variables failure

Signed-off-by: ShutingZhao <shuting@nirmata.com>

---------

Signed-off-by: ShutingZhao <shuting@nirmata.com>
This commit is contained in:
shuting 2024-01-09 17:30:31 +08:00 committed by GitHub
parent 5826482f2a
commit 600e19b340
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 683 additions and 11 deletions

View file

@ -24,10 +24,12 @@ import (
"github.com/kyverno/kyverno/pkg/engine/jmespath"
"github.com/kyverno/kyverno/pkg/engine/validate"
"github.com/kyverno/kyverno/pkg/engine/variables"
regex "github.com/kyverno/kyverno/pkg/engine/variables/regex"
"github.com/kyverno/kyverno/pkg/event"
admissionutils "github.com/kyverno/kyverno/pkg/utils/admission"
engineutils "github.com/kyverno/kyverno/pkg/utils/engine"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
validationpolicy "github.com/kyverno/kyverno/pkg/validation/policy"
"github.com/pkg/errors"
admissionv1 "k8s.io/api/admission/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
@ -99,18 +101,14 @@ func (c *GenerateController) ProcessUR(ur *kyvernov1beta1.UpdateRequest) error {
logger.Info("start processing UR", "ur", ur.Name, "resourceVersion", ur.GetResourceVersion())
trigger, err := c.getTrigger(ur.Spec)
if err != nil {
logger.V(3).Info("the trigger resource does not exist or is pending creation, re-queueing", "details", err.Error())
if err != nil || trigger == nil {
logger.V(3).Info("the trigger resource does not exist or is pending creation")
if err := updateStatus(c.statusControl, *ur, err, nil); err != nil {
return err
}
return nil
}
if trigger == nil {
return nil
}
namespaceLabels := engineutils.GetNamespaceSelectorsFromNamespaceLister(trigger.GetKind(), trigger.GetNamespace(), c.nsLister, logger)
genResources, err = c.applyGenerate(*trigger, *ur, namespaceLabels)
if err != nil {
@ -286,8 +284,6 @@ func (c *GenerateController) applyGenerate(resource unstructured.Unstructured, u
// Apply the generate rule on resource
genResources, err := c.ApplyGeneratePolicy(logger, policyContext, ur, applicableRules)
// generate events.
if err == nil {
for _, res := range genResources {
e := event.NewResourceGenerationEvent(ur.Spec.Policy, ur.Spec.Rule, event.GeneratePolicyController, res)
@ -356,6 +352,22 @@ func (c *GenerateController) ApplyGeneratePolicy(log logr.Logger, policyContext
continue
}
if rule.Generation.Synchronize {
ruleRaw, err := json.Marshal(rule.DeepCopy())
if err != nil {
return nil, fmt.Errorf("failed to serialize the policy: %v", err)
}
vars := regex.RegexVariables.FindAllStringSubmatch(string(ruleRaw), -1)
for _, s := range vars {
for _, banned := range validationpolicy.ForbiddenUserVariables {
if banned.Match([]byte(s[2])) {
log.Info("warning: resources with admission request variables may not be regenerated", "policy", policy.GetName(), "rule", rule.Name, "variable", s[2])
}
}
}
}
startTime := time.Now()
var genResource []kyvernov1.ResourceSpec
if applyRules == kyvernov1.ApplyOne && applyCount > 0 {
@ -369,7 +381,7 @@ func (c *GenerateController) ApplyGeneratePolicy(log logr.Logger, policyContext
}
if rule, err = variables.SubstituteAllInRule(log, policyContext.JSONContext(), rule); err != nil {
log.Error(err, "variable substitution failed for rule %s", rule.Name)
log.Error(err, "variable substitution failed for rule", "rule", rule.Name)
return nil, err
}

View file

@ -8,7 +8,7 @@ import (
"github.com/kyverno/kyverno/pkg/autogen"
)
var forbidden = []*regexp.Regexp{
var ForbiddenUserVariables = []*regexp.Regexp{
regexp.MustCompile(`[^\.](serviceAccountName)\b`),
regexp.MustCompile(`[^\.](serviceAccountNamespace)\b`),
regexp.MustCompile(`[^\.](request.userInfo)\b`),
@ -30,7 +30,7 @@ func containsUserVariables(policy kyvernov1.PolicyInterface, vars [][]string) er
}
}
for _, s := range vars {
for _, banned := range forbidden {
for _, banned := range ForbiddenUserVariables {
if banned.Match([]byte(s[2])) {
return fmt.Errorf("variable %s is not allowed", s[2])
}

View file

@ -0,0 +1,11 @@
## Description
This test checks to ensure that deletion of a generated resource with sync enabled, does not result in pending URs in the cluster.
## Expected Behavior
No pending URs are left in the cluster
## Reference Issue(s)
#9350

View file

@ -0,0 +1,50 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
creationTimestamp: null
name: cpol-data-trigger-not-present
spec:
timeouts:
delete: 2m
steps:
- name: step-01
try:
- apply:
file: roles.yaml
- name: step-02
try:
- apply:
file: rbac.yaml
- name: step-03
try:
- apply:
file: policy.yaml
- assert:
file: policy-ready.yaml
- name: step-04
try:
- script:
content: "kubectl create ns cpol-data-trigger-not-present-ns --as nancy"
- name: step-05
try:
- assert:
file: generated.yaml
- name: step-06
try:
- script:
content: "kubectl delete ns cpol-data-trigger-not-present-ns"
timeout: 2m
- name: step-07
try:
- script:
content: "kubectl delete clusterrole ns-admin-cpol-data-trigger-not-present-ns-nancy"
- name: step-08
try:
- sleep:
duration: 10s
- name: step-07
try:
- script:
content: "if kubectl get updaterequests -n kyverno 2>&1 | grep -q 'No resources found in kyverno namespace.'\nthen \n exit 0 \nelse \n exit
1\nfi\n"

View file

@ -0,0 +1,47 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
kyverno.io/user: nancy
name: ns-admin-cpol-data-trigger-not-present-ns-nancy-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ns-admin-cpol-data-trigger-not-present-ns-nancy
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: nancy
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
kyverno.io/user: nancy
name: ns-admin-cpol-data-trigger-not-present-ns-nancy
rules:
- apiGroups:
- ""
resourceNames:
- cpol-data-trigger-not-present-ns
resources:
- namespaces
verbs:
- get
- delete
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
annotations:
kyverno.io/user: nancy
name: nancy-admin-binding
namespace: cpol-data-trigger-not-present-ns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: nancy

View file

@ -0,0 +1,9 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: cpol-data-trigger-not-present
status:
conditions:
- reason: Succeeded
status: "True"
type: Ready

View file

@ -0,0 +1,83 @@
---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: cpol-data-trigger-not-present
annotations:
policies.kyverno.io/description: >-
Generate Roles and RoleBindings for namespace owners
spec:
background: false
rules:
- name: generate-owner-role
match:
resources:
kinds:
- Namespace
exclude:
clusterRoles:
- "cluster-admin"
generate:
synchronize: true
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
name: "ns-admin-{{request.object.metadata.name}}-{{request.userInfo.username}}"
data:
metadata:
annotations:
kyverno.io/user: "{{request.userInfo.username}}"
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "delete"]
resourceNames:
- "{{request.object.metadata.name}}"
- name: generate-owner-role-binding
match:
resources:
kinds:
- Namespace
exclude:
clusterRoles:
- "cluster-admin"
generate:
synchronize: true
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
name: "ns-admin-{{request.object.metadata.name}}-{{request.userInfo.username}}-binding"
data:
metadata:
annotations:
kyverno.io/user: "{{request.userInfo.username}}"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: "ns-admin-{{request.object.metadata.name}}-{{request.userInfo.username}}"
subjects:
- kind: User
name: "{{request.userInfo.username}}"
- name: generate-admin-binding
match:
resources:
kinds:
- Namespace
exclude:
clusterRoles:
- "cluster-admin"
generate:
synchronize: true
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
name: "{{request.userInfo.username}}-admin-binding"
namespace: "{{request.object.metadata.name}}"
data:
metadata:
annotations:
kyverno.io/user: "{{request.userInfo.username}}"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- kind: User
name: "{{request.userInfo.username}}"

View file

@ -0,0 +1,427 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app: kyverno
app.kubernetes.io/component: background-controller
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
app.kubernetes.io/version: latest
name: kyverno:generate-additional
rules:
- apiGroups:
- networking.k8s.io
resources:
- ingresses
- ingressclasses
- networkpolicies
verbs:
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- namespaces
- configmaps
- secrets
- resourcequotas
- limitranges
verbs:
- create
- update
- patch
- delete
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- clusterrolebindings
- roles
- clusterroles
verbs:
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- pods/attach
- pods/exec
- pods/portforward
- pods/proxy
- secrets
- services/proxy
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- impersonate
- apiGroups:
- ""
resources:
- pods
- pods/attach
- pods/exec
- pods/portforward
- pods/proxy
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- ""
resources:
- pods/eviction
verbs:
- create
- apiGroups:
- ""
resources:
- configmaps
- events
- persistentvolumeclaims
- replicationcontrollers
- replicationcontrollers/scale
- secrets
- serviceaccounts
- services
- services/proxy
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- ""
resources:
- serviceaccounts/token
verbs:
- create
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- deployments/rollback
- deployments/scale
- replicasets
- replicasets/scale
- statefulsets
- statefulsets/scale
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- batch
resources:
- cronjobs
- jobs
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- extensions
resources:
- daemonsets
- deployments
- deployments/rollback
- deployments/scale
- ingresses
- networkpolicies
- replicasets
- replicasets/scale
- replicationcontrollers/scale
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- networking.k8s.io
resources:
- ingresses
- networkpolicies
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- persistentvolumeclaims
- persistentvolumeclaims/status
- pods
- replicationcontrollers
- replicationcontrollers/scale
- serviceaccounts
- services
- services/status
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- bindings
- events
- limitranges
- namespaces/status
- pods/log
- pods/status
- replicationcontrollers/status
- resourcequotas
- resourcequotas/status
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
- controllerrevisions
- daemonsets
- daemonsets/status
- deployments
- deployments/scale
- deployments/status
- replicasets
- replicasets/scale
- replicasets/status
- statefulsets
- statefulsets/scale
- statefulsets/status
verbs:
- get
- list
- watch
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
- horizontalpodautoscalers/status
verbs:
- get
- list
- watch
- apiGroups:
- batch
resources:
- cronjobs
- cronjobs/status
- jobs
- jobs/status
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- daemonsets
- daemonsets/status
- deployments
- deployments/scale
- deployments/status
- ingresses
- ingresses/status
- networkpolicies
- replicasets
- replicasets/scale
- replicasets/status
- replicationcontrollers/scale
verbs:
- get
- list
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
- poddisruptionbudgets/status
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
- ingresses/status
- networkpolicies
verbs:
- get
- list
- watch
- apiGroups:
- kyverno.io
resources:
- generaterequests
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- kyverno.io
resources:
- policies
- clusterpolicies
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- wgpolicyk8s.io
resources:
- policyreports
- clusterpolicyreports
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- kyverno.io
resources:
- admissionreports
- clusteradmissionreports
- backgroundscanreports
- clusterbackgroundscanreports
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- kyverno.io
resources:
- updaterequests
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- authorization.k8s.io
resources:
- localsubjectaccessreviews
verbs:
- create
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- kyverno.io
resources:
- cleanuppolicies
- clustercleanuppolicies
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch

View file

@ -0,0 +1,33 @@
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: "ns-admin"
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["create", "list"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nancy
subjects:
- kind: User
name: nancy
roleRef:
kind: ClusterRole
name: ns-admin
apiGroup: rbac.authorization.k8s.io
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ned
subjects:
- kind: User
name: ned
roleRef:
kind: ClusterRole
name: ns-admin
apiGroup: rbac.authorization.k8s.io