1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-13 19:28:55 +00:00

Add handler to UR.status (#3791)

* - Add "handler" to "ur.status"
- Mark / Unmark handler upon UR reconciliation

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

* Add field onPolicyUpdate

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

* Update API docs

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

* Add delay in generate e2e tests

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

* Remove duplicate logic for cleaning up the cloned resource

Signed-off-by: ShutingZhao <shuting@nirmata.com>
This commit is contained in:
shuting 2022-05-05 18:56:27 +08:00 committed by GitHub
parent 4d08354498
commit 8a9a98d8b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 407 additions and 116 deletions

View file

@ -131,9 +131,9 @@ func (r *Rule) GetCloneSyncForGenerate() (clone bool, sync bool) {
if r.Generation.Clone.Name != "" {
clone = true
sync = r.Generation.Synchronize
}
sync = r.Generation.Synchronize
return
}

View file

@ -63,6 +63,11 @@ type Spec struct {
// After the configured time expires, the admission request may fail, or may simply ignore the policy results,
// based on the failure policy. The default timeout is 10s, the value must be between 1 and 30 seconds.
WebhookTimeoutSeconds *int32 `json:"webhookTimeoutSeconds,omitempty" yaml:"webhookTimeoutSeconds,omitempty"`
// OnPolicyUpdate controls if a policy is applied to existing resources for mutateExisting and generate policies.
// Default value is "false".
// +optional
OnPolicyUpdate bool `json:"onPolicyUpdate,omitempty" yaml:"onPolicyUpdate,omitempty"`
}
func (s *Spec) SetRules(rules []Rule) {

View file

@ -25,6 +25,8 @@ import (
// UpdateRequestStatus defines the observed state of UpdateRequest
type UpdateRequestStatus struct {
// Handler represents the instance ID that handles the UR
Handler string `json:"handler,omitempty" yaml:"handler,omitempty"`
// State represents state of the update request.
State UpdateRequestState `json:"state" yaml:"state"`
@ -43,7 +45,7 @@ type UpdateRequestStatus struct {
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Policy",type="string",JSONPath=".spec.policy"
// +kubebuilder:printcolumn:name="RuleType",type="string",JSONPath=".spec.type"
// +kubebuilder:printcolumn:name="RuleType",type="string",JSONPath=".spec.requestType"
// +kubebuilder:printcolumn:name="ResourceKind",type="string",JSONPath=".spec.resource.kind"
// +kubebuilder:printcolumn:name="ResourceName",type="string",JSONPath=".spec.resource.name"
// +kubebuilder:printcolumn:name="ResourceNamespace",type="string",JSONPath=".spec.resource.namespace"

View file

@ -64,6 +64,9 @@ spec:
- Ignore
- Fail
type: string
onPolicyUpdate:
description: OnPolicyUpdate controls if a policy is applied to existing resources for mutateExisting and generate policies. Default value is "false".
type: boolean
rules:
description: Rules is a list of Rule instances. A Policy contains multiple rules and each rule can validate, mutate, or generate resources.
items:
@ -3835,6 +3838,9 @@ spec:
- Ignore
- Fail
type: string
onPolicyUpdate:
description: OnPolicyUpdate controls if a policy is applied to existing resources for mutateExisting and generate policies. Default value is "false".
type: boolean
rules:
description: Rules is a list of Rule instances. A Policy contains multiple rules and each rule can validate, mutate, or generate resources.
items:
@ -7388,7 +7394,7 @@ spec:
- jsonPath: .spec.policy
name: Policy
type: string
- jsonPath: .spec.type
- jsonPath: .spec.requestType
name: RuleType
type: string
- jsonPath: .spec.resource.kind
@ -7527,6 +7533,9 @@ spec:
type: string
type: object
type: array
handler:
description: Handler represents the instance ID that handles the UR
type: string
message:
description: Specifies request status message.
type: string

View file

@ -121,6 +121,10 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: KYVERNO_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: KYVERNO_SVC
value: {{ template "kyverno.serviceName" . }}
{{- with .Values.envVars }}

View file

@ -68,6 +68,11 @@ spec:
- Ignore
- Fail
type: string
onPolicyUpdate:
description: OnPolicyUpdate controls if a policy is applied to existing
resources for mutateExisting and generate policies. Default value
is "false".
type: boolean
rules:
description: Rules is a list of Rule instances. A Policy contains
multiple rules and each rule can validate, mutate, or generate resources.

View file

@ -69,6 +69,11 @@ spec:
- Ignore
- Fail
type: string
onPolicyUpdate:
description: OnPolicyUpdate controls if a policy is applied to existing
resources for mutateExisting and generate policies. Default value
is "false".
type: boolean
rules:
description: Rules is a list of Rule instances. A Policy contains
multiple rules and each rule can validate, mutate, or generate resources.

View file

@ -21,7 +21,7 @@ spec:
- jsonPath: .spec.policy
name: Policy
type: string
- jsonPath: .spec.type
- jsonPath: .spec.requestType
name: RuleType
type: string
- jsonPath: .spec.resource.kind
@ -178,6 +178,9 @@ spec:
type: string
type: object
type: array
handler:
description: Handler represents the instance ID that handles the UR
type: string
message:
description: Specifies request status message.
type: string

View file

@ -3,6 +3,9 @@ kind: Kustomization
namespace: kyverno
transformers:
- labels.yaml
resources:
- ../crds/
- ../k8s-resource/

16
config/debug/labels.yaml Normal file
View file

@ -0,0 +1,16 @@
---
apiVersion: builtin
kind: LabelTransformer
metadata:
name: labelTransformer
labels:
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
fieldSpecs:
- path: metadata/labels
create: true
- kind: Deployment
path: spec/template/metadata/labels
create: true

View file

@ -85,6 +85,11 @@ spec:
- Ignore
- Fail
type: string
onPolicyUpdate:
description: OnPolicyUpdate controls if a policy is applied to existing
resources for mutateExisting and generate policies. Default value
is "false".
type: boolean
rules:
description: Rules is a list of Rule instances. A Policy contains
multiple rules and each rule can validate, mutate, or generate resources.
@ -5905,6 +5910,11 @@ spec:
- Ignore
- Fail
type: string
onPolicyUpdate:
description: OnPolicyUpdate controls if a policy is applied to existing
resources for mutateExisting and generate policies. Default value
is "false".
type: boolean
rules:
description: Rules is a list of Rule instances. A Policy contains
multiple rules and each rule can validate, mutate, or generate resources.
@ -11479,7 +11489,7 @@ spec:
- jsonPath: .spec.policy
name: Policy
type: string
- jsonPath: .spec.type
- jsonPath: .spec.requestType
name: RuleType
type: string
- jsonPath: .spec.resource.kind
@ -11636,6 +11646,9 @@ spec:
type: string
type: object
type: array
handler:
description: Handler represents the instance ID that handles the UR
type: string
message:
description: Specifies request status message.
type: string
@ -12277,6 +12290,10 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: KYVERNO_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: KYVERNO_SVC
value: kyverno-svc
- name: TUF_ROOT

View file

@ -3,6 +3,10 @@ kind: Namespace
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno
---
apiVersion: apiextensions.k8s.io/v1
@ -11,6 +15,11 @@ metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
labels:
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: clusterpolicies.kyverno.io
spec:
group: kyverno.io
@ -74,6 +83,11 @@ spec:
- Ignore
- Fail
type: string
onPolicyUpdate:
description: OnPolicyUpdate controls if a policy is applied to existing
resources for mutateExisting and generate policies. Default value
is "false".
type: boolean
rules:
description: Rules is a list of Rule instances. A Policy contains
multiple rules and each rule can validate, mutate, or generate resources.
@ -4890,6 +4904,11 @@ metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
labels:
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: clusterpolicyreports.wgpolicyk8s.io
spec:
group: wgpolicyk8s.io
@ -5252,6 +5271,11 @@ metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
labels:
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: clusterreportchangerequests.kyverno.io
spec:
group: kyverno.io
@ -5614,6 +5638,11 @@ metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
labels:
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: generaterequests.kyverno.io
spec:
group: kyverno.io
@ -5806,6 +5835,11 @@ metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
labels:
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: policies.kyverno.io
spec:
group: kyverno.io
@ -5870,6 +5904,11 @@ spec:
- Ignore
- Fail
type: string
onPolicyUpdate:
description: OnPolicyUpdate controls if a policy is applied to existing
resources for mutateExisting and generate policies. Default value
is "false".
type: boolean
rules:
description: Rules is a list of Rule instances. A Policy contains
multiple rules and each rule can validate, mutate, or generate resources.
@ -10687,6 +10726,11 @@ metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
labels:
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: policyreports.wgpolicyk8s.io
spec:
group: wgpolicyk8s.io
@ -11048,6 +11092,11 @@ metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
labels:
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: reportchangerequests.kyverno.io
spec:
group: kyverno.io
@ -11410,6 +11459,11 @@ metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.8.0
creationTimestamp: null
labels:
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: updaterequests.kyverno.io
spec:
group: kyverno.io
@ -11426,7 +11480,7 @@ spec:
- jsonPath: .spec.policy
name: Policy
type: string
- jsonPath: .spec.type
- jsonPath: .spec.requestType
name: RuleType
type: string
- jsonPath: .spec.resource.kind
@ -11583,6 +11637,9 @@ spec:
type: string
type: object
type: array
handler:
description: Handler represents the instance ID that handles the UR
type: string
message:
description: Specifies request status message.
type: string
@ -11609,6 +11666,10 @@ kind: ServiceAccount
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno-service-account
namespace: kyverno
---
@ -11617,6 +11678,10 @@ kind: Role
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:leaderelection
namespace: kyverno
rules:
@ -11646,6 +11711,10 @@ kind: ClusterRole
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
rbac.authorization.k8s.io/aggregate-to-admin: "true"
name: kyverno:admin-generaterequest
rules:
@ -11667,6 +11736,10 @@ kind: ClusterRole
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
rbac.authorization.k8s.io/aggregate-to-admin: "true"
name: kyverno:admin-policies
rules:
@ -11689,6 +11762,10 @@ kind: ClusterRole
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
rbac.authorization.k8s.io/aggregate-to-admin: "true"
name: kyverno:admin-policyreport
rules:
@ -11711,6 +11788,10 @@ kind: ClusterRole
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
rbac.authorization.k8s.io/aggregate-to-admin: "true"
name: kyverno:admin-reportchangerequest
rules:
@ -11733,6 +11814,10 @@ kind: ClusterRole
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:events
rules:
- apiGroups:
@ -11750,6 +11835,10 @@ kind: ClusterRole
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:generate
rules:
- apiGroups:
@ -11792,6 +11881,10 @@ kind: ClusterRole
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:policies
rules:
- apiGroups:
@ -11840,6 +11933,10 @@ kind: ClusterRole
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:userinfo
rules:
- apiGroups:
@ -11858,6 +11955,10 @@ kind: ClusterRole
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:view
rules:
- apiGroups:
@ -11874,6 +11975,10 @@ kind: ClusterRole
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:webhook
rules:
- apiGroups:
@ -11895,6 +12000,10 @@ kind: RoleBinding
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:leaderelection
namespace: kyverno
roleRef:
@ -11911,6 +12020,10 @@ kind: ClusterRoleBinding
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:events
roleRef:
apiGroup: rbac.authorization.k8s.io
@ -11926,6 +12039,10 @@ kind: ClusterRoleBinding
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:generate
roleRef:
apiGroup: rbac.authorization.k8s.io
@ -11941,6 +12058,10 @@ kind: ClusterRoleBinding
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:policies
roleRef:
apiGroup: rbac.authorization.k8s.io
@ -11956,6 +12077,10 @@ kind: ClusterRoleBinding
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:userinfo
roleRef:
apiGroup: rbac.authorization.k8s.io
@ -11971,6 +12096,10 @@ kind: ClusterRoleBinding
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:view
roleRef:
apiGroup: rbac.authorization.k8s.io
@ -11986,6 +12115,10 @@ kind: ClusterRoleBinding
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno:webhook
roleRef:
apiGroup: rbac.authorization.k8s.io
@ -12005,6 +12138,10 @@ kind: ConfigMap
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno
namespace: kyverno
---
@ -12016,6 +12153,10 @@ kind: ConfigMap
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno-metrics
namespace: kyverno
---
@ -12024,6 +12165,10 @@ kind: Service
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno-svc
namespace: kyverno
spec:
@ -12040,6 +12185,10 @@ kind: Service
metadata:
labels:
app: kyverno
app.kubernetes.io/component: kyverno
app.kubernetes.io/instance: kyverno
app.kubernetes.io/name: kyverno
app.kubernetes.io/part-of: kyverno
name: kyverno-svc-metrics
namespace: kyverno
spec:

View file

@ -94,6 +94,10 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: KYVERNO_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: KYVERNO_SVC
value: kyverno-svc
- name: TUF_ROOT

View file

@ -189,6 +189,19 @@ After the configured time expires, the admission request may fail, or may simply
based on the failure policy. The default timeout is 10s, the value must be between 1 and 30 seconds.</p>
</td>
</tr>
<tr>
<td>
<code>onPolicyUpdate</code></br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>OnPolicyUpdate controls if a policy is applied to existing resources for mutateExisting and generate policies.
Default value is &ldquo;false&rdquo;.</p>
</td>
</tr>
</table>
</td>
</tr>
@ -369,6 +382,19 @@ After the configured time expires, the admission request may fail, or may simply
based on the failure policy. The default timeout is 10s, the value must be between 1 and 30 seconds.</p>
</td>
</tr>
<tr>
<td>
<code>onPolicyUpdate</code></br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>OnPolicyUpdate controls if a policy is applied to existing resources for mutateExisting and generate policies.
Default value is &ldquo;false&rdquo;.</p>
</td>
</tr>
</table>
</td>
</tr>
@ -2889,6 +2915,19 @@ After the configured time expires, the admission request may fail, or may simply
based on the failure policy. The default timeout is 10s, the value must be between 1 and 30 seconds.</p>
</td>
</tr>
<tr>
<td>
<code>onPolicyUpdate</code></br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>OnPolicyUpdate controls if a policy is applied to existing resources for mutateExisting and generate policies.
Default value is &ldquo;false&rdquo;.</p>
</td>
</tr>
</tbody>
</table>
<hr />

View file

@ -409,6 +409,17 @@ AdmissionRequestInfoObject
<tbody>
<tr>
<td>
<code>handler</code></br>
<em>
string
</em>
</td>
<td>
<p>Handler represents the instance ID that handles the UR</p>
</td>
</tr>
<tr>
<td>
<code>state</code></br>
<em>
<a href="#kyverno.io/v1beta1.UpdateRequestState">

View file

@ -66,7 +66,7 @@ func (sc StatusControl) Success(ur urkyverno.UpdateRequest, genResources []kyver
log.Log.Error(err, "failed to patch update request status", "name", ur.Name)
return err
}
log.Log.V(3).Info("updated update request status", "name", ur.Name, "status", string(kyverno.Completed))
log.Log.V(3).Info("updated update request status", "name", ur.Name, "status", string(urkyverno.Completed))
return nil
}

View file

@ -6,7 +6,6 @@ import (
"github.com/go-logr/logr"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
urkyverno "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/autogen"
kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned"
kyvernoinformer "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1"
urkyvernoinformer "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1beta1"
@ -111,9 +110,8 @@ func (c *Controller) deletePolicy(obj interface{}) {
}
logger.V(4).Info("deleting policy", "name", p.Name)
rules := autogen.ComputeRules(p)
generatePolicyWithClone := pkgCommon.ProcessDeletePolicyForCloneGenerateRule(rules, c.client, p.GetName(), logger)
generatePolicyWithClone := pkgCommon.ProcessDeletePolicyForCloneGenerateRule(p, c.client, c.kyvernoClient, c.urLister, p.GetName(), logger)
// get the generated resource name from update request for log
selector := labels.SelectorFromSet(labels.Set(map[string]string{
@ -141,21 +139,11 @@ func (c *Controller) deletePolicy(obj interface{}) {
for _, ur := range urs {
logger.V(4).Info("enqueue the ur for cleanup", "ur name", ur.Name)
c.addUR(ur)
c.enqueue(ur)
}
}
}
func (c *Controller) addUR(obj interface{}) {
ur := obj.(*urkyverno.UpdateRequest)
c.enqueue(ur)
}
func (c *Controller) updateUR(old, cur interface{}) {
ur := cur.(*urkyverno.UpdateRequest)
c.enqueue(ur)
}
func (c *Controller) deleteUR(obj interface{}) {
logger := c.log
ur, ok := obj.(*urkyverno.UpdateRequest)
@ -172,23 +160,10 @@ func (c *Controller) deleteUR(obj interface{}) {
}
}
for _, resource := range ur.Status.GeneratedResources {
r, err := c.client.GetResource(resource.APIVersion, resource.Kind, resource.Namespace, resource.Name)
if err != nil && !apierrors.IsNotFound(err) {
logger.Error(err, "failed to fetch generated resource", "resource", resource.Name)
return
}
if r != nil && r.GetLabels()["policy.kyverno.io/synchronize"] == "enable" {
if err := c.client.DeleteResource(r.GetAPIVersion(), r.GetKind(), r.GetNamespace(), r.GetName(), false); err != nil && !apierrors.IsNotFound(err) {
logger.Error(err, "failed to delete the generated resource", "resource", r.GetName())
return
}
}
if ur.Status.Handler != "" {
return
}
logger.V(4).Info("deleting Update Request CR", "name", ur.Name)
// sync Handler will remove it from the queue
c.enqueue(ur)
}
@ -222,8 +197,6 @@ func (c *Controller) Run(workers int, stopCh <-chan struct{}) {
})
c.urInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: c.addUR,
UpdateFunc: c.updateUR,
DeleteFunc: c.deleteUR,
})
@ -304,30 +277,19 @@ func (c *Controller) syncUpdateRequest(key string) error {
if pNamespace == "" {
_, err = c.pLister.Get(pName)
if err != nil {
if !apierrors.IsNotFound(err) {
return err
}
logger.Error(err, "failed to get clusterpolicy, deleting the update request")
err = c.control.Delete(ur.Name)
if err != nil {
return err
}
return nil
}
} else {
_, err = c.npLister.Policies(pNamespace).Get(pName)
if err != nil {
if !apierrors.IsNotFound(err) {
return err
}
logger.Error(err, "failed to get policy, deleting the update request")
err = c.control.Delete(ur.Name)
if err != nil {
return err
}
return nil
}
}
if err != nil {
if !apierrors.IsNotFound(err) {
return err
}
logger.Error(err, "failed to get policy, deleting the update request", "key", ur.Spec.Policy)
return c.control.Delete(ur.Name)
}
return c.processUR(*ur)
}

View file

@ -102,6 +102,7 @@ func (c *GenerateController) ProcessUR(ur *urkyverno.UpdateRequest) error {
var resource *unstructured.Unstructured
var genResources []kyverno.ResourceSpec
var precreatedResource bool
logger.Info("start processing UR", "resourceVersion", ur.GetResourceVersion())
// 1 - Check if the resource exists
resource, err = common.GetResource(c.client, ur.Spec, c.log)
@ -143,7 +144,7 @@ func (c *GenerateController) ProcessUR(ur *urkyverno.UpdateRequest) error {
ur.SetAnnotations(urAnnotations)
_, err := c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace).Update(contextdefault.TODO(), ur, metav1.UpdateOptions{})
if err != nil {
logger.Error(err, "failed to update annotation in update request for the resource", "update request", ur.Name)
logger.Error(err, "failed to update annotation in update request for the resource", "update request", ur.Name, "resourceVersion", ur.GetResourceVersion())
return err
}
}
@ -179,27 +180,15 @@ func (c *GenerateController) ProcessUR(ur *urkyverno.UpdateRequest) error {
const doesNotApply = "policy does not apply to resource"
func (c *GenerateController) applyGenerate(resource unstructured.Unstructured, ur urkyverno.UpdateRequest, namespaceLabels map[string]string) ([]kyverno.ResourceSpec, bool, error) {
logger := c.log.WithValues("name", ur.Name, "policy", ur.Spec.Policy, "kind", ur.Spec.Resource.Kind, "apiVersion", ur.Spec.Resource.APIVersion, "namespace", ur.Spec.Resource.Namespace, "name", ur.Spec.Resource.Name)
// Get the list of rules to be applied
// get policy
// build context
logger := c.log.WithValues("name", ur.GetName(), "policy", ur.Spec.Policy, "kind", ur.Spec.Resource.Kind, "apiVersion", ur.Spec.Resource.APIVersion, "namespace", ur.Spec.Resource.Namespace, "name", ur.Spec.Resource.Name)
logger.V(3).Info("applying generate policy rule")
policy, err := c.getPolicySpec(ur)
if err != nil {
if apierrors.IsNotFound(err) {
for _, e := range ur.Status.GeneratedResources {
resp, err := c.client.GetResource(e.APIVersion, e.Kind, e.Namespace, e.Name)
if err != nil && !apierrors.IsNotFound(err) {
logger.Error(err, "failed to find generated resource", "name", e.Name)
continue
}
if resp != nil && resp.GetLabels()["policy.kyverno.io/synchronize"] == "enable" {
if err := c.client.DeleteResource(resp.GetAPIVersion(), resp.GetKind(), resp.GetNamespace(), resp.GetName(), false); err != nil {
logger.Error(err, "generated resource is not deleted", "Resource", e.Name)
}
if err := c.cleanupClonedResource(e); err != nil {
logger.Error(err, "failed to clean up cloned resource on policy deletion")
}
}
return nil, false, nil
@ -253,6 +242,31 @@ func (c *GenerateController) applyGenerate(resource unstructured.Unstructured, u
return c.applyGeneratePolicy(logger, policyContext, ur, applicableRules)
}
// cleanupClonedResource deletes cloned resource if sync is not enabled for the clone policy
func (c *GenerateController) cleanupClonedResource(targetSpec kyverno.ResourceSpec) error {
target, err := c.client.GetResource(targetSpec.APIVersion, targetSpec.Kind, targetSpec.Namespace, targetSpec.Name)
if err != nil {
if !apierrors.IsNotFound(err) {
return fmt.Errorf("failed to find generated resource %s/%s: %v", targetSpec.Namespace, targetSpec.Name, err)
}
}
if target == nil {
return nil
}
labels := target.GetLabels()
syncEnabled := labels["policy.kyverno.io/synchronize"] == "enable"
clone := labels["generate.kyverno.io/clone-policy-name"] != ""
if syncEnabled && !clone {
if err := c.client.DeleteResource(target.GetAPIVersion(), target.GetKind(), target.GetNamespace(), target.GetName(), false); err != nil {
return fmt.Errorf("cloned resource is not deleted %s/%s: %v", targetSpec.Namespace, targetSpec.Name, err)
}
}
return nil
}
// getPolicySpec gets the policy spec from the ClusterPolicy/Policy
func (c *GenerateController) getPolicySpec(ur urkyverno.UpdateRequest) (kyverno.ClusterPolicy, error) {
var policy kyverno.ClusterPolicy
@ -405,7 +419,7 @@ func applyRule(log logr.Logger, client dclient.Interface, rule kyverno.Rule, res
return noGenResource, fmt.Errorf("failed to read `clone`: %v", err.Error())
}
if genClone != nil && len(genClone) != 0 {
if len(genClone) != 0 {
rdata, mode, err = manageClone(logger, genAPIVersion, genKind, genNamespace, genName, policy, genClone, client)
} else {
rdata, mode, err = manageData(logger, genAPIVersion, genKind, genNamespace, genName, genData, client)
@ -443,7 +457,6 @@ func applyRule(log logr.Logger, client dclient.Interface, rule kyverno.Rule, res
label := newResource.GetLabels()
label["policy.kyverno.io/policy-name"] = policy
label["policy.kyverno.io/gr-name"] = ur.Name
delete(label, "generate.kyverno.io/clone-policy-name")
if mode == Create {
if rule.Generation.Synchronize {
label["policy.kyverno.io/synchronize"] = "enable"

View file

@ -1,9 +1,13 @@
package background
import (
"context"
urkyverno "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/background/generate"
"github.com/kyverno/kyverno/pkg/background/mutate"
"github.com/kyverno/kyverno/pkg/config"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func (c *Controller) ProcessUR(ur *urkyverno.UpdateRequest) error {
@ -21,3 +25,29 @@ func (c *Controller) ProcessUR(ur *urkyverno.UpdateRequest) error {
}
return nil
}
func (c *Controller) MarkUR(ur *urkyverno.UpdateRequest) (*urkyverno.UpdateRequest, bool, error) {
handler := ur.Status.Handler
if handler != "" {
if handler != config.KyvernoPodName {
return nil, false, nil
}
return ur, true, nil
}
handler = config.KyvernoPodName
ur.Status.Handler = handler
new, err := c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace).UpdateStatus(context.TODO(), ur, metav1.UpdateOptions{})
return new, true, err
}
func (c *Controller) UnmarkUR(ur *urkyverno.UpdateRequest) error {
newUR, err := c.urLister.Get(ur.Name)
if err != nil {
return err
}
newUR.Status.Handler = ""
_, err = c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace).UpdateStatus(context.TODO(), newUR, metav1.UpdateOptions{})
return err
}

View file

@ -191,7 +191,23 @@ func (c *Controller) syncUpdateRequest(key string) error {
return err
}
return c.ProcessUR(ur)
ur, ok, err := c.MarkUR(ur)
if !ok {
logger.V(3).Info("another instance is handling the UR", "handler", ur.Status.Handler)
return nil
}
if err != nil {
logger.Error(err, "failed to mark UR handler", "key", key)
return err
}
logger.V(3).Info("UR is marked successfully", "ur", ur.GetName(), "resourceVersion", ur.GetResourceVersion())
if err := c.ProcessUR(ur); err != nil {
logger.Error(err, "failed to process UR", "key", key)
return err
}
return c.UnmarkUR(ur)
}
func (c *Controller) enqueueUpdateRequest(obj interface{}) {
@ -247,6 +263,9 @@ func (c *Controller) updatePolicy(old, cur interface{}) {
func (c *Controller) addUR(obj interface{}) {
ur := obj.(*urkyverno.UpdateRequest)
if ur.Status.Handler != "" {
return
}
c.enqueueUpdateRequest(ur)
}
@ -263,6 +282,10 @@ func (c *Controller) updateUR(old, cur interface{}) {
if curUr.Status.State != urkyverno.Pending {
return
}
if curUr.Status.Handler != "" {
return
}
c.enqueueUpdateRequest(curUr)
}
@ -282,22 +305,8 @@ func (c *Controller) deleteUR(obj interface{}) {
}
}
if ur.Spec.GetRequestType() == urkyverno.Generate {
for _, resource := range ur.Status.GeneratedResources {
r, err := c.client.GetResource(resource.APIVersion, resource.Kind, resource.Namespace, resource.Name)
if err != nil && !apierrors.IsNotFound(err) {
logger.Error(err, "Generated resource is not deleted", "Resource", resource.Name)
continue
}
if r != nil && r.GetLabels()["policy.kyverno.io/synchronize"] == "enable" {
if err := c.client.DeleteResource(r.GetAPIVersion(), r.GetKind(), r.GetNamespace(), r.GetName(), false); err != nil && !apierrors.IsNotFound(err) {
logger.Error(err, "Generated resource is not deleted", "Resource", r.GetName())
}
}
}
logger.V(3).Info("deleting update request", "name", ur.Name)
if ur.Status.Handler != "" {
return
}
// sync Handler will remove it from the queue

View file

@ -6,14 +6,15 @@ import (
"strings"
"time"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"github.com/go-logr/logr"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned"
urkyvernolister "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1"
dclient "github.com/kyverno/kyverno/pkg/dclient"
enginutils "github.com/kyverno/kyverno/pkg/engine/utils"
"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/client-go/informers"
listerv1 "k8s.io/client-go/listers/core/v1"
@ -127,10 +128,11 @@ func RetryFunc(retryInterval, timeout time.Duration, run func() error, msg strin
}
}
func ProcessDeletePolicyForCloneGenerateRule(rules []kyverno.Rule, client dclient.Interface, pName string, logger logr.Logger) bool {
func ProcessDeletePolicyForCloneGenerateRule(policy kyverno.PolicyInterface, client dclient.Interface, kyvernoClient kyvernoclient.Interface, urlister urkyvernolister.UpdateRequestNamespaceLister, pName string, logger logr.Logger) bool {
generatePolicyWithClone := false
for _, rule := range rules {
if rule.Generation.Clone.Name == "" {
for _, rule := range policy.GetSpec().Rules {
clone, sync := rule.GetCloneSyncForGenerate()
if !(clone && sync) {
continue
}
@ -139,7 +141,7 @@ func ProcessDeletePolicyForCloneGenerateRule(rules []kyverno.Rule, client dclien
retryCount := 0
for retryCount < 5 {
err := updateSourceResource(pName, rule, client, logger)
err := updateSourceResource(policy.GetName(), rule, client, logger)
if err != nil {
logger.Error(err, "failed to update generate source resource labels")
if apierrors.IsConflict(err) {

View file

@ -76,6 +76,8 @@ var (
KyvernoDeploymentName = osutils.GetEnvWithFallback("KYVERNO_DEPLOYMENT", "kyverno")
// KyvernoServiceName is the Kyverno service name
KyvernoServiceName = osutils.GetEnvWithFallback("KYVERNO_SVC", "kyverno-svc")
// KyvernoPodName is the Kyverno pod name
KyvernoPodName = osutils.GetEnvWithFallback("KYVERNO_POD_NAME", "kyverno")
// KyvernoConfigMapName is the Kyverno configmap name
KyvernoConfigMapName = osutils.GetEnvWithFallback("INIT_CONFIG", "kyverno")
// defaultExcludeGroupRole ...

View file

@ -475,7 +475,7 @@ func (pc *PolicyController) syncPolicy(key string) error {
if errors.IsNotFound(err) {
mutateURs := pc.listMutateURs(key, nil)
generateURs := pc.listGenerateURs(key, nil)
deleteGR(pc.kyvernoClient, key, append(mutateURs, generateURs...), logger)
deleteUR(pc.kyvernoClient, key, append(mutateURs, generateURs...), logger)
return nil
}
return err
@ -565,7 +565,7 @@ func getTrigger(rd kyverno.ResourceDescription) []*kyverno.ResourceSpec {
return specs
}
func deleteGR(kyvernoClient kyvernoclient.Interface, policyKey string, grList []*urkyverno.UpdateRequest, logger logr.Logger) {
func deleteUR(kyvernoClient kyvernoclient.Interface, policyKey string, grList []*urkyverno.UpdateRequest, logger logr.Logger) {
for _, v := range grList {
if policyKey == v.Spec.Policy {
err := kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace).Delete(context.TODO(), v.GetName(), metav1.DeleteOptions{})
@ -576,24 +576,24 @@ func deleteGR(kyvernoClient kyvernoclient.Interface, policyKey string, grList []
}
}
func updateUR(kyvernoClient kyvernoclient.Interface, policyKey string, grList []*urkyverno.UpdateRequest, logger logr.Logger) {
for _, gr := range grList {
if policyKey == gr.Spec.Policy {
grLabels := gr.Labels
if len(grLabels) == 0 {
grLabels = make(map[string]string)
func updateUR(kyvernoClient kyvernoclient.Interface, policyKey string, urList []*urkyverno.UpdateRequest, logger logr.Logger) {
for _, ur := range urList {
if policyKey == ur.Spec.Policy {
urLabels := ur.Labels
if len(urLabels) == 0 {
urLabels = make(map[string]string)
}
nBig, err := rand.Int(rand.Reader, big.NewInt(100000))
if err != nil {
logger.Error(err, "failed to generate random interger")
}
grLabels["policy-update"] = fmt.Sprintf("revision-count-%d", nBig.Int64())
gr.SetLabels(grLabels)
urLabels["policy-update"] = fmt.Sprintf("revision-count-%d", nBig.Int64())
ur.SetLabels(urLabels)
new, err := kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace).Update(context.TODO(), gr, metav1.UpdateOptions{})
new, err := kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace).Update(context.TODO(), ur, metav1.UpdateOptions{})
if err != nil {
logger.Error(err, "failed to update gr", "name", gr.GetName())
logger.Error(err, "failed to update gr", "name", ur.GetName())
continue
}

View file

@ -18,7 +18,7 @@ func (pc *PolicyController) updateUR(policyKey string, policy kyverno.PolicyInte
mutateURs := pc.listMutateURs(policyKey, nil)
generateURs := pc.listGenerateURs(policyKey, nil)
updateUR(pc.kyvernoClient, policy.GetName(), append(mutateURs, generateURs...), pc.log.WithName("updateUR"))
updateUR(pc.kyvernoClient, policyKey, append(mutateURs, generateURs...), pc.log.WithName("updateUR"))
for _, rule := range policy.GetSpec().Rules {
var ruleType urkyverno.RequestType

View file

@ -139,7 +139,7 @@ func retryApplyResource(client kyvernoclient.Interface, urSpec urkyverno.UpdateR
urList, err := urLister.List(labels.SelectorFromSet(queryLabels))
if err != nil {
logger.Error(err, "failed to get update request for the resource", "kind", urSpec.Resource.Kind, "name", urSpec.Resource.Name, "namespace", urSpec.Resource.Namespace)
log.Error(err, "failed to get update request for the resource", "kind", urSpec.Resource.Kind, "name", urSpec.Resource.Name, "namespace", urSpec.Resource.Namespace)
return err
}

View file

@ -1116,6 +1116,7 @@ func Test_Generate_Policy_Deletion_for_Clone(t *testing.T) {
}
return nil
})
Expect(err).NotTo(HaveOccurred())
// ===========================================