1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-05 07:26:55 +00:00

feat: trigger generate on existing matched resource (#3819)

* feat: trigger generate on existing matched resource

Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com>

* refactor the triggers and fix review comments

Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com>

* add trigger for other matching kinds

Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com>

* implement match exclude using dynamic client

Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com>

* refactor generate trigger

Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com>

* increase sleep timeout

Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com>

* optimize unstructured list

Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com>

* fix review comments

Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com>

* log refactor and clean debug comments

Signed-off-by: prateekpandey14 <prateek.pandey@nirmata.com>
This commit is contained in:
Prateek Pandey 2022-05-09 12:43:11 +05:30 committed by GitHub
parent bbe65959bc
commit 8b6d3d1f6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 295 additions and 66 deletions

View file

@ -68,6 +68,12 @@ type Spec struct {
// Default value is "false".
// +optional
MutateExistingOnPolicyUpdate bool `json:"mutateExistingOnPolicyUpdate,omitempty" yaml:"mutateExistingOnPolicyUpdate,omitempty"`
// GenerateExistingOnPolicyUpdate controls wether to trigger generate rule in existing resources
// If is set to "true" generate rule will be triggered and applied to existing matched resources.
// Defaults to "false" if not specified.
// +optional
GenerateExistingOnPolicyUpdate bool `json:"generateExistingOnPolicyUpdate,omitempty" yaml:"generateExistingOnPolicyUpdate,omitempty"`
}
func (s *Spec) SetRules(rules []Rule) {
@ -163,6 +169,11 @@ func (s *Spec) GetMutateExistingOnPolicyUpdate() bool {
return s.MutateExistingOnPolicyUpdate
}
// IsGenerateExistingOnPolicyUpdate return GenerateExistingOnPolicyUpdate set value
func (s *Spec) IsGenerateExistingOnPolicyUpdate() bool {
return s.GenerateExistingOnPolicyUpdate
}
// GetFailurePolicy returns the failure policy to be applied
func (s *Spec) GetFailurePolicy() FailurePolicyType {
if s.FailurePolicy == nil {

View file

@ -64,6 +64,9 @@ spec:
- Ignore
- Fail
type: string
generateExistingOnPolicyUpdate:
description: GenerateExistingOnPolicyUpdate controls wether to trigger generate rule in existing resources If is set to "true" generate rule will be triggered and applied to existing matched resources. Defaults to "false" if not specified.
type: boolean
mutateExistingOnPolicyUpdate:
description: MutateExistingOnPolicyUpdate controls if a mutateExisting policy is applied on policy events. Default value is "false".
type: boolean
@ -2409,6 +2412,9 @@ spec:
- Ignore
- Fail
type: string
generateExistingOnPolicyUpdate:
description: GenerateExistingOnPolicyUpdate controls wether to trigger generate rule in existing resources If is set to "true" generate rule will be triggered and applied to existing matched resources. Defaults to "false" if not specified.
type: boolean
mutateExistingOnPolicyUpdate:
description: MutateExistingOnPolicyUpdate controls if a mutateExisting policy is applied on policy events. Default value is "false".
type: boolean

View file

@ -68,6 +68,12 @@ spec:
- Ignore
- Fail
type: string
generateExistingOnPolicyUpdate:
description: GenerateExistingOnPolicyUpdate controls wether to trigger
generate rule in existing resources If is set to "true" generate
rule will be triggered and applied to existing matched resources.
Defaults to "false" if not specified.
type: boolean
mutateExistingOnPolicyUpdate:
description: MutateExistingOnPolicyUpdate controls if a mutateExisting
policy is applied on policy events. Default value is "false".

View file

@ -69,6 +69,12 @@ spec:
- Ignore
- Fail
type: string
generateExistingOnPolicyUpdate:
description: GenerateExistingOnPolicyUpdate controls wether to trigger
generate rule in existing resources If is set to "true" generate
rule will be triggered and applied to existing matched resources.
Defaults to "false" if not specified.
type: boolean
mutateExistingOnPolicyUpdate:
description: MutateExistingOnPolicyUpdate controls if a mutateExisting
policy is applied on policy events. Default value is "false".

View file

@ -85,6 +85,12 @@ spec:
- Ignore
- Fail
type: string
generateExistingOnPolicyUpdate:
description: GenerateExistingOnPolicyUpdate controls wether to trigger
generate rule in existing resources If is set to "true" generate
rule will be triggered and applied to existing matched resources.
Defaults to "false" if not specified.
type: boolean
mutateExistingOnPolicyUpdate:
description: MutateExistingOnPolicyUpdate controls if a mutateExisting
policy is applied on policy events. Default value is "false".
@ -3591,6 +3597,12 @@ spec:
- Ignore
- Fail
type: string
generateExistingOnPolicyUpdate:
description: GenerateExistingOnPolicyUpdate controls wether to trigger
generate rule in existing resources If is set to "true" generate
rule will be triggered and applied to existing matched resources.
Defaults to "false" if not specified.
type: boolean
mutateExistingOnPolicyUpdate:
description: MutateExistingOnPolicyUpdate controls if a mutateExisting
policy is applied on policy events. Default value is "false".

View file

@ -83,6 +83,12 @@ spec:
- Ignore
- Fail
type: string
generateExistingOnPolicyUpdate:
description: GenerateExistingOnPolicyUpdate controls wether to trigger
generate rule in existing resources If is set to "true" generate
rule will be triggered and applied to existing matched resources.
Defaults to "false" if not specified.
type: boolean
mutateExistingOnPolicyUpdate:
description: MutateExistingOnPolicyUpdate controls if a mutateExisting
policy is applied on policy events. Default value is "false".
@ -3585,6 +3591,12 @@ spec:
- Ignore
- Fail
type: string
generateExistingOnPolicyUpdate:
description: GenerateExistingOnPolicyUpdate controls wether to trigger
generate rule in existing resources If is set to "true" generate
rule will be triggered and applied to existing matched resources.
Defaults to "false" if not specified.
type: boolean
mutateExistingOnPolicyUpdate:
description: MutateExistingOnPolicyUpdate controls if a mutateExisting
policy is applied on policy events. Default value is "false".

View file

@ -202,6 +202,20 @@ bool
Default value is &ldquo;false&rdquo;.</p>
</td>
</tr>
<tr>
<td>
<code>generateExistingOnPolicyUpdate</code></br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>GenerateExistingOnPolicyUpdate controls wether to trigger generate rule in existing resources
If is set to &ldquo;true&rdquo; generate rule will be triggered and applied to existing matched resources.
Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
</table>
</td>
</tr>
@ -395,6 +409,20 @@ bool
Default value is &ldquo;false&rdquo;.</p>
</td>
</tr>
<tr>
<td>
<code>generateExistingOnPolicyUpdate</code></br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>GenerateExistingOnPolicyUpdate controls wether to trigger generate rule in existing resources
If is set to &ldquo;true&rdquo; generate rule will be triggered and applied to existing matched resources.
Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
</table>
</td>
</tr>
@ -2954,6 +2982,20 @@ bool
Default value is &ldquo;false&rdquo;.</p>
</td>
</tr>
<tr>
<td>
<code>generateExistingOnPolicyUpdate</code></br>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>GenerateExistingOnPolicyUpdate controls wether to trigger generate rule in existing resources
If is set to &ldquo;true&rdquo; generate rule will be triggered and applied to existing matched resources.
Defaults to &ldquo;false&rdquo; if not specified.</p>
</td>
</tr>
</tbody>
</table>
<hr />

View file

@ -349,8 +349,8 @@ func (c *GenerateController) applyGeneratePolicy(log logr.Logger, policyContext
return nil, processExisting, err
}
if !processExisting {
genResource, err = applyRule(log, c.client, rule, resource, jsonContext, policy.GetName(), ur)
if policy.GetSpec().IsGenerateExistingOnPolicyUpdate() || !processExisting {
genResource, err = applyRule(log, c.client, rule, resource, jsonContext, policy, ur)
if err != nil {
log.Error(err, "failed to apply generate rule", "policy", policy.GetName(),
"rule", rule.Name, "resource", resource.GetName(), "suggestion", "users need to grant Kyverno's service account additional privileges")
@ -359,6 +359,10 @@ func (c *GenerateController) applyGeneratePolicy(log logr.Logger, policyContext
ruleNameToProcessingTime[rule.Name] = time.Since(startTime)
genResources = append(genResources, genResource)
}
if policy.GetSpec().IsGenerateExistingOnPolicyUpdate() {
processExisting = false
}
}
return genResources, processExisting, nil
@ -384,7 +388,7 @@ func getResourceInfo(object map[string]interface{}) (kind, name, namespace, apiv
return
}
func applyRule(log logr.Logger, client dclient.Interface, rule kyverno.Rule, resource unstructured.Unstructured, ctx context.EvalInterface, policy string, ur urkyverno.UpdateRequest) (kyverno.ResourceSpec, error) {
func applyRule(log logr.Logger, client dclient.Interface, rule kyverno.Rule, resource unstructured.Unstructured, ctx context.EvalInterface, policy kyverno.PolicyInterface, ur urkyverno.UpdateRequest) (kyverno.ResourceSpec, error) {
var rdata map[string]interface{}
var err error
var mode ResourceMode
@ -420,7 +424,7 @@ func applyRule(log logr.Logger, client dclient.Interface, rule kyverno.Rule, res
}
if len(genClone) != 0 {
rdata, mode, err = manageClone(logger, genAPIVersion, genKind, genNamespace, genName, policy, genClone, client)
rdata, mode, err = manageClone(logger, genAPIVersion, genKind, genNamespace, genName, policy.GetName(), genClone, client)
} else {
rdata, mode, err = manageData(logger, genAPIVersion, genKind, genNamespace, genName, genData, client)
}
@ -455,7 +459,13 @@ func applyRule(log logr.Logger, client dclient.Interface, rule kyverno.Rule, res
common.ManageLabels(newResource, resource)
// Add Synchronize label
label := newResource.GetLabels()
label["policy.kyverno.io/policy-name"] = policy
// Add background gen-rule label if generate rule applied on existing resource
if policy.GetSpec().IsGenerateExistingOnPolicyUpdate() {
label["kyverno.io/background-gen-rule"] = rule.Name
}
label["policy.kyverno.io/policy-name"] = policy.GetName()
label["policy.kyverno.io/gr-name"] = ur.Name
if mode == Create {
if rule.Generation.Synchronize {

View file

@ -12,7 +12,7 @@ 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/cmd/cli/kubectl-kyverno/utils/common"
utilscommon "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common"
"github.com/kyverno/kyverno/pkg/autogen"
kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned"
"github.com/kyverno/kyverno/pkg/client/clientset/versioned/scheme"
@ -30,6 +30,7 @@ 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/apis/meta/v1/unstructured"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
informers "k8s.io/client-go/informers/core/v1"
@ -177,7 +178,7 @@ func (pc *PolicyController) addPolicy(obj interface{}) {
go pc.registerPolicyChangesMetricAddPolicy(logger, p)
if p.Spec.Background == nil || p.Spec.ValidationFailureAction == "" || missingAutoGenRules(p, logger) {
pol, _ := common.MutatePolicy(p, logger)
pol, _ := utilscommon.MutatePolicy(p, logger)
_, err := pc.kyvernoClient.KyvernoV1().ClusterPolicies().Update(context.TODO(), pol.(*kyverno.ClusterPolicy), metav1.UpdateOptions{})
if err != nil {
logger.Error(err, "failed to add policy ")
@ -203,7 +204,7 @@ func (pc *PolicyController) updatePolicy(old, cur interface{}) {
go pc.registerPolicyChangesMetricUpdatePolicy(logger, oldP, curP)
if curP.Spec.Background == nil || curP.Spec.ValidationFailureAction == "" || missingAutoGenRules(curP, logger) {
pol, _ := common.MutatePolicy(curP, logger)
pol, _ := utilscommon.MutatePolicy(curP, logger)
_, err := pc.kyvernoClient.KyvernoV1().ClusterPolicies().Update(context.TODO(), pol.(*kyverno.ClusterPolicy), metav1.UpdateOptions{})
if err != nil {
logger.Error(err, "failed to update policy ")
@ -273,7 +274,7 @@ func (pc *PolicyController) addNsPolicy(obj interface{}) {
spec := p.GetSpec()
if spec.Background == nil || spec.ValidationFailureAction == "" || missingAutoGenRules(p, logger) {
nsPol, _ := common.MutatePolicy(p, logger)
nsPol, _ := utilscommon.MutatePolicy(p, logger)
_, err := pc.kyvernoClient.KyvernoV1().Policies(p.Namespace).Update(context.TODO(), nsPol.(*kyverno.Policy), metav1.UpdateOptions{})
if err != nil {
logger.Error(err, "failed to add namespace policy")
@ -297,7 +298,7 @@ func (pc *PolicyController) updateNsPolicy(old, cur interface{}) {
go pc.registerPolicyChangesMetricUpdatePolicy(logger, oldP, curP)
if curP.Spec.Background == nil || curP.Spec.ValidationFailureAction == "" || missingAutoGenRules(curP, logger) {
nsPol, _ := common.MutatePolicy(curP, logger)
nsPol, _ := utilscommon.MutatePolicy(curP, logger)
_, err := pc.kyvernoClient.KyvernoV1().Policies(curP.GetNamespace()).Update(context.TODO(), nsPol.(*kyverno.Policy), metav1.UpdateOptions{})
if err != nil {
logger.Error(err, "failed to update namespace policy ")
@ -481,7 +482,10 @@ func (pc *PolicyController) syncPolicy(key string) error {
}
return err
} else {
pc.updateUR(key, policy)
err = pc.updateUR(key, policy)
if err != nil {
logger.Error(err, "failed to updateUR on Policy update")
}
}
pc.processExistingResources(policy)
@ -566,6 +570,21 @@ func getTrigger(rd kyverno.ResourceDescription) []*kyverno.ResourceSpec {
return specs
}
func generateTriggers(client client.Interface, rule kyverno.Rule, log logr.Logger) []*unstructured.Unstructured {
list := &unstructured.UnstructuredList{}
kinds := fetchUniqueKinds(rule)
for _, kind := range kinds {
mlist, err := client.ListResource("", kind, "", rule.MatchResources.Selector)
if err != nil {
log.Error(err, "failed to list matched resource")
}
list.Items = append(list.Items, mlist.Items...)
}
return convertlist(list.Items)
}
func deleteUR(kyvernoClient kyvernoclient.Interface, policyKey string, grList []*urkyverno.UpdateRequest, logger logr.Logger) {
for _, v := range grList {
if policyKey == v.Spec.Policy {

View file

@ -7,71 +7,119 @@ import (
"github.com/gardener/controller-manager-library/pkg/logger"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
urkyverno "github.com/kyverno/kyverno/api/kyverno/v1beta1"
common "github.com/kyverno/kyverno/pkg/background/common"
"github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/engine"
"github.com/kyverno/kyverno/pkg/engine/response"
engineutils "github.com/kyverno/kyverno/pkg/engine/utils"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func (pc *PolicyController) updateUR(policyKey string, policy kyverno.PolicyInterface) {
func (pc *PolicyController) updateUR(policyKey string, policy kyverno.PolicyInterface) error {
logger := pc.log.WithName("updateUR").WithName(policyKey)
// TODO: add check for genExisting
if !policy.GetSpec().MutateExistingOnPolicyUpdate {
logger.V(4).Info("skip policy application on policy event", "policyKey", policyKey, "mutateExiting", policy.GetSpec().MutateExistingOnPolicyUpdate)
return
if !policy.GetSpec().MutateExistingOnPolicyUpdate && !policy.GetSpec().IsGenerateExistingOnPolicyUpdate() {
logger.V(4).Info("skip policy application on policy event", "policyKey", policyKey, "mutateExiting", policy.GetSpec().MutateExistingOnPolicyUpdate, "generateExisting", policy.GetSpec().IsGenerateExistingOnPolicyUpdate())
return nil
}
logger.Info("update URs on policy event")
var errors []error
mutateURs := pc.listMutateURs(policyKey, nil)
generateURs := pc.listGenerateURs(policyKey, nil)
updateUR(pc.kyvernoClient, policyKey, 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
triggers := generateTriggers(pc.client, rule, pc.log)
for _, trigger := range triggers {
murs := pc.listMutateURs(policyKey, trigger)
if murs != nil {
logger.V(4).Info("UR was created", "rule", rule.Name, "rule type", ruleType, "trigger", trigger.GetNamespace()+trigger.GetName())
continue
}
logger.Info("creating new UR")
ur := newUR(policy, trigger, ruleType)
err := pc.handleUpdateRequest(ur, trigger, rule, policy)
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.GetAPIVersion(), trigger.GetKind(), trigger.GetNamespace(), trigger.GetName()))
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.GetAPIVersion(), trigger.GetKind(), trigger.GetNamespace(), trigger.GetName()))
}
}
}
if policy.GetSpec().IsGenerateExistingOnPolicyUpdate() {
ruleType = urkyverno.Generate
triggers := generateTriggers(pc.client, rule, pc.log)
for _, trigger := range triggers {
gurs := pc.listGenerateURs(policyKey, trigger)
if gurs != nil {
logger.V(4).Info("UR was created", "rule", rule.Name, "rule type", ruleType, "trigger", trigger.GetNamespace()+"/"+trigger.GetName())
continue
}
logger.Info("creating new UR")
ur := newUR(policy, trigger, ruleType)
err := pc.handleUpdateRequest(ur, trigger, rule, policy)
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.GetAPIVersion(), trigger.GetKind(), trigger.GetNamespace(), trigger.GetName()))
errors = append(errors, err)
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.GetAPIVersion(), trigger.GetKind(), trigger.GetNamespace(), trigger.GetName()))
}
}
err := engineutils.CombineErrors(errors)
return err
}
}
return nil
}
func (pc *PolicyController) handleUpdateRequest(ur *urkyverno.UpdateRequest, triggerResource *unstructured.Unstructured, rule kyverno.Rule, policy kyverno.PolicyInterface) error {
policyContext, _, err := common.NewBackgroundContext(pc.client, ur, policy, triggerResource, pc.configHandler, nil, pc.log)
if err != nil {
pc.log.WithName(rule.Name).Error(err, "failed to build policy context for existing")
}
engineResponse := engine.ApplyBackgroundChecks(policyContext)
for _, ruleResponse := range engineResponse.PolicyResponse.Rules {
if ruleResponse.Status != response.RuleStatusPass {
pc.log.Error(err, "can not create new UR for genExisting rule on policy update", "policy", policy.GetName(), "rule", rule.Name, "rule.Status", ruleResponse.Status)
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)
}
new, err := pc.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace).Create(context.TODO(), ur, metav1.CreateOptions{})
if err != nil {
return err
}
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")
}
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 err
}
}
return err
}
func (pc *PolicyController) listMutateURs(policyKey string, trigger *kyverno.ResourceSpec) []*urkyverno.UpdateRequest {
func (pc *PolicyController) listMutateURs(policyKey string, trigger *unstructured.Unstructured) []*urkyverno.UpdateRequest {
selector := createMutateLabels(policyKey, trigger)
mutateURs, err := pc.urLister.List(labels.SelectorFromSet(selector))
if err != nil {
@ -81,7 +129,7 @@ func (pc *PolicyController) listMutateURs(policyKey string, trigger *kyverno.Res
return mutateURs
}
func (pc *PolicyController) listGenerateURs(policyKey string, trigger *kyverno.ResourceSpec) []*urkyverno.UpdateRequest {
func (pc *PolicyController) listGenerateURs(policyKey string, trigger *unstructured.Unstructured) []*urkyverno.UpdateRequest {
selector := createGenerateLabels(policyKey, trigger)
generateURs, err := pc.urLister.List(labels.SelectorFromSet(selector))
if err != nil {
@ -91,7 +139,7 @@ func (pc *PolicyController) listGenerateURs(policyKey string, trigger *kyverno.R
return generateURs
}
func newUR(policy kyverno.PolicyInterface, trigger *kyverno.ResourceSpec, ruleType urkyverno.RequestType) *urkyverno.UpdateRequest {
func newUR(policy kyverno.PolicyInterface, trigger *unstructured.Unstructured, ruleType urkyverno.RequestType) *urkyverno.UpdateRequest {
var policyNameNamespaceKey string
if policy.IsNamespaced() {
@ -117,16 +165,16 @@ func newUR(policy kyverno.PolicyInterface, trigger *kyverno.ResourceSpec, ruleTy
Type: ruleType,
Policy: policyNameNamespaceKey,
Resource: kyverno.ResourceSpec{
Kind: trigger.Kind,
Namespace: trigger.Namespace,
Name: trigger.Name,
APIVersion: trigger.APIVersion,
Kind: trigger.GetKind(),
Namespace: trigger.GetNamespace(),
Name: trigger.GetName(),
APIVersion: trigger.GetAPIVersion(),
},
},
}
}
func createMutateLabels(policyKey string, trigger *kyverno.ResourceSpec) labels.Set {
func createMutateLabels(policyKey string, trigger *unstructured.Unstructured) labels.Set {
var selector labels.Set
if trigger == nil {
selector = labels.Set(map[string]string{
@ -135,20 +183,21 @@ func createMutateLabels(policyKey string, trigger *kyverno.ResourceSpec) labels.
} else {
selector = labels.Set(map[string]string{
urkyverno.URMutatePolicyLabel: policyKey,
urkyverno.URMutateTriggerNameLabel: trigger.Name,
urkyverno.URMutateTriggerNSLabel: trigger.Namespace,
urkyverno.URMutatetriggerKindLabel: trigger.Kind,
urkyverno.URMutateTriggerNameLabel: trigger.GetName(),
urkyverno.URMutateTriggerNSLabel: trigger.GetNamespace(),
urkyverno.URMutatetriggerKindLabel: trigger.GetKind(),
})
if trigger.APIVersion != "" {
selector[urkyverno.URMutatetriggerAPIVersionLabel] = trigger.APIVersion
if trigger.GetAPIVersion() != "" {
selector[urkyverno.URMutatetriggerAPIVersionLabel] = trigger.GetAPIVersion()
}
}
return selector
}
func createGenerateLabels(policyKey string, trigger *kyverno.ResourceSpec) labels.Set {
func createGenerateLabels(policyKey string, trigger *unstructured.Unstructured) labels.Set {
var selector labels.Set
if trigger == nil {
selector = labels.Set(map[string]string{
@ -157,9 +206,9 @@ func createGenerateLabels(policyKey string, trigger *kyverno.ResourceSpec) label
} 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,
"generate.kyverno.io/resource-name": trigger.GetName(),
"generate.kyverno.io/resource-kind": trigger.GetKind(),
"generate.kyverno.io/resource-namespace": trigger.GetNamespace(),
})
}

View file

@ -1,6 +1,9 @@
package policy
import "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
import (
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func isRunningPod(obj unstructured.Unstructured) bool {
objMap := obj.UnstructuredContent()
@ -11,3 +14,56 @@ func isRunningPod(obj unstructured.Unstructured) bool {
return phase == "Running"
}
// check if all slice elements are same
func isMatchResourcesAllValid(rule kyverno.Rule) bool {
var kindlist []string
for _, all := range rule.MatchResources.All {
kindlist = append(kindlist, all.Kinds...)
}
if len(kindlist) == 0 {
return false
}
for i := 1; i < len(kindlist); i++ {
if kindlist[i] != kindlist[0] {
return false
}
}
return true
}
func fetchUniqueKinds(rule kyverno.Rule) []string {
var kindlist []string
kindlist = append(kindlist, rule.MatchResources.Kinds...)
for _, all := range rule.MatchResources.Any {
kindlist = append(kindlist, all.Kinds...)
}
if isMatchResourcesAllValid(rule) {
for _, all := range rule.MatchResources.All {
kindlist = append(kindlist, all.Kinds...)
}
}
inResult := make(map[string]bool)
var result []string
for _, kind := range kindlist {
if _, ok := inResult[kind]; !ok {
inResult[kind] = true
result = append(result, kind)
}
}
return result
}
func convertlist(ulists []unstructured.Unstructured) []*unstructured.Unstructured {
var result []*unstructured.Unstructured
for _, list := range ulists {
result = append(result, list.DeepCopy())
}
return result
}