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

Create UR for both mutate and generate policies (#3717)

* remove mutateExisting field

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

* update policy controller to create UR for generate

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

* remove debug log

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

* - Update api docs
- Ignore e2e tests cleanup failure

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

* Add back index to helm template

Signed-off-by: ShutingZhao <shuting@nirmata.com>
This commit is contained in:
shuting 2022-04-29 13:31:02 +08:00 committed by GitHub
parent 7fca026678
commit e248308cb3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 188 additions and 272 deletions

View file

@ -214,13 +214,6 @@ type ResourceFilter struct {
// Mutation defines how resource are modified.
type Mutation struct {
// mutateExisting controls whether to mutate existing resource ONLY
// The existing resources will be mutated ONLY if set to "true".
// Otherwise all resources including admission requests are mutated.
// Optional. Defaults to "false" if not specified.
// +optional
MutateExisting bool `json:"mutateExisting,omitempty" yaml:"mutatingExisting,omitempty"`
// Targets defines the target resources to be mutated.
// +optional
Targets []ResourceSpec `json:"targets,omitempty" yaml:"targets,omitempty"`
@ -465,7 +458,6 @@ type CloneFrom struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
}
// ResourceSpec contains information to identify a resource.
type ResourceSpec struct {
// APIVersion specifies resource apiVersion.
// +optional

View file

@ -2,7 +2,12 @@ package v1beta1
const (
// URMutatePolicyLabel adds the policy name to URs for mutate policies
URMutatePolicyLabel = "mutate.updaterequest.kyverno.io/policy-name"
URMutatePolicyLabel = "mutate.updaterequest.kyverno.io/policy-name"
URMutateTriggerNameLabel = "mutate.updaterequest.kyverno.io/trigger-name"
URMutateTriggerNSLabel = "mutate.updaterequest.kyverno.io/trigger-namespace"
URMutatetriggerKindLabel = "mutate.updaterequest.kyverno.io/trigger-kind"
URMutatetriggerAPIVersionLabel = "mutate.updaterequest.kyverno.io/trigger-apiversion"
// URGeneratePolicyLabel adds the policy name to URs for generate policies
URGeneratePolicyLabel = "generate.kyverno.io/policy-name"
)

View file

@ -1082,9 +1082,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing resource ONLY The existing resources will be mutated ONLY if set to "true". Otherwise all resources including admission requests are mutated. Optional. Defaults to "false" if not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/ and https://kubectl.docs.kubernetes.io/references/kustomize/patchesstrategicmerge/.
x-kubernetes-preserve-unknown-fields: true
@ -1094,7 +1091,6 @@ spec:
targets:
description: Targets defines the target resources to be mutated.
items:
description: ResourceSpec contains information to identify a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -2614,9 +2610,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing resource ONLY The existing resources will be mutated ONLY if set to "true". Otherwise all resources including admission requests are mutated. Optional. Defaults to "false" if not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/ and https://kubectl.docs.kubernetes.io/references/kustomize/patchesstrategicmerge/.
x-kubernetes-preserve-unknown-fields: true
@ -2626,7 +2619,6 @@ spec:
targets:
description: Targets defines the target resources to be mutated.
items:
description: ResourceSpec contains information to identify a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -3739,7 +3731,6 @@ spec:
generatedResources:
description: This will track the resources that are generated by the generate Policy. Will be used during clean up resources.
items:
description: ResourceSpec contains information to identify a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -4862,9 +4853,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing resource ONLY The existing resources will be mutated ONLY if set to "true". Otherwise all resources including admission requests are mutated. Optional. Defaults to "false" if not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/ and https://kubectl.docs.kubernetes.io/references/kustomize/patchesstrategicmerge/.
x-kubernetes-preserve-unknown-fields: true
@ -4874,7 +4862,6 @@ spec:
targets:
description: Targets defines the target resources to be mutated.
items:
description: ResourceSpec contains information to identify a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -6394,9 +6381,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing resource ONLY The existing resources will be mutated ONLY if set to "true". Otherwise all resources including admission requests are mutated. Optional. Defaults to "false" if not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/ and https://kubectl.docs.kubernetes.io/references/kustomize/patchesstrategicmerge/.
x-kubernetes-preserve-unknown-fields: true
@ -6406,7 +6390,6 @@ spec:
targets:
description: Targets defines the target resources to be mutated.
items:
description: ResourceSpec contains information to identify a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -7525,7 +7508,6 @@ spec:
generatedResources:
description: This will track the resources that are updated by the generate Policy. Will be used during clean up resources.
items:
description: ResourceSpec contains information to identify a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.

View file

@ -1730,13 +1730,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing
resource ONLY The existing resources will be mutated ONLY
if set to "true". Otherwise all resources including admission
requests are mutated. Optional. Defaults to "false" if
not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch
used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
@ -1751,8 +1744,6 @@ spec:
description: Targets defines the target resources to be
mutated.
items:
description: ResourceSpec contains information to identify
a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -4202,13 +4193,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing
resource ONLY The existing resources will be mutated ONLY
if set to "true". Otherwise all resources including admission
requests are mutated. Optional. Defaults to "false" if
not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch
used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
@ -4223,8 +4207,6 @@ spec:
description: Targets defines the target resources to be
mutated.
items:
description: ResourceSpec contains information to identify
a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.

View file

@ -152,7 +152,6 @@ spec:
description: This will track the resources that are generated by the
generate Policy. Will be used during clean up resources.
items:
description: ResourceSpec contains information to identify a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.

View file

@ -1731,13 +1731,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing
resource ONLY The existing resources will be mutated ONLY
if set to "true". Otherwise all resources including admission
requests are mutated. Optional. Defaults to "false" if
not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch
used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
@ -1752,8 +1745,6 @@ spec:
description: Targets defines the target resources to be
mutated.
items:
description: ResourceSpec contains information to identify
a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -4204,13 +4195,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing
resource ONLY The existing resources will be mutated ONLY
if set to "true". Otherwise all resources including admission
requests are mutated. Optional. Defaults to "false" if
not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch
used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
@ -4225,8 +4209,6 @@ spec:
description: Targets defines the target resources to be
mutated.
items:
description: ResourceSpec contains information to identify
a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.

View file

@ -159,7 +159,6 @@ spec:
description: This will track the resources that are updated by the
generate Policy. Will be used during clean up resources.
items:
description: ResourceSpec contains information to identify a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.

View file

@ -1747,13 +1747,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing
resource ONLY The existing resources will be mutated ONLY
if set to "true". Otherwise all resources including admission
requests are mutated. Optional. Defaults to "false" if
not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch
used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
@ -1768,8 +1761,6 @@ spec:
description: Targets defines the target resources to be
mutated.
items:
description: ResourceSpec contains information to identify
a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -4219,13 +4210,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing
resource ONLY The existing resources will be mutated ONLY
if set to "true". Otherwise all resources including admission
requests are mutated. Optional. Defaults to "false" if
not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch
used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
@ -4240,8 +4224,6 @@ spec:
description: Targets defines the target resources to be
mutated.
items:
description: ResourceSpec contains information to identify
a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -5808,7 +5790,6 @@ spec:
description: This will track the resources that are generated by the
generate Policy. Will be used during clean up resources.
items:
description: ResourceSpec contains information to identify a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -7586,13 +7567,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing
resource ONLY The existing resources will be mutated ONLY
if set to "true". Otherwise all resources including admission
requests are mutated. Optional. Defaults to "false" if
not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch
used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
@ -7607,8 +7581,6 @@ spec:
description: Targets defines the target resources to be
mutated.
items:
description: ResourceSpec contains information to identify
a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -10059,13 +10031,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing
resource ONLY The existing resources will be mutated ONLY
if set to "true". Otherwise all resources including admission
requests are mutated. Optional. Defaults to "false" if
not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch
used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
@ -10080,8 +10045,6 @@ spec:
description: Targets defines the target resources to be
mutated.
items:
description: ResourceSpec contains information to identify
a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -11654,7 +11617,6 @@ spec:
description: This will track the resources that are updated by the
generate Policy. Will be used during clean up resources.
items:
description: ResourceSpec contains information to identify a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.

View file

@ -1736,13 +1736,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing
resource ONLY The existing resources will be mutated ONLY
if set to "true". Otherwise all resources including admission
requests are mutated. Optional. Defaults to "false" if
not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch
used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
@ -1757,8 +1750,6 @@ spec:
description: Targets defines the target resources to be
mutated.
items:
description: ResourceSpec contains information to identify
a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -4208,13 +4199,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing
resource ONLY The existing resources will be mutated ONLY
if set to "true". Otherwise all resources including admission
requests are mutated. Optional. Defaults to "false" if
not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch
used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
@ -4229,8 +4213,6 @@ spec:
description: Targets defines the target resources to be
mutated.
items:
description: ResourceSpec contains information to identify
a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -5779,7 +5761,6 @@ spec:
description: This will track the resources that are generated by the
generate Policy. Will be used during clean up resources.
items:
description: ResourceSpec contains information to identify a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -7551,13 +7532,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing
resource ONLY The existing resources will be mutated ONLY
if set to "true". Otherwise all resources including admission
requests are mutated. Optional. Defaults to "false" if
not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch
used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
@ -7572,8 +7546,6 @@ spec:
description: Targets defines the target resources to be
mutated.
items:
description: ResourceSpec contains information to identify
a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -10024,13 +9996,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
type: object
type: array
mutateExisting:
description: mutateExisting controls whether to mutate existing
resource ONLY The existing resources will be mutated ONLY
if set to "true". Otherwise all resources including admission
requests are mutated. Optional. Defaults to "false" if
not specified.
type: boolean
patchStrategicMerge:
description: PatchStrategicMerge is a strategic merge patch
used to modify resources. See https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/
@ -10045,8 +10010,6 @@ spec:
description: Targets defines the target resources to be
mutated.
items:
description: ResourceSpec contains information to identify
a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.
@ -11601,7 +11564,6 @@ spec:
description: This will track the resources that are updated by the
generate Policy. Will be used during clean up resources.
items:
description: ResourceSpec contains information to identify a resource.
properties:
apiVersion:
description: APIVersion specifies resource apiVersion.

View file

@ -2082,21 +2082,6 @@ Please specify under &ldquo;any&rdquo; or &ldquo;all&rdquo; instead.</p>
<tbody>
<tr>
<td>
<code>mutateExisting</code></br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>mutateExisting controls whether to mutate existing resource ONLY
The existing resources will be mutated ONLY if set to &ldquo;true&rdquo;.
Otherwise all resources including admission requests are mutated.
Optional. Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
<tr>
<td>
<code>targets</code></br>
<em>
<a href="#kyverno.io/v1.ResourceSpec">
@ -2479,7 +2464,6 @@ ResourceDescription
<a href="#kyverno.io/v1.Mutation">Mutation</a>)
</p>
<p>
<p>ResourceSpec contains information to identify a resource.</p>
</p>
<table class="table table-striped">
<thead class="thead-dark">

View file

@ -9,7 +9,6 @@ import (
"strings"
"time"
"github.com/gardener/controller-manager-library/pkg/logger"
"github.com/go-logr/logr"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
urkyverno "github.com/kyverno/kyverno/api/kyverno/v1beta1"
@ -31,7 +30,6 @@ import (
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
informers "k8s.io/client-go/informers/core/v1"
@ -506,47 +504,23 @@ func (pc *PolicyController) syncPolicy(key string) error {
logger.V(4).Info("finished syncing policy", "key", key, "processingTime", time.Since(startTime).String())
}()
mutateURs, generateURs := pc.listURs(key)
policy, err := pc.getPolicy(key)
if err != nil {
if errors.IsNotFound(err) {
mutateURs := pc.listMutateURs(key, nil)
generateURs := pc.listGenerateURs(key, nil)
deleteGR(pc.kyvernoClient, key, append(mutateURs, generateURs...), logger)
return nil
}
return err
} else {
pc.updateUR(key, policy)
}
pc.updateUR(policy, mutateURs, generateURs)
pc.processExistingResources(policy)
return nil
}
func (pc *PolicyController) listURs(key string) ([]*urkyverno.UpdateRequest, []*urkyverno.UpdateRequest) {
_, pName, _ := ParseNamespacedPolicy(key)
selector := labels.SelectorFromSet(labels.Set(map[string]string{
urkyverno.URMutatePolicyLabel: pName,
}))
mutateURs, err := pc.urLister.List(selector)
if err != nil {
logger.Error(err, "failed to list update request")
}
selector = labels.SelectorFromSet(labels.Set(map[string]string{
urkyverno.URGeneratePolicyLabel: pName,
}))
generateURs, err := pc.urLister.List(selector)
if err != nil {
logger.Error(err, "failed to list update request")
}
return mutateURs, generateURs
}
func (pc *PolicyController) getPolicy(key string) (policy kyverno.PolicyInterface, err error) {
namespace, key, isNamespacedPolicy := ParseNamespacedPolicy(key)
if !isNamespacedPolicy {
@ -561,39 +535,6 @@ func (pc *PolicyController) getPolicy(key string) (policy kyverno.PolicyInterfac
return
}
func (pc *PolicyController) updateUR(policy kyverno.PolicyInterface, mutateURs, generateURs []*urkyverno.UpdateRequest) {
if mutateURs == nil {
for _, rule := range policy.GetSpec().Rules {
if !rule.IsMutateExisting() {
continue
}
triggers := getTriggers(rule)
for _, trigger := range triggers {
ur := newUR(policy, trigger)
new, err := pc.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace).Create(context.TODO(), ur, metav1.CreateOptions{})
if err != nil {
pc.log.Error(err, "failed to create new UR for mutateExisting rule on policy update", "policy", policy.GetName(), "rule", rule.Name,
"target", fmt.Sprintf("%s/%s/%s/%s", trigger.APIVersion, trigger.Kind, trigger.Namespace, trigger.Name))
continue
} else {
pc.log.V(4).Info("successfully created UR for mutateExisting on policy update", "policy", policy.GetName(), "rule", rule.Name,
"target", fmt.Sprintf("%s/%s/%s/%s", trigger.APIVersion, trigger.Kind, trigger.Namespace, trigger.Name))
}
new.Status.State = urkyverno.Pending
if _, err := pc.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace).UpdateStatus(context.TODO(), new, metav1.UpdateOptions{}); err != nil {
pc.log.Error(err, "failed to set UpdateRequest state to Pending")
}
}
}
return
}
updateUR(pc.kyvernoClient, policy.GetName(), append(mutateURs, generateURs...), pc.log.WithName("updateUR"))
}
func getTriggers(rule kyverno.Rule) []*kyverno.ResourceSpec {
var specs []*kyverno.ResourceSpec
@ -625,7 +566,7 @@ func getTriggers(rule kyverno.Rule) []*kyverno.ResourceSpec {
}
func getTrigger(rd kyverno.ResourceDescription) []*kyverno.ResourceSpec {
if len(rd.Names) == 0 {
if len(rd.Names) == 0 && rd.Name == "" {
return nil
}
@ -637,18 +578,19 @@ func getTrigger(rd kyverno.ResourceDescription) []*kyverno.ResourceSpec {
continue
}
for _, ns := range rd.Namespaces {
for _, name := range rd.Names {
if name == "" {
continue
}
for _, name := range rd.Names {
if name == "" {
continue
}
spec := &kyverno.ResourceSpec{
APIVersion: apiVersion,
Kind: kind,
Namespace: ns,
Name: name,
}
spec := &kyverno.ResourceSpec{
APIVersion: apiVersion,
Kind: kind,
Name: name,
}
for _, ns := range rd.Namespaces {
spec.Namespace = ns
specs = append(specs, spec)
}
}
@ -735,42 +677,3 @@ func missingAutoGenRules(policy kyverno.PolicyInterface, log logr.Logger) bool {
}
return false
}
func newUR(policy kyverno.PolicyInterface, target *kyverno.ResourceSpec) *urkyverno.UpdateRequest {
var policyNameNamespaceKey string
if policy.GetKind() == "Policy" {
policyNameNamespaceKey = policy.GetNamespace() + "/" + policy.GetName()
} else {
policyNameNamespaceKey = policy.GetName()
}
label := map[string]string{
urkyverno.URMutatePolicyLabel: policyNameNamespaceKey,
"mutate.updaterequest.kyverno.io/trigger-name": target.Name,
"mutate.updaterequest.kyverno.io/trigger-namespace": target.Namespace,
"mutate.updaterequest.kyverno.io/trigger-kind": target.Kind,
}
if target.APIVersion != "" {
label["mutate.updaterequest.kyverno.io/trigger-apiversion"] = target.APIVersion
}
return &urkyverno.UpdateRequest{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "ur-",
Namespace: config.KyvernoNamespace,
Labels: label,
},
Spec: urkyverno.UpdateRequestSpec{
Type: urkyverno.Mutate,
Policy: policyNameNamespaceKey,
Resource: kyverno.ResourceSpec{
Kind: target.Kind,
Namespace: target.Namespace,
Name: target.Name,
APIVersion: target.APIVersion,
},
},
}
}

160
pkg/policy/updaterequest.go Normal file
View file

@ -0,0 +1,160 @@
package policy
import (
"context"
"fmt"
"github.com/gardener/controller-manager-library/pkg/logger"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
urkyverno "github.com/kyverno/kyverno/api/kyverno/v1beta1"
"github.com/kyverno/kyverno/pkg/config"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
)
func (pc *PolicyController) updateUR(policyKey string, policy kyverno.PolicyInterface) {
logger := pc.log.WithName("updateUR").WithName(policyKey)
logger.Info("update URs on policy event")
mutateURs := pc.listMutateURs(policyKey, nil)
generateURs := pc.listGenerateURs(policyKey, nil)
updateUR(pc.kyvernoClient, policy.GetName(), append(mutateURs, generateURs...), pc.log.WithName("updateUR"))
for _, rule := range policy.GetSpec().Rules {
var ruleType urkyverno.RequestType
if rule.IsMutateExisting() {
ruleType = urkyverno.Mutate
} else {
// TODO: assign generate ruleType
continue
}
triggers := getTriggers(rule)
for _, trigger := range triggers {
var urs []*urkyverno.UpdateRequest
if ruleType == urkyverno.Mutate {
urs = pc.listMutateURs(policyKey, trigger)
} else {
urs = pc.listGenerateURs(policyKey, trigger)
}
logger.V(4).Info("UR was created", "rule", rule.Name, "rule type", ruleType, "trigger", trigger.Namespace+trigger.Name)
if urs != nil {
continue
}
logger.Info("creating new UR")
ur := newUR(policy, trigger, ruleType)
new, err := pc.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace).Create(context.TODO(), ur, metav1.CreateOptions{})
if err != nil {
pc.log.Error(err, "failed to create new UR policy update", "policy", policy.GetName(), "rule", rule.Name, "rule type", ruleType,
"target", fmt.Sprintf("%s/%s/%s/%s", trigger.APIVersion, trigger.Kind, trigger.Namespace, trigger.Name))
continue
} else {
pc.log.V(4).Info("successfully created UR on policy update", "policy", policy.GetName(), "rule", rule.Name, "rule type", ruleType,
"target", fmt.Sprintf("%s/%s/%s/%s", trigger.APIVersion, trigger.Kind, trigger.Namespace, trigger.Name))
}
new.Status.State = urkyverno.Pending
if _, err := pc.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace).UpdateStatus(context.TODO(), new, metav1.UpdateOptions{}); err != nil {
pc.log.Error(err, "failed to set UpdateRequest state to Pending")
}
}
}
}
func (pc *PolicyController) listMutateURs(policyKey string, trigger *kyverno.ResourceSpec) []*urkyverno.UpdateRequest {
selector := createMutateLabels(policyKey, trigger)
mutateURs, err := pc.urLister.List(labels.SelectorFromSet(selector))
if err != nil {
logger.Error(err, "failed to list update request for mutate policy")
}
return mutateURs
}
func (pc *PolicyController) listGenerateURs(policyKey string, trigger *kyverno.ResourceSpec) []*urkyverno.UpdateRequest {
selector := createGenerateLabels(policyKey, trigger)
generateURs, err := pc.urLister.List(labels.SelectorFromSet(selector))
if err != nil {
logger.Error(err, "failed to list update request for generate policy")
}
return generateURs
}
func newUR(policy kyverno.PolicyInterface, trigger *kyverno.ResourceSpec, ruleType urkyverno.RequestType) *urkyverno.UpdateRequest {
var policyNameNamespaceKey string
if policy.IsNamespaced() {
policyNameNamespaceKey = policy.GetNamespace() + "/" + policy.GetName()
} else {
policyNameNamespaceKey = policy.GetName()
}
var label labels.Set
if ruleType == urkyverno.Mutate {
label = createMutateLabels(policyNameNamespaceKey, trigger)
} else {
label = createGenerateLabels(policyNameNamespaceKey, trigger)
}
return &urkyverno.UpdateRequest{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "ur-",
Namespace: config.KyvernoNamespace,
Labels: label,
},
Spec: urkyverno.UpdateRequestSpec{
Type: ruleType,
Policy: policyNameNamespaceKey,
Resource: kyverno.ResourceSpec{
Kind: trigger.Kind,
Namespace: trigger.Namespace,
Name: trigger.Name,
APIVersion: trigger.APIVersion,
},
},
}
}
func createMutateLabels(policyKey string, trigger *kyverno.ResourceSpec) labels.Set {
var selector labels.Set
if trigger == nil {
selector = labels.Set(map[string]string{
urkyverno.URMutatePolicyLabel: policyKey,
})
} else {
selector = labels.Set(map[string]string{
urkyverno.URMutatePolicyLabel: policyKey,
urkyverno.URMutateTriggerNameLabel: trigger.Name,
urkyverno.URMutateTriggerNSLabel: trigger.Namespace,
urkyverno.URMutatetriggerKindLabel: trigger.Kind,
})
if trigger.APIVersion != "" {
selector[urkyverno.URMutatetriggerAPIVersionLabel] = trigger.APIVersion
}
}
return selector
}
func createGenerateLabels(policyKey string, trigger *kyverno.ResourceSpec) labels.Set {
var selector labels.Set
if trigger == nil {
selector = labels.Set(map[string]string{
urkyverno.URGeneratePolicyLabel: policyKey,
})
} else {
selector = labels.Set(map[string]string{
urkyverno.URGeneratePolicyLabel: policyKey,
"generate.kyverno.io/resource-name": trigger.Name,
"generate.kyverno.io/resource-kind": trigger.Kind,
"generate.kyverno.io/resource-namespace": trigger.Namespace,
})
}
return selector
}

View file

@ -780,7 +780,11 @@ func Test_Generate_Synchronize_Flag(t *testing.T) {
}
return errors.New("deleting Namespace")
})
Expect(err).NotTo(HaveOccurred())
// Do not fail if waiting fails. Sometimes namespace needs time to be deleted.
if err != nil {
By(err.Error())
}
By(fmt.Sprintf("Test %s Completed \n\n\n", test.TestName))
}