mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-09 17:37:12 +00:00
* fix: generate label resource name character length issue Signed-off-by: Chandan-DK <chandandk468@gmail.com> * add source label Signed-off-by: Chandan-DK <chandandk468@gmail.com> * modify newUR function Signed-off-by: Chandan-DK <chandandk468@gmail.com> * fix Signed-off-by: Chandan-DK <chandandk468@gmail.com> * improve readability Signed-off-by: Chandan-DK <chandandk468@gmail.com> * remove generate source name label Signed-off-by: Chandan-DK <chandandk468@gmail.com> * Revert changes Signed-off-by: Chandan-DK <chandandk468@gmail.com> * update ResourceSpec Signed-off-by: Chandan-DK <chandandk468@gmail.com> * add URGenerateResourceUIDLabel Signed-off-by: Chandan-DK <chandandk468@gmail.com> * make codegen crds all Signed-off-by: Chandan-DK <chandandk468@gmail.com> * make codegen client all Signed-off-by: Chandan-DK <chandandk468@gmail.com> * add GenerateSourceUIDLabel Signed-off-by: Chandan-DK <chandandk468@gmail.com> * modify comment Signed-off-by: Chandan-DK <chandandk468@gmail.com> * make codegen crds all Signed-off-by: Chandan-DK <chandandk468@gmail.com> * make codegen-docs-all Signed-off-by: Chandan-DK <chandandk468@gmail.com> * make codegen-all Signed-off-by: Chandan-DK <chandandk468@gmail.com> * set trigger uid Signed-off-by: Chandan-DK <chandandk468@gmail.com> * add uid in transform() Signed-off-by: Chandan-DK <chandandk468@gmail.com> * add name label Signed-off-by: Chandan-DK <chandandk468@gmail.com> * fix: use resource name labels along with its UID Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: use the resource name label only if its uid label isn't set Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * add kuttl tests Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: delete the trigger resource in the test Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * fix: delete the source in the kuttl test Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> * add generate trigger uid label Signed-off-by: Chandan-DK <chandandk468@gmail.com> * modify TriggerInfo function Signed-off-by: Chandan-DK <chandandk468@gmail.com> * populate uid field for new update requests Signed-off-by: Chandan-DK <chandandk468@gmail.com> * populate new ur spec with uid Signed-off-by: Chandan-DK <chandandk468@gmail.com> * handle downstream resources cleanup Signed-off-by: Chandan-DK <chandandk468@gmail.com> * populate uid of ur status Signed-off-by: Chandan-DK <chandandk468@gmail.com> * fetch triggers by the UID label Signed-off-by: ShutingZhao <shuting@nirmata.com> * label triggers Signed-off-by: ShutingZhao <shuting@nirmata.com> * fetch trigger by comparing UID Signed-off-by: ShutingZhao <shuting@nirmata.com> * fetch cloneList downstream resource by UID Signed-off-by: ShutingZhao <shuting@nirmata.com> * update test names Signed-off-by: ShutingZhao <shuting@nirmata.com> * remove trigger name label assertions from kuttl tests Signed-off-by: ShutingZhao <shuting@nirmata.com> * add unit name selector Signed-off-by: ShutingZhao <shuting@nirmata.com> * add sleep Signed-off-by: ShutingZhao <shuting@nirmata.com> * assert events on failures Signed-off-by: ShutingZhao <shuting@nirmata.com> * rename tests Signed-off-by: ShutingZhao <shuting@nirmata.com> --------- Signed-off-by: Chandan-DK <chandandk468@gmail.com> Signed-off-by: Chip Zoller <chipzoller@gmail.com> Signed-off-by: Mariam Fahmy <mariam.fahmy@nirmata.com> Signed-off-by: shuting <shuting@nirmata.com> Signed-off-by: ShutingZhao <shuting@nirmata.com> Co-authored-by: Chip Zoller <chipzoller@gmail.com> Co-authored-by: Mariam Fahmy <mariam.fahmy@nirmata.com> Co-authored-by: shuting <shuting@nirmata.com>
152 lines
5.8 KiB
Go
152 lines
5.8 KiB
Go
package generate
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/kyverno/kyverno/api/kyverno"
|
|
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
|
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
|
"github.com/kyverno/kyverno/pkg/background/common"
|
|
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
|
"go.uber.org/multierr"
|
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
)
|
|
|
|
func (c *GenerateController) deleteDownstream(policy kyvernov1.PolicyInterface, ur *kyvernov1beta1.UpdateRequest) (err error) {
|
|
if !ur.Spec.DeleteDownstream {
|
|
return nil
|
|
}
|
|
|
|
// handle data policy/rule deletion
|
|
if ur.Status.GeneratedResources != nil {
|
|
c.log.V(4).Info("policy/rule no longer exists, deleting the downstream resource based on synchronize", "ur", ur.Name, "policy", ur.Spec.Policy, "rule", ur.Spec.Rule)
|
|
var errs []error
|
|
failedDownstreams := []kyvernov1.ResourceSpec{}
|
|
for _, e := range ur.Status.GeneratedResources {
|
|
if err := c.client.DeleteResource(context.TODO(), e.GetAPIVersion(), e.GetKind(), e.GetNamespace(), e.GetName(), false); err != nil && !apierrors.IsNotFound(err) {
|
|
failedDownstreams = append(failedDownstreams, e)
|
|
errs = append(errs, err)
|
|
}
|
|
}
|
|
|
|
if len(errs) != 0 {
|
|
c.log.Error(multierr.Combine(errs...), "failed to clean up downstream resources on policy deletion")
|
|
_, err = c.statusControl.Failed(ur.GetName(),
|
|
fmt.Sprintf("failed to clean up downstream resources on policy deletion: %v", multierr.Combine(errs...)),
|
|
failedDownstreams)
|
|
} else {
|
|
_, err = c.statusControl.Success(ur.GetName(), nil)
|
|
}
|
|
return
|
|
}
|
|
|
|
if policy == nil {
|
|
return nil
|
|
}
|
|
|
|
return c.handleNonPolicyChanges(policy, ur)
|
|
}
|
|
|
|
func (c *GenerateController) handleNonPolicyChanges(policy kyvernov1.PolicyInterface, ur *kyvernov1beta1.UpdateRequest) error {
|
|
if !ur.Spec.DeleteDownstream {
|
|
return nil
|
|
}
|
|
|
|
for _, rule := range policy.GetSpec().Rules {
|
|
if ur.Spec.Rule != rule.Name {
|
|
continue
|
|
}
|
|
labels := map[string]string{
|
|
common.GeneratePolicyLabel: policy.GetName(),
|
|
common.GeneratePolicyNamespaceLabel: policy.GetNamespace(),
|
|
common.GenerateRuleLabel: rule.Name,
|
|
kyverno.LabelAppManagedBy: kyverno.ValueKyvernoApp,
|
|
}
|
|
|
|
downstreams, err := c.getDownstreams(rule, labels, ur)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to fetch downstream resources: %v", err)
|
|
}
|
|
var errs []error
|
|
failedDownstreams := []kyvernov1.ResourceSpec{}
|
|
for _, downstream := range downstreams.Items {
|
|
spec := common.ResourceSpecFromUnstructured(downstream)
|
|
if err := c.client.DeleteResource(context.TODO(), downstream.GetAPIVersion(), downstream.GetKind(), downstream.GetNamespace(), downstream.GetName(), false); err != nil && !apierrors.IsNotFound(err) {
|
|
failedDownstreams = append(failedDownstreams, spec)
|
|
errs = append(errs, err)
|
|
} else {
|
|
c.log.V(4).Info("downstream resource deleted", spec.String())
|
|
}
|
|
}
|
|
if len(errs) != 0 {
|
|
_, err = c.statusControl.Failed(ur.GetName(),
|
|
fmt.Sprintf("failed to clean up downstream resources on source deletion: %v", multierr.Combine(errs...)),
|
|
failedDownstreams)
|
|
} else {
|
|
_, err = c.statusControl.Success(ur.GetName(), nil)
|
|
}
|
|
if err != nil {
|
|
c.log.Error(err, "failed to update ur status")
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *GenerateController) getDownstreams(rule kyvernov1.Rule, selector map[string]string, ur *kyvernov1beta1.UpdateRequest) (*unstructured.UnstructuredList, error) {
|
|
gv, err := ur.Spec.GetResource().GetGroupVersion()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
selector[common.GenerateTriggerUIDLabel] = string(ur.Spec.GetResource().GetUID())
|
|
selector[common.GenerateTriggerNSLabel] = ur.Spec.GetResource().GetNamespace()
|
|
selector[common.GenerateTriggerKindLabel] = ur.Spec.GetResource().GetKind()
|
|
selector[common.GenerateTriggerGroupLabel] = gv.Group
|
|
selector[common.GenerateTriggerVersionLabel] = gv.Version
|
|
if rule.Generation.GetKind() != "" {
|
|
// Fetch downstream resources using trigger uid label
|
|
c.log.V(4).Info("fetching downstream resource by the UID", "APIVersion", rule.Generation.GetAPIVersion(), "kind", rule.Generation.GetKind(), "selector", selector)
|
|
downstreamList, err := common.FindDownstream(c.client, rule.Generation.GetAPIVersion(), rule.Generation.GetKind(), selector)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(downstreamList.Items) == 0 {
|
|
// Fetch downstream resources using the trigger name label
|
|
delete(selector, common.GenerateTriggerUIDLabel)
|
|
selector[common.GenerateTriggerNameLabel] = ur.Spec.GetResource().GetName()
|
|
c.log.V(4).Info("fetching downstream resource by the name", "APIVersion", rule.Generation.GetAPIVersion(), "kind", rule.Generation.GetKind(), "selector", selector)
|
|
dsList, err := common.FindDownstream(c.client, rule.Generation.GetAPIVersion(), rule.Generation.GetKind(), selector)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
downstreamList.Items = append(downstreamList.Items, dsList.Items...)
|
|
}
|
|
|
|
return downstreamList, err
|
|
}
|
|
|
|
dsList := &unstructured.UnstructuredList{}
|
|
for _, kind := range rule.Generation.CloneList.Kinds {
|
|
apiVersion, kind := kubeutils.GetKindFromGVK(kind)
|
|
c.log.V(4).Info("fetching downstream cloneList resources by the UID", "APIVersion", apiVersion, "kind", kind, "selector", selector)
|
|
dsList, err = common.FindDownstream(c.client, apiVersion, kind, selector)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(dsList.Items) == 0 {
|
|
delete(selector, common.GenerateTriggerUIDLabel)
|
|
selector[common.GenerateTriggerNameLabel] = ur.Spec.GetResource().GetName()
|
|
c.log.V(4).Info("fetching downstream resource by the name", "APIVersion", rule.Generation.GetAPIVersion(), "kind", rule.Generation.GetKind(), "selector", selector)
|
|
dsList, err = common.FindDownstream(c.client, rule.Generation.GetAPIVersion(), rule.Generation.GetKind(), selector)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
}
|
|
return dsList, nil
|
|
}
|