diff --git a/api/kyverno/v2alpha1/global_context_entry_types.go b/api/kyverno/v2alpha1/global_context_entry_types.go index 2273a8c955..f25ed08b9a 100644 --- a/api/kyverno/v2alpha1/global_context_entry_types.go +++ b/api/kyverno/v2alpha1/global_context_entry_types.go @@ -28,6 +28,8 @@ import ( // +kubebuilder:object:root=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +kubebuilder:resource:shortName=gctxentry,categories=kyverno,scope="Cluster" +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type == "Ready")].status` // GlobalContextEntry declares resources to be cached. type GlobalContextEntry struct { diff --git a/charts/kyverno/charts/crds/templates/kyverno.io/kyverno.io_globalcontextentries.yaml b/charts/kyverno/charts/crds/templates/kyverno.io/kyverno.io_globalcontextentries.yaml index 7c6fb2e581..fed7a39165 100644 --- a/charts/kyverno/charts/crds/templates/kyverno.io/kyverno.io_globalcontextentries.yaml +++ b/charts/kyverno/charts/crds/templates/kyverno.io/kyverno.io_globalcontextentries.yaml @@ -24,7 +24,11 @@ spec: singular: globalcontextentry scope: Cluster versions: - - name: v2alpha1 + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type == "Ready")].status + name: READY + type: string + name: v2alpha1 schema: openAPIV3Schema: description: GlobalContextEntry declares resources to be cached. @@ -199,4 +203,6 @@ spec: type: object served: true storage: true + subresources: + status: {} {{- end }} diff --git a/charts/kyverno/templates/admission-controller/clusterrole.yaml b/charts/kyverno/templates/admission-controller/clusterrole.yaml index 4b5e5b6855..4ea7088614 100644 --- a/charts/kyverno/templates/admission-controller/clusterrole.yaml +++ b/charts/kyverno/templates/admission-controller/clusterrole.yaml @@ -60,6 +60,8 @@ rules: - clusterpolicies/status - updaterequests - updaterequests/status + - globalcontextentries + - globalcontextentries/status - admissionreports - clusteradmissionreports - backgroundscanreports @@ -74,13 +76,6 @@ rules: - update - watch - deletecollection - - apiGroups: - - kyverno.io - resources: - - globalcontextentries - verbs: - - list - - watch - apiGroups: - reports.kyverno.io resources: diff --git a/charts/kyverno/templates/admission-controller/flowschema.yaml b/charts/kyverno/templates/admission-controller/flowschema.yaml index ecad34df23..8bb6f52311 100644 --- a/charts/kyverno/templates/admission-controller/flowschema.yaml +++ b/charts/kyverno/templates/admission-controller/flowschema.yaml @@ -50,6 +50,8 @@ spec: resources: - clusterpolicies - clusterpolicies/status + - globalcontextentries + - globalcontextentries/status - clusteradmissionreports - clusterbackgroundscanreports verbs: diff --git a/charts/kyverno/templates/background-controller/clusterrole.yaml b/charts/kyverno/templates/background-controller/clusterrole.yaml index 47400d4c12..2c47558136 100644 --- a/charts/kyverno/templates/background-controller/clusterrole.yaml +++ b/charts/kyverno/templates/background-controller/clusterrole.yaml @@ -32,6 +32,8 @@ rules: - policyexceptions - updaterequests - updaterequests/status + - globalcontextentries + - globalcontextentries/status verbs: - create - delete @@ -41,13 +43,6 @@ rules: - update - watch - deletecollection - - apiGroups: - - kyverno.io - resources: - - globalcontextentries - verbs: - - list - - watch - apiGroups: - '' resources: diff --git a/charts/kyverno/templates/cleanup-controller/clusterrole.yaml b/charts/kyverno/templates/cleanup-controller/clusterrole.yaml index 42b1404694..4584dba1c5 100644 --- a/charts/kyverno/templates/cleanup-controller/clusterrole.yaml +++ b/charts/kyverno/templates/cleanup-controller/clusterrole.yaml @@ -55,9 +55,16 @@ rules: - kyverno.io resources: - globalcontextentries + - globalcontextentries/status verbs: + - create + - delete + - get - list + - patch + - update - watch + - deletecollection - apiGroups: - kyverno.io resources: diff --git a/charts/kyverno/templates/reports-controller/clusterrole.yaml b/charts/kyverno/templates/reports-controller/clusterrole.yaml index 3ddb7465e3..45bccb9c2c 100644 --- a/charts/kyverno/templates/reports-controller/clusterrole.yaml +++ b/charts/kyverno/templates/reports-controller/clusterrole.yaml @@ -38,12 +38,7 @@ rules: - kyverno.io resources: - globalcontextentries - verbs: - - list - - watch - - apiGroups: - - kyverno.io - resources: + - globalcontextentries/status - admissionreports - clusteradmissionreports - backgroundscanreports diff --git a/cmd/background-controller/main.go b/cmd/background-controller/main.go index 0ae6e2884b..276c68ec58 100644 --- a/cmd/background-controller/main.go +++ b/cmd/background-controller/main.go @@ -160,8 +160,11 @@ func main() { globalcontextcontroller.NewController( kyvernoInformer.Kyverno().V2alpha1().GlobalContextEntries(), setup.KyvernoDynamicClient, + setup.KyvernoClient, gcstore, + eventGenerator, maxAPICallResponseLength, + false, ), globalcontextcontroller.Workers, ) // this controller only subscribe to events, nothing is returned... diff --git a/cmd/cleanup-controller/main.go b/cmd/cleanup-controller/main.go index 25c86bdb56..05a0b05df1 100644 --- a/cmd/cleanup-controller/main.go +++ b/cmd/cleanup-controller/main.go @@ -166,8 +166,11 @@ func main() { globalcontextcontroller.NewController( kyvernoInformer.Kyverno().V2alpha1().GlobalContextEntries(), setup.KyvernoDynamicClient, + setup.KyvernoClient, gcstore, + eventGenerator, maxAPICallResponseLength, + false, ), globalcontextcontroller.Workers, ) @@ -305,6 +308,7 @@ func main() { cmResolver, setup.Jp, eventGenerator, + gcstore, ), cleanup.Workers, ) diff --git a/cmd/kyverno/main.go b/cmd/kyverno/main.go index 9db068e30f..24f6c94ac9 100644 --- a/cmd/kyverno/main.go +++ b/cmd/kyverno/main.go @@ -362,8 +362,11 @@ func main() { globalcontextcontroller.NewController( kyvernoInformer.Kyverno().V2alpha1().GlobalContextEntries(), setup.KyvernoDynamicClient, + setup.KyvernoClient, gcstore, + eventGenerator, maxAPICallResponseLength, + true, ), globalcontextcontroller.Workers, ) @@ -508,7 +511,7 @@ func main() { ) policyHandlers := webhookspolicy.NewHandlers( setup.KyvernoDynamicClient, - kyvernoInformer.Kyverno().V2alpha1().GlobalContextEntries(), + setup.KyvernoClient, backgroundServiceAccountName, ) resourceHandlers := webhooksresource.NewHandlers( diff --git a/cmd/reports-controller/main.go b/cmd/reports-controller/main.go index c7725c0159..ddfddac2cd 100644 --- a/cmd/reports-controller/main.go +++ b/cmd/reports-controller/main.go @@ -278,8 +278,11 @@ func main() { globalcontextcontroller.NewController( kyvernoInformer.Kyverno().V2alpha1().GlobalContextEntries(), setup.KyvernoDynamicClient, + setup.KyvernoClient, gcstore, + eventGenerator, maxAPICallResponseLength, + false, ), globalcontextcontroller.Workers, ) diff --git a/config/crds/kyverno/kyverno.io_globalcontextentries.yaml b/config/crds/kyverno/kyverno.io_globalcontextentries.yaml index bff7086a7f..7f9b73bad1 100644 --- a/config/crds/kyverno/kyverno.io_globalcontextentries.yaml +++ b/config/crds/kyverno/kyverno.io_globalcontextentries.yaml @@ -18,7 +18,11 @@ spec: singular: globalcontextentry scope: Cluster versions: - - name: v2alpha1 + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type == "Ready")].status + name: READY + type: string + name: v2alpha1 schema: openAPIV3Schema: description: GlobalContextEntry declares resources to be cached. @@ -193,3 +197,5 @@ spec: type: object served: true storage: true + subresources: + status: {} diff --git a/config/install-latest-testing.yaml b/config/install-latest-testing.yaml index 0972faf938..1669dde384 100644 --- a/config/install-latest-testing.yaml +++ b/config/install-latest-testing.yaml @@ -28569,7 +28569,11 @@ spec: singular: globalcontextentry scope: Cluster versions: - - name: v2alpha1 + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type == "Ready")].status + name: READY + type: string + name: v2alpha1 schema: openAPIV3Schema: description: GlobalContextEntry declares resources to be cached. @@ -28744,6 +28748,8 @@ spec: type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -51279,6 +51285,8 @@ rules: - clusterpolicies/status - updaterequests - updaterequests/status + - globalcontextentries + - globalcontextentries/status - admissionreports - clusteradmissionreports - backgroundscanreports @@ -51293,13 +51301,6 @@ rules: - update - watch - deletecollection - - apiGroups: - - kyverno.io - resources: - - globalcontextentries - verbs: - - list - - watch - apiGroups: - reports.kyverno.io resources: @@ -51414,6 +51415,8 @@ rules: - policyexceptions - updaterequests - updaterequests/status + - globalcontextentries + - globalcontextentries/status verbs: - create - delete @@ -51423,13 +51426,6 @@ rules: - update - watch - deletecollection - - apiGroups: - - kyverno.io - resources: - - globalcontextentries - verbs: - - list - - watch - apiGroups: - '' resources: @@ -51556,9 +51552,16 @@ rules: - kyverno.io resources: - globalcontextentries + - globalcontextentries/status verbs: + - create + - delete + - get - list + - patch + - update - watch + - deletecollection - apiGroups: - kyverno.io resources: @@ -51867,12 +51870,7 @@ rules: - kyverno.io resources: - globalcontextentries - verbs: - - list - - watch - - apiGroups: - - kyverno.io - resources: + - globalcontextentries/status - admissionreports - clusteradmissionreports - backgroundscanreports diff --git a/pkg/controllers/cleanup/controller.go b/pkg/controllers/cleanup/controller.go index 94d97a1f36..0d916bdb1f 100644 --- a/pkg/controllers/cleanup/controller.go +++ b/pkg/controllers/cleanup/controller.go @@ -17,6 +17,7 @@ import ( "github.com/kyverno/kyverno/pkg/controllers" engineapi "github.com/kyverno/kyverno/pkg/engine/api" enginecontext "github.com/kyverno/kyverno/pkg/engine/context" + "github.com/kyverno/kyverno/pkg/engine/context/loaders" "github.com/kyverno/kyverno/pkg/engine/factories" "github.com/kyverno/kyverno/pkg/engine/jmespath" "github.com/kyverno/kyverno/pkg/event" @@ -57,6 +58,7 @@ type controller struct { eventGen event.Interface jp jmespath.Interface metrics cleanupMetrics + gctxStore loaders.Store } type cleanupMetrics struct { @@ -80,6 +82,7 @@ func NewController( cmResolver engineapi.ConfigmapResolver, jp jmespath.Interface, eventGen event.Interface, + gctxStore loaders.Store, ) controllers.Controller { queue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), ControllerName) keyFunc := controllerutils.MetaNamespaceKeyT[kyvernov2alpha1.CleanupPolicyInterface] @@ -112,6 +115,7 @@ func NewController( eventGen: eventGen, metrics: newCleanupMetrics(logger), jp: jp, + gctxStore: gctxStore, } if _, err := controllerutils.AddEventHandlersT( cpolInformer.Informer(), @@ -181,7 +185,7 @@ func (c *controller) cleanup(ctx context.Context, logger logr.Logger, policy kyv var errs []error enginectx := enginecontext.NewContext(c.jp) - ctxFactory := factories.DefaultContextLoaderFactory(c.cmResolver) + ctxFactory := factories.DefaultContextLoaderFactory(c.cmResolver, factories.WithGlobalContextStore(c.gctxStore)) loader := ctxFactory(nil, kyvernov1.Rule{}) if err := loader.Load( diff --git a/pkg/controllers/globalcontext/controller.go b/pkg/controllers/globalcontext/controller.go index a06b2613b4..e8939af7ac 100644 --- a/pkg/controllers/globalcontext/controller.go +++ b/pkg/controllers/globalcontext/controller.go @@ -6,17 +6,21 @@ import ( "github.com/go-logr/logr" kyvernov2alpha1 "github.com/kyverno/kyverno/api/kyverno/v2alpha1" + "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov2alpha1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v2alpha1" kyvernov2alpha1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v2alpha1" "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/controllers" "github.com/kyverno/kyverno/pkg/engine/adapters" + "github.com/kyverno/kyverno/pkg/event" "github.com/kyverno/kyverno/pkg/globalcontext/externalapi" "github.com/kyverno/kyverno/pkg/globalcontext/k8sresource" "github.com/kyverno/kyverno/pkg/globalcontext/store" controllerutils "github.com/kyverno/kyverno/pkg/utils/controller" + datautils "github.com/kyverno/kyverno/pkg/utils/data" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" ) @@ -35,29 +39,66 @@ type controller struct { queue workqueue.RateLimitingInterface // state - dclient dclient.Interface - store store.Store - maxResponseLength int64 + dclient dclient.Interface + kyvernoClient versioned.Interface + store store.Store + eventGen event.Interface + maxResponseLength int64 + shouldUpdateStatus bool } func NewController( gceInformer kyvernov2alpha1informers.GlobalContextEntryInformer, dclient dclient.Interface, + kyvernoClient versioned.Interface, storage store.Store, + eventGen event.Interface, maxResponseLength int64, + shouldUpdateStatus bool, ) controllers.Controller { queue := workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), ControllerName) - _, _, err := controllerutils.AddDefaultEventHandlers(logger, gceInformer.Informer(), queue) - if err != nil { + c := &controller{ + gceLister: gceInformer.Lister(), + queue: queue, + dclient: dclient, + kyvernoClient: kyvernoClient, + store: storage, + eventGen: eventGen, + maxResponseLength: maxResponseLength, + shouldUpdateStatus: shouldUpdateStatus, + } + + if _, err := controllerutils.AddEventHandlersT(gceInformer.Informer(), c.addGTXEntry, c.updateGTXEntry, c.deleteGTXEntry); err != nil { logger.Error(err, "failed to register event handlers") } - return &controller{ - gceLister: gceInformer.Lister(), - queue: queue, - dclient: dclient, - store: storage, - maxResponseLength: maxResponseLength, + + return c +} + +func (c *controller) addGTXEntry(obj *kyvernov2alpha1.GlobalContextEntry) { + logger.Info("globalcontextentry created", "uid", obj.GetUID(), "kind", obj.Kind, "name", obj.GetName()) + c.enqueueGCTXEntry(obj) +} + +func (c *controller) updateGTXEntry(old, obj *kyvernov2alpha1.GlobalContextEntry) { + if datautils.DeepEqual(old.Spec, obj.Spec) { + return } + logger.Info("globalcontextentry updated", "uid", obj.GetUID(), "kind", obj.Kind, "name", obj.GetName()) + c.enqueueGCTXEntry(obj) +} + +func (c *controller) deleteGTXEntry(obj *kyvernov2alpha1.GlobalContextEntry) { + c.enqueueGCTXEntry(obj) +} + +func (c *controller) enqueueGCTXEntry(gctxentry *kyvernov2alpha1.GlobalContextEntry) { + key, err := cache.MetaNamespaceKeyFunc(gctxentry) + if err != nil { + logger.Error(err, "failed to enqueue global context entry") + return + } + c.queue.Add(key) } func (c *controller) Run(ctx context.Context, workers int) { @@ -95,14 +136,29 @@ func (c *controller) makeStoreEntry(ctx context.Context, gce *kyvernov2alpha1.Gl Version: gce.Spec.KubernetesResource.Version, Resource: gce.Spec.KubernetesResource.Resource, } - return k8sresource.New(ctx, c.dclient.GetDynamicInterface(), gvr, gce.Spec.KubernetesResource.Namespace) + return k8sresource.New( + ctx, + gce, + c.eventGen, + c.dclient.GetDynamicInterface(), + c.kyvernoClient, + logger, + gvr, + gce.Spec.KubernetesResource.Namespace, + c.shouldUpdateStatus, + ) } return externalapi.New( ctx, + gce, + c.eventGen, + c.kyvernoClient, + c.gceLister, logger, adapters.Client(c.dclient), gce.Spec.APICall.APICall, gce.Spec.APICall.RefreshInterval.Duration, c.maxResponseLength, + c.shouldUpdateStatus, ) } diff --git a/pkg/controllers/webhook/controller.go b/pkg/controllers/webhook/controller.go index d55f175386..5959a0604a 100644 --- a/pkg/controllers/webhook/controller.go +++ b/pkg/controllers/webhook/controller.go @@ -426,7 +426,7 @@ func (c *controller) reconcileMutatingWebhookConfiguration(ctx context.Context, func (c *controller) isGlobalContextEntryReady(name string, gctxentries []*kyvernov2alpha1.GlobalContextEntry) bool { for _, gctxentry := range gctxentries { if gctxentry.Name == name { - return true + return gctxentry.Status.IsReady() } } return false diff --git a/pkg/event/controller.go b/pkg/event/controller.go index 83c131c3c4..0570c305df 100644 --- a/pkg/event/controller.go +++ b/pkg/event/controller.go @@ -135,7 +135,9 @@ func (gen *controller) processNextWorkItem(ctx context.Context) bool { func (gen *controller) emitEvent(key Info) { logger := gen.logger eventType := corev1.EventTypeWarning - if key.Reason == PolicyApplied || key.Reason == PolicySkipped { + if key.Type != "" { + eventType = key.Type + } else if key.Reason == PolicyApplied || key.Reason == PolicySkipped { eventType = corev1.EventTypeNormal } diff --git a/pkg/event/info.go b/pkg/event/info.go index d3d054414e..9c5455d49d 100644 --- a/pkg/event/info.go +++ b/pkg/event/info.go @@ -14,6 +14,7 @@ type Info struct { Message string Action Action Source Source + Type string } func (i *Info) Resource() string { diff --git a/pkg/globalcontext/event/event.go b/pkg/globalcontext/event/event.go new file mode 100644 index 0000000000..1fd384642c --- /dev/null +++ b/pkg/globalcontext/event/event.go @@ -0,0 +1,22 @@ +package event + +import ( + "github.com/kyverno/kyverno/pkg/event" + corev1 "k8s.io/api/core/v1" +) + +const ( + source = "globalcontext-controller" + action = "Retrying" +) + +func NewErrorEvent(regarding corev1.ObjectReference, reason event.Reason, err error) event.Info { + return event.Info{ + Regarding: regarding, + Source: source, + Reason: reason, + Message: err.Error(), + Action: action, + Type: corev1.EventTypeWarning, + } +} diff --git a/pkg/globalcontext/event/reason.go b/pkg/globalcontext/event/reason.go new file mode 100644 index 0000000000..879d8e8757 --- /dev/null +++ b/pkg/globalcontext/event/reason.go @@ -0,0 +1,7 @@ +package event + +const ( + ReasonResourceListFailure = "FailedToList" + ReasonAPICallFailure = "FailedToCallAPI" + ReasonCacheSyncFailure = "FailedToWaitForCacheSync" +) diff --git a/pkg/globalcontext/externalapi/entry.go b/pkg/globalcontext/externalapi/entry.go index 2db5d91179..c8962a3fa2 100644 --- a/pkg/globalcontext/externalapi/entry.go +++ b/pkg/globalcontext/externalapi/entry.go @@ -8,8 +8,18 @@ import ( "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" + kyvernov2alpha1 "github.com/kyverno/kyverno/api/kyverno/v2alpha1" + "github.com/kyverno/kyverno/pkg/client/clientset/versioned" + kyvernov2alpha1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v2alpha1" "github.com/kyverno/kyverno/pkg/engine/apicall" + "github.com/kyverno/kyverno/pkg/event" + entryevent "github.com/kyverno/kyverno/pkg/globalcontext/event" + "github.com/kyverno/kyverno/pkg/globalcontext/store" + controllerutils "github.com/kyverno/kyverno/pkg/utils/controller" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/util/retry" ) type entry struct { @@ -21,12 +31,17 @@ type entry struct { func New( ctx context.Context, + gce *kyvernov2alpha1.GlobalContextEntry, + eventGen event.Interface, + kyvernoClient versioned.Interface, + gceLister kyvernov2alpha1listers.GlobalContextEntryLister, logger logr.Logger, client apicall.ClientInterface, call kyvernov1.APICall, period time.Duration, maxResponseLength int64, -) (*entry, error) { + shouldUpdateStatus bool, +) (store.Entry, error) { var group wait.Group ctx, cancel := context.WithCancel(ctx) stop := func() { @@ -38,19 +53,42 @@ func New( e := &entry{ stop: stop, } + group.StartWithContext(ctx, func(ctx context.Context) { - // TODO: make sure we have called it at least once before returning config := apicall.NewAPICallConfiguration(maxResponseLength) caller := apicall.NewCaller(logger, "globalcontext", client, config) + wait.UntilWithContext(ctx, func(ctx context.Context) { if data, err := doCall(ctx, caller, call); err != nil { - logger.Error(err, "failed to get data from api caller") e.setData(nil, err) + + logger.Error(err, "failed to get data from api caller") + + eventGen.Add(entryevent.NewErrorEvent(corev1.ObjectReference{ + APIVersion: gce.APIVersion, + Kind: gce.Kind, + Name: gce.Name, + Namespace: gce.Namespace, + UID: gce.UID, + }, entryevent.ReasonAPICallFailure, err)) + + if shouldUpdateStatus { + if updateErr := updateStatus(ctx, gce.Name, kyvernoClient, false, entryevent.ReasonAPICallFailure); updateErr != nil { + logger.Error(updateErr, "failed to update status") + } + } } else { e.setData(data, nil) + + if shouldUpdateStatus { + if updateErr := updateStatus(ctx, gce.Name, kyvernoClient, true, "APICallSuccess"); updateErr != nil { + logger.Error(updateErr, "failed to update status") + } + } } }, period) }) + return e, nil } @@ -89,3 +127,24 @@ func (e *entry) setData(data any, err error) { func doCall(ctx context.Context, caller apicall.Caller, call kyvernov1.APICall) (any, error) { return caller.Execute(ctx, &call) } + +func updateStatus(ctx context.Context, gceName string, kyvernoClient versioned.Interface, ready bool, reason string) error { + retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { + latestGCE, getErr := kyvernoClient.KyvernoV2alpha1().GlobalContextEntries().Get(ctx, gceName, metav1.GetOptions{}) + if getErr != nil { + return getErr + } + + _, updateErr := controllerutils.UpdateStatus(ctx, latestGCE, kyvernoClient.KyvernoV2alpha1().GlobalContextEntries(), func(latest *kyvernov2alpha1.GlobalContextEntry) error { + if latest == nil { + return fmt.Errorf("failed to update status: %s", latestGCE.Name) + } + latest.Status.SetReady(ready, reason) + return nil + }) + + return updateErr + }) + + return retryErr +} diff --git a/pkg/globalcontext/k8sresource/entry.go b/pkg/globalcontext/k8sresource/entry.go index 9de39b6fca..b5fa3afd22 100644 --- a/pkg/globalcontext/k8sresource/entry.go +++ b/pkg/globalcontext/k8sresource/entry.go @@ -4,6 +4,15 @@ import ( "context" "fmt" + "github.com/go-logr/logr" + kyvernov2alpha1 "github.com/kyverno/kyverno/api/kyverno/v2alpha1" + "github.com/kyverno/kyverno/pkg/client/clientset/versioned" + "github.com/kyverno/kyverno/pkg/event" + entryevent "github.com/kyverno/kyverno/pkg/globalcontext/event" + "github.com/kyverno/kyverno/pkg/globalcontext/invalid" + "github.com/kyverno/kyverno/pkg/globalcontext/store" + controllerutils "github.com/kyverno/kyverno/pkg/utils/controller" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime/schema" @@ -14,11 +23,24 @@ import ( ) type entry struct { - lister cache.GenericLister - stop func() + lister cache.GenericLister + stop func() + gce *kyvernov2alpha1.GlobalContextEntry + eventGen event.Interface } -func New(ctx context.Context, client dynamic.Interface, gvr schema.GroupVersionResource, namespace string) (*entry, error) { +// TODO: Handle Kyverno Pod Ready State +func New( + ctx context.Context, + gce *kyvernov2alpha1.GlobalContextEntry, + eventGen event.Interface, + client dynamic.Interface, + kyvernoClient versioned.Interface, + logger logr.Logger, + gvr schema.GroupVersionResource, + namespace string, + shouldUpdateStatus bool, +) (store.Entry, error) { indexers := cache.Indexers{ cache.NamespaceIndex: cache.MetaNamespaceIndexFunc, } @@ -39,17 +61,48 @@ func New(ctx context.Context, client dynamic.Interface, gvr schema.GroupVersionR }) if !cache.WaitForCacheSync(ctx.Done(), informer.Informer().HasSynced) { stop() - return nil, fmt.Errorf("failed to wait for cache sync: %s", gvr.Resource) + + if shouldUpdateStatus { + if err := updateStatus(ctx, gce, kyvernoClient, false, "CacheSyncFailure"); err != nil { + logger.Error(err, "failed to update status") + } + } + + err := fmt.Errorf("failed to sync cache for %s", gvr) + eventGen.Add(entryevent.NewErrorEvent(corev1.ObjectReference{ + APIVersion: gce.APIVersion, + Kind: gce.Kind, + Name: gce.Name, + Namespace: gce.Namespace, + UID: gce.UID, + }, entryevent.ReasonCacheSyncFailure, err)) + + return invalid.New(err), nil } + + if shouldUpdateStatus { + if err := updateStatus(ctx, gce, kyvernoClient, true, "CacheSyncSuccess"); err != nil { + logger.Error(err, "failed to update status") + } + } + return &entry{ - lister: informer.Lister(), - stop: stop, + lister: informer.Lister(), + stop: stop, + eventGen: eventGen, }, nil } func (e *entry) Get() (any, error) { obj, err := e.lister.List(labels.Everything()) if err != nil { + e.eventGen.Add(entryevent.NewErrorEvent(corev1.ObjectReference{ + APIVersion: e.gce.APIVersion, + Kind: e.gce.Kind, + Name: e.gce.Name, + Namespace: e.gce.Namespace, + UID: e.gce.UID, + }, entryevent.ReasonResourceListFailure, err)) return nil, err } return obj, nil @@ -58,3 +111,14 @@ func (e *entry) Get() (any, error) { func (e *entry) Stop() { e.stop() } + +func updateStatus(ctx context.Context, gce *kyvernov2alpha1.GlobalContextEntry, kyvernoClient versioned.Interface, ready bool, reason string) error { + _, err := controllerutils.UpdateStatus(ctx, gce, kyvernoClient.KyvernoV2alpha1().GlobalContextEntries(), func(latest *kyvernov2alpha1.GlobalContextEntry) error { + if latest == nil { + return fmt.Errorf("failed to update status: %s", gce.Name) + } + latest.Status.SetReady(ready, reason) + return nil + }) + return err +} diff --git a/pkg/validation/policy/validate.go b/pkg/validation/policy/validate.go index be08f8ca94..6e21f5c93a 100644 --- a/pkg/validation/policy/validate.go +++ b/pkg/validation/policy/validate.go @@ -1,6 +1,7 @@ package policy import ( + "context" "encoding/json" "errors" "fmt" @@ -19,7 +20,7 @@ import ( kyvernov2alpha1 "github.com/kyverno/kyverno/api/kyverno/v2alpha1" "github.com/kyverno/kyverno/ext/wildcard" "github.com/kyverno/kyverno/pkg/autogen" - kyvernov2alpha1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v2alpha1" + "github.com/kyverno/kyverno/pkg/client/clientset/versioned" "github.com/kyverno/kyverno/pkg/clients/dclient" enginecontext "github.com/kyverno/kyverno/pkg/engine/context" "github.com/kyverno/kyverno/pkg/engine/variables" @@ -33,7 +34,6 @@ import ( admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/yaml" @@ -128,7 +128,7 @@ func checkValidationFailureAction(spec *kyvernov1.Spec) []string { } // Validate checks the policy and rules declarations for required configurations -func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interface, gctxentryLister kyvernov2alpha1listers.GlobalContextEntryLister, mock bool, username string) ([]string, error) { +func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interface, kyvernoClient versioned.Interface, mock bool, username string) ([]string, error) { var warnings []string spec := policy.GetSpec() background := spec.BackgroundProcessingEnabled() @@ -404,8 +404,8 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf } // global context entry validation - if gctxentryLister != nil { - gctxentries, err := gctxentryLister.List(labels.Everything()) + if kyvernoClient != nil { + gctxentries, err := kyvernoClient.KyvernoV2alpha1().GlobalContextEntries().List(context.Background(), metav1.ListOptions{}) if err != nil { return nil, err } @@ -416,7 +416,7 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf for _, ctxEntry := range rule.Context { if ctxEntry.GlobalReference != nil { if !isGlobalContextEntryReady(ctxEntry.GlobalReference.Name, gctxentries) { - return nil, fmt.Errorf("global context entry %s is not ready", ctxEntry.Name) + return nil, fmt.Errorf("global context entry %s is not ready", ctxEntry.GlobalReference.Name) } } } @@ -473,10 +473,10 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf return warnings, nil } -func isGlobalContextEntryReady(name string, gctxentries []*kyvernov2alpha1.GlobalContextEntry) bool { - for _, gctxentry := range gctxentries { +func isGlobalContextEntryReady(name string, gctxentries *kyvernov2alpha1.GlobalContextEntryList) bool { + for _, gctxentry := range gctxentries.Items { if gctxentry.Name == name { - return true + return gctxentry.Status.IsReady() } } return false diff --git a/pkg/webhooks/policy/handlers.go b/pkg/webhooks/policy/handlers.go index f4a67f9700..5dc2d0652b 100644 --- a/pkg/webhooks/policy/handlers.go +++ b/pkg/webhooks/policy/handlers.go @@ -5,8 +5,7 @@ import ( "time" "github.com/go-logr/logr" - kyvernov2alpha1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v2alpha1" - kyvernov2alpha1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v2alpha1" + "github.com/kyverno/kyverno/pkg/client/clientset/versioned" "github.com/kyverno/kyverno/pkg/clients/dclient" admissionutils "github.com/kyverno/kyverno/pkg/utils/admission" policyvalidate "github.com/kyverno/kyverno/pkg/validation/policy" @@ -16,14 +15,14 @@ import ( type policyHandlers struct { client dclient.Interface - gctxentryLister kyvernov2alpha1listers.GlobalContextEntryLister + kyvernoClient versioned.Interface backgroundServiceAccountName string } -func NewHandlers(client dclient.Interface, gctxentryInformer kyvernov2alpha1informers.GlobalContextEntryInformer, serviceaccount string) webhooks.PolicyHandlers { +func NewHandlers(client dclient.Interface, kyvernoClient versioned.Interface, serviceaccount string) webhooks.PolicyHandlers { return &policyHandlers{ client: client, - gctxentryLister: gctxentryInformer.Lister(), + kyvernoClient: kyvernoClient, backgroundServiceAccountName: serviceaccount, } } @@ -34,7 +33,7 @@ func (h *policyHandlers) Validate(ctx context.Context, logger logr.Logger, reque logger.Error(err, "failed to unmarshal policies from admission request") return admissionutils.Response(request.UID, err) } - warnings, err := policyvalidate.Validate(policy, oldPolicy, h.client, h.gctxentryLister, false, h.backgroundServiceAccountName) + warnings, err := policyvalidate.Validate(policy, oldPolicy, h.client, h.kyvernoClient, false, h.backgroundServiceAccountName) if err != nil { logger.Error(err, "policy validation errors") } diff --git a/test/conformance/chainsaw/globalcontext/apicall-correct/chainsaw-test.yaml b/test/conformance/chainsaw/globalcontext/apicall-correct/chainsaw-test.yaml index 4c74ff5137..b077033504 100755 --- a/test/conformance/chainsaw/globalcontext/apicall-correct/chainsaw-test.yaml +++ b/test/conformance/chainsaw/globalcontext/apicall-correct/chainsaw-test.yaml @@ -2,7 +2,7 @@ apiVersion: chainsaw.kyverno.io/v1alpha1 kind: Test metadata: creationTimestamp: null - name: resource-correct + name: apicall-correct spec: steps: - name: scenario @@ -13,11 +13,13 @@ spec: file: main-deployment.yaml - apply: file: gctxentry.yaml + - sleep: + duration: 15s - apply: file: clusterpolicy.yaml + - assert: + file: clusterpolicy-ready.yaml - apply: file: new-deployment.yaml - - assert: - file: clusterpolicy-succeeded.yaml - assert: file: new-deployment-exists.yaml diff --git a/test/conformance/chainsaw/globalcontext/apicall-correct/clusterpolicy-succeeded.yaml b/test/conformance/chainsaw/globalcontext/apicall-correct/clusterpolicy-ready.yaml similarity index 79% rename from test/conformance/chainsaw/globalcontext/apicall-correct/clusterpolicy-succeeded.yaml rename to test/conformance/chainsaw/globalcontext/apicall-correct/clusterpolicy-ready.yaml index 47b54ce1f2..d456c1b81c 100755 --- a/test/conformance/chainsaw/globalcontext/apicall-correct/clusterpolicy-succeeded.yaml +++ b/test/conformance/chainsaw/globalcontext/apicall-correct/clusterpolicy-ready.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: namespace-has-coordinator + name: cpol-apicall-correct status: conditions: - reason: Succeeded diff --git a/test/conformance/chainsaw/globalcontext/apicall-correct/clusterpolicy.yaml b/test/conformance/chainsaw/globalcontext/apicall-correct/clusterpolicy.yaml index 1c459b0a16..31c1c8adf2 100755 --- a/test/conformance/chainsaw/globalcontext/apicall-correct/clusterpolicy.yaml +++ b/test/conformance/chainsaw/globalcontext/apicall-correct/clusterpolicy.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: namespace-has-coordinator + name: cpol-apicall-correct spec: validationFailureAction: Enforce failurePolicy: Fail @@ -10,7 +10,7 @@ spec: context: - name: deploymentCount globalReference: - name: deployments + name: gctxentry-apicall-correct jmesPath: "items | length(@)" match: all: diff --git a/test/conformance/chainsaw/globalcontext/apicall-correct/gctxentry.yaml b/test/conformance/chainsaw/globalcontext/apicall-correct/gctxentry.yaml index 46d1da9f8f..4cd652dfbf 100755 --- a/test/conformance/chainsaw/globalcontext/apicall-correct/gctxentry.yaml +++ b/test/conformance/chainsaw/globalcontext/apicall-correct/gctxentry.yaml @@ -1,8 +1,8 @@ apiVersion: kyverno.io/v2alpha1 kind: GlobalContextEntry metadata: - name: deployments + name: gctxentry-apicall-correct spec: apiCall: - urlPath: "/apis/apps/v1/namespaces/test-globalcontext/deployments" - refreshInterval: 10s + urlPath: "/apis/apps/v1/namespaces/test-globalcontext-apicall-correct/deployments" + refreshInterval: 1h diff --git a/test/conformance/chainsaw/globalcontext/apicall-correct/main-deployment.yaml b/test/conformance/chainsaw/globalcontext/apicall-correct/main-deployment.yaml index bd269e4252..09fac90b00 100755 --- a/test/conformance/chainsaw/globalcontext/apicall-correct/main-deployment.yaml +++ b/test/conformance/chainsaw/globalcontext/apicall-correct/main-deployment.yaml @@ -2,7 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: main-deployment - namespace: test-globalcontext + namespace: test-globalcontext-apicall-correct labels: app: main-deployment spec: diff --git a/test/conformance/chainsaw/globalcontext/apicall-correct/namespace.yaml b/test/conformance/chainsaw/globalcontext/apicall-correct/namespace.yaml index 9310828450..80f2b8e573 100755 --- a/test/conformance/chainsaw/globalcontext/apicall-correct/namespace.yaml +++ b/test/conformance/chainsaw/globalcontext/apicall-correct/namespace.yaml @@ -1,4 +1,4 @@ apiVersion: v1 kind: Namespace metadata: - name: test-globalcontext + name: test-globalcontext-apicall-correct diff --git a/test/conformance/chainsaw/globalcontext/apicall-correct/new-deployment-exists.yaml b/test/conformance/chainsaw/globalcontext/apicall-correct/new-deployment-exists.yaml index 969c3bc053..24d08fe849 100755 --- a/test/conformance/chainsaw/globalcontext/apicall-correct/new-deployment-exists.yaml +++ b/test/conformance/chainsaw/globalcontext/apicall-correct/new-deployment-exists.yaml @@ -2,6 +2,6 @@ apiVersion: apps/v1 kind: Deployment metadata: name: new-deployment - namespace: test-globalcontext + namespace: test-globalcontext-apicall-correct labels: app: new-deployment diff --git a/test/conformance/chainsaw/globalcontext/apicall-correct/new-deployment.yaml b/test/conformance/chainsaw/globalcontext/apicall-correct/new-deployment.yaml index 343cbc492b..c162c0a48b 100755 --- a/test/conformance/chainsaw/globalcontext/apicall-correct/new-deployment.yaml +++ b/test/conformance/chainsaw/globalcontext/apicall-correct/new-deployment.yaml @@ -2,7 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: new-deployment - namespace: test-globalcontext + namespace: test-globalcontext-apicall-correct labels: app: new-deployment spec: diff --git a/test/conformance/chainsaw/globalcontext/apicall-failed/README.md b/test/conformance/chainsaw/globalcontext/apicall-failed/README.md new file mode 100644 index 0000000000..e4830f2597 --- /dev/null +++ b/test/conformance/chainsaw/globalcontext/apicall-failed/README.md @@ -0,0 +1,11 @@ +## Description + +This test verifies that Global Context Entries are evaluated correctly. + +## Expected Behavior + +`new-deployment` should be created. + +## Reference Issues + + diff --git a/test/conformance/chainsaw/globalcontext/apicall-failed/chainsaw-test.yaml b/test/conformance/chainsaw/globalcontext/apicall-failed/chainsaw-test.yaml new file mode 100755 index 0000000000..a2f0d2f3ac --- /dev/null +++ b/test/conformance/chainsaw/globalcontext/apicall-failed/chainsaw-test.yaml @@ -0,0 +1,13 @@ +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + creationTimestamp: null + name: apicall-failed +spec: + steps: + - name: scenario + try: + - apply: + file: gctxentry.yaml + - assert: + file: gctxentry-not-ready.yaml diff --git a/test/conformance/chainsaw/globalcontext/apicall-failed/gctxentry-not-ready.yaml b/test/conformance/chainsaw/globalcontext/apicall-failed/gctxentry-not-ready.yaml new file mode 100755 index 0000000000..a7ece467cb --- /dev/null +++ b/test/conformance/chainsaw/globalcontext/apicall-failed/gctxentry-not-ready.yaml @@ -0,0 +1,8 @@ +apiVersion: kyverno.io/v2alpha1 +kind: GlobalContextEntry +metadata: + name: gctxentry-apicall-failed +status: + conditions: + - status: "False" + type: Ready diff --git a/test/conformance/chainsaw/globalcontext/apicall-failed/gctxentry.yaml b/test/conformance/chainsaw/globalcontext/apicall-failed/gctxentry.yaml new file mode 100755 index 0000000000..e1cc305a27 --- /dev/null +++ b/test/conformance/chainsaw/globalcontext/apicall-failed/gctxentry.yaml @@ -0,0 +1,8 @@ +apiVersion: kyverno.io/v2alpha1 +kind: GlobalContextEntry +metadata: + name: gctxentry-apicall-failed +spec: + apiCall: + urlPath: "/apis/apps/v1/namespaces/default/unknown" + refreshInterval: 10s diff --git a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/README.md b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/README.md index 8e678c56af..e4c4d50cc5 100644 --- a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/README.md +++ b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/README.md @@ -1,10 +1,10 @@ ## Description -This test verifies that policies are not ready if referenced Global Context Entries don't exist. +This test verifies that policies cannot be created if referenced Global Context Entries don't exist. ## Expected Behavior -`new-deployment` should not be created because the policy is not ready. +The clusterpolicy ` cpol-gctxentry-not-exist` should not be created because the globalcontextentry does not exist. ## Reference Issues diff --git a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/chainsaw-test.yaml b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/chainsaw-test.yaml index bc17ae4ed1..b04cc4ab16 100755 --- a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/chainsaw-test.yaml +++ b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/chainsaw-test.yaml @@ -11,8 +11,6 @@ spec: file: namespace.yaml - apply: file: main-deployment.yaml - - apply: - file: gctxentry.yaml - name: negative try: - apply: diff --git a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/clusterpolicy.yaml b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/clusterpolicy.yaml index b2775d0b10..bce134a389 100755 --- a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/clusterpolicy.yaml +++ b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/clusterpolicy.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: namespace-has-coordinator + name: cpol-gctxentry-not-exist spec: validationFailureAction: Enforce failurePolicy: Fail diff --git a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/gctxentry.yaml b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/gctxentry.yaml index 334874bd89..5ad29c3338 100755 --- a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/gctxentry.yaml +++ b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/gctxentry.yaml @@ -1,10 +1,10 @@ apiVersion: kyverno.io/v2alpha1 kind: GlobalContextEntry metadata: - name: deployments + name: non-existent-gctx spec: kubernetesResource: group: apps version: v1 resource: deployments - namespace: test-globalcontext + namespace: test-globalcontext-gctxentry-not-exist diff --git a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/main-deployment.yaml b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/main-deployment.yaml index bd269e4252..a79c3f841f 100755 --- a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/main-deployment.yaml +++ b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/main-deployment.yaml @@ -2,7 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: main-deployment - namespace: test-globalcontext + namespace: test-globalcontext-gctxentry-not-exist labels: app: main-deployment spec: diff --git a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/namespace.yaml b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/namespace.yaml index 9310828450..3d1958b313 100755 --- a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/namespace.yaml +++ b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/namespace.yaml @@ -1,4 +1,4 @@ apiVersion: v1 kind: Namespace metadata: - name: test-globalcontext + name: test-globalcontext-gctxentry-not-exist diff --git a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/new-deployment.yaml b/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/new-deployment.yaml deleted file mode 100755 index 343cbc492b..0000000000 --- a/test/conformance/chainsaw/globalcontext/gctxentry-not-exist/new-deployment.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: new-deployment - namespace: test-globalcontext - labels: - app: new-deployment -spec: - replicas: 1 - selector: - matchLabels: - app: new-deployment - template: - metadata: - labels: - app: new-deployment - spec: - containers: - - name: nginx - image: nginx:1.14.2 - ports: - - containerPort: 80 diff --git a/test/conformance/chainsaw/globalcontext/not-ready/README.md b/test/conformance/chainsaw/globalcontext/not-ready/README.md index 8e678c56af..bf33ac73a9 100644 --- a/test/conformance/chainsaw/globalcontext/not-ready/README.md +++ b/test/conformance/chainsaw/globalcontext/not-ready/README.md @@ -1,6 +1,6 @@ ## Description -This test verifies that policies are not ready if referenced Global Context Entries don't exist. +This test verifies that the policy becomes not ready if the referenced Global Context Entries don't exist anymore. ## Expected Behavior diff --git a/test/conformance/chainsaw/globalcontext/not-ready/chainsaw-test.yaml b/test/conformance/chainsaw/globalcontext/not-ready/chainsaw-test.yaml index d920e77e1b..4349ddc67b 100755 --- a/test/conformance/chainsaw/globalcontext/not-ready/chainsaw-test.yaml +++ b/test/conformance/chainsaw/globalcontext/not-ready/chainsaw-test.yaml @@ -13,15 +13,19 @@ spec: file: main-deployment.yaml - apply: file: gctxentry.yaml - - assert: - file: gctxentry-exists.yaml + - sleep: + duration: 15s - apply: file: clusterpolicy.yaml + - assert: + file: clusterpolicy-ready.yaml - delete: ref: apiVersion: kyverno.io/v2alpha1 kind: GlobalContextEntry - name: deployments + name: gctx-not-ready + - sleep: + duration: 5s - assert: file: clusterpolicy-failed.yaml - apply: diff --git a/test/conformance/chainsaw/globalcontext/not-ready/clusterpolicy-failed.yaml b/test/conformance/chainsaw/globalcontext/not-ready/clusterpolicy-failed.yaml index 8e33aa69ed..0b45387ea7 100755 --- a/test/conformance/chainsaw/globalcontext/not-ready/clusterpolicy-failed.yaml +++ b/test/conformance/chainsaw/globalcontext/not-ready/clusterpolicy-failed.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: namespace-has-coordinator + name: cpol-not-ready status: conditions: - reason: Failed diff --git a/test/conformance/chainsaw/globalcontext/resource-correct/clusterpolicy-succeeded.yaml b/test/conformance/chainsaw/globalcontext/not-ready/clusterpolicy-ready.yaml similarity index 79% rename from test/conformance/chainsaw/globalcontext/resource-correct/clusterpolicy-succeeded.yaml rename to test/conformance/chainsaw/globalcontext/not-ready/clusterpolicy-ready.yaml index 47b54ce1f2..ce59fdcea4 100755 --- a/test/conformance/chainsaw/globalcontext/resource-correct/clusterpolicy-succeeded.yaml +++ b/test/conformance/chainsaw/globalcontext/not-ready/clusterpolicy-ready.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: namespace-has-coordinator + name: cpol-not-ready status: conditions: - reason: Succeeded diff --git a/test/conformance/chainsaw/globalcontext/not-ready/clusterpolicy.yaml b/test/conformance/chainsaw/globalcontext/not-ready/clusterpolicy.yaml index 1c459b0a16..da32709a9e 100755 --- a/test/conformance/chainsaw/globalcontext/not-ready/clusterpolicy.yaml +++ b/test/conformance/chainsaw/globalcontext/not-ready/clusterpolicy.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: namespace-has-coordinator + name: cpol-not-ready spec: validationFailureAction: Enforce failurePolicy: Fail @@ -10,7 +10,7 @@ spec: context: - name: deploymentCount globalReference: - name: deployments + name: gctx-not-ready jmesPath: "items | length(@)" match: all: diff --git a/test/conformance/chainsaw/globalcontext/not-ready/gctxentry-exists.yaml b/test/conformance/chainsaw/globalcontext/not-ready/gctxentry-exists.yaml deleted file mode 100755 index 1b74e4595c..0000000000 --- a/test/conformance/chainsaw/globalcontext/not-ready/gctxentry-exists.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: kyverno.io/v2alpha1 -kind: GlobalContextEntry -metadata: - name: deployments diff --git a/test/conformance/chainsaw/globalcontext/not-ready/gctxentry.yaml b/test/conformance/chainsaw/globalcontext/not-ready/gctxentry.yaml index 46d1da9f8f..68e4359cde 100755 --- a/test/conformance/chainsaw/globalcontext/not-ready/gctxentry.yaml +++ b/test/conformance/chainsaw/globalcontext/not-ready/gctxentry.yaml @@ -1,8 +1,8 @@ apiVersion: kyverno.io/v2alpha1 kind: GlobalContextEntry metadata: - name: deployments + name: gctx-not-ready spec: apiCall: - urlPath: "/apis/apps/v1/namespaces/test-globalcontext/deployments" + urlPath: "/apis/apps/v1/namespaces/test-globalcontext-not-ready/deployments" refreshInterval: 10s diff --git a/test/conformance/chainsaw/globalcontext/not-ready/main-deployment.yaml b/test/conformance/chainsaw/globalcontext/not-ready/main-deployment.yaml index bd269e4252..05c7d1ae44 100755 --- a/test/conformance/chainsaw/globalcontext/not-ready/main-deployment.yaml +++ b/test/conformance/chainsaw/globalcontext/not-ready/main-deployment.yaml @@ -2,7 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: main-deployment - namespace: test-globalcontext + namespace: test-globalcontext-not-ready labels: app: main-deployment spec: diff --git a/test/conformance/chainsaw/globalcontext/not-ready/namespace.yaml b/test/conformance/chainsaw/globalcontext/not-ready/namespace.yaml index 9310828450..a145dd302e 100755 --- a/test/conformance/chainsaw/globalcontext/not-ready/namespace.yaml +++ b/test/conformance/chainsaw/globalcontext/not-ready/namespace.yaml @@ -1,4 +1,4 @@ apiVersion: v1 kind: Namespace metadata: - name: test-globalcontext + name: test-globalcontext-not-ready diff --git a/test/conformance/chainsaw/globalcontext/not-ready/new-deployment-exists.yaml b/test/conformance/chainsaw/globalcontext/not-ready/new-deployment-exists.yaml index 969c3bc053..c09c5f44a2 100755 --- a/test/conformance/chainsaw/globalcontext/not-ready/new-deployment-exists.yaml +++ b/test/conformance/chainsaw/globalcontext/not-ready/new-deployment-exists.yaml @@ -2,6 +2,6 @@ apiVersion: apps/v1 kind: Deployment metadata: name: new-deployment - namespace: test-globalcontext + namespace: test-globalcontext-not-ready labels: app: new-deployment diff --git a/test/conformance/chainsaw/globalcontext/not-ready/new-deployment.yaml b/test/conformance/chainsaw/globalcontext/not-ready/new-deployment.yaml index 343cbc492b..53e0128f2f 100755 --- a/test/conformance/chainsaw/globalcontext/not-ready/new-deployment.yaml +++ b/test/conformance/chainsaw/globalcontext/not-ready/new-deployment.yaml @@ -2,7 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: new-deployment - namespace: test-globalcontext + namespace: test-globalcontext-not-ready labels: app: new-deployment spec: diff --git a/test/conformance/chainsaw/globalcontext/resource-correct/chainsaw-test.yaml b/test/conformance/chainsaw/globalcontext/resource-correct/chainsaw-test.yaml index 4c74ff5137..4a2dde9d2e 100755 --- a/test/conformance/chainsaw/globalcontext/resource-correct/chainsaw-test.yaml +++ b/test/conformance/chainsaw/globalcontext/resource-correct/chainsaw-test.yaml @@ -13,11 +13,13 @@ spec: file: main-deployment.yaml - apply: file: gctxentry.yaml + - sleep: + duration: 5s - apply: file: clusterpolicy.yaml + - assert: + file: clusterpolicy-ready.yaml - apply: file: new-deployment.yaml - - assert: - file: clusterpolicy-succeeded.yaml - assert: file: new-deployment-exists.yaml diff --git a/test/conformance/chainsaw/globalcontext/resource-correct/clusterpolicy-ready.yaml b/test/conformance/chainsaw/globalcontext/resource-correct/clusterpolicy-ready.yaml new file mode 100755 index 0000000000..941491ba9c --- /dev/null +++ b/test/conformance/chainsaw/globalcontext/resource-correct/clusterpolicy-ready.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: cpol-resource-correct +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/chainsaw/globalcontext/resource-correct/clusterpolicy.yaml b/test/conformance/chainsaw/globalcontext/resource-correct/clusterpolicy.yaml index 35e172629e..ec2126c4f5 100755 --- a/test/conformance/chainsaw/globalcontext/resource-correct/clusterpolicy.yaml +++ b/test/conformance/chainsaw/globalcontext/resource-correct/clusterpolicy.yaml @@ -1,7 +1,7 @@ apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: - name: namespace-has-coordinator + name: cpol-resource-correct spec: validationFailureAction: Enforce failurePolicy: Fail @@ -10,7 +10,7 @@ spec: context: - name: deploymentCount globalReference: - name: deployments + name: gctxentry-resource-correct jmesPath: "length(@)" match: all: diff --git a/test/conformance/chainsaw/globalcontext/resource-correct/gctxentry.yaml b/test/conformance/chainsaw/globalcontext/resource-correct/gctxentry.yaml index 334874bd89..041fd312a8 100755 --- a/test/conformance/chainsaw/globalcontext/resource-correct/gctxentry.yaml +++ b/test/conformance/chainsaw/globalcontext/resource-correct/gctxentry.yaml @@ -1,10 +1,10 @@ apiVersion: kyverno.io/v2alpha1 kind: GlobalContextEntry metadata: - name: deployments + name: gctxentry-resource-correct spec: kubernetesResource: group: apps version: v1 resource: deployments - namespace: test-globalcontext + namespace: test-globalcontext-resource-correct diff --git a/test/conformance/chainsaw/globalcontext/resource-correct/main-deployment.yaml b/test/conformance/chainsaw/globalcontext/resource-correct/main-deployment.yaml index bd269e4252..ca3b365478 100755 --- a/test/conformance/chainsaw/globalcontext/resource-correct/main-deployment.yaml +++ b/test/conformance/chainsaw/globalcontext/resource-correct/main-deployment.yaml @@ -2,7 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: main-deployment - namespace: test-globalcontext + namespace: test-globalcontext-resource-correct labels: app: main-deployment spec: diff --git a/test/conformance/chainsaw/globalcontext/resource-correct/namespace.yaml b/test/conformance/chainsaw/globalcontext/resource-correct/namespace.yaml index 9310828450..614c18b9b4 100755 --- a/test/conformance/chainsaw/globalcontext/resource-correct/namespace.yaml +++ b/test/conformance/chainsaw/globalcontext/resource-correct/namespace.yaml @@ -1,4 +1,4 @@ apiVersion: v1 kind: Namespace metadata: - name: test-globalcontext + name: test-globalcontext-resource-correct diff --git a/test/conformance/chainsaw/globalcontext/resource-correct/new-deployment-exists.yaml b/test/conformance/chainsaw/globalcontext/resource-correct/new-deployment-exists.yaml index 969c3bc053..b958612a92 100755 --- a/test/conformance/chainsaw/globalcontext/resource-correct/new-deployment-exists.yaml +++ b/test/conformance/chainsaw/globalcontext/resource-correct/new-deployment-exists.yaml @@ -2,6 +2,6 @@ apiVersion: apps/v1 kind: Deployment metadata: name: new-deployment - namespace: test-globalcontext + namespace: test-globalcontext-resource-correct labels: app: new-deployment diff --git a/test/conformance/chainsaw/globalcontext/resource-correct/new-deployment.yaml b/test/conformance/chainsaw/globalcontext/resource-correct/new-deployment.yaml index 343cbc492b..c9812eda73 100755 --- a/test/conformance/chainsaw/globalcontext/resource-correct/new-deployment.yaml +++ b/test/conformance/chainsaw/globalcontext/resource-correct/new-deployment.yaml @@ -2,7 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: new-deployment - namespace: test-globalcontext + namespace: test-globalcontext-resource-correct labels: app: new-deployment spec: