mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 02:18:15 +00:00
fix: delete downstream for a generate rule removal, with data and sync (#6393)
* remove policy handler for updates Signed-off-by: ShutingZhao <shuting@nirmata.com> * remove policy update handler from the ur controller Signed-off-by: ShutingZhao <shuting@nirmata.com> * rework cleanup downstream on policy deletion Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix downstream deletion on data rule removal Signed-off-by: ShutingZhao <shuting@nirmata.com> * add kuttl test for clusterpolicy Signed-off-by: ShutingZhao <shuting@nirmata.com> * linter fix Signed-off-by: ShutingZhao <shuting@nirmata.com> * add kuttl test for policy Signed-off-by: ShutingZhao <shuting@nirmata.com> * update api docs Signed-off-by: ShutingZhao <shuting@nirmata.com> * add delays Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix name assertion Signed-off-by: ShutingZhao <shuting@nirmata.com> * delete downstream when deletes the clone source Signed-off-by: ShutingZhao <shuting@nirmata.com> * add kuttl test pol-clone-sync-delete-source Signed-off-by: ShutingZhao <shuting@nirmata.com> * linter fixes Signed-off-by: ShutingZhao <shuting@nirmata.com> * add kuttl test pol-clone-sync-delete-downstream Signed-off-by: ShutingZhao <shuting@nirmata.com> * add kuttl test pol-data-sync-modify-rule Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix panic Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix panic Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix labels Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix policy assertions Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix annotation missing names Signed-off-by: ShutingZhao <shuting@nirmata.com> * rename policy Signed-off-by: ShutingZhao <shuting@nirmata.com> * remove dead code Signed-off-by: ShutingZhao <shuting@nirmata.com> * create unique namespaces Signed-off-by: ShutingZhao <shuting@nirmata.com> * create more unique namespaces Signed-off-by: ShutingZhao <shuting@nirmata.com> * fix assertion Signed-off-by: ShutingZhao <shuting@nirmata.com> --------- Signed-off-by: ShutingZhao <shuting@nirmata.com> Co-authored-by: Charles-Edouard Brétéché <charled.breteche@gmail.com>
This commit is contained in:
parent
8299e03279
commit
0c91e87bbb
106 changed files with 980 additions and 385 deletions
|
@ -568,6 +568,20 @@ func (g *Generation) SetData(in apiextensions.JSON) {
|
|||
g.RawData = ToJSON(in)
|
||||
}
|
||||
|
||||
type GenerateType string
|
||||
|
||||
const (
|
||||
Data GenerateType = "Data"
|
||||
Clone GenerateType = "Clone"
|
||||
)
|
||||
|
||||
func (g *Generation) GetTypeAndSync() (GenerateType, bool) {
|
||||
if g.RawData != nil {
|
||||
return Data, g.Synchronize
|
||||
}
|
||||
return Clone, g.Synchronize
|
||||
}
|
||||
|
||||
// CloneFrom provides the location of the source resource used to generate target resources.
|
||||
// The resource kind is derived from the match criteria.
|
||||
type CloneFrom struct {
|
||||
|
|
|
@ -150,18 +150,11 @@ func (r *Rule) IsPodSecurity() bool {
|
|||
return r.Validation.PodSecurity != nil
|
||||
}
|
||||
|
||||
// IsCloneSyncGenerate checks if the generate rule has the clone block with sync=true
|
||||
func (r *Rule) GetCloneSyncForGenerate() (clone bool, sync bool) {
|
||||
func (r *Rule) GetGenerateTypeAndSync() (_ GenerateType, sync bool) {
|
||||
if !r.HasGenerate() {
|
||||
return
|
||||
}
|
||||
|
||||
if r.Generation.Clone.Name != "" {
|
||||
clone = true
|
||||
}
|
||||
|
||||
sync = r.Generation.Synchronize
|
||||
return
|
||||
return r.Generation.GetTypeAndSync()
|
||||
}
|
||||
|
||||
func (r *Rule) GetAnyAllConditions() apiextensions.JSON {
|
||||
|
|
|
@ -1530,6 +1530,10 @@ Kubernetes apiextensions/v1.JSON
|
|||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<h3 id="kyverno.io/v1.GenerateType">GenerateType
|
||||
(<code>string</code> alias)</p></h3>
|
||||
<p>
|
||||
</p>
|
||||
<h3 id="kyverno.io/v1.Generation">Generation
|
||||
</h3>
|
||||
<p>
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/logging"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/client-go/util/retry"
|
||||
)
|
||||
|
||||
|
@ -72,3 +73,12 @@ func PolicyKey(namespace, name string) string {
|
|||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func ResourceSpecFromUnstructured(obj unstructured.Unstructured) kyvernov1.ResourceSpec {
|
||||
return kyvernov1.ResourceSpec{
|
||||
APIVersion: obj.GetAPIVersion(),
|
||||
Kind: obj.GetKind(),
|
||||
Namespace: obj.GetNamespace(),
|
||||
Name: obj.GetName(),
|
||||
}
|
||||
}
|
||||
|
|
83
pkg/background/generate/cleanup.go
Normal file
83
pkg/background/generate/cleanup.go
Normal file
|
@ -0,0 +1,83 @@
|
|||
package generate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
"github.com/kyverno/kyverno/pkg/background/common"
|
||||
"go.uber.org/multierr"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
// handle clone source deletion
|
||||
return c.deleteDownstreamForClone(policy, ur)
|
||||
}
|
||||
|
||||
func (c *GenerateController) deleteDownstreamForClone(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
|
||||
}
|
||||
|
||||
downstreams, err := FindDownstream(c.client, policy, rule)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var errs []error
|
||||
failedDownstreams := []kyvernov1.ResourceSpec{}
|
||||
for _, downstream := range downstreams.Items {
|
||||
if err := c.client.DeleteResource(context.TODO(), downstream.GetAPIVersion(), downstream.GetKind(), downstream.GetNamespace(), downstream.GetName(), false); err != nil && !apierrors.IsNotFound(err) {
|
||||
failedDownstreams = append(failedDownstreams, common.ResourceSpecFromUnstructured(downstream))
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if len(errs) != 0 {
|
||||
c.log.Error(multierr.Combine(errs...), "failed to clean up downstream resources on source deletion")
|
||||
_, 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)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -151,20 +151,16 @@ func (c *GenerateController) applyGenerate(resource unstructured.Unstructured, u
|
|||
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 {
|
||||
if err := c.cleanupClonedResource(e); err != nil {
|
||||
logger.Error(err, "failed to clean up cloned resource on policy deletion")
|
||||
}
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
logger.Error(err, "error in fetching policy")
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if ur.Spec.DeleteDownstream || apierrors.IsNotFound(err) {
|
||||
err = c.deleteDownstream(policy, &ur)
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
policyContext, precreatedResource, err := common.NewBackgroundContext(c.client, &ur, policy, &resource, c.configuration, namespaceLabels, logger)
|
||||
if err != nil {
|
||||
return nil, precreatedResource, err
|
||||
|
@ -209,31 +205,6 @@ 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 kyvernov1.ResourceSpec) error {
|
||||
target, err := c.client.GetResource(context.TODO(), 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[LabelSynchronize] == "enable"
|
||||
clone := labels[LabelClonePolicyName] != ""
|
||||
|
||||
if syncEnabled && !clone {
|
||||
if err := c.client.DeleteResource(context.TODO(), 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 kyvernov1beta1.UpdateRequest) (kyvernov1.PolicyInterface, error) {
|
||||
pNamespace, pName, err := cache.SplitMetaNamespaceKey(ur.Spec.Policy)
|
||||
|
@ -320,12 +291,6 @@ func (c *GenerateController) ApplyGeneratePolicy(log logr.Logger, policyContext
|
|||
return nil, processExisting, err
|
||||
}
|
||||
|
||||
if ur.Spec.DeleteDownstream {
|
||||
pKey := common.PolicyKey(policy.GetNamespace(), policy.GetName())
|
||||
err = c.deleteResource(pKey, rule, ur)
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if policy.GetSpec().IsGenerateExistingOnPolicyUpdate() || !processExisting {
|
||||
genResource, err = applyRule(log, c.client, rule, resource, jsonContext, policy, ur)
|
||||
if err != nil {
|
||||
|
@ -818,15 +783,3 @@ func (c *GenerateController) GetUnstrResource(genResourceSpec kyvernov1.Resource
|
|||
}
|
||||
return resource, nil
|
||||
}
|
||||
|
||||
func (c *GenerateController) deleteResource(policyKey string, rule kyvernov1.Rule, ur kyvernov1beta1.UpdateRequest) error {
|
||||
if policyKey != ur.Spec.Policy {
|
||||
return nil
|
||||
}
|
||||
|
||||
if rule.Name == ur.Spec.Rule {
|
||||
return c.client.DeleteResource(context.TODO(), rule.Generation.GetAPIVersion(), rule.Generation.GetKind(), rule.Generation.GetNamespace(), rule.Generation.GetName(), false)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
package generate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
"github.com/kyverno/kyverno/pkg/background/common"
|
||||
"github.com/kyverno/kyverno/pkg/clients/dclient"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
func increaseRetryAnnotation(ur *kyvernov1beta1.UpdateRequest) (int, map[string]string, error) {
|
||||
urAnnotations := ur.Annotations
|
||||
if len(urAnnotations) == 0 {
|
||||
urAnnotations = map[string]string{
|
||||
urAnnotations[kyvernov1beta1.URGenerateRetryCountAnnotation]: "1",
|
||||
kyvernov1beta1.URGenerateRetryCountAnnotation: "1",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,3 +47,14 @@ func TriggerFromLabels(labels map[string]string) kyvernov1.ResourceSpec {
|
|||
APIVersion: labels[common.GenerateTriggerAPIVersionLabel],
|
||||
}
|
||||
}
|
||||
|
||||
func FindDownstream(client dclient.Interface, policy kyvernov1.PolicyInterface, rule kyvernov1.Rule) (*unstructured.UnstructuredList, error) {
|
||||
generation := rule.Generation
|
||||
selector := &metav1.LabelSelector{MatchLabels: map[string]string{
|
||||
common.GeneratePolicyLabel: policy.GetName(),
|
||||
common.GeneratePolicyNamespaceLabel: policy.GetNamespace(),
|
||||
common.GenerateRuleLabel: rule.Name,
|
||||
}}
|
||||
|
||||
return client.ListResource(context.TODO(), generation.GetAPIVersion(), generation.GetKind(), "", selector)
|
||||
}
|
||||
|
|
21
pkg/background/mutate.go
Normal file
21
pkg/background/mutate.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package background
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
common "github.com/kyverno/kyverno/pkg/background/common"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func (c *controller) handleMutatePolicyAbsence(ur *kyvernov1beta1.UpdateRequest) error {
|
||||
selector := &metav1.LabelSelector{
|
||||
MatchLabels: common.MutateLabelsSet(ur.Spec.Policy, nil),
|
||||
}
|
||||
return c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).DeleteCollection(
|
||||
context.TODO(),
|
||||
metav1.DeleteOptions{},
|
||||
metav1.ListOptions{LabelSelector: metav1.FormatLabelSelector(selector)},
|
||||
)
|
||||
}
|
|
@ -3,7 +3,6 @@ package background
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
|
@ -20,10 +19,8 @@ import (
|
|||
"github.com/kyverno/kyverno/pkg/config"
|
||||
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
||||
"github.com/kyverno/kyverno/pkg/event"
|
||||
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
corev1informers "k8s.io/client-go/informers/core/v1"
|
||||
|
@ -96,14 +93,6 @@ func NewController(
|
|||
UpdateFunc: c.updateUR,
|
||||
DeleteFunc: c.deleteUR,
|
||||
})
|
||||
_, _ = cpolInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
UpdateFunc: c.updatePolicy,
|
||||
DeleteFunc: c.deletePolicy,
|
||||
})
|
||||
_, _ = polInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
UpdateFunc: c.updatePolicy,
|
||||
DeleteFunc: c.deletePolicy,
|
||||
})
|
||||
|
||||
c.informersSynced = []cache.InformerSynced{cpolInformer.Informer().HasSynced, polInformer.Informer().HasSynced, urInformer.Informer().HasSynced, namespaceInformer.Informer().HasSynced}
|
||||
|
||||
|
@ -186,33 +175,12 @@ func (c *controller) syncUpdateRequest(key string) error {
|
|||
|
||||
// Deep-copy otherwise we are mutating our cache.
|
||||
ur = ur.DeepCopy()
|
||||
if _, err := c.getPolicy(ur.Spec.Policy); err != nil && apierrors.IsNotFound(err) {
|
||||
if ur.Spec.GetRequestType() == kyvernov1beta1.Mutate {
|
||||
return c.handleMutatePolicyAbsence(ur)
|
||||
}
|
||||
}
|
||||
|
||||
// if not in any state, try to set it to pending
|
||||
if ur.Status.State == "" {
|
||||
ur.Status.State = kyvernov1beta1.Pending
|
||||
_, err := c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).UpdateStatus(context.TODO(), ur, metav1.UpdateOptions{})
|
||||
return err
|
||||
}
|
||||
// try to get the linked policy
|
||||
if _, err := c.getPolicy(ur.Spec.Policy); err != nil {
|
||||
if apierrors.IsNotFound(err) && ur.Spec.GetRequestType() == kyvernov1beta1.Mutate {
|
||||
// here only takes care of mutateExisting policies
|
||||
// generate cleanup controller handles policy deletion
|
||||
selector := &metav1.LabelSelector{
|
||||
MatchLabels: common.MutateLabelsSet(ur.Spec.Policy, nil),
|
||||
}
|
||||
return c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).DeleteCollection(
|
||||
context.TODO(),
|
||||
metav1.DeleteOptions{},
|
||||
metav1.ListOptions{LabelSelector: metav1.FormatLabelSelector(selector)},
|
||||
)
|
||||
}
|
||||
// check if cleanup is required in case policy is no longer exists
|
||||
if err := c.checkIfCleanupRequired(ur); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// process pending URs
|
||||
if ur.Status.State == kyvernov1beta1.Pending {
|
||||
if err := c.processUR(ur); err != nil {
|
||||
return fmt.Errorf("failed to process UR %s: %v", key, err)
|
||||
|
@ -223,59 +191,6 @@ func (c *controller) syncUpdateRequest(key string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (c *controller) checkIfCleanupRequired(ur *kyvernov1beta1.UpdateRequest) error {
|
||||
var err error
|
||||
pNamespace, pName, err := cache.SplitMetaNamespaceKey(ur.Spec.Policy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if pNamespace == "" {
|
||||
_, err = c.cpolLister.Get(pName)
|
||||
} else {
|
||||
_, err = c.polLister.Policies(pNamespace).Get(pName)
|
||||
}
|
||||
if err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.V(4).Info("policy no longer exists, deleting the update request and respective resource based on synchronize", "ur", ur.Name, "policy", ur.Spec.Policy)
|
||||
for _, e := range ur.Status.GeneratedResources {
|
||||
if err := c.cleanupDataResource(e); err != nil {
|
||||
logger.Error(err, "failed to clean up data resource on policy deletion")
|
||||
}
|
||||
}
|
||||
return c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Delete(context.TODO(), ur.Name, metav1.DeleteOptions{})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// cleanupDataResource deletes resource if sync is enabled for data policy
|
||||
func (c *controller) cleanupDataResource(targetSpec kyvernov1.ResourceSpec) error {
|
||||
target, err := c.client.GetResource(context.TODO(), 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[generate.LabelSynchronize] == "enable"
|
||||
clone := labels[generate.LabelClonePolicyName] != ""
|
||||
|
||||
if syncEnabled && !clone {
|
||||
if err := c.client.DeleteResource(context.TODO(), target.GetAPIVersion(), target.GetKind(), target.GetNamespace(), target.GetName(), false); err != nil {
|
||||
return fmt.Errorf("failed to delete data resource %s/%s: %v", targetSpec.Namespace, targetSpec.Name, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *controller) enqueueUpdateRequest(obj interface{}) {
|
||||
key, err := cache.MetaNamespaceKeyFunc(obj)
|
||||
if err != nil {
|
||||
|
@ -286,74 +201,6 @@ func (c *controller) enqueueUpdateRequest(obj interface{}) {
|
|||
c.queue.Add(key)
|
||||
}
|
||||
|
||||
func (c *controller) updatePolicy(_, obj interface{}) {
|
||||
key, err := cache.MetaNamespaceKeyFunc(obj)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to compute policy key")
|
||||
} else {
|
||||
logger.V(4).Info("updating policy", "key", key)
|
||||
urs, err := c.urLister.GetUpdateRequestsForClusterPolicy(key)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to list update requests for policy", "key", key)
|
||||
return
|
||||
}
|
||||
// re-evaluate the UR as the policy was updated
|
||||
for _, ur := range urs {
|
||||
c.enqueueUpdateRequest(ur)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) deletePolicy(obj interface{}) {
|
||||
var p kyvernov1.PolicyInterface
|
||||
|
||||
switch kubeutils.GetObjectWithTombstone(obj).(type) {
|
||||
case *kyvernov1.ClusterPolicy:
|
||||
p = kubeutils.GetObjectWithTombstone(obj).(*kyvernov1.ClusterPolicy)
|
||||
case *kyvernov1.Policy:
|
||||
p = kubeutils.GetObjectWithTombstone(obj).(*kyvernov1.Policy)
|
||||
default:
|
||||
logger.Info("Failed to get deleted object", "obj", obj)
|
||||
return
|
||||
}
|
||||
|
||||
logger.V(4).Info("deleting policy", "name", p.GetName())
|
||||
key, err := cache.MetaNamespaceKeyFunc(kubeutils.GetObjectWithTombstone(obj))
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to compute policy key")
|
||||
} else {
|
||||
logger.V(4).Info("updating policy", "key", key)
|
||||
|
||||
// check if deleted policy is clone generate policy
|
||||
generatePolicyWithClone := c.processDeletePolicyForCloneGenerateRule(p, p.GetName())
|
||||
|
||||
// get the generated resource name from update request
|
||||
selector := labels.SelectorFromSet(labels.Set(map[string]string{
|
||||
kyvernov1beta1.URGeneratePolicyLabel: p.GetName(),
|
||||
}))
|
||||
|
||||
urList, err := c.urLister.List(selector)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to get update request for the resource", "label", kyvernov1beta1.URGeneratePolicyLabel)
|
||||
return
|
||||
}
|
||||
|
||||
if !generatePolicyWithClone {
|
||||
// re-evaluate the UR as the policy was updated
|
||||
for _, ur := range urList {
|
||||
logger.V(4).Info("enqueue the ur for cleanup", "ur name", ur.Name)
|
||||
c.enqueueUpdateRequest(ur)
|
||||
}
|
||||
} else {
|
||||
for _, ur := range urList {
|
||||
for _, generatedResource := range ur.Status.GeneratedResources {
|
||||
logger.V(4).Info("retaining resource for cloned policy", "apiVersion", generatedResource.APIVersion, "kind", generatedResource.Kind, "name", generatedResource.Name, "namespace", generatedResource.Namespace)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) addUR(obj interface{}) {
|
||||
ur := obj.(*kyvernov1beta1.UpdateRequest)
|
||||
c.enqueueUpdateRequest(ur)
|
||||
|
@ -399,7 +246,7 @@ func (c *controller) processUR(ur *kyvernov1beta1.UpdateRequest) error {
|
|||
}
|
||||
|
||||
func (c *controller) cleanUR(ur *kyvernov1beta1.UpdateRequest) error {
|
||||
if ur.Spec.GetRequestType() == kyvernov1beta1.Mutate && ur.Status.State == kyvernov1beta1.Completed {
|
||||
if ur.Status.State == kyvernov1beta1.Completed {
|
||||
return c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Delete(context.TODO(), ur.GetName(), metav1.DeleteOptions{})
|
||||
}
|
||||
return nil
|
||||
|
@ -415,67 +262,3 @@ func (c *controller) getPolicy(key string) (kyvernov1.PolicyInterface, error) {
|
|||
}
|
||||
return c.polLister.Policies(namespace).Get(name)
|
||||
}
|
||||
|
||||
func (c *controller) processDeletePolicyForCloneGenerateRule(policy kyvernov1.PolicyInterface, pName string) bool {
|
||||
generatePolicyWithClone := false
|
||||
for _, rule := range policy.GetSpec().Rules {
|
||||
clone, sync := rule.GetCloneSyncForGenerate()
|
||||
if !(clone && sync) {
|
||||
continue
|
||||
}
|
||||
logger.V(4).Info("generate policy with clone, remove policy name from label of source resource")
|
||||
generatePolicyWithClone = true
|
||||
var retryCount int
|
||||
for retryCount < 5 {
|
||||
err := c.updateSourceResource(policy.GetName(), rule)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to update generate source resource labels")
|
||||
if apierrors.IsConflict(err) {
|
||||
retryCount++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return generatePolicyWithClone
|
||||
}
|
||||
|
||||
func (c *controller) updateSourceResource(pName string, rule kyvernov1.Rule) error {
|
||||
obj, err := c.client.GetResource(context.TODO(), "", rule.Generation.Kind, rule.Generation.Clone.Namespace, rule.Generation.Clone.Name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("source resource %s/%s/%s not found: %w", rule.Generation.Kind, rule.Generation.Clone.Namespace, rule.Generation.Clone.Name, err)
|
||||
}
|
||||
|
||||
var update bool
|
||||
labels := obj.GetLabels()
|
||||
update, labels = removePolicyFromLabels(pName, labels)
|
||||
if !update {
|
||||
return nil
|
||||
}
|
||||
|
||||
obj.SetLabels(labels)
|
||||
_, err = c.client.UpdateResource(context.TODO(), obj.GetAPIVersion(), rule.Generation.Kind, rule.Generation.Clone.Namespace, obj, false)
|
||||
return err
|
||||
}
|
||||
|
||||
func removePolicyFromLabels(pName string, labels map[string]string) (bool, map[string]string) {
|
||||
if len(labels) == 0 {
|
||||
return false, labels
|
||||
}
|
||||
if labels[generate.LabelClonePolicyName] != "" {
|
||||
policyNames := labels[generate.LabelClonePolicyName]
|
||||
if strings.Contains(policyNames, pName) {
|
||||
desiredLabels := make(map[string]string, len(labels)-1)
|
||||
for k, v := range labels {
|
||||
if k != generate.LabelClonePolicyName {
|
||||
desiredLabels[k] = v
|
||||
}
|
||||
}
|
||||
return true, desiredLabels
|
||||
}
|
||||
}
|
||||
return false, labels
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
"github.com/kyverno/kyverno/pkg/autogen"
|
||||
"github.com/kyverno/kyverno/pkg/background/common"
|
||||
generateutils "github.com/kyverno/kyverno/pkg/background/generate"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
|
@ -24,7 +25,7 @@ func (pc *PolicyController) handleGenerate(policyKey string, policy kyvernov1.Po
|
|||
updateUR(pc.kyvernoClient, pc.urLister.UpdateRequests(config.KyvernoNamespace()), policyKey, generateURs, pc.log.WithName("updateUR"))
|
||||
|
||||
for _, rule := range policy.GetSpec().Rules {
|
||||
if err := pc.createUR(policy, rule); err != nil {
|
||||
if err := pc.createUR(policy, rule, false); err != nil {
|
||||
logger.Error(err, "failed to create UR on policy event")
|
||||
}
|
||||
|
||||
|
@ -39,7 +40,7 @@ func (pc *PolicyController) handleGenerate(policyKey string, policy kyvernov1.Po
|
|||
continue
|
||||
}
|
||||
|
||||
ur := newUR(policy, resourceSpecFromUnstructured(trigger), ruleType)
|
||||
ur := newUR(policy, common.ResourceSpecFromUnstructured(*trigger), rule.Name, ruleType, false)
|
||||
skip, err := pc.handleUpdateRequest(ur, trigger, rule, policy)
|
||||
if err != nil {
|
||||
pc.log.Error(err, "failed to create new UR on policy update", "policy", policy.GetName(), "rule", rule.Name, "rule type", ruleType,
|
||||
|
@ -70,32 +71,81 @@ func (pc *PolicyController) listGenerateURs(policyKey string, trigger *unstructu
|
|||
return generateURs
|
||||
}
|
||||
|
||||
func (pc *PolicyController) createUR(policy kyvernov1.PolicyInterface, rule kyvernov1.Rule) error {
|
||||
func (pc *PolicyController) createURForDownstreamDeletion(policy kyvernov1.PolicyInterface) error {
|
||||
var errs []error
|
||||
rules := autogen.ComputeRules(policy)
|
||||
for _, r := range rules {
|
||||
generateType, sync := r.GetGenerateTypeAndSync()
|
||||
if sync && (generateType == kyvernov1.Data) {
|
||||
if err := pc.createUR(policy, r, true); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return multierr.Combine(errs...)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) createUR(policy kyvernov1.PolicyInterface, rule kyvernov1.Rule, deleteDownstream bool) error {
|
||||
generate := rule.Generation
|
||||
if !generate.Synchronize {
|
||||
// no action for non-sync policy/rule
|
||||
return nil
|
||||
}
|
||||
|
||||
var errorList []error
|
||||
if generate.GetData() != nil {
|
||||
downstream, err := pc.client.GetResource(context.TODO(), generate.APIVersion, generate.Kind, generate.Namespace, generate.Name)
|
||||
downstreams, err := generateutils.FindDownstream(pc.client, policy, rule)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
labels := downstream.GetLabels()
|
||||
trigger := generateutils.TriggerFromLabels(labels)
|
||||
ur := newUR(policy, trigger, kyvernov1beta1.Generate)
|
||||
created, err := pc.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(context.TODO(), ur, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updated := created.DeepCopy()
|
||||
updated.Status.State = kyvernov1beta1.Pending
|
||||
_, err = pc.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).UpdateStatus(context.TODO(), updated, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
for _, downstream := range downstreams.Items {
|
||||
labels := downstream.GetLabels()
|
||||
trigger := generateutils.TriggerFromLabels(labels)
|
||||
ur := newUR(policy, trigger, rule.Name, kyvernov1beta1.Generate, deleteDownstream)
|
||||
created, err := pc.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(context.TODO(), ur, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
errorList = append(errorList, err)
|
||||
continue
|
||||
}
|
||||
updated := created.DeepCopy()
|
||||
updated.Status = newURStatus(downstream)
|
||||
_, err = pc.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).UpdateStatus(context.TODO(), updated, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
errorList = append(errorList, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return multierr.Combine(errorList...)
|
||||
}
|
||||
|
||||
// ruleDeletion returns true if any rule is deleted, along with deleted rules
|
||||
func ruleDeletion(old, new kyvernov1.PolicyInterface) (_ kyvernov1.PolicyInterface, ruleDeleted bool) {
|
||||
if !new.GetDeletionTimestamp().IsZero() {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
newRules := new.GetSpec().Rules
|
||||
oldRules := old.GetSpec().Rules
|
||||
newRulesMap := make(map[string]bool, len(newRules))
|
||||
var deletedRules []kyvernov1.Rule
|
||||
|
||||
for _, r := range newRules {
|
||||
newRulesMap[r.Name] = true
|
||||
}
|
||||
for _, r := range oldRules {
|
||||
if exist := newRulesMap[r.Name]; !exist {
|
||||
deletedRules = append(deletedRules, r)
|
||||
ruleDeleted = true
|
||||
}
|
||||
}
|
||||
|
||||
return buildPolicyWithDeletedRules(old, deletedRules), ruleDeleted
|
||||
}
|
||||
|
||||
func buildPolicyWithDeletedRules(policy kyvernov1.PolicyInterface, deletedRules []kyvernov1.Rule) kyvernov1.PolicyInterface {
|
||||
newPolicy := policy.CreateDeepCopy()
|
||||
spec := newPolicy.GetSpec()
|
||||
spec.SetRules(deletedRules)
|
||||
return newPolicy
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ func (pc *PolicyController) handleMutate(policyKey string, policy kyvernov1.Poli
|
|||
}
|
||||
|
||||
logger.Info("creating new UR for mutate")
|
||||
ur := newUR(policy, resourceSpecFromUnstructured(trigger), ruleType)
|
||||
ur := newUR(policy, backgroundcommon.ResourceSpecFromUnstructured(*trigger), rule.Name, ruleType, false)
|
||||
skip, err := pc.handleUpdateRequest(ur, trigger, rule, policy)
|
||||
if err != nil {
|
||||
pc.log.Error(err, "failed to create new UR on policy update", "policy", policy.GetName(), "rule", rule.Name, "rule type", ruleType,
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/go-logr/logr"
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1"
|
||||
"github.com/kyverno/kyverno/pkg/autogen"
|
||||
backgroundcommon "github.com/kyverno/kyverno/pkg/background/common"
|
||||
"github.com/kyverno/kyverno/pkg/client/clientset/versioned"
|
||||
"github.com/kyverno/kyverno/pkg/client/clientset/versioned/scheme"
|
||||
|
@ -211,6 +210,12 @@ func (pc *PolicyController) updatePolicy(old, cur interface{}) {
|
|||
}
|
||||
|
||||
logger.V(2).Info("updating policy", "name", oldP.GetName())
|
||||
if deleted, ok := ruleDeletion(oldP, curP); ok {
|
||||
err := pc.createURForDownstreamDeletion(deleted)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("failed to create UR on rule deletion, clean up downstream resource may be failed: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
pc.enqueuePolicy(curP)
|
||||
}
|
||||
|
@ -230,16 +235,10 @@ func (pc *PolicyController) deletePolicy(obj interface{}) {
|
|||
}
|
||||
|
||||
logger.Info("policy deleted", "uid", p.GetUID(), "kind", p.GetKind(), "namespace", p.GetNamespace(), "name", p.GetName())
|
||||
|
||||
// do not clean up UR on generate clone (sync=true) policy deletion
|
||||
rules := autogen.ComputeRules(p)
|
||||
for _, r := range rules {
|
||||
clone, sync := r.GetCloneSyncForGenerate()
|
||||
if clone && sync {
|
||||
return
|
||||
}
|
||||
err := pc.createURForDownstreamDeletion(p)
|
||||
if err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("failed to create UR on policy deletion, clean up downstream resource may be failed: %v", err))
|
||||
}
|
||||
pc.enqueuePolicy(p)
|
||||
}
|
||||
|
||||
func (pc *PolicyController) enqueuePolicy(policy kyvernov1.PolicyInterface) {
|
||||
|
@ -425,7 +424,13 @@ func (pc *PolicyController) handleUpdateRequest(ur *kyvernov1beta1.UpdateRequest
|
|||
}
|
||||
|
||||
pc.log.V(2).Info("creating new UR for generate")
|
||||
_, err := pc.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(context.TODO(), ur, metav1.CreateOptions{})
|
||||
created, err := pc.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(context.TODO(), ur, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
updated := created.DeepCopy()
|
||||
updated.Status.State = kyvernov1beta1.Pending
|
||||
_, err = pc.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).UpdateStatus(context.TODO(), updated, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -474,12 +479,3 @@ func updateUR(kyvernoClient versioned.Interface, urLister kyvernov1beta1listers.
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func resourceSpecFromUnstructured(obj *unstructured.Unstructured) kyvernov1.ResourceSpec {
|
||||
return kyvernov1.ResourceSpec{
|
||||
APIVersion: obj.GetAPIVersion(),
|
||||
Kind: obj.GetKind(),
|
||||
Namespace: obj.GetNamespace(),
|
||||
Name: obj.GetName(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,11 @@ import (
|
|||
common "github.com/kyverno/kyverno/pkg/background/common"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
func newUR(policy kyvernov1.PolicyInterface, trigger kyvernov1.ResourceSpec, ruleType kyvernov1beta1.RequestType) *kyvernov1beta1.UpdateRequest {
|
||||
func newUR(policy kyvernov1.PolicyInterface, trigger kyvernov1.ResourceSpec, ruleName string, ruleType kyvernov1beta1.RequestType, deleteDownstream bool) *kyvernov1beta1.UpdateRequest {
|
||||
var policyNameNamespaceKey string
|
||||
|
||||
if policy.IsNamespaced() {
|
||||
|
@ -26,6 +27,10 @@ func newUR(policy kyvernov1.PolicyInterface, trigger kyvernov1.ResourceSpec, rul
|
|||
}
|
||||
|
||||
return &kyvernov1beta1.UpdateRequest{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: kyvernov1beta1.SchemeGroupVersion.String(),
|
||||
Kind: "UpdateRequest",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "ur-",
|
||||
Namespace: config.KyvernoNamespace(),
|
||||
|
@ -34,12 +39,28 @@ func newUR(policy kyvernov1.PolicyInterface, trigger kyvernov1.ResourceSpec, rul
|
|||
Spec: kyvernov1beta1.UpdateRequestSpec{
|
||||
Type: ruleType,
|
||||
Policy: policyNameNamespaceKey,
|
||||
Rule: ruleName,
|
||||
Resource: kyvernov1.ResourceSpec{
|
||||
Kind: trigger.GetKind(),
|
||||
Namespace: trigger.GetNamespace(),
|
||||
Name: trigger.GetName(),
|
||||
APIVersion: trigger.GetAPIVersion(),
|
||||
},
|
||||
DeleteDownstream: deleteDownstream,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func newURStatus(downstream unstructured.Unstructured) kyvernov1beta1.UpdateRequestStatus {
|
||||
return kyvernov1beta1.UpdateRequestStatus{
|
||||
State: kyvernov1beta1.Pending,
|
||||
GeneratedResources: []kyvernov1.ResourceSpec{
|
||||
{
|
||||
APIVersion: downstream.GetAPIVersion(),
|
||||
Kind: downstream.GetKind(),
|
||||
Namespace: downstream.GetNamespace(),
|
||||
Name: downstream.GetName(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,10 +158,13 @@ func (h *generationHandler) createUR(ctx context.Context, policyContext *engine.
|
|||
return fmt.Errorf("labels have been changed, new: %v, old: %v", labels, oldLabels)
|
||||
}
|
||||
|
||||
managedBy := oldLabels[kyvernov1.LabelAppManagedBy] == kyvernov1.ValueKyvernoApp
|
||||
deleteDownstream := false
|
||||
if reflect.DeepEqual(new, unstructured.Unstructured{}) {
|
||||
deleteDownstream = true
|
||||
labels = oldLabels
|
||||
if !managedBy {
|
||||
deleteDownstream = true
|
||||
}
|
||||
}
|
||||
pName := labels[common.GeneratePolicyLabel]
|
||||
pNamespace := labels[common.GeneratePolicyNamespaceLabel]
|
||||
|
@ -187,6 +190,7 @@ func (h *generationHandler) createUR(ctx context.Context, policyContext *engine.
|
|||
Resource: generateutils.TriggerFromLabels(labels),
|
||||
}
|
||||
ur.DeleteDownstream = deleteDownstream
|
||||
|
||||
if err := h.urGenerator.Apply(ctx, ur, admissionv1.Update); err != nil {
|
||||
e := event.NewBackgroundFailedEvent(err, pKey, pRuleName, event.GeneratePolicyController, &new)
|
||||
h.eventGen.Add(e...)
|
||||
|
|
|
@ -105,12 +105,18 @@ func (g *generator) tryApplyResource(ctx context.Context, urSpec kyvernov1beta1.
|
|||
},
|
||||
Spec: urSpec,
|
||||
}
|
||||
if new, err := g.client.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(ctx, &ur, metav1.CreateOptions{}); err != nil {
|
||||
created, err := g.client.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(ctx, &ur, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
l.V(4).Error(err, "failed to create UpdateRequest, retrying", "name", ur.GetGenerateName(), "namespace", ur.GetNamespace())
|
||||
return err
|
||||
} else {
|
||||
l.V(4).Info("successfully created UpdateRequest", "name", new.GetName(), "namespace", ur.GetNamespace())
|
||||
}
|
||||
updated := created.DeepCopy()
|
||||
updated.Status.State = kyvernov1beta1.Pending
|
||||
_, err = g.client.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).UpdateStatus(context.TODO(), updated, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l.V(4).Info("successfully created UpdateRequest", "name", updated.GetName(), "namespace", ur.GetNamespace())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: bar
|
||||
name: cpol-clone-nosync-create-ns
|
|
@ -0,0 +1,5 @@
|
|||
# A command can only run a single command, not a pipeline and not a script. The program called must exist on the system where the test is run.
|
||||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
commands:
|
||||
- command: sleep 3
|
|
@ -2,4 +2,4 @@ apiVersion: v1
|
|||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: bar
|
||||
namespace: cpol-clone-nosync-create-ns
|
|
@ -1,4 +0,0 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
commands:
|
||||
- command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true
|
|
@ -2,4 +2,4 @@ apiVersion: v1
|
|||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: bar
|
||||
namespace: cpol-clone-nosync-delete-downstream-ns
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: bar
|
||||
name: cpol-clone-nosync-delete-downstream-ns
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: bar
|
||||
name: cpol-clone-nosync-delete-downstream-ns
|
|
@ -4,4 +4,4 @@ delete:
|
|||
- apiVersion: v1
|
||||
kind: Secret
|
||||
name: regcred
|
||||
namespace: bar
|
||||
namespace: cpol-clone-nosync-delete-downstream-ns
|
|
@ -3,4 +3,4 @@ apiVersion: v1
|
|||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: bar
|
||||
namespace: cpol-clone-nosync-delete-downstream-ns
|
|
@ -1,4 +0,0 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
commands:
|
||||
- command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true
|
|
@ -2,4 +2,4 @@ apiVersion: v1
|
|||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: bar
|
||||
namespace: cpol-clone-sync-create-ns
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: bar
|
||||
name: cpol-clone-sync-create-ns
|
|
@ -2,4 +2,4 @@ apiVersion: v1
|
|||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: bar
|
||||
namespace: cpol-clone-sync-delete-downstream-ns
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: bar
|
||||
name: cpol-clone-sync-delete-downstream-ns
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: bar
|
||||
name: cpol-clone-sync-delete-downstream-ns
|
|
@ -4,4 +4,4 @@ delete:
|
|||
- apiVersion: v1
|
||||
kind: Secret
|
||||
name: regcred
|
||||
namespace: bar
|
||||
namespace: cpol-clone-sync-delete-downstream-ns
|
|
@ -3,4 +3,4 @@ apiVersion: v1
|
|||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: bar
|
||||
namespace: cpol-clone-sync-delete-downstream-ns
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
labels:
|
||||
somekey: somevalue
|
||||
name: zk-kafka-address
|
||||
namespace: bar
|
||||
namespace: cpol-data-nosync-delete-downstream-ns
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: bar
|
||||
name: cpol-data-nosync-delete-downstream-ns
|
|
@ -4,4 +4,4 @@ delete:
|
|||
- apiVersion: v1
|
||||
kind: ConfigMap
|
||||
name: zk-kafka-address
|
||||
namespace: bar
|
||||
namespace: cpol-data-nosync-delete-downstream-ns
|
|
@ -2,4 +2,4 @@ apiVersion: v1
|
|||
kind: ConfigMap
|
||||
metadata:
|
||||
name: zk-kafka-address
|
||||
namespace: bar
|
||||
namespace: cpol-data-nosync-delete-downstream-ns
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
labels:
|
||||
somekey: somevalue
|
||||
name: zk-kafka-address
|
||||
namespace: bar
|
||||
namespace: cpol-data-sync-create-ns
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: bar
|
||||
name: cpol-data-sync-create-ns
|
|
@ -1,4 +0,0 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
commands:
|
||||
- command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
labels:
|
||||
somekey: somevalue
|
||||
name: zk-kafka-address
|
||||
namespace: falcon-heavy
|
||||
namespace: cpol-data-sync-delete-downstream-ns
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: falcon-heavy
|
||||
name: cpol-data-sync-delete-downstream-ns
|
|
@ -5,4 +5,4 @@ delete:
|
|||
- apiVersion: v1
|
||||
kind: ConfigMap
|
||||
name: zk-kafka-address
|
||||
namespace: falcon-heavy
|
||||
namespace: cpol-data-sync-delete-downstream-ns
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
labels:
|
||||
somekey: somevalue
|
||||
name: zk-kafka-address
|
||||
namespace: falcon-heavy
|
||||
namespace: cpol-data-sync-delete-downstream-ns
|
|
@ -1,7 +1,7 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: zk-kafka-address
|
||||
name: cpol-data-sync-delete-policy
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: zk-kafka-address
|
||||
name: cpol-data-sync-delete-policy
|
||||
spec:
|
||||
generateExistingOnPolicyUpdate: false
|
||||
rules:
|
||||
- name: k-kafka-address
|
||||
- name: cpol-data-sync-delete-rule
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
|
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
labels:
|
||||
somekey: somevalue
|
||||
name: zk-kafka-address
|
||||
namespace: bar
|
||||
namespace: cpol-data-sync-delete-policy-ns
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: bar
|
||||
name: cpol-data-sync-delete-policy-ns
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
labels:
|
||||
somekey: somevalue
|
||||
name: zk-kafka-address
|
||||
namespace: bar
|
||||
namespace: cpol-data-sync-delete-policy-ns
|
|
@ -2,4 +2,4 @@ apiVersion: v1
|
|||
kind: ConfigMap
|
||||
metadata:
|
||||
name: zk-kafka-address
|
||||
namespace: bar
|
||||
namespace: cpol-data-sync-delete-policy-ns
|
|
@ -3,4 +3,4 @@ kind: TestStep
|
|||
delete:
|
||||
- apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
name: zk-kafka-address
|
||||
name: cpol-data-sync-delete-policy
|
|
@ -1,4 +0,0 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
commands:
|
||||
- command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-ready.yaml
|
|
@ -0,0 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: cpol-data-sync-delete-rule
|
|
@ -0,0 +1,5 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
assert:
|
||||
- secret.yaml
|
||||
- configmap.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- delete-rule.yaml
|
||||
assert:
|
||||
- policy-ready.yaml
|
|
@ -0,0 +1,5 @@
|
|||
# A command can only run a single command, not a pipeline and not a script. The program called must exist on the system where the test is run.
|
||||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
commands:
|
||||
- command: sleep 3
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
assert:
|
||||
- secret.yaml
|
||||
error:
|
||||
- configmap.yaml
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This test checks to ensure that deletion of a rule in a ClusterPolicy generate rule, data declaration, with sync enabled, results in the downstream resource's deletion.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
The downstream (generated) resource is expected to be deleted if the corresponding rule within a ClusterPolicy is deleted. If it is not deleted, the test fails. If it is deleted, the test passes.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
https://github.com/kyverno/kyverno/issues/5744
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
KAFKA_ADDRESS: 192.168.10.13:9092,192.168.10.14:9092,192.168.10.15:9092
|
||||
ZK_ADDRESS: 192.168.10.10:2181,192.168.10.11:2181,192.168.10.12:2181
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
labels:
|
||||
somekey: somevalue
|
||||
name: zk-kafka-address
|
||||
namespace: cpol-data-sync-delete-rule
|
|
@ -0,0 +1,35 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: multiple-gens
|
||||
spec:
|
||||
generateExistingOnPolicyUpdate: false
|
||||
rules:
|
||||
- name: super-secret
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Namespace
|
||||
exclude:
|
||||
any:
|
||||
- resources:
|
||||
namespaces:
|
||||
- kube-system
|
||||
- default
|
||||
- kube-public
|
||||
- kyverno
|
||||
generate:
|
||||
synchronize: true
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
name: supersecret
|
||||
namespace: "{{request.object.metadata.name}}"
|
||||
data:
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
metadata:
|
||||
labels:
|
||||
somekey: somesecretvalue
|
||||
data:
|
||||
mysupersecretkey: bXlzdXBlcnNlY3JldHZhbHVl
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: multiple-gens
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,63 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: multiple-gens
|
||||
spec:
|
||||
generateExistingOnPolicyUpdate: false
|
||||
rules:
|
||||
- name: k-kafka-address
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Namespace
|
||||
exclude:
|
||||
any:
|
||||
- resources:
|
||||
namespaces:
|
||||
- kube-system
|
||||
- default
|
||||
- kube-public
|
||||
- kyverno
|
||||
generate:
|
||||
synchronize: true
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
name: zk-kafka-address
|
||||
namespace: "{{request.object.metadata.name}}"
|
||||
data:
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
labels:
|
||||
somekey: somevalue
|
||||
data:
|
||||
ZK_ADDRESS: "192.168.10.10:2181,192.168.10.11:2181,192.168.10.12:2181"
|
||||
KAFKA_ADDRESS: "192.168.10.13:9092,192.168.10.14:9092,192.168.10.15:9092"
|
||||
- name: super-secret
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Namespace
|
||||
exclude:
|
||||
any:
|
||||
- resources:
|
||||
namespaces:
|
||||
- kube-system
|
||||
- default
|
||||
- kube-public
|
||||
- kyverno
|
||||
generate:
|
||||
synchronize: true
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
name: supersecret
|
||||
namespace: "{{request.object.metadata.name}}"
|
||||
data:
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
metadata:
|
||||
labels:
|
||||
somekey: somesecretvalue
|
||||
data:
|
||||
mysupersecretkey: bXlzdXBlcnNlY3JldHZhbHVl
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
mysupersecretkey: bXlzdXBlcnNlY3JldHZhbHVl
|
||||
kind: Secret
|
||||
metadata:
|
||||
labels:
|
||||
somekey: somesecretvalue
|
||||
name: supersecret
|
||||
namespace: cpol-data-sync-delete-rule
|
||||
type: Opaque
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
labels:
|
||||
somekey: somevalue
|
||||
name: zk-kafka-address
|
||||
namespace: bar
|
||||
namespace: cpol-data-sync-modify-rule-ns
|
|
@ -1,4 +1,4 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: bar
|
||||
name: cpol-data-sync-modify-rule-ns
|
|
@ -7,4 +7,4 @@ metadata:
|
|||
labels:
|
||||
somekey: somevalue
|
||||
name: zk-kafka-address
|
||||
namespace: bar
|
||||
namespace: cpol-data-sync-modify-rule-ns
|
|
@ -1,4 +0,0 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
commands:
|
||||
- command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: pol-sync-clone-delete-downstream
|
||||
---
|
||||
apiVersion: v1
|
||||
data:
|
||||
foo: YmFy
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: pol-sync-clone-delete-downstream
|
||||
type: Opaque
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: pol-sync-clone-delete-downstream
|
||||
---
|
||||
apiVersion: v1
|
||||
data:
|
||||
foo: YmFy
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: pol-sync-clone-delete-downstream
|
||||
type: Opaque
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: kyverno.io/v2beta1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: pol-sync-clone-delete-downstream
|
||||
namespace: pol-sync-clone-delete-downstream
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: kyverno.io/v2beta1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: pol-sync-clone-delete-downstream
|
||||
namespace: pol-sync-clone-delete-downstream
|
||||
spec:
|
||||
rules:
|
||||
- name: gen-zk
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- ConfigMap
|
||||
generate:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
name: myclonedsecret
|
||||
namespace: pol-sync-clone-delete-downstream
|
||||
synchronize: true
|
||||
clone:
|
||||
namespace: pol-sync-clone-delete-downstream
|
||||
name: regcred
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
foo: bar
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: foo
|
||||
namespace: pol-sync-clone-delete-downstream
|
|
@ -0,0 +1,4 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
assert:
|
||||
- downstream.yaml
|
|
@ -0,0 +1,8 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
foo: YmFy
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: myclonedsecret
|
||||
namespace: pol-sync-clone-delete-downstream
|
||||
type: Opaque
|
|
@ -0,0 +1,4 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
commands:
|
||||
- command: sleep 3
|
|
@ -0,0 +1,4 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
assert:
|
||||
- downstream.yaml
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This test ensures that deletion of a downstream resource created by a Policy `generate` rule with sync enabled using a clone declaration causes it to be regenerated. If it is not regenerated, the test fails.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
The downstream resource, upon deletion, is expected to be recreated/recloned from the source resource.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
N/A
|
|
@ -0,0 +1,8 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
foo: YmFy
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: myclonedsecret
|
||||
namespace: pol-sync-clone-delete-downstream
|
||||
type: Opaque
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- policy.yaml
|
||||
assert:
|
||||
- policy-ready.yaml
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
- create-cm.yaml
|
||||
assert:
|
||||
- cloned-secret.yaml
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
delete:
|
||||
- apiVersion: v1
|
||||
kind: Secret
|
||||
name: regcred
|
||||
namespace: pol-clone-sync-delete-source
|
|
@ -0,0 +1,4 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
commands:
|
||||
- command: sleep 5
|
|
@ -0,0 +1,8 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
foo: YmFy
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: newsecret
|
||||
namespace: pol-clone-sync-delete-source
|
||||
type: Opaque
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This test ensures that deletion of the source (upstream) resource used by a Policy `generate` rule with sync enabled using a clone declaration DOES cause deletion of downstream/cloned resources.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
After the source is deleted, the downstream resources should be deleted. If the downstream resource remains, the test fails. If the downstream resource is deleted, the test passes.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
N/A
|
|
@ -0,0 +1,8 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
foo: YmFy
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: newsecret
|
||||
namespace: pol-clone-sync-delete-source
|
||||
type: Opaque
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: mycm
|
||||
namespace: pol-clone-sync-delete-source
|
||||
data:
|
||||
food: cheese
|
||||
day: monday
|
||||
color: red
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: kyverno.io/v2beta1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: pol-clone-sync-delete-source
|
||||
namespace: pol-clone-sync-delete-source
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,36 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: pol-clone-sync-delete-source
|
||||
---
|
||||
apiVersion: v1
|
||||
data:
|
||||
foo: YmFy
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: regcred
|
||||
namespace: pol-clone-sync-delete-source
|
||||
type: Opaque
|
||||
---
|
||||
apiVersion: kyverno.io/v2beta1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: pol-clone-sync-delete-source
|
||||
namespace: pol-clone-sync-delete-source
|
||||
spec:
|
||||
rules:
|
||||
- name: pol-clone-sync-delete-source-secret
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- ConfigMap
|
||||
generate:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
name: newsecret
|
||||
namespace: pol-clone-sync-delete-source
|
||||
synchronize: true
|
||||
clone:
|
||||
namespace: pol-clone-sync-delete-source
|
||||
name: regcred
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: multiple-gens
|
||||
namespace: pol-data-sync-delete-rule
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,57 @@
|
|||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: pol-data-sync-delete-rule
|
||||
---
|
||||
apiVersion: kyverno.io/v1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: multiple-gens
|
||||
namespace: pol-data-sync-delete-rule
|
||||
spec:
|
||||
generateExistingOnPolicyUpdate: false
|
||||
rules:
|
||||
- name: k-kafka-address
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Secret
|
||||
names:
|
||||
- trigger-secret
|
||||
generate:
|
||||
synchronize: true
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
name: zk-kafka-address
|
||||
namespace: pol-data-sync-delete-rule
|
||||
data:
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
labels:
|
||||
somekey: somevalue
|
||||
data:
|
||||
ZK_ADDRESS: "192.168.10.10:2181,192.168.10.11:2181,192.168.10.12:2181"
|
||||
KAFKA_ADDRESS: "192.168.10.13:9092,192.168.10.14:9092,192.168.10.15:9092"
|
||||
- name: super-secret
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Secret
|
||||
names:
|
||||
- trigger-secret
|
||||
generate:
|
||||
synchronize: true
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
name: supersecret
|
||||
namespace: pol-data-sync-delete-rule
|
||||
data:
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
metadata:
|
||||
labels:
|
||||
somekey: somesecretvalue
|
||||
data:
|
||||
mysupersecretkey: bXlzdXBlcnNlY3JldHZhbHVl
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
foo: YmFy
|
||||
kind: Secret
|
||||
metadata:
|
||||
labels:
|
||||
org: kyverno
|
||||
name: trigger-secret
|
||||
namespace: pol-data-sync-delete-rule
|
||||
type: Opaque
|
|
@ -0,0 +1,5 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
assert:
|
||||
- secret.yaml
|
||||
- configmap.yaml
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: multiple-gens
|
||||
namespace: pol-data-sync-delete-rule
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
|
@ -0,0 +1,30 @@
|
|||
apiVersion: kyverno.io/v1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: multiple-gens
|
||||
namespace: pol-data-sync-delete-rule
|
||||
spec:
|
||||
generateExistingOnPolicyUpdate: false
|
||||
rules:
|
||||
- name: super-secret
|
||||
match:
|
||||
any:
|
||||
- resources:
|
||||
kinds:
|
||||
- Secret
|
||||
names:
|
||||
- trigger-secret
|
||||
generate:
|
||||
synchronize: true
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
name: supersecret
|
||||
namespace: pol-data-sync-delete-rule
|
||||
data:
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
metadata:
|
||||
labels:
|
||||
somekey: somesecretvalue
|
||||
data:
|
||||
mysupersecretkey: bXlzdXBlcnNlY3JldHZhbHVl
|
|
@ -0,0 +1,5 @@
|
|||
# A command can only run a single command, not a pipeline and not a script. The program called must exist on the system where the test is run.
|
||||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
commands:
|
||||
- command: sleep 3
|
|
@ -0,0 +1,7 @@
|
|||
apiVersion: kuttl.dev/v1beta1
|
||||
kind: TestStep
|
||||
apply:
|
||||
assert:
|
||||
- secret.yaml
|
||||
error:
|
||||
- configmap.yaml
|
|
@ -0,0 +1,11 @@
|
|||
## Description
|
||||
|
||||
This test checks to ensure that deletion of a rule in a Policy (Namespaced) generate rule, data declaration, with sync enabled, results in the downstream resource's deletion.
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
The downstream (generated) resource is expected to be deleted if the corresponding rule within a Policy is deleted. If it is not deleted, the test fails. If it is deleted, the test passes.
|
||||
|
||||
## Reference Issue(s)
|
||||
|
||||
https://github.com/kyverno/kyverno/issues/5744
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
KAFKA_ADDRESS: 192.168.10.13:9092,192.168.10.14:9092,192.168.10.15:9092
|
||||
ZK_ADDRESS: 192.168.10.10:2181,192.168.10.11:2181,192.168.10.12:2181
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
labels:
|
||||
somekey: somevalue
|
||||
name: zk-kafka-address
|
||||
namespace: pol-data-sync-delete-rule
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
mysupersecretkey: bXlzdXBlcnNlY3JldHZhbHVl
|
||||
kind: Secret
|
||||
metadata:
|
||||
labels:
|
||||
somekey: somesecretvalue
|
||||
name: supersecret
|
||||
namespace: pol-data-sync-delete-rule
|
||||
type: Opaque
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: kyverno.io/v2beta1
|
||||
kind: Policy
|
||||
metadata:
|
||||
name: zk-kafka-address
|
||||
namespace: pol-data-sync-modify-rule
|
||||
status:
|
||||
conditions:
|
||||
- reason: Succeeded
|
||||
status: "True"
|
||||
type: Ready
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue