mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-29 02:45:06 +00:00
[Improvement] Kyverno should not delete downstream resources when a generate policy using the clone behavior has synchronize: true (#1880)
* debuging issue Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * issue fixed Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * remove policy name in source resource Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * fixed deletion of GR on source updation Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * added function in common Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * removing comments Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * added generated resource list to the log Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * small improvement Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com>
This commit is contained in:
parent
2c9e52af98
commit
cd9e596e7e
5 changed files with 106 additions and 15 deletions
1
go.sum
1
go.sum
|
@ -1019,6 +1019,7 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
|
|||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
|
||||
github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||
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"
|
||||
|
@ -136,3 +138,47 @@ func RetryFunc(retryInterval, timeout time.Duration, run func() error, logger lo
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func ProcessDeletePolicyForCloneGenerateRule(rules []kyverno.Rule, client *dclient.Client, pName string, logger logr.Logger) bool {
|
||||
generatePolicyWithClone := false
|
||||
for _, rule := range rules {
|
||||
if rule.Generation.Clone.Name != "" {
|
||||
logger.V(4).Info("generate policy with clone, skipping deletion of generate request")
|
||||
generatePolicyWithClone = true
|
||||
obj, err := client.GetResource("", rule.Generation.Kind, rule.Generation.Clone.Namespace, rule.Generation.Clone.Name)
|
||||
if err != nil {
|
||||
logger.Error(err, fmt.Sprintf("source resource %s/%s/%s not found.", rule.Generation.Kind, rule.Generation.Clone.Namespace, rule.Generation.Clone.Name))
|
||||
continue
|
||||
}
|
||||
|
||||
updateSource := true
|
||||
label := obj.GetLabels()
|
||||
logger.V(4).Info("removing policy name from label of source resource")
|
||||
|
||||
if len(label) != 0 {
|
||||
if label["generate.kyverno.io/clone-policy-name"] != "" {
|
||||
policyNames := label["generate.kyverno.io/clone-policy-name"]
|
||||
if strings.Contains(policyNames, pName) {
|
||||
updatedPolicyNames := strings.Replace(policyNames, pName, "", -1)
|
||||
label["generate.kyverno.io/clone-policy-name"] = updatedPolicyNames
|
||||
} else {
|
||||
updateSource = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if updateSource {
|
||||
logger.V(4).Info("updating existing clone source")
|
||||
obj.SetLabels(label)
|
||||
_, err = client.UpdateResource(obj.GetAPIVersion(), rule.Generation.Kind, rule.Generation.Clone.Namespace, obj, false)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to update source", "kind", obj.GetKind(), "name", obj.GetName(), "namespace", obj.GetNamespace())
|
||||
continue
|
||||
}
|
||||
logger.V(4).Info("updated source", "kind", obj.GetKind(), "name", obj.GetName(), "namespace", obj.GetNamespace())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return generatePolicyWithClone
|
||||
}
|
||||
|
|
|
@ -10,10 +10,12 @@ import (
|
|||
kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned"
|
||||
kyvernoinformer "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1"
|
||||
kyvernolister "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1"
|
||||
pkgCommon "github.com/kyverno/kyverno/pkg/common"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
dclient "github.com/kyverno/kyverno/pkg/dclient"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/dynamic/dynamicinformer"
|
||||
|
@ -139,14 +141,37 @@ func (c *Controller) deletePolicy(obj interface{}) {
|
|||
// clean up the GR
|
||||
// Get the corresponding GR
|
||||
// get the list of GR for the current Policy version
|
||||
grs, err := c.grLister.GetGenerateRequestsForClusterPolicy(p.Name)
|
||||
rules := p.Spec.Rules
|
||||
|
||||
generatePolicyWithClone := pkgCommon.ProcessDeletePolicyForCloneGenerateRule(rules, c.client, p.GetName(), logger)
|
||||
|
||||
// get the generated resource name from generate request for log
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{
|
||||
"generate.kyverno.io/policy-name": p.Name,
|
||||
}))
|
||||
|
||||
grList, err := c.grLister.List(selector)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to generate request CR for the policy", "name", p.Name)
|
||||
logger.Error(err, "failed to get generate request for the resource", "label", "generate.kyverno.io/policy-name")
|
||||
return
|
||||
}
|
||||
|
||||
for _, gr := range grs {
|
||||
c.addGR(gr)
|
||||
for _, gr := range grList {
|
||||
for _, generatedResource := range gr.Status.GeneratedResources {
|
||||
logger.Info("retaining resource", "APIVersion", generatedResource.APIVersion, "Kind", generatedResource.Kind, "Name", generatedResource.Name, "Nmaespace", generatedResource.Namespace)
|
||||
}
|
||||
}
|
||||
|
||||
if !generatePolicyWithClone {
|
||||
grs, err := c.grLister.GetGenerateRequestsForClusterPolicy(p.Name)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to generate request CR for the policy", "name", p.Name)
|
||||
return
|
||||
}
|
||||
|
||||
for _, gr := range grs {
|
||||
c.addGR(gr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/client/clientset/versioned/scheme"
|
||||
kyvernoinformer "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1"
|
||||
kyvernolister "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1"
|
||||
pkgCommon "github.com/kyverno/kyverno/pkg/common"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
client "github.com/kyverno/kyverno/pkg/dclient"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
|
@ -341,8 +342,15 @@ func (pc *PolicyController) deletePolicy(obj interface{}) {
|
|||
|
||||
// we process policies that are not set of background processing
|
||||
// as we need to clean up GRs when a policy is deleted
|
||||
pc.enqueuePolicy(p)
|
||||
pc.enqueueRCRDeletedPolicy(p.Name)
|
||||
// skip generate policies with clone
|
||||
rules := p.Spec.Rules
|
||||
|
||||
generatePolicyWithClone := pkgCommon.ProcessDeletePolicyForCloneGenerateRule(rules, pc.client, p.GetName(), logger)
|
||||
|
||||
if !generatePolicyWithClone {
|
||||
pc.enqueuePolicy(p)
|
||||
pc.enqueueRCRDeletedPolicy(p.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func (pc *PolicyController) registerPolicyRuleInfoMetricAddNsPolicy(logger logr.Logger, p *kyverno.Policy) {
|
||||
|
|
|
@ -154,18 +154,29 @@ func (ws *WebhookServer) handleUpdate(request *v1beta1.AdmissionRequest, policie
|
|||
func (ws *WebhookServer) handleUpdateCloneSourceResource(resLabels map[string]string, logger logr.Logger) {
|
||||
policyNames := strings.Split(resLabels["generate.kyverno.io/clone-policy-name"], ",")
|
||||
for _, policyName := range policyNames {
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{
|
||||
"generate.kyverno.io/policy-name": policyName,
|
||||
}))
|
||||
|
||||
grList, err := ws.grLister.List(selector)
|
||||
// check if the policy exists
|
||||
_, err := ws.kyvernoClient.KyvernoV1().ClusterPolicies().Get(contextdefault.TODO(), policyName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to get generate request for the resource", "label", "generate.kyverno.io/policy-name")
|
||||
return
|
||||
}
|
||||
for _, gr := range grList {
|
||||
ws.updateAnnotationInGR(gr, logger)
|
||||
if strings.Contains(err.Error(), "not found") {
|
||||
logger.V(4).Info("skipping updation of generate request as policy is deleted")
|
||||
} else {
|
||||
logger.Error(err, "failed to get generate policy", "Name", policyName)
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{
|
||||
"generate.kyverno.io/policy-name": policyName,
|
||||
}))
|
||||
|
||||
grList, err := ws.grLister.List(selector)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to get generate request for the resource", "label", "generate.kyverno.io/policy-name")
|
||||
return
|
||||
}
|
||||
for _, gr := range grList {
|
||||
ws.updateAnnotationInGR(gr, logger)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue