From 547771a221f8b696ae3bd42527cce4ffe6e9d434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 2 Nov 2022 07:10:48 +0000 Subject: [PATCH 01/55] fix: use pagination to aggregate reports (#5190) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- .../report/aggregate/controller.go | 117 +++++++++++------- 1 file changed, 75 insertions(+), 42 deletions(-) diff --git a/pkg/controllers/report/aggregate/controller.go b/pkg/controllers/report/aggregate/controller.go index 184a9e1f5297..31ee050e7ed6 100644 --- a/pkg/controllers/report/aggregate/controller.go +++ b/pkg/controllers/report/aggregate/controller.go @@ -35,6 +35,7 @@ const ( Workers = 1 ControllerName = "aggregate-report-controller" maxRetries = 10 + mergeLimit = 1000 ) type controller struct { @@ -74,6 +75,8 @@ func NewController( cadmrInformer := metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("clusteradmissionreports")) bgscanrInformer := metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("backgroundscanreports")) cbgscanrInformer := metadataFactory.ForResource(kyvernov1alpha2.SchemeGroupVersion.WithResource("clusterbackgroundscanreports")) + polrInformer := metadataFactory.ForResource(policyreportv1alpha2.SchemeGroupVersion.WithResource("policyreports")) + cpolrInformer := metadataFactory.ForResource(policyreportv1alpha2.SchemeGroupVersion.WithResource("clusterpolicyreports")) c := controller{ client: client, polLister: polInformer.Lister(), @@ -87,6 +90,8 @@ func NewController( chunkSize: chunkSize, } delay := 15 * time.Second + controllerutils.AddDelayedExplicitEventHandlers(logger, polrInformer.Informer(), c.queue, delay, keyFunc) + controllerutils.AddDelayedExplicitEventHandlers(logger, cpolrInformer.Informer(), c.queue, delay, keyFunc) controllerutils.AddDelayedExplicitEventHandlers(logger, admrInformer.Informer(), c.queue, delay, keyFunc) controllerutils.AddDelayedExplicitEventHandlers(logger, cadmrInformer.Informer(), c.queue, delay, keyFunc) controllerutils.AddDelayedExplicitEventHandlers(logger, bgscanrInformer.Informer(), c.queue, delay, keyFunc) @@ -98,48 +103,84 @@ func (c *controller) Run(ctx context.Context, workers int) { controllerutils.Run(ctx, logger, ControllerName, time.Second, c.queue, workers, maxRetries, c.reconcile) } -func (c *controller) listAdmissionReports(ctx context.Context, namespace string) ([]kyvernov1alpha2.ReportInterface, error) { - var reports []kyvernov1alpha2.ReportInterface +func (c *controller) mergeAdmissionReports(ctx context.Context, namespace string, policyMap map[string]sets.String, accumulator map[string]policyreportv1alpha2.PolicyReportResult) error { if namespace == "" { - cadms, err := c.client.KyvernoV1alpha2().ClusterAdmissionReports().List(ctx, metav1.ListOptions{}) - if err != nil { - return nil, err - } - for i := range cadms.Items { - reports = append(reports, &cadms.Items[i]) + next := "" + for { + cadms, err := c.client.KyvernoV1alpha2().ClusterAdmissionReports().List(ctx, metav1.ListOptions{ + Limit: mergeLimit, + Continue: next, + }) + if err != nil { + return err + } + next = cadms.Continue + for i := range cadms.Items { + mergeReports(policyMap, accumulator, &cadms.Items[i]) + } + if next == "" { + return nil + } } } else { - adms, err := c.client.KyvernoV1alpha2().AdmissionReports(namespace).List(ctx, metav1.ListOptions{}) - if err != nil { - return nil, err - } - for i := range adms.Items { - reports = append(reports, &adms.Items[i]) + next := "" + for { + adms, err := c.client.KyvernoV1alpha2().AdmissionReports(namespace).List(ctx, metav1.ListOptions{ + Limit: mergeLimit, + Continue: next, + }) + if err != nil { + return err + } + next = adms.Continue + for i := range adms.Items { + mergeReports(policyMap, accumulator, &adms.Items[i]) + } + if next == "" { + return nil + } } } - return reports, nil } -func (c *controller) listBackgroundScanReports(ctx context.Context, namespace string) ([]kyvernov1alpha2.ReportInterface, error) { - var reports []kyvernov1alpha2.ReportInterface +func (c *controller) mergeBackgroundScanReports(ctx context.Context, namespace string, policyMap map[string]sets.String, accumulator map[string]policyreportv1alpha2.PolicyReportResult) error { if namespace == "" { - cbgscans, err := c.client.KyvernoV1alpha2().ClusterBackgroundScanReports().List(ctx, metav1.ListOptions{}) - if err != nil { - return nil, err - } - for i := range cbgscans.Items { - reports = append(reports, &cbgscans.Items[i]) + next := "" + for { + cbgscans, err := c.client.KyvernoV1alpha2().ClusterBackgroundScanReports().List(ctx, metav1.ListOptions{ + Limit: mergeLimit, + Continue: next, + }) + if err != nil { + return err + } + next = cbgscans.Continue + for i := range cbgscans.Items { + mergeReports(policyMap, accumulator, &cbgscans.Items[i]) + } + if next == "" { + return nil + } } } else { - bgscans, err := c.client.KyvernoV1alpha2().BackgroundScanReports(namespace).List(ctx, metav1.ListOptions{}) - if err != nil { - return nil, err - } - for i := range bgscans.Items { - reports = append(reports, &bgscans.Items[i]) + next := "" + for { + bgscans, err := c.client.KyvernoV1alpha2().BackgroundScanReports(namespace).List(ctx, metav1.ListOptions{ + Limit: mergeLimit, + Continue: next, + }) + if err != nil { + return err + } + next = bgscans.Continue + for i := range bgscans.Items { + mergeReports(policyMap, accumulator, &bgscans.Items[i]) + } + if next == "" { + return nil + } } } - return reports, nil } func (c *controller) reconcileReport(ctx context.Context, report kyvernov1alpha2.ReportInterface, namespace, name string, results ...policyreportv1alpha2.PolicyReportResult) (kyvernov1alpha2.ReportInterface, error) { @@ -236,19 +277,11 @@ func (c *controller) buildReportsResults(ctx context.Context, namespace string) return nil, err } merged := map[string]policyreportv1alpha2.PolicyReportResult{} - { - reports, err := c.listAdmissionReports(ctx, namespace) - if err != nil { - return nil, err - } - mergeReports(policyMap, merged, reports...) + if err := c.mergeAdmissionReports(ctx, namespace, policyMap, merged); err != nil { + return nil, err } - { - reports, err := c.listBackgroundScanReports(ctx, namespace) - if err != nil { - return nil, err - } - mergeReports(policyMap, merged, reports...) + if err := c.mergeBackgroundScanReports(ctx, namespace, policyMap, merged); err != nil { + return nil, err } var results []policyreportv1alpha2.PolicyReportResult for _, result := range merged { From 9f6b0e8017da7c2e5254dea3277488cdac8e3304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 2 Nov 2022 09:06:44 +0000 Subject: [PATCH 02/55] refactor: remove policyreport package (#5174) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- cmd/cli/kubectl-kyverno/apply/apply_command.go | 5 ++--- cmd/cli/kubectl-kyverno/apply/report.go | 6 +++--- cmd/cli/kubectl-kyverno/apply/report_test.go | 6 +++--- cmd/cli/kubectl-kyverno/test/test_command.go | 5 ++--- cmd/cli/kubectl-kyverno/utils/common/common.go | 17 ++++++++--------- .../cli/kubectl-kyverno/utils/common}/info.go | 2 +- 6 files changed, 19 insertions(+), 22 deletions(-) rename {pkg/policyreport => cmd/cli/kubectl-kyverno/utils/common}/info.go (95%) diff --git a/cmd/cli/kubectl-kyverno/apply/apply_command.go b/cmd/cli/kubectl-kyverno/apply/apply_command.go index 157a5e7e6f64..15b30b71084d 100644 --- a/cmd/cli/kubectl-kyverno/apply/apply_command.go +++ b/cmd/cli/kubectl-kyverno/apply/apply_command.go @@ -17,7 +17,6 @@ import ( "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/openapi" policy2 "github.com/kyverno/kyverno/pkg/policy" - "github.com/kyverno/kyverno/pkg/policyreport" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/client-go/kubernetes" @@ -167,7 +166,7 @@ func Command() *cobra.Command { return cmd } -func (c *ApplyCommandConfig) applyCommandHelper() (rc *common.ResultCounts, resources []*unstructured.Unstructured, skipInvalidPolicies SkippedInvalidPolicies, pvInfos []policyreport.Info, err error) { +func (c *ApplyCommandConfig) applyCommandHelper() (rc *common.ResultCounts, resources []*unstructured.Unstructured, skipInvalidPolicies SkippedInvalidPolicies, pvInfos []common.Info, err error) { store.SetMock(true) store.SetRegistryAccess(c.RegistryAccess) if c.Cluster { @@ -396,7 +395,7 @@ func checkMutateLogPath(mutateLogPath string) (mutateLogPathIsDir bool, err erro } // PrintReportOrViolation - printing policy report/violations -func PrintReportOrViolation(policyReport bool, rc *common.ResultCounts, resourcePaths []string, resourcesLen int, skipInvalidPolicies SkippedInvalidPolicies, stdin bool, pvInfos []policyreport.Info) { +func PrintReportOrViolation(policyReport bool, rc *common.ResultCounts, resourcePaths []string, resourcesLen int, skipInvalidPolicies SkippedInvalidPolicies, stdin bool, pvInfos []common.Info) { divider := "----------------------------------------------------------------------" if len(skipInvalidPolicies.skipped) > 0 { diff --git a/cmd/cli/kubectl-kyverno/apply/report.go b/cmd/cli/kubectl-kyverno/apply/report.go index 1449a0c1d307..14a16ac3bff4 100644 --- a/cmd/cli/kubectl-kyverno/apply/report.go +++ b/cmd/cli/kubectl-kyverno/apply/report.go @@ -8,9 +8,9 @@ import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2" + "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common" "github.com/kyverno/kyverno/pkg/engine/response" engineutils "github.com/kyverno/kyverno/pkg/engine/utils" - "github.com/kyverno/kyverno/pkg/policyreport" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -21,7 +21,7 @@ import ( const clusterpolicyreport = "clusterpolicyreport" // resps is the engine responses generated for a single policy -func buildPolicyReports(pvInfos []policyreport.Info) (res []*unstructured.Unstructured) { +func buildPolicyReports(pvInfos []common.Info) (res []*unstructured.Unstructured) { var raw []byte var err error @@ -74,7 +74,7 @@ func buildPolicyReports(pvInfos []policyreport.Info) (res []*unstructured.Unstru // buildPolicyResults returns a string-PolicyReportResult map // the key of the map is one of "clusterpolicyreport", "policyreport-ns-" -func buildPolicyResults(infos []policyreport.Info) map[string][]policyreportv1alpha2.PolicyReportResult { +func buildPolicyResults(infos []common.Info) map[string][]policyreportv1alpha2.PolicyReportResult { results := make(map[string][]policyreportv1alpha2.PolicyReportResult) now := metav1.Timestamp{Seconds: time.Now().Unix()} diff --git a/cmd/cli/kubectl-kyverno/apply/report_test.go b/cmd/cli/kubectl-kyverno/apply/report_test.go index 2c6d1c0b2260..94cd3ea9be96 100644 --- a/cmd/cli/kubectl-kyverno/apply/report_test.go +++ b/cmd/cli/kubectl-kyverno/apply/report_test.go @@ -6,9 +6,9 @@ import ( kyverno "github.com/kyverno/kyverno/api/kyverno/v1" preport "github.com/kyverno/kyverno/api/policyreport/v1alpha2" + "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common" kyvCommon "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common" "github.com/kyverno/kyverno/pkg/engine/response" - "github.com/kyverno/kyverno/pkg/policyreport" "gotest.tools/assert" v1 "k8s.io/api/core/v1" ) @@ -87,7 +87,7 @@ var rawEngRes = []byte(`{"PatchedResource":{"apiVersion":"v1","kind":"Pod","meta func Test_buildPolicyReports(t *testing.T) { rc := &kyvCommon.ResultCounts{} - var pvInfos []policyreport.Info + var pvInfos []common.Info var policy kyverno.ClusterPolicy err := json.Unmarshal(rawPolicy, &policy) assert.NilError(t, err) @@ -123,7 +123,7 @@ func Test_buildPolicyReports(t *testing.T) { func Test_buildPolicyResults(t *testing.T) { rc := &kyvCommon.ResultCounts{} - var pvInfos []policyreport.Info + var pvInfos []common.Info var policy kyverno.ClusterPolicy err := json.Unmarshal(rawPolicy, &policy) assert.NilError(t, err) diff --git a/cmd/cli/kubectl-kyverno/test/test_command.go b/cmd/cli/kubectl-kyverno/test/test_command.go index dcfbf558a998..ecb3b2a4b652 100644 --- a/cmd/cli/kubectl-kyverno/test/test_command.go +++ b/cmd/cli/kubectl-kyverno/test/test_command.go @@ -29,7 +29,6 @@ import ( "github.com/kyverno/kyverno/pkg/engine/response" "github.com/kyverno/kyverno/pkg/openapi" policy2 "github.com/kyverno/kyverno/pkg/policy" - "github.com/kyverno/kyverno/pkg/policyreport" util "github.com/kyverno/kyverno/pkg/utils" "github.com/lensesio/tableprinter" "github.com/spf13/cobra" @@ -514,7 +513,7 @@ func getLocalDirTestFiles(fs billy.Filesystem, path, fileName string, rc *result return errors } -func buildPolicyResults(engineResponses []*response.EngineResponse, testResults []TestResults, infos []policyreport.Info, policyResourcePath string, fs billy.Filesystem, isGit bool) (map[string]policyreportv1alpha2.PolicyReportResult, []TestResults) { +func buildPolicyResults(engineResponses []*response.EngineResponse, testResults []TestResults, infos []common.Info, policyResourcePath string, fs billy.Filesystem, isGit bool) (map[string]policyreportv1alpha2.PolicyReportResult, []TestResults) { results := make(map[string]policyreportv1alpha2.PolicyReportResult) now := metav1.Timestamp{Seconds: time.Now().Unix()} @@ -824,7 +823,7 @@ func applyPoliciesFromPath(fs billy.Filesystem, policyBytes []byte, isGit bool, var dClient dclient.Interface values := &Test{} var variablesString string - var pvInfos []policyreport.Info + var pvInfos []common.Info var resultCounts common.ResultCounts store.SetMock(true) diff --git a/cmd/cli/kubectl-kyverno/utils/common/common.go b/cmd/cli/kubectl-kyverno/utils/common/common.go index 1b045c40012f..168971ebdf70 100644 --- a/cmd/cli/kubectl-kyverno/utils/common/common.go +++ b/cmd/cli/kubectl-kyverno/utils/common/common.go @@ -26,7 +26,6 @@ import ( "github.com/kyverno/kyverno/pkg/engine/response" ut "github.com/kyverno/kyverno/pkg/engine/utils" "github.com/kyverno/kyverno/pkg/engine/variables" - "github.com/kyverno/kyverno/pkg/policyreport" yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml" yamlv2 "gopkg.in/yaml.v2" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -355,7 +354,7 @@ func GetVariable(variablesString, valuesFile string, fs billy.Filesystem, isGit } // ApplyPolicyOnResource - function to apply policy on resource -func ApplyPolicyOnResource(c ApplyPolicyConfig) ([]*response.EngineResponse, policyreport.Info, error) { +func ApplyPolicyOnResource(c ApplyPolicyConfig) ([]*response.EngineResponse, Info, error) { var engineResponses []*response.EngineResponse namespaceLabels := make(map[string]string) operationIsDelete := false @@ -402,7 +401,7 @@ OuterLoop: resourceNamespace := c.Resource.GetNamespace() namespaceLabels = c.NamespaceSelectorMap[c.Resource.GetNamespace()] if resourceNamespace != "default" && len(namespaceLabels) < 1 { - return engineResponses, policyreport.Info{}, sanitizederror.NewWithError(fmt.Sprintf("failed to get namespace labels for resource %s. use --values-file flag to pass the namespace labels", c.Resource.GetName()), nil) + return engineResponses, Info{}, sanitizederror.NewWithError(fmt.Sprintf("failed to get namespace labels for resource %s. use --values-file flag to pass the namespace labels", c.Resource.GetName()), nil) } } @@ -464,7 +463,7 @@ OuterLoop: err = processMutateEngineResponse(c, mutateResponse, resPath) if err != nil { if !sanitizederror.IsErrorSanitized(err) { - return engineResponses, policyreport.Info{}, sanitizederror.NewWithError("failed to print mutated result", err) + return engineResponses, Info{}, sanitizederror.NewWithError("failed to print mutated result", err) } } @@ -477,7 +476,7 @@ OuterLoop: policyContext.NewResource = mutateResponse.PatchedResource - var info policyreport.Info + var info Info var validateResponse *response.EngineResponse if policyHasValidate { validateResponse = engine.Validate(policyContext) @@ -674,7 +673,7 @@ func GetResourceAccordingToResourcePath(fs billy.Filesystem, resourcePaths []str return resources, err } -func ProcessValidateEngineResponse(policy kyvernov1.PolicyInterface, validateResponse *response.EngineResponse, resPath string, rc *ResultCounts, policyReport bool) policyreport.Info { +func ProcessValidateEngineResponse(policy kyvernov1.PolicyInterface, validateResponse *response.EngineResponse, resPath string, rc *ResultCounts, policyReport bool) Info { var violatedRules []kyvernov1.ViolatedRule printCount := 0 @@ -750,11 +749,11 @@ func ProcessValidateEngineResponse(policy kyvernov1.PolicyInterface, validateRes return buildPVInfo(validateResponse, violatedRules) } -func buildPVInfo(er *response.EngineResponse, violatedRules []kyvernov1.ViolatedRule) policyreport.Info { - info := policyreport.Info{ +func buildPVInfo(er *response.EngineResponse, violatedRules []kyvernov1.ViolatedRule) Info { + info := Info{ PolicyName: er.PolicyResponse.Policy.Name, Namespace: er.PatchedResource.GetNamespace(), - Results: []policyreport.EngineResponseResult{ + Results: []EngineResponseResult{ { Resource: er.GetResourceSpec(), Rules: violatedRules, diff --git a/pkg/policyreport/info.go b/cmd/cli/kubectl-kyverno/utils/common/info.go similarity index 95% rename from pkg/policyreport/info.go rename to cmd/cli/kubectl-kyverno/utils/common/info.go index 4cf45f388fc4..47d64a7aa49a 100644 --- a/pkg/policyreport/info.go +++ b/cmd/cli/kubectl-kyverno/utils/common/info.go @@ -1,4 +1,4 @@ -package policyreport +package common import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" From 0e1d2cae055bc3a204b94fceb27feee28906a692 Mon Sep 17 00:00:00 2001 From: Edwin Mackenzie-Owen Date: Wed, 2 Nov 2022 10:35:33 +0100 Subject: [PATCH 03/55] Helm chart: add extraCRDAnnotations value and set ArgoCD sync option by default (#4964) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: add extraCRDAnnotations option to helm chart set ArgoCD replace sync option by default Signed-off-by: Edwin Mackenzie-Owen * fix: add extraCRDAnnotations via codegen * use template Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Edwin Mackenzie-Owen Signed-off-by: Charles-Edouard Brétéché Co-authored-by: Charles-Edouard Brétéché Co-authored-by: Charles-Edouard Brétéché --- Makefile | 2 +- charts/kyverno/Chart.yaml | 2 ++ charts/kyverno/README.md | 1 + charts/kyverno/templates/_helpers.tpl | 6 ++++++ charts/kyverno/templates/crds.yaml | 10 ++++++++++ charts/kyverno/values.yaml | 6 ++++++ 6 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7dc1c0305f08..b718f5244948 100644 --- a/Makefile +++ b/Makefile @@ -447,7 +447,7 @@ codegen-helm-crds: $(KUSTOMIZE) codegen-crds-all ## Generate helm CRDs @VERSION='"{{.Chart.AppVersion}}"' TOP_PATH=".." envsubst < config/templates/labels.yaml.envsubst > config/.helm/labels.yaml @VERSION=dummy TOP_PATH=".." envsubst < config/templates/kustomization.yaml.envsubst > config/.helm/kustomization.yaml @echo Generate helm crds... >&2 - @$(KUSTOMIZE) build ./config/.helm | $(KUSTOMIZE) cfg grep kind=CustomResourceDefinition | $(SED) -e "1i{{- if .Values.installCRDs }}" -e '$$a{{- end }}' > ./charts/kyverno/templates/crds.yaml + @$(KUSTOMIZE) build ./config/.helm | $(KUSTOMIZE) cfg grep kind=CustomResourceDefinition | $(SED) -e "1i{{- if .Values.installCRDs }}" -e '$$a{{- end }}' -e '/^ creationTimestamp: null/i \ \ \ \ {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }}' > ./charts/kyverno/templates/crds.yaml .PHONY: codegen-helm-all codegen-helm-all: codegen-helm-crds codegen-helm-docs ## Generate helm docs and CRDs diff --git a/charts/kyverno/Chart.yaml b/charts/kyverno/Chart.yaml index 7258fc7b997a..86e3944b39ce 100644 --- a/charts/kyverno/Chart.yaml +++ b/charts/kyverno/Chart.yaml @@ -48,3 +48,5 @@ annotations: description: Enable adding optional annotations to configmaps - kind: added description: Add startup probes support + - kind: added + description: Support extra CRD annotations diff --git a/charts/kyverno/README.md b/charts/kyverno/README.md index 231a7dac951f..0d19727afc08 100644 --- a/charts/kyverno/README.md +++ b/charts/kyverno/README.md @@ -205,6 +205,7 @@ The command removes all the Kubernetes components associated with the chart and | serviceMonitor.tlsConfig | object | `{}` | TLS Configuration for endpoint | | createSelfSignedCert | bool | `false` | Kyverno requires a certificate key pair and corresponding certificate authority to properly register its webhooks. This can be done in one of 3 ways: 1) Use kube-controller-manager to generate a CA-signed certificate (preferred) 2) Provide your own CA and cert. In this case, you will need to create a certificate with a specific name and data structure. As long as you follow the naming scheme, it will be automatically picked up. kyverno-svc.(namespace).svc.kyverno-tls-ca (with data entries named tls.key and tls.crt) kyverno-svc.kyverno.svc.kyverno-tls-pair (with data entries named tls.key and tls.crt) 3) Let Helm generate a self signed cert, by setting createSelfSignedCert true If letting Kyverno create its own CA or providing your own, make createSelfSignedCert is false | | installCRDs | bool | `true` | Whether to have Helm install the Kyverno CRDs. If the CRDs are not installed by Helm, they must be added before policies can be created. | +| crds.annotations | object | `{}` | Additional CRDs annotations. | | networkPolicy.enabled | bool | `false` | When true, use a NetworkPolicy to allow ingress to the webhook This is useful on clusters using Calico and/or native k8s network policies in a default-deny setup. | | networkPolicy.ingressFrom | list | `[]` | A list of valid from selectors according to https://kubernetes.io/docs/concepts/services-networking/network-policies. | | webhooksCleanup.enable | bool | `false` | Create a helm pre-delete hook to cleanup webhooks. | diff --git a/charts/kyverno/templates/_helpers.tpl b/charts/kyverno/templates/_helpers.tpl index 17dbcd5dbf9f..5d577b3e7c7a 100644 --- a/charts/kyverno/templates/_helpers.tpl +++ b/charts/kyverno/templates/_helpers.tpl @@ -159,3 +159,9 @@ maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} {{- end }} {{- $newWebhook | toJson }} {{- end }} + +{{- define "kyverno.crdAnnotations" -}} +{{- range $key, $value := .Values.crds.annotations }} +{{ $key }}: {{ $value | quote }} +{{- end }} +{{- end }} diff --git a/charts/kyverno/templates/crds.yaml b/charts/kyverno/templates/crds.yaml index 33348c5d9e8f..22bf56c12955 100644 --- a/charts/kyverno/templates/crds.yaml +++ b/charts/kyverno/templates/crds.yaml @@ -6,6 +6,7 @@ metadata: controller-gen.kubebuilder.io/version: v0.10.0 config.kubernetes.io/index: '1' internal.config.kubernetes.io/index: '1' + {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: app.kubernetes.io/component: kyverno @@ -267,6 +268,7 @@ metadata: controller-gen.kubebuilder.io/version: v0.10.0 config.kubernetes.io/index: '2' internal.config.kubernetes.io/index: '2' + {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: app.kubernetes.io/component: kyverno @@ -498,6 +500,7 @@ metadata: controller-gen.kubebuilder.io/version: v0.10.0 config.kubernetes.io/index: '3' internal.config.kubernetes.io/index: '3' + {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: app.kubernetes.io/component: kyverno @@ -759,6 +762,7 @@ metadata: controller-gen.kubebuilder.io/version: v0.10.0 config.kubernetes.io/index: '4' internal.config.kubernetes.io/index: '4' + {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: app.kubernetes.io/component: kyverno @@ -990,6 +994,7 @@ metadata: controller-gen.kubebuilder.io/version: v0.10.0 config.kubernetes.io/index: '5' internal.config.kubernetes.io/index: '5' + {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: app.kubernetes.io/component: kyverno @@ -8211,6 +8216,7 @@ metadata: controller-gen.kubebuilder.io/version: v0.10.0 config.kubernetes.io/index: '6' internal.config.kubernetes.io/index: '6' + {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: app.kubernetes.io/component: kyverno @@ -8483,6 +8489,7 @@ metadata: controller-gen.kubebuilder.io/version: v0.10.0 config.kubernetes.io/index: '7' internal.config.kubernetes.io/index: '7' + {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: app.kubernetes.io/component: kyverno @@ -8658,6 +8665,7 @@ metadata: controller-gen.kubebuilder.io/version: v0.10.0 config.kubernetes.io/index: '8' internal.config.kubernetes.io/index: '8' + {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: app.kubernetes.io/component: kyverno @@ -15879,6 +15887,7 @@ metadata: controller-gen.kubebuilder.io/version: v0.10.0 config.kubernetes.io/index: '9' internal.config.kubernetes.io/index: '9' + {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: app.kubernetes.io/component: kyverno @@ -16151,6 +16160,7 @@ metadata: controller-gen.kubebuilder.io/version: v0.10.0 config.kubernetes.io/index: '10' internal.config.kubernetes.io/index: '10' + {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: app.kubernetes.io/component: kyverno diff --git a/charts/kyverno/values.yaml b/charts/kyverno/values.yaml index 9687aa910454..54145767d5b6 100644 --- a/charts/kyverno/values.yaml +++ b/charts/kyverno/values.yaml @@ -445,6 +445,12 @@ createSelfSignedCert: false # If the CRDs are not installed by Helm, they must be added before policies can be created. installCRDs: true +crds: + # -- Additional CRDs annotations. + annotations: {} + # argocd.argoproj.io/sync-options: Replace=true + # strategy.spinnaker.io/replace: 'true' + networkPolicy: # -- When true, use a NetworkPolicy to allow ingress to the webhook # This is useful on clusters using Calico and/or native k8s network policies in a default-deny setup. From 076f2c3c49faf4c61df8844f8b0a39cac3625f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 2 Nov 2022 10:08:54 +0000 Subject: [PATCH 04/55] fix: deletion of reports not belonging to kyverno (#5194) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- pkg/controllers/report/aggregate/controller.go | 9 +++++++-- pkg/utils/controller/metadata.go | 8 ++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pkg/controllers/report/aggregate/controller.go b/pkg/controllers/report/aggregate/controller.go index 31ee050e7ed6..8c5e96c4d2a0 100644 --- a/pkg/controllers/report/aggregate/controller.go +++ b/pkg/controllers/report/aggregate/controller.go @@ -7,6 +7,7 @@ import ( "time" "github.com/go-logr/logr" + kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2" policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2" "github.com/kyverno/kyverno/pkg/autogen" @@ -298,7 +299,9 @@ func (c *controller) getPolicyReports(ctx context.Context, namespace string) ([] return nil, err } for i := range list.Items { - reports = append(reports, &list.Items[i]) + if controllerutils.CheckLabel(&list.Items[i], kyvernov1.LabelAppManagedBy, kyvernov1.ValueKyvernoApp) { + reports = append(reports, &list.Items[i]) + } } } else { list, err := c.client.Wgpolicyk8sV1alpha2().PolicyReports(namespace).List(ctx, metav1.ListOptions{}) @@ -306,7 +309,9 @@ func (c *controller) getPolicyReports(ctx context.Context, namespace string) ([] return nil, err } for i := range list.Items { - reports = append(reports, &list.Items[i]) + if controllerutils.CheckLabel(&list.Items[i], kyvernov1.LabelAppManagedBy, kyvernov1.ValueKyvernoApp) { + reports = append(reports, &list.Items[i]) + } } } return reports, nil diff --git a/pkg/utils/controller/metadata.go b/pkg/utils/controller/metadata.go index 657ae1edf2c9..e5105e74f0d8 100644 --- a/pkg/utils/controller/metadata.go +++ b/pkg/utils/controller/metadata.go @@ -15,6 +15,14 @@ func SetLabel(obj metav1.Object, key, value string) map[string]string { return labels } +func CheckLabel(obj metav1.Object, key, value string) bool { + labels := obj.GetLabels() + if labels == nil { + return false + } + return labels[key] == value +} + func SetAnnotation(obj metav1.Object, key, value string) { annotations := obj.GetAnnotations() if annotations == nil { From 3fc157717a77aedc9bf4a739c70ac75b526d63db Mon Sep 17 00:00:00 2001 From: shuting Date: Thu, 3 Nov 2022 16:12:44 +0800 Subject: [PATCH 05/55] feat: support disabling schema validation on the patched resource (#5197) * Support disable schema validation on the patched resource Signed-off-by: ShutingZhao * update api doc Signed-off-by: ShutingZhao Signed-off-by: ShutingZhao --- api/kyverno/v1/clusterpolicy_types.go | 4 ++++ api/kyverno/v1/policy_interface.go | 1 + api/kyverno/v1/policy_types.go | 4 ++++ api/kyverno/v1/spec_types.go | 9 ++++++++- api/kyverno/v2beta1/spec_types.go | 2 +- charts/kyverno/templates/crds.yaml | 8 ++++---- config/crds/kyverno.io_clusterpolicies.yaml | 12 ++++++------ config/crds/kyverno.io_policies.yaml | 12 ++++++------ docs/user/crd/index.html | 12 ++++++------ pkg/webhooks/resource/mutation/mutation.go | 2 +- 10 files changed, 41 insertions(+), 25 deletions(-) diff --git a/api/kyverno/v1/clusterpolicy_types.go b/api/kyverno/v1/clusterpolicy_types.go index 8703a7fe00e6..e832e55387f9 100644 --- a/api/kyverno/v1/clusterpolicy_types.go +++ b/api/kyverno/v1/clusterpolicy_types.go @@ -103,6 +103,10 @@ func (p *ClusterPolicy) IsReady() bool { return p.Status.IsReady() } +func (p *ClusterPolicy) ValidateSchema() bool { + return p.Spec.ValidateSchema() +} + // Validate implements programmatic validation // namespaced means that the policy is bound to a namespace and therefore // should not filter/generate cluster wide resources. diff --git a/api/kyverno/v1/policy_interface.go b/api/kyverno/v1/policy_interface.go index e5c2eb8f8520..d450b7e7219d 100644 --- a/api/kyverno/v1/policy_interface.go +++ b/api/kyverno/v1/policy_interface.go @@ -19,4 +19,5 @@ type PolicyInterface interface { GetKind() string CreateDeepCopy() PolicyInterface IsReady() bool + ValidateSchema() bool } diff --git a/api/kyverno/v1/policy_types.go b/api/kyverno/v1/policy_types.go index 0af283d591fb..9353d82efb1a 100644 --- a/api/kyverno/v1/policy_types.go +++ b/api/kyverno/v1/policy_types.go @@ -104,6 +104,10 @@ func (p *Policy) IsReady() bool { return p.Status.IsReady() } +func (p *Policy) ValidateSchema() bool { + return p.Spec.ValidateSchema() +} + // Validate implements programmatic validation. // namespaced means that the policy is bound to a namespace and therefore // should not filter/generate cluster wide resources. diff --git a/api/kyverno/v1/spec_types.go b/api/kyverno/v1/spec_types.go index f63fff9de498..de28de8e36e1 100644 --- a/api/kyverno/v1/spec_types.go +++ b/api/kyverno/v1/spec_types.go @@ -75,7 +75,7 @@ type Spec struct { // +kubebuilder:default=true Background *bool `json:"background,omitempty" yaml:"background,omitempty"` - // SchemaValidation skips policy validation checks. + // SchemaValidation skips validation checks for policies as well as patched resources. // Optional. The default value is set to "true", it must be set to "false" to disable the validation checks. // +optional SchemaValidation *bool `json:"schemaValidation,omitempty" yaml:"schemaValidation,omitempty"` @@ -224,6 +224,13 @@ func (s *Spec) GetApplyRules() ApplyRulesType { return *s.ApplyRules } +func (s *Spec) ValidateSchema() bool { + if s.SchemaValidation != nil { + return *s.SchemaValidation + } + return true +} + // ValidateRuleNames checks if the rule names are unique across a policy func (s *Spec) ValidateRuleNames(path *field.Path) (errs field.ErrorList) { names := sets.NewString() diff --git a/api/kyverno/v2beta1/spec_types.go b/api/kyverno/v2beta1/spec_types.go index aec927175972..a1d1bfb20102 100644 --- a/api/kyverno/v2beta1/spec_types.go +++ b/api/kyverno/v2beta1/spec_types.go @@ -48,7 +48,7 @@ type Spec struct { // +kubebuilder:default=true Background *bool `json:"background,omitempty" yaml:"background,omitempty"` - // SchemaValidation skips policy validation checks. + // SchemaValidation skips validation checks for policies as well as patched resources. // Optional. The default value is set to "true", it must be set to "false" to disable the validation checks. // +optional SchemaValidation *bool `json:"schemaValidation,omitempty" yaml:"schemaValidation,omitempty"` diff --git a/charts/kyverno/templates/crds.yaml b/charts/kyverno/templates/crds.yaml index 22bf56c12955..666672436eee 100644 --- a/charts/kyverno/templates/crds.yaml +++ b/charts/kyverno/templates/crds.yaml @@ -2829,7 +2829,7 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. The default value is set to "true", it must be set to "false" to disable the validation checks. + description: SchemaValidation skips validation checks for policies as well as patched resources. Optional. The default value is set to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -6351,7 +6351,7 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. The default value is set to "true", it must be set to "false" to disable the validation checks. + description: SchemaValidation skips validation checks for policies as well as patched resources. Optional. The default value is set to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -10500,7 +10500,7 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. The default value is set to "true", it must be set to "false" to disable the validation checks. + description: SchemaValidation skips validation checks for policies as well as patched resources. Optional. The default value is set to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -14022,7 +14022,7 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. The default value is set to "true", it must be set to "false" to disable the validation checks. + description: SchemaValidation skips validation checks for policies as well as patched resources. Optional. The default value is set to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit diff --git a/config/crds/kyverno.io_clusterpolicies.yaml b/config/crds/kyverno.io_clusterpolicies.yaml index 39e7aca4c0af..3957319dcf85 100644 --- a/config/crds/kyverno.io_clusterpolicies.yaml +++ b/config/crds/kyverno.io_clusterpolicies.yaml @@ -2878,9 +2878,9 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. - The default value is set to "true", it must be set to "false" to - disable the validation checks. + description: SchemaValidation skips validation checks for policies + as well as patched resources. Optional. The default value is set + to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -8499,9 +8499,9 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. - The default value is set to "true", it must be set to "false" to - disable the validation checks. + description: SchemaValidation skips validation checks for policies + as well as patched resources. Optional. The default value is set + to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit diff --git a/config/crds/kyverno.io_policies.yaml b/config/crds/kyverno.io_policies.yaml index f53d82d06d14..ec56fa157956 100644 --- a/config/crds/kyverno.io_policies.yaml +++ b/config/crds/kyverno.io_policies.yaml @@ -2879,9 +2879,9 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. - The default value is set to "true", it must be set to "false" to - disable the validation checks. + description: SchemaValidation skips validation checks for policies + as well as patched resources. Optional. The default value is set + to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -8502,9 +8502,9 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. - The default value is set to "true", it must be set to "false" to - disable the validation checks. + description: SchemaValidation skips validation checks for policies + as well as patched resources. Optional. The default value is set + to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit diff --git a/docs/user/crd/index.html b/docs/user/crd/index.html index f3fcf94f3b77..23d3b63a3c0e 100644 --- a/docs/user/crd/index.html +++ b/docs/user/crd/index.html @@ -205,7 +205,7 @@

ClusterPolicy (Optional) -

SchemaValidation skips policy validation checks. +

SchemaValidation skips validation checks for policies as well as patched resources. Optional. The default value is set to “true”, it must be set to “false” to disable the validation checks.

@@ -546,7 +546,7 @@

Policy (Optional) -

SchemaValidation skips policy validation checks. +

SchemaValidation skips validation checks for policies as well as patched resources. Optional. The default value is set to “true”, it must be set to “false” to disable the validation checks.

@@ -3476,7 +3476,7 @@

Spec (Optional) -

SchemaValidation skips policy validation checks. +

SchemaValidation skips validation checks for policies as well as patched resources. Optional. The default value is set to “true”, it must be set to “false” to disable the validation checks.

@@ -5093,7 +5093,7 @@

ClusterPolicy (Optional) -

SchemaValidation skips policy validation checks. +

SchemaValidation skips validation checks for policies as well as patched resources. Optional. The default value is set to “true”, it must be set to “false” to disable the validation checks.

@@ -5318,7 +5318,7 @@

Policy (Optional) -

SchemaValidation skips policy validation checks. +

SchemaValidation skips validation checks for policies as well as patched resources. Optional. The default value is set to “true”, it must be set to “false” to disable the validation checks.

@@ -6145,7 +6145,7 @@

Spec (Optional) -

SchemaValidation skips policy validation checks. +

SchemaValidation skips validation checks for policies as well as patched resources. Optional. The default value is set to “true”, it must be set to “false” to disable the validation checks.

diff --git a/pkg/webhooks/resource/mutation/mutation.go b/pkg/webhooks/resource/mutation/mutation.go index 0a079fe1410f..65a382bc6081 100644 --- a/pkg/webhooks/resource/mutation/mutation.go +++ b/pkg/webhooks/resource/mutation/mutation.go @@ -156,7 +156,7 @@ func (h *mutationHandler) applyMutation(request *admissionv1.AdmissionRequest, p return nil, nil, fmt.Errorf("failed to apply policy %s rules %v", policyContext.Policy.GetName(), engineResponse.GetFailedRules()) } - if engineResponse.PatchedResource.GetKind() != "*" { + if policyContext.Policy.ValidateSchema() && engineResponse.PatchedResource.GetKind() != "*" { err := h.openApiManager.ValidateResource(*engineResponse.PatchedResource.DeepCopy(), engineResponse.PatchedResource.GetAPIVersion(), engineResponse.PatchedResource.GetKind()) if err != nil { return nil, nil, errors.Wrapf(err, "failed to validate resource mutated by policy %s", policyContext.Policy.GetName()) From f52da91b7292c90283fc54fd06dbfe608e276fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Thu, 3 Nov 2022 09:05:23 +0000 Subject: [PATCH 06/55] fix: early return in policy validation (#5200) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: early return in policy validation Signed-off-by: Charles-Edouard Brétéché * fix test Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- pkg/policy/validate.go | 81 +++++++++++++++------------------ pkg/policy/validate_test.go | 12 ++--- pkg/utils/admission/utils.go | 12 +++++ pkg/webhooks/policy/handlers.go | 7 +-- 4 files changed, 55 insertions(+), 57 deletions(-) diff --git a/pkg/policy/validate.go b/pkg/policy/validate.go index 63b2758c6a43..678fea4e8680 100644 --- a/pkg/policy/validate.go +++ b/pkg/policy/validate.go @@ -25,7 +25,6 @@ import ( "github.com/kyverno/kyverno/pkg/utils" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" "github.com/pkg/errors" - admissionv1 "k8s.io/api/admission/v1" "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" @@ -110,7 +109,8 @@ func validateJSONPatch(patch string, ruleIdx int) error { } // Validate checks the policy and rules declarations for required configurations -func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock bool, openApiManager openapi.Manager) (*admissionv1.AdmissionResponse, error) { +func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock bool, openApiManager openapi.Manager) ([]string, error) { + var warnings []string namespaced := policy.IsNamespaced() spec := policy.GetSpec() background := spec.BackgroundProcessingEnabled() @@ -124,13 +124,13 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b err := ValidateVariables(policy, background) if err != nil { - return nil, err + return warnings, err } if onPolicyUpdate { err := ValidateOnPolicyUpdate(policy, onPolicyUpdate) if err != nil { - return nil, err + return warnings, err } } @@ -140,7 +140,7 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b // Get all the cluster type kind supported by cluster res, err := discovery.ServerPreferredResources(client.Discovery().DiscoveryInterface()) if err != nil { - return nil, err + return warnings, err } for _, resList := range res { for _, r := range resList.APIResources { @@ -152,13 +152,13 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b } if errs := policy.Validate(clusterResources); len(errs) != 0 { - return nil, errs.ToAggregate() + return warnings, errs.ToAggregate() } if !namespaced { err := validateNamespaces(spec, specPath.Child("validationFailureActionOverrides")) if err != nil { - return nil, err + return warnings, err } } @@ -168,34 +168,31 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b rulePath := rulesPath.Index(i) // check for forward slash if err := validateJSONPatchPathForForwardSlash(rule.Mutation.PatchesJSON6902); err != nil { - return nil, fmt.Errorf("path must begin with a forward slash: spec.rules[%d]: %s", i, err) + return warnings, fmt.Errorf("path must begin with a forward slash: spec.rules[%d]: %s", i, err) } if err := validateJSONPatch(rule.Mutation.PatchesJSON6902, i); err != nil { - return nil, fmt.Errorf("%s", err) + return warnings, fmt.Errorf("%s", err) } if jsonPatchOnPod(rule) { msg := "Pods managed by workload controllers should not be directly mutated using policies. " + "Use the autogen feature or write policies that match Pod controllers." logging.V(1).Info(msg) - return &admissionv1.AdmissionResponse{ - Allowed: true, - Warnings: []string{msg}, - }, nil + warnings = append(warnings, msg) } // validate resource description if path, err := validateResources(rulePath, rule); err != nil { - return nil, fmt.Errorf("path: spec.rules[%d].%s: %v", i, path, err) + return warnings, fmt.Errorf("path: spec.rules[%d].%s: %v", i, path, err) } err := validateElementInForEach(rule) if err != nil { - return nil, err + return warnings, err } if err := validateRuleContext(rule); err != nil { - return nil, fmt.Errorf("path: spec.rules[%d]: %v", i, err) + return warnings, fmt.Errorf("path: spec.rules[%d]: %v", i, err) } // If a rule's match block does not match any kind, @@ -203,25 +200,25 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b if len(rule.MatchResources.Any) > 0 { for _, rmr := range rule.MatchResources.Any { if len(rmr.Kinds) == 0 { - return nil, validateMatchKindHelper(rule) + return warnings, validateMatchKindHelper(rule) } } } else if len(rule.MatchResources.All) > 0 { for _, rmr := range rule.MatchResources.All { if len(rmr.Kinds) == 0 { - return nil, validateMatchKindHelper(rule) + return warnings, validateMatchKindHelper(rule) } } } else { if len(rule.MatchResources.Kinds) == 0 { - return nil, validateMatchKindHelper(rule) + return warnings, validateMatchKindHelper(rule) } } // validate Cluster Resources in namespaced policy // For namespaced policy, ClusterResource type field and values are not allowed in match and exclude if namespaced { - return nil, checkClusterResourceInMatchAndExclude(rule, clusterResources, mock, res) + return warnings, checkClusterResourceInMatchAndExclude(rule, clusterResources, mock, res) } // validate rule actions @@ -229,26 +226,26 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b // - Validate // - Generate if err := validateActions(i, &rules[i], client, mock); err != nil { - return nil, err + return warnings, err } if utils.ContainsString(rule.MatchResources.Kinds, "*") && spec.BackgroundProcessingEnabled() { - return nil, fmt.Errorf("wildcard policy not allowed in background mode. Set spec.background=false to disable background mode for this policy rule ") + return warnings, fmt.Errorf("wildcard policy not allowed in background mode. Set spec.background=false to disable background mode for this policy rule ") } if (utils.ContainsString(rule.MatchResources.Kinds, "*") && len(rule.MatchResources.Kinds) > 1) || (utils.ContainsString(rule.ExcludeResources.Kinds, "*") && len(rule.ExcludeResources.Kinds) > 1) { - return nil, fmt.Errorf("wildard policy can not deal more than one kind") + return warnings, fmt.Errorf("wildard policy can not deal more than one kind") } if utils.ContainsString(rule.MatchResources.Kinds, "*") || utils.ContainsString(rule.ExcludeResources.Kinds, "*") { if rule.HasGenerate() || rule.HasVerifyImages() || rule.Validation.ForEachValidation != nil { - return nil, fmt.Errorf("wildcard policy does not support rule type") + return warnings, fmt.Errorf("wildcard policy does not support rule type") } if rule.HasValidate() { if rule.Validation.GetPattern() != nil || rule.Validation.GetAnyPattern() != nil { if !ruleOnlyDealsWithResourceMetaData(rule) { - return nil, fmt.Errorf("policy can only deal with the metadata field of the resource if" + + return warnings, fmt.Errorf("policy can only deal with the metadata field of the resource if" + " the rule does not match any kind") } } @@ -260,7 +257,7 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b for _, condition := range typedConditions { key := condition.GetKey() if !strings.Contains(key.(string), "request.object.metadata.") && (!wildCardAllowedVariables.MatchString(key.(string)) || strings.Contains(key.(string), "request.object.spec")) { - return nil, fmt.Errorf("policy can only deal with the metadata field of the resource if" + + return warnings, fmt.Errorf("policy can only deal with the metadata field of the resource if" + " the rule does not match any kind") } } @@ -270,7 +267,7 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b if rule.HasMutate() { if !ruleOnlyDealsWithResourceMetaData(rule) { - return nil, fmt.Errorf("policy can only deal with the metadata field of the resource if" + + return warnings, fmt.Errorf("policy can only deal with the metadata field of the resource if" + " the rule does not match any kind") } } @@ -283,7 +280,7 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b } if len(errs) != 0 { - return nil, errs.ToAggregate() + return warnings, errs.ToAggregate() } } @@ -293,7 +290,7 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b errs = append(errs, i.Validate(verifyImagePath.Index(index))...) } if len(errs) != 0 { - return nil, errs.ToAggregate() + return warnings, errs.ToAggregate() } } @@ -303,11 +300,7 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b msg := "Policies that match Pods apply to all Pods including those created and managed by controllers " + "excluded from autogen. Use preconditions to exclude the Pods managed by controllers which are " + "excluded from autogen. Refer to https://kyverno.io/docs/writing-policies/autogen/ for details." - - return &admissionv1.AdmissionResponse{ - Allowed: true, - Warnings: []string{msg}, - }, nil + warnings = append(warnings, msg) } // Validate Kind with match resource kinds @@ -317,7 +310,7 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b if !utils.ContainsString(value.ResourceDescription.Kinds, "*") { err := validateKinds(value.ResourceDescription.Kinds, mock, client, policy) if err != nil { - return nil, errors.Wrapf(err, "the kind defined in the any match resource is invalid") + return warnings, errors.Wrapf(err, "the kind defined in the any match resource is invalid") } } } @@ -325,7 +318,7 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b if !utils.ContainsString(value.ResourceDescription.Kinds, "*") { err := validateKinds(value.ResourceDescription.Kinds, mock, client, policy) if err != nil { - return nil, errors.Wrapf(err, "the kind defined in the all match resource is invalid") + return warnings, errors.Wrapf(err, "the kind defined in the all match resource is invalid") } } } @@ -333,7 +326,7 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b if !utils.ContainsString(value.ResourceDescription.Kinds, "*") { err := validateKinds(value.ResourceDescription.Kinds, mock, client, policy) if err != nil { - return nil, errors.Wrapf(err, "the kind defined in the any exclude resource is invalid") + return warnings, errors.Wrapf(err, "the kind defined in the any exclude resource is invalid") } } } @@ -341,24 +334,24 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b if !utils.ContainsString(value.ResourceDescription.Kinds, "*") { err := validateKinds(value.ResourceDescription.Kinds, mock, client, policy) if err != nil { - return nil, errors.Wrapf(err, "the kind defined in the all exclude resource is invalid") + return warnings, errors.Wrapf(err, "the kind defined in the all exclude resource is invalid") } } } if !utils.ContainsString(rule.MatchResources.Kinds, "*") { err := validateKinds(rule.MatchResources.Kinds, mock, client, policy) if err != nil { - return nil, errors.Wrapf(err, "match resource kind is invalid") + return warnings, errors.Wrapf(err, "match resource kind is invalid") } err = validateKinds(rule.ExcludeResources.Kinds, mock, client, policy) if err != nil { - return nil, errors.Wrapf(err, "exclude resource kind is invalid") + return warnings, errors.Wrapf(err, "exclude resource kind is invalid") } } // Validate string values in labels if !isLabelAndAnnotationsString(rule) { - return nil, fmt.Errorf("labels and annotations supports only string values, \"use double quotes around the non string values\"") + return warnings, fmt.Errorf("labels and annotations supports only string values, \"use double quotes around the non string values\"") } // add label to source mentioned in policy @@ -402,13 +395,13 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b } } - if spec.SchemaValidation == nil || *spec.SchemaValidation { + if !mock && (spec.SchemaValidation == nil || *spec.SchemaValidation) { if err := openApiManager.ValidatePolicyMutation(policy); err != nil { - return nil, err + return warnings, err } } - return nil, nil + return warnings, nil } func ValidateVariables(p kyvernov1.PolicyInterface, backgroundMode bool) error { diff --git a/pkg/policy/validate_test.go b/pkg/policy/validate_test.go index 667536002b44..4d74c6e83166 100644 --- a/pkg/policy/validate_test.go +++ b/pkg/policy/validate_test.go @@ -1533,10 +1533,8 @@ func Test_PodControllerAutoGenExclusion_Not_All_Controllers_Policy(t *testing.T) assert.NilError(t, err) openApiManager, _ := openapi.NewManager() - res, err := Validate(policy, nil, true, openApiManager) - if res != nil { - assert.Assert(t, res.Warnings != nil) - } + warnings, err := Validate(policy, nil, true, openApiManager) + assert.Assert(t, warnings != nil) assert.NilError(t, err) } @@ -1592,10 +1590,8 @@ func Test_PodControllerAutoGenExclusion_None_Policy(t *testing.T) { assert.NilError(t, err) openApiManager, _ := openapi.NewManager() - res, err := Validate(policy, nil, true, openApiManager) - if res != nil { - assert.Assert(t, res.Warnings != nil) - } + warnings, err := Validate(policy, nil, true, openApiManager) + assert.Assert(t, warnings == nil) assert.NilError(t, err) } diff --git a/pkg/utils/admission/utils.go b/pkg/utils/admission/utils.go index d93e7a6e364f..a4ac9d62bd64 100644 --- a/pkg/utils/admission/utils.go +++ b/pkg/utils/admission/utils.go @@ -111,3 +111,15 @@ func GetResourceName(request *admissionv1.AdmissionRequest) string { } return resourceName } + +func ValidationResponse(err error, warnings ...string) *admissionv1.AdmissionResponse { + response := Response(err == nil) + if err != nil { + response.Result = &metav1.Status{ + Status: metav1.StatusFailure, + Message: err.Error(), + } + } + response.Warnings = warnings + return response +} diff --git a/pkg/webhooks/policy/handlers.go b/pkg/webhooks/policy/handlers.go index dc991d66928f..dfbfc3291587 100644 --- a/pkg/webhooks/policy/handlers.go +++ b/pkg/webhooks/policy/handlers.go @@ -35,15 +35,12 @@ func (h *handlers) Validate(logger logr.Logger, request *admissionv1.AdmissionRe logger.Error(err, "failed to unmarshal policies from admission request") return admissionutils.ResponseWithMessage(true, fmt.Sprintf("failed to validate policy, check kyverno controller logs for details: %v", err)) } - response, err := policyvalidate.Validate(policy, h.client, false, h.openApiManager) + warnings, err := policyvalidate.Validate(policy, h.client, false, h.openApiManager) if err != nil { logger.Error(err, "policy validation errors") return admissionutils.ResponseWithMessage(false, err.Error()) } - if response != nil && len(response.Warnings) != 0 { - return response - } - return admissionutils.Response(true) + return admissionutils.ValidationResponse(err, warnings...) } func (h *handlers) Mutate(logger logr.Logger, request *admissionv1.AdmissionRequest, _ time.Time) *admissionv1.AdmissionResponse { From a64475a6db506430bf46b0a12c4b1d8403c8a7c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Thu, 3 Nov 2022 10:19:38 +0000 Subject: [PATCH 07/55] refactor: health check system (#5176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: health check system Signed-off-by: Charles-Edouard Brétéché * filter Signed-off-by: Charles-Edouard Brétéché * fix Signed-off-by: Charles-Edouard Brétéché * fix Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché Co-authored-by: Vyankatesh Kudtarkar --- cmd/kyverno/main.go | 1 - pkg/controllers/webhook/controller.go | 52 +++++++++++++++------------ pkg/utils/runtime/utils.go | 39 ++------------------ pkg/webhooks/handlers/admission.go | 12 ++++++- pkg/webhooks/server.go | 1 + 5 files changed, 44 insertions(+), 61 deletions(-) diff --git a/cmd/kyverno/main.go b/cmd/kyverno/main.go index 5e0c5622629e..32318a5a41eb 100644 --- a/cmd/kyverno/main.go +++ b/cmd/kyverno/main.go @@ -621,7 +621,6 @@ func main() { runtime := runtimeutils.NewRuntime( logger.WithName("runtime-checks"), serverIP, - kubeKyvernoInformer.Coordination().V1().Leases(), kubeKyvernoInformer.Apps().V1().Deployments(), certRenewer, ) diff --git a/pkg/controllers/webhook/controller.go b/pkg/controllers/webhook/controller.go index 43a1cc5a2c79..6eafe96cc052 100644 --- a/pkg/controllers/webhook/controller.go +++ b/pkg/controllers/webhook/controller.go @@ -44,10 +44,10 @@ const ( ControllerName = "webhook-controller" DefaultWebhookTimeout = 10 AnnotationLastRequestTime = "kyverno.io/last-request-time" - IdleDeadline = tickerInterval * 5 + IdleDeadline = tickerInterval * 10 maxRetries = 10 managedByLabel = "webhook.kyverno.io/managed-by" - tickerInterval = 30 * time.Second + tickerInterval = 10 * time.Second ) var ( @@ -74,7 +74,7 @@ type controller struct { secretClient controllerutils.GetClient[*corev1.Secret] mwcClient controllerutils.ObjectClient[*admissionregistrationv1.MutatingWebhookConfiguration] vwcClient controllerutils.ObjectClient[*admissionregistrationv1.ValidatingWebhookConfiguration] - leaseClient controllerutils.UpdateClient[*coordinationv1.Lease] + leaseClient controllerutils.ObjectClient[*coordinationv1.Lease] kyvernoClient versioned.Interface // listers @@ -106,7 +106,7 @@ func NewController( secretClient controllerutils.GetClient[*corev1.Secret], mwcClient controllerutils.ObjectClient[*admissionregistrationv1.MutatingWebhookConfiguration], vwcClient controllerutils.ObjectClient[*admissionregistrationv1.ValidatingWebhookConfiguration], - leaseClient controllerutils.UpdateClient[*coordinationv1.Lease], + leaseClient controllerutils.ObjectClient[*coordinationv1.Lease], kyvernoClient versioned.Interface, mwcInformer admissionregistrationv1informers.MutatingWebhookConfigurationInformer, vwcInformer admissionregistrationv1informers.ValidatingWebhookConfigurationInformer, @@ -216,24 +216,32 @@ func (c *controller) watchdog(ctx context.Context, logger logr.Logger) { case <-ticker.C: lease, err := c.getLease() if err != nil { - logger.Error(err, "failed to get lease") + if apierrors.IsNotFound(err) { + _, err = c.leaseClient.Create(ctx, &coordinationv1.Lease{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kyverno-health", + Namespace: config.KyvernoNamespace(), + Labels: map[string]string{ + "app.kubernetes.io/name": kyvernov1.ValueKyvernoApp, + }, + Annotations: map[string]string{ + AnnotationLastRequestTime: time.Now().Format(time.RFC3339), + }, + }, + }, metav1.CreateOptions{}) + if err != nil { + logger.Error(err, "failed to create lease") + } + } else { + logger.Error(err, "failed to get lease") + } } else { - if _, err := controllerutils.Update( - ctx, - lease, - c.leaseClient, - func(lease *coordinationv1.Lease) error { - if lease.Annotations == nil { - lease.Annotations = map[string]string{} - } - lease.Annotations[AnnotationLastRequestTime] = time.Now().Format(time.RFC3339) - if lease.Labels == nil { - lease.Labels = map[string]string{} - } - lease.Labels["app.kubernetes.io/name"] = kyvernov1.ValueKyvernoApp - return nil - }, - ); err != nil { + lease := lease.DeepCopy() + lease.Labels = map[string]string{ + "app.kubernetes.io/name": kyvernov1.ValueKyvernoApp, + } + _, err = c.leaseClient.Update(ctx, lease, metav1.UpdateOptions{}) + if err != nil { logger.Error(err, "failed to update lease") } } @@ -811,7 +819,7 @@ func (c *controller) getAllPolicies() ([]kyvernov1.PolicyInterface, error) { } func (c *controller) getLease() (*coordinationv1.Lease, error) { - return c.leaseLister.Leases(config.KyvernoNamespace()).Get("kyverno") + return c.leaseLister.Leases(config.KyvernoNamespace()).Get("kyverno-health") } // mergeWebhook merges the matching kinds of the policy to webhook.rule diff --git a/pkg/utils/runtime/utils.go b/pkg/utils/runtime/utils.go index 82f5ef676bc0..9ba1904d24d4 100644 --- a/pkg/utils/runtime/utils.go +++ b/pkg/utils/runtime/utils.go @@ -1,24 +1,13 @@ package runtime import ( - "time" - "github.com/go-logr/logr" "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/tls" appsv1 "k8s.io/api/apps/v1" - coordinationv1 "k8s.io/api/coordination/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" appsv1informers "k8s.io/client-go/informers/apps/v1" - coordinationv1informers "k8s.io/client-go/informers/coordination/v1" appsv1listers "k8s.io/client-go/listers/apps/v1" - coordinationv1listers "k8s.io/client-go/listers/coordination/v1" -) - -const ( - AnnotationLastRequestTime = "kyverno.io/last-request-time" - IdleDeadline = tickerInterval * 5 - tickerInterval = 30 * time.Second ) type Runtime interface { @@ -31,7 +20,6 @@ type Runtime interface { type runtime struct { serverIP string - leaseLister coordinationv1listers.LeaseLister deploymentLister appsv1listers.DeploymentLister certValidator tls.CertValidator logger logr.Logger @@ -40,14 +28,12 @@ type runtime struct { func NewRuntime( logger logr.Logger, serverIP string, - leaseInformer coordinationv1informers.LeaseInformer, deploymentInformer appsv1informers.DeploymentInformer, certValidator tls.CertValidator, ) Runtime { return &runtime{ logger: logger, serverIP: serverIP, - leaseLister: leaseInformer.Lister(), deploymentLister: deploymentInformer.Lister(), certValidator: certValidator, } @@ -58,11 +44,11 @@ func (c *runtime) IsDebug() bool { } func (c *runtime) IsLive() bool { - return c.check() + return true } func (c *runtime) IsReady() bool { - return c.check() && c.validateCertificates() + return c.validateCertificates() } func (c *runtime) IsRollingUpdate() bool { @@ -103,31 +89,10 @@ func (c *runtime) IsGoingDown() bool { return false } -func (c *runtime) getLease() (*coordinationv1.Lease, error) { - return c.leaseLister.Leases(config.KyvernoNamespace()).Get("kyverno") -} - func (c *runtime) getDeployment() (*appsv1.Deployment, error) { return c.deploymentLister.Deployments(config.KyvernoNamespace()).Get(config.KyvernoDeploymentName()) } -func (c *runtime) check() bool { - lease, err := c.getLease() - if err != nil { - c.logger.Error(err, "failed to get lease") - return false - } - annotations := lease.GetAnnotations() - if annotations == nil { - return false - } - annTime, err := time.Parse(time.RFC3339, annotations[AnnotationLastRequestTime]) - if err != nil { - return false - } - return time.Now().Before(annTime.Add(IdleDeadline)) -} - func (c *runtime) validateCertificates() bool { validity, err := c.certValidator.ValidateCert() if err != nil { diff --git a/pkg/webhooks/handlers/admission.go b/pkg/webhooks/handlers/admission.go index eded679cbe80..ced2c973b0d9 100644 --- a/pkg/webhooks/handlers/admission.go +++ b/pkg/webhooks/handlers/admission.go @@ -11,6 +11,7 @@ import ( "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/tracing" admissionutils "github.com/kyverno/kyverno/pkg/utils/admission" + jsonutils "github.com/kyverno/kyverno/pkg/utils/json" "go.opentelemetry.io/otel/attribute" admissionv1 "k8s.io/api/admission/v1" ) @@ -101,6 +102,15 @@ func Filter(c config.Configuration, inner AdmissionHandler) AdmissionHandler { func Verify() AdmissionHandler { return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { - return admissionutils.Response(true) + if request.Name != "kyverno-health" || request.Namespace != config.KyvernoNamespace() { + return admissionutils.ResponseSuccess() + } + patch := jsonutils.NewPatchOperation("/metadata/annotations/"+"kyverno.io~1last-request-time", "replace", time.Now().Format(time.RFC3339)) + bytes, err := patch.ToPatchBytes() + if err != nil { + logger.Error(err, "failed to build patch bytes") + return admissionutils.ResponseFailure(err.Error()) + } + return admissionutils.ResponseSuccessWithPatch(bytes) } } diff --git a/pkg/webhooks/server.go b/pkg/webhooks/server.go index 29bfd362b50c..3871246db2c6 100644 --- a/pkg/webhooks/server.go +++ b/pkg/webhooks/server.go @@ -239,6 +239,7 @@ func (s *server) cleanup(ctx context.Context) { } } deleteLease("kyvernopre-lock") + deleteLease("kyverno-health") deleteVwc(config.ValidatingWebhookConfigurationName) deleteVwc(config.PolicyValidatingWebhookConfigurationName) deleteMwc(config.MutatingWebhookConfigurationName) From b3c5a9c74165d573aab9928dd8ac1187e8d8fc3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Thu, 3 Nov 2022 11:16:07 +0000 Subject: [PATCH 08/55] chore: server side apply in argo lab (#5209) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- scripts/labs/argocd/kind-argo.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/labs/argocd/kind-argo.sh b/scripts/labs/argocd/kind-argo.sh index 00f9a4543903..0933f212dca4 100755 --- a/scripts/labs/argocd/kind-argo.sh +++ b/scripts/labs/argocd/kind-argo.sh @@ -122,7 +122,7 @@ spec: source: chart: metrics-server repoURL: https://charts.bitnami.com/bitnami - targetRevision: 6.2.1 + targetRevision: 6.2.2 helm: values: | extraArgs: @@ -151,7 +151,7 @@ spec: source: chart: kube-prometheus-stack repoURL: https://prometheus-community.github.io/helm-charts - targetRevision: 41.4.1 + targetRevision: 41.7.3 helm: values: | kubeEtcd: @@ -207,7 +207,7 @@ spec: selfHeal: true syncOptions: - CreateNamespace=true - - Replace=true + - ServerSideApply=true EOF # CREATE KYVERNO APP @@ -226,7 +226,7 @@ spec: source: chart: kyverno repoURL: https://kyverno.github.io/kyverno - targetRevision: 2.6.0 + targetRevision: 2.6.1 helm: values: | serviceMonitor: @@ -237,7 +237,7 @@ spec: selfHeal: true syncOptions: - CreateNamespace=true - - Replace=true + - ServerSideApply=true EOF # CREATE KYVERNO-POLICIES APP @@ -256,7 +256,7 @@ spec: source: chart: kyverno-policies repoURL: https://kyverno.github.io/kyverno - targetRevision: 2.6.0 + targetRevision: 2.6.1 syncPolicy: automated: prune: true @@ -281,7 +281,7 @@ spec: source: chart: policy-reporter repoURL: https://kyverno.github.io/policy-reporter - targetRevision: 2.13.1 + targetRevision: 2.13.4 helm: values: | ui: From da84b777bc8b872424903095e56248e28b6f831e Mon Sep 17 00:00:00 2001 From: shuting Date: Fri, 4 Nov 2022 14:31:23 +0800 Subject: [PATCH 09/55] fix: too much information for the Policy Rule Execution Latency metric (#5208) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove general_rule_latency_type Signed-off-by: ShutingZhao * remove resource_request_operation Signed-off-by: ShutingZhao * remove resource_namespace Signed-off-by: ShutingZhao * remove resource_kind Signed-off-by: ShutingZhao * fix linter Signed-off-by: ShutingZhao Signed-off-by: ShutingZhao Co-authored-by: Charles-Edouard Brétéché --- pkg/metrics/common_types.go | 1 + pkg/metrics/metrics.go | 9 ++------- .../policyExecutionDuration.go | 17 +++++------------ pkg/policy/existing.go | 2 +- pkg/webhooks/utils/metrics.go | 6 +++--- 5 files changed, 12 insertions(+), 23 deletions(-) diff --git a/pkg/metrics/common_types.go b/pkg/metrics/common_types.go index 975b66b9873d..7e725e271028 100644 --- a/pkg/metrics/common_types.go +++ b/pkg/metrics/common_types.go @@ -27,6 +27,7 @@ const ( Validate RuleType = "validate" Mutate RuleType = "mutate" Generate RuleType = "generate" + ImageVerify RuleType = "imageVerify" EmptyRuleType RuleType = "-" ) diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 304ad65cd304..7a29c3ba4faf 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -51,7 +51,7 @@ type MetricsConfigManager interface { RecordPolicyChanges(policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, policyChangeType string) RecordPolicyRuleInfo(policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, ruleName string, ruleType RuleType, status string, metricValue float64) RecordAdmissionRequests(resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation) - RecordPolicyExecutionDuration(policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation, ruleName string, ruleResult RuleResult, ruleType RuleType, ruleExecutionCause RuleExecutionCause, generalRuleLatencyType string, ruleExecutionLatency float64) + RecordPolicyExecutionDuration(policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, ruleName string, ruleResult RuleResult, ruleType RuleType, ruleExecutionCause RuleExecutionCause, ruleExecutionLatency float64) RecordAdmissionReviewDuration(resourceKind string, resourceNamespace string, resourceRequestOperation string, admissionRequestLatency float64) RecordClientQueries(clientQueryOperation ClientQueryOperation, clientType ClientType, resourceKind string, resourceNamespace string) } @@ -308,8 +308,7 @@ func (m *MetricsConfig) RecordAdmissionRequests(resourceKind string, resourceNam } func (m *MetricsConfig) RecordPolicyExecutionDuration(policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, - resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation, ruleName string, ruleResult RuleResult, ruleType RuleType, - ruleExecutionCause RuleExecutionCause, generalRuleLatencyType string, ruleExecutionLatency float64, + ruleName string, ruleResult RuleResult, ruleType RuleType, ruleExecutionCause RuleExecutionCause, ruleExecutionLatency float64, ) { ctx := context.Background() @@ -319,14 +318,10 @@ func (m *MetricsConfig) RecordPolicyExecutionDuration(policyValidationMode Polic attribute.String("policy_background_mode", string(policyBackgroundMode)), attribute.String("policy_namespace", policyNamespace), attribute.String("policy_name", policyName), - attribute.String("resource_kind", resourceKind), - attribute.String("resource_namespace", resourceNamespace), - attribute.String("resource_request_operation", string(resourceRequestOperation)), attribute.String("rule_name", ruleName), attribute.String("rule_result", string(ruleResult)), attribute.String("rule_type", string(ruleType)), attribute.String("rule_execution_cause", string(ruleExecutionCause)), - attribute.String("general_rule_latency_type", generalRuleLatencyType), } m.policyExecutionDurationMetric.Record(ctx, ruleExecutionLatency, commonLabels...) diff --git a/pkg/metrics/policyexecutionduration/policyExecutionDuration.go b/pkg/metrics/policyexecutionduration/policyExecutionDuration.go index 5cca7a066f87..7b2d480cee5f 100644 --- a/pkg/metrics/policyexecutionduration/policyExecutionDuration.go +++ b/pkg/metrics/policyexecutionduration/policyExecutionDuration.go @@ -15,21 +15,17 @@ func registerPolicyExecutionDurationMetric( policyType metrics.PolicyType, policyBackgroundMode metrics.PolicyBackgroundMode, policyNamespace, policyName string, - resourceKind, resourceNamespace string, - resourceRequestOperation metrics.ResourceRequestOperation, + resourceNamespace string, ruleName string, ruleResult metrics.RuleResult, ruleType metrics.RuleType, ruleExecutionCause metrics.RuleExecutionCause, - generateRuleLatencyType string, ruleExecutionLatency float64, ) error { if policyType == metrics.Cluster { policyNamespace = "-" } - if ruleType != metrics.Generate || generateRuleLatencyType == "" { - generateRuleLatencyType = "-" - } + includeNamespaces, excludeNamespaces := m.Config.GetIncludeNamespaces(), m.Config.GetExcludeNamespaces() if (resourceNamespace != "" && resourceNamespace != "-") && utils.ContainsString(excludeNamespaces, resourceNamespace) { m.Log.V(2).Info(fmt.Sprintf("Skipping the registration of kyverno_policy_execution_duration_seconds metric as the operation belongs to the namespace '%s' which is one of 'namespaces.exclude' %+v in values.yaml", resourceNamespace, excludeNamespaces)) @@ -40,20 +36,19 @@ func registerPolicyExecutionDurationMetric( return nil } - m.RecordPolicyExecutionDuration(policyValidationMode, policyType, policyBackgroundMode, policyNamespace, policyName, resourceKind, resourceNamespace, resourceRequestOperation, ruleName, ruleResult, ruleType, ruleExecutionCause, generateRuleLatencyType, ruleExecutionLatency) + m.RecordPolicyExecutionDuration(policyValidationMode, policyType, policyBackgroundMode, policyNamespace, policyName, ruleName, ruleResult, ruleType, ruleExecutionCause, ruleExecutionLatency) return nil } // policy - policy related data // engineResponse - resource and rule related data -func ProcessEngineResponse(m *metrics.MetricsConfig, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse, executionCause metrics.RuleExecutionCause, generateRuleLatencyType string, resourceRequestOperation metrics.ResourceRequestOperation) error { +func ProcessEngineResponse(m *metrics.MetricsConfig, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse, executionCause metrics.RuleExecutionCause, resourceRequestOperation metrics.ResourceRequestOperation) error { name, namespace, policyType, backgroundMode, validationMode, err := metrics.GetPolicyInfos(policy) if err != nil { return err } resourceSpec := engineResponse.PolicyResponse.Resource - resourceKind := resourceSpec.Kind resourceNamespace := resourceSpec.Namespace ruleResponses := engineResponse.PolicyResponse.Rules for _, rule := range ruleResponses { @@ -81,13 +76,11 @@ func ProcessEngineResponse(m *metrics.MetricsConfig, policy kyvernov1.PolicyInte policyType, backgroundMode, namespace, name, - resourceKind, resourceNamespace, - resourceRequestOperation, + resourceNamespace, ruleName, ruleResult, ruleType, executionCause, - generateRuleLatencyType, ruleExecutionLatencyInSeconds, ); err != nil { return err diff --git a/pkg/policy/existing.go b/pkg/policy/existing.go index 5d12d71dc34d..c673b1fe9eda 100644 --- a/pkg/policy/existing.go +++ b/pkg/policy/existing.go @@ -68,7 +68,7 @@ func (pc *PolicyController) registerPolicyResultsMetricValidation(logger logr.Lo } func (pc *PolicyController) registerPolicyExecutionDurationMetricValidate(logger logr.Logger, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse) { - if err := policyExecutionDuration.ProcessEngineResponse(pc.metricsConfig, policy, engineResponse, metrics.BackgroundScan, "", metrics.ResourceCreated); err != nil { + if err := policyExecutionDuration.ProcessEngineResponse(pc.metricsConfig, policy, engineResponse, metrics.BackgroundScan, metrics.ResourceCreated); err != nil { logger.Error(err, "error occurred while registering kyverno_policy_execution_duration_seconds metrics for the above policy", "name", policy.GetName()) } } diff --git a/pkg/webhooks/utils/metrics.go b/pkg/webhooks/utils/metrics.go index 7f19b4122579..9d2d36beb28f 100644 --- a/pkg/webhooks/utils/metrics.go +++ b/pkg/webhooks/utils/metrics.go @@ -92,18 +92,18 @@ func RegisterPolicyResultsMetricGeneration(logger logr.Logger, metricsConfig *me func RegisterPolicyExecutionDurationMetricMutate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse) { registerMetric(logger, "kyverno_policy_execution_duration_seconds", requestOperation, func(op metrics.ResourceRequestOperation) error { - return policyExecutionDuration.ProcessEngineResponse(metricsConfig, policy, engineResponse, metrics.AdmissionRequest, "", op) + return policyExecutionDuration.ProcessEngineResponse(metricsConfig, policy, engineResponse, metrics.AdmissionRequest, op) }) } func RegisterPolicyExecutionDurationMetricValidate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse) { registerMetric(logger, "kyverno_policy_execution_duration_seconds", requestOperation, func(op metrics.ResourceRequestOperation) error { - return policyExecutionDuration.ProcessEngineResponse(metricsConfig, policy, engineResponse, metrics.AdmissionRequest, "", op) + return policyExecutionDuration.ProcessEngineResponse(metricsConfig, policy, engineResponse, metrics.AdmissionRequest, op) }) } func RegisterPolicyExecutionDurationMetricGenerate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse) { registerMetric(logger, "kyverno_policy_execution_duration_seconds", requestOperation, func(op metrics.ResourceRequestOperation) error { - return policyExecutionDuration.ProcessEngineResponse(metricsConfig, policy, engineResponse, metrics.AdmissionRequest, "", op) + return policyExecutionDuration.ProcessEngineResponse(metricsConfig, policy, engineResponse, metrics.AdmissionRequest, op) }) } From 786e595c06143c92e8481a9aa2880e15e8fe4833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Fri, 4 Nov 2022 08:55:41 +0100 Subject: [PATCH 10/55] feat: add policy label to policy reports (#5198) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- .../report/aggregate/controller.go | 64 +++++++++++++------ 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/pkg/controllers/report/aggregate/controller.go b/pkg/controllers/report/aggregate/controller.go index 8c5e96c4d2a0..2591708ad48e 100644 --- a/pkg/controllers/report/aggregate/controller.go +++ b/pkg/controllers/report/aggregate/controller.go @@ -60,6 +60,11 @@ type controller struct { chunkSize int } +type policyMapEntry struct { + policy kyvernov1.PolicyInterface + rules sets.String +} + func keyFunc(obj metav1.Object) cache.ExplicitKey { return cache.ExplicitKey(obj.GetNamespace()) } @@ -104,7 +109,7 @@ func (c *controller) Run(ctx context.Context, workers int) { controllerutils.Run(ctx, logger, ControllerName, time.Second, c.queue, workers, maxRetries, c.reconcile) } -func (c *controller) mergeAdmissionReports(ctx context.Context, namespace string, policyMap map[string]sets.String, accumulator map[string]policyreportv1alpha2.PolicyReportResult) error { +func (c *controller) mergeAdmissionReports(ctx context.Context, namespace string, policyMap map[string]policyMapEntry, accumulator map[string]policyreportv1alpha2.PolicyReportResult) error { if namespace == "" { next := "" for { @@ -144,7 +149,7 @@ func (c *controller) mergeAdmissionReports(ctx context.Context, namespace string } } -func (c *controller) mergeBackgroundScanReports(ctx context.Context, namespace string, policyMap map[string]sets.String, accumulator map[string]policyreportv1alpha2.PolicyReportResult) error { +func (c *controller) mergeBackgroundScanReports(ctx context.Context, namespace string, policyMap map[string]policyMapEntry, accumulator map[string]policyreportv1alpha2.PolicyReportResult) error { if namespace == "" { next := "" for { @@ -184,11 +189,26 @@ func (c *controller) mergeBackgroundScanReports(ctx context.Context, namespace s } } -func (c *controller) reconcileReport(ctx context.Context, report kyvernov1alpha2.ReportInterface, namespace, name string, results ...policyreportv1alpha2.PolicyReportResult) (kyvernov1alpha2.ReportInterface, error) { +func (c *controller) reconcileReport(ctx context.Context, policyMap map[string]policyMapEntry, report kyvernov1alpha2.ReportInterface, namespace, name string, results ...policyreportv1alpha2.PolicyReportResult) (kyvernov1alpha2.ReportInterface, error) { if report == nil { - return reportutils.CreateReport(ctx, reportutils.NewPolicyReport(namespace, name, results...), c.client) + report = reportutils.NewPolicyReport(namespace, name, results...) + for _, result := range results { + policy := policyMap[result.Policy] + if policy.policy != nil { + reportutils.SetPolicyLabel(report, policy.policy) + } + } + return reportutils.CreateReport(ctx, report, c.client) } after := reportutils.DeepCopy(report) + after.SetLabels(nil) + reportutils.SetManagedByKyvernoLabel(after) + for _, result := range results { + policy := policyMap[result.Policy] + if policy.policy != nil { + reportutils.SetPolicyLabel(after, policy.policy) + } + } reportutils.SetResults(after, results...) if reflect.DeepEqual(report, after) { return after, nil @@ -212,7 +232,7 @@ func (c *controller) cleanReports(ctx context.Context, actual map[string]kyverno return nil } -func mergeReports(policyMap map[string]sets.String, accumulator map[string]policyreportv1alpha2.PolicyReportResult, reports ...kyvernov1alpha2.ReportInterface) { +func mergeReports(policyMap map[string]policyMapEntry, accumulator map[string]policyreportv1alpha2.PolicyReportResult, reports ...kyvernov1alpha2.ReportInterface) { for _, report := range reports { if len(report.GetOwnerReferences()) == 1 { ownerRef := report.GetOwnerReferences()[0] @@ -225,7 +245,7 @@ func mergeReports(policyMap map[string]sets.String, accumulator map[string]polic }} for _, result := range report.GetResults() { currentPolicy := policyMap[result.Policy] - if currentPolicy != nil && currentPolicy.Has(result.Rule) { + if currentPolicy.rules != nil && currentPolicy.rules.Has(result.Rule) { key := result.Policy + "/" + result.Rule + "/" + string(ownerRef.UID) result.Resources = objectRefs if rule, exists := accumulator[key]; !exists { @@ -239,8 +259,8 @@ func mergeReports(policyMap map[string]sets.String, accumulator map[string]polic } } -func (c *controller) createPolicyMap() (map[string]sets.String, error) { - results := map[string]sets.String{} +func (c *controller) createPolicyMap() (map[string]policyMapEntry, error) { + results := map[string]policyMapEntry{} cpols, err := c.cpolLister.List(labels.Everything()) if err != nil { return nil, err @@ -250,9 +270,12 @@ func (c *controller) createPolicyMap() (map[string]sets.String, error) { if err != nil { return nil, err } - results[key] = sets.NewString() + results[key] = policyMapEntry{ + policy: cpol, + rules: sets.NewString(), + } for _, rule := range autogen.ComputeRules(cpol) { - results[key].Insert(rule.Name) + results[key].rules.Insert(rule.Name) } } pols, err := c.polLister.List(labels.Everything()) @@ -264,31 +287,34 @@ func (c *controller) createPolicyMap() (map[string]sets.String, error) { if err != nil { return nil, err } - results[key] = sets.NewString() + results[key] = policyMapEntry{ + policy: pol, + rules: sets.NewString(), + } for _, rule := range autogen.ComputeRules(pol) { - results[key].Insert(rule.Name) + results[key].rules.Insert(rule.Name) } } return results, nil } -func (c *controller) buildReportsResults(ctx context.Context, namespace string) ([]policyreportv1alpha2.PolicyReportResult, error) { +func (c *controller) buildReportsResults(ctx context.Context, namespace string) ([]policyreportv1alpha2.PolicyReportResult, map[string]policyMapEntry, error) { policyMap, err := c.createPolicyMap() if err != nil { - return nil, err + return nil, nil, err } merged := map[string]policyreportv1alpha2.PolicyReportResult{} if err := c.mergeAdmissionReports(ctx, namespace, policyMap, merged); err != nil { - return nil, err + return nil, nil, err } if err := c.mergeBackgroundScanReports(ctx, namespace, policyMap, merged); err != nil { - return nil, err + return nil, nil, err } var results []policyreportv1alpha2.PolicyReportResult for _, result := range merged { results = append(results, result) } - return results, nil + return results, policyMap, nil } func (c *controller) getPolicyReports(ctx context.Context, namespace string) ([]kyvernov1alpha2.ReportInterface, error) { @@ -318,7 +344,7 @@ func (c *controller) getPolicyReports(ctx context.Context, namespace string) ([] } func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, _, _ string) error { - results, err := c.buildReportsResults(ctx, key) + results, policyMap, err := c.buildReportsResults(ctx, key) if err != nil { return err } @@ -346,7 +372,7 @@ func (c *controller) reconcile(ctx context.Context, logger logr.Logger, key, _, if i > 0 { name = fmt.Sprintf("%s-%d", name, i/chunkSize) } - report, err := c.reconcileReport(ctx, actual[name], key, name, results[i:end]...) + report, err := c.reconcileReport(ctx, policyMap, actual[name], key, name, results[i:end]...) if err != nil { return err } From 42322bae09552df1e668591505c38d231d308f97 Mon Sep 17 00:00:00 2001 From: Vyankatesh Kudtarkar Date: Fri, 4 Nov 2022 15:05:25 +0530 Subject: [PATCH 11/55] [BUG] Fix foreach deletion issue (#5224) * fix foreach deletion issue --- pkg/engine/mutation.go | 3 +++ pkg/engine/validation.go | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/engine/mutation.go b/pkg/engine/mutation.go index 120e5daa8c84..fcf733f21cd0 100644 --- a/pkg/engine/mutation.go +++ b/pkg/engine/mutation.go @@ -224,6 +224,9 @@ func mutateElements(name string, foreach kyvernov1.ForEachMutation, ctx *PolicyC } for i, e := range elements { + if e == nil { + continue + } ctx.JSONContext.Reset() ctx := ctx.Copy() store.SetForeachElement(i) diff --git a/pkg/engine/validation.go b/pkg/engine/validation.go index dce28b97e0f9..699553943d36 100644 --- a/pkg/engine/validation.go +++ b/pkg/engine/validation.go @@ -305,7 +305,6 @@ func (v *validator) validateForEach() *response.RuleResponse { v.log.V(2).Info("failed to evaluate list", "list", foreach.List, "error", err.Error()) continue } - resp, count := v.validateElements(foreach, elements, foreach.ElementScope) if resp.Status != response.RuleStatusPass { return resp @@ -327,6 +326,9 @@ func (v *validator) validateElements(foreach kyvernov1.ForEachValidation, elemen applyCount := 0 for i, e := range elements { + if e == nil { + continue + } store.SetForeachElement(i) v.ctx.JSONContext.Reset() From da1830501547aed4cfcf52d225f5fd7a41c9806b Mon Sep 17 00:00:00 2001 From: Chip Zoller Date: Fri, 4 Nov 2022 10:00:31 -0400 Subject: [PATCH 12/55] add kuttl tests (#5204) - add kuttl tests - try rekor: {url: "https://rekor.sigstore.dev"} - add rekor{} object to last two policies Signed-off-by: Chip Zoller --- .github/workflows/conformance.yaml | 18 ++-- .../aaa_template_resources/01-assert.yaml | 8 ++ .../aaa_template_resources/01-manifests.yaml | 20 +++++ .../aaa_template_resources/02-assert.yaml | 7 ++ .../aaa_template_resources/02-secret.yaml | 8 ++ .../aaa_template_resources/03-delete.yaml | 8 ++ .../aaa_template_resources/05-errors.yaml | 6 ++ .../aaa_template_resources/99-cleanup.yaml | 5 ++ .../aaa_template_resources/BEST_PRACTICES.md | 6 ++ .../kuttl/aaa_template_resources/README.md | 5 ++ .../commands/04-sleep.yaml | 5 ++ .../commands/99-cleanup.yaml | 4 + .../scripts/01-script-check-for-error.yaml | 13 +++ .../scripts/02-script-check-for-output.yaml | 13 +++ .../clusterpolicy/cornercases/README.md | 3 + .../generate/clusterpolicy/standard/README.md | 3 + .../cpol-clone-nosync-create/01-assert.yaml | 6 ++ .../01-manifests.yaml | 30 +++++++ .../cpol-clone-nosync-create/02-assert.yaml | 5 ++ .../cpol-clone-nosync-create/02-ns.yaml | 4 + .../cpol-clone-nosync-create/99-cleanup.yaml | 4 + .../nosync/cpol-clone-nosync-create/README.md | 3 + .../01-assert.yaml | 6 ++ .../01-manifests.yaml | 30 +++++++ .../02-assert.yaml | 5 ++ .../02-ns.yaml | 4 + .../03-assert.yaml | 4 + .../03-delete-secret.yaml | 7 ++ .../04-sleep.yaml | 4 + .../05-errors.yaml | 6 ++ .../99-cleanup.yaml | 4 + .../README.md | 7 ++ .../cpol-clone-sync-create/01-assert.yaml | 6 ++ .../cpol-clone-sync-create/01-manifests.yaml | 30 +++++++ .../cpol-clone-sync-create/02-assert.yaml | 5 ++ .../sync/cpol-clone-sync-create/02-ns.yaml | 4 + .../cpol-clone-sync-create/99-cleanup.yaml | 4 + .../sync/cpol-clone-sync-create/README.md | 3 + .../01-assert.yaml | 6 ++ .../01-manifests.yaml | 30 +++++++ .../02-assert.yaml | 5 ++ .../02-ns.yaml | 4 + .../03-assert.yaml | 4 + .../03-delete-secret.yaml | 7 ++ .../04-sleep.yaml | 4 + .../05-assert.yaml | 6 ++ .../99-cleanup.yaml | 4 + .../README.md | 7 ++ .../01-assert.yaml | 6 ++ .../01-manifests.yaml | 35 ++++++++ .../02-assert.yaml | 10 +++ .../02-ns.yaml | 4 + .../03-downstream-delete.yaml | 7 ++ .../04-errors.yaml | 5 ++ .../99-cleanup.yaml | 4 + .../README.md | 3 + .../sync/cpol-data-sync-create/01-assert.yaml | 6 ++ .../cpol-data-sync-create/01-manifests.yaml | 35 ++++++++ .../sync/cpol-data-sync-create/02-assert.yaml | 10 +++ .../sync/cpol-data-sync-create/02-ns.yaml | 4 + .../cpol-data-sync-create/99-cleanup.yaml | 4 + .../data/sync/cpol-data-sync-create/README.md | 3 + .../01-assert.yaml | 6 ++ .../01-manifests.yaml | 35 ++++++++ .../02-assert.yaml | 10 +++ .../cpol-data-sync-delete-policy/02-ns.yaml | 4 + .../03-assert.yaml | 10 +++ .../04-errors.yaml | 5 ++ .../04-policy-delete.yaml | 6 ++ .../99-cleanup.yaml | 4 + .../cpol-data-sync-delete-policy/README.md | 3 + .../cpol-data-sync-modify-rule/01-assert.yaml | 6 ++ .../01-manifests.yaml | 35 ++++++++ .../cpol-data-sync-modify-rule/02-assert.yaml | 10 +++ .../cpol-data-sync-modify-rule/02-ns.yaml | 4 + .../cpol-data-sync-modify-rule/03-assert.yaml | 10 +++ .../03-policy-update.yaml | 35 ++++++++ .../99-cleanup.yaml | 4 + .../sync/cpol-data-sync-modify-rule/README.md | 3 + test/conformance/kuttl/kuttl-test.yaml | 22 +++++ .../basic-check-output/01-assert.yaml | 6 ++ .../basic-check-output/01-manifests.yaml | 19 ++++ .../basic-check-output/02-assert.yaml | 7 ++ .../basic-check-output/02-secret.yaml | 8 ++ .../basic-check-output/99-cleanup.yaml | 4 + .../standard/basic-check-output/README.md | 3 + .../standard/existing/basic/01-assert.yaml | 6 ++ .../standard/existing/basic/01-manifests.yaml | 52 +++++++++++ .../standard/existing/basic/02-edit-cm.yaml | 8 ++ .../standard/existing/basic/03-assert.yaml | 7 ++ .../standard/existing/basic/99-cleanup.yaml | 4 + .../standard/existing/basic/README.md | 3 + .../01-manifests.yaml | 89 +++++++++++++++++++ .../02-script.yaml | 50 +++++++++++ .../03-create-as-chip.yaml | 4 + .../04-assert.yaml | 11 +++ .../99-cleanup.yaml | 4 + .../userInfo-roles-clusterRoles/README.md | 3 + .../userInfo-roles-clusterRoles/script.sh | 44 +++++++++ .../test-report-admission-mode/01-assert.yaml | 6 ++ .../01-manifests.yaml | 20 +++++ .../test-report-admission-mode/02-ns.yaml | 6 ++ .../test-report-admission-mode/03-assert.yaml | 15 ++++ .../99-cleanup.yaml | 4 + .../test-report-admission-mode/README.md | 3 + .../01-assert.yaml | 5 ++ .../01-manifests.yaml | 14 +++ .../02-assert.yaml | 20 +++++ .../test-report-background-mode/02-cpol.yaml | 32 +++++++ .../03-assert.yaml | 27 ++++++ .../99-cleanup.yaml | 4 + .../test-report-background-mode/README.md | 3 + .../01-script-check-for-output.yaml | 14 +++ .../02-errors.yaml} | 2 +- .../background-match-clusterRoles/README.md | 3 + .../manifests.yaml | 22 +++++ .../01-script-check-for-output.yaml | 14 +++ .../background-match-roles/02-errors.yaml} | 2 +- .../audit/background-match-roles/README.md | 3 + .../background-match-roles/manifests.yaml | 22 +++++ .../01-script-check-for-output.yaml | 14 +++ .../background-vars-roles/02-errors.yaml} | 2 +- .../audit/background-vars-roles/README.md | 3 + .../background-vars-roles/manifests.yaml | 20 +++++ .../01-script-check-for-output.yaml | 14 +++ .../02-errors.yaml} | 2 +- .../README.md | 3 + .../manifests.yaml | 20 +++++ .../01-script-check-for-output.yaml | 14 +++ .../background-vars-userInfo/02-errors.yaml} | 2 +- .../audit/background-vars-userInfo/README.md | 3 + .../background-vars-userInfo/manifests.yaml | 20 +++++ .../resource-apply-block/01-assert.yaml | 6 ++ .../resource-apply-block/01-manifests.yaml | 20 +++++ .../resource-apply-block/02-script.yaml | 14 +++ .../resource-apply-block/03-errors.yaml | 8 ++ .../resource-apply-block/99-cleanup.yaml | 4 + .../enforce/resource-apply-block/README.md | 3 + .../resource-apply-block/resource.yaml | 8 ++ .../standard/keyed-secret/01-assert.yaml | 6 ++ .../standard/keyed-secret/01-manifests.yaml | 39 ++++++++ .../standard/keyed-secret/02-assert.yaml | 5 ++ .../standard/keyed-secret/02-goodpod.yaml | 9 ++ .../standard/keyed-secret/99-cleanup.yaml | 4 + .../standard/keyed-secret/README.md | 3 + .../01-assert.yaml | 6 ++ .../01-manifests.yaml | 27 ++++++ .../02-assert.yaml | 11 +++ .../02-pod.yaml | 9 ++ .../99-cleanup.yaml | 4 + .../README.md | 3 + .../01-assert.yaml | 6 ++ .../01-manifests.yaml | 27 ++++++ .../02-assert.yaml | 11 +++ .../02-pod.yaml | 9 ++ .../99-cleanup.yaml | 4 + .../README.md | 3 + .../01-assert.yaml | 6 ++ .../01-manifests.yaml | 27 ++++++ .../02-assert.yaml | 11 +++ .../02-pod.yaml | 9 ++ .../99-cleanup.yaml | 4 + .../README.md | 3 + test/conformance/manifests/generate/foo.yaml | 1 - test/conformance/manifests/mutate/foo.yaml | 1 - .../manifests/verifyImages/foo.yaml | 1 - 166 files changed, 1727 insertions(+), 13 deletions(-) create mode 100644 test/conformance/kuttl/aaa_template_resources/01-assert.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/01-manifests.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/02-assert.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/02-secret.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/03-delete.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/05-errors.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/99-cleanup.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/BEST_PRACTICES.md create mode 100644 test/conformance/kuttl/aaa_template_resources/README.md create mode 100644 test/conformance/kuttl/aaa_template_resources/commands/04-sleep.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/commands/99-cleanup.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/scripts/01-script-check-for-error.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/scripts/02-script-check-for-output.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/README.md create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/README.md create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/01-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/01-manifests.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/02-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/02-ns.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/99-cleanup.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/README.md create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/01-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/01-manifests.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/02-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/02-ns.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/03-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/03-delete-secret.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/04-sleep.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/05-errors.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/99-cleanup.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/README.md create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/01-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/01-manifests.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/02-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/02-ns.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/99-cleanup.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/README.md create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/01-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/01-manifests.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/02-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/02-ns.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/03-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/03-delete-secret.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/04-sleep.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/05-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/99-cleanup.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/README.md create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/01-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/01-manifests.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/02-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/02-ns.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/03-downstream-delete.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/04-errors.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/99-cleanup.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/README.md create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/01-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/01-manifests.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/02-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/02-ns.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/99-cleanup.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/README.md create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/01-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/01-manifests.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/02-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/02-ns.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/03-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/04-errors.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/04-policy-delete.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/99-cleanup.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/README.md create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/01-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/01-manifests.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/02-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/02-ns.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/03-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/03-policy-update.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/99-cleanup.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/README.md create mode 100644 test/conformance/kuttl/kuttl-test.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/01-assert.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/01-manifests.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/02-assert.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/02-secret.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/99-cleanup.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/README.md create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/01-assert.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/01-manifests.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/02-edit-cm.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/03-assert.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/99-cleanup.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/README.md create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/01-manifests.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/02-script.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/03-create-as-chip.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/04-assert.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/99-cleanup.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/README.md create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/script.sh create mode 100644 test/conformance/kuttl/reports/admission/test-report-admission-mode/01-assert.yaml create mode 100644 test/conformance/kuttl/reports/admission/test-report-admission-mode/01-manifests.yaml create mode 100644 test/conformance/kuttl/reports/admission/test-report-admission-mode/02-ns.yaml create mode 100644 test/conformance/kuttl/reports/admission/test-report-admission-mode/03-assert.yaml create mode 100644 test/conformance/kuttl/reports/admission/test-report-admission-mode/99-cleanup.yaml create mode 100644 test/conformance/kuttl/reports/admission/test-report-admission-mode/README.md create mode 100644 test/conformance/kuttl/reports/background/test-report-background-mode/01-assert.yaml create mode 100644 test/conformance/kuttl/reports/background/test-report-background-mode/01-manifests.yaml create mode 100644 test/conformance/kuttl/reports/background/test-report-background-mode/02-assert.yaml create mode 100644 test/conformance/kuttl/reports/background/test-report-background-mode/02-cpol.yaml create mode 100644 test/conformance/kuttl/reports/background/test-report-background-mode/03-assert.yaml create mode 100644 test/conformance/kuttl/reports/background/test-report-background-mode/99-cleanup.yaml create mode 100644 test/conformance/kuttl/reports/background/test-report-background-mode/README.md create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/01-script-check-for-output.yaml rename test/conformance/{manifests/validate/fail/background-match-clusterroles.yaml => kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/02-errors.yaml} (94%) create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/README.md create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/manifests.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/01-script-check-for-output.yaml rename test/conformance/{manifests/validate/fail/background-match-roles.yaml => kuttl/validate/clusterpolicy/standard/audit/background-match-roles/02-errors.yaml} (94%) create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/README.md create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/manifests.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/01-script-check-for-output.yaml rename test/conformance/{manifests/validate/fail/background-vars-roles.yaml => kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/02-errors.yaml} (91%) create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/README.md create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/manifests.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/01-script-check-for-output.yaml rename test/conformance/{manifests/validate/fail/background-vars-serviceaccountname.yaml => kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/02-errors.yaml} (90%) create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/README.md create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/manifests.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/01-script-check-for-output.yaml rename test/conformance/{manifests/validate/fail/background-vars-userinfo.yaml => kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/02-errors.yaml} (90%) create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/README.md create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/manifests.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/01-assert.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/01-manifests.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/02-script.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/03-errors.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/99-cleanup.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/README.md create mode 100644 test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/resource.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/01-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/01-manifests.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/02-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/02-goodpod.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/README.md create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/01-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/01-manifests.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/02-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/02-pod.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/README.md create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/01-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/01-manifests.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/02-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/02-pod.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/README.md create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/01-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/01-manifests.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/02-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/02-pod.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/README.md delete mode 100644 test/conformance/manifests/generate/foo.yaml delete mode 100644 test/conformance/manifests/mutate/foo.yaml delete mode 100644 test/conformance/manifests/verifyImages/foo.yaml diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index 3f5631534a2e..b86b8b67392b 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -6,16 +6,24 @@ on: - 'release*' jobs: - run-conformace: + run-conformance: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # pin@v3 + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # pin@v3.1.0 - name: Unshallow run: git fetch --prune --unshallow - name: Setup go - uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f # pin@v3 + uses: actions/setup-go@c4a742cab115ed795e34d4513e2cf7d472deb55f # pin@v3.3.1 with: go-version: ~1.18.6 - - name: Kyverno conformance tests - run: go run ./test/conformance/main.go + - name: Prep environment + run: make kind-create-cluster kind-deploy-kyverno + - name: Wait for Kyverno to start + run: sleep 60 + - name: Install kuttl + run: curl -sL https://github.com/kudobuilder/kuttl/releases/download/v0.13.0/kubectl-kuttl_0.13.0_linux_x86_64 -o kuttl && chmod +x kuttl + - name: Test with kuttl + run: ./kuttl test --config ./test/conformance/kuttl/kuttl-test.yaml + # - name: Kyverno conformance tests + # run: go run ./test/conformance/main.go diff --git a/test/conformance/kuttl/aaa_template_resources/01-assert.yaml b/test/conformance/kuttl/aaa_template_resources/01-assert.yaml new file mode 100644 index 000000000000..304a5e80c4d6 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/01-assert.yaml @@ -0,0 +1,8 @@ +# An assert file can be a partial representation of an object. What is specified MUST be present for the check to pass and the test to proceed. +# If the specified timeout is reached and the assert does not evaluate to true, the test fails and halts. +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-labels +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/01-manifests.yaml b/test/conformance/kuttl/aaa_template_resources/01-manifests.yaml new file mode 100644 index 000000000000..f577d14177c9 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/01-manifests.yaml @@ -0,0 +1,20 @@ +# A file with no reserved name "assert" or "errors" will be created with the below contents. Can be multiple YAML docs in the same file. +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-labels +spec: + rules: + - name: add-labels + match: + resources: + kinds: + - Pod + - Service + - ConfigMap + - Secret + mutate: + patchStrategicMerge: + metadata: + labels: + foo: bar diff --git a/test/conformance/kuttl/aaa_template_resources/02-assert.yaml b/test/conformance/kuttl/aaa_template_resources/02-assert.yaml new file mode 100644 index 000000000000..dcb47a5770a8 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/02-assert.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: testingsecret + namespace: default + labels: + foo: bar \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/02-secret.yaml b/test/conformance/kuttl/aaa_template_resources/02-secret.yaml new file mode 100644 index 000000000000..cfafb7c22be4 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/02-secret.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +data: + foo: YmFy +kind: Secret +metadata: + name: testingsecret + namespace: default +type: Opaque \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/03-delete.yaml b/test/conformance/kuttl/aaa_template_resources/03-delete.yaml new file mode 100644 index 000000000000..8c0ce38c1c52 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/03-delete.yaml @@ -0,0 +1,8 @@ +# Specifying the kind as `TestStep` performs certain behaviors like this delete operation. +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: v1 + kind: Secret + name: regcred + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/05-errors.yaml b/test/conformance/kuttl/aaa_template_resources/05-errors.yaml new file mode 100644 index 000000000000..12452a8cbfff --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/05-errors.yaml @@ -0,0 +1,6 @@ +### If this resource is found, create an error which fails the test. Since there is no timeout for this step, it will adopt the global defined in the TestSuite. +apiVersion: v1 +kind: Secret +metadata: + name: regcred + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/99-cleanup.yaml b/test/conformance/kuttl/aaa_template_resources/99-cleanup.yaml new file mode 100644 index 000000000000..6ed1836e0728 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/99-cleanup.yaml @@ -0,0 +1,5 @@ +# A clean-up is presently required because kuttl does not do a reliable job of cleaning up both cluster-scoped objects. +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-secret.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/BEST_PRACTICES.md b/test/conformance/kuttl/aaa_template_resources/BEST_PRACTICES.md new file mode 100644 index 000000000000..c245e1ada616 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/BEST_PRACTICES.md @@ -0,0 +1,6 @@ +# Some Best Practices + +* Don't put anything in index `00` so it can be used in the future. +* Put clean-up as index `99` so it's always last no matter how many steps. +* The `*-errors.yaml` file, like an `*-assert.yaml` file only performs an existence check, not a creation check. +* One test can contain both positive and negative tests by extending the test case. No need to write separate. \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/README.md b/test/conformance/kuttl/aaa_template_resources/README.md new file mode 100644 index 000000000000..22091f0fe077 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/README.md @@ -0,0 +1,5 @@ +# Title + +Issue: 1234 + +This is a description of your test. diff --git a/test/conformance/kuttl/aaa_template_resources/commands/04-sleep.yaml b/test/conformance/kuttl/aaa_template_resources/commands/04-sleep.yaml new file mode 100644 index 000000000000..fe3b8abbcb9c --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/commands/04-sleep.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 \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/commands/99-cleanup.yaml b/test/conformance/kuttl/aaa_template_resources/commands/99-cleanup.yaml new file mode 100644 index 000000000000..b7de47a47c99 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/commands/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-secret.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scripts/01-script-check-for-error.yaml b/test/conformance/kuttl/aaa_template_resources/scripts/01-script-check-for-error.yaml new file mode 100644 index 000000000000..fc29fa83d39e --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scripts/01-script-check-for-error.yaml @@ -0,0 +1,13 @@ +## Checks that the manifests.yaml file CANNOT be successfully created. If it can, fail the test as this is incorrect. +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f manifests.yaml + then + echo "Tested failed. Policy was created when it shouldn't have been." + exit 1 + else + echo "Test succeeded. Policy was not created as intended." + exit 0 + fi \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scripts/02-script-check-for-output.yaml b/test/conformance/kuttl/aaa_template_resources/scripts/02-script-check-for-output.yaml new file mode 100644 index 000000000000..a7ddaea4c4d1 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scripts/02-script-check-for-output.yaml @@ -0,0 +1,13 @@ +## Checks that there is specific output when creating a manifest +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f manifests.yaml 2>&1 | grep -q 'clusterRoles' + then + echo "Has clusterRoles." + exit 0 + else + echo "Does not have clusterRoles." + exit 1 + fi \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/README.md b/test/conformance/kuttl/generate/clusterpolicy/cornercases/README.md new file mode 100644 index 000000000000..99979ca070b7 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/README.md @@ -0,0 +1,3 @@ +# Title + +Tests in the `cornercases` directory should typically correspond either to a specific Kyverno issue (please provide issue number or link) or a Slack conversation if no issue is logged. These are NOT standard tests for basic functionality but outliers or highly specific/esoteric combinations that have exposed a bug in the past. diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/README.md b/test/conformance/kuttl/generate/clusterpolicy/standard/README.md new file mode 100644 index 000000000000..a822f444f4fe --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/README.md @@ -0,0 +1,3 @@ +# Title + +Tests in the `standard` directory should only cover basic functionality of a feature. For testing of specific corner cases addressed as acknowledged bugs, please use the `cornercases` directory. diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/01-assert.yaml new file mode 100644 index 000000000000..aa86792b0a76 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v2beta1 +kind: ClusterPolicy +metadata: + name: cpol-nosync-clone +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/01-manifests.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/01-manifests.yaml new file mode 100644 index 000000000000..f3713bb3bb62 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/01-manifests.yaml @@ -0,0 +1,30 @@ +apiVersion: kyverno.io/v2beta1 +kind: ClusterPolicy +metadata: + name: cpol-nosync-clone +spec: + rules: + - name: clone-secret + match: + any: + - resources: + kinds: + - Namespace + generate: + apiVersion: v1 + kind: Secret + name: regcred + namespace: "{{request.object.metadata.name}}" + synchronize: false + clone: + namespace: default + name: regcred +--- +apiVersion: v1 +data: + foo: YmFy +kind: Secret +metadata: + name: regcred + namespace: default +type: Opaque diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/02-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/02-assert.yaml new file mode 100644 index 000000000000..54cede2c505d --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/02-assert.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Secret +metadata: + name: regcred + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/02-ns.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/02-ns.yaml new file mode 100644 index 000000000000..26f9d8ac2eb3 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/02-ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/99-cleanup.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/99-cleanup.yaml new file mode 100644 index 000000000000..1c6b4578bc1e --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/README.md b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/README.md new file mode 100644 index 000000000000..ff3a2de1a268 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/README.md @@ -0,0 +1,3 @@ +# Title + +This is a generate test to ensure a cloned secret shows properly in the new Namespace. diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/01-assert.yaml new file mode 100644 index 000000000000..aa86792b0a76 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v2beta1 +kind: ClusterPolicy +metadata: + name: cpol-nosync-clone +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/01-manifests.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/01-manifests.yaml new file mode 100644 index 000000000000..f3713bb3bb62 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/01-manifests.yaml @@ -0,0 +1,30 @@ +apiVersion: kyverno.io/v2beta1 +kind: ClusterPolicy +metadata: + name: cpol-nosync-clone +spec: + rules: + - name: clone-secret + match: + any: + - resources: + kinds: + - Namespace + generate: + apiVersion: v1 + kind: Secret + name: regcred + namespace: "{{request.object.metadata.name}}" + synchronize: false + clone: + namespace: default + name: regcred +--- +apiVersion: v1 +data: + foo: YmFy +kind: Secret +metadata: + name: regcred + namespace: default +type: Opaque diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/02-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/02-assert.yaml new file mode 100644 index 000000000000..54cede2c505d --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/02-assert.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Secret +metadata: + name: regcred + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/02-ns.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/02-ns.yaml new file mode 100644 index 000000000000..26f9d8ac2eb3 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/02-ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/03-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/03-assert.yaml new file mode 100644 index 000000000000..26f9d8ac2eb3 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/03-assert.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/03-delete-secret.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/03-delete-secret.yaml new file mode 100644 index 000000000000..9040065230db --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/03-delete-secret.yaml @@ -0,0 +1,7 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: v1 + kind: Secret + name: regcred + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/04-sleep.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/04-sleep.yaml new file mode 100644 index 000000000000..e0f2098e5d5b --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/04-sleep.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: sleep 3 \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/05-errors.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/05-errors.yaml new file mode 100644 index 000000000000..12452a8cbfff --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/05-errors.yaml @@ -0,0 +1,6 @@ +### If this resource is found, create an error which fails the test. Since there is no timeout for this step, it will adopt the global defined in the TestSuite. +apiVersion: v1 +kind: Secret +metadata: + name: regcred + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/99-cleanup.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/99-cleanup.yaml new file mode 100644 index 000000000000..1c6b4578bc1e --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/README.md b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/README.md new file mode 100644 index 000000000000..ff899675251a --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/README.md @@ -0,0 +1,7 @@ +# Title + +This test ensures that deletion of a downstream resource created by a ClusterPolicy `generate` rule with sync disabled using a clone declaration does NOT cause it to be regenerated. If the downstream resource is regenerated, the test fails. If it is not regenerated, the test succeeds. + +### Tests a clone rule with sync not enabled that deleting a downstream resource shows it is not recreated. +### Because https://github.com/kyverno/kyverno/issues/4457 is not yet fixed for this type, the test will fail. +### Expected result: fail \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/01-assert.yaml new file mode 100644 index 000000000000..370f29765ba9 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v2beta1 +kind: ClusterPolicy +metadata: + name: cpol-sync-clone +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/01-manifests.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/01-manifests.yaml new file mode 100644 index 000000000000..005f75e40bfa --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/01-manifests.yaml @@ -0,0 +1,30 @@ +apiVersion: kyverno.io/v2beta1 +kind: ClusterPolicy +metadata: + name: cpol-sync-clone +spec: + rules: + - name: clone-secret + match: + any: + - resources: + kinds: + - Namespace + generate: + apiVersion: v1 + kind: Secret + name: regcred + namespace: "{{request.object.metadata.name}}" + synchronize: true + clone: + namespace: default + name: regcred +--- +apiVersion: v1 +data: + foo: YmFy +kind: Secret +metadata: + name: regcred + namespace: default +type: Opaque diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/02-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/02-assert.yaml new file mode 100644 index 000000000000..54cede2c505d --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/02-assert.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Secret +metadata: + name: regcred + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/02-ns.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/02-ns.yaml new file mode 100644 index 000000000000..26f9d8ac2eb3 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/02-ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/99-cleanup.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/99-cleanup.yaml new file mode 100644 index 000000000000..1c6b4578bc1e --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/README.md b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/README.md new file mode 100644 index 000000000000..ff3a2de1a268 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/README.md @@ -0,0 +1,3 @@ +# Title + +This is a generate test to ensure a cloned secret shows properly in the new Namespace. diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/01-assert.yaml new file mode 100644 index 000000000000..370f29765ba9 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v2beta1 +kind: ClusterPolicy +metadata: + name: cpol-sync-clone +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/01-manifests.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/01-manifests.yaml new file mode 100644 index 000000000000..005f75e40bfa --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/01-manifests.yaml @@ -0,0 +1,30 @@ +apiVersion: kyverno.io/v2beta1 +kind: ClusterPolicy +metadata: + name: cpol-sync-clone +spec: + rules: + - name: clone-secret + match: + any: + - resources: + kinds: + - Namespace + generate: + apiVersion: v1 + kind: Secret + name: regcred + namespace: "{{request.object.metadata.name}}" + synchronize: true + clone: + namespace: default + name: regcred +--- +apiVersion: v1 +data: + foo: YmFy +kind: Secret +metadata: + name: regcred + namespace: default +type: Opaque diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/02-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/02-assert.yaml new file mode 100644 index 000000000000..54cede2c505d --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/02-assert.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Secret +metadata: + name: regcred + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/02-ns.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/02-ns.yaml new file mode 100644 index 000000000000..26f9d8ac2eb3 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/02-ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/03-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/03-assert.yaml new file mode 100644 index 000000000000..26f9d8ac2eb3 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/03-assert.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/03-delete-secret.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/03-delete-secret.yaml new file mode 100644 index 000000000000..9040065230db --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/03-delete-secret.yaml @@ -0,0 +1,7 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: v1 + kind: Secret + name: regcred + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/04-sleep.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/04-sleep.yaml new file mode 100644 index 000000000000..e0f2098e5d5b --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/04-sleep.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: sleep 3 \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/05-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/05-assert.yaml new file mode 100644 index 000000000000..c1a3970413ef --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/05-assert.yaml @@ -0,0 +1,6 @@ +### If this resource is found, the step should pass. We expect the downstream resource to be recreated. +apiVersion: v1 +kind: Secret +metadata: + name: regcred + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/99-cleanup.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/99-cleanup.yaml new file mode 100644 index 000000000000..1c6b4578bc1e --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/README.md b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/README.md new file mode 100644 index 000000000000..ff899675251a --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/README.md @@ -0,0 +1,7 @@ +# Title + +This test ensures that deletion of a downstream resource created by a ClusterPolicy `generate` rule with sync disabled using a clone declaration does NOT cause it to be regenerated. If the downstream resource is regenerated, the test fails. If it is not regenerated, the test succeeds. + +### Tests a clone rule with sync not enabled that deleting a downstream resource shows it is not recreated. +### Because https://github.com/kyverno/kyverno/issues/4457 is not yet fixed for this type, the test will fail. +### Expected result: fail \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/01-assert.yaml new file mode 100644 index 000000000000..952a960e5069 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: zk-kafka-address +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/01-manifests.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/01-manifests.yaml new file mode 100644 index 000000000000..3677a6290d77 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/01-manifests.yaml @@ -0,0 +1,35 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: zk-kafka-address +spec: + generateExistingOnPolicyUpdate: true + rules: + - name: k-kafka-address + match: + any: + - resources: + kinds: + - Namespace + exclude: + any: + - resources: + namespaces: + - kube-system + - default + - kube-public + - kyverno + generate: + synchronize: false + 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" \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/02-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/02-assert.yaml new file mode 100644 index 000000000000..e20de3d1bb69 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/02-assert.yaml @@ -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: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/02-ns.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/02-ns.yaml new file mode 100644 index 000000000000..26f9d8ac2eb3 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/02-ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/03-downstream-delete.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/03-downstream-delete.yaml new file mode 100644 index 000000000000..c0b69b5c969c --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/03-downstream-delete.yaml @@ -0,0 +1,7 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: v1 + kind: ConfigMap + name: zk-kafka-address + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/04-errors.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/04-errors.yaml new file mode 100644 index 000000000000..322ded2e1552 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/04-errors.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: zk-kafka-address + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/99-cleanup.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/99-cleanup.yaml new file mode 100644 index 000000000000..1c6b4578bc1e --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/README.md b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/README.md new file mode 100644 index 000000000000..e4636d9dc5ff --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/README.md @@ -0,0 +1,3 @@ +# Title + +This is a generate test to ensure deleting a generate policy using a data declaration with sync enabled deletes the downstream ConfigMap when matching a new Namespace. diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/01-assert.yaml new file mode 100644 index 000000000000..952a960e5069 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: zk-kafka-address +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/01-manifests.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/01-manifests.yaml new file mode 100644 index 000000000000..f029bc421a07 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/01-manifests.yaml @@ -0,0 +1,35 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: zk-kafka-address +spec: + generateExistingOnPolicyUpdate: true + 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" \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/02-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/02-assert.yaml new file mode 100644 index 000000000000..e20de3d1bb69 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/02-assert.yaml @@ -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: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/02-ns.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/02-ns.yaml new file mode 100644 index 000000000000..26f9d8ac2eb3 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/02-ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/99-cleanup.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/99-cleanup.yaml new file mode 100644 index 000000000000..1c6b4578bc1e --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/README.md b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/README.md new file mode 100644 index 000000000000..1a6d9f93096c --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/README.md @@ -0,0 +1,3 @@ +# Title + +This is a generate test to ensure a generate policy using a data declaration with sync enabled creates a downstream ConfigMap when matching a new Namespace. diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/01-assert.yaml new file mode 100644 index 000000000000..952a960e5069 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: zk-kafka-address +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/01-manifests.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/01-manifests.yaml new file mode 100644 index 000000000000..f029bc421a07 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/01-manifests.yaml @@ -0,0 +1,35 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: zk-kafka-address +spec: + generateExistingOnPolicyUpdate: true + 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" \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/02-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/02-assert.yaml new file mode 100644 index 000000000000..e20de3d1bb69 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/02-assert.yaml @@ -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: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/02-ns.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/02-ns.yaml new file mode 100644 index 000000000000..26f9d8ac2eb3 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/02-ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/03-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/03-assert.yaml new file mode 100644 index 000000000000..e20de3d1bb69 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/03-assert.yaml @@ -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: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/04-errors.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/04-errors.yaml new file mode 100644 index 000000000000..322ded2e1552 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/04-errors.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: zk-kafka-address + namespace: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/04-policy-delete.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/04-policy-delete.yaml new file mode 100644 index 000000000000..e8dff700b2e5 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/04-policy-delete.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: zk-kafka-address \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/99-cleanup.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/99-cleanup.yaml new file mode 100644 index 000000000000..1c6b4578bc1e --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/README.md b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/README.md new file mode 100644 index 000000000000..e4636d9dc5ff --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/README.md @@ -0,0 +1,3 @@ +# Title + +This is a generate test to ensure deleting a generate policy using a data declaration with sync enabled deletes the downstream ConfigMap when matching a new Namespace. diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/01-assert.yaml new file mode 100644 index 000000000000..952a960e5069 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: zk-kafka-address +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/01-manifests.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/01-manifests.yaml new file mode 100644 index 000000000000..f029bc421a07 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/01-manifests.yaml @@ -0,0 +1,35 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: zk-kafka-address +spec: + generateExistingOnPolicyUpdate: true + 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" \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/02-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/02-assert.yaml new file mode 100644 index 000000000000..e20de3d1bb69 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/02-assert.yaml @@ -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: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/02-ns.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/02-ns.yaml new file mode 100644 index 000000000000..26f9d8ac2eb3 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/02-ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/03-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/03-assert.yaml new file mode 100644 index 000000000000..55cba48ae19e --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/03-assert.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +data: + KAFKA_ADDRESS: 192.168.10.13:9092,192.168.10.14:9092,192.168.10.15:9999 + 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: bar \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/03-policy-update.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/03-policy-update.yaml new file mode 100644 index 000000000000..9cada13ab32d --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/03-policy-update.yaml @@ -0,0 +1,35 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: zk-kafka-address +spec: + generateExistingOnPolicyUpdate: true + 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:9999" \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/99-cleanup.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/99-cleanup.yaml new file mode 100644 index 000000000000..1c6b4578bc1e --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/README.md b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/README.md new file mode 100644 index 000000000000..10c3b6432d83 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/README.md @@ -0,0 +1,3 @@ +# Title + +This is a generate test to ensure a generate policy using a data declaration with sync enabled and modifying the policy/rule propagates those changes to a downstream ConfigMap. diff --git a/test/conformance/kuttl/kuttl-test.yaml b/test/conformance/kuttl/kuttl-test.yaml new file mode 100644 index 000000000000..8f4b4b9eceb2 --- /dev/null +++ b/test/conformance/kuttl/kuttl-test.yaml @@ -0,0 +1,22 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestSuite +testDirs: + # Generate tests +# - ./generate/clusterpolicy/standard/clone/nosync +- ./test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync +- ./test/conformance/kuttl/generate/clusterpolicy/standard/data/sync +- ./test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync + # Mutate tests +- ./test/conformance/kuttl/mutate/clusterpolicy/standard +- ./test/conformance/kuttl/mutate/clusterpolicy/standard/existing + # Validate tests +- ./test/conformance/kuttl/validate/clusterpolicy/standard/audit +- ./test/conformance/kuttl/validate/clusterpolicy/standard/enforce + # verifyImages tests +- ./test/conformance/kuttl/verifyImages/clusterpolicy/standard + # Report tests +- ./test/conformance/kuttl/reports/admission +- ./test/conformance/kuttl/reports/background +startKIND: false +timeout: 15 +parallel: 1 \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/01-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/01-assert.yaml new file mode 100644 index 000000000000..7f1d7387c9b0 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-labels +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/01-manifests.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/01-manifests.yaml new file mode 100644 index 000000000000..970b4aa5c439 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/01-manifests.yaml @@ -0,0 +1,19 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-labels +spec: + rules: + - name: add-labels + match: + resources: + kinds: + - Pod + - Service + - ConfigMap + - Secret + mutate: + patchStrategicMerge: + metadata: + labels: + foo: bar diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/02-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/02-assert.yaml new file mode 100644 index 000000000000..dcb47a5770a8 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/02-assert.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: testingsecret + namespace: default + labels: + foo: bar \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/02-secret.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/02-secret.yaml new file mode 100644 index 000000000000..cfafb7c22be4 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/02-secret.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +data: + foo: YmFy +kind: Secret +metadata: + name: testingsecret + namespace: default +type: Opaque \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/99-cleanup.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/99-cleanup.yaml new file mode 100644 index 000000000000..b7de47a47c99 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-secret.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/README.md b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/README.md new file mode 100644 index 000000000000..7ca7b77a9ebd --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/README.md @@ -0,0 +1,3 @@ +# Title + +This is a basic mutation test. diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/01-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/01-assert.yaml new file mode 100644 index 000000000000..56d8a26762d1 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: mutate-existing-secret +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/01-manifests.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/01-manifests.yaml new file mode 100644 index 000000000000..8400e934c917 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/01-manifests.yaml @@ -0,0 +1,52 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: staging + labels: + app-type: corp + annotations: + cloud.platformzero.com/serviceClass: "xl2" +--- +apiVersion: v1 +data: + foo: bar +kind: ConfigMap +metadata: + name: dictionary-1 + namespace: staging +--- +apiVersion: v1 +data: + foo: YmFy +kind: Secret +metadata: + name: secret-1 + namespace: staging +type: Opaque +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: "mutate-existing-secret" +spec: + rules: + - name: "mutate-secret-on-configmap-event" + match: + any: + - resources: + kinds: + - ConfigMap + names: + - dictionary-1 + namespaces: + - staging + mutate: + targets: + - apiVersion: v1 + kind: Secret + name: secret-1 + namespace: "{{ request.object.metadata.namespace }}" + patchStrategicMerge: + metadata: + labels: + foo: bar \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/02-edit-cm.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/02-edit-cm.yaml new file mode 100644 index 000000000000..ca18559545cd --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/02-edit-cm.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +data: + foo: bar + dog: dory +kind: ConfigMap +metadata: + name: dictionary-1 + namespace: staging \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/03-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/03-assert.yaml new file mode 100644 index 000000000000..5e7a22434627 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/03-assert.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: secret-1 + namespace: staging + labels: + foo: bar \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/99-cleanup.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/99-cleanup.yaml new file mode 100644 index 000000000000..15c3c4905153 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/README.md b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/README.md new file mode 100644 index 000000000000..3f13a0c273c8 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/README.md @@ -0,0 +1,3 @@ +# Title + +This is a test for mutation of existing resources. diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/01-manifests.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/01-manifests.yaml new file mode 100644 index 000000000000..db1e70c8b35d --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/01-manifests.yaml @@ -0,0 +1,89 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: qa +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: chip +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: chip-qa-rolebinding + namespace: qa +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: chip +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: chip +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: chip-special-role + namespace: qa +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - create + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: chip-qa-specialrb + namespace: qa +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: chip-special-role +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: chip +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: record-creation-details +spec: + background: false + rules: + - name: add-userinfo + match: + any: + - resources: + kinds: + - ConfigMap + preconditions: + any: + - key: "{{request.operation || 'BACKGROUND'}}" + operator: Equals + value: CREATE + mutate: + patchStrategicMerge: + metadata: + annotations: + kyverno.io/created-by: "{{ request.userInfo | to_string(@) }}" + kyverno.io/roles: "{{ request.roles | sort(@) | to_string(@) }}" + kyverno.io/clusterroles: "{{ request.clusterRoles | sort(@) | to_string(@) }}" \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/02-script.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/02-script.yaml new file mode 100644 index 000000000000..c9c2e91468d6 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/02-script.yaml @@ -0,0 +1,50 @@ +## Runs the identity generation script. This assumes that there is only one entry in the kubeconfig. + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + #!/bin/bash + set -eu + + export USERNAME=chip + export NAMESPACE=qa + export CA=ca.crt + #### + #### Get CA certificate from kubeconfig assuming it's the first in the list. + kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 --decode > ca.crt + #### Set CLUSTER_SERVER from kubeconfig assuming it's the first in the list. + CLUSTER_SERVER=$(kubectl config view --raw -o jsonpath='{.clusters[0].cluster.server}') + #### Set CLUSTER from kubeconfig assuming it's the first in the list. + CLUSTER=$(kubectl config view --raw -o jsonpath='{.clusters[0].name}') + #### Generate private key + openssl genrsa -out $USERNAME.key 2048 + #### Create CSR + openssl req -new -key $USERNAME.key -out $USERNAME.csr -subj "/O=mygroup/CN=$USERNAME" + #### Send CSR to kube-apiserver for approval + cat < $USERNAME.crt + #### + #### Create the credential object and output the new kubeconfig file + kubectl --kubeconfig=$USERNAME-kubeconfig config set-credentials $USERNAME --client-certificate=$USERNAME.crt --client-key=$USERNAME.key --embed-certs + #### Set the cluster info + kubectl --kubeconfig=$USERNAME-kubeconfig config set-cluster $CLUSTER --server=$CLUSTER_SERVER --certificate-authority=$CA --embed-certs + #### Set the context + kubectl --kubeconfig=$USERNAME-kubeconfig config set-context $USERNAME-$NAMESPACE-$CLUSTER --user=$USERNAME --cluster=$CLUSTER --namespace=$NAMESPACE + #### Use the context + kubectl --kubeconfig=$USERNAME-kubeconfig config use-context $USERNAME-$NAMESPACE-$CLUSTER + ### Clean up the approved CSR + kubectl delete certificatesigningrequest chip \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/03-create-as-chip.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/03-create-as-chip.yaml new file mode 100644 index 000000000000..e106e2f13a2a --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/03-create-as-chip.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl -n qa create cm foo --from-literal=foo=bar --kubeconfig chip-kubeconfig \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/04-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/04-assert.yaml new file mode 100644 index 000000000000..180e86114916 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/04-assert.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +data: + foo: bar +kind: ConfigMap +metadata: + annotations: + kyverno.io/clusterroles: '["chip","system:basic-user","system:discovery","system:public-info-viewer"]' + kyverno.io/created-by: '{"groups":["mygroup","system:authenticated"],"username":"chip"}' + kyverno.io/roles: '["qa:chip-special-role"]' + name: foo + namespace: qa \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/99-cleanup.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/99-cleanup.yaml new file mode 100644 index 000000000000..15c3c4905153 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/README.md b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/README.md new file mode 100644 index 000000000000..c14baaac90b2 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/README.md @@ -0,0 +1,3 @@ +# Title + +This test verifies that Kyverno is able to pick up and write the `request.userInfo` information from the AdmissionReview payload correctly, as well as the pre-defined vars `request.roles` and `request.clusterRoles` by creating and then performing an action as a new user in the system. The expectation is the custom group and username are both being reflected correctly in a mutation. Similar tests exist for validation flows. diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/script.sh b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/script.sh new file mode 100644 index 000000000000..b3c5709f9344 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/userInfo-roles-clusterRoles/script.sh @@ -0,0 +1,44 @@ +#!/bin/bash +set -euo pipefail + +export USERNAME=chip +export NAMESPACE=qa +export CA=ca.crt +#### +#### Get CA certificate from kubeconfig assuming it's the first in the list. +kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 --decode > ca.crt +#### Set CLUSTER_SERVER from kubeconfig assuming it's the first in the list. +CLUSTER_SERVER=$(kubectl config view --raw -o jsonpath='{.clusters[0].cluster.server}') +#### Set CLUSTER from kubeconfig assuming it's the first in the list. +CLUSTER=$(kubectl config view --raw -o jsonpath='{.clusters[0].name}') +#### Generate private key +openssl genrsa -out $USERNAME.key 2048 +#### Create CSR +openssl req -new -key $USERNAME.key -out $USERNAME.csr -subj "/O=mygroup/CN=$USERNAME" +#### Send CSR to kube-apiserver for approval +cat < $USERNAME.crt +#### +#### Create the credential object and output the new kubeconfig file +kubectl --kubeconfig=$USERNAME-kubeconfig config set-credentials $USERNAME --client-certificate=$USERNAME.crt --client-key=$USERNAME.key --embed-certs +#### Set the cluster info +kubectl --kubeconfig=$USERNAME-kubeconfig config set-cluster $CLUSTER --server=$CLUSTER_SERVER --certificate-authority=$CA --embed-certs +#### Set the context +kubectl --kubeconfig=$USERNAME-kubeconfig config set-context $USERNAME-$NAMESPACE-$CLUSTER --user=$USERNAME --cluster=$CLUSTER --namespace=$NAMESPACE +#### Use the context +kubectl --kubeconfig=$USERNAME-kubeconfig config use-context $USERNAME-$NAMESPACE-$CLUSTER +### Clean up the approved CSR +kubectl delete certificatesigningrequest chip \ No newline at end of file diff --git a/test/conformance/kuttl/reports/admission/test-report-admission-mode/01-assert.yaml b/test/conformance/kuttl/reports/admission/test-report-admission-mode/01-assert.yaml new file mode 100644 index 000000000000..8d9a20c329cb --- /dev/null +++ b/test/conformance/kuttl/reports/admission/test-report-admission-mode/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-owner +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/reports/admission/test-report-admission-mode/01-manifests.yaml b/test/conformance/kuttl/reports/admission/test-report-admission-mode/01-manifests.yaml new file mode 100644 index 000000000000..576fe03288d5 --- /dev/null +++ b/test/conformance/kuttl/reports/admission/test-report-admission-mode/01-manifests.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-owner +spec: + validationFailureAction: audit + background: false + rules: + - name: check-owner + match: + any: + - resources: + kinds: + - Namespace + validate: + message: The `owner` label is required for all Namespaces. + pattern: + metadata: + labels: + owner: "?*" \ No newline at end of file diff --git a/test/conformance/kuttl/reports/admission/test-report-admission-mode/02-ns.yaml b/test/conformance/kuttl/reports/admission/test-report-admission-mode/02-ns.yaml new file mode 100644 index 000000000000..4f230d84eb50 --- /dev/null +++ b/test/conformance/kuttl/reports/admission/test-report-admission-mode/02-ns.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bar + labels: + owner: david \ No newline at end of file diff --git a/test/conformance/kuttl/reports/admission/test-report-admission-mode/03-assert.yaml b/test/conformance/kuttl/reports/admission/test-report-admission-mode/03-assert.yaml new file mode 100644 index 000000000000..efaaf4c2a1c9 --- /dev/null +++ b/test/conformance/kuttl/reports/admission/test-report-admission-mode/03-assert.yaml @@ -0,0 +1,15 @@ +apiVersion: wgpolicyk8s.io/v1alpha2 +kind: ClusterPolicyReport +metadata: + name: cpol-require-owner +results: +- message: validation rule 'check-owner' passed. + policy: require-owner + resources: + - apiVersion: v1 + kind: Namespace + name: bar + result: pass + rule: check-owner + scored: true + source: kyverno \ No newline at end of file diff --git a/test/conformance/kuttl/reports/admission/test-report-admission-mode/99-cleanup.yaml b/test/conformance/kuttl/reports/admission/test-report-admission-mode/99-cleanup.yaml new file mode 100644 index 000000000000..1c6b4578bc1e --- /dev/null +++ b/test/conformance/kuttl/reports/admission/test-report-admission-mode/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/reports/admission/test-report-admission-mode/README.md b/test/conformance/kuttl/reports/admission/test-report-admission-mode/README.md new file mode 100644 index 000000000000..cdc1a901a7f1 --- /dev/null +++ b/test/conformance/kuttl/reports/admission/test-report-admission-mode/README.md @@ -0,0 +1,3 @@ +# Title + +This test checks that a Policy Report in admission mode is created with an entry that is as expected. \ No newline at end of file diff --git a/test/conformance/kuttl/reports/background/test-report-background-mode/01-assert.yaml b/test/conformance/kuttl/reports/background/test-report-background-mode/01-assert.yaml new file mode 100644 index 000000000000..6fa1f4c067e9 --- /dev/null +++ b/test/conformance/kuttl/reports/background/test-report-background-mode/01-assert.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + namespace: default \ No newline at end of file diff --git a/test/conformance/kuttl/reports/background/test-report-background-mode/01-manifests.yaml b/test/conformance/kuttl/reports/background/test-report-background-mode/01-manifests.yaml new file mode 100644 index 000000000000..00ac4d55756d --- /dev/null +++ b/test/conformance/kuttl/reports/background/test-report-background-mode/01-manifests.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 + namespace: default +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault \ No newline at end of file diff --git a/test/conformance/kuttl/reports/background/test-report-background-mode/02-assert.yaml b/test/conformance/kuttl/reports/background/test-report-background-mode/02-assert.yaml new file mode 100644 index 000000000000..559357481ddd --- /dev/null +++ b/test/conformance/kuttl/reports/background/test-report-background-mode/02-assert.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: podsecurity-subrule-restricted +spec: + background: true + rules: + - match: + any: + - resources: + kinds: + - Pod + name: restricted + validate: + podSecurity: + level: restricted + version: latest + validationFailureAction: audit +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/reports/background/test-report-background-mode/02-cpol.yaml b/test/conformance/kuttl/reports/background/test-report-background-mode/02-cpol.yaml new file mode 100644 index 000000000000..0bd22853c825 --- /dev/null +++ b/test/conformance/kuttl/reports/background/test-report-background-mode/02-cpol.yaml @@ -0,0 +1,32 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: podsecurity-subrule-restricted + annotations: + policies.kyverno.io/title: Restricted Pod Security Standards + policies.kyverno.io/category: Pod Security + policies.kyverno.io/severity: medium + kyverno.io/kyverno-version: 1.8.0 + policies.kyverno.io/minversion: 1.8.0 + kyverno.io/kubernetes-version: "1.24" + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + The restricted profile of the Pod Security Standards, which is inclusive of + the baseline profile, is a collection of all the most common configurations + that can be taken to secure Pods. Beginning with Kyverno 1.8, an entire profile + may be assigned to the cluster through a single rule. This policy configures the + restricted profile through the latest version of the Pod Security Standards cluster wide. +spec: + background: true + validationFailureAction: audit + rules: + - name: restricted + match: + any: + - resources: + kinds: + - Pod + validate: + podSecurity: + level: restricted + version: latest \ No newline at end of file diff --git a/test/conformance/kuttl/reports/background/test-report-background-mode/03-assert.yaml b/test/conformance/kuttl/reports/background/test-report-background-mode/03-assert.yaml new file mode 100644 index 000000000000..73981fd078f1 --- /dev/null +++ b/test/conformance/kuttl/reports/background/test-report-background-mode/03-assert.yaml @@ -0,0 +1,27 @@ +apiVersion: wgpolicyk8s.io/v1alpha2 +kind: PolicyReport +metadata: + name: cpol-podsecurity-subrule-restricted + namespace: default +results: +- category: Pod Security + message: | + Validation rule 'restricted' failed. It violates PodSecurity "restricted:latest": ({Allowed:false ForbiddenReason:unrestricted capabilities ForbiddenDetail:container "container01" must set securityContext.capabilities.drop=["ALL"]}) + ({Allowed:false ForbiddenReason:unrestricted capabilities ForbiddenDetail:container "container01" must set securityContext.capabilities.drop=["ALL"]}) + policy: podsecurity-subrule-restricted + resources: + - apiVersion: v1 + kind: Pod + name: badpod01 + namespace: default + result: fail + rule: restricted + scored: true + severity: medium + source: kyverno +summary: + error: 0 + fail: 1 + pass: 0 + skip: 0 + warn: 0 \ No newline at end of file diff --git a/test/conformance/kuttl/reports/background/test-report-background-mode/99-cleanup.yaml b/test/conformance/kuttl/reports/background/test-report-background-mode/99-cleanup.yaml new file mode 100644 index 000000000000..c5bcf59c459e --- /dev/null +++ b/test/conformance/kuttl/reports/background/test-report-background-mode/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-cpol.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/reports/background/test-report-background-mode/README.md b/test/conformance/kuttl/reports/background/test-report-background-mode/README.md new file mode 100644 index 000000000000..98bbddf4a355 --- /dev/null +++ b/test/conformance/kuttl/reports/background/test-report-background-mode/README.md @@ -0,0 +1,3 @@ +# Title + +This test checks that a Policy Report is created with an entry that is as expected. \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/01-script-check-for-output.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/01-script-check-for-output.yaml new file mode 100644 index 000000000000..0a2e7acf8acd --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/01-script-check-for-output.yaml @@ -0,0 +1,14 @@ +## Checks that there is specific output when creating a manifest + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f manifests.yaml 2>&1 | grep -q 'invalid variable used' + then + echo "Test succeeded. The phrase 'invalid variable used' is found." + exit 0 + else + echo "Test failed. The phrase 'invalid variable used' has not been found." + exit 1 + fi \ No newline at end of file diff --git a/test/conformance/manifests/validate/fail/background-match-clusterroles.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/02-errors.yaml similarity index 94% rename from test/conformance/manifests/validate/fail/background-match-clusterroles.yaml rename to test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/02-errors.yaml index 74884770cc96..99b192325118 100644 --- a/test/conformance/manifests/validate/fail/background-match-clusterroles.yaml +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/02-errors.yaml @@ -19,4 +19,4 @@ spec: pattern: metadata: labels: - owner: "?*" + owner: "?*" \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/README.md b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/README.md new file mode 100644 index 000000000000..80d57b93cfea --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/README.md @@ -0,0 +1,3 @@ +# Title + +Ensures this policy cannot be created because clusterRoles is not valid in background mode. It checks that the return failure output contains the given string and finally checks that the policy has not been created (in case somehow it returned an error, which passed, but was still created). \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/manifests.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/manifests.yaml new file mode 100644 index 000000000000..99b192325118 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-clusterRoles/manifests.yaml @@ -0,0 +1,22 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: background-match-clusterroles +spec: + validationFailureAction: audit + background: true + rules: + - name: ns-clusterroles + match: + any: + - resources: + kinds: + - Pod + clusterRoles: + - foo-admin + validate: + message: The `owner` label is required for all Namespaces. + pattern: + metadata: + labels: + owner: "?*" \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/01-script-check-for-output.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/01-script-check-for-output.yaml new file mode 100644 index 000000000000..0a2e7acf8acd --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/01-script-check-for-output.yaml @@ -0,0 +1,14 @@ +## Checks that there is specific output when creating a manifest + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f manifests.yaml 2>&1 | grep -q 'invalid variable used' + then + echo "Test succeeded. The phrase 'invalid variable used' is found." + exit 0 + else + echo "Test failed. The phrase 'invalid variable used' has not been found." + exit 1 + fi \ No newline at end of file diff --git a/test/conformance/manifests/validate/fail/background-match-roles.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/02-errors.yaml similarity index 94% rename from test/conformance/manifests/validate/fail/background-match-roles.yaml rename to test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/02-errors.yaml index b247f9a2152c..c8980b51334f 100644 --- a/test/conformance/manifests/validate/fail/background-match-roles.yaml +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/02-errors.yaml @@ -19,4 +19,4 @@ spec: pattern: metadata: labels: - owner: "?*" + owner: "?*" \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/README.md b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/README.md new file mode 100644 index 000000000000..80d57b93cfea --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/README.md @@ -0,0 +1,3 @@ +# Title + +Ensures this policy cannot be created because clusterRoles is not valid in background mode. It checks that the return failure output contains the given string and finally checks that the policy has not been created (in case somehow it returned an error, which passed, but was still created). \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/manifests.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/manifests.yaml new file mode 100644 index 000000000000..c8980b51334f --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-match-roles/manifests.yaml @@ -0,0 +1,22 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: background-match-roles +spec: + validationFailureAction: audit + background: true + rules: + - name: ns-roles + match: + any: + - resources: + kinds: + - Pod + roles: + - foo-role + validate: + message: The `owner` label is required for all Namespaces. + pattern: + metadata: + labels: + owner: "?*" \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/01-script-check-for-output.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/01-script-check-for-output.yaml new file mode 100644 index 000000000000..120259ce0ba2 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/01-script-check-for-output.yaml @@ -0,0 +1,14 @@ +## Checks that there is specific output when creating a manifest + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f manifests.yaml 2>&1 | grep -q 'variable {{request.roles}} is not allowed' + then + echo "Test succeeded. The phrase 'variable {{request.roles}} is not allowed' is found." + exit 0 + else + echo "Test failed. The phrase 'variable {{request.roles}} is not allowed' has not been found." + exit 1 + fi \ No newline at end of file diff --git a/test/conformance/manifests/validate/fail/background-vars-roles.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/02-errors.yaml similarity index 91% rename from test/conformance/manifests/validate/fail/background-vars-roles.yaml rename to test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/02-errors.yaml index 541569ce04e5..c1c3968a538d 100644 --- a/test/conformance/manifests/validate/fail/background-vars-roles.yaml +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/02-errors.yaml @@ -17,4 +17,4 @@ spec: pattern: metadata: labels: - foo: "{{request.roles}}" + foo: "{{request.roles}}" \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/README.md b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/README.md new file mode 100644 index 000000000000..80d57b93cfea --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/README.md @@ -0,0 +1,3 @@ +# Title + +Ensures this policy cannot be created because clusterRoles is not valid in background mode. It checks that the return failure output contains the given string and finally checks that the policy has not been created (in case somehow it returned an error, which passed, but was still created). \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/manifests.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/manifests.yaml new file mode 100644 index 000000000000..c1c3968a538d --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-roles/manifests.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: background-vars-roles +spec: + validationFailureAction: audit + background: true + rules: + - name: ns-vars-roles + match: + any: + - resources: + kinds: + - Pod + validate: + message: The `owner` label is required for all Namespaces. + pattern: + metadata: + labels: + foo: "{{request.roles}}" \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/01-script-check-for-output.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/01-script-check-for-output.yaml new file mode 100644 index 000000000000..e781794400dc --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/01-script-check-for-output.yaml @@ -0,0 +1,14 @@ +## Checks that there is specific output when creating a manifest + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f manifests.yaml 2>&1 | grep -q 'variable {{serviceAccountName}} is not allowed' + then + echo "Test succeeded. The phrase 'variable {{serviceAccountName}} is not allowed' is found." + exit 0 + else + echo "Test failed. The phrase 'variable {{serviceAccountName}} is not allowed' has not been found." + exit 1 + fi \ No newline at end of file diff --git a/test/conformance/manifests/validate/fail/background-vars-serviceaccountname.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/02-errors.yaml similarity index 90% rename from test/conformance/manifests/validate/fail/background-vars-serviceaccountname.yaml rename to test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/02-errors.yaml index 2efd9e3834a9..27144825acd1 100644 --- a/test/conformance/manifests/validate/fail/background-vars-serviceaccountname.yaml +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/02-errors.yaml @@ -17,4 +17,4 @@ spec: pattern: metadata: labels: - baz: "{{serviceAccountName}}" + baz: "{{serviceAccountName}}" \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/README.md b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/README.md new file mode 100644 index 000000000000..80d57b93cfea --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/README.md @@ -0,0 +1,3 @@ +# Title + +Ensures this policy cannot be created because clusterRoles is not valid in background mode. It checks that the return failure output contains the given string and finally checks that the policy has not been created (in case somehow it returned an error, which passed, but was still created). \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/manifests.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/manifests.yaml new file mode 100644 index 000000000000..27144825acd1 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-serviceAccountName/manifests.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: background-vars-serviceaccountname +spec: + validationFailureAction: audit + background: true + rules: + - name: ns-vars-serviceaccountname + match: + any: + - resources: + kinds: + - Pod + validate: + message: The `owner` label is required for all Namespaces. + pattern: + metadata: + labels: + baz: "{{serviceAccountName}}" \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/01-script-check-for-output.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/01-script-check-for-output.yaml new file mode 100644 index 000000000000..eecf0a850a66 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/01-script-check-for-output.yaml @@ -0,0 +1,14 @@ +## Checks that there is specific output when creating a manifest + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f manifests.yaml 2>&1 | grep -q 'variable {{request.userInfo}} is not allowed' + then + echo "Test succeeded. The phrase 'variable {{request.userInfo}} is not allowed' is found." + exit 0 + else + echo "Test failed. The phrase 'variable {{request.userInfo}} is not allowed' has not been found." + exit 1 + fi \ No newline at end of file diff --git a/test/conformance/manifests/validate/fail/background-vars-userinfo.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/02-errors.yaml similarity index 90% rename from test/conformance/manifests/validate/fail/background-vars-userinfo.yaml rename to test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/02-errors.yaml index 087ae2e26a69..937292c5842d 100644 --- a/test/conformance/manifests/validate/fail/background-vars-userinfo.yaml +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/02-errors.yaml @@ -17,4 +17,4 @@ spec: pattern: metadata: labels: - owner: "{{request.userInfo}}" + owner: "{{request.userInfo}}" \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/README.md b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/README.md new file mode 100644 index 000000000000..80d57b93cfea --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/README.md @@ -0,0 +1,3 @@ +# Title + +Ensures this policy cannot be created because clusterRoles is not valid in background mode. It checks that the return failure output contains the given string and finally checks that the policy has not been created (in case somehow it returned an error, which passed, but was still created). \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/manifests.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/manifests.yaml new file mode 100644 index 000000000000..937292c5842d --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/audit/background-vars-userInfo/manifests.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: background-vars-userinfo +spec: + validationFailureAction: audit + background: true + rules: + - name: ns-vars-userinfo + match: + any: + - resources: + kinds: + - Pod + validate: + message: The `owner` label is required for all Namespaces. + pattern: + metadata: + labels: + owner: "{{request.userInfo}}" \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/01-assert.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/01-assert.yaml new file mode 100644 index 000000000000..8d9a20c329cb --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-owner +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/01-manifests.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/01-manifests.yaml new file mode 100644 index 000000000000..ad80531fb77d --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/01-manifests.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: require-owner +spec: + validationFailureAction: enforce + background: false + rules: + - name: check-owner + match: + any: + - resources: + kinds: + - Namespace + validate: + message: The `owner` label is required for all Namespaces. + pattern: + metadata: + labels: + owner: "?*" \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/02-script.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/02-script.yaml new file mode 100644 index 000000000000..7580344147fe --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/02-script.yaml @@ -0,0 +1,14 @@ +## Checks that the manifests.yaml file CANNOT be successfully created. If it can, fail the test as this is incorrect. + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f resource.yaml + then + echo "Tested failed. Resource was allowed." + exit 1 + else + echo "Test succeeded. Resource was blocked." + exit 0 + fi \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/03-errors.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/03-errors.yaml new file mode 100644 index 000000000000..095067671584 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/03-errors.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: mytestingns + labels: + app-type: corp + annotations: + cloud.platformzero.com/serviceClass: "xl2" \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/99-cleanup.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/99-cleanup.yaml new file mode 100644 index 000000000000..15c3c4905153 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/README.md b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/README.md new file mode 100644 index 000000000000..b9ed7e236ea0 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/README.md @@ -0,0 +1,3 @@ +# Title + +Basic validate test to check that a violating resource cannot be created when the policy is in enforce mode. \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/resource.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/resource.yaml new file mode 100644 index 000000000000..095067671584 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/resource.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: mytestingns + labels: + app-type: corp + annotations: + cloud.platformzero.com/serviceClass: "xl2" \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/01-assert.yaml new file mode 100644 index 000000000000..8679bbbc1d97 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: secret-in-keys +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/01-manifests.yaml new file mode 100644 index 000000000000..2ef0abb272c9 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/01-manifests.yaml @@ -0,0 +1,39 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: test-verify-images +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: secret-in-keys +spec: + validationFailureAction: enforce + background: false + webhookTimeoutSeconds: 30 + failurePolicy: Fail + rules: + - name: check-secret-in-keys + match: + any: + - resources: + kinds: + - Pod + verifyImages: + - imageReferences: + - "ghcr.io/kyverno/test-verify-image:*" + attestors: + - entries: + - keys: + secret: + name: testsecret + namespace: test-verify-images +--- +apiVersion: v1 +kind: Secret +metadata: + name: testsecret + namespace: test-verify-images +data: + cosign.pub: LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFOG5YUmg5NTBJWmJSajhSYS9OOXNicU9QWnJmTQo1L0tBUU4wL0tqSGNvcm0vSjV5Y3RWZDdpRWNuZXNzUlFqVTkxN2htS082SldWR0hwRGd1SXlha1pBPT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0t +type: Opaque diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/02-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/02-assert.yaml new file mode 100644 index 000000000000..b736ae3d4860 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/02-assert.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Pod +metadata: + name: test-secret-pod + namespace: test-verify-images \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/02-goodpod.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/02-goodpod.yaml new file mode 100644 index 000000000000..de7987da272a --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/02-goodpod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: test-secret-pod + namespace: test-verify-images +spec: + containers: + - image: ghcr.io/kyverno/test-verify-image:signed + name: test-secret \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/99-cleanup.yaml new file mode 100644 index 000000000000..61b75559765b --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-goodpod.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/README.md b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/README.md new file mode 100644 index 000000000000..3cb272bb5599 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/README.md @@ -0,0 +1,3 @@ +# Title + +This test tries to verify an image from a public key stored in a Kubernetes Secret. For version 1.9+. \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/01-assert.yaml new file mode 100644 index 000000000000..4b3e65c71533 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: keyless-mutatedigest-verifydigest-required +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/01-manifests.yaml new file mode 100644 index 000000000000..fb5a00a5642a --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/01-manifests.yaml @@ -0,0 +1,27 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: keyless-mutatedigest-verifydigest-required +spec: + validationFailureAction: enforce + webhookTimeoutSeconds: 30 + rules: + - name: check-builder-id-keyless + match: + any: + - resources: + kinds: + - Pod + verifyImages: + - imageReferences: + - "ghcr.io/chipzoller/zulu:*" + mutateDigest: true + verifyDigest: true + required: true + attestors: + - entries: + - keyless: + subject: "https://github.com/chipzoller/zulu/.github/workflows/slsa-generic-keyless.yaml@refs/tags/v*" + issuer: "https://token.actions.githubusercontent.com" + rekor: + url: https://rekor.sigstore.dev \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/02-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/02-assert.yaml new file mode 100644 index 000000000000..79cb2b586be4 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/02-assert.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + annotations: + kyverno.io/verify-images: '{"ghcr.io/chipzoller/zulu@sha256:476b21f1a75dc90fac3579ee757f4607bb5546f476195cf645c54badf558c0db":true}' + name: zulu + namespace: default +spec: + containers: + - image: ghcr.io/chipzoller/zulu:v0.0.14@sha256:476b21f1a75dc90fac3579ee757f4607bb5546f476195cf645c54badf558c0db + name: zulu \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/02-pod.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/02-pod.yaml new file mode 100644 index 000000000000..f5619b68734a --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/02-pod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: zulu + namespace: default +spec: + containers: + - image: ghcr.io/chipzoller/zulu:v0.0.14 + name: zulu \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/99-cleanup.yaml new file mode 100644 index 000000000000..1f710a50a66f --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-pod.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/README.md b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/README.md new file mode 100644 index 000000000000..7ce10ee11d26 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/README.md @@ -0,0 +1,3 @@ +# Title + +This is a description of your test. diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/01-assert.yaml new file mode 100644 index 000000000000..320fe9bd541d --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: keyless-nomutatedigest-noverifydigest-norequired +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/01-manifests.yaml new file mode 100644 index 000000000000..507a11c41a66 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/01-manifests.yaml @@ -0,0 +1,27 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: keyless-nomutatedigest-noverifydigest-norequired +spec: + validationFailureAction: enforce + webhookTimeoutSeconds: 30 + rules: + - name: check-builder-id-keyless + match: + any: + - resources: + kinds: + - Pod + verifyImages: + - imageReferences: + - "ghcr.io/chipzoller/zulu*" + mutateDigest: false + verifyDigest: false + required: false + attestors: + - entries: + - keyless: + subject: "https://github.com/chipzoller/zulu/.github/workflows/slsa-generic-keyless.yaml@refs/tags/v*" + issuer: "https://token.actions.githubusercontent.com" + rekor: + url: https://rekor.sigstore.dev \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/02-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/02-assert.yaml new file mode 100644 index 000000000000..2d32ed3cb681 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/02-assert.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + annotations: + kyverno.io/verify-images: '{"ghcr.io/chipzoller/zulu:latest":true}' + name: zulu + namespace: default +spec: + containers: + - image: ghcr.io/chipzoller/zulu + name: zulu \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/02-pod.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/02-pod.yaml new file mode 100644 index 000000000000..5160f6f59349 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/02-pod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: zulu + namespace: default +spec: + containers: + - image: ghcr.io/chipzoller/zulu + name: zulu \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/99-cleanup.yaml new file mode 100644 index 000000000000..1f710a50a66f --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-pod.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/README.md b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/README.md new file mode 100644 index 000000000000..7ce10ee11d26 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/README.md @@ -0,0 +1,3 @@ +# Title + +This is a description of your test. diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/01-assert.yaml new file mode 100644 index 000000000000..304da4359d37 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: keyless-nomutatedigest-noverifydigest-required +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/01-manifests.yaml new file mode 100644 index 000000000000..4c18f321ae7f --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/01-manifests.yaml @@ -0,0 +1,27 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: keyless-nomutatedigest-noverifydigest-required +spec: + validationFailureAction: enforce + webhookTimeoutSeconds: 30 + rules: + - name: check-builder-id-keyless + match: + any: + - resources: + kinds: + - Pod + verifyImages: + - imageReferences: + - "ghcr.io/chipzoller/zulu*" + mutateDigest: false + verifyDigest: false + required: true + attestors: + - entries: + - keyless: + subject: "https://github.com/chipzoller/zulu/.github/workflows/slsa-generic-keyless.yaml@refs/tags/v*" + issuer: "https://token.actions.githubusercontent.com" + rekor: + url: https://rekor.sigstore.dev \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/02-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/02-assert.yaml new file mode 100644 index 000000000000..2d32ed3cb681 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/02-assert.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + annotations: + kyverno.io/verify-images: '{"ghcr.io/chipzoller/zulu:latest":true}' + name: zulu + namespace: default +spec: + containers: + - image: ghcr.io/chipzoller/zulu + name: zulu \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/02-pod.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/02-pod.yaml new file mode 100644 index 000000000000..5160f6f59349 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/02-pod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: zulu + namespace: default +spec: + containers: + - image: ghcr.io/chipzoller/zulu + name: zulu \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/99-cleanup.yaml new file mode 100644 index 000000000000..1f710a50a66f --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-pod.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/README.md b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/README.md new file mode 100644 index 000000000000..7ce10ee11d26 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/README.md @@ -0,0 +1,3 @@ +# Title + +This is a description of your test. diff --git a/test/conformance/manifests/generate/foo.yaml b/test/conformance/manifests/generate/foo.yaml deleted file mode 100644 index f4572339b970..000000000000 --- a/test/conformance/manifests/generate/foo.yaml +++ /dev/null @@ -1 +0,0 @@ -# placeholder \ No newline at end of file diff --git a/test/conformance/manifests/mutate/foo.yaml b/test/conformance/manifests/mutate/foo.yaml deleted file mode 100644 index f4572339b970..000000000000 --- a/test/conformance/manifests/mutate/foo.yaml +++ /dev/null @@ -1 +0,0 @@ -# placeholder \ No newline at end of file diff --git a/test/conformance/manifests/verifyImages/foo.yaml b/test/conformance/manifests/verifyImages/foo.yaml deleted file mode 100644 index f4572339b970..000000000000 --- a/test/conformance/manifests/verifyImages/foo.yaml +++ /dev/null @@ -1 +0,0 @@ -# placeholder \ No newline at end of file From 745482a0e4055cf1a85856ffb0808fdfc5a6bdd4 Mon Sep 17 00:00:00 2001 From: Chip Zoller Date: Fri, 4 Nov 2022 11:58:24 -0400 Subject: [PATCH 13/55] add remainder of e2e verifyImages tests (#5229) Signed-off-by: Chip Zoller Signed-off-by: Chip Zoller --- .../01-assert.yaml | 6 ++ .../01-manifests.yaml | 63 +++++++++++++++++++ .../02-task.yaml | 9 +++ .../03-assert.yaml | 7 +++ .../99-cleanup.yaml | 4 ++ .../imageExtractors-complex-keyless/README.md | 3 + .../imageExtractors-complex/01-assert.yaml | 6 ++ .../imageExtractors-complex/01-manifests.yaml | 60 ++++++++++++++++++ .../02-create-task.yaml | 14 +++++ .../imageExtractors-complex/03-errors.yaml | 5 ++ .../imageExtractors-complex/99-cleanup.yaml | 4 ++ .../imageExtractors-complex/README.md | 3 + .../imageExtractors-complex/badtask.yaml | 9 +++ .../imageExtractors-none/01-assert.yaml | 6 ++ .../imageExtractors-none/01-manifests.yaml | 54 ++++++++++++++++ .../imageExtractors-none/02-task.yaml | 9 +++ .../imageExtractors-none/03-assert.yaml | 5 ++ .../imageExtractors-none/99-cleanup.yaml | 4 ++ .../standard/imageExtractors-none/README.md | 3 + .../imageExtractors-simple/01-assert.yaml | 6 ++ .../imageExtractors-simple/01-manifests.yaml | 58 +++++++++++++++++ .../02-create-task.yaml | 14 +++++ .../imageExtractors-simple/03-errors.yaml | 5 ++ .../imageExtractors-simple/99-cleanup.yaml | 4 ++ .../standard/imageExtractors-simple/README.md | 3 + .../imageExtractors-simple/badtask.yaml | 9 +++ 26 files changed, 373 insertions(+) create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-manifests.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/02-task.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/03-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/README.md create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-manifests.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/02-create-task.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/03-errors.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/README.md create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/badtask.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-manifests.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/02-task.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/03-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/README.md create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-manifests.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/02-create-task.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/03-errors.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/README.md create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/badtask.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-assert.yaml new file mode 100644 index 000000000000..33390d5dcbbc --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: tasks-keyless +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-manifests.yaml new file mode 100644 index 000000000000..bf239d5aaeb4 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-manifests.yaml @@ -0,0 +1,63 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: tekton-test +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tasks.tekton.dev +spec: + group: tekton.dev + preserveUnknownFields: false + versions: + - name: v1beta1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + subresources: + status: {} + names: + kind: Task + plural: tasks + categories: + - tekton + - tekton-pipelines + scope: Namespaced +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: tasks-keyless +spec: + validationFailureAction: enforce + webhookTimeoutSeconds: 30 + rules: + - name: verify-images + match: + any: + - resources: + kinds: + - tekton.dev/v1beta1/Task + preconditions: + - key: "{{request.operation}}" + operator: NotEquals + value: DELETE + imageExtractors: + Task: + - path: /spec/steps/*/image + verifyImages: + - imageReferences: + - "ghcr.io/*" + attestors: + - count: 1 + entries: + - keyless: + issuer: "https://token.actions.githubusercontent.com" + subject: "https://github.com/*" + rekor: + url: https://rekor.sigstore.dev + required: true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/02-task.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/02-task.yaml new file mode 100644 index 000000000000..797d2f4dd945 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/02-task.yaml @@ -0,0 +1,9 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: example-task-name + namespace: tekton-test +spec: + steps: + - name: cosign + image: ghcr.io/sigstore/cosign/cosign@sha256:33a6a55d2f1354bc989b791974cf4ee00a900ab9e4e54b393962321758eee3c6 \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/03-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/03-assert.yaml new file mode 100644 index 000000000000..00a796d51627 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/03-assert.yaml @@ -0,0 +1,7 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: example-task-name + namespace: tekton-test + annotations: + kyverno.io/verify-images: '{"ghcr.io/sigstore/cosign/cosign@sha256:33a6a55d2f1354bc989b791974cf4ee00a900ab9e4e54b393962321758eee3c6":true}' \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/99-cleanup.yaml new file mode 100644 index 000000000000..901039dff198 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-task.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/README.md b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/README.md new file mode 100644 index 000000000000..6abc915a9b6d --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/README.md @@ -0,0 +1,3 @@ +# Title + +Checks that more complex image extraction with keyless verification and required=true is working by submitting a Task which uses a verified container image. The Task should be created and the annotation `kyverno.io/verify-images` written which contains the image with digest and `true` indicating it was verified. \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-assert.yaml new file mode 100644 index 000000000000..4e8ef06f0863 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: tasks-complex +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-manifests.yaml new file mode 100644 index 000000000000..a14488e3a1d2 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-manifests.yaml @@ -0,0 +1,60 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: tekton-test +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tasks.tekton.dev +spec: + group: tekton.dev + preserveUnknownFields: false + versions: + - name: v1beta1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + subresources: + status: {} + names: + kind: Task + plural: tasks + categories: + - tekton + - tekton-pipelines + scope: Namespaced +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: tasks-complex +spec: + validationFailureAction: enforce + rules: + - name: verify-images + match: + any: + - resources: + kinds: + - tekton.dev/v1beta1/Task + preconditions: + - key: "{{request.operation}}" + operator: NotEquals + value: DELETE + imageExtractors: + Task: + - path: /spec/steps/* + name: steps + value: image + key: name + verifyImages: + - image: "*" + key: |- + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM + 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== + -----END PUBLIC KEY----- diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/02-create-task.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/02-create-task.yaml new file mode 100644 index 000000000000..850b8c6eb619 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/02-create-task.yaml @@ -0,0 +1,14 @@ +## Checks that the manifests.yaml file CANNOT be successfully created. If it can, fail the test as this is incorrect. + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f badtask.yaml + then + echo "Tested failed. Task was created when it shouldn't have been." + exit 1 + else + echo "Test succeeded. Task was not created as intended." + exit 0 + fi \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/03-errors.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/03-errors.yaml new file mode 100644 index 000000000000..de1b3f099bfe --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/03-errors.yaml @@ -0,0 +1,5 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: example-task-name + namespace: tekton-test \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/99-cleanup.yaml new file mode 100644 index 000000000000..15c3c4905153 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/README.md b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/README.md new file mode 100644 index 000000000000..698da27e0311 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/README.md @@ -0,0 +1,3 @@ +# Title + +Checks that more complex image extraction is working by submitting a Task which uses an unverified container image. The Task should fail to be created since the supplied public key is not valid for it (the image is unsigned). \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/badtask.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/badtask.yaml new file mode 100644 index 000000000000..192d130a6bf2 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/badtask.yaml @@ -0,0 +1,9 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: example-task-name + namespace: tekton-test +spec: + steps: + - name: ubuntu-example + image: ubuntu:bionic diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-assert.yaml new file mode 100644 index 000000000000..e51f26047c74 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: tasks-no-extractor +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-manifests.yaml new file mode 100644 index 000000000000..b643df8eb35e --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-manifests.yaml @@ -0,0 +1,54 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: tekton-test +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tasks.tekton.dev +spec: + group: tekton.dev + preserveUnknownFields: false + versions: + - name: v1beta1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + subresources: + status: {} + names: + kind: Task + plural: tasks + categories: + - tekton + - tekton-pipelines + scope: Namespaced +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: tasks-no-extractor +spec: + validationFailureAction: enforce + rules: + - name: verify-images + match: + any: + - resources: + kinds: + - tekton.dev/v1beta1/Task + preconditions: + - key: "{{request.operation}}" + operator: NotEquals + value: DELETE + verifyImages: + - image: "*" + key: |- + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM + 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== + -----END PUBLIC KEY----- \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/02-task.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/02-task.yaml new file mode 100644 index 000000000000..192d130a6bf2 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/02-task.yaml @@ -0,0 +1,9 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: example-task-name + namespace: tekton-test +spec: + steps: + - name: ubuntu-example + image: ubuntu:bionic diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/03-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/03-assert.yaml new file mode 100644 index 000000000000..de1b3f099bfe --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/03-assert.yaml @@ -0,0 +1,5 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: example-task-name + namespace: tekton-test \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/99-cleanup.yaml new file mode 100644 index 000000000000..901039dff198 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-task.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/README.md b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/README.md new file mode 100644 index 000000000000..d4dd872f5192 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/README.md @@ -0,0 +1,3 @@ +# Title + +Checks that a ClusterPolicy without defining an imageExtractor causes a CustomResource to pass through. Since the ClusterPolicy does not name a field from which to extract the image, no verification can be performed. Expected result is the Task is created even though the image within is not verified. \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-assert.yaml new file mode 100644 index 000000000000..9dc5e6e273a9 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: tasks-simple +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-manifests.yaml new file mode 100644 index 000000000000..b59928742a01 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-manifests.yaml @@ -0,0 +1,58 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: tekton-test +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tasks.tekton.dev +spec: + group: tekton.dev + preserveUnknownFields: false + versions: + - name: v1beta1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + subresources: + status: {} + names: + kind: Task + plural: tasks + categories: + - tekton + - tekton-pipelines + scope: Namespaced +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: tasks-simple +spec: + validationFailureAction: enforce + rules: + - name: verify-images + match: + any: + - resources: + kinds: + - tekton.dev/v1beta1/Task + preconditions: + - key: "{{request.operation}}" + operator: NotEquals + value: DELETE + imageExtractors: + Task: + - path: /spec/steps/*/image + verifyImages: + - image: "*" + key: |- + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM + 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== + -----END PUBLIC KEY----- +--- diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/02-create-task.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/02-create-task.yaml new file mode 100644 index 000000000000..850b8c6eb619 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/02-create-task.yaml @@ -0,0 +1,14 @@ +## Checks that the manifests.yaml file CANNOT be successfully created. If it can, fail the test as this is incorrect. + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f badtask.yaml + then + echo "Tested failed. Task was created when it shouldn't have been." + exit 1 + else + echo "Test succeeded. Task was not created as intended." + exit 0 + fi \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/03-errors.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/03-errors.yaml new file mode 100644 index 000000000000..de1b3f099bfe --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/03-errors.yaml @@ -0,0 +1,5 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: example-task-name + namespace: tekton-test \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/99-cleanup.yaml new file mode 100644 index 000000000000..15c3c4905153 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/README.md b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/README.md new file mode 100644 index 000000000000..dd7287ff04c6 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/README.md @@ -0,0 +1,3 @@ +# Title + +Checks that simple image extraction is working by submitting a Task which uses an unverified container image. The Task should fail to be created since the supplied public key is not valid for it (the image is unsigned). \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/badtask.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/badtask.yaml new file mode 100644 index 000000000000..192d130a6bf2 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/badtask.yaml @@ -0,0 +1,9 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: example-task-name + namespace: tekton-test +spec: + steps: + - name: ubuntu-example + image: ubuntu:bionic From 5557d6c85d7e1866ebd3bed5c1c3a4c9d55a3881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Fri, 4 Nov 2022 17:38:05 +0100 Subject: [PATCH 14/55] feat: add grafana dashboard to helm chart (#5230) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add grafana dashboard to helm chart Signed-off-by: Charles-Edouard Brétéché * release note Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché Co-authored-by: treydock --- charts/kyverno/Chart.yaml | 2 + charts/kyverno/README.md | 5 +- charts/kyverno/grafana/dashboard.json | 2854 +++++++++++++++++++++++++ charts/kyverno/templates/grafana.yaml | 13 + charts/kyverno/values.yaml | 11 +- 5 files changed, 2883 insertions(+), 2 deletions(-) create mode 100644 charts/kyverno/grafana/dashboard.json create mode 100644 charts/kyverno/templates/grafana.yaml diff --git a/charts/kyverno/Chart.yaml b/charts/kyverno/Chart.yaml index 86e3944b39ce..1943a3081a63 100644 --- a/charts/kyverno/Chart.yaml +++ b/charts/kyverno/Chart.yaml @@ -50,3 +50,5 @@ annotations: description: Add startup probes support - kind: added description: Support extra CRD annotations + - kind: added + description: Grafana dashboard. diff --git a/charts/kyverno/README.md b/charts/kyverno/README.md index 0d19727afc08..4164ad63b2e2 100644 --- a/charts/kyverno/README.md +++ b/charts/kyverno/README.md @@ -210,7 +210,10 @@ The command removes all the Kubernetes components associated with the chart and | networkPolicy.ingressFrom | list | `[]` | A list of valid from selectors according to https://kubernetes.io/docs/concepts/services-networking/network-policies. | | webhooksCleanup.enable | bool | `false` | Create a helm pre-delete hook to cleanup webhooks. | | webhooksCleanup.image | string | `"bitnami/kubectl:latest"` | `kubectl` image to run commands for deleting webhooks. | -| tufRootMountPath | string | `"/.sigstore"` | A writable volume to use for the TUF root initialization | +| tufRootMountPath | string | `"/.sigstore"` | A writable volume to use for the TUF root initialization. | +| grafana.enabled | bool | `false` | Enable grafana dashboard creation. | +| grafana.namespace | string | `nil` | Namespace to create the grafana dashboard configmap. If not set, it will be created in the same namespace where the chart is deployed. | +| grafana.annotations | object | `{}` | Grafana dashboard configmap annotations. | ## TLS Configuration diff --git a/charts/kyverno/grafana/dashboard.json b/charts/kyverno/grafana/dashboard.json new file mode 100644 index 000000000000..f98d01124da5 --- /dev/null +++ b/charts/kyverno/grafana/dashboard.json @@ -0,0 +1,2854 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS_KYVERNO", + "label": "Prometheus Data Source exposing Kyverno's metrics", + "description": "Prometheus Data Source exposing Kyverno's metrics", + "type": "datasource" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "description": "", + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 2, + "iteration": 1628375170149, + "links": [], + "panels": [ + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 42, + "options": { + "content": "# Kyverno\nA Kubernetes-native policy management engine\n\n#### About this dashboard\n\nThis dashboard represents generic insights that can be extracted from a cluster with Kyverno running.\n\n#### For more details around the metrics\n\nCheckout the [official docs of Kyverno metrics](https://kyverno.io/docs/monitoring/)", + "mode": "markdown" + }, + "pluginVersion": "8.1.0", + "timeFrom": null, + "timeShift": null, + "transparent": true, + "type": "text" + }, + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 12, + "panels": [], + "title": "Latest Status", + "type": "row" + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "red", + "value": 50 + }, + { + "color": "#EAB839", + "value": 75 + }, + { + "color": "green", + "value": 100 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 7 + }, + "id": 29, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "sum(delta(kyverno_policy_results_total{rule_result=\"fail\"}[24h]))*100/sum(delta(kyverno_policy_results_total{}[24h]))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Rule Execution Failure Rate (Last 24 Hours)", + "transparent": true, + "type": "gauge" + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 4, + "x": 8, + "y": 7 + }, + "id": 2, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "count(count(kyverno_policy_rule_info_total{policy_type=\"cluster\"}==1) by (policy_name))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Cluster Policies", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 4, + "x": 12, + "y": 7 + }, + "id": 3, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "count(count(kyverno_policy_rule_info_total{policy_type=\"namespaced\"}==1) by (policy_name))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Policies", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 100, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "red", + "value": 50 + }, + { + "color": "#EAB839", + "value": 75 + }, + { + "color": "green", + "value": 100 + } + ] + }, + "unit": "percent" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 7 + }, + "id": 28, + "options": { + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "text": {} + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "sum(delta(kyverno_policy_results_total{rule_result=\"fail\", policy_background_mode=\"true\"}[24h]))*100/sum(delta(kyverno_policy_results_total{policy_background_mode=\"true\"}[24h]))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Background Scans Failure Rate (Last 24 Hours)", + "transparent": true, + "type": "gauge" + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 6, + "y": 12 + }, + "id": 4, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "count(kyverno_policy_rule_info_total{rule_type=\"validate\"}==1)", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Validate Rules", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 10, + "y": 12 + }, + "id": 23, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "count(kyverno_policy_rule_info_total{rule_type=\"mutate\"}==1)", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Mutate Rules", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 4, + "x": 14, + "y": 12 + }, + "id": 6, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "count(kyverno_policy_rule_info_total{rule_type=\"generate\"}==1)", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Generate Rules", + "type": "stat" + }, + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 26, + "panels": [], + "title": "Policy-Rule Results", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 17 + }, + "hiddenSeries": false, + "id": 15, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:2021", + "alias": "pass", + "color": "rgb(43, 219, 23)", + "dashes": true + }, + { + "$$hashKey": "object:2029", + "alias": "fail", + "color": "#F2495C" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(delta(kyverno_policy_results_total{rule_execution_cause=\"admission_request\"}[5m])) by (rule_result)", + "interval": "", + "legendFormat": "{{rule_result}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Admission Review Results (per-rule)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 17 + }, + "hiddenSeries": false, + "id": 17, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:2021", + "alias": "pass", + "color": "rgb(43, 219, 23)", + "dashes": true + }, + { + "$$hashKey": "object:2029", + "alias": "fail", + "color": "#F2495C" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(delta(kyverno_policy_results_total{rule_execution_cause=\"background_scan\"}[5m])) by (rule_result)", + "interval": "", + "legendFormat": "{{rule_result}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Background Scan Results (per-rule)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 16, + "w": 8, + "x": 16, + "y": 17 + }, + "hiddenSeries": false, + "id": 30, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:2021", + "alias": "cluster", + "color": "#5794F2", + "dashes": true + }, + { + "$$hashKey": "object:2029", + "alias": "namespaced", + "color": "#F2495C", + "dashes": true + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(sum(delta(kyverno_policy_results_total{rule_result=\"fail\"}[5m])) by (policy_name, policy_type)) by (policy_type)", + "interval": "", + "legendFormat": "{{policy_type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Policy Failures", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 25 + }, + "hiddenSeries": false, + "id": 31, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:2021", + "alias": "pass", + "color": "rgb(43, 219, 23)", + "dashes": true + }, + { + "$$hashKey": "object:2029", + "alias": "fail", + "color": "#F2495C" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(sum(delta(kyverno_policy_results_total{rule_execution_cause=\"admission_request\"}[5m])) by (policy_name, rule_result)) by (rule_result)", + "interval": "", + "legendFormat": "{{rule_result}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Admission Review Results (per-policy)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 25 + }, + "hiddenSeries": false, + "id": 32, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:2021", + "alias": "pass", + "color": "rgb(43, 219, 23)", + "dashes": true + }, + { + "$$hashKey": "object:2029", + "alias": "fail", + "color": "#F2495C" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(sum(delta(kyverno_policy_results_total{rule_execution_cause=\"background_scan\"}[5m])) by (policy_name, rule_result)) by (rule_result)", + "interval": "", + "legendFormat": "{{rule_result}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Background Scan Results (per-policy)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 33 + }, + "id": 19, + "panels": [], + "title": "Policy-Rule Info", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 34 + }, + "hiddenSeries": false, + "id": 16, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:3795", + "alias": "cluster", + "color": "#5794F2" + }, + { + "$$hashKey": "object:3800", + "alias": "namespaced", + "color": "#FF7383" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "count(count(kyverno_policy_rule_info_total{}==1) by (policy_name, policy_type)) by (policy_type)", + "interval": "", + "legendFormat": "{{policy_type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Active Policies (by policy type)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 34 + }, + "hiddenSeries": false, + "id": 20, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:3319", + "alias": "audit", + "color": "#37872D" + }, + { + "$$hashKey": "object:3335", + "alias": "enforce", + "color": "#FF9830" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "count(count(kyverno_policy_rule_info_total{}==1) by (policy_name, policy_validation_mode)) by (policy_validation_mode)", + "interval": "", + "legendFormat": "audit", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Active Policies (by policy validation action)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 34 + }, + "hiddenSeries": false, + "id": 24, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:3934", + "alias": "cluster", + "color": "#B877D9" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "count(count(kyverno_policy_rule_info_total{policy_background_mode=\"true\"}==1) by (policy_name, policy_type)) by (policy_type)", + "interval": "", + "legendFormat": "{{policy_type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Active Policies running in background mode", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 42 + }, + "hiddenSeries": false, + "id": 21, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "count(count(kyverno_policy_rule_info_total{policy_namespace!=\"-\"}==1) by (policy_name, policy_namespace)) by (policy_namespace)", + "interval": "", + "legendFormat": "{{policy_namespace}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Active Namespaced Policies (by namespaces)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 10, + "x": 8, + "y": 42 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:3021", + "alias": "mutate", + "color": "rgb(169, 58, 227)" + }, + { + "$$hashKey": "object:3029", + "alias": "validate", + "color": "rgb(255, 232, 0)" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "count(kyverno_policy_rule_info_total{}==1) by (rule_type)", + "interval": "", + "legendFormat": "{{rule_type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Active Rules (by rule type)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 50 + }, + "id": 34, + "panels": [], + "title": "Policy-Rule Execution Latency", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 9, + "x": 0, + "y": 51 + }, + "hiddenSeries": false, + "id": 36, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(kyverno_policy_execution_duration_seconds_sum{}[5m])) by (rule_type) / sum(rate(kyverno_policy_execution_duration_seconds_count{}[5m])) by (rule_type)", + "interval": "", + "legendFormat": "{{rule_type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average Rule Execution Latency Over Time", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:5548", + "format": "s", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:5549", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 9, + "x": 9, + "y": 51 + }, + "hiddenSeries": false, + "id": 37, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:5526", + "alias": "cluster", + "color": "#5794F2" + }, + { + "$$hashKey": "object:5534", + "alias": "namespaced", + "color": "#F2495C" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(kyverno_policy_execution_duration_seconds_sum{}[5m])) by (policy_type) / sum(rate(kyverno_policy_execution_duration_seconds_count{}[5m])) by (policy_type)", + "interval": "", + "legendFormat": "{{policy_type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average Policy Execution Latency Over Time", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:5548", + "format": "clocks", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:5549", + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "purple", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 51 + }, + "id": 39, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "sum(kyverno_policy_execution_duration_seconds_sum{}) / sum(kyverno_policy_execution_duration_seconds_count{})", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Overall Average Rule Execution Latency", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 55 + }, + "id": 40, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "avg(sum(kyverno_policy_execution_duration_seconds_sum{}) by (policy_name, policy_type) / sum(kyverno_policy_execution_duration_seconds_count{}) by (policy_name, policy_type))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Overall Average Policy Execution Latency", + "type": "stat" + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 59 + }, + "id": 52, + "panels": [], + "title": "Admission Review Latency", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 9, + "x": 0, + "y": 60 + }, + "hiddenSeries": false, + "id": 53, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(kyverno_admission_review_duration_seconds_sum{}[5m])) by (resource_request_operation) / sum(rate(kyverno_admission_review_duration_seconds_count{}[5m])) by (resource_request_operation)", + "interval": "", + "legendFormat": "Resource Operation: {{resource_request_operation}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Avg - Admission Review Duration Over Time (by operation)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "transparent": true, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 9, + "x": 9, + "y": 60 + }, + "hiddenSeries": false, + "id": 54, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(kyverno_admission_review_duration_seconds_sum{}[5m])) by (resource_kind) / sum(rate(kyverno_admission_review_duration_seconds_count{}[5m])) by (resource_kind)", + "interval": "", + "legendFormat": "Resource Kind: {{resource_kind}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Avg - Admission Review Duration Over Time (by resource kind)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "transparent": true, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 60 + }, + "id": 50, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "sum(delta(kyverno_admission_requests_total{}[5m]))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Rate - Incoming Admission Requests (per 5m)", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "purple", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 64 + }, + "id": 55, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "sum(kyverno_admission_review_duration_seconds_sum{})/sum(kyverno_admission_review_duration_seconds_count{})", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Avg - Overall Admission Review Duration", + "type": "stat" + }, + { + "collapsed": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": {}, + "overrides": [] + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 68 + }, + "id": 8, + "panels": [], + "title": "Policy Changes", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 9, + "x": 0, + "y": 69 + }, + "hiddenSeries": false, + "id": 10, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:1487", + "alias": "Change type: created", + "color": "#5794F2" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(delta(kyverno_policy_changes_total{}[5m])) by (policy_change_type)", + "interval": "", + "legendFormat": "Change type: {{policy_change_type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Policy Changes Over Time (by change type)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "transparent": true, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 9, + "x": 9, + "y": 69 + }, + "hiddenSeries": false, + "id": 13, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:1679", + "alias": "cluster", + "color": "#F2495C" + }, + { + "$$hashKey": "object:1769" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(delta(kyverno_policy_changes_total{}[5m])) by (policy_type)", + "interval": "", + "legendFormat": "{{policy_type}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Policy Changes Over Time (by policy type)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "orange", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 69 + }, + "id": 49, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "sum(delta(kyverno_policy_changes_total{}[24h]))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Total Policy Changes (Last 24 Hours)", + "type": "stat" + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 73 + }, + "id": 48, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "sum(rate(kyverno_policy_changes_total{}[5m]))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Rate - Policy Changes Happening (last 5m)", + "type": "stat" + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 77 + }, + "id": 44, + "panels": [], + "title": "Admission Requests", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 9, + "x": 0, + "y": 78 + }, + "hiddenSeries": false, + "id": 45, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:1487", + "alias": "Change type: created", + "color": "#5794F2" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(delta(kyverno_admission_requests_total{}[5m])) by (resource_request_operation)", + "interval": "", + "legendFormat": "Resource Operation: {{resource_request_operation}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Admission Requests (by operation)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "transparent": true, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 9, + "x": 9, + "y": 78 + }, + "hiddenSeries": false, + "id": 46, + "legend": { + "alignAsTable": true, + "avg": false, + "current": true, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.1.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "$$hashKey": "object:1487", + "alias": "Change type: created", + "color": "#5794F2" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "exemplar": true, + "expr": "sum(delta(kyverno_admission_requests_total{}[5m])) by (resource_kind)", + "interval": "", + "legendFormat": "Resource Kind: {{resource_kind}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Admission Requests (by resource kind)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "transparent": true, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:218", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:219", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "${DS_PROMETHEUS_KYVERNO}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "semi-dark-green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 6, + "x": 18, + "y": 78 + }, + "id": 47, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.1.0", + "targets": [ + { + "exemplar": true, + "expr": "sum(delta(kyverno_admission_requests_total{}[24h]))", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "title": "Total Admission Requests (Last 24 Hours)", + "type": "stat" + } + ], + "refresh": false, + "schemaVersion": 30, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "hide": 0, + "label": "datasource", + "name": "DS_PROMETHEUS_KYVERNO", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Kyverno", + "folder": "Kyverno", + "uid": "Rg8lWBG7k", + "version": "1.4.3" +} \ No newline at end of file diff --git a/charts/kyverno/templates/grafana.yaml b/charts/kyverno/templates/grafana.yaml new file mode 100644 index 000000000000..7f4fb3eea03b --- /dev/null +++ b/charts/kyverno/templates/grafana.yaml @@ -0,0 +1,13 @@ +{{- if .Values.grafana.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "kyverno.configMapName" . }}-grafana + namespace: {{ default (include "kyverno.namespace" .) .Values.grafana.namespace }} + annotations: + {{- toYaml .Values.grafana.annotations | nindent 4 }} + labels: + grafana_dashboard: "1" +data: +{{ (.Files.Glob "grafana/*").AsConfig | indent 2 }} +{{- end -}} diff --git a/charts/kyverno/values.yaml b/charts/kyverno/values.yaml index 54145767d5b6..1dac0f0ffcda 100644 --- a/charts/kyverno/values.yaml +++ b/charts/kyverno/values.yaml @@ -464,5 +464,14 @@ webhooksCleanup: # -- `kubectl` image to run commands for deleting webhooks. image: bitnami/kubectl:latest -# -- A writable volume to use for the TUF root initialization +# -- A writable volume to use for the TUF root initialization. tufRootMountPath: /.sigstore + +grafana: + # -- Enable grafana dashboard creation. + enabled: false + # -- Namespace to create the grafana dashboard configmap. + # If not set, it will be created in the same namespace where the chart is deployed. + namespace: + # -- Grafana dashboard configmap annotations. + annotations: {} From 6cdbd55f9379e9f05595dd60360656dbffee2054 Mon Sep 17 00:00:00 2001 From: Pratik Shah Date: Mon, 7 Nov 2022 10:59:16 +0530 Subject: [PATCH 15/55] Fixed description for secret name (#5228) Signed-off-by: Pratik Shah Signed-off-by: Vyankatesh --- api/kyverno/v1/image_verification_types.go | 4 +- charts/kyverno/templates/crds.yaml | 64 ++++----- config/crds/kyverno.io_clusterpolicies.yaml | 64 +++++---- config/crds/kyverno.io_policies.yaml | 64 +++++---- config/install.yaml | 152 ++++++++++++-------- config/install_debug.yaml | 152 ++++++++++++-------- docs/user/crd/index.html | 4 +- 7 files changed, 300 insertions(+), 204 deletions(-) diff --git a/api/kyverno/v1/image_verification_types.go b/api/kyverno/v1/image_verification_types.go index b110b91918ff..71e454e7c5ac 100644 --- a/api/kyverno/v1/image_verification_types.go +++ b/api/kyverno/v1/image_verification_types.go @@ -151,10 +151,10 @@ type StaticKeyAttestor struct { } type SecretReference struct { - // name of the secret + // Name of the secret. The provided secret must contain a key named cosign.pub. Name string `json:"name" yaml:"name"` - // namespace name in which secret is created + // Namespace name where the Secret exists. Namespace string `json:"namespace" yaml:"namespace"` } diff --git a/charts/kyverno/templates/crds.yaml b/charts/kyverno/templates/crds.yaml index 666672436eee..73d551a6aa5f 100644 --- a/charts/kyverno/templates/crds.yaml +++ b/charts/kyverno/templates/crds.yaml @@ -2461,10 +2461,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -2768,10 +2768,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -4240,10 +4240,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -4547,10 +4547,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -6008,10 +6008,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -6305,10 +6305,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -7762,10 +7762,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -8069,10 +8069,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -10132,10 +10132,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -10439,10 +10439,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -11911,10 +11911,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -12218,10 +12218,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -13679,10 +13679,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -13976,10 +13976,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -15433,10 +15433,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name @@ -15740,10 +15740,10 @@ spec: description: Reference to a Secret resource that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The provided secret must contain a key named cosign.pub. type: string namespace: - description: namespace name in which secret is created + description: Namespace name where the Secret exists. type: string required: - name diff --git a/config/crds/kyverno.io_clusterpolicies.yaml b/config/crds/kyverno.io_clusterpolicies.yaml index 3957319dcf85..f14a1bb5a7ae 100644 --- a/config/crds/kyverno.io_clusterpolicies.yaml +++ b/config/crds/kyverno.io_clusterpolicies.yaml @@ -2324,11 +2324,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -2785,11 +2787,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The + provided secret must contain a key + named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -5236,11 +5240,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name - in which secret is created + description: Namespace name + where the Secret exists. type: string required: - name @@ -5710,11 +5716,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in - which secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -7985,11 +7993,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -8431,11 +8441,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The + provided secret must contain a key + named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -10857,11 +10869,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name - in which secret is created + description: Namespace name + where the Secret exists. type: string required: - name @@ -11331,11 +11345,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in - which secret is created + description: Namespace name where + the Secret exists. type: string required: - name diff --git a/config/crds/kyverno.io_policies.yaml b/config/crds/kyverno.io_policies.yaml index ec56fa157956..1bb74a9b1f92 100644 --- a/config/crds/kyverno.io_policies.yaml +++ b/config/crds/kyverno.io_policies.yaml @@ -2325,11 +2325,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -2786,11 +2788,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The + provided secret must contain a key + named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -5238,11 +5242,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name - in which secret is created + description: Namespace name + where the Secret exists. type: string required: - name @@ -5712,11 +5718,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in - which secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -7988,11 +7996,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -8434,11 +8444,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The + provided secret must contain a key + named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -10860,11 +10872,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name - in which secret is created + description: Namespace name + where the Secret exists. type: string required: - name @@ -11334,11 +11348,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in - which secret is created + description: Namespace name where + the Secret exists. type: string required: - name diff --git a/config/install.yaml b/config/install.yaml index ac9fcc354951..489c1f373678 100644 --- a/config/install.yaml +++ b/config/install.yaml @@ -3646,11 +3646,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -4107,11 +4109,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The + provided secret must contain a key + named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -4200,9 +4204,9 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. - The default value is set to "true", it must be set to "false" to - disable the validation checks. + description: SchemaValidation skips validation checks for policies + as well as patched resources. Optional. The default value is set + to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -6558,11 +6562,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name - in which secret is created + description: Namespace name + where the Secret exists. type: string required: - name @@ -7032,11 +7038,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in - which secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -9307,11 +9315,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -9753,11 +9763,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The + provided secret must contain a key + named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -9821,9 +9833,9 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. - The default value is set to "true", it must be set to "false" to - disable the validation checks. + description: SchemaValidation skips validation checks for policies + as well as patched resources. Optional. The default value is set + to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -12179,11 +12191,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name - in which secret is created + description: Namespace name + where the Secret exists. type: string required: - name @@ -12653,11 +12667,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in - which secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -15745,11 +15761,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -16206,11 +16224,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The + provided secret must contain a key + named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -16299,9 +16319,9 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. - The default value is set to "true", it must be set to "false" to - disable the validation checks. + description: SchemaValidation skips validation checks for policies + as well as patched resources. Optional. The default value is set + to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -18658,11 +18678,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name - in which secret is created + description: Namespace name + where the Secret exists. type: string required: - name @@ -19132,11 +19154,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in - which secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -21408,11 +21432,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -21854,11 +21880,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The + provided secret must contain a key + named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -21922,9 +21950,9 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. - The default value is set to "true", it must be set to "false" to - disable the validation checks. + description: SchemaValidation skips validation checks for policies + as well as patched resources. Optional. The default value is set + to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -24280,11 +24308,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name - in which secret is created + description: Namespace name + where the Secret exists. type: string required: - name @@ -24754,11 +24784,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in - which secret is created + description: Namespace name where + the Secret exists. type: string required: - name diff --git a/config/install_debug.yaml b/config/install_debug.yaml index aaff31cd330e..ed75cb86d5d5 100644 --- a/config/install_debug.yaml +++ b/config/install_debug.yaml @@ -3640,11 +3640,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -4101,11 +4103,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The + provided secret must contain a key + named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -4194,9 +4198,9 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. - The default value is set to "true", it must be set to "false" to - disable the validation checks. + description: SchemaValidation skips validation checks for policies + as well as patched resources. Optional. The default value is set + to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -6552,11 +6556,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name - in which secret is created + description: Namespace name + where the Secret exists. type: string required: - name @@ -7026,11 +7032,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in - which secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -9301,11 +9309,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -9747,11 +9757,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The + provided secret must contain a key + named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -9815,9 +9827,9 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. - The default value is set to "true", it must be set to "false" to - disable the validation checks. + description: SchemaValidation skips validation checks for policies + as well as patched resources. Optional. The default value is set + to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -12173,11 +12185,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name - in which secret is created + description: Namespace name + where the Secret exists. type: string required: - name @@ -12647,11 +12661,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in - which secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -15736,11 +15752,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -16197,11 +16215,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The + provided secret must contain a key + named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -16290,9 +16310,9 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. - The default value is set to "true", it must be set to "false" to - disable the validation checks. + description: SchemaValidation skips validation checks for policies + as well as patched resources. Optional. The default value is set + to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -18649,11 +18669,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name - in which secret is created + description: Namespace name + where the Secret exists. type: string required: - name @@ -19123,11 +19145,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in - which secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -21399,11 +21423,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -21845,11 +21871,13 @@ spec: that contains a public key properties: name: - description: name of the secret + description: Name of the secret. The + provided secret must contain a key + named cosign.pub. type: string namespace: - description: namespace name in which - secret is created + description: Namespace name where + the Secret exists. type: string required: - name @@ -21913,9 +21941,9 @@ spec: type: object type: array schemaValidation: - description: SchemaValidation skips policy validation checks. Optional. - The default value is set to "true", it must be set to "false" to - disable the validation checks. + description: SchemaValidation skips validation checks for policies + as well as patched resources. Optional. The default value is set + to "true", it must be set to "false" to disable the validation checks. type: boolean validationFailureAction: default: audit @@ -24271,11 +24299,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name - in which secret is created + description: Namespace name + where the Secret exists. type: string required: - name @@ -24745,11 +24775,13 @@ spec: key properties: name: - description: name of the secret + description: Name of the secret. + The provided secret must contain + a key named cosign.pub. type: string namespace: - description: namespace name in - which secret is created + description: Namespace name where + the Secret exists. type: string required: - name diff --git a/docs/user/crd/index.html b/docs/user/crd/index.html index 23d3b63a3c0e..9517a934c552 100644 --- a/docs/user/crd/index.html +++ b/docs/user/crd/index.html @@ -3338,7 +3338,7 @@

SecretReference -

name of the secret

+

Name of the secret. The provided secret must contain a key named cosign.pub.

@@ -3349,7 +3349,7 @@

SecretReference -

namespace name in which secret is created

+

Namespace name where the Secret exists.

From 6325860c89772b6787c2a242273d1a5736fb6cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Mon, 7 Nov 2022 09:24:59 +0100 Subject: [PATCH 16/55] chore: add loki to argocd lab (#5231) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: add loki to argocd lab Signed-off-by: Charles-Edouard Brétéché * chore: add loki to argocd lab Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- scripts/labs/argocd/README.md | 3 +-- scripts/labs/argocd/kind-argo.sh | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/scripts/labs/argocd/README.md b/scripts/labs/argocd/README.md index 66e9cbe1a2fe..837b6038a61d 100644 --- a/scripts/labs/argocd/README.md +++ b/scripts/labs/argocd/README.md @@ -9,8 +9,7 @@ This lab sets up the following components: - ArgoCD application to deploy [policy-reporter](https://kyverno.github.io/policy-reporter) - ArgoCD application to deploy [metrics-server](https://github.com/kubernetes-sigs/metrics-server) - ArgoCD application to deploy [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) - -> **Note**: Unfortunately kube-prometheus-stack fails to sync the first time it is deployed hence we need to make it pass by hand. +- ArgoCD application to deploy [loki-stack](https://github.com/grafana/helm-charts/tree/main/charts/loki-stack) ## Install diff --git a/scripts/labs/argocd/kind-argo.sh b/scripts/labs/argocd/kind-argo.sh index 0933f212dca4..267389ebe5dd 100755 --- a/scripts/labs/argocd/kind-argo.sh +++ b/scripts/labs/argocd/kind-argo.sh @@ -210,6 +210,33 @@ spec: - ServerSideApply=true EOF +# CREATE LOKI APP + +kubectl apply -f - < Date: Mon, 7 Nov 2022 14:29:26 +0530 Subject: [PATCH 17/55] [Feature] Pin Dependencies by Hash (#5168) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * pin dependencies by hash Signed-off-by: Anant Vijay * pin scripts Signed-off-by: Anant Vijay Signed-off-by: Anant Vijay Co-authored-by: shuting Co-authored-by: Charles-Edouard Brétéché --- .github/workflows/fossa.yml | 2 +- .github/workflows/tests.yaml | 2 +- cmd/cli/kubectl-kyverno/Dockerfile | 2 +- cmd/initContainer/Dockerfile | 2 +- cmd/kyverno/Dockerfile | 4 ++-- cmd/kyverno/localDockerfile | 2 +- scripts/create-e2e-infrastruture.sh | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/fossa.yml b/.github/workflows/fossa.yml index 0dbc0a71329f..b1234d672ba8 100644 --- a/.github/workflows/fossa.yml +++ b/.github/workflows/fossa.yml @@ -25,6 +25,6 @@ jobs: run: | export GOPATH=$HOME/go export PATH=$PATH:$(go env GOPATH)/bin - curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install-latest.sh | bash + curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/f90d8f6ea32a55bc3b08d557590066b820a7c1b8/install-latest.sh | bash # v3.5.2 fossa init fossa analyze diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index fc5d6c5f1542..c33fe5a29a61 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -50,7 +50,7 @@ jobs: - name: goimports run: | - go install golang.org/x/tools/cmd/goimports@latest + go install golang.org/x/tools/cmd/goimports@f112c43328372460f7ac5bc951711609e22b01cc # v0.2.0 if [ "$(goimports -l . | wc -l)" -ne 0 ] then echo "The following files were found to have import formatting issues:" diff --git a/cmd/cli/kubectl-kyverno/Dockerfile b/cmd/cli/kubectl-kyverno/Dockerfile index 9a7aaaf958c1..66c375c4c8f7 100644 --- a/cmd/cli/kubectl-kyverno/Dockerfile +++ b/cmd/cli/kubectl-kyverno/Dockerfile @@ -25,7 +25,7 @@ RUN --mount=type=bind,target=. \ CGO_ENABLED=0 xx-go build -o /output/kyverno -ldflags="${LD_FLAGS}" -v ./cmd/cli/kubectl-kyverno/ # Packaging stage -FROM ghcr.io/distroless/static:latest +FROM ghcr.io/distroless/static@sha256:a9650a15060275287ebf4530b34020b8d998bd2de9aea00d113c332d8c41eb0b LABEL maintainer="Kyverno" diff --git a/cmd/initContainer/Dockerfile b/cmd/initContainer/Dockerfile index 1c1f4bcc3f60..431f88d5cf97 100644 --- a/cmd/initContainer/Dockerfile +++ b/cmd/initContainer/Dockerfile @@ -25,7 +25,7 @@ RUN --mount=type=bind,target=. \ CGO_ENABLED=0 xx-go build -o /output/kyvernopre -ldflags="${LD_FLAGS}" -v ./cmd/initContainer/ # Packaging stage -FROM ghcr.io/distroless/static:latest +FROM ghcr.io/distroless/static@sha256:a9650a15060275287ebf4530b34020b8d998bd2de9aea00d113c332d8c41eb0b LABEL maintainer="Kyverno" diff --git a/cmd/kyverno/Dockerfile b/cmd/kyverno/Dockerfile index e8459060680c..893c5936c3e7 100644 --- a/cmd/kyverno/Dockerfile +++ b/cmd/kyverno/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=${BUILDPLATFORM} golang:alpine AS certs +FROM --platform=${BUILDPLATFORM} golang:alpine@sha256:e4dcdac3ed37d8c2b3b8bcef2909573b2ad9c2ab53ba53c608909e8b89ccee36 AS certs LABEL maintainer="Kyverno" @@ -29,7 +29,7 @@ RUN --mount=type=bind,target=. \ CGO_ENABLED=0 xx-go build -o /output/kyverno -ldflags="${LD_FLAGS}" -v ./cmd/kyverno/ # Packaging stage -FROM ghcr.io/distroless/static:latest +FROM ghcr.io/distroless/static@sha256:a9650a15060275287ebf4530b34020b8d998bd2de9aea00d113c332d8c41eb0b LABEL maintainer="Kyverno" COPY --from=builder /output/kyverno / diff --git a/cmd/kyverno/localDockerfile b/cmd/kyverno/localDockerfile index dd8cc2bee1b5..db7f435bc9cc 100644 --- a/cmd/kyverno/localDockerfile +++ b/cmd/kyverno/localDockerfile @@ -1,4 +1,4 @@ -FROM golang:alpine +FROM golang@sha256:992d5fea982526ce265a0631a391e3c94694f4d15190fd170f35d91b2e6cb0ba ADD kyverno /kyverno RUN apk add --no-cache ca-certificates USER 10001 diff --git a/scripts/create-e2e-infrastruture.sh b/scripts/create-e2e-infrastruture.sh index 99964f786da7..b9e803f2c16d 100755 --- a/scripts/create-e2e-infrastruture.sh +++ b/scripts/create-e2e-infrastruture.sh @@ -21,7 +21,7 @@ fi pwd=$(pwd) cd "$pwd"/config echo "Installing kustomize" -curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash +curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/56d82a8378dfc8dc3b3b1085e5a6e67b82966bd7/hack/install_kustomize.sh" | bash # v4.5.7 kustomize edit set image ghcr.io/kyverno/kyverno:"$hash" kustomize edit set image ghcr.io/kyverno/kyvernopre:"$hash" kustomize build "$pwd"/config/ -o "$pwd"/config/install.yaml From 01b28abf917d3aa5292e284e86d631e5fdadfe0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Mon, 7 Nov 2022 12:10:22 +0100 Subject: [PATCH 18/55] fix: remove /approve from prow actions (#5243) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché Co-authored-by: Vyankatesh Kudtarkar --- .github/workflows/comment-commands.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/comment-commands.yaml b/.github/workflows/comment-commands.yaml index c9148d911b54..cf8f6f74791f 100644 --- a/.github/workflows/comment-commands.yaml +++ b/.github/workflows/comment-commands.yaml @@ -16,7 +16,6 @@ jobs: prow-commands: '/assign /unassign /lgtm - /milestone - /approve' + /milestone' github-token: "${{ secrets.GITHUB_TOKEN }}" \ No newline at end of file From a6e866fe1ff447edca4f6ebee91d77df2970c96d Mon Sep 17 00:00:00 2001 From: Vyankatesh Kudtarkar Date: Mon, 7 Nov 2022 18:54:44 +0530 Subject: [PATCH 19/55] Fix Keda policy installation issue (#5239) --- pkg/policy/validate.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg/policy/validate.go b/pkg/policy/validate.go index 678fea4e8680..23b0fddb362a 100644 --- a/pkg/policy/validate.go +++ b/pkg/policy/validate.go @@ -11,6 +11,7 @@ import ( "github.com/distribution/distribution/reference" jsonpatch "github.com/evanphx/json-patch/v5" + "github.com/gardener/controller-manager-library/pkg/logger" "github.com/jmespath/go-jmespath" "github.com/jmoiron/jsonq" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" @@ -140,7 +141,14 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b // Get all the cluster type kind supported by cluster res, err := discovery.ServerPreferredResources(client.Discovery().DiscoveryInterface()) if err != nil { - return warnings, err + if discovery.IsGroupDiscoveryFailedError(err) { + err := err.(*discovery.ErrGroupDiscoveryFailed) + for gv, err := range err.Groups { + logger.Error(err, "failed to list api resources", "group", gv) + } + } else { + return warnings, err + } } for _, resList := range res { for _, r := range resList.APIResources { From c639c6d681f8c2318470eddd05046ab52477c258 Mon Sep 17 00:00:00 2001 From: Vyankatesh Kudtarkar Date: Mon, 7 Nov 2022 19:50:50 +0530 Subject: [PATCH 20/55] fix generateName mutation (#5146) --- pkg/engine/mutate/patch/patchesUtils.go | 1 + pkg/engine/mutate/patch/patchesUtils_test.go | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/pkg/engine/mutate/patch/patchesUtils.go b/pkg/engine/mutate/patch/patchesUtils.go index 7c7c1c87ff42..05491e3a9182 100644 --- a/pkg/engine/mutate/patch/patchesUtils.go +++ b/pkg/engine/mutate/patch/patchesUtils.go @@ -140,6 +140,7 @@ func ignorePatch(path string) bool { !strings.Contains(path, "/metadata/annotations") && !strings.Contains(path, "/metadata/labels") && !strings.Contains(path, "/metadata/ownerReferences") && + !strings.Contains(path, "/metadata/generateName") && !strings.Contains(path, "/metadata/finalizers") { return true } diff --git a/pkg/engine/mutate/patch/patchesUtils_test.go b/pkg/engine/mutate/patch/patchesUtils_test.go index 759d397c702f..ae7fd0c0dadd 100644 --- a/pkg/engine/mutate/patch/patchesUtils_test.go +++ b/pkg/engine/mutate/patch/patchesUtils_test.go @@ -177,6 +177,10 @@ func Test_ignorePath(t *testing.T) { path: "/metadata/finalizers", ignore: false, }, + { + path: "/metadata/generateName", + ignore: false, + }, { path: "/metadata/creationTimestamp", ignore: true, From a08c8b03fec6c3f7eaaa2d55d6aecea3227798f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Mon, 7 Nov 2022 15:53:40 +0100 Subject: [PATCH 21/55] refactor: move all middlewares in handlers sub package (#5244) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- pkg/webhooks/handlers/admission.go | 27 ----- pkg/webhooks/handlers/dump.go | 102 ++++++++++++++++ .../{debug_test.go => handlers/dump_test.go} | 2 +- pkg/webhooks/handlers/filter.go | 18 +++ pkg/webhooks/handlers/protect.go | 34 ++++++ pkg/webhooks/handlers/verify.go | 26 ++++ pkg/webhooks/server.go | 112 +----------------- 7 files changed, 183 insertions(+), 138 deletions(-) create mode 100644 pkg/webhooks/handlers/dump.go rename pkg/webhooks/{debug_test.go => handlers/dump_test.go} (99%) create mode 100644 pkg/webhooks/handlers/filter.go create mode 100644 pkg/webhooks/handlers/protect.go create mode 100644 pkg/webhooks/handlers/verify.go diff --git a/pkg/webhooks/handlers/admission.go b/pkg/webhooks/handlers/admission.go index ced2c973b0d9..1ca1fca2c806 100644 --- a/pkg/webhooks/handlers/admission.go +++ b/pkg/webhooks/handlers/admission.go @@ -8,10 +8,7 @@ import ( "time" "github.com/go-logr/logr" - "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/tracing" - admissionutils "github.com/kyverno/kyverno/pkg/utils/admission" - jsonutils "github.com/kyverno/kyverno/pkg/utils/json" "go.opentelemetry.io/otel/attribute" admissionv1 "k8s.io/api/admission/v1" ) @@ -90,27 +87,3 @@ func Admission(logger logr.Logger, inner AdmissionHandler) http.HandlerFunc { } } } - -func Filter(c config.Configuration, inner AdmissionHandler) AdmissionHandler { - return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { - if c.ToFilter(request.Kind.Kind, request.Namespace, request.Name) { - return nil - } - return inner(logger, request, startTime) - } -} - -func Verify() AdmissionHandler { - return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { - if request.Name != "kyverno-health" || request.Namespace != config.KyvernoNamespace() { - return admissionutils.ResponseSuccess() - } - patch := jsonutils.NewPatchOperation("/metadata/annotations/"+"kyverno.io~1last-request-time", "replace", time.Now().Format(time.RFC3339)) - bytes, err := patch.ToPatchBytes() - if err != nil { - logger.Error(err, "failed to build patch bytes") - return admissionutils.ResponseFailure(err.Error()) - } - return admissionutils.ResponseSuccessWithPatch(bytes) - } -} diff --git a/pkg/webhooks/handlers/dump.go b/pkg/webhooks/handlers/dump.go new file mode 100644 index 000000000000..1f3005564e96 --- /dev/null +++ b/pkg/webhooks/handlers/dump.go @@ -0,0 +1,102 @@ +package handlers + +import ( + "strings" + "time" + + "github.com/go-logr/logr" + engineutils "github.com/kyverno/kyverno/pkg/engine/utils" + "github.com/kyverno/kyverno/pkg/utils" + admissionv1 "k8s.io/api/admission/v1" + authenticationv1 "k8s.io/api/authentication/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" +) + +func dumpPayload(logger logr.Logger, request *admissionv1.AdmissionRequest, response *admissionv1.AdmissionResponse) { + reqPayload, err := newAdmissionRequestPayload(request) + if err != nil { + logger.Error(err, "Failed to extract resources") + } else { + logger.Info("Logging admission request and response payload ", "AdmissionRequest", reqPayload, "AdmissionResponse", response) + } +} + +// admissionRequestPayload holds a copy of the AdmissionRequest payload +type admissionRequestPayload struct { + UID types.UID `json:"uid"` + Kind metav1.GroupVersionKind `json:"kind"` + Resource metav1.GroupVersionResource `json:"resource"` + SubResource string `json:"subResource,omitempty"` + RequestKind *metav1.GroupVersionKind `json:"requestKind,omitempty"` + RequestResource *metav1.GroupVersionResource `json:"requestResource,omitempty"` + RequestSubResource string `json:"requestSubResource,omitempty"` + Name string `json:"name,omitempty"` + Namespace string `json:"namespace,omitempty"` + Operation string `json:"operation"` + UserInfo authenticationv1.UserInfo `json:"userInfo"` + Object unstructured.Unstructured `json:"object,omitempty"` + OldObject unstructured.Unstructured `json:"oldObject,omitempty"` + DryRun *bool `json:"dryRun,omitempty"` + Options unstructured.Unstructured `json:"options,omitempty"` +} + +func newAdmissionRequestPayload(rq *admissionv1.AdmissionRequest) (*admissionRequestPayload, error) { + newResource, oldResource, err := utils.ExtractResources(nil, rq) + if err != nil { + return nil, err + } + options := new(unstructured.Unstructured) + if rq.Options.Raw != nil { + options, err = engineutils.ConvertToUnstructured(rq.Options.Raw) + if err != nil { + return nil, err + } + } + return redactPayload(&admissionRequestPayload{ + UID: rq.UID, + Kind: rq.Kind, + Resource: rq.Resource, + SubResource: rq.SubResource, + RequestKind: rq.RequestKind, + RequestResource: rq.RequestResource, + RequestSubResource: rq.RequestSubResource, + Name: rq.Name, + Namespace: rq.Namespace, + Operation: string(rq.Operation), + UserInfo: rq.UserInfo, + Object: newResource, + OldObject: oldResource, + DryRun: rq.DryRun, + Options: *options, + }) +} + +func redactPayload(payload *admissionRequestPayload) (*admissionRequestPayload, error) { + if strings.EqualFold(payload.Kind.Kind, "Secret") { + if payload.Object.Object != nil { + obj, err := utils.RedactSecret(&payload.Object) + if err != nil { + return nil, err + } + payload.Object = obj + } + if payload.OldObject.Object != nil { + oldObj, err := utils.RedactSecret(&payload.OldObject) + if err != nil { + return nil, err + } + payload.OldObject = oldObj + } + } + return payload, nil +} + +func Dump(inner AdmissionHandler) AdmissionHandler { + return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { + response := inner(logger, request, startTime) + dumpPayload(logger, request, response) + return response + } +} diff --git a/pkg/webhooks/debug_test.go b/pkg/webhooks/handlers/dump_test.go similarity index 99% rename from pkg/webhooks/debug_test.go rename to pkg/webhooks/handlers/dump_test.go index 72f89ad27d60..bb989025c50b 100644 --- a/pkg/webhooks/debug_test.go +++ b/pkg/webhooks/handlers/dump_test.go @@ -1,4 +1,4 @@ -package webhooks +package handlers import ( "encoding/json" diff --git a/pkg/webhooks/handlers/filter.go b/pkg/webhooks/handlers/filter.go new file mode 100644 index 000000000000..77f97b4c3f4b --- /dev/null +++ b/pkg/webhooks/handlers/filter.go @@ -0,0 +1,18 @@ +package handlers + +import ( + "time" + + "github.com/go-logr/logr" + "github.com/kyverno/kyverno/pkg/config" + admissionv1 "k8s.io/api/admission/v1" +) + +func Filter(c config.Configuration, inner AdmissionHandler) AdmissionHandler { + return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { + if c.ToFilter(request.Kind.Kind, request.Namespace, request.Name) { + return nil + } + return inner(logger, request, startTime) + } +} diff --git a/pkg/webhooks/handlers/protect.go b/pkg/webhooks/handlers/protect.go new file mode 100644 index 000000000000..c927aac423a6 --- /dev/null +++ b/pkg/webhooks/handlers/protect.go @@ -0,0 +1,34 @@ +package handlers + +import ( + "fmt" + "time" + + "github.com/go-logr/logr" + kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" + "github.com/kyverno/kyverno/pkg/config" + "github.com/kyverno/kyverno/pkg/utils" + admissionutils "github.com/kyverno/kyverno/pkg/utils/admission" + admissionv1 "k8s.io/api/admission/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func Protect(inner AdmissionHandler) AdmissionHandler { + return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { + newResource, oldResource, err := utils.ExtractResources(nil, request) + if err != nil { + logger.Error(err, "Failed to extract resources") + return admissionutils.ResponseFailure(err.Error()) + } + for _, resource := range []unstructured.Unstructured{newResource, oldResource} { + resLabels := resource.GetLabels() + if resLabels[kyvernov1.LabelAppManagedBy] == kyvernov1.ValueKyvernoApp { + if request.UserInfo.Username != fmt.Sprintf("system:serviceaccount:%s:%s", config.KyvernoNamespace(), config.KyvernoServiceAccountName()) { + logger.Info("Access to the resource not authorized, this is a kyverno managed resource and should be altered only by kyverno") + return admissionutils.ResponseFailure("A kyverno managed resource can only be modified by kyverno") + } + } + } + return inner(logger, request, startTime) + } +} diff --git a/pkg/webhooks/handlers/verify.go b/pkg/webhooks/handlers/verify.go new file mode 100644 index 000000000000..67bca2304708 --- /dev/null +++ b/pkg/webhooks/handlers/verify.go @@ -0,0 +1,26 @@ +package handlers + +import ( + "time" + + "github.com/go-logr/logr" + "github.com/kyverno/kyverno/pkg/config" + admissionutils "github.com/kyverno/kyverno/pkg/utils/admission" + jsonutils "github.com/kyverno/kyverno/pkg/utils/json" + admissionv1 "k8s.io/api/admission/v1" +) + +func Verify() AdmissionHandler { + return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { + if request.Name != "kyverno-health" || request.Namespace != config.KyvernoNamespace() { + return admissionutils.ResponseSuccess() + } + patch := jsonutils.NewPatchOperation("/metadata/annotations/"+"kyverno.io~1last-request-time", "replace", time.Now().Format(time.RFC3339)) + bytes, err := patch.ToPatchBytes() + if err != nil { + logger.Error(err, "failed to build patch bytes") + return admissionutils.ResponseFailure(err.Error()) + } + return admissionutils.ResponseSuccessWithPatch(bytes) + } +} diff --git a/pkg/webhooks/server.go b/pkg/webhooks/server.go index 3871246db2c6..2846b49f42da 100644 --- a/pkg/webhooks/server.go +++ b/pkg/webhooks/server.go @@ -3,31 +3,22 @@ package webhooks import ( "context" "crypto/tls" - "fmt" "net/http" - "strings" "time" "github.com/go-logr/logr" "github.com/julienschmidt/httprouter" - kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/config" - engineutils "github.com/kyverno/kyverno/pkg/engine/utils" "github.com/kyverno/kyverno/pkg/logging" "github.com/kyverno/kyverno/pkg/toggle" - "github.com/kyverno/kyverno/pkg/utils" - admissionutils "github.com/kyverno/kyverno/pkg/utils/admission" controllerutils "github.com/kyverno/kyverno/pkg/utils/controller" runtimeutils "github.com/kyverno/kyverno/pkg/utils/runtime" "github.com/kyverno/kyverno/pkg/webhooks/handlers" admissionv1 "k8s.io/api/admission/v1" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" - authenticationv1 "k8s.io/api/authentication/v1" coordinationv1 "k8s.io/api/coordination/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/types" ) // DebugModeOptions holds the options to configure debug mode @@ -36,76 +27,6 @@ type DebugModeOptions struct { DumpPayload bool } -// AdmissionRequestPayload holds a copy of the AdmissionRequest payload -type AdmissionRequestPayload struct { - UID types.UID `json:"uid"` - Kind metav1.GroupVersionKind `json:"kind"` - Resource metav1.GroupVersionResource `json:"resource"` - SubResource string `json:"subResource,omitempty"` - RequestKind *metav1.GroupVersionKind `json:"requestKind,omitempty"` - RequestResource *metav1.GroupVersionResource `json:"requestResource,omitempty"` - RequestSubResource string `json:"requestSubResource,omitempty"` - Name string `json:"name,omitempty"` - Namespace string `json:"namespace,omitempty"` - Operation string `json:"operation"` - UserInfo authenticationv1.UserInfo `json:"userInfo"` - Object unstructured.Unstructured `json:"object,omitempty"` - OldObject unstructured.Unstructured `json:"oldObject,omitempty"` - DryRun *bool `json:"dryRun,omitempty"` - Options unstructured.Unstructured `json:"options,omitempty"` -} - -func newAdmissionRequestPayload(rq *admissionv1.AdmissionRequest) (*AdmissionRequestPayload, error) { - newResource, oldResource, err := utils.ExtractResources(nil, rq) - if err != nil { - return nil, err - } - options := new(unstructured.Unstructured) - if rq.Options.Raw != nil { - options, err = engineutils.ConvertToUnstructured(rq.Options.Raw) - if err != nil { - return nil, err - } - } - return redactPayload(&AdmissionRequestPayload{ - UID: rq.UID, - Kind: rq.Kind, - Resource: rq.Resource, - SubResource: rq.SubResource, - RequestKind: rq.RequestKind, - RequestResource: rq.RequestResource, - RequestSubResource: rq.RequestSubResource, - Name: rq.Name, - Namespace: rq.Namespace, - Operation: string(rq.Operation), - UserInfo: rq.UserInfo, - Object: newResource, - OldObject: oldResource, - DryRun: rq.DryRun, - Options: *options, - }) -} - -func redactPayload(payload *AdmissionRequestPayload) (*AdmissionRequestPayload, error) { - if strings.EqualFold(payload.Kind.Kind, "Secret") { - if payload.Object.Object != nil { - obj, err := utils.RedactSecret(&payload.Object) - if err != nil { - return nil, err - } - payload.Object = obj - } - if payload.OldObject.Object != nil { - oldObj, err := utils.RedactSecret(&payload.OldObject) - if err != nil { - return nil, err - } - payload.OldObject = oldObj - } - } - return payload, nil -} - type Server interface { // Run TLS server in separate thread and returns control immediately Run(<-chan struct{}) @@ -249,48 +170,19 @@ func (s *server) cleanup(ctx context.Context) { close(s.cleanUp) } -func dumpPayload(logger logr.Logger, request *admissionv1.AdmissionRequest, response *admissionv1.AdmissionResponse) { - reqPayload, err := newAdmissionRequestPayload(request) - if err != nil { - logger.Error(err, "Failed to extract resources") - } else { - logger.Info("Logging admission request and response payload ", "AdmissionRequest", reqPayload, "AdmissionResponse", response) - } -} - func dump(inner handlers.AdmissionHandler, debugModeOpts DebugModeOptions) handlers.AdmissionHandler { // debug mode not enabled, no need to add debug middleware if !debugModeOpts.DumpPayload { return inner } - return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { - response := inner(logger, request, startTime) - dumpPayload(logger, request, response) - return response - } + return handlers.Dump(inner) } func protect(inner handlers.AdmissionHandler) handlers.AdmissionHandler { if !toggle.ProtectManagedResources.Enabled() { return inner } - return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { - newResource, oldResource, err := utils.ExtractResources(nil, request) - if err != nil { - logger.Error(err, "Failed to extract resources") - return admissionutils.ResponseFailure(err.Error()) - } - for _, resource := range []unstructured.Unstructured{newResource, oldResource} { - resLabels := resource.GetLabels() - if resLabels[kyvernov1.LabelAppManagedBy] == kyvernov1.ValueKyvernoApp { - if request.UserInfo.Username != fmt.Sprintf("system:serviceaccount:%s:%s", config.KyvernoNamespace(), config.KyvernoServiceAccountName()) { - logger.Info("Access to the resource not authorized, this is a kyverno managed resource and should be altered only by kyverno") - return admissionutils.ResponseFailure("A kyverno managed resource can only be modified by kyverno") - } - } - } - return inner(logger, request, startTime) - } + return handlers.Protect(inner) } func filter(configuration config.Configuration, inner handlers.AdmissionHandler) handlers.AdmissionHandler { From 2d475c1b85f0b6874ec6245cab5071078540a4ab Mon Sep 17 00:00:00 2001 From: Prateek Pandey Date: Mon, 7 Nov 2022 21:02:41 +0530 Subject: [PATCH 22/55] fix: kyverno Dockerfile base image tag and sha256 hash (#5248) Signed-off-by: prateekpandey14 --- cmd/kyverno/localDockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/kyverno/localDockerfile b/cmd/kyverno/localDockerfile index db7f435bc9cc..8072a38fc448 100644 --- a/cmd/kyverno/localDockerfile +++ b/cmd/kyverno/localDockerfile @@ -1,5 +1,5 @@ -FROM golang@sha256:992d5fea982526ce265a0631a391e3c94694f4d15190fd170f35d91b2e6cb0ba +FROM golang:alpine@sha256:e4dcdac3ed37d8c2b3b8bcef2909573b2ad9c2ab53ba53c608909e8b89ccee36 ADD kyverno /kyverno RUN apk add --no-cache ca-certificates USER 10001 -ENTRYPOINT ["/kyverno"] \ No newline at end of file +ENTRYPOINT ["/kyverno"] From e4c493093ed0376312b24348553230ce7ba7308d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Mon, 7 Nov 2022 17:05:56 +0100 Subject: [PATCH 23/55] feat: separate webhook rules per GVK/rule (#4986) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché Co-authored-by: shuting --- pkg/controllers/webhook/controller.go | 47 +++++------------ pkg/controllers/webhook/utils.go | 72 ++++++++++++++++++++------- 2 files changed, 67 insertions(+), 52 deletions(-) diff --git a/pkg/controllers/webhook/controller.go b/pkg/controllers/webhook/controller.go index 6eafe96cc052..2a5f66b6d1ef 100644 --- a/pkg/controllers/webhook/controller.go +++ b/pkg/controllers/webhook/controller.go @@ -646,11 +646,9 @@ func (c *controller) buildResourceMutatingWebhookConfiguration(caBundle []byte) result.Webhooks = append( result.Webhooks, admissionregistrationv1.MutatingWebhook{ - Name: config.MutatingWebhookName + "-ignore", - ClientConfig: c.clientConfig(caBundle, config.MutatingWebhookServicePath+"/ignore"), - Rules: []admissionregistrationv1.RuleWithOperations{ - ignore.buildRuleWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update), - }, + Name: config.MutatingWebhookName + "-ignore", + ClientConfig: c.clientConfig(caBundle, config.MutatingWebhookServicePath+"/ignore"), + Rules: ignore.buildRulesWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update), FailurePolicy: &ignore.failurePolicy, SideEffects: &noneOnDryRun, AdmissionReviewVersions: []string{"v1beta1"}, @@ -665,11 +663,9 @@ func (c *controller) buildResourceMutatingWebhookConfiguration(caBundle []byte) result.Webhooks = append( result.Webhooks, admissionregistrationv1.MutatingWebhook{ - Name: config.MutatingWebhookName + "-fail", - ClientConfig: c.clientConfig(caBundle, config.MutatingWebhookServicePath+"/fail"), - Rules: []admissionregistrationv1.RuleWithOperations{ - fail.buildRuleWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update), - }, + Name: config.MutatingWebhookName + "-fail", + ClientConfig: c.clientConfig(caBundle, config.MutatingWebhookServicePath+"/fail"), + Rules: fail.buildRulesWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update), FailurePolicy: &fail.failurePolicy, SideEffects: &noneOnDryRun, AdmissionReviewVersions: []string{"v1beta1"}, @@ -761,11 +757,9 @@ func (c *controller) buildResourceValidatingWebhookConfiguration(caBundle []byte result.Webhooks = append( result.Webhooks, admissionregistrationv1.ValidatingWebhook{ - Name: config.ValidatingWebhookName + "-ignore", - ClientConfig: c.clientConfig(caBundle, config.ValidatingWebhookServicePath+"/ignore"), - Rules: []admissionregistrationv1.RuleWithOperations{ - ignore.buildRuleWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update, admissionregistrationv1.Delete, admissionregistrationv1.Connect), - }, + Name: config.ValidatingWebhookName + "-ignore", + ClientConfig: c.clientConfig(caBundle, config.ValidatingWebhookServicePath+"/ignore"), + Rules: ignore.buildRulesWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update, admissionregistrationv1.Delete, admissionregistrationv1.Connect), FailurePolicy: &ignore.failurePolicy, SideEffects: sideEffects, AdmissionReviewVersions: []string{"v1beta1"}, @@ -779,11 +773,9 @@ func (c *controller) buildResourceValidatingWebhookConfiguration(caBundle []byte result.Webhooks = append( result.Webhooks, admissionregistrationv1.ValidatingWebhook{ - Name: config.ValidatingWebhookName + "-fail", - ClientConfig: c.clientConfig(caBundle, config.ValidatingWebhookServicePath+"/fail"), - Rules: []admissionregistrationv1.RuleWithOperations{ - fail.buildRuleWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update, admissionregistrationv1.Delete, admissionregistrationv1.Connect), - }, + Name: config.ValidatingWebhookName + "-fail", + ClientConfig: c.clientConfig(caBundle, config.ValidatingWebhookServicePath+"/fail"), + Rules: fail.buildRulesWithOperations(admissionregistrationv1.Create, admissionregistrationv1.Update, admissionregistrationv1.Delete, admissionregistrationv1.Connect), FailurePolicy: &fail.failurePolicy, SideEffects: sideEffects, AdmissionReviewVersions: []string{"v1beta1"}, @@ -878,20 +870,7 @@ func (c *controller) mergeWebhook(dst *webhook, policy kyvernov1.PolicyInterface } } for _, gvr := range gvrList { - dst.groups.Insert(gvr.Group) - if gvr.Version == "*" { - dst.versions = sets.NewString() - dst.versions.Insert(gvr.Version) - } else if !dst.versions.Has("*") { - dst.versions.Insert(gvr.Version) - } - dst.resources.Insert(gvr.Resource) - } - if dst.resources.Has("pods") { - dst.resources.Insert("pods/ephemeralcontainers") - } - if dst.resources.Has("services") { - dst.resources.Insert("services/status") + dst.set(gvr) } spec := policy.GetSpec() if spec.WebhookTimeoutSeconds != nil { diff --git a/pkg/controllers/webhook/utils.go b/pkg/controllers/webhook/utils.go index 6a73f6df8fc8..c92ab735e94c 100644 --- a/pkg/controllers/webhook/utils.go +++ b/pkg/controllers/webhook/utils.go @@ -5,8 +5,10 @@ import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/utils" + "golang.org/x/exp/slices" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" ) @@ -15,40 +17,74 @@ import ( type webhook struct { maxWebhookTimeout int32 failurePolicy admissionregistrationv1.FailurePolicyType - groups sets.String - versions sets.String - resources sets.String + rules map[schema.GroupVersionResource]struct{} } func newWebhook(timeout int32, failurePolicy admissionregistrationv1.FailurePolicyType) *webhook { return &webhook{ maxWebhookTimeout: timeout, failurePolicy: failurePolicy, - groups: sets.NewString(), - versions: sets.NewString(), - resources: sets.NewString(), + rules: map[schema.GroupVersionResource]struct{}{}, } } -func (wh *webhook) buildRuleWithOperations(ops ...admissionregistrationv1.OperationType) admissionregistrationv1.RuleWithOperations { - return admissionregistrationv1.RuleWithOperations{ - Rule: admissionregistrationv1.Rule{ - APIGroups: wh.groups.List(), - APIVersions: wh.versions.List(), - Resources: wh.resources.List(), - }, - Operations: ops, +func (wh *webhook) buildRulesWithOperations(ops ...admissionregistrationv1.OperationType) []admissionregistrationv1.RuleWithOperations { + var rules []admissionregistrationv1.RuleWithOperations + for gvr := range wh.rules { + resources := sets.NewString(gvr.Resource) + if resources.Has("pods") { + resources.Insert("pods/ephemeralcontainers") + } + if resources.Has("services") { + resources.Insert("services/status") + } + rules = append(rules, admissionregistrationv1.RuleWithOperations{ + Rule: admissionregistrationv1.Rule{ + APIGroups: []string{gvr.Group}, + APIVersions: []string{gvr.Version}, + Resources: resources.List(), + }, + Operations: ops, + }) + } + less := func(a []string, b []string) (bool, bool) { + if len(a) != len(b) { + return len(a) < len(b), true + } + for i := range a { + if a[i] != b[i] { + return a[i] < b[i], true + } + } + return false, false } + slices.SortFunc(rules, func(a admissionregistrationv1.RuleWithOperations, b admissionregistrationv1.RuleWithOperations) bool { + if less, match := less(a.APIGroups, b.APIGroups); match { + return less + } + if less, match := less(a.APIVersions, b.APIVersions); match { + return less + } + if less, match := less(a.Resources, b.Resources); match { + return less + } + return false + }) + return rules +} + +func (wh *webhook) set(gvr schema.GroupVersionResource) { + wh.rules[gvr] = struct{}{} } func (wh *webhook) isEmpty() bool { - return wh.groups.Len() == 0 || wh.versions.Len() == 0 || wh.resources.Len() == 0 + return len(wh.rules) == 0 } func (wh *webhook) setWildcard() { - wh.groups = sets.NewString("*") - wh.versions = sets.NewString("*") - wh.resources = sets.NewString("*/*") + wh.rules = map[schema.GroupVersionResource]struct{}{ + {Group: "*", Version: "*", Resource: "*/*"}: {}, + } } func hasWildcard(policies ...kyvernov1.PolicyInterface) bool { From 35123af638926acd156c8c4264991de1fd5e1266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Mon, 7 Nov 2022 17:48:25 +0100 Subject: [PATCH 24/55] fix: remove unused code in config (#5242) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- pkg/config/config.go | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 0c8d18da0750..5a1e76a5e26d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -109,8 +109,6 @@ type Configuration interface { GetExcludeUsername() []string // GetGenerateSuccessEvents return if should generate success events GetGenerateSuccessEvents() bool - // RestrictDevelopmentUsername return exclude development username - RestrictDevelopmentUsername() []string // FilterNamespaces filters exclude namespace FilterNamespaces(namespaces []string) []string // GetWebhooks returns the webhook configs @@ -121,20 +119,18 @@ type Configuration interface { // configuration stores the configuration type configuration struct { - mux sync.RWMutex - filters []filter - excludeGroupRole []string - excludeUsername []string - restrictDevelopmentUsername []string - webhooks []WebhookConfig - generateSuccessEvents bool + mux sync.RWMutex + filters []filter + excludeGroupRole []string + excludeUsername []string + webhooks []WebhookConfig + generateSuccessEvents bool } // NewConfiguration ... func NewDefaultConfiguration() *configuration { return &configuration{ - restrictDevelopmentUsername: []string{"minikube-user", "kubernetes-admin"}, - excludeGroupRole: defaultExcludeGroupRole, + excludeGroupRole: defaultExcludeGroupRole, } } @@ -174,12 +170,6 @@ func (cd *configuration) GetExcludeGroupRole() []string { return cd.excludeGroupRole } -func (cd *configuration) RestrictDevelopmentUsername() []string { - cd.mux.RLock() - defer cd.mux.RUnlock() - return cd.restrictDevelopmentUsername -} - func (cd *configuration) GetExcludeUsername() []string { cd.mux.RLock() defer cd.mux.RUnlock() From d9480c268d68a1a24348186d8124e2e26a11e79e Mon Sep 17 00:00:00 2001 From: Chip Zoller Date: Mon, 7 Nov 2022 12:23:19 -0500 Subject: [PATCH 25/55] More kuttl tests (#5238) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add remainder of e2e verifyImages tests Signed-off-by: Chip Zoller * add tests Signed-off-by: Chip Zoller * add external-metrics test case and scaffolding Signed-off-by: Chip Zoller * update scaffolding Signed-off-by: Chip Zoller * add keyed-basic test Signed-off-by: Chip Zoller * add migrated e2e test for gen role and rolebinding Signed-off-by: Chip Zoller * add clone-role-and-rolebinding from e2e Signed-off-by: Chip Zoller * remove timeout param from kuttl-test.yaml Signed-off-by: Chip Zoller * add tests for external-metrics Policy fix Signed-off-by: Chip Zoller Signed-off-by: Chip Zoller Co-authored-by: Vyankatesh Kudtarkar Co-authored-by: Charles-Edouard Brétéché --- .../kuttl/aaa_template_resources/README.md | 12 +- .../scaffold/01-assert.yaml | 6 + .../scaffold/01-manifests.yaml | 19 + .../scaffold/99-cleanup.yaml | 4 + .../aaa_template_resources/scaffold/README.md | 11 + .../scaffold/errors.yaml | 7 + .../aaa_template_resources/scaffold/ns.yaml | 4 + .../scaffold/resource.yaml | 8 + .../scaffold/script-check-for-error.yaml | 13 + .../clone-role-and-rolebinding/01-assert.yaml | 6 + .../01-manifests.yaml | 59 ++ .../clone-role-and-rolebinding/02-ns.yaml | 4 + .../clone-role-and-rolebinding/03-assert.yaml | 30 + .../99-cleanup.yaml | 4 + .../clone-role-and-rolebinding/README.md | 11 + .../data-role-and-rolebinding/01-assert.yaml | 6 + .../01-manifests.yaml | 44 + .../data-role-and-rolebinding/02-ns.yaml | 4 + .../data-role-and-rolebinding/03-assert.yaml | 28 + .../data-role-and-rolebinding/99-cleanup.yaml | 4 + .../data-role-and-rolebinding/README.md | 11 + test/conformance/kuttl/kuttl-test.yaml | 4 +- .../external-metrics/01-manifests.yaml | 770 ++++++++++++++++++ .../external-metrics/02-sleep.yaml | 5 + .../external-metrics/03-assert.yaml | 9 + .../external-metrics/04-assert.yaml | 6 + .../external-metrics/04-clusterpolicy.yaml | 30 + .../external-metrics/05-assert.yaml | 7 + .../external-metrics/05-policy.yaml | 31 + .../external-metrics/99-cleanup.yaml | 4 + .../cornercases/external-metrics/README.md | 23 + .../standard/keyed-basic/01-assert.yaml | 6 + .../standard/keyed-basic/01-manifests.yaml | 32 + .../standard/keyed-basic/02-assert.yaml | 5 + .../standard/keyed-basic/02-goodpod.yaml | 9 + .../standard/keyed-basic/99-cleanup.yaml | 4 + .../standard/keyed-basic/README.md | 11 + .../01-assert.yaml | 6 + .../01-manifests.yaml | 20 + .../02-pod.yaml | 9 + .../03-assert.yaml | 9 + .../99-cleanup.yaml | 4 + .../README.md | 5 + .../errors.yaml | 7 + .../resource.yaml | 8 + .../script-check-for-error.yaml | 14 + .../01-assert.yaml | 6 + .../01-manifests.yaml | 20 + .../02-goodpod.yaml | 9 + .../03-assert.yaml | 9 + .../04-create-badpod.yaml | 14 + .../99-cleanup.yaml | 4 + .../README.md | 5 + .../badpod.yaml | 9 + .../errors.yaml | 7 + 55 files changed, 1412 insertions(+), 4 deletions(-) create mode 100644 test/conformance/kuttl/aaa_template_resources/scaffold/01-assert.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/scaffold/01-manifests.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/scaffold/99-cleanup.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/scaffold/README.md create mode 100644 test/conformance/kuttl/aaa_template_resources/scaffold/errors.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/scaffold/ns.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/scaffold/resource.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/scaffold/script-check-for-error.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/01-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/01-manifests.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/02-ns.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/03-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/99-cleanup.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/README.md create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/01-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/01-manifests.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/02-ns.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/03-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/99-cleanup.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/README.md create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/01-manifests.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/02-sleep.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/03-assert.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-assert.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-clusterpolicy.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-assert.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-policy.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/99-cleanup.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/README.md create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/01-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/01-manifests.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/02-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/02-goodpod.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/README.md create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/01-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/01-manifests.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/02-pod.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/03-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/README.md create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/errors.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/resource.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/script-check-for-error.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/01-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/01-manifests.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/02-goodpod.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/03-assert.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/04-create-badpod.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/README.md create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/badpod.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/errors.yaml diff --git a/test/conformance/kuttl/aaa_template_resources/README.md b/test/conformance/kuttl/aaa_template_resources/README.md index 22091f0fe077..f08e18d5e8fc 100644 --- a/test/conformance/kuttl/aaa_template_resources/README.md +++ b/test/conformance/kuttl/aaa_template_resources/README.md @@ -1,5 +1,11 @@ -# Title +## Description -Issue: 1234 +This is a description of what my test does and why it needs to do it. -This is a description of your test. +## Expected Behavior + +This is the expected behavior of my test. Although it's assumed the test, overall, should pass/succeed, be specific about what the internal behavior is which leads to that result. + +## Reference Issue(s) + +1234 diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/01-assert.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/01-assert.yaml new file mode 100644 index 000000000000..7f1d7387c9b0 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-labels +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/01-manifests.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/01-manifests.yaml new file mode 100644 index 000000000000..970b4aa5c439 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/01-manifests.yaml @@ -0,0 +1,19 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: add-labels +spec: + rules: + - name: add-labels + match: + resources: + kinds: + - Pod + - Service + - ConfigMap + - Secret + mutate: + patchStrategicMerge: + metadata: + labels: + foo: bar diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/99-cleanup.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/99-cleanup.yaml new file mode 100644 index 000000000000..15c3c4905153 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/README.md b/test/conformance/kuttl/aaa_template_resources/scaffold/README.md new file mode 100644 index 000000000000..f08e18d5e8fc --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/README.md @@ -0,0 +1,11 @@ +## Description + +This is a description of what my test does and why it needs to do it. + +## Expected Behavior + +This is the expected behavior of my test. Although it's assumed the test, overall, should pass/succeed, be specific about what the internal behavior is which leads to that result. + +## Reference Issue(s) + +1234 diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/errors.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/errors.yaml new file mode 100644 index 000000000000..dcb47a5770a8 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/errors.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: testingsecret + namespace: default + labels: + foo: bar \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/ns.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/ns.yaml new file mode 100644 index 000000000000..26f9d8ac2eb3 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: bar \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/resource.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/resource.yaml new file mode 100644 index 000000000000..cfafb7c22be4 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/resource.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +data: + foo: YmFy +kind: Secret +metadata: + name: testingsecret + namespace: default +type: Opaque \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/script-check-for-error.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/script-check-for-error.yaml new file mode 100644 index 000000000000..fc29fa83d39e --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/script-check-for-error.yaml @@ -0,0 +1,13 @@ +## Checks that the manifests.yaml file CANNOT be successfully created. If it can, fail the test as this is incorrect. +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f manifests.yaml + then + echo "Tested failed. Policy was created when it shouldn't have been." + exit 1 + else + echo "Test succeeded. Policy was not created as intended." + exit 0 + fi \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/01-assert.yaml new file mode 100644 index 000000000000..ef8b3de63821 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: gen-clone-role-policy +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/01-manifests.yaml b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/01-manifests.yaml new file mode 100644 index 000000000000..f13d131c3464 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/01-manifests.yaml @@ -0,0 +1,59 @@ +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + namespace: default + name: ns-role +rules: +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "watch", "list", "delete", "create"] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: ns-role-binding + namespace: default +subjects: + - apiGroup: rbac.authorization.k8s.io + kind: User + name: minikube-userclone +roleRef: + kind: Role + name: ns-role + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: gen-clone-role-policy +spec: + background: false + rules: + - name: gen-role + match: + any: + - resources: + kinds: + - Namespace + generate: + kind: Role + name: ns-role + namespace: "{{request.object.metadata.name}}" + synchronize: true + clone: + name: ns-role + namespace: default + - name: gen-role-binding + match: + any: + - resources: + kinds: + - Namespace + generate: + kind: RoleBinding + name: ns-role-binding + namespace: "{{request.object.metadata.name}}" + synchronize: true + clone: + name: ns-role-binding + namespace: default \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/02-ns.yaml b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/02-ns.yaml new file mode 100644 index 000000000000..f09957352b9f --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/02-ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: generate-clone-role-tests \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/03-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/03-assert.yaml new file mode 100644 index 000000000000..8ae6267cb20b --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/03-assert.yaml @@ -0,0 +1,30 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: ns-role + namespace: generate-clone-role-tests +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - watch + - list + - delete + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ns-role-binding + namespace: generate-clone-role-tests +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ns-role +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: minikube-userclone \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/99-cleanup.yaml b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/99-cleanup.yaml new file mode 100644 index 000000000000..1c6b4578bc1e --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/README.md b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/README.md new file mode 100644 index 000000000000..edea18ec63cf --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/README.md @@ -0,0 +1,11 @@ +## Description + +This test checks the Kyverno can generate a Role and RoleBinding from a clone-type generate rule. This test does NOT require additional privileges granted to the Kyverno ServiceAccount. Because this is a test which covers generation of security-related constructs which the API server has special logic to block if it detects a possible privilege escalation attack, it is being considered a corner case. This test was migrated from e2e. + +## Expected Behavior + +The Role and RoleBinding should be generated as per the clone declaration in the ClusterPolicy. + +## Reference Issue(s) + +N/A \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/01-assert.yaml new file mode 100644 index 000000000000..4047f4fc55f9 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: gen-role-policy +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/01-manifests.yaml b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/01-manifests.yaml new file mode 100644 index 000000000000..c09729c4a15f --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/01-manifests.yaml @@ -0,0 +1,44 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: gen-role-policy +spec: + background: false + rules: + - name: gen-role + match: + any: + - resources: + kinds: + - Namespace + generate: + kind: Role + name: ns-role + namespace: "{{request.object.metadata.name}}" + synchronize: true + data: + rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "watch", "list"] + - name: gen-role-binding + match: + any: + - resources: + kinds: + - Namespace + generate: + kind: RoleBinding + name: ns-role-binding + namespace: "{{request.object.metadata.name}}" + synchronize: true + data: + subjects: + - apiGroup: rbac.authorization.k8s.io + kind: User + name: minikube-user + roleRef: + kind: Role + name: ns-role + namespace: "{{request.object.metadata.name}}" + apiGroup: rbac.authorization.k8s.io diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/02-ns.yaml b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/02-ns.yaml new file mode 100644 index 000000000000..82164ae27a49 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/02-ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: generate-role-tests \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/03-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/03-assert.yaml new file mode 100644 index 000000000000..c0844f4aca07 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/03-assert.yaml @@ -0,0 +1,28 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: ns-role + namespace: generate-role-tests +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - watch + - list +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ns-role-binding + namespace: generate-role-tests +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ns-role +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: User + name: minikube-user \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/99-cleanup.yaml b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/99-cleanup.yaml new file mode 100644 index 000000000000..1c6b4578bc1e --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-ns.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/README.md b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/README.md new file mode 100644 index 000000000000..1b4ea5b28cd4 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/README.md @@ -0,0 +1,11 @@ +## Description + +This test checks the Kyverno can generate a Role and RoleBinding from a data-type generate rule. This test does NOT require additional privileges granted to the Kyverno ServiceAccount. Because this is a test which covers generation of security-related constructs which the API server has special logic to block if it detects a possible privilege escalation attack, it is being considered a corner case. This test was migrated from e2e. + +## Expected Behavior + +The Role and RoleBinding should be generate as per the data declaration in the ClusterPolicy. + +## Reference Issue(s) + +N/A \ No newline at end of file diff --git a/test/conformance/kuttl/kuttl-test.yaml b/test/conformance/kuttl/kuttl-test.yaml index 8f4b4b9eceb2..5c608ec9b662 100644 --- a/test/conformance/kuttl/kuttl-test.yaml +++ b/test/conformance/kuttl/kuttl-test.yaml @@ -6,17 +6,19 @@ testDirs: - ./test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync - ./test/conformance/kuttl/generate/clusterpolicy/standard/data/sync - ./test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync +- ./test/conformance/kuttl/generate/clusterpolicy/cornercases # Mutate tests - ./test/conformance/kuttl/mutate/clusterpolicy/standard - ./test/conformance/kuttl/mutate/clusterpolicy/standard/existing # Validate tests - ./test/conformance/kuttl/validate/clusterpolicy/standard/audit - ./test/conformance/kuttl/validate/clusterpolicy/standard/enforce +- ./test/conformance/kuttl/validate/clusterpolicy/cornercases # verifyImages tests - ./test/conformance/kuttl/verifyImages/clusterpolicy/standard # Report tests - ./test/conformance/kuttl/reports/admission - ./test/conformance/kuttl/reports/background startKIND: false -timeout: 15 +# timeout: 15 parallel: 1 \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/01-manifests.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/01-manifests.yaml new file mode 100644 index 000000000000..02598d5442bd --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/01-manifests.yaml @@ -0,0 +1,770 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/name: keda + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: keda +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.0 + creationTimestamp: null + labels: + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: scaledobjects.keda.sh +spec: + group: keda.sh + names: + kind: ScaledObject + listKind: ScaledObjectList + plural: scaledobjects + shortNames: + - so + singular: scaledobject + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.scaleTargetKind + name: ScaleTargetKind + type: string + - jsonPath: .spec.scaleTargetRef.name + name: ScaleTargetName + type: string + - jsonPath: .spec.minReplicaCount + name: Min + type: integer + - jsonPath: .spec.maxReplicaCount + name: Max + type: integer + - jsonPath: .spec.triggers[*].type + name: Triggers + type: string + - jsonPath: .spec.triggers[*].authenticationRef.name + name: Authentication + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Active")].status + name: Active + type: string + - jsonPath: .status.conditions[?(@.type=="Fallback")].status + name: Fallback + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ScaledObject is a specification for a ScaledObject resource + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ScaledObjectSpec is the spec for a ScaledObject resource + properties: + advanced: + description: AdvancedConfig specifies advance scaling options + properties: + horizontalPodAutoscalerConfig: + description: HorizontalPodAutoscalerConfig specifies horizontal + scale config + properties: + behavior: + description: HorizontalPodAutoscalerBehavior configures the + scaling behavior of the target in both Up and Down directions + (scaleUp and scaleDown fields respectively). + properties: + scaleDown: + description: scaleDown is scaling policy for scaling Down. + If not set, the default value is to allow to scale down + to minReplicas pods, with a 300 second stabilization + window (i.e., the highest recommendation for the last + 300sec is used). + properties: + policies: + description: policies is a list of potential scaling + polices which can be used during scaling. At least + one policy must be specified, otherwise the HPAScalingRules + will be discarded as invalid + items: + description: HPAScalingPolicy is a single policy + which must hold true for a specified past interval. + properties: + periodSeconds: + description: PeriodSeconds specifies the window + of time for which the policy should hold true. + PeriodSeconds must be greater than zero and + less than or equal to 1800 (30 min). + format: int32 + type: integer + type: + description: Type is used to specify the scaling + policy. + type: string + value: + description: Value contains the amount of change + which is permitted by the policy. It must + be greater than zero + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + selectPolicy: + description: selectPolicy is used to specify which + policy should be used. If not set, the default value + MaxPolicySelect is used. + type: string + stabilizationWindowSeconds: + description: 'StabilizationWindowSeconds is the number + of seconds for which past recommendations should + be considered while scaling up or scaling down. + StabilizationWindowSeconds must be greater than + or equal to zero and less than or equal to 3600 + (one hour). If not set, use the default values: + - For scale up: 0 (i.e. no stabilization is done). + - For scale down: 300 (i.e. the stabilization window + is 300 seconds long).' + format: int32 + type: integer + type: object + scaleUp: + description: 'scaleUp is scaling policy for scaling Up. + If not set, the default value is the higher of: * increase + no more than 4 pods per 60 seconds * double the number + of pods per 60 seconds No stabilization is used.' + properties: + policies: + description: policies is a list of potential scaling + polices which can be used during scaling. At least + one policy must be specified, otherwise the HPAScalingRules + will be discarded as invalid + items: + description: HPAScalingPolicy is a single policy + which must hold true for a specified past interval. + properties: + periodSeconds: + description: PeriodSeconds specifies the window + of time for which the policy should hold true. + PeriodSeconds must be greater than zero and + less than or equal to 1800 (30 min). + format: int32 + type: integer + type: + description: Type is used to specify the scaling + policy. + type: string + value: + description: Value contains the amount of change + which is permitted by the policy. It must + be greater than zero + format: int32 + type: integer + required: + - periodSeconds + - type + - value + type: object + type: array + selectPolicy: + description: selectPolicy is used to specify which + policy should be used. If not set, the default value + MaxPolicySelect is used. + type: string + stabilizationWindowSeconds: + description: 'StabilizationWindowSeconds is the number + of seconds for which past recommendations should + be considered while scaling up or scaling down. + StabilizationWindowSeconds must be greater than + or equal to zero and less than or equal to 3600 + (one hour). If not set, use the default values: + - For scale up: 0 (i.e. no stabilization is done). + - For scale down: 300 (i.e. the stabilization window + is 300 seconds long).' + format: int32 + type: integer + type: object + type: object + name: + type: string + type: object + restoreToOriginalReplicaCount: + type: boolean + type: object + cooldownPeriod: + format: int32 + type: integer + fallback: + description: Fallback is the spec for fallback options + properties: + failureThreshold: + format: int32 + type: integer + replicas: + format: int32 + type: integer + required: + - failureThreshold + - replicas + type: object + idleReplicaCount: + format: int32 + type: integer + maxReplicaCount: + format: int32 + type: integer + minReplicaCount: + format: int32 + type: integer + pollingInterval: + format: int32 + type: integer + scaleTargetRef: + description: ScaleTarget holds the a reference to the scale target + Object + properties: + apiVersion: + type: string + envSourceContainerName: + type: string + kind: + type: string + name: + type: string + required: + - name + type: object + triggers: + items: + description: ScaleTriggers reference the scaler that will be used + properties: + authenticationRef: + description: ScaledObjectAuthRef points to the TriggerAuthentication + or ClusterTriggerAuthentication object that is used to authenticate + the scaler with the environment + properties: + kind: + description: Kind of the resource being referred to. Defaults + to TriggerAuthentication. + type: string + name: + type: string + required: + - name + type: object + metadata: + additionalProperties: + type: string + type: object + metricType: + description: MetricTargetType specifies the type of metric being + targeted, and should be either "Value", "AverageValue", or + "Utilization" + type: string + name: + type: string + type: + type: string + required: + - metadata + - type + type: object + type: array + required: + - scaleTargetRef + - triggers + type: object + status: + description: ScaledObjectStatus is the status for a ScaledObject resource + properties: + conditions: + description: Conditions an array representation to store multiple + Conditions + items: + description: Condition to store the condition state + properties: + message: + description: A human readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition + type: string + required: + - status + - type + type: object + type: array + externalMetricNames: + items: + type: string + type: array + health: + additionalProperties: + description: HealthStatus is the status for a ScaledObject's health + properties: + numberOfFailures: + format: int32 + type: integer + status: + description: HealthStatusType is an indication of whether the + health status is happy or failing + type: string + type: object + type: object + hpaName: + type: string + lastActiveTime: + format: date-time + type: string + originalReplicaCount: + format: int32 + type: integer + pausedReplicaCount: + format: int32 + type: integer + resourceMetricNames: + items: + type: string + type: array + scaleTargetGVKR: + description: GroupVersionKindResource provides unified structure for + schema.GroupVersionKind and Resource + properties: + group: + type: string + kind: + type: string + resource: + type: string + version: + type: string + required: + - group + - kind + - resource + - version + type: object + scaleTargetKind: + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: keda-operator + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: keda-operator + namespace: keda +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: keda-external-metrics-reader + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: keda-external-metrics-reader +rules: +- apiGroups: + - external.metrics.k8s.io + resources: + - '*' + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + labels: + app.kubernetes.io/name: keda-operator + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: keda-operator +rules: +- apiGroups: + - "" + resources: + - configmaps + - configmaps/status + - events + verbs: + - '*' +- apiGroups: + - "" + resources: + - external + - pods + - secrets + - services + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - list + - watch +- apiGroups: + - '*' + resources: + - '*' + verbs: + - get +- apiGroups: + - '*' + resources: + - '*/scale' + verbs: + - '*' +- apiGroups: + - apps + resources: + - deployments + - statefulsets + verbs: + - list + - watch +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - '*' +- apiGroups: + - batch + resources: + - jobs + verbs: + - '*' +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - '*' +- apiGroups: + - keda.sh + resources: + - clustertriggerauthentications + - clustertriggerauthentications/status + verbs: + - '*' +- apiGroups: + - keda.sh + resources: + - scaledjobs + - scaledjobs/finalizers + - scaledjobs/status + verbs: + - '*' +- apiGroups: + - keda.sh + resources: + - scaledobjects + - scaledobjects/finalizers + - scaledobjects/status + verbs: + - '*' +- apiGroups: + - keda.sh + resources: + - triggerauthentications + - triggerauthentications/status + verbs: + - '*' +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/name: keda-auth-reader + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: keda-auth-reader + namespace: kube-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: extension-apiserver-authentication-reader +subjects: +- kind: ServiceAccount + name: keda-operator + namespace: keda +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: keda-hpa-controller-external-metrics + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: keda-hpa-controller-external-metrics +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: keda-external-metrics-reader +subjects: +- kind: ServiceAccount + name: horizontal-pod-autoscaler + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: keda-operator + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: keda-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: keda-operator +subjects: +- kind: ServiceAccount + name: keda-operator + namespace: keda +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: keda-system-auth-delegator + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: keda-system-auth-delegator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: keda-operator + namespace: keda +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: keda-metrics-apiserver + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: keda-metrics-apiserver + namespace: keda +spec: + ports: + - name: https + port: 443 + targetPort: 6443 + - name: http + port: 80 + targetPort: 8080 + selector: + app: keda-metrics-apiserver +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: keda-metrics-apiserver + app.kubernetes.io/name: keda-metrics-apiserver + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: keda-metrics-apiserver + namespace: keda +spec: + replicas: 1 + selector: + matchLabels: + app: keda-metrics-apiserver + template: + metadata: + labels: + app: keda-metrics-apiserver + name: keda-metrics-apiserver + spec: + containers: + - args: + - /usr/local/bin/keda-adapter + - --secure-port=6443 + - --logtostderr=true + - --v=0 + env: + - name: WATCH_NAMESPACE + value: "" + - name: KEDA_HTTP_DEFAULT_TIMEOUT + value: "" + image: ghcr.io/kedacore/keda-metrics-apiserver:2.8.0 + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz + port: 6443 + scheme: HTTPS + initialDelaySeconds: 5 + name: keda-metrics-apiserver + ports: + - containerPort: 6443 + name: https + - containerPort: 8080 + name: http + readinessProbe: + httpGet: + path: /readyz + port: 6443 + scheme: HTTPS + initialDelaySeconds: 5 + resources: + limits: + cpu: 1000m + memory: 1000Mi + requests: + cpu: 100m + memory: 100Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + volumeMounts: + - mountPath: /tmp + name: temp-vol + nodeSelector: + kubernetes.io/os: linux + securityContext: + runAsNonRoot: true + serviceAccountName: keda-operator + volumes: + - emptyDir: {} + name: temp-vol +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: keda-operator + app.kubernetes.io/component: operator + app.kubernetes.io/name: keda-operator + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: keda-operator + namespace: keda +spec: + replicas: 1 + selector: + matchLabels: + app: keda-operator + template: + metadata: + labels: + app: keda-operator + name: keda-operator + name: keda-operator + spec: + containers: + - args: + - --leader-elect + - --zap-log-level=info + - --zap-encoder=console + - --zap-time-encoding=rfc3339 + command: + - /keda + env: + - name: WATCH_NAMESPACE + value: "" + - name: KEDA_HTTP_DEFAULT_TIMEOUT + value: "" + image: ghcr.io/kedacore/keda:2.8.0 + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 25 + name: keda-operator + ports: + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 20 + resources: + limits: + cpu: 1000m + memory: 1000Mi + requests: + cpu: 100m + memory: 100Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + nodeSelector: + kubernetes.io/os: linux + securityContext: + runAsNonRoot: true + serviceAccountName: keda-operator + terminationGracePeriodSeconds: 10 +--- +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + labels: + app.kubernetes.io/name: v1beta1.external.metrics.k8s.io + app.kubernetes.io/part-of: keda-operator + app.kubernetes.io/version: 2.8.0 + name: v1beta1.external.metrics.k8s.io +spec: + group: external.metrics.k8s.io + groupPriorityMinimum: 100 + insecureSkipTLSVerify: true + service: + name: keda-metrics-apiserver + namespace: keda + version: v1beta1 + versionPriority: 100 diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/02-sleep.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/02-sleep.yaml new file mode 100644 index 000000000000..f34516fc2df9 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/02-sleep.yaml @@ -0,0 +1,5 @@ +# Need to wait for the KEDA images to be pulled, Pods run, and external metrics API group to be properly registered and served. +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: sleep 20 \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/03-assert.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/03-assert.yaml new file mode 100644 index 000000000000..c2ade741b961 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/03-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: keda-metrics-apiserver + namespace: keda +status: + availableReplicas: 1 + readyReplicas: 1 + replicas: 1 \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-assert.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-assert.yaml new file mode 100644 index 000000000000..9d36296cef03 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: external-metrics-policy +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-clusterpolicy.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-clusterpolicy.yaml new file mode 100644 index 000000000000..67850b5039b0 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-clusterpolicy.yaml @@ -0,0 +1,30 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: external-metrics-policy +spec: + validationFailureAction: enforce + background: false + rules: + - name: external-metrics-rule + match: + all: + - clusterRoles: + - evil-cr + resources: + kinds: + - Secret + validate: + message: 'You should be careful when trying to change/delete {{request.oldObject.kind}} in {{request.oldObject.name}}. These are my-precious resources and touching them might break my heart.' + deny: + conditions: + any: + - key: '{{request.operation}}' + operator: Equals + value: DELETE + - key: '{{request.operation}}' + operator: Equals + value: UPDATE + - key: '{{request.operation}}' + operator: Equals + value: CREATE \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-assert.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-assert.yaml new file mode 100644 index 000000000000..1f89a4d15997 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-assert.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: external-metrics-policy-default + namespace: default +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-policy.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-policy.yaml new file mode 100644 index 000000000000..5a401385f878 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-policy.yaml @@ -0,0 +1,31 @@ +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: external-metrics-policy-default + namespace: default +spec: + validationFailureAction: enforce + background: false + rules: + - name: external-metrics-rule-default + match: + all: + - clusterRoles: + - evil-cr + resources: + kinds: + - Secret + validate: + message: 'You should be careful when trying to change/delete {{request.oldObject.kind}} in {{request.oldObject.name}}. These are my-precious resources and touching them might break my heart.' + deny: + conditions: + any: + - key: '{{request.operation}}' + operator: Equals + value: DELETE + - key: '{{request.operation}}' + operator: Equals + value: UPDATE + - key: '{{request.operation}}' + operator: Equals + value: CREATE \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/99-cleanup.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/99-cleanup.yaml new file mode 100644 index 000000000000..1eb8dbd55835 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,04-clusterpolicy.yaml,05-policy.yaml --force --wait=false --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/README.md b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/README.md new file mode 100644 index 000000000000..2a0054d0d07a --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/README.md @@ -0,0 +1,23 @@ +## Description + +Tests the ability to create both a ClusterPolicy and a Policy when there is an external API provider registered in the cluster but with no resources which fall under that group. + +## Expected Behavior + +Both ClusterPolicy and Policy should be successfully created. + +## Reference Issue(s) + +918 +942 +1324 +1325 +1490 +1830 +2126 +2162 +2267 +2684 +3244 +3788 +5221 diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/01-assert.yaml new file mode 100644 index 000000000000..99a0cad5253f --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: keyed-basic-policy +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/01-manifests.yaml new file mode 100644 index 000000000000..f67dd1293872 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/01-manifests.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: test-verify-images +--- +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: keyed-basic-policy +spec: + validationFailureAction: enforce + background: false + webhookTimeoutSeconds: 30 + failurePolicy: Fail + rules: + - name: keyed-basic-rule + match: + any: + - resources: + kinds: + - Pod + verifyImages: + - imageReferences: + - "ghcr.io/kyverno/test-verify-image:*" + attestors: + - entries: + - keys: + publicKeys: |- + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM + 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== + -----END PUBLIC KEY----- diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/02-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/02-assert.yaml new file mode 100644 index 000000000000..b736ae3d4860 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/02-assert.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Pod +metadata: + name: test-secret-pod + namespace: test-verify-images \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/02-goodpod.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/02-goodpod.yaml new file mode 100644 index 000000000000..de7987da272a --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/02-goodpod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: test-secret-pod + namespace: test-verify-images +spec: + containers: + - image: ghcr.io/kyverno/test-verify-image:signed + name: test-secret \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/99-cleanup.yaml new file mode 100644 index 000000000000..61b75559765b --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-goodpod.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/README.md b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/README.md new file mode 100644 index 000000000000..8c84b5a79d25 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/README.md @@ -0,0 +1,11 @@ +## Description + +This test performs a simple verification of an image using a public key specified directly in the policy. + +## Expected Behavior + +Pod creation should pass as the image has been signed by the public key specified in the policy. + +## Reference Issue(s) + +N/A \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/01-assert.yaml new file mode 100644 index 000000000000..7d7c5b7da2a9 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: mutatedigest-policy +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/01-manifests.yaml new file mode 100644 index 000000000000..06279d213033 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/01-manifests.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: mutatedigest-policy +spec: + validationFailureAction: enforce + webhookTimeoutSeconds: 30 + rules: + - name: mutatedigest-rule + match: + any: + - resources: + kinds: + - Pod + verifyImages: + - imageReferences: + - "ghcr.io/kyverno/test-verify-image*" + mutateDigest: true + verifyDigest: false + required: false \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/02-pod.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/02-pod.yaml new file mode 100644 index 000000000000..5222b22b4905 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/02-pod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: testpod + namespace: default +spec: + containers: + - name: container01 + image: ghcr.io/kyverno/test-verify-image:signed-keyless diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/03-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/03-assert.yaml new file mode 100644 index 000000000000..21a523763221 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/03-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: testpod + namespace: default +spec: + containers: + - image: ghcr.io/kyverno/test-verify-image:signed-keyless@sha256:445a99db22e9add9bfb15ddb1980861a329e5dff5c88d7eec9cbf08b6b2f4eb1 + name: container01 \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/99-cleanup.yaml new file mode 100644 index 000000000000..1f710a50a66f --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-pod.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/README.md b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/README.md new file mode 100644 index 000000000000..22091f0fe077 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/README.md @@ -0,0 +1,5 @@ +# Title + +Issue: 1234 + +This is a description of your test. diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/errors.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/errors.yaml new file mode 100644 index 000000000000..dcb47a5770a8 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/errors.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: testingsecret + namespace: default + labels: + foo: bar \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/resource.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/resource.yaml new file mode 100644 index 000000000000..cfafb7c22be4 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/resource.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +data: + foo: YmFy +kind: Secret +metadata: + name: testingsecret + namespace: default +type: Opaque \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/script-check-for-error.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/script-check-for-error.yaml new file mode 100644 index 000000000000..28860150910a --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/script-check-for-error.yaml @@ -0,0 +1,14 @@ +## Checks that the manifests.yaml file CANNOT be successfully created. If it can, fail the test as this is incorrect. + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f manifests.yaml + then + echo "Tested failed. Policy was created when it shouldn't have been." + exit 1 + else + echo "Test succeeded. Policy was not created as intended." + exit 0 + fi \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/01-assert.yaml new file mode 100644 index 000000000000..7d7c5b7da2a9 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/01-assert.yaml @@ -0,0 +1,6 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: mutatedigest-policy +status: + ready: true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/01-manifests.yaml new file mode 100644 index 000000000000..e7f8a75d081e --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/01-manifests.yaml @@ -0,0 +1,20 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: mutatedigest-policy +spec: + validationFailureAction: enforce + webhookTimeoutSeconds: 30 + rules: + - name: mutatedigest-rule + match: + any: + - resources: + kinds: + - Pod + verifyImages: + - imageReferences: + - "ghcr.io/kyverno/test-verify-image*" + mutateDigest: false + verifyDigest: true + required: false \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/02-goodpod.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/02-goodpod.yaml new file mode 100644 index 000000000000..21a523763221 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/02-goodpod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: testpod + namespace: default +spec: + containers: + - image: ghcr.io/kyverno/test-verify-image:signed-keyless@sha256:445a99db22e9add9bfb15ddb1980861a329e5dff5c88d7eec9cbf08b6b2f4eb1 + name: container01 \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/03-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/03-assert.yaml new file mode 100644 index 000000000000..21a523763221 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/03-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: testpod + namespace: default +spec: + containers: + - image: ghcr.io/kyverno/test-verify-image:signed-keyless@sha256:445a99db22e9add9bfb15ddb1980861a329e5dff5c88d7eec9cbf08b6b2f4eb1 + name: container01 \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/04-create-badpod.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/04-create-badpod.yaml new file mode 100644 index 000000000000..e8c31676e896 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/04-create-badpod.yaml @@ -0,0 +1,14 @@ +## Checks that the badpod.yaml file CANNOT be successfully created. If it can, fail the test as this is incorrect. + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f badpod.yaml + then + echo "Tested failed. Bad pod was created when it shouldn't have been." + exit 1 + else + echo "Test succeeded. Bad pod was not created as intended." + exit 0 + fi \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/99-cleanup.yaml new file mode 100644 index 000000000000..61b75559765b --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,02-goodpod.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/README.md b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/README.md new file mode 100644 index 000000000000..22091f0fe077 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/README.md @@ -0,0 +1,5 @@ +# Title + +Issue: 1234 + +This is a description of your test. diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/badpod.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/badpod.yaml new file mode 100644 index 000000000000..84b1db96abe1 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/badpod.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Pod +metadata: + name: testpod + namespace: default +spec: + containers: + - image: ghcr.io/kyverno/test-verify-image:signed-keyless + name: container01 \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/errors.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/errors.yaml new file mode 100644 index 000000000000..dcb47a5770a8 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/errors.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: testingsecret + namespace: default + labels: + foo: bar \ No newline at end of file From 4e22ad26bf2af5acdf08d6cb7ae51530dcb68f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Mon, 7 Nov 2022 19:01:25 +0100 Subject: [PATCH 26/55] chore: add kuttl in makefile (#5254) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- .github/workflows/conformance.yaml | 8 ++------ Makefile | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/.github/workflows/conformance.yaml b/.github/workflows/conformance.yaml index b86b8b67392b..f69a3d98f6f9 100644 --- a/.github/workflows/conformance.yaml +++ b/.github/workflows/conformance.yaml @@ -17,13 +17,9 @@ jobs: uses: actions/setup-go@c4a742cab115ed795e34d4513e2cf7d472deb55f # pin@v3.3.1 with: go-version: ~1.18.6 - - name: Prep environment + - name: Prepare environment run: make kind-create-cluster kind-deploy-kyverno - name: Wait for Kyverno to start run: sleep 60 - - name: Install kuttl - run: curl -sL https://github.com/kudobuilder/kuttl/releases/download/v0.13.0/kubectl-kuttl_0.13.0_linux_x86_64 -o kuttl && chmod +x kuttl - name: Test with kuttl - run: ./kuttl test --config ./test/conformance/kuttl/kuttl-test.yaml - # - name: Kyverno conformance tests - # run: go run ./test/conformance/main.go + run: make test-kuttl diff --git a/Makefile b/Makefile index b718f5244948..484d6a307918 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,9 @@ HELM_DOCS := $(TOOLS_DIR)/helm-docs HELM_DOCS_VERSION := v1.11.0 KO := $(TOOLS_DIR)/ko KO_VERSION := main #e93dbee8540f28c45ec9a2b8aec5ef8e43123966 -TOOLS := $(KIND) $(CONTROLLER_GEN) $(CLIENT_GEN) $(LISTER_GEN) $(INFORMER_GEN) $(OPENAPI_GEN) $(GEN_CRD_API_REFERENCE_DOCS) $(GO_ACC) $(KUSTOMIZE) $(GOIMPORTS) $(HELM) $(HELM_DOCS) $(KO) +KUTTL := $(TOOLS_DIR)/kubectl-kuttl +KUTTL_VERSION := v0.13.0 +TOOLS := $(KIND) $(CONTROLLER_GEN) $(CLIENT_GEN) $(LISTER_GEN) $(INFORMER_GEN) $(OPENAPI_GEN) $(GEN_CRD_API_REFERENCE_DOCS) $(GO_ACC) $(KUSTOMIZE) $(GOIMPORTS) $(HELM) $(HELM_DOCS) $(KO) $(KUTTL) ifeq ($(GOOS), darwin) SED := gsed else @@ -116,6 +118,10 @@ $(KO): @echo Install ko... >&2 @GOBIN=$(TOOLS_DIR) go install github.com/google/ko@$(KO_VERSION) +$(KUTTL): + @echo Install kuttl... >&2 + @GOBIN=$(TOOLS_DIR) go install github.com/kudobuilder/kuttl/cmd/kubectl-kuttl@$(KUTTL_VERSION) + .PHONY: install-tools install-tools: $(TOOLS) ## Install tools @@ -575,6 +581,15 @@ kind-test-conformance: kind-deploy-kyverno ## Run conformance tests on a local c @echo Running conformance tests... >&2 @go run ./test/conformance --create-cluster=false +############### +# KUTTL TESTS # +############### + +.PHONY: test-kuttl +test-kuttl: $(KUTTL) ## Run kuttl tests + @echo Running kuttl tests... >&2 + @$(KUTTL) test --config ./test/conformance/kuttl/kuttl-test.yaml + ############# # CLI TESTS # ############# From 1899938f050c8d5021e437a66c430216886712d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Mon, 7 Nov 2022 19:34:29 +0100 Subject: [PATCH 27/55] chore: use conditions in kuttl tests to check ready policies (#5252) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché Co-authored-by: shuting --- test/conformance/kuttl/aaa_template_resources/01-assert.yaml | 5 ++++- .../clone/nosync/cpol-clone-nosync-create/01-assert.yaml | 5 ++++- .../cpol-clone-nosync-delete-downstream/01-assert.yaml | 5 ++++- .../clone/sync/cpol-clone-sync-create/01-assert.yaml | 5 ++++- .../sync/cpol-clone-sync-delete-downstream/01-assert.yaml | 5 ++++- .../nosync/cpol-data-nosync-delete-downstream/01-assert.yaml | 5 ++++- .../standard/data/sync/cpol-data-sync-create/01-assert.yaml | 5 ++++- .../data/sync/cpol-data-sync-delete-policy/01-assert.yaml | 5 ++++- .../data/sync/cpol-data-sync-modify-rule/01-assert.yaml | 5 ++++- .../clusterpolicy/standard/basic-check-output/01-assert.yaml | 5 ++++- .../clusterpolicy/standard/existing/basic/01-assert.yaml | 5 ++++- .../admission/test-report-admission-mode/01-assert.yaml | 5 ++++- .../background/test-report-background-mode/02-assert.yaml | 5 ++++- .../standard/enforce/resource-apply-block/01-assert.yaml | 5 ++++- .../standard/imageExtractors-complex-keyless/01-assert.yaml | 5 ++++- .../standard/imageExtractors-complex/01-assert.yaml | 5 ++++- .../standard/imageExtractors-none/01-assert.yaml | 5 ++++- .../standard/imageExtractors-simple/01-assert.yaml | 5 ++++- .../clusterpolicy/standard/keyed-secret/01-assert.yaml | 5 ++++- .../01-assert.yaml | 5 ++++- .../01-assert.yaml | 5 ++++- .../01-assert.yaml | 5 ++++- 22 files changed, 88 insertions(+), 22 deletions(-) diff --git a/test/conformance/kuttl/aaa_template_resources/01-assert.yaml b/test/conformance/kuttl/aaa_template_resources/01-assert.yaml index 304a5e80c4d6..64afbe13fb7a 100644 --- a/test/conformance/kuttl/aaa_template_resources/01-assert.yaml +++ b/test/conformance/kuttl/aaa_template_resources/01-assert.yaml @@ -5,4 +5,7 @@ kind: ClusterPolicy metadata: name: add-labels status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/01-assert.yaml index aa86792b0a76..bb748c5b1f98 100644 --- a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/01-assert.yaml +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-create/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: cpol-nosync-clone status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/01-assert.yaml index aa86792b0a76..bb748c5b1f98 100644 --- a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/01-assert.yaml +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync/cpol-clone-nosync-delete-downstream/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: cpol-nosync-clone status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/01-assert.yaml index 370f29765ba9..329e56b1d5fe 100644 --- a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/01-assert.yaml +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-create/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: cpol-sync-clone status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/01-assert.yaml index 370f29765ba9..329e56b1d5fe 100644 --- a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/01-assert.yaml +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: cpol-sync-clone status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/01-assert.yaml index 952a960e5069..a74a39118d37 100644 --- a/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/01-assert.yaml +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync/cpol-data-nosync-delete-downstream/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: zk-kafka-address status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/01-assert.yaml index 952a960e5069..a74a39118d37 100644 --- a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/01-assert.yaml +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-create/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: zk-kafka-address status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/01-assert.yaml index 952a960e5069..a74a39118d37 100644 --- a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/01-assert.yaml +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-delete-policy/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: zk-kafka-address status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/01-assert.yaml index 952a960e5069..a74a39118d37 100644 --- a/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/01-assert.yaml +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/data/sync/cpol-data-sync-modify-rule/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: zk-kafka-address status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/01-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/01-assert.yaml index 7f1d7387c9b0..7e9f14965b97 100644 --- a/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/01-assert.yaml +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/basic-check-output/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: add-labels status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/01-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/01-assert.yaml index 56d8a26762d1..450edc769bd8 100644 --- a/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/01-assert.yaml +++ b/test/conformance/kuttl/mutate/clusterpolicy/standard/existing/basic/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: mutate-existing-secret status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/reports/admission/test-report-admission-mode/01-assert.yaml b/test/conformance/kuttl/reports/admission/test-report-admission-mode/01-assert.yaml index 8d9a20c329cb..d3fab0a6600a 100644 --- a/test/conformance/kuttl/reports/admission/test-report-admission-mode/01-assert.yaml +++ b/test/conformance/kuttl/reports/admission/test-report-admission-mode/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: require-owner status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/reports/background/test-report-background-mode/02-assert.yaml b/test/conformance/kuttl/reports/background/test-report-background-mode/02-assert.yaml index 559357481ddd..d5fb779bb2b4 100644 --- a/test/conformance/kuttl/reports/background/test-report-background-mode/02-assert.yaml +++ b/test/conformance/kuttl/reports/background/test-report-background-mode/02-assert.yaml @@ -17,4 +17,7 @@ spec: version: latest validationFailureAction: audit status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/01-assert.yaml b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/01-assert.yaml index 8d9a20c329cb..d3fab0a6600a 100644 --- a/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/01-assert.yaml +++ b/test/conformance/kuttl/validate/clusterpolicy/standard/enforce/resource-apply-block/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: require-owner status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-assert.yaml index 33390d5dcbbc..058180242b93 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-assert.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: tasks-keyless status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-assert.yaml index 4e8ef06f0863..b585ce2dc6db 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-assert.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: tasks-complex status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-assert.yaml index e51f26047c74..098aa8282193 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-assert.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: tasks-no-extractor status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-assert.yaml index 9dc5e6e273a9..567f022953aa 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-assert.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: tasks-simple status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/01-assert.yaml index 8679bbbc1d97..ca9cef7de72c 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/01-assert.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-secret/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: secret-in-keys status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/01-assert.yaml index 4b3e65c71533..efc7fb59b48e 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/01-assert.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-mutatedigest-verifydigest-required/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: keyless-mutatedigest-verifydigest-required status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/01-assert.yaml index 320fe9bd541d..1ef915c783b9 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/01-assert.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-norequired/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: keyless-nomutatedigest-noverifydigest-norequired status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/01-assert.yaml index 304da4359d37..090b115c1b8d 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/01-assert.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyless-nomutatedigest-noverifydigest-required/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: keyless-nomutatedigest-noverifydigest-required status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready From 9f842fe626bfecb2807b63c934cf6630f749b96f Mon Sep 17 00:00:00 2001 From: Chip Zoller Date: Mon, 7 Nov 2022 16:35:11 -0500 Subject: [PATCH 28/55] Kuttl updates (#5257) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add remainder of e2e verifyImages tests Signed-off-by: Chip Zoller * add tests Signed-off-by: Chip Zoller * add external-metrics test case and scaffolding Signed-off-by: Chip Zoller * update scaffolding Signed-off-by: Chip Zoller * add keyed-basic test Signed-off-by: Chip Zoller * add migrated e2e test for gen role and rolebinding Signed-off-by: Chip Zoller * add clone-role-and-rolebinding from e2e Signed-off-by: Chip Zoller * remove timeout param from kuttl-test.yaml Signed-off-by: Chip Zoller * add tests for external-metrics Policy fix Signed-off-by: Chip Zoller * update test path Signed-off-by: Chip Zoller * update README Signed-off-by: Chip Zoller Signed-off-by: Chip Zoller Co-authored-by: Vyankatesh Kudtarkar Co-authored-by: Charles-Edouard Brétéché --- .../cpol-clone-sync-delete-downstream/README.md | 14 +++++++++----- test/conformance/kuttl/kuttl-test.yaml | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/README.md b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/README.md index ff899675251a..cca30e962dd0 100644 --- a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/README.md +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-sync-delete-downstream/README.md @@ -1,7 +1,11 @@ -# Title +## Description -This test ensures that deletion of a downstream resource created by a ClusterPolicy `generate` rule with sync disabled using a clone declaration does NOT cause it to be regenerated. If the downstream resource is regenerated, the test fails. If it is not regenerated, the test succeeds. +This test ensures that deletion of a downstream resource created by a ClusterPolicy `generate` rule with sync enabled using a clone declaration causes it to be regenerated. If it is not regenerated, the test fails. -### Tests a clone rule with sync not enabled that deleting a downstream resource shows it is not recreated. -### Because https://github.com/kyverno/kyverno/issues/4457 is not yet fixed for this type, the test will fail. -### Expected result: fail \ No newline at end of file +## Expected Behavior + +The downstream resource, upon deletion, is expected to be recreated/recloned from the source resource. + +## Reference Issue(s) + +N/A \ No newline at end of file diff --git a/test/conformance/kuttl/kuttl-test.yaml b/test/conformance/kuttl/kuttl-test.yaml index 5c608ec9b662..acd3a798229f 100644 --- a/test/conformance/kuttl/kuttl-test.yaml +++ b/test/conformance/kuttl/kuttl-test.yaml @@ -2,7 +2,7 @@ apiVersion: kuttl.dev/v1beta1 kind: TestSuite testDirs: # Generate tests -# - ./generate/clusterpolicy/standard/clone/nosync +# - ./test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync - ./test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync - ./test/conformance/kuttl/generate/clusterpolicy/standard/data/sync - ./test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync From 564c92d4bfeb3902fa2c1d5bff53a88722281945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Mon, 7 Nov 2022 23:16:53 +0100 Subject: [PATCH 29/55] fix: add warning when using deprecated validation failure action (#5219) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: add warning when using deprecated validation failure action Signed-off-by: Charles-Edouard Brétéché * fix tests Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché Co-authored-by: shuting --- pkg/policy/validate.go | 14 ++++++++++++++ pkg/policy/validate_test.go | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/pkg/policy/validate.go b/pkg/policy/validate.go index 23b0fddb362a..19d2c8560318 100644 --- a/pkg/policy/validate.go +++ b/pkg/policy/validate.go @@ -109,6 +109,19 @@ func validateJSONPatch(patch string, ruleIdx int) error { return nil } +func checkValidationFailureAction(spec *kyvernov1.Spec) []string { + msg := "Validation failure actions enforce/audit are deprecated, use Enforce/Audit instead." + if spec.ValidationFailureAction == "enforce" || spec.ValidationFailureAction == "audit" { + return []string{msg} + } + for _, override := range spec.ValidationFailureActionOverrides { + if override.Action == "enforce" || override.Action == "audit" { + return []string{msg} + } + } + return nil +} + // Validate checks the policy and rules declarations for required configurations func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock bool, openApiManager openapi.Manager) ([]string, error) { var warnings []string @@ -120,6 +133,7 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b openapicontroller.NewController(client, openApiManager).CheckSync(context.TODO()) } + warnings = append(warnings, checkValidationFailureAction(spec)...) var errs field.ErrorList specPath := field.NewPath("spec") diff --git a/pkg/policy/validate_test.go b/pkg/policy/validate_test.go index 4d74c6e83166..9c5f888895a8 100644 --- a/pkg/policy/validate_test.go +++ b/pkg/policy/validate_test.go @@ -1436,7 +1436,7 @@ func Test_PodControllerAutoGenExclusion_All_Controllers_Policy(t *testing.T) { } }, "spec": { - "validationFailureAction": "enforce", + "validationFailureAction": "Enforce", "background": false, "rules": [ { @@ -1493,7 +1493,7 @@ func Test_PodControllerAutoGenExclusion_Not_All_Controllers_Policy(t *testing.T) } }, "spec": { - "validationFailureAction": "enforce", + "validationFailureAction": "Enforce", "background": false, "rules": [ { @@ -1550,7 +1550,7 @@ func Test_PodControllerAutoGenExclusion_None_Policy(t *testing.T) { } }, "spec": { - "validationFailureAction": "enforce", + "validationFailureAction": "Enforce", "background": false, "rules": [ { From f471f5c4e01b3ca1499ae614c647751bca3cb854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Tue, 8 Nov 2022 00:07:32 +0100 Subject: [PATCH 30/55] chore: remove old conformance tests files (#5260) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- test/conformance/main.go | 172 ------------------------------------ test/conformance/tests.yaml | 111 ----------------------- 2 files changed, 283 deletions(-) delete mode 100644 test/conformance/main.go delete mode 100644 test/conformance/tests.yaml diff --git a/test/conformance/main.go b/test/conformance/main.go deleted file mode 100644 index a76896a3199e..000000000000 --- a/test/conformance/main.go +++ /dev/null @@ -1,172 +0,0 @@ -package main - -import ( - "bytes" - "errors" - "flag" - "fmt" - "io/ioutil" - "log" - "os" - "os/exec" - "strings" - - "go.uber.org/multierr" - "gopkg.in/yaml.v3" -) - -type CommandExpectation struct { - ExitCode *int - StdOut *string - StdErr *string -} - -func (x CommandExpectation) Verify(stdout []byte, stderr []byte, err error) error { - exitcode := 0 - if err != nil { - exitError := err.(*exec.ExitError) - exitcode = exitError.ExitCode() - } - if x.ExitCode != nil { - if exitcode != *x.ExitCode { - return errors.New(fmt.Sprint("unexpected exit code\n expected: ", *x.ExitCode, "\n actual: ", exitcode)) - } - } - if x.StdOut != nil { - if trim(*x.StdOut, "\n", " ") != trim(string(stdout), "\n", " ") { - return errors.New(fmt.Sprint("unexpected stdout\n expected: ", *x.StdOut, "\n actual: ", string(stdout))) - } - } - if x.StdErr != nil { - if trim(*x.StdErr, "\n", " ") != trim(string(stderr), "\n", " ") { - return errors.New(fmt.Sprint("unexpected stderr\n expected: ", *x.StdErr, "\n actual: ", string(stderr))) - } - } - return nil -} - -type KubectlTest struct { - Args []string - Expect *CommandExpectation -} - -func (kt KubectlTest) Run(name string) error { - stdout, stderr, err := runCommand("kubectl", kt.Args...) - if kt.Expect != nil { - if err := kt.Expect.Verify(stdout, stderr, err); err != nil { - log.Println("--- STDERR ---") - log.Println(string(stderr)) - log.Println("--- STDOUT ---") - log.Println(string(stdout)) - return err - } - } - return nil -} - -type Test struct { - Description string - Kubectl *KubectlTest -} - -func (t Test) Run(name string) error { - if t.Kubectl != nil { - return t.Kubectl.Run(name) - } - return errors.New("no test defined") -} - -func trim(in string, s ...string) string { - for _, s := range s { - in = strings.TrimSuffix(in, s) - } - return in -} - -func runCommand(name string, arg ...string) ([]byte, []byte, error) { - cmd := exec.Command(name, arg...) - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - err := cmd.Run() - return stdout.Bytes(), stderr.Bytes(), err -} - -func stdCommand(name string, arg ...string) *exec.Cmd { - cmd := exec.Command(name, arg...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - return cmd -} - -func makeCluster() error { - cmd := stdCommand("make", "kind-create-cluster", "kind-deploy-kyverno") - if err := cmd.Run(); err != nil { - return err - } - return nil -} - -func makeDeleteCluster() error { - cmd := stdCommand("make", "kind-delete-cluster") - if err := cmd.Run(); err != nil { - return err - } - return nil -} - -func loadTests() (map[string][]Test, error) { - data, err := ioutil.ReadFile("./test/conformance/tests.yaml") - if err != nil { - return nil, err - } - tests := map[string][]Test{} - if err := yaml.Unmarshal(data, tests); err != nil { - return nil, err - } - return tests, nil -} - -func main() { - var createCluster bool - var deleteCluster bool - flag.BoolVar(&createCluster, "create-cluster", true, "Set this flag to 'false', to use an existing cluster.") - flag.BoolVar(&deleteCluster, "delete-cluster", true, "Set this flag to 'false', to not delete the created cluster.") - flag.Parse() - - tests, err := loadTests() - if err != nil { - log.Fatal(err) - } - for cluster, tests := range tests { - runner := func(name string, tests []Test) error { - if err := os.Setenv("KIND_NAME", name); err != nil { - return err - } - if createCluster { - if err := makeCluster(); err != nil { - return err - } - if deleteCluster { - defer func(name string) { - if err := makeDeleteCluster(); err != nil { - log.Fatal(err) - } - }(name) - } - } - var errs []error - for _, test := range tests { - log.Println("Running test", test.Description, "...") - if err := test.Run(name); err != nil { - log.Println("FAILED: ", err) - errs = append(errs, err) - } - } - return multierr.Combine(errs...) - } - if err := runner(cluster, tests); err != nil { - log.Fatal(err) - } - } -} diff --git a/test/conformance/tests.yaml b/test/conformance/tests.yaml deleted file mode 100644 index 39fdbf9c6bf6..000000000000 --- a/test/conformance/tests.yaml +++ /dev/null @@ -1,111 +0,0 @@ -validate-fail: - - description: Policy with background enabled and referencing clusterRoles in match/exclude statements should be rejected - kubectl: - args: - - create - - -f - - test/conformance/manifests/validate/fail/background-match-clusterroles.yaml - expect: - exitcode: 1 - stderr: >- - Error from server: error when creating "test/conformance/manifests/validate/fail/background-match-clusterroles.yaml": - admission webhook "validate-policy.kyverno.svc" denied the request: only select variables are allowed in background mode. - Set spec.background=false to disable background mode for this policy rule: - invalid variable used at path: spec/rules[0]/match/any[0]/clusterRoles - - description: Policy with background enabled and referencing roles in match/exclude statements should be rejected - kubectl: - args: - - create - - -f - - test/conformance/manifests/validate/fail/background-match-roles.yaml - expect: - exitcode: 1 - stderr: >- - Error from server: error when creating "test/conformance/manifests/validate/fail/background-match-roles.yaml": - admission webhook "validate-policy.kyverno.svc" denied the request: only select variables are allowed in background mode. - Set spec.background=false to disable background mode for this policy rule: - invalid variable used at path: spec/rules[0]/match/any[0]/roles - - description: Policy with background enabled and referencing the var request.roles should be rejected. - kubectl: - args: - - create - - -f - - test/conformance/manifests/validate/fail/background-vars-roles.yaml - expect: - exitcode: 1 - stderr: >- - Error from server: error when creating "test/conformance/manifests/validate/fail/background-vars-roles.yaml": - admission webhook "validate-policy.kyverno.svc" denied the request: only select variables are allowed in background mode. - Set spec.background=false to disable background mode for this policy rule: variable {{request.roles}} is not allowed - - description: Policy with background enabled and referencing the var request.userInfo should be rejected. - kubectl: - args: - - create - - -f - - test/conformance/manifests/validate/fail/background-vars-userinfo.yaml - expect: - exitcode: 1 - stderr: >- - Error from server: error when creating "test/conformance/manifests/validate/fail/background-vars-userinfo.yaml": - admission webhook "validate-policy.kyverno.svc" denied the request: only select variables are allowed in background mode. - Set spec.background=false to disable background mode for this policy rule: variable {{request.userInfo}} is not allowed - - description: Policy with background enabled and referencing the var request.serviceaccountname should be rejected. - kubectl: - args: - - create - - -f - - test/conformance/manifests/validate/fail/background-vars-serviceaccountname.yaml - expect: - exitcode: 1 - stderr: >- - Error from server: error when creating "test/conformance/manifests/validate/fail/background-vars-serviceaccountname.yaml": - admission webhook "validate-policy.kyverno.svc" denied the request: only select variables are allowed in background mode. - Set spec.background=false to disable background mode for this policy rule: variable {{serviceAccountName}} is not allowed - - description: Best practice policies should create fine - kubectl: - args: - - create - - -f - - test/best_practices - expect: - exitcode: 0 - stdout: |- - clusterpolicy.kyverno.io/add-networkpolicy created - clusterpolicy.kyverno.io/add-ns-quota created - clusterpolicy.kyverno.io/add-safe-to-evict created - clusterpolicy.kyverno.io/disallow-bind-mounts created - clusterpolicy.kyverno.io/disallow-host-network-port created - clusterpolicy.kyverno.io/disallow-host-pid-ipc created - clusterpolicy.kyverno.io/disallow-latest-tag created - clusterpolicy.kyverno.io/disallow-privileged created - clusterpolicy.kyverno.io/disallow-sysctls created - clusterpolicy.kyverno.io/require-certain-labels created - clusterpolicy.kyverno.io/require-labels created - clusterpolicy.kyverno.io/require-pod-requests-limits created - clusterpolicy.kyverno.io/select-secrets created - - description: Best practice policies should become ready - kubectl: - args: - - wait - - --for - - condition=ready - - cpol - - --all - - --timeout - - 90s - expect: - exitcode: 0 - stdout: |- - clusterpolicy.kyverno.io/add-networkpolicy condition met - clusterpolicy.kyverno.io/add-ns-quota condition met - clusterpolicy.kyverno.io/add-safe-to-evict condition met - clusterpolicy.kyverno.io/disallow-bind-mounts condition met - clusterpolicy.kyverno.io/disallow-host-network-port condition met - clusterpolicy.kyverno.io/disallow-host-pid-ipc condition met - clusterpolicy.kyverno.io/disallow-latest-tag condition met - clusterpolicy.kyverno.io/disallow-privileged condition met - clusterpolicy.kyverno.io/disallow-sysctls condition met - clusterpolicy.kyverno.io/require-certain-labels condition met - clusterpolicy.kyverno.io/require-labels condition met - clusterpolicy.kyverno.io/require-pod-requests-limits condition met - clusterpolicy.kyverno.io/select-secrets condition met From 6d801b26dbaec1becf95dc7daae597d46dc09565 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Tue, 8 Nov 2022 14:12:35 +0530 Subject: [PATCH 31/55] feat: create cleanup new CRDs (#5233) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * create new cleanup CRDs Signed-off-by: Nikhil Sharma * fix package Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Nikhil Sharma Signed-off-by: Charles-Edouard Brétéché Co-authored-by: Charles-Edouard Brétéché --- Makefile | 2 +- api/kyverno/v1alpha1/cleanup_policy_types.go | 111 + api/kyverno/v1alpha1/doc.go | 20 + api/kyverno/v1alpha1/register.go | 59 + api/kyverno/v1alpha1/zz_generated.deepcopy.go | 190 + charts/kyverno/templates/crds.yaml | 2530 +++++++++-- config/crds/kustomization.yaml | 2 + config/crds/kyverno.io_cleanuppolicies.yaml | 1430 ++++++ .../kyverno.io_clustercleanuppolicies.yaml | 1430 ++++++ config/install.yaml | 3976 ++++++++++++++--- config/install_debug.yaml | 3972 +++++++++++++--- docs/user/crd/index.html | 401 +- pkg/client/clientset/versioned/clientset.go | 13 + .../versioned/fake/clientset_generated.go | 7 + .../clientset/versioned/fake/register.go | 16 +- .../clientset/versioned/scheme/register.go | 16 +- .../typed/kyverno/v1alpha1/cleanuppolicy.go | 195 + .../kyverno/v1alpha1/clustercleanuppolicy.go | 184 + .../versioned/typed/kyverno/v1alpha1/doc.go | 20 + .../typed/kyverno/v1alpha1/fake/doc.go | 20 + .../v1alpha1/fake/fake_cleanuppolicy.go | 142 + .../fake/fake_clustercleanuppolicy.go | 133 + .../v1alpha1/fake/fake_kyverno_client.go | 44 + .../kyverno/v1alpha1/generated_expansion.go | 23 + .../typed/kyverno/v1alpha1/kyverno_client.go | 112 + .../informers/externalversions/generic.go | 7 + .../externalversions/kyverno/interface.go | 8 + .../kyverno/v1alpha1/cleanuppolicy.go | 90 + .../kyverno/v1alpha1/clustercleanuppolicy.go | 89 + .../kyverno/v1alpha1/interface.go | 52 + .../listers/kyverno/v1alpha1/cleanuppolicy.go | 99 + .../kyverno/v1alpha1/clustercleanuppolicy.go | 68 + .../kyverno/v1alpha1/expansion_generated.go | 31 + pkg/clients/wrappers/clientset.go | 8 + .../kyverno/v1alpha1/kyverno_client.go | 48 + 35 files changed, 14110 insertions(+), 1438 deletions(-) create mode 100644 api/kyverno/v1alpha1/cleanup_policy_types.go create mode 100644 api/kyverno/v1alpha1/doc.go create mode 100755 api/kyverno/v1alpha1/register.go create mode 100644 api/kyverno/v1alpha1/zz_generated.deepcopy.go create mode 100644 config/crds/kyverno.io_cleanuppolicies.yaml create mode 100644 config/crds/kyverno.io_clustercleanuppolicies.yaml create mode 100644 pkg/client/clientset/versioned/typed/kyverno/v1alpha1/cleanuppolicy.go create mode 100644 pkg/client/clientset/versioned/typed/kyverno/v1alpha1/clustercleanuppolicy.go create mode 100644 pkg/client/clientset/versioned/typed/kyverno/v1alpha1/doc.go create mode 100644 pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/doc.go create mode 100644 pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_cleanuppolicy.go create mode 100644 pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_clustercleanuppolicy.go create mode 100644 pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_kyverno_client.go create mode 100644 pkg/client/clientset/versioned/typed/kyverno/v1alpha1/generated_expansion.go create mode 100644 pkg/client/clientset/versioned/typed/kyverno/v1alpha1/kyverno_client.go create mode 100644 pkg/client/informers/externalversions/kyverno/v1alpha1/cleanuppolicy.go create mode 100644 pkg/client/informers/externalversions/kyverno/v1alpha1/clustercleanuppolicy.go create mode 100644 pkg/client/informers/externalversions/kyverno/v1alpha1/interface.go create mode 100644 pkg/client/listers/kyverno/v1alpha1/cleanuppolicy.go create mode 100644 pkg/client/listers/kyverno/v1alpha1/clustercleanuppolicy.go create mode 100644 pkg/client/listers/kyverno/v1alpha1/expansion_generated.go create mode 100644 pkg/clients/wrappers/kyverno/v1alpha1/kyverno_client.go diff --git a/Makefile b/Makefile index 484d6a307918..9f9415db5535 100644 --- a/Makefile +++ b/Makefile @@ -372,7 +372,7 @@ image-build-all: $(BUILD_WITH)-build-all GOPATH_SHIM := ${PWD}/.gopath PACKAGE_SHIM := $(GOPATH_SHIM)/src/$(PACKAGE) OUT_PACKAGE := $(PACKAGE)/pkg/client -INPUT_DIRS := $(PACKAGE)/api/kyverno/v1,$(PACKAGE)/api/kyverno/v1beta1,$(PACKAGE)/api/kyverno/v1alpha2,$(PACKAGE)/api/policyreport/v1alpha2 +INPUT_DIRS := $(PACKAGE)/api/kyverno/v1,$(PACKAGE)/api/kyverno/v1beta1,$(PACKAGE)/api/kyverno/v1alpha2,$(PACKAGE)/api/kyverno/v1alpha1,$(PACKAGE)/api/policyreport/v1alpha2 CLIENTSET_PACKAGE := $(OUT_PACKAGE)/clientset LISTERS_PACKAGE := $(OUT_PACKAGE)/listers INFORMERS_PACKAGE := $(OUT_PACKAGE)/informers diff --git a/api/kyverno/v1alpha1/cleanup_policy_types.go b/api/kyverno/v1alpha1/cleanup_policy_types.go new file mode 100644 index 000000000000..f26e4097815a --- /dev/null +++ b/api/kyverno/v1alpha1/cleanup_policy_types.go @@ -0,0 +1,111 @@ +/* +Copyright 2020 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Schedule",type=string,JSONPath=".spec.schedule" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" + +// CleanupPolicy defines a rule for resource cleanup. +type CleanupPolicy struct { + metav1.TypeMeta `json:",inline,omitempty"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec declares policy behaviors. + Spec CleanupPolicySpec `json:"spec"` + + // Status contains policy runtime data. + // +optional + Status CleanupPolicyStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CleanupPolicyList is a list of ClusterPolicy instances. +type CleanupPolicyList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []CleanupPolicy `json:"items"` +} + +// +genclient +// +genclient:nonNamespaced +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Schedule",type=string,JSONPath=".spec.schedule" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" + +// ClusterCleanupPolicy defines rule for resource cleanup. +type ClusterCleanupPolicy struct { + metav1.TypeMeta `json:",inline,omitempty"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec declares policy behaviors. + Spec CleanupPolicySpec `json:"spec"` + + // Status contains policy runtime data. + // +optional + Status CleanupPolicyStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterCleanupPolicyList is a list of ClusterCleanupPolicy instances. +type ClusterCleanupPolicyList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []ClusterCleanupPolicy `json:"items"` +} + +// CleanupPolicySpec stores specifications for selecting resources that the user needs to delete +// and schedule when the matching resources needs deleted. +type CleanupPolicySpec struct { + // MatchResources defines when cleanuppolicy should be applied. The match + // criteria can include resource information (e.g. kind, name, namespace, labels) + // and admission review request information like the user name or role. + // At least one kind is required. + MatchResources kyvernov1.MatchResources `json:"match,omitempty"` + + // ExcludeResources defines when cleanuppolicy should not be applied. The exclude + // criteria can include resource information (e.g. kind, name, namespace, labels) + // and admission review request information like the name or role. + // +optional + ExcludeResources kyvernov1.MatchResources `json:"exclude,omitempty"` + + // The schedule in Cron format + Schedule string `json:"schedule"` + + // Conditions defines conditions used to select resources which user needs to delete + // +optional + Conditions *kyvernov1.AnyAllConditions `json:"conditions,omitempty"` +} + +// CleanupPolicyStatus stores the status of the policy. +type CleanupPolicyStatus struct { + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` +} diff --git a/api/kyverno/v1alpha1/doc.go b/api/kyverno/v1alpha1/doc.go new file mode 100644 index 000000000000..2c250f00a785 --- /dev/null +++ b/api/kyverno/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright 2020 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +kubebuilder:object:generate=true +// +groupName=kyverno.io +package v1alpha1 diff --git a/api/kyverno/v1alpha1/register.go b/api/kyverno/v1alpha1/register.go new file mode 100755 index 000000000000..262ee312dcba --- /dev/null +++ b/api/kyverno/v1alpha1/register.go @@ -0,0 +1,59 @@ +/* +Copyright 2020 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +kubebuilder:object:generate=true +// +groupName=kyverno.io +package v1alpha1 + +import ( + "github.com/kyverno/kyverno/api/kyverno" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: kyverno.GroupName, Version: "v1alpha1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // SchemeBuilder builds the scheme + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + + // AddToScheme adds all types of this clientset into the given scheme + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &CleanupPolicy{}, + &CleanupPolicyList{}, + &ClusterCleanupPolicy{}, + &ClusterCleanupPolicyList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/api/kyverno/v1alpha1/zz_generated.deepcopy.go b/api/kyverno/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 000000000000..9627f046afe2 --- /dev/null +++ b/api/kyverno/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,190 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "github.com/kyverno/kyverno/api/kyverno/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CleanupPolicy) DeepCopyInto(out *CleanupPolicy) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CleanupPolicy. +func (in *CleanupPolicy) DeepCopy() *CleanupPolicy { + if in == nil { + return nil + } + out := new(CleanupPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CleanupPolicy) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CleanupPolicyList) DeepCopyInto(out *CleanupPolicyList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CleanupPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CleanupPolicyList. +func (in *CleanupPolicyList) DeepCopy() *CleanupPolicyList { + if in == nil { + return nil + } + out := new(CleanupPolicyList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CleanupPolicyList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CleanupPolicySpec) DeepCopyInto(out *CleanupPolicySpec) { + *out = *in + in.MatchResources.DeepCopyInto(&out.MatchResources) + in.ExcludeResources.DeepCopyInto(&out.ExcludeResources) + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = new(v1.AnyAllConditions) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CleanupPolicySpec. +func (in *CleanupPolicySpec) DeepCopy() *CleanupPolicySpec { + if in == nil { + return nil + } + out := new(CleanupPolicySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CleanupPolicyStatus) DeepCopyInto(out *CleanupPolicyStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CleanupPolicyStatus. +func (in *CleanupPolicyStatus) DeepCopy() *CleanupPolicyStatus { + if in == nil { + return nil + } + out := new(CleanupPolicyStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCleanupPolicy) DeepCopyInto(out *ClusterCleanupPolicy) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCleanupPolicy. +func (in *ClusterCleanupPolicy) DeepCopy() *ClusterCleanupPolicy { + if in == nil { + return nil + } + out := new(ClusterCleanupPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterCleanupPolicy) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterCleanupPolicyList) DeepCopyInto(out *ClusterCleanupPolicyList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterCleanupPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterCleanupPolicyList. +func (in *ClusterCleanupPolicyList) DeepCopy() *ClusterCleanupPolicyList { + if in == nil { + return nil + } + out := new(ClusterCleanupPolicyList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterCleanupPolicyList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} diff --git a/charts/kyverno/templates/crds.yaml b/charts/kyverno/templates/crds.yaml index 73d551a6aa5f..2fe9ade849f0 100644 --- a/charts/kyverno/templates/crds.yaml +++ b/charts/kyverno/templates/crds.yaml @@ -508,60 +508,27 @@ metadata: app.kubernetes.io/name: kyverno app.kubernetes.io/part-of: kyverno app.kubernetes.io/version: '{{.Chart.AppVersion}}' - name: clusteradmissionreports.kyverno.io + name: cleanuppolicies.kyverno.io spec: group: kyverno.io names: - categories: - - kyverno - - all - kind: ClusterAdmissionReport - listKind: ClusterAdmissionReportList - plural: clusteradmissionreports - shortNames: - - cadmr - singular: clusteradmissionreport - scope: Cluster + kind: CleanupPolicy + listKind: CleanupPolicyList + plural: cleanuppolicies + singular: cleanuppolicy + scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .metadata.ownerReferences[0].apiVersion - name: ApiVersion - priority: 1 - type: string - - jsonPath: .metadata.ownerReferences[0].kind - name: Kind - priority: 1 - type: string - - jsonPath: .metadata.ownerReferences[0].name - name: Subject - priority: 1 + - jsonPath: .spec.schedule + name: Schedule type: string - - jsonPath: .spec.summary.pass - name: Pass - type: integer - - jsonPath: .spec.summary.fail - name: Fail - type: integer - - jsonPath: .spec.summary.warn - name: Warn - type: integer - - jsonPath: .spec.summary.error - name: Error - type: integer - - jsonPath: .spec.summary.skip - name: Skip - type: integer - jsonPath: .metadata.creationTimestamp name: Age type: date - - jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash'] - name: Hash - priority: 1 - type: string - name: v1alpha2 + name: v1alpha1 schema: openAPIV3Schema: - description: ClusterAdmissionReport is the Schema for the ClusterAdmissionReports API + description: CleanupPolicy defines a rule for resource cleanup. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' @@ -572,176 +539,1156 @@ spec: metadata: type: object spec: + description: Spec declares policy behaviors. properties: - owner: - description: Owner is a reference to the report owner (e.g. a Deployment, Namespace, or Node) + conditions: + description: Conditions defines conditions used to select resources which user needs to delete properties: - apiVersion: - description: API version of the referent. - type: string - blockOwnerDeletion: - description: If true, AND if the owner has the "foregroundDeletion" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs "delete" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned. - type: boolean - controller: - description: If true, this reference points to the managing controller. - type: boolean - kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names' - type: string - uid: - description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids' - type: string - required: - - apiVersion - - kind - - name - - uid - type: object - x-kubernetes-map-type: atomic - results: - description: PolicyReportResult provides result details - items: - description: PolicyReportResult provides the result for an individual policy - properties: - category: - description: Category indicates policy category - type: string - message: - description: Description is a short user friendly message for the policy rule - type: string - policy: - description: Policy is the name or identifier of the policy - type: string - properties: - additionalProperties: - type: string - description: Properties provides additional information for the policy rule + all: + description: AllConditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation. Here, all of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using JMESPath. + x-kubernetes-preserve-unknown-fields: true type: object - resourceSelector: - description: SubjectSelector is an optional label selector for checked Kubernetes resources. For example, a policy result may apply to all pods that match a label. Either a Subject or a SubjectSelector can be specified. If neither are provided, the result is assumed to be for the policy report scope. + type: array + any: + description: AnyConditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation. Here, at least one of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria for rule execution. properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + key: + description: Key is the context entry (using JMESPath) for conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + type: object + exclude: + description: ExcludeResources defines when cleanuppolicy should not be applied. The exclude criteria can include resource information (e.g. kind, name, namespace, labels) and admission review request information like the name or role. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names for the user. items: - description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: string + type: array + resources: + description: ResourceDescription contains information about the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value pairs of type string). Annotation keys and values support the wildcard characters "*" (matches zero or many characters) and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the resource namespace. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character).Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character). Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, user groups, and service accounts. + items: + description: Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names. properties: - key: - description: key is the label key that the selector applies to. + apiGroup: + description: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. type: string - operator: - description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + kind: + description: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error. type: string - values: - description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. - items: - type: string - type: array required: - - key - - operator + - kind + - name type: object + x-kubernetes-map-type: atomic type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object type: object - x-kubernetes-map-type: atomic - resources: - description: Subjects is an optional reference to the checked Kubernetes resources - items: - description: "ObjectReference contains enough information to let you inspect or modify the referred object. --- New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs. 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage. 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular restrictions like, \"must refer only to types A and B\" or \"UID not honored\" or \"name must be restricted\". Those cannot be well described when embedded. 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen. 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple and the version of the actual struct is irrelevant. 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. \n Instead of using this type, create a locally provided and used type that is well-focused on your reference. For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 ." - properties: - apiVersion: - description: API version of the referent. + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names for the user. + items: type: string - fieldPath: - description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' - type: string - kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' - type: string - resourceVersion: - description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' - type: string - uid: - description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: array + resources: + description: ResourceDescription contains information about the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value pairs of type string). Annotation keys and values support the wildcard characters "*" (matches zero or many characters) and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the resource namespace. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character).Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character). Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the user. + items: type: string + type: array + subjects: + description: Subjects is the list of subject names like users, user groups, and service accounts. + items: + description: Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the resource being created or modified. Requires at least one tag to be specified when under MatchResources. Specifying ResourceDescription directly under match is being deprecated. Please specify under "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value pairs of type string). Annotation keys and values support the wildcard characters "*" (matches zero or many characters) and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the resource namespace. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character).Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object type: object x-kubernetes-map-type: atomic - type: array - result: - description: Result indicates the outcome of the policy rule execution - enum: - - pass - - fail - - warn - - error - - skip - type: string - rule: - description: Rule is the name or identifier of the rule within the policy - type: string - scored: - description: Scored indicates if this result is scored - type: boolean - severity: - description: Severity indicates policy check result criticality - enum: - - critical - - high - - low - - medium - - info - type: string - source: - description: Source is an identifier for the policy engine that manages this report + namespaces: + description: Namespaces is a list of namespaces names. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character). Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the user. + items: type: string - timestamp: - description: Timestamp indicates the time the result was found + type: array + subjects: + description: Subjects is the list of subject names like users, user groups, and service accounts. + items: + description: Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names. properties: - nanos: - description: Non-negative fractions of a second at nanosecond resolution. Negative second values with fractions must still have non-negative nanos values that count forward in time. Must be from 0 to 999,999,999 inclusive. This field may be limited in precision depending on context. - format: int32 - type: integer - seconds: - description: Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive. - format: int64 - type: integer + apiGroup: + description: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error. + type: string required: - - nanos - - seconds + - kind + - name type: object - required: - - policy - type: object - type: array - summary: - description: PolicyReportSummary provides a summary of results + x-kubernetes-map-type: atomic + type: array + type: object + match: + description: MatchResources defines when cleanuppolicy should be applied. The match criteria can include resource information (e.g. kind, name, namespace, labels) and admission review request information like the user name or role. At least one kind is required. properties: - error: - description: Error provides the count of policies that could not be evaluated - type: integer - fail: - description: Fail provides the count of policies whose requirements were not met - type: integer - pass: - description: Pass provides the count of policies whose requirements were met - type: integer - skip: - description: Skip indicates the count of policies that were not selected for evaluation - type: integer - warn: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value pairs of type string). Annotation keys and values support the wildcard characters "*" (matches zero or many characters) and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the resource namespace. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character).Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character). Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, user groups, and service accounts. + items: + description: Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value pairs of type string). Annotation keys and values support the wildcard characters "*" (matches zero or many characters) and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the resource namespace. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character).Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character). Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, user groups, and service accounts. + items: + description: Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the resource being created or modified. Requires at least one tag to be specified when under MatchResources. Specifying ResourceDescription directly under match is being deprecated. Please specify under "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value pairs of type string). Annotation keys and values support the wildcard characters "*" (matches zero or many characters) and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the resource namespace. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character).Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character). Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, user groups, and service accounts. + items: + description: Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + schedule: + description: The schedule in Cron format + type: string + required: + - schedule + type: object + status: + description: Status contains policy runtime data. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + config.kubernetes.io/index: '4' + internal.config.kubernetes.io/index: '4' + {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} + creationTimestamp: null + labels: + app.kubernetes.io/component: kyverno + app.kubernetes.io/instance: kyverno + app.kubernetes.io/name: kyverno + app.kubernetes.io/part-of: kyverno + app.kubernetes.io/version: '{{.Chart.AppVersion}}' + name: clusteradmissionreports.kyverno.io +spec: + group: kyverno.io + names: + categories: + - kyverno + - all + kind: ClusterAdmissionReport + listKind: ClusterAdmissionReportList + plural: clusteradmissionreports + shortNames: + - cadmr + singular: clusteradmissionreport + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.ownerReferences[0].apiVersion + name: ApiVersion + priority: 1 + type: string + - jsonPath: .metadata.ownerReferences[0].kind + name: Kind + priority: 1 + type: string + - jsonPath: .metadata.ownerReferences[0].name + name: Subject + priority: 1 + type: string + - jsonPath: .spec.summary.pass + name: Pass + type: integer + - jsonPath: .spec.summary.fail + name: Fail + type: integer + - jsonPath: .spec.summary.warn + name: Warn + type: integer + - jsonPath: .spec.summary.error + name: Error + type: integer + - jsonPath: .spec.summary.skip + name: Skip + type: integer + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash'] + name: Hash + priority: 1 + type: string + name: v1alpha2 + schema: + openAPIV3Schema: + description: ClusterAdmissionReport is the Schema for the ClusterAdmissionReports API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + owner: + description: Owner is a reference to the report owner (e.g. a Deployment, Namespace, or Node) + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: If true, AND if the owner has the "foregroundDeletion" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs "delete" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing controller. + type: boolean + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + uid: + description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + x-kubernetes-map-type: atomic + results: + description: PolicyReportResult provides result details + items: + description: PolicyReportResult provides the result for an individual policy + properties: + category: + description: Category indicates policy category + type: string + message: + description: Description is a short user friendly message for the policy rule + type: string + policy: + description: Policy is the name or identifier of the policy + type: string + properties: + additionalProperties: + type: string + description: Properties provides additional information for the policy rule + type: object + resourceSelector: + description: SubjectSelector is an optional label selector for checked Kubernetes resources. For example, a policy result may apply to all pods that match a label. Either a Subject or a SubjectSelector can be specified. If neither are provided, the result is assumed to be for the policy report scope. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Subjects is an optional reference to the checked Kubernetes resources + items: + description: "ObjectReference contains enough information to let you inspect or modify the referred object. --- New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs. 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage. 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular restrictions like, \"must refer only to types A and B\" or \"UID not honored\" or \"name must be restricted\". Those cannot be well described when embedded. 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen. 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple and the version of the actual struct is irrelevant. 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. \n Instead of using this type, create a locally provided and used type that is well-focused on your reference. For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + result: + description: Result indicates the outcome of the policy rule execution + enum: + - pass + - fail + - warn + - error + - skip + type: string + rule: + description: Rule is the name or identifier of the rule within the policy + type: string + scored: + description: Scored indicates if this result is scored + type: boolean + severity: + description: Severity indicates policy check result criticality + enum: + - critical + - high + - low + - medium + - info + type: string + source: + description: Source is an identifier for the policy engine that manages this report + type: string + timestamp: + description: Timestamp indicates the time the result was found + properties: + nanos: + description: Non-negative fractions of a second at nanosecond resolution. Negative second values with fractions must still have non-negative nanos values that count forward in time. Must be from 0 to 999,999,999 inclusive. This field may be limited in precision depending on context. + format: int32 + type: integer + seconds: + description: Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive. + format: int64 + type: integer + required: + - nanos + - seconds + type: object + required: + - policy + type: object + type: array + summary: + description: PolicyReportSummary provides a summary of results + properties: + error: + description: Error provides the count of policies that could not be evaluated + type: integer + fail: + description: Fail provides the count of policies whose requirements were not met + type: integer + pass: + description: Pass provides the count of policies whose requirements were met + type: integer + skip: + description: Skip indicates the count of policies that were not selected for evaluation + type: integer + warn: description: Warn provides the count of non-scored policies whose requirements were not met type: integer type: object @@ -760,8 +1707,8 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.10.0 - config.kubernetes.io/index: '4' - internal.config.kubernetes.io/index: '4' + config.kubernetes.io/index: '5' + internal.config.kubernetes.io/index: '5' {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: @@ -846,154 +1793,1101 @@ spec: message: description: Description is a short user friendly message for the policy rule type: string - policy: - description: Policy is the name or identifier of the policy + policy: + description: Policy is the name or identifier of the policy + type: string + properties: + additionalProperties: + type: string + description: Properties provides additional information for the policy rule + type: object + resourceSelector: + description: SubjectSelector is an optional label selector for checked Kubernetes resources. For example, a policy result may apply to all pods that match a label. Either a Subject or a SubjectSelector can be specified. If neither are provided, the result is assumed to be for the policy report scope. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Subjects is an optional reference to the checked Kubernetes resources + items: + description: "ObjectReference contains enough information to let you inspect or modify the referred object. --- New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs. 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage. 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular restrictions like, \"must refer only to types A and B\" or \"UID not honored\" or \"name must be restricted\". Those cannot be well described when embedded. 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen. 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple and the version of the actual struct is irrelevant. 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. \n Instead of using this type, create a locally provided and used type that is well-focused on your reference. For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + result: + description: Result indicates the outcome of the policy rule execution + enum: + - pass + - fail + - warn + - error + - skip + type: string + rule: + description: Rule is the name or identifier of the rule within the policy + type: string + scored: + description: Scored indicates if this result is scored + type: boolean + severity: + description: Severity indicates policy check result criticality + enum: + - critical + - high + - low + - medium + - info + type: string + source: + description: Source is an identifier for the policy engine that manages this report + type: string + timestamp: + description: Timestamp indicates the time the result was found + properties: + nanos: + description: Non-negative fractions of a second at nanosecond resolution. Negative second values with fractions must still have non-negative nanos values that count forward in time. Must be from 0 to 999,999,999 inclusive. This field may be limited in precision depending on context. + format: int32 + type: integer + seconds: + description: Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive. + format: int64 + type: integer + required: + - nanos + - seconds + type: object + required: + - policy + type: object + type: array + summary: + description: PolicyReportSummary provides a summary of results + properties: + error: + description: Error provides the count of policies that could not be evaluated + type: integer + fail: + description: Fail provides the count of policies whose requirements were not met + type: integer + pass: + description: Pass provides the count of policies whose requirements were met + type: integer + skip: + description: Skip indicates the count of policies that were not selected for evaluation + type: integer + warn: + description: Warn provides the count of non-scored policies whose requirements were not met + type: integer + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + config.kubernetes.io/index: '6' + internal.config.kubernetes.io/index: '6' + {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} + creationTimestamp: null + labels: + app.kubernetes.io/component: kyverno + app.kubernetes.io/instance: kyverno + app.kubernetes.io/name: kyverno + app.kubernetes.io/part-of: kyverno + app.kubernetes.io/version: '{{.Chart.AppVersion}}' + name: clustercleanuppolicies.kyverno.io +spec: + group: kyverno.io + names: + kind: ClusterCleanupPolicy + listKind: ClusterCleanupPolicyList + plural: clustercleanuppolicies + singular: clustercleanuppolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.schedule + name: Schedule + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ClusterCleanupPolicy defines rule for resource cleanup. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec declares policy behaviors. + properties: + conditions: + description: Conditions defines conditions used to select resources which user needs to delete + properties: + all: + description: AllConditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation. Here, all of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + any: + description: AnyConditions enable variable-based conditional rule execution. This is useful for finer control of when an rule is applied. A condition can reference object data using JMESPath notation. Here, at least one of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. The values can be fixed set or can be variables declared using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + type: object + exclude: + description: ExcludeResources defines when cleanuppolicy should not be applied. The exclude criteria can include resource information (e.g. kind, name, namespace, labels) and admission review request information like the name or role. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value pairs of type string). Annotation keys and values support the wildcard characters "*" (matches zero or many characters) and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the resource namespace. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character).Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character). Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, user groups, and service accounts. + items: + description: Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value pairs of type string). Annotation keys and values support the wildcard characters "*" (matches zero or many characters) and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the resource namespace. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character).Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character). Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, user groups, and service accounts. + items: + description: Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the resource being created or modified. Requires at least one tag to be specified when under MatchResources. Specifying ResourceDescription directly under match is being deprecated. Please specify under "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value pairs of type string). Annotation keys and values support the wildcard characters "*" (matches zero or many characters) and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the resource namespace. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character).Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character). Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the user. + items: type: string - properties: - additionalProperties: - type: string - description: Properties provides additional information for the policy rule + type: array + subjects: + description: Subjects is the list of subject names like users, user groups, and service accounts. + items: + description: Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error. + type: string + required: + - kind + - name type: object - resourceSelector: - description: SubjectSelector is an optional label selector for checked Kubernetes resources. For example, a policy result may apply to all pods that match a label. Either a Subject or a SubjectSelector can be specified. If neither are provided, the result is assumed to be for the policy report scope. + x-kubernetes-map-type: atomic + type: array + type: object + match: + description: MatchResources defines when cleanuppolicy should be applied. The match criteria can include resource information (e.g. kind, name, namespace, labels) and admission review request information like the user name or role. At least one kind is required. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between resources properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value pairs of type string). Annotation keys and values support the wildcard characters "*" (matches zero or many characters) and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the resource namespace. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character).Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character). Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, user groups, and service accounts. + items: + description: Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value pairs of type string). Annotation keys and values support the wildcard characters "*" (matches zero or many characters) and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the resource namespace. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character).Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character). Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the user. items: - description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, user groups, and service accounts. + items: + description: Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names. properties: - key: - description: key is the label key that the selector applies to. + apiGroup: + description: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. type: string - operator: - description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + kind: + description: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error. type: string - values: - description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. - items: - type: string - type: array required: - - key - - operator + - kind + - name type: object + x-kubernetes-map-type: atomic type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object type: object - x-kubernetes-map-type: atomic - resources: - description: Subjects is an optional reference to the checked Kubernetes resources - items: - description: "ObjectReference contains enough information to let you inspect or modify the referred object. --- New uses of this type are discouraged because of difficulty describing its usage when embedded in APIs. 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage. 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular restrictions like, \"must refer only to types A and B\" or \"UID not honored\" or \"name must be restricted\". Those cannot be well described when embedded. 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen. 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple and the version of the actual struct is irrelevant. 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control. \n Instead of using this type, create a locally provided and used type that is well-focused on your reference. For example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 ." + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the resource being created or modified. Requires at least one tag to be specified when under MatchResources. Specifying ResourceDescription directly under match is being deprecated. Please specify under "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value pairs of type string). Annotation keys and values support the wildcard characters "*" (matches zero or many characters) and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the resource namespace. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character).Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' properties: - apiVersion: - description: API version of the referent. - type: string - fieldPath: - description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' - type: string - kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' - type: string - resourceVersion: - description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' - type: string - uid: - description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' - type: string + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object type: object x-kubernetes-map-type: atomic - type: array - result: - description: Result indicates the outcome of the policy rule execution - enum: - - pass - - fail - - warn - - error - - skip + namespaces: + description: Namespaces is a list of namespaces names. Each name supports wildcard characters "*" (matches zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and values in `matchLabels` support the wildcard characters `*` (matches zero or many characters) and `?` (matches one character). Wildcards allows writing label selectors like ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the user. + items: type: string - rule: - description: Rule is the name or identifier of the rule within the policy + type: array + subjects: + description: Subjects is the list of subject names like users, user groups, and service accounts. + items: + description: Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced subject. Defaults to "" for ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount". If the Authorizer does not recognized the kind value, the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty the Authorizer should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + schedule: + description: The schedule in Cron format + type: string + required: + - schedule + type: object + status: + description: Status contains policy runtime data. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time type: string - scored: - description: Scored indicates if this result is scored - type: boolean - severity: - description: Severity indicates policy check result criticality + message: + description: message is a human readable message indicating details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. enum: - - critical - - high - - low - - medium - - info + - "True" + - "False" + - Unknown type: string - source: - description: Source is an identifier for the policy engine that manages this report + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string - timestamp: - description: Timestamp indicates the time the result was found - properties: - nanos: - description: Non-negative fractions of a second at nanosecond resolution. Negative second values with fractions must still have non-negative nanos values that count forward in time. Must be from 0 to 999,999,999 inclusive. This field may be limited in precision depending on context. - format: int32 - type: integer - seconds: - description: Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive. - format: int64 - type: integer - required: - - nanos - - seconds - type: object required: - - policy + - lastTransitionTime + - message + - reason + - status + - type type: object type: array - summary: - description: PolicyReportSummary provides a summary of results - properties: - error: - description: Error provides the count of policies that could not be evaluated - type: integer - fail: - description: Fail provides the count of policies whose requirements were not met - type: integer - pass: - description: Pass provides the count of policies whose requirements were met - type: integer - skip: - description: Skip indicates the count of policies that were not selected for evaluation - type: integer - warn: - description: Warn provides the count of non-scored policies whose requirements were not met - type: integer - type: object type: object required: - spec type: object served: true storage: true - subresources: {} + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.10.0 - config.kubernetes.io/index: '5' - internal.config.kubernetes.io/index: '5' + config.kubernetes.io/index: '7' + internal.config.kubernetes.io/index: '7' {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: @@ -8214,8 +10108,8 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.10.0 - config.kubernetes.io/index: '6' - internal.config.kubernetes.io/index: '6' + config.kubernetes.io/index: '8' + internal.config.kubernetes.io/index: '8' {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: @@ -8487,8 +10381,8 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.10.0 - config.kubernetes.io/index: '7' - internal.config.kubernetes.io/index: '7' + config.kubernetes.io/index: '9' + internal.config.kubernetes.io/index: '9' {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: @@ -8663,8 +10557,8 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.10.0 - config.kubernetes.io/index: '8' - internal.config.kubernetes.io/index: '8' + config.kubernetes.io/index: '10' + internal.config.kubernetes.io/index: '10' {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: @@ -15885,8 +17779,8 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.10.0 - config.kubernetes.io/index: '9' - internal.config.kubernetes.io/index: '9' + config.kubernetes.io/index: '11' + internal.config.kubernetes.io/index: '11' {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: @@ -16158,8 +18052,8 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.10.0 - config.kubernetes.io/index: '10' - internal.config.kubernetes.io/index: '10' + config.kubernetes.io/index: '12' + internal.config.kubernetes.io/index: '12' {{- trim (include "kyverno.crdAnnotations" .) | nindent 4 }} creationTimestamp: null labels: diff --git a/config/crds/kustomization.yaml b/config/crds/kustomization.yaml index f81ed5e8ef7d..ea837128230e 100755 --- a/config/crds/kustomization.yaml +++ b/config/crds/kustomization.yaml @@ -4,8 +4,10 @@ kind: Kustomization resources: - ./kyverno.io_admissionreports.yaml - ./kyverno.io_backgroundscanreports.yaml +- ./kyverno.io_cleanuppolicies.yaml - ./kyverno.io_clusteradmissionreports.yaml - ./kyverno.io_clusterbackgroundscanreports.yaml +- ./kyverno.io_clustercleanuppolicies.yaml - ./kyverno.io_clusterpolicies.yaml - ./kyverno.io_generaterequests.yaml - ./kyverno.io_policies.yaml diff --git a/config/crds/kyverno.io_cleanuppolicies.yaml b/config/crds/kyverno.io_cleanuppolicies.yaml new file mode 100644 index 000000000000..40163373a6f0 --- /dev/null +++ b/config/crds/kyverno.io_cleanuppolicies.yaml @@ -0,0 +1,1430 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: cleanuppolicies.kyverno.io +spec: + group: kyverno.io + names: + kind: CleanupPolicy + listKind: CleanupPolicyList + plural: cleanuppolicies + singular: cleanuppolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.schedule + name: Schedule + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: CleanupPolicy defines a rule for resource cleanup. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec declares policy behaviors. + properties: + conditions: + description: Conditions defines conditions used to select resources + which user needs to delete + properties: + all: + description: AllConditions enable variable-based conditional rule + execution. This is useful for finer control of when an rule + is applied. A condition can reference object data using JMESPath + notation. Here, all of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria + for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for + conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. + Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, + NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, + LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, + DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. + The values can be fixed set or can be variables declared + using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + any: + description: AnyConditions enable variable-based conditional rule + execution. This is useful for finer control of when an rule + is applied. A condition can reference object data using JMESPath + notation. Here, at least one of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria + for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for + conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. + Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, + NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, + LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, + DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. + The values can be fixed set or can be variables declared + using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + type: object + exclude: + description: ExcludeResources defines when cleanuppolicy should not + be applied. The exclude criteria can include resource information + (e.g. kind, name, namespace, labels) and admission review request + information like the name or role. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names + for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the + resource being created or modified. Requires at least one tag + to be specified when under MatchResources. Specifying ResourceDescription + directly under match is being deprecated. Please specify under + "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values support + the wildcard characters "*" (matches zero or many characters) + and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports + wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). NOTE: "Name" is being + deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name + supports wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the + resource namespace. Label keys and values in `matchLabels` + support the wildcard characters `*` (matches zero or many + characters) and `?` (matches one character).Wildcards allows + writing label selectors like ["storage.k8s.io/*": "*"]. + Note that using ["*" : "*"] matches any key and value but + does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each + name supports wildcard characters "*" (matches zero or many + characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and + values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches one + character). Wildcards allows writing label selectors like + ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches + any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the + user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, + user groups, and service accounts. + items: + description: Subject contains a reference to the object or user + identities a role binding applies to. This can either hold + a direct API object reference, or a value for non-objects + such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. Defaults + to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined + by this API group are "User", "Group", and "ServiceAccount". + If the Authorizer does not recognized the kind value, + the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the + object kind is non-namespace, such as "User" or "Group", + and this value is not empty the Authorizer should report + an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + match: + description: MatchResources defines when cleanuppolicy should be applied. + The match criteria can include resource information (e.g. kind, + name, namespace, labels) and admission review request information + like the user name or role. At least one kind is required. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names + for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the + resource being created or modified. Requires at least one tag + to be specified when under MatchResources. Specifying ResourceDescription + directly under match is being deprecated. Please specify under + "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values support + the wildcard characters "*" (matches zero or many characters) + and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports + wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). NOTE: "Name" is being + deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name + supports wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the + resource namespace. Label keys and values in `matchLabels` + support the wildcard characters `*` (matches zero or many + characters) and `?` (matches one character).Wildcards allows + writing label selectors like ["storage.k8s.io/*": "*"]. + Note that using ["*" : "*"] matches any key and value but + does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each + name supports wildcard characters "*" (matches zero or many + characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and + values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches one + character). Wildcards allows writing label selectors like + ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches + any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the + user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, + user groups, and service accounts. + items: + description: Subject contains a reference to the object or user + identities a role binding applies to. This can either hold + a direct API object reference, or a value for non-objects + such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. Defaults + to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined + by this API group are "User", "Group", and "ServiceAccount". + If the Authorizer does not recognized the kind value, + the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the + object kind is non-namespace, such as "User" or "Group", + and this value is not empty the Authorizer should report + an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + schedule: + description: The schedule in Cron format + type: string + required: + - schedule + type: object + status: + description: Status contains policy runtime data. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crds/kyverno.io_clustercleanuppolicies.yaml b/config/crds/kyverno.io_clustercleanuppolicies.yaml new file mode 100644 index 000000000000..481c58443f5e --- /dev/null +++ b/config/crds/kyverno.io_clustercleanuppolicies.yaml @@ -0,0 +1,1430 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: clustercleanuppolicies.kyverno.io +spec: + group: kyverno.io + names: + kind: ClusterCleanupPolicy + listKind: ClusterCleanupPolicyList + plural: clustercleanuppolicies + singular: clustercleanuppolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.schedule + name: Schedule + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ClusterCleanupPolicy defines rule for resource cleanup. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec declares policy behaviors. + properties: + conditions: + description: Conditions defines conditions used to select resources + which user needs to delete + properties: + all: + description: AllConditions enable variable-based conditional rule + execution. This is useful for finer control of when an rule + is applied. A condition can reference object data using JMESPath + notation. Here, all of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria + for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for + conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. + Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, + NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, + LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, + DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. + The values can be fixed set or can be variables declared + using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + any: + description: AnyConditions enable variable-based conditional rule + execution. This is useful for finer control of when an rule + is applied. A condition can reference object data using JMESPath + notation. Here, at least one of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria + for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for + conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. + Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, + NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, + LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, + DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. + The values can be fixed set or can be variables declared + using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + type: object + exclude: + description: ExcludeResources defines when cleanuppolicy should not + be applied. The exclude criteria can include resource information + (e.g. kind, name, namespace, labels) and admission review request + information like the name or role. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names + for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the + resource being created or modified. Requires at least one tag + to be specified when under MatchResources. Specifying ResourceDescription + directly under match is being deprecated. Please specify under + "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values support + the wildcard characters "*" (matches zero or many characters) + and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports + wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). NOTE: "Name" is being + deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name + supports wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the + resource namespace. Label keys and values in `matchLabels` + support the wildcard characters `*` (matches zero or many + characters) and `?` (matches one character).Wildcards allows + writing label selectors like ["storage.k8s.io/*": "*"]. + Note that using ["*" : "*"] matches any key and value but + does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each + name supports wildcard characters "*" (matches zero or many + characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and + values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches one + character). Wildcards allows writing label selectors like + ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches + any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the + user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, + user groups, and service accounts. + items: + description: Subject contains a reference to the object or user + identities a role binding applies to. This can either hold + a direct API object reference, or a value for non-objects + such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. Defaults + to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined + by this API group are "User", "Group", and "ServiceAccount". + If the Authorizer does not recognized the kind value, + the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the + object kind is non-namespace, such as "User" or "Group", + and this value is not empty the Authorizer should report + an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + match: + description: MatchResources defines when cleanuppolicy should be applied. + The match criteria can include resource information (e.g. kind, + name, namespace, labels) and admission review request information + like the user name or role. At least one kind is required. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names + for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the + resource being created or modified. Requires at least one tag + to be specified when under MatchResources. Specifying ResourceDescription + directly under match is being deprecated. Please specify under + "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values support + the wildcard characters "*" (matches zero or many characters) + and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports + wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). NOTE: "Name" is being + deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name + supports wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the + resource namespace. Label keys and values in `matchLabels` + support the wildcard characters `*` (matches zero or many + characters) and `?` (matches one character).Wildcards allows + writing label selectors like ["storage.k8s.io/*": "*"]. + Note that using ["*" : "*"] matches any key and value but + does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each + name supports wildcard characters "*" (matches zero or many + characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and + values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches one + character). Wildcards allows writing label selectors like + ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches + any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the + user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, + user groups, and service accounts. + items: + description: Subject contains a reference to the object or user + identities a role binding applies to. This can either hold + a direct API object reference, or a value for non-objects + such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. Defaults + to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined + by this API group are "User", "Group", and "ServiceAccount". + If the Authorizer does not recognized the kind value, + the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the + object kind is non-namespace, such as "User" or "Group", + and this value is not empty the Authorizer should report + an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + schedule: + description: The schedule in Cron format + type: string + required: + - schedule + type: object + status: + description: Status contains policy runtime data. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/install.yaml b/config/install.yaml index 489c1f373678..44b29211eba3 100644 --- a/config/install.yaml +++ b/config/install.yaml @@ -674,61 +674,27 @@ metadata: app.kubernetes.io/name: kyverno app.kubernetes.io/part-of: kyverno app.kubernetes.io/version: latest - name: clusteradmissionreports.kyverno.io + name: cleanuppolicies.kyverno.io spec: group: kyverno.io names: - categories: - - kyverno - - all - kind: ClusterAdmissionReport - listKind: ClusterAdmissionReportList - plural: clusteradmissionreports - shortNames: - - cadmr - singular: clusteradmissionreport - scope: Cluster + kind: CleanupPolicy + listKind: CleanupPolicyList + plural: cleanuppolicies + singular: cleanuppolicy + scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .metadata.ownerReferences[0].apiVersion - name: ApiVersion - priority: 1 - type: string - - jsonPath: .metadata.ownerReferences[0].kind - name: Kind - priority: 1 - type: string - - jsonPath: .metadata.ownerReferences[0].name - name: Subject - priority: 1 + - jsonPath: .spec.schedule + name: Schedule type: string - - jsonPath: .spec.summary.pass - name: Pass - type: integer - - jsonPath: .spec.summary.fail - name: Fail - type: integer - - jsonPath: .spec.summary.warn - name: Warn - type: integer - - jsonPath: .spec.summary.error - name: Error - type: integer - - jsonPath: .spec.summary.skip - name: Skip - type: integer - jsonPath: .metadata.creationTimestamp name: Age type: date - - jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash'] - name: Hash - priority: 1 - type: string - name: v1alpha2 + name: v1alpha1 schema: openAPIV3Schema: - description: ClusterAdmissionReport is the Schema for the ClusterAdmissionReports - API + description: CleanupPolicy defines a rule for resource cleanup. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation @@ -743,187 +709,1967 @@ spec: metadata: type: object spec: + description: Spec declares policy behaviors. properties: - owner: - description: Owner is a reference to the report owner (e.g. a Deployment, - Namespace, or Node) + conditions: + description: Conditions defines conditions used to select resources + which user needs to delete properties: - apiVersion: - description: API version of the referent. - type: string - blockOwnerDeletion: - description: If true, AND if the owner has the "foregroundDeletion" - finalizer, then the owner cannot be deleted from the key-value - store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion - for how the garbage collector interacts with this field and - enforces the foreground deletion. Defaults to false. To set - this field, a user needs "delete" permission of the owner, otherwise - 422 (Unprocessable Entity) will be returned. - type: boolean - controller: - description: If true, this reference points to the managing controller. - type: boolean - kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names' - type: string - uid: - description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids' - type: string - required: - - apiVersion - - kind - - name - - uid - type: object - x-kubernetes-map-type: atomic - results: - description: PolicyReportResult provides result details - items: - description: PolicyReportResult provides the result for an individual - policy - properties: - category: - description: Category indicates policy category - type: string - message: - description: Description is a short user friendly message for - the policy rule - type: string - policy: - description: Policy is the name or identifier of the policy - type: string - properties: - additionalProperties: - type: string - description: Properties provides additional information for - the policy rule + all: + description: AllConditions enable variable-based conditional rule + execution. This is useful for finer control of when an rule + is applied. A condition can reference object data using JMESPath + notation. Here, all of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria + for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for + conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. + Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, + NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, + LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, + DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. + The values can be fixed set or can be variables declared + using JMESPath. + x-kubernetes-preserve-unknown-fields: true type: object - resourceSelector: - description: SubjectSelector is an optional label selector for - checked Kubernetes resources. For example, a policy result - may apply to all pods that match a label. Either a Subject - or a SubjectSelector can be specified. If neither are provided, - the result is assumed to be for the policy report scope. + type: array + any: + description: AnyConditions enable variable-based conditional rule + execution. This is useful for finer control of when an rule + is applied. A condition can reference object data using JMESPath + notation. Here, at least one of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria + for rule execution. properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. + key: + description: Key is the context entry (using JMESPath) for + conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. + Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, + NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, + LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, + DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. + The values can be fixed set or can be variables declared + using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + type: object + exclude: + description: ExcludeResources defines when cleanuppolicy should not + be applied. The exclude criteria can include resource information + (e.g. kind, name, namespace, labels) and admission review request + information like the name or role. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists or - DoesNotExist, the values array must be empty. This - array is replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is - "key", the operator is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - resources: - description: Subjects is an optional reference to the checked - Kubernetes resources - items: - description: "ObjectReference contains enough information - to let you inspect or modify the referred object. --- New - uses of this type are discouraged because of difficulty - describing its usage when embedded in APIs. 1. Ignored fields. - \ It includes many fields which are not generally honored. - \ For instance, ResourceVersion and FieldPath are both very - rarely valid in actual usage. 2. Invalid usage help. It - is impossible to add specific help for individual usage. - \ In most embedded usages, there are particular restrictions - like, \"must refer only to types A and B\" or \"UID not - honored\" or \"name must be restricted\". Those cannot be - well described when embedded. 3. Inconsistent validation. - \ Because the usages are different, the validation rules - are different by usage, which makes it hard for users to - predict what will happen. 4. The fields are both imprecise - and overly precise. Kind is not a precise mapping to a - URL. This can produce ambiguity during interpretation and - require a REST mapping. In most cases, the dependency is - on the group,resource tuple and the version of the actual - struct is irrelevant. 5. We cannot easily change it. Because - this type is embedded in many locations, updates to this - type will affect numerous schemas. Don't make new APIs - embed an underspecified API type they do not control. \n - Instead of using this type, create a locally provided and - used type that is well-focused on your reference. For example, - ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 - ." - properties: - apiVersion: - description: API version of the referent. - type: string - fieldPath: - description: 'If referring to a piece of an object instead - of an entire object, this string should contain a valid - JSON/Go field access statement, such as desiredState.manifest.containers[2]. - For example, if the object reference is to a container - within a pod, this would take on a value like: "spec.containers{name}" - (where "name" refers to the name of the container that - triggered the event) or if no container name is specified - "spec.containers[2]" (container with index 2 in this - pod). This syntax is chosen only to have some well-defined - way of referencing a part of an object. TODO: this design - is not final and this field is subject to change in - the future.' - type: string - kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' - type: string - resourceVersion: - description: 'Specific resourceVersion to which this reference - is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' - type: string - uid: - description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' - type: string - type: object - x-kubernetes-map-type: atomic - type: array - result: - description: Result indicates the outcome of the policy rule - execution - enum: - - pass - - fail + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names + for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the + resource being created or modified. Requires at least one tag + to be specified when under MatchResources. Specifying ResourceDescription + directly under match is being deprecated. Please specify under + "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values support + the wildcard characters "*" (matches zero or many characters) + and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports + wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). NOTE: "Name" is being + deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name + supports wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the + resource namespace. Label keys and values in `matchLabels` + support the wildcard characters `*` (matches zero or many + characters) and `?` (matches one character).Wildcards allows + writing label selectors like ["storage.k8s.io/*": "*"]. + Note that using ["*" : "*"] matches any key and value but + does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each + name supports wildcard characters "*" (matches zero or many + characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and + values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches one + character). Wildcards allows writing label selectors like + ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches + any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the + user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, + user groups, and service accounts. + items: + description: Subject contains a reference to the object or user + identities a role binding applies to. This can either hold + a direct API object reference, or a value for non-objects + such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. Defaults + to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined + by this API group are "User", "Group", and "ServiceAccount". + If the Authorizer does not recognized the kind value, + the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the + object kind is non-namespace, such as "User" or "Group", + and this value is not empty the Authorizer should report + an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + match: + description: MatchResources defines when cleanuppolicy should be applied. + The match criteria can include resource information (e.g. kind, + name, namespace, labels) and admission review request information + like the user name or role. At least one kind is required. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names + for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the + resource being created or modified. Requires at least one tag + to be specified when under MatchResources. Specifying ResourceDescription + directly under match is being deprecated. Please specify under + "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values support + the wildcard characters "*" (matches zero or many characters) + and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports + wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). NOTE: "Name" is being + deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name + supports wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the + resource namespace. Label keys and values in `matchLabels` + support the wildcard characters `*` (matches zero or many + characters) and `?` (matches one character).Wildcards allows + writing label selectors like ["storage.k8s.io/*": "*"]. + Note that using ["*" : "*"] matches any key and value but + does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each + name supports wildcard characters "*" (matches zero or many + characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and + values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches one + character). Wildcards allows writing label selectors like + ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches + any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the + user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, + user groups, and service accounts. + items: + description: Subject contains a reference to the object or user + identities a role binding applies to. This can either hold + a direct API object reference, or a value for non-objects + such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. Defaults + to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined + by this API group are "User", "Group", and "ServiceAccount". + If the Authorizer does not recognized the kind value, + the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the + object kind is non-namespace, such as "User" or "Group", + and this value is not empty the Authorizer should report + an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + schedule: + description: The schedule in Cron format + type: string + required: + - schedule + type: object + status: + description: Status contains policy runtime data. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + labels: + app.kubernetes.io/component: kyverno + app.kubernetes.io/instance: kyverno + app.kubernetes.io/name: kyverno + app.kubernetes.io/part-of: kyverno + app.kubernetes.io/version: latest + name: clusteradmissionreports.kyverno.io +spec: + group: kyverno.io + names: + categories: + - kyverno + - all + kind: ClusterAdmissionReport + listKind: ClusterAdmissionReportList + plural: clusteradmissionreports + shortNames: + - cadmr + singular: clusteradmissionreport + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.ownerReferences[0].apiVersion + name: ApiVersion + priority: 1 + type: string + - jsonPath: .metadata.ownerReferences[0].kind + name: Kind + priority: 1 + type: string + - jsonPath: .metadata.ownerReferences[0].name + name: Subject + priority: 1 + type: string + - jsonPath: .spec.summary.pass + name: Pass + type: integer + - jsonPath: .spec.summary.fail + name: Fail + type: integer + - jsonPath: .spec.summary.warn + name: Warn + type: integer + - jsonPath: .spec.summary.error + name: Error + type: integer + - jsonPath: .spec.summary.skip + name: Skip + type: integer + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash'] + name: Hash + priority: 1 + type: string + name: v1alpha2 + schema: + openAPIV3Schema: + description: ClusterAdmissionReport is the Schema for the ClusterAdmissionReports + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + owner: + description: Owner is a reference to the report owner (e.g. a Deployment, + Namespace, or Node) + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: If true, AND if the owner has the "foregroundDeletion" + finalizer, then the owner cannot be deleted from the key-value + store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion + for how the garbage collector interacts with this field and + enforces the foreground deletion. Defaults to false. To set + this field, a user needs "delete" permission of the owner, otherwise + 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing controller. + type: boolean + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + uid: + description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + x-kubernetes-map-type: atomic + results: + description: PolicyReportResult provides result details + items: + description: PolicyReportResult provides the result for an individual + policy + properties: + category: + description: Category indicates policy category + type: string + message: + description: Description is a short user friendly message for + the policy rule + type: string + policy: + description: Policy is the name or identifier of the policy + type: string + properties: + additionalProperties: + type: string + description: Properties provides additional information for + the policy rule + type: object + resourceSelector: + description: SubjectSelector is an optional label selector for + checked Kubernetes resources. For example, a policy result + may apply to all pods that match a label. Either a Subject + or a SubjectSelector can be specified. If neither are provided, + the result is assumed to be for the policy report scope. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. This + array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Subjects is an optional reference to the checked + Kubernetes resources + items: + description: "ObjectReference contains enough information + to let you inspect or modify the referred object. --- New + uses of this type are discouraged because of difficulty + describing its usage when embedded in APIs. 1. Ignored fields. + \ It includes many fields which are not generally honored. + \ For instance, ResourceVersion and FieldPath are both very + rarely valid in actual usage. 2. Invalid usage help. It + is impossible to add specific help for individual usage. + \ In most embedded usages, there are particular restrictions + like, \"must refer only to types A and B\" or \"UID not + honored\" or \"name must be restricted\". Those cannot be + well described when embedded. 3. Inconsistent validation. + \ Because the usages are different, the validation rules + are different by usage, which makes it hard for users to + predict what will happen. 4. The fields are both imprecise + and overly precise. Kind is not a precise mapping to a + URL. This can produce ambiguity during interpretation and + require a REST mapping. In most cases, the dependency is + on the group,resource tuple and the version of the actual + struct is irrelevant. 5. We cannot easily change it. Because + this type is embedded in many locations, updates to this + type will affect numerous schemas. Don't make new APIs + embed an underspecified API type they do not control. \n + Instead of using this type, create a locally provided and + used type that is well-focused on your reference. For example, + ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 + ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this + pod). This syntax is chosen only to have some well-defined + way of referencing a part of an object. TODO: this design + is not final and this field is subject to change in + the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + result: + description: Result indicates the outcome of the policy rule + execution + enum: + - pass + - fail + - warn + - error + - skip + type: string + rule: + description: Rule is the name or identifier of the rule within + the policy + type: string + scored: + description: Scored indicates if this result is scored + type: boolean + severity: + description: Severity indicates policy check result criticality + enum: + - critical + - high + - low + - medium + - info + type: string + source: + description: Source is an identifier for the policy engine that + manages this report + type: string + timestamp: + description: Timestamp indicates the time the result was found + properties: + nanos: + description: Non-negative fractions of a second at nanosecond + resolution. Negative second values with fractions must + still have non-negative nanos values that count forward + in time. Must be from 0 to 999,999,999 inclusive. This + field may be limited in precision depending on context. + format: int32 + type: integer + seconds: + description: Represents seconds of UTC time since Unix epoch + 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z + to 9999-12-31T23:59:59Z inclusive. + format: int64 + type: integer + required: + - nanos + - seconds + type: object + required: + - policy + type: object + type: array + summary: + description: PolicyReportSummary provides a summary of results + properties: + error: + description: Error provides the count of policies that could not + be evaluated + type: integer + fail: + description: Fail provides the count of policies whose requirements + were not met + type: integer + pass: + description: Pass provides the count of policies whose requirements + were met + type: integer + skip: + description: Skip indicates the count of policies that were not + selected for evaluation + type: integer + warn: + description: Warn provides the count of non-scored policies whose + requirements were not met + type: integer + type: object + required: + - owner + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + labels: + app.kubernetes.io/component: kyverno + app.kubernetes.io/instance: kyverno + app.kubernetes.io/name: kyverno + app.kubernetes.io/part-of: kyverno + app.kubernetes.io/version: latest + name: clusterbackgroundscanreports.kyverno.io +spec: + group: kyverno.io + names: + categories: + - kyverno + - all + kind: ClusterBackgroundScanReport + listKind: ClusterBackgroundScanReportList + plural: clusterbackgroundscanreports + shortNames: + - cbgscanr + singular: clusterbackgroundscanreport + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.ownerReferences[0].apiVersion + name: ApiVersion + priority: 1 + type: string + - jsonPath: .metadata.ownerReferences[0].kind + name: Kind + priority: 1 + type: string + - jsonPath: .metadata.ownerReferences[0].name + name: Subject + priority: 1 + type: string + - jsonPath: .spec.summary.pass + name: Pass + type: integer + - jsonPath: .spec.summary.fail + name: Fail + type: integer + - jsonPath: .spec.summary.warn + name: Warn + type: integer + - jsonPath: .spec.summary.error + name: Error + type: integer + - jsonPath: .spec.summary.skip + name: Skip + type: integer + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash'] + name: Hash + priority: 1 + type: string + name: v1alpha2 + schema: + openAPIV3Schema: + description: ClusterBackgroundScanReport is the Schema for the ClusterBackgroundScanReports + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + results: + description: PolicyReportResult provides result details + items: + description: PolicyReportResult provides the result for an individual + policy + properties: + category: + description: Category indicates policy category + type: string + message: + description: Description is a short user friendly message for + the policy rule + type: string + policy: + description: Policy is the name or identifier of the policy + type: string + properties: + additionalProperties: + type: string + description: Properties provides additional information for + the policy rule + type: object + resourceSelector: + description: SubjectSelector is an optional label selector for + checked Kubernetes resources. For example, a policy result + may apply to all pods that match a label. Either a Subject + or a SubjectSelector can be specified. If neither are provided, + the result is assumed to be for the policy report scope. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. This + array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Subjects is an optional reference to the checked + Kubernetes resources + items: + description: "ObjectReference contains enough information + to let you inspect or modify the referred object. --- New + uses of this type are discouraged because of difficulty + describing its usage when embedded in APIs. 1. Ignored fields. + \ It includes many fields which are not generally honored. + \ For instance, ResourceVersion and FieldPath are both very + rarely valid in actual usage. 2. Invalid usage help. It + is impossible to add specific help for individual usage. + \ In most embedded usages, there are particular restrictions + like, \"must refer only to types A and B\" or \"UID not + honored\" or \"name must be restricted\". Those cannot be + well described when embedded. 3. Inconsistent validation. + \ Because the usages are different, the validation rules + are different by usage, which makes it hard for users to + predict what will happen. 4. The fields are both imprecise + and overly precise. Kind is not a precise mapping to a + URL. This can produce ambiguity during interpretation and + require a REST mapping. In most cases, the dependency is + on the group,resource tuple and the version of the actual + struct is irrelevant. 5. We cannot easily change it. Because + this type is embedded in many locations, updates to this + type will affect numerous schemas. Don't make new APIs + embed an underspecified API type they do not control. \n + Instead of using this type, create a locally provided and + used type that is well-focused on your reference. For example, + ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 + ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this + pod). This syntax is chosen only to have some well-defined + way of referencing a part of an object. TODO: this design + is not final and this field is subject to change in + the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + result: + description: Result indicates the outcome of the policy rule + execution + enum: + - pass + - fail - warn - error - skip @@ -951,369 +2697,1495 @@ spec: timestamp: description: Timestamp indicates the time the result was found properties: - nanos: - description: Non-negative fractions of a second at nanosecond - resolution. Negative second values with fractions must - still have non-negative nanos values that count forward - in time. Must be from 0 to 999,999,999 inclusive. This - field may be limited in precision depending on context. - format: int32 - type: integer - seconds: - description: Represents seconds of UTC time since Unix epoch - 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z - to 9999-12-31T23:59:59Z inclusive. - format: int64 - type: integer - required: - - nanos - - seconds + nanos: + description: Non-negative fractions of a second at nanosecond + resolution. Negative second values with fractions must + still have non-negative nanos values that count forward + in time. Must be from 0 to 999,999,999 inclusive. This + field may be limited in precision depending on context. + format: int32 + type: integer + seconds: + description: Represents seconds of UTC time since Unix epoch + 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z + to 9999-12-31T23:59:59Z inclusive. + format: int64 + type: integer + required: + - nanos + - seconds + type: object + required: + - policy + type: object + type: array + summary: + description: PolicyReportSummary provides a summary of results + properties: + error: + description: Error provides the count of policies that could not + be evaluated + type: integer + fail: + description: Fail provides the count of policies whose requirements + were not met + type: integer + pass: + description: Pass provides the count of policies whose requirements + were met + type: integer + skip: + description: Skip indicates the count of policies that were not + selected for evaluation + type: integer + warn: + description: Warn provides the count of non-scored policies whose + requirements were not met + type: integer + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + labels: + app.kubernetes.io/component: kyverno + app.kubernetes.io/instance: kyverno + app.kubernetes.io/name: kyverno + app.kubernetes.io/part-of: kyverno + app.kubernetes.io/version: latest + name: clustercleanuppolicies.kyverno.io +spec: + group: kyverno.io + names: + kind: ClusterCleanupPolicy + listKind: ClusterCleanupPolicyList + plural: clustercleanuppolicies + singular: clustercleanuppolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.schedule + name: Schedule + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ClusterCleanupPolicy defines rule for resource cleanup. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec declares policy behaviors. + properties: + conditions: + description: Conditions defines conditions used to select resources + which user needs to delete + properties: + all: + description: AllConditions enable variable-based conditional rule + execution. This is useful for finer control of when an rule + is applied. A condition can reference object data using JMESPath + notation. Here, all of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria + for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for + conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. + Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, + NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, + LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, + DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. + The values can be fixed set or can be variables declared + using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + any: + description: AnyConditions enable variable-based conditional rule + execution. This is useful for finer control of when an rule + is applied. A condition can reference object data using JMESPath + notation. Here, at least one of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria + for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for + conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. + Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, + NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, + LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, + DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. + The values can be fixed set or can be variables declared + using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + type: object + exclude: + description: ExcludeResources defines when cleanuppolicy should not + be applied. The exclude criteria can include resource information + (e.g. kind, name, namespace, labels) and admission review request + information like the name or role. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array type: object - required: - - policy - type: object - type: array - summary: - description: PolicyReportSummary provides a summary of results - properties: - error: - description: Error provides the count of policies that could not - be evaluated - type: integer - fail: - description: Fail provides the count of policies whose requirements - were not met - type: integer - pass: - description: Pass provides the count of policies whose requirements - were met - type: integer - skip: - description: Skip indicates the count of policies that were not - selected for evaluation - type: integer - warn: - description: Warn provides the count of non-scored policies whose - requirements were not met - type: integer - type: object - required: - - owner - type: object - required: - - spec - type: object - served: true - storage: true - subresources: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null - labels: - app.kubernetes.io/component: kyverno - app.kubernetes.io/instance: kyverno - app.kubernetes.io/name: kyverno - app.kubernetes.io/part-of: kyverno - app.kubernetes.io/version: latest - name: clusterbackgroundscanreports.kyverno.io -spec: - group: kyverno.io - names: - categories: - - kyverno - - all - kind: ClusterBackgroundScanReport - listKind: ClusterBackgroundScanReportList - plural: clusterbackgroundscanreports - shortNames: - - cbgscanr - singular: clusterbackgroundscanreport - scope: Cluster - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.ownerReferences[0].apiVersion - name: ApiVersion - priority: 1 - type: string - - jsonPath: .metadata.ownerReferences[0].kind - name: Kind - priority: 1 - type: string - - jsonPath: .metadata.ownerReferences[0].name - name: Subject - priority: 1 - type: string - - jsonPath: .spec.summary.pass - name: Pass - type: integer - - jsonPath: .spec.summary.fail - name: Fail - type: integer - - jsonPath: .spec.summary.warn - name: Warn - type: integer - - jsonPath: .spec.summary.error - name: Error - type: integer - - jsonPath: .spec.summary.skip - name: Skip - type: integer - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash'] - name: Hash - priority: 1 - type: string - name: v1alpha2 - schema: - openAPIV3Schema: - description: ClusterBackgroundScanReport is the Schema for the ClusterBackgroundScanReports - API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - properties: - results: - description: PolicyReportResult provides result details - items: - description: PolicyReportResult provides the result for an individual - policy - properties: - category: - description: Category indicates policy category - type: string - message: - description: Description is a short user friendly message for - the policy rule - type: string - policy: - description: Policy is the name or identifier of the policy + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names + for the user. + items: type: string + type: array + resources: + description: ResourceDescription contains information about the + resource being created or modified. Requires at least one tag + to be specified when under MatchResources. Specifying ResourceDescription + directly under match is being deprecated. Please specify under + "any" or "all" instead. properties: - additionalProperties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values support + the wildcard characters "*" (matches zero or many characters) + and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports + wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). NOTE: "Name" is being + deprecated in favor of "Names".' type: string - description: Properties provides additional information for - the policy rule + names: + description: Names are the names of the resources. Each name + supports wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the + resource namespace. Label keys and values in `matchLabels` + support the wildcard characters `*` (matches zero or many + characters) and `?` (matches one character).Wildcards allows + writing label selectors like ["storage.k8s.io/*": "*"]. + Note that using ["*" : "*"] matches any key and value but + does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each + name supports wildcard characters "*" (matches zero or many + characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and + values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches one + character). Wildcards allows writing label selectors like + ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches + any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the + user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, + user groups, and service accounts. + items: + description: Subject contains a reference to the object or user + identities a role binding applies to. This can either hold + a direct API object reference, or a value for non-objects + such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. Defaults + to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined + by this API group are "User", "Group", and "ServiceAccount". + If the Authorizer does not recognized the kind value, + the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the + object kind is non-namespace, such as "User" or "Group", + and this value is not empty the Authorizer should report + an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + match: + description: MatchResources defines when cleanuppolicy should be applied. + The match criteria can include resource information (e.g. kind, + name, namespace, labels) and admission review request information + like the user name or role. At least one kind is required. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array type: object - resourceSelector: - description: SubjectSelector is an optional label selector for - checked Kubernetes resources. For example, a policy result - may apply to all pods that match a label. Either a Subject - or a SubjectSelector can be specified. If neither are provided, - the result is assumed to be for the policy report scope. + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. properties: - key: - description: key is the label key that the selector - applies to. + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists or - DoesNotExist, the values array must be empty. This - array is replaced during a strategic merge patch. - items: - type: string - type: array required: - - key - - operator + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names + for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the + resource being created or modified. Requires at least one tag + to be specified when under MatchResources. Specifying ResourceDescription + directly under match is being deprecated. Please specify under + "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values support + the wildcard characters "*" (matches zero or many characters) + and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports + wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). NOTE: "Name" is being + deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name + supports wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the + resource namespace. Label keys and values in `matchLabels` + support the wildcard characters `*` (matches zero or many + characters) and `?` (matches one character).Wildcards allows + writing label selectors like ["storage.k8s.io/*": "*"]. + Note that using ["*" : "*"] matches any key and value but + does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is - "key", the operator is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - resources: - description: Subjects is an optional reference to the checked - Kubernetes resources - items: - description: "ObjectReference contains enough information - to let you inspect or modify the referred object. --- New - uses of this type are discouraged because of difficulty - describing its usage when embedded in APIs. 1. Ignored fields. - \ It includes many fields which are not generally honored. - \ For instance, ResourceVersion and FieldPath are both very - rarely valid in actual usage. 2. Invalid usage help. It - is impossible to add specific help for individual usage. - \ In most embedded usages, there are particular restrictions - like, \"must refer only to types A and B\" or \"UID not - honored\" or \"name must be restricted\". Those cannot be - well described when embedded. 3. Inconsistent validation. - \ Because the usages are different, the validation rules - are different by usage, which makes it hard for users to - predict what will happen. 4. The fields are both imprecise - and overly precise. Kind is not a precise mapping to a - URL. This can produce ambiguity during interpretation and - require a REST mapping. In most cases, the dependency is - on the group,resource tuple and the version of the actual - struct is irrelevant. 5. We cannot easily change it. Because - this type is embedded in many locations, updates to this - type will affect numerous schemas. Don't make new APIs - embed an underspecified API type they do not control. \n - Instead of using this type, create a locally provided and - used type that is well-focused on your reference. For example, - ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 - ." + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each + name supports wildcard characters "*" (matches zero or many + characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and + values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches one + character). Wildcards allows writing label selectors like + ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches + any key and value but does not match an empty label set.' properties: - apiVersion: - description: API version of the referent. - type: string - fieldPath: - description: 'If referring to a piece of an object instead - of an entire object, this string should contain a valid - JSON/Go field access statement, such as desiredState.manifest.containers[2]. - For example, if the object reference is to a container - within a pod, this would take on a value like: "spec.containers{name}" - (where "name" refers to the name of the container that - triggered the event) or if no container name is specified - "spec.containers[2]" (container with index 2 in this - pod). This syntax is chosen only to have some well-defined - way of referencing a part of an object. TODO: this design - is not final and this field is subject to change in - the future.' - type: string - kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' - type: string - resourceVersion: - description: 'Specific resourceVersion to which this reference - is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' - type: string - uid: - description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' - type: string + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object type: object x-kubernetes-map-type: atomic - type: array - result: - description: Result indicates the outcome of the policy rule - execution - enum: - - pass - - fail - - warn - - error - - skip + type: object + roles: + description: Roles is the list of namespaced role names for the + user. + items: type: string - rule: - description: Rule is the name or identifier of the rule within - the policy + type: array + subjects: + description: Subjects is the list of subject names like users, + user groups, and service accounts. + items: + description: Subject contains a reference to the object or user + identities a role binding applies to. This can either hold + a direct API object reference, or a value for non-objects + such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. Defaults + to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined + by this API group are "User", "Group", and "ServiceAccount". + If the Authorizer does not recognized the kind value, + the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the + object kind is non-namespace, such as "User" or "Group", + and this value is not empty the Authorizer should report + an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + schedule: + description: The schedule in Cron format + type: string + required: + - schedule + type: object + status: + description: Status contains policy runtime data. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time type: string - scored: - description: Scored indicates if this result is scored - type: boolean - severity: - description: Severity indicates policy check result criticality + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. enum: - - critical - - high - - low - - medium - - info + - "True" + - "False" + - Unknown type: string - source: - description: Source is an identifier for the policy engine that - manages this report + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string - timestamp: - description: Timestamp indicates the time the result was found - properties: - nanos: - description: Non-negative fractions of a second at nanosecond - resolution. Negative second values with fractions must - still have non-negative nanos values that count forward - in time. Must be from 0 to 999,999,999 inclusive. This - field may be limited in precision depending on context. - format: int32 - type: integer - seconds: - description: Represents seconds of UTC time since Unix epoch - 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z - to 9999-12-31T23:59:59Z inclusive. - format: int64 - type: integer - required: - - nanos - - seconds - type: object required: - - policy + - lastTransitionTime + - message + - reason + - status + - type type: object type: array - summary: - description: PolicyReportSummary provides a summary of results - properties: - error: - description: Error provides the count of policies that could not - be evaluated - type: integer - fail: - description: Fail provides the count of policies whose requirements - were not met - type: integer - pass: - description: Pass provides the count of policies whose requirements - were met - type: integer - skip: - description: Skip indicates the count of policies that were not - selected for evaluation - type: integer - warn: - description: Warn provides the count of non-scored policies whose - requirements were not met - type: integer - type: object type: object required: - spec type: object served: true storage: true - subresources: {} + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition diff --git a/config/install_debug.yaml b/config/install_debug.yaml index ed75cb86d5d5..bb0923c59906 100644 --- a/config/install_debug.yaml +++ b/config/install_debug.yaml @@ -670,61 +670,27 @@ metadata: app.kubernetes.io/instance: kyverno app.kubernetes.io/name: kyverno app.kubernetes.io/part-of: kyverno - name: clusteradmissionreports.kyverno.io + name: cleanuppolicies.kyverno.io spec: group: kyverno.io names: - categories: - - kyverno - - all - kind: ClusterAdmissionReport - listKind: ClusterAdmissionReportList - plural: clusteradmissionreports - shortNames: - - cadmr - singular: clusteradmissionreport - scope: Cluster + kind: CleanupPolicy + listKind: CleanupPolicyList + plural: cleanuppolicies + singular: cleanuppolicy + scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .metadata.ownerReferences[0].apiVersion - name: ApiVersion - priority: 1 - type: string - - jsonPath: .metadata.ownerReferences[0].kind - name: Kind - priority: 1 - type: string - - jsonPath: .metadata.ownerReferences[0].name - name: Subject - priority: 1 + - jsonPath: .spec.schedule + name: Schedule type: string - - jsonPath: .spec.summary.pass - name: Pass - type: integer - - jsonPath: .spec.summary.fail - name: Fail - type: integer - - jsonPath: .spec.summary.warn - name: Warn - type: integer - - jsonPath: .spec.summary.error - name: Error - type: integer - - jsonPath: .spec.summary.skip - name: Skip - type: integer - jsonPath: .metadata.creationTimestamp name: Age type: date - - jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash'] - name: Hash - priority: 1 - type: string - name: v1alpha2 + name: v1alpha1 schema: openAPIV3Schema: - description: ClusterAdmissionReport is the Schema for the ClusterAdmissionReports - API + description: CleanupPolicy defines a rule for resource cleanup. properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation @@ -739,187 +705,1965 @@ spec: metadata: type: object spec: + description: Spec declares policy behaviors. properties: - owner: - description: Owner is a reference to the report owner (e.g. a Deployment, - Namespace, or Node) + conditions: + description: Conditions defines conditions used to select resources + which user needs to delete properties: - apiVersion: - description: API version of the referent. - type: string - blockOwnerDeletion: - description: If true, AND if the owner has the "foregroundDeletion" - finalizer, then the owner cannot be deleted from the key-value - store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion - for how the garbage collector interacts with this field and - enforces the foreground deletion. Defaults to false. To set - this field, a user needs "delete" permission of the owner, otherwise - 422 (Unprocessable Entity) will be returned. - type: boolean - controller: - description: If true, this reference points to the managing controller. - type: boolean - kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names' - type: string - uid: - description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids' - type: string - required: - - apiVersion - - kind - - name - - uid - type: object - x-kubernetes-map-type: atomic - results: - description: PolicyReportResult provides result details - items: - description: PolicyReportResult provides the result for an individual - policy - properties: - category: - description: Category indicates policy category - type: string - message: - description: Description is a short user friendly message for - the policy rule - type: string - policy: - description: Policy is the name or identifier of the policy - type: string - properties: - additionalProperties: - type: string - description: Properties provides additional information for - the policy rule + all: + description: AllConditions enable variable-based conditional rule + execution. This is useful for finer control of when an rule + is applied. A condition can reference object data using JMESPath + notation. Here, all of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria + for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for + conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. + Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, + NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, + LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, + DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. + The values can be fixed set or can be variables declared + using JMESPath. + x-kubernetes-preserve-unknown-fields: true type: object - resourceSelector: - description: SubjectSelector is an optional label selector for - checked Kubernetes resources. For example, a policy result - may apply to all pods that match a label. Either a Subject - or a SubjectSelector can be specified. If neither are provided, - the result is assumed to be for the policy report scope. + type: array + any: + description: AnyConditions enable variable-based conditional rule + execution. This is useful for finer control of when an rule + is applied. A condition can reference object data using JMESPath + notation. Here, at least one of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria + for rule execution. properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. + key: + description: Key is the context entry (using JMESPath) for + conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. + Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, + NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, + LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, + DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. + The values can be fixed set or can be variables declared + using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + type: object + exclude: + description: ExcludeResources defines when cleanuppolicy should not + be applied. The exclude criteria can include resource information + (e.g. kind, name, namespace, labels) and admission review request + information like the name or role. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists or - DoesNotExist, the values array must be empty. This - array is replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is - "key", the operator is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - resources: - description: Subjects is an optional reference to the checked - Kubernetes resources - items: - description: "ObjectReference contains enough information - to let you inspect or modify the referred object. --- New - uses of this type are discouraged because of difficulty - describing its usage when embedded in APIs. 1. Ignored fields. - \ It includes many fields which are not generally honored. - \ For instance, ResourceVersion and FieldPath are both very - rarely valid in actual usage. 2. Invalid usage help. It - is impossible to add specific help for individual usage. - \ In most embedded usages, there are particular restrictions - like, \"must refer only to types A and B\" or \"UID not - honored\" or \"name must be restricted\". Those cannot be - well described when embedded. 3. Inconsistent validation. - \ Because the usages are different, the validation rules - are different by usage, which makes it hard for users to - predict what will happen. 4. The fields are both imprecise - and overly precise. Kind is not a precise mapping to a - URL. This can produce ambiguity during interpretation and - require a REST mapping. In most cases, the dependency is - on the group,resource tuple and the version of the actual - struct is irrelevant. 5. We cannot easily change it. Because - this type is embedded in many locations, updates to this - type will affect numerous schemas. Don't make new APIs - embed an underspecified API type they do not control. \n - Instead of using this type, create a locally provided and - used type that is well-focused on your reference. For example, - ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 - ." - properties: - apiVersion: - description: API version of the referent. - type: string - fieldPath: - description: 'If referring to a piece of an object instead - of an entire object, this string should contain a valid - JSON/Go field access statement, such as desiredState.manifest.containers[2]. - For example, if the object reference is to a container - within a pod, this would take on a value like: "spec.containers{name}" - (where "name" refers to the name of the container that - triggered the event) or if no container name is specified - "spec.containers[2]" (container with index 2 in this - pod). This syntax is chosen only to have some well-defined - way of referencing a part of an object. TODO: this design - is not final and this field is subject to change in - the future.' - type: string - kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' - type: string - resourceVersion: - description: 'Specific resourceVersion to which this reference - is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' - type: string - uid: - description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' - type: string - type: object - x-kubernetes-map-type: atomic - type: array - result: - description: Result indicates the outcome of the policy rule - execution - enum: - - pass - - fail + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names + for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the + resource being created or modified. Requires at least one tag + to be specified when under MatchResources. Specifying ResourceDescription + directly under match is being deprecated. Please specify under + "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values support + the wildcard characters "*" (matches zero or many characters) + and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports + wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). NOTE: "Name" is being + deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name + supports wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the + resource namespace. Label keys and values in `matchLabels` + support the wildcard characters `*` (matches zero or many + characters) and `?` (matches one character).Wildcards allows + writing label selectors like ["storage.k8s.io/*": "*"]. + Note that using ["*" : "*"] matches any key and value but + does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each + name supports wildcard characters "*" (matches zero or many + characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and + values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches one + character). Wildcards allows writing label selectors like + ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches + any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the + user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, + user groups, and service accounts. + items: + description: Subject contains a reference to the object or user + identities a role binding applies to. This can either hold + a direct API object reference, or a value for non-objects + such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. Defaults + to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined + by this API group are "User", "Group", and "ServiceAccount". + If the Authorizer does not recognized the kind value, + the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the + object kind is non-namespace, such as "User" or "Group", + and this value is not empty the Authorizer should report + an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + match: + description: MatchResources defines when cleanuppolicy should be applied. + The match criteria can include resource information (e.g. kind, + name, namespace, labels) and admission review request information + like the user name or role. At least one kind is required. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names + for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the + resource being created or modified. Requires at least one tag + to be specified when under MatchResources. Specifying ResourceDescription + directly under match is being deprecated. Please specify under + "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values support + the wildcard characters "*" (matches zero or many characters) + and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports + wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). NOTE: "Name" is being + deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name + supports wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the + resource namespace. Label keys and values in `matchLabels` + support the wildcard characters `*` (matches zero or many + characters) and `?` (matches one character).Wildcards allows + writing label selectors like ["storage.k8s.io/*": "*"]. + Note that using ["*" : "*"] matches any key and value but + does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each + name supports wildcard characters "*" (matches zero or many + characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and + values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches one + character). Wildcards allows writing label selectors like + ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches + any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the + user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, + user groups, and service accounts. + items: + description: Subject contains a reference to the object or user + identities a role binding applies to. This can either hold + a direct API object reference, or a value for non-objects + such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. Defaults + to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined + by this API group are "User", "Group", and "ServiceAccount". + If the Authorizer does not recognized the kind value, + the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the + object kind is non-namespace, such as "User" or "Group", + and this value is not empty the Authorizer should report + an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + schedule: + description: The schedule in Cron format + type: string + required: + - schedule + type: object + status: + description: Status contains policy runtime data. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + labels: + app.kubernetes.io/component: kyverno + app.kubernetes.io/instance: kyverno + app.kubernetes.io/name: kyverno + app.kubernetes.io/part-of: kyverno + name: clusteradmissionreports.kyverno.io +spec: + group: kyverno.io + names: + categories: + - kyverno + - all + kind: ClusterAdmissionReport + listKind: ClusterAdmissionReportList + plural: clusteradmissionreports + shortNames: + - cadmr + singular: clusteradmissionreport + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.ownerReferences[0].apiVersion + name: ApiVersion + priority: 1 + type: string + - jsonPath: .metadata.ownerReferences[0].kind + name: Kind + priority: 1 + type: string + - jsonPath: .metadata.ownerReferences[0].name + name: Subject + priority: 1 + type: string + - jsonPath: .spec.summary.pass + name: Pass + type: integer + - jsonPath: .spec.summary.fail + name: Fail + type: integer + - jsonPath: .spec.summary.warn + name: Warn + type: integer + - jsonPath: .spec.summary.error + name: Error + type: integer + - jsonPath: .spec.summary.skip + name: Skip + type: integer + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash'] + name: Hash + priority: 1 + type: string + name: v1alpha2 + schema: + openAPIV3Schema: + description: ClusterAdmissionReport is the Schema for the ClusterAdmissionReports + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + owner: + description: Owner is a reference to the report owner (e.g. a Deployment, + Namespace, or Node) + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: If true, AND if the owner has the "foregroundDeletion" + finalizer, then the owner cannot be deleted from the key-value + store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion + for how the garbage collector interacts with this field and + enforces the foreground deletion. Defaults to false. To set + this field, a user needs "delete" permission of the owner, otherwise + 422 (Unprocessable Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing controller. + type: boolean + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + uid: + description: 'UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids' + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + x-kubernetes-map-type: atomic + results: + description: PolicyReportResult provides result details + items: + description: PolicyReportResult provides the result for an individual + policy + properties: + category: + description: Category indicates policy category + type: string + message: + description: Description is a short user friendly message for + the policy rule + type: string + policy: + description: Policy is the name or identifier of the policy + type: string + properties: + additionalProperties: + type: string + description: Properties provides additional information for + the policy rule + type: object + resourceSelector: + description: SubjectSelector is an optional label selector for + checked Kubernetes resources. For example, a policy result + may apply to all pods that match a label. Either a Subject + or a SubjectSelector can be specified. If neither are provided, + the result is assumed to be for the policy report scope. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. This + array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Subjects is an optional reference to the checked + Kubernetes resources + items: + description: "ObjectReference contains enough information + to let you inspect or modify the referred object. --- New + uses of this type are discouraged because of difficulty + describing its usage when embedded in APIs. 1. Ignored fields. + \ It includes many fields which are not generally honored. + \ For instance, ResourceVersion and FieldPath are both very + rarely valid in actual usage. 2. Invalid usage help. It + is impossible to add specific help for individual usage. + \ In most embedded usages, there are particular restrictions + like, \"must refer only to types A and B\" or \"UID not + honored\" or \"name must be restricted\". Those cannot be + well described when embedded. 3. Inconsistent validation. + \ Because the usages are different, the validation rules + are different by usage, which makes it hard for users to + predict what will happen. 4. The fields are both imprecise + and overly precise. Kind is not a precise mapping to a + URL. This can produce ambiguity during interpretation and + require a REST mapping. In most cases, the dependency is + on the group,resource tuple and the version of the actual + struct is irrelevant. 5. We cannot easily change it. Because + this type is embedded in many locations, updates to this + type will affect numerous schemas. Don't make new APIs + embed an underspecified API type they do not control. \n + Instead of using this type, create a locally provided and + used type that is well-focused on your reference. For example, + ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 + ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this + pod). This syntax is chosen only to have some well-defined + way of referencing a part of an object. TODO: this design + is not final and this field is subject to change in + the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + result: + description: Result indicates the outcome of the policy rule + execution + enum: + - pass + - fail + - warn + - error + - skip + type: string + rule: + description: Rule is the name or identifier of the rule within + the policy + type: string + scored: + description: Scored indicates if this result is scored + type: boolean + severity: + description: Severity indicates policy check result criticality + enum: + - critical + - high + - low + - medium + - info + type: string + source: + description: Source is an identifier for the policy engine that + manages this report + type: string + timestamp: + description: Timestamp indicates the time the result was found + properties: + nanos: + description: Non-negative fractions of a second at nanosecond + resolution. Negative second values with fractions must + still have non-negative nanos values that count forward + in time. Must be from 0 to 999,999,999 inclusive. This + field may be limited in precision depending on context. + format: int32 + type: integer + seconds: + description: Represents seconds of UTC time since Unix epoch + 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z + to 9999-12-31T23:59:59Z inclusive. + format: int64 + type: integer + required: + - nanos + - seconds + type: object + required: + - policy + type: object + type: array + summary: + description: PolicyReportSummary provides a summary of results + properties: + error: + description: Error provides the count of policies that could not + be evaluated + type: integer + fail: + description: Fail provides the count of policies whose requirements + were not met + type: integer + pass: + description: Pass provides the count of policies whose requirements + were met + type: integer + skip: + description: Skip indicates the count of policies that were not + selected for evaluation + type: integer + warn: + description: Warn provides the count of non-scored policies whose + requirements were not met + type: integer + type: object + required: + - owner + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + labels: + app.kubernetes.io/component: kyverno + app.kubernetes.io/instance: kyverno + app.kubernetes.io/name: kyverno + app.kubernetes.io/part-of: kyverno + name: clusterbackgroundscanreports.kyverno.io +spec: + group: kyverno.io + names: + categories: + - kyverno + - all + kind: ClusterBackgroundScanReport + listKind: ClusterBackgroundScanReportList + plural: clusterbackgroundscanreports + shortNames: + - cbgscanr + singular: clusterbackgroundscanreport + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.ownerReferences[0].apiVersion + name: ApiVersion + priority: 1 + type: string + - jsonPath: .metadata.ownerReferences[0].kind + name: Kind + priority: 1 + type: string + - jsonPath: .metadata.ownerReferences[0].name + name: Subject + priority: 1 + type: string + - jsonPath: .spec.summary.pass + name: Pass + type: integer + - jsonPath: .spec.summary.fail + name: Fail + type: integer + - jsonPath: .spec.summary.warn + name: Warn + type: integer + - jsonPath: .spec.summary.error + name: Error + type: integer + - jsonPath: .spec.summary.skip + name: Skip + type: integer + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash'] + name: Hash + priority: 1 + type: string + name: v1alpha2 + schema: + openAPIV3Schema: + description: ClusterBackgroundScanReport is the Schema for the ClusterBackgroundScanReports + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + properties: + results: + description: PolicyReportResult provides result details + items: + description: PolicyReportResult provides the result for an individual + policy + properties: + category: + description: Category indicates policy category + type: string + message: + description: Description is a short user friendly message for + the policy rule + type: string + policy: + description: Policy is the name or identifier of the policy + type: string + properties: + additionalProperties: + type: string + description: Properties provides additional information for + the policy rule + type: object + resourceSelector: + description: SubjectSelector is an optional label selector for + checked Kubernetes resources. For example, a policy result + may apply to all pods that match a label. Either a Subject + or a SubjectSelector can be specified. If neither are provided, + the result is assumed to be for the policy report scope. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. This + array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Subjects is an optional reference to the checked + Kubernetes resources + items: + description: "ObjectReference contains enough information + to let you inspect or modify the referred object. --- New + uses of this type are discouraged because of difficulty + describing its usage when embedded in APIs. 1. Ignored fields. + \ It includes many fields which are not generally honored. + \ For instance, ResourceVersion and FieldPath are both very + rarely valid in actual usage. 2. Invalid usage help. It + is impossible to add specific help for individual usage. + \ In most embedded usages, there are particular restrictions + like, \"must refer only to types A and B\" or \"UID not + honored\" or \"name must be restricted\". Those cannot be + well described when embedded. 3. Inconsistent validation. + \ Because the usages are different, the validation rules + are different by usage, which makes it hard for users to + predict what will happen. 4. The fields are both imprecise + and overly precise. Kind is not a precise mapping to a + URL. This can produce ambiguity during interpretation and + require a REST mapping. In most cases, the dependency is + on the group,resource tuple and the version of the actual + struct is irrelevant. 5. We cannot easily change it. Because + this type is embedded in many locations, updates to this + type will affect numerous schemas. Don't make new APIs + embed an underspecified API type they do not control. \n + Instead of using this type, create a locally provided and + used type that is well-focused on your reference. For example, + ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 + ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this + pod). This syntax is chosen only to have some well-defined + way of referencing a part of an object. TODO: this design + is not final and this field is subject to change in + the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + result: + description: Result indicates the outcome of the policy rule + execution + enum: + - pass + - fail - warn - error - skip @@ -947,368 +2691,1494 @@ spec: timestamp: description: Timestamp indicates the time the result was found properties: - nanos: - description: Non-negative fractions of a second at nanosecond - resolution. Negative second values with fractions must - still have non-negative nanos values that count forward - in time. Must be from 0 to 999,999,999 inclusive. This - field may be limited in precision depending on context. - format: int32 - type: integer - seconds: - description: Represents seconds of UTC time since Unix epoch - 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z - to 9999-12-31T23:59:59Z inclusive. - format: int64 - type: integer - required: - - nanos - - seconds + nanos: + description: Non-negative fractions of a second at nanosecond + resolution. Negative second values with fractions must + still have non-negative nanos values that count forward + in time. Must be from 0 to 999,999,999 inclusive. This + field may be limited in precision depending on context. + format: int32 + type: integer + seconds: + description: Represents seconds of UTC time since Unix epoch + 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z + to 9999-12-31T23:59:59Z inclusive. + format: int64 + type: integer + required: + - nanos + - seconds + type: object + required: + - policy + type: object + type: array + summary: + description: PolicyReportSummary provides a summary of results + properties: + error: + description: Error provides the count of policies that could not + be evaluated + type: integer + fail: + description: Fail provides the count of policies whose requirements + were not met + type: integer + pass: + description: Pass provides the count of policies whose requirements + were met + type: integer + skip: + description: Skip indicates the count of policies that were not + selected for evaluation + type: integer + warn: + description: Warn provides the count of non-scored policies whose + requirements were not met + type: integer + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + labels: + app.kubernetes.io/component: kyverno + app.kubernetes.io/instance: kyverno + app.kubernetes.io/name: kyverno + app.kubernetes.io/part-of: kyverno + name: clustercleanuppolicies.kyverno.io +spec: + group: kyverno.io + names: + kind: ClusterCleanupPolicy + listKind: ClusterCleanupPolicyList + plural: clustercleanuppolicies + singular: clustercleanuppolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.schedule + name: Schedule + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ClusterCleanupPolicy defines rule for resource cleanup. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec declares policy behaviors. + properties: + conditions: + description: Conditions defines conditions used to select resources + which user needs to delete + properties: + all: + description: AllConditions enable variable-based conditional rule + execution. This is useful for finer control of when an rule + is applied. A condition can reference object data using JMESPath + notation. Here, all of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria + for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for + conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. + Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, + NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, + LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, + DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. + The values can be fixed set or can be variables declared + using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + any: + description: AnyConditions enable variable-based conditional rule + execution. This is useful for finer control of when an rule + is applied. A condition can reference object data using JMESPath + notation. Here, at least one of the conditions need to pass + items: + description: Condition defines variable-based conditional criteria + for rule execution. + properties: + key: + description: Key is the context entry (using JMESPath) for + conditional rule evaluation. + x-kubernetes-preserve-unknown-fields: true + operator: + description: 'Operator is the conditional operation to perform. + Valid operators are: Equals, NotEquals, In, AnyIn, AllIn, + NotIn, AnyNotIn, AllNotIn, GreaterThanOrEquals, GreaterThan, + LessThanOrEquals, LessThan, DurationGreaterThanOrEquals, + DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan' + enum: + - Equals + - NotEquals + - In + - AnyIn + - AllIn + - NotIn + - AnyNotIn + - AllNotIn + - GreaterThanOrEquals + - GreaterThan + - LessThanOrEquals + - LessThan + - DurationGreaterThanOrEquals + - DurationGreaterThan + - DurationLessThanOrEquals + - DurationLessThan + type: string + value: + description: Value is the conditional value, or set of values. + The values can be fixed set or can be variables declared + using JMESPath. + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + type: object + exclude: + description: ExcludeResources defines when cleanuppolicy should not + be applied. The exclude criteria can include resource information + (e.g. kind, name, namespace, labels) and admission review request + information like the name or role. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array type: object - required: - - policy - type: object - type: array - summary: - description: PolicyReportSummary provides a summary of results - properties: - error: - description: Error provides the count of policies that could not - be evaluated - type: integer - fail: - description: Fail provides the count of policies whose requirements - were not met - type: integer - pass: - description: Pass provides the count of policies whose requirements - were met - type: integer - skip: - description: Skip indicates the count of policies that were not - selected for evaluation - type: integer - warn: - description: Warn provides the count of non-scored policies whose - requirements were not met - type: integer - type: object - required: - - owner - type: object - required: - - spec - type: object - served: true - storage: true - subresources: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null - labels: - app.kubernetes.io/component: kyverno - app.kubernetes.io/instance: kyverno - app.kubernetes.io/name: kyverno - app.kubernetes.io/part-of: kyverno - name: clusterbackgroundscanreports.kyverno.io -spec: - group: kyverno.io - names: - categories: - - kyverno - - all - kind: ClusterBackgroundScanReport - listKind: ClusterBackgroundScanReportList - plural: clusterbackgroundscanreports - shortNames: - - cbgscanr - singular: clusterbackgroundscanreport - scope: Cluster - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.ownerReferences[0].apiVersion - name: ApiVersion - priority: 1 - type: string - - jsonPath: .metadata.ownerReferences[0].kind - name: Kind - priority: 1 - type: string - - jsonPath: .metadata.ownerReferences[0].name - name: Subject - priority: 1 - type: string - - jsonPath: .spec.summary.pass - name: Pass - type: integer - - jsonPath: .spec.summary.fail - name: Fail - type: integer - - jsonPath: .spec.summary.warn - name: Warn - type: integer - - jsonPath: .spec.summary.error - name: Error - type: integer - - jsonPath: .spec.summary.skip - name: Skip - type: integer - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .metadata.labels['audit\.kyverno\.io/resource\.hash'] - name: Hash - priority: 1 - type: string - name: v1alpha2 - schema: - openAPIV3Schema: - description: ClusterBackgroundScanReport is the Schema for the ClusterBackgroundScanReports - API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - properties: - results: - description: PolicyReportResult provides result details - items: - description: PolicyReportResult provides the result for an individual - policy - properties: - category: - description: Category indicates policy category - type: string - message: - description: Description is a short user friendly message for - the policy rule - type: string - policy: - description: Policy is the name or identifier of the policy + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names + for the user. + items: type: string + type: array + resources: + description: ResourceDescription contains information about the + resource being created or modified. Requires at least one tag + to be specified when under MatchResources. Specifying ResourceDescription + directly under match is being deprecated. Please specify under + "any" or "all" instead. properties: - additionalProperties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values support + the wildcard characters "*" (matches zero or many characters) + and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports + wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). NOTE: "Name" is being + deprecated in favor of "Names".' type: string - description: Properties provides additional information for - the policy rule + names: + description: Names are the names of the resources. Each name + supports wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the + resource namespace. Label keys and values in `matchLabels` + support the wildcard characters `*` (matches zero or many + characters) and `?` (matches one character).Wildcards allows + writing label selectors like ["storage.k8s.io/*": "*"]. + Note that using ["*" : "*"] matches any key and value but + does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each + name supports wildcard characters "*" (matches zero or many + characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and + values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches one + character). Wildcards allows writing label selectors like + ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches + any key and value but does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names for the + user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like users, + user groups, and service accounts. + items: + description: Subject contains a reference to the object or user + identities a role binding applies to. This can either hold + a direct API object reference, or a value for non-objects + such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. Defaults + to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined + by this API group are "User", "Group", and "ServiceAccount". + If the Authorizer does not recognized the kind value, + the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the + object kind is non-namespace, such as "User" or "Group", + and this value is not empty the Authorizer should report + an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + match: + description: MatchResources defines when cleanuppolicy should be applied. + The match criteria can include resource information (e.g. kind, + name, namespace, labels) and admission review request information + like the user name or role. At least one kind is required. + properties: + all: + description: All allows specifying resources which will be ANDed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources + properties: + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array type: object - resourceSelector: - description: SubjectSelector is an optional label selector for - checked Kubernetes resources. For example, a policy result - may apply to all pods that match a label. Either a Subject - or a SubjectSelector can be specified. If neither are provided, - the result is assumed to be for the policy report scope. + type: array + any: + description: Any allows specifying resources which will be ORed + items: + description: ResourceFilter allow users to "AND" or "OR" between + resources properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. + clusterRoles: + description: ClusterRoles is the list of cluster-wide role + names for the user. items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. + type: string + type: array + resources: + description: ResourceDescription contains information about + the resource being created or modified. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values + support the wildcard characters "*" (matches zero + or many characters) and "?" (matches at least one + character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + NOTE: "Name" is being deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each + name supports wildcard characters "*" (matches zero + or many characters) and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector + for the resource namespace. Label keys and values + in `matchLabels` support the wildcard characters `*` + (matches zero or many characters) and `?` (matches + one character).Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. + Each name supports wildcard characters "*" (matches + zero or many characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys + and values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches + one character). Wildcards allows writing label selectors + like ["storage.k8s.io/*": "*"]. Note that using ["*" + : "*"] matches any key and value but does not match + an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + roles: + description: Roles is the list of namespaced role names + for the user. + items: + type: string + type: array + subjects: + description: Subjects is the list of subject names like + users, user groups, and service accounts. + items: + description: Subject contains a reference to the object + or user identities a role binding applies to. This + can either hold a direct API object reference, or a + value for non-objects such as user and group names. properties: - key: - description: key is the label key that the selector - applies to. + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. + Defaults to "rbac.authorization.k8s.io" for User + and Group subjects. type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. + kind: + description: Kind of object being referenced. Values + defined by this API group are "User", "Group", and + "ServiceAccount". If the Authorizer does not recognized + the kind value, the Authorizer should report an + error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If + the object kind is non-namespace, such as "User" + or "Group", and this value is not empty the Authorizer + should report an error. type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists or - DoesNotExist, the values array must be empty. This - array is replaced during a strategic merge patch. - items: - type: string - type: array required: - - key - - operator + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + type: array + clusterRoles: + description: ClusterRoles is the list of cluster-wide role names + for the user. + items: + type: string + type: array + resources: + description: ResourceDescription contains information about the + resource being created or modified. Requires at least one tag + to be specified when under MatchResources. Specifying ResourceDescription + directly under match is being deprecated. Please specify under + "any" or "all" instead. + properties: + annotations: + additionalProperties: + type: string + description: Annotations is a map of annotations (key-value + pairs of type string). Annotation keys and values support + the wildcard characters "*" (matches zero or many characters) + and "?" (matches at least one character). + type: object + kinds: + description: Kinds is a list of resource kinds. + items: + type: string + type: array + name: + description: 'Name is the name of the resource. The name supports + wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). NOTE: "Name" is being + deprecated in favor of "Names".' + type: string + names: + description: Names are the names of the resources. Each name + supports wildcard characters "*" (matches zero or many characters) + and "?" (at least one character). + items: + type: string + type: array + namespaceSelector: + description: 'NamespaceSelector is a label selector for the + resource namespace. Label keys and values in `matchLabels` + support the wildcard characters `*` (matches zero or many + characters) and `?` (matches one character).Wildcards allows + writing label selectors like ["storage.k8s.io/*": "*"]. + Note that using ["*" : "*"] matches any key and value but + does not match an empty label set.' + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is - "key", the operator is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - resources: - description: Subjects is an optional reference to the checked - Kubernetes resources - items: - description: "ObjectReference contains enough information - to let you inspect or modify the referred object. --- New - uses of this type are discouraged because of difficulty - describing its usage when embedded in APIs. 1. Ignored fields. - \ It includes many fields which are not generally honored. - \ For instance, ResourceVersion and FieldPath are both very - rarely valid in actual usage. 2. Invalid usage help. It - is impossible to add specific help for individual usage. - \ In most embedded usages, there are particular restrictions - like, \"must refer only to types A and B\" or \"UID not - honored\" or \"name must be restricted\". Those cannot be - well described when embedded. 3. Inconsistent validation. - \ Because the usages are different, the validation rules - are different by usage, which makes it hard for users to - predict what will happen. 4. The fields are both imprecise - and overly precise. Kind is not a precise mapping to a - URL. This can produce ambiguity during interpretation and - require a REST mapping. In most cases, the dependency is - on the group,resource tuple and the version of the actual - struct is irrelevant. 5. We cannot easily change it. Because - this type is embedded in many locations, updates to this - type will affect numerous schemas. Don't make new APIs - embed an underspecified API type they do not control. \n - Instead of using this type, create a locally provided and - used type that is well-focused on your reference. For example, - ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 - ." + type: object + x-kubernetes-map-type: atomic + namespaces: + description: Namespaces is a list of namespaces names. Each + name supports wildcard characters "*" (matches zero or many + characters) and "?" (at least one character). + items: + type: string + type: array + selector: + description: 'Selector is a label selector. Label keys and + values in `matchLabels` support the wildcard characters + `*` (matches zero or many characters) and `?` (matches one + character). Wildcards allows writing label selectors like + ["storage.k8s.io/*": "*"]. Note that using ["*" : "*"] matches + any key and value but does not match an empty label set.' properties: - apiVersion: - description: API version of the referent. - type: string - fieldPath: - description: 'If referring to a piece of an object instead - of an entire object, this string should contain a valid - JSON/Go field access statement, such as desiredState.manifest.containers[2]. - For example, if the object reference is to a container - within a pod, this would take on a value like: "spec.containers{name}" - (where "name" refers to the name of the container that - triggered the event) or if no container name is specified - "spec.containers[2]" (container with index 2 in this - pod). This syntax is chosen only to have some well-defined - way of referencing a part of an object. TODO: this design - is not final and this field is subject to change in - the future.' - type: string - kind: - description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' - type: string - resourceVersion: - description: 'Specific resourceVersion to which this reference - is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' - type: string - uid: - description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' - type: string + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object type: object x-kubernetes-map-type: atomic - type: array - result: - description: Result indicates the outcome of the policy rule - execution - enum: - - pass - - fail - - warn - - error - - skip + type: object + roles: + description: Roles is the list of namespaced role names for the + user. + items: type: string - rule: - description: Rule is the name or identifier of the rule within - the policy + type: array + subjects: + description: Subjects is the list of subject names like users, + user groups, and service accounts. + items: + description: Subject contains a reference to the object or user + identities a role binding applies to. This can either hold + a direct API object reference, or a value for non-objects + such as user and group names. + properties: + apiGroup: + description: APIGroup holds the API group of the referenced + subject. Defaults to "" for ServiceAccount subjects. Defaults + to "rbac.authorization.k8s.io" for User and Group subjects. + type: string + kind: + description: Kind of object being referenced. Values defined + by this API group are "User", "Group", and "ServiceAccount". + If the Authorizer does not recognized the kind value, + the Authorizer should report an error. + type: string + name: + description: Name of the object being referenced. + type: string + namespace: + description: Namespace of the referenced object. If the + object kind is non-namespace, such as "User" or "Group", + and this value is not empty the Authorizer should report + an error. + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + type: array + type: object + schedule: + description: The schedule in Cron format + type: string + required: + - schedule + type: object + status: + description: Status contains policy runtime data. + properties: + conditions: + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time type: string - scored: - description: Scored indicates if this result is scored - type: boolean - severity: - description: Severity indicates policy check result criticality + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. enum: - - critical - - high - - low - - medium - - info + - "True" + - "False" + - Unknown type: string - source: - description: Source is an identifier for the policy engine that - manages this report + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string - timestamp: - description: Timestamp indicates the time the result was found - properties: - nanos: - description: Non-negative fractions of a second at nanosecond - resolution. Negative second values with fractions must - still have non-negative nanos values that count forward - in time. Must be from 0 to 999,999,999 inclusive. This - field may be limited in precision depending on context. - format: int32 - type: integer - seconds: - description: Represents seconds of UTC time since Unix epoch - 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z - to 9999-12-31T23:59:59Z inclusive. - format: int64 - type: integer - required: - - nanos - - seconds - type: object required: - - policy + - lastTransitionTime + - message + - reason + - status + - type type: object type: array - summary: - description: PolicyReportSummary provides a summary of results - properties: - error: - description: Error provides the count of policies that could not - be evaluated - type: integer - fail: - description: Fail provides the count of policies whose requirements - were not met - type: integer - pass: - description: Pass provides the count of policies whose requirements - were met - type: integer - skip: - description: Skip indicates the count of policies that were not - selected for evaluation - type: integer - warn: - description: Warn provides the count of non-scored policies whose - requirements were not met - type: integer - type: object type: object required: - spec type: object served: true storage: true - subresources: {} + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition diff --git a/docs/user/crd/index.html b/docs/user/crd/index.html index 9517a934c552..e4ae4f99c095 100644 --- a/docs/user/crd/index.html +++ b/docs/user/crd/index.html @@ -21,6 +21,9 @@ kyverno.io/v1
  • +kyverno.io/v1alpha1 +
  • +
  • kyverno.io/v1alpha2
  • @@ -713,7 +716,8 @@

    AnyAllConditions (Appears on: Attestation, ForEachMutation, -ForEachValidation) +ForEachValidation, +CleanupPolicySpec)

    AnyAllConditions consists of conditions wrapped denoting a logical criteria to be fulfilled. @@ -2394,7 +2398,8 @@

    MatchResources

    (Appears on: -Rule) +Rule, +CleanupPolicySpec)

    MatchResources is used to specify resource and admission review request data for @@ -3962,6 +3967,398 @@

    ViolatedRule
    +

    kyverno.io/v1alpha1

    +

    +

    +Resource Types: + +
    +

    CleanupPolicy +

    +

    +

    CleanupPolicy defines a rule for resource cleanup.

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +apiVersion
    +string
    + +kyverno.io/v1alpha1 + +
    +kind
    +string +
    CleanupPolicy
    +metadata
    + + +Kubernetes meta/v1.ObjectMeta + + +
    +Refer to the Kubernetes API documentation for the fields of the +metadata field. +
    +spec
    + + +CleanupPolicySpec + + +
    +

    Spec declares policy behaviors.

    +
    +
    + + + + + + + + + + + + + + + + + +
    +match
    + + +MatchResources + + +
    +

    MatchResources defines when cleanuppolicy should be applied. The match +criteria can include resource information (e.g. kind, name, namespace, labels) +and admission review request information like the user name or role. +At least one kind is required.

    +
    +exclude
    + + +MatchResources + + +
    +(Optional) +

    ExcludeResources defines when cleanuppolicy should not be applied. The exclude +criteria can include resource information (e.g. kind, name, namespace, labels) +and admission review request information like the name or role.

    +
    +schedule
    + +string + +
    +

    The schedule in Cron format

    +
    +conditions
    + + +AnyAllConditions + + +
    +(Optional) +

    Conditions defines conditions used to select resources which user needs to delete

    +
    +
    +status
    + + +CleanupPolicyStatus + + +
    +(Optional) +

    Status contains policy runtime data.

    +
    +
    +

    ClusterCleanupPolicy +

    +

    +

    ClusterCleanupPolicy defines rule for resource cleanup.

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +apiVersion
    +string
    + +kyverno.io/v1alpha1 + +
    +kind
    +string +
    ClusterCleanupPolicy
    +metadata
    + + +Kubernetes meta/v1.ObjectMeta + + +
    +Refer to the Kubernetes API documentation for the fields of the +metadata field. +
    +spec
    + + +CleanupPolicySpec + + +
    +

    Spec declares policy behaviors.

    +
    +
    + + + + + + + + + + + + + + + + + +
    +match
    + + +MatchResources + + +
    +

    MatchResources defines when cleanuppolicy should be applied. The match +criteria can include resource information (e.g. kind, name, namespace, labels) +and admission review request information like the user name or role. +At least one kind is required.

    +
    +exclude
    + + +MatchResources + + +
    +(Optional) +

    ExcludeResources defines when cleanuppolicy should not be applied. The exclude +criteria can include resource information (e.g. kind, name, namespace, labels) +and admission review request information like the name or role.

    +
    +schedule
    + +string + +
    +

    The schedule in Cron format

    +
    +conditions
    + + +AnyAllConditions + + +
    +(Optional) +

    Conditions defines conditions used to select resources which user needs to delete

    +
    +
    +status
    + + +CleanupPolicyStatus + + +
    +(Optional) +

    Status contains policy runtime data.

    +
    +
    +

    CleanupPolicySpec +

    +

    +(Appears on: +CleanupPolicy, +ClusterCleanupPolicy) +

    +

    +

    CleanupPolicySpec stores specifications for selecting resources that the user needs to delete +and schedule when the matching resources needs deleted.

    +

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +match
    + + +MatchResources + + +
    +

    MatchResources defines when cleanuppolicy should be applied. The match +criteria can include resource information (e.g. kind, name, namespace, labels) +and admission review request information like the user name or role. +At least one kind is required.

    +
    +exclude
    + + +MatchResources + + +
    +(Optional) +

    ExcludeResources defines when cleanuppolicy should not be applied. The exclude +criteria can include resource information (e.g. kind, name, namespace, labels) +and admission review request information like the name or role.

    +
    +schedule
    + +string + +
    +

    The schedule in Cron format

    +
    +conditions
    + + +AnyAllConditions + + +
    +(Optional) +

    Conditions defines conditions used to select resources which user needs to delete

    +
    +
    +

    CleanupPolicyStatus +

    +

    +(Appears on: +CleanupPolicy, +ClusterCleanupPolicy) +

    +

    +

    CleanupPolicyStatus stores the status of the policy.

    +

    + + + + + + + + + + + + + +
    FieldDescription
    +conditions
    + + +[]Kubernetes meta/v1.Condition + + +
    +
    +

    kyverno.io/v1alpha2

    Package v1alpha2 contains API Schema definitions for the policy v1alpha2 API group

    diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index 8672c2b1b54c..7dbc2e916c69 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -23,6 +23,7 @@ import ( "net/http" kyvernov1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1" + kyvernov1alpha1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha1" kyvernov1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha2" kyvernov1beta1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1beta1" wgpolicyk8sv1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/policyreport/v1alpha2" @@ -36,6 +37,7 @@ type Interface interface { KyvernoV1() kyvernov1.KyvernoV1Interface KyvernoV1beta1() kyvernov1beta1.KyvernoV1beta1Interface KyvernoV1alpha2() kyvernov1alpha2.KyvernoV1alpha2Interface + KyvernoV1alpha1() kyvernov1alpha1.KyvernoV1alpha1Interface Wgpolicyk8sV1alpha2() wgpolicyk8sv1alpha2.Wgpolicyk8sV1alpha2Interface } @@ -46,6 +48,7 @@ type Clientset struct { kyvernoV1 *kyvernov1.KyvernoV1Client kyvernoV1beta1 *kyvernov1beta1.KyvernoV1beta1Client kyvernoV1alpha2 *kyvernov1alpha2.KyvernoV1alpha2Client + kyvernoV1alpha1 *kyvernov1alpha1.KyvernoV1alpha1Client wgpolicyk8sV1alpha2 *wgpolicyk8sv1alpha2.Wgpolicyk8sV1alpha2Client } @@ -64,6 +67,11 @@ func (c *Clientset) KyvernoV1alpha2() kyvernov1alpha2.KyvernoV1alpha2Interface { return c.kyvernoV1alpha2 } +// KyvernoV1alpha1 retrieves the KyvernoV1alpha1Client +func (c *Clientset) KyvernoV1alpha1() kyvernov1alpha1.KyvernoV1alpha1Interface { + return c.kyvernoV1alpha1 +} + // Wgpolicyk8sV1alpha2 retrieves the Wgpolicyk8sV1alpha2Client func (c *Clientset) Wgpolicyk8sV1alpha2() wgpolicyk8sv1alpha2.Wgpolicyk8sV1alpha2Interface { return c.wgpolicyk8sV1alpha2 @@ -125,6 +133,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.kyvernoV1alpha1, err = kyvernov1alpha1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.wgpolicyk8sV1alpha2, err = wgpolicyk8sv1alpha2.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -153,6 +165,7 @@ func New(c rest.Interface) *Clientset { cs.kyvernoV1 = kyvernov1.New(c) cs.kyvernoV1beta1 = kyvernov1beta1.New(c) cs.kyvernoV1alpha2 = kyvernov1alpha2.New(c) + cs.kyvernoV1alpha1 = kyvernov1alpha1.New(c) cs.wgpolicyk8sV1alpha2 = wgpolicyk8sv1alpha2.New(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c) diff --git a/pkg/client/clientset/versioned/fake/clientset_generated.go b/pkg/client/clientset/versioned/fake/clientset_generated.go index 74cc2268ca8d..680d7e8b2fef 100644 --- a/pkg/client/clientset/versioned/fake/clientset_generated.go +++ b/pkg/client/clientset/versioned/fake/clientset_generated.go @@ -22,6 +22,8 @@ import ( clientset "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1" fakekyvernov1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1/fake" + kyvernov1alpha1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha1" + fakekyvernov1alpha1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake" kyvernov1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha2" fakekyvernov1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha2/fake" kyvernov1beta1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1beta1" @@ -100,6 +102,11 @@ func (c *Clientset) KyvernoV1alpha2() kyvernov1alpha2.KyvernoV1alpha2Interface { return &fakekyvernov1alpha2.FakeKyvernoV1alpha2{Fake: &c.Fake} } +// KyvernoV1alpha1 retrieves the KyvernoV1alpha1Client +func (c *Clientset) KyvernoV1alpha1() kyvernov1alpha1.KyvernoV1alpha1Interface { + return &fakekyvernov1alpha1.FakeKyvernoV1alpha1{Fake: &c.Fake} +} + // Wgpolicyk8sV1alpha2 retrieves the Wgpolicyk8sV1alpha2Client func (c *Clientset) Wgpolicyk8sV1alpha2() wgpolicyk8sv1alpha2.Wgpolicyk8sV1alpha2Interface { return &fakewgpolicyk8sv1alpha2.FakeWgpolicyk8sV1alpha2{Fake: &c.Fake} diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index a93604b6d11a..0796c591c350 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -20,6 +20,7 @@ package fake import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" + kyvernov1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" wgpolicyk8sv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2" @@ -37,20 +38,21 @@ var localSchemeBuilder = runtime.SchemeBuilder{ kyvernov1.AddToScheme, kyvernov1beta1.AddToScheme, kyvernov1alpha2.AddToScheme, + kyvernov1alpha1.AddToScheme, wgpolicyk8sv1alpha2.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition // of clientsets, like in: // -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) // -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. diff --git a/pkg/client/clientset/versioned/scheme/register.go b/pkg/client/clientset/versioned/scheme/register.go index 9fbeaa98f0d3..a90d5bb636aa 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -20,6 +20,7 @@ package scheme import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" + kyvernov1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" wgpolicyk8sv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2" @@ -37,20 +38,21 @@ var localSchemeBuilder = runtime.SchemeBuilder{ kyvernov1.AddToScheme, kyvernov1beta1.AddToScheme, kyvernov1alpha2.AddToScheme, + kyvernov1alpha1.AddToScheme, wgpolicyk8sv1alpha2.AddToScheme, } // AddToScheme adds all types of this clientset into the given scheme. This allows composition // of clientsets, like in: // -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) // -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. diff --git a/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/cleanuppolicy.go b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/cleanuppolicy.go new file mode 100644 index 000000000000..b369025090cd --- /dev/null +++ b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/cleanuppolicy.go @@ -0,0 +1,195 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + "time" + + v1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" + scheme "github.com/kyverno/kyverno/pkg/client/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CleanupPoliciesGetter has a method to return a CleanupPolicyInterface. +// A group's client should implement this interface. +type CleanupPoliciesGetter interface { + CleanupPolicies(namespace string) CleanupPolicyInterface +} + +// CleanupPolicyInterface has methods to work with CleanupPolicy resources. +type CleanupPolicyInterface interface { + Create(ctx context.Context, cleanupPolicy *v1alpha1.CleanupPolicy, opts v1.CreateOptions) (*v1alpha1.CleanupPolicy, error) + Update(ctx context.Context, cleanupPolicy *v1alpha1.CleanupPolicy, opts v1.UpdateOptions) (*v1alpha1.CleanupPolicy, error) + UpdateStatus(ctx context.Context, cleanupPolicy *v1alpha1.CleanupPolicy, opts v1.UpdateOptions) (*v1alpha1.CleanupPolicy, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.CleanupPolicy, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.CleanupPolicyList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.CleanupPolicy, err error) + CleanupPolicyExpansion +} + +// cleanupPolicies implements CleanupPolicyInterface +type cleanupPolicies struct { + client rest.Interface + ns string +} + +// newCleanupPolicies returns a CleanupPolicies +func newCleanupPolicies(c *KyvernoV1alpha1Client, namespace string) *cleanupPolicies { + return &cleanupPolicies{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cleanupPolicy, and returns the corresponding cleanupPolicy object, and an error if there is any. +func (c *cleanupPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.CleanupPolicy, err error) { + result = &v1alpha1.CleanupPolicy{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cleanuppolicies"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CleanupPolicies that match those selectors. +func (c *cleanupPolicies) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.CleanupPolicyList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.CleanupPolicyList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cleanuppolicies"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cleanupPolicies. +func (c *cleanupPolicies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cleanuppolicies"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cleanupPolicy and creates it. Returns the server's representation of the cleanupPolicy, and an error, if there is any. +func (c *cleanupPolicies) Create(ctx context.Context, cleanupPolicy *v1alpha1.CleanupPolicy, opts v1.CreateOptions) (result *v1alpha1.CleanupPolicy, err error) { + result = &v1alpha1.CleanupPolicy{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cleanuppolicies"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cleanupPolicy). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cleanupPolicy and updates it. Returns the server's representation of the cleanupPolicy, and an error, if there is any. +func (c *cleanupPolicies) Update(ctx context.Context, cleanupPolicy *v1alpha1.CleanupPolicy, opts v1.UpdateOptions) (result *v1alpha1.CleanupPolicy, err error) { + result = &v1alpha1.CleanupPolicy{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cleanuppolicies"). + Name(cleanupPolicy.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cleanupPolicy). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *cleanupPolicies) UpdateStatus(ctx context.Context, cleanupPolicy *v1alpha1.CleanupPolicy, opts v1.UpdateOptions) (result *v1alpha1.CleanupPolicy, err error) { + result = &v1alpha1.CleanupPolicy{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cleanuppolicies"). + Name(cleanupPolicy.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cleanupPolicy). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cleanupPolicy and deletes it. Returns an error if one occurs. +func (c *cleanupPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cleanuppolicies"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cleanupPolicies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cleanuppolicies"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cleanupPolicy. +func (c *cleanupPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.CleanupPolicy, err error) { + result = &v1alpha1.CleanupPolicy{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cleanuppolicies"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/clustercleanuppolicy.go b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/clustercleanuppolicy.go new file mode 100644 index 000000000000..5e0968f715e2 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/clustercleanuppolicy.go @@ -0,0 +1,184 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + "time" + + v1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" + scheme "github.com/kyverno/kyverno/pkg/client/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ClusterCleanupPoliciesGetter has a method to return a ClusterCleanupPolicyInterface. +// A group's client should implement this interface. +type ClusterCleanupPoliciesGetter interface { + ClusterCleanupPolicies() ClusterCleanupPolicyInterface +} + +// ClusterCleanupPolicyInterface has methods to work with ClusterCleanupPolicy resources. +type ClusterCleanupPolicyInterface interface { + Create(ctx context.Context, clusterCleanupPolicy *v1alpha1.ClusterCleanupPolicy, opts v1.CreateOptions) (*v1alpha1.ClusterCleanupPolicy, error) + Update(ctx context.Context, clusterCleanupPolicy *v1alpha1.ClusterCleanupPolicy, opts v1.UpdateOptions) (*v1alpha1.ClusterCleanupPolicy, error) + UpdateStatus(ctx context.Context, clusterCleanupPolicy *v1alpha1.ClusterCleanupPolicy, opts v1.UpdateOptions) (*v1alpha1.ClusterCleanupPolicy, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ClusterCleanupPolicy, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ClusterCleanupPolicyList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterCleanupPolicy, err error) + ClusterCleanupPolicyExpansion +} + +// clusterCleanupPolicies implements ClusterCleanupPolicyInterface +type clusterCleanupPolicies struct { + client rest.Interface +} + +// newClusterCleanupPolicies returns a ClusterCleanupPolicies +func newClusterCleanupPolicies(c *KyvernoV1alpha1Client) *clusterCleanupPolicies { + return &clusterCleanupPolicies{ + client: c.RESTClient(), + } +} + +// Get takes name of the clusterCleanupPolicy, and returns the corresponding clusterCleanupPolicy object, and an error if there is any. +func (c *clusterCleanupPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterCleanupPolicy, err error) { + result = &v1alpha1.ClusterCleanupPolicy{} + err = c.client.Get(). + Resource("clustercleanuppolicies"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ClusterCleanupPolicies that match those selectors. +func (c *clusterCleanupPolicies) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterCleanupPolicyList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.ClusterCleanupPolicyList{} + err = c.client.Get(). + Resource("clustercleanuppolicies"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested clusterCleanupPolicies. +func (c *clusterCleanupPolicies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Resource("clustercleanuppolicies"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a clusterCleanupPolicy and creates it. Returns the server's representation of the clusterCleanupPolicy, and an error, if there is any. +func (c *clusterCleanupPolicies) Create(ctx context.Context, clusterCleanupPolicy *v1alpha1.ClusterCleanupPolicy, opts v1.CreateOptions) (result *v1alpha1.ClusterCleanupPolicy, err error) { + result = &v1alpha1.ClusterCleanupPolicy{} + err = c.client.Post(). + Resource("clustercleanuppolicies"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterCleanupPolicy). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a clusterCleanupPolicy and updates it. Returns the server's representation of the clusterCleanupPolicy, and an error, if there is any. +func (c *clusterCleanupPolicies) Update(ctx context.Context, clusterCleanupPolicy *v1alpha1.ClusterCleanupPolicy, opts v1.UpdateOptions) (result *v1alpha1.ClusterCleanupPolicy, err error) { + result = &v1alpha1.ClusterCleanupPolicy{} + err = c.client.Put(). + Resource("clustercleanuppolicies"). + Name(clusterCleanupPolicy.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterCleanupPolicy). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *clusterCleanupPolicies) UpdateStatus(ctx context.Context, clusterCleanupPolicy *v1alpha1.ClusterCleanupPolicy, opts v1.UpdateOptions) (result *v1alpha1.ClusterCleanupPolicy, err error) { + result = &v1alpha1.ClusterCleanupPolicy{} + err = c.client.Put(). + Resource("clustercleanuppolicies"). + Name(clusterCleanupPolicy.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterCleanupPolicy). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the clusterCleanupPolicy and deletes it. Returns an error if one occurs. +func (c *clusterCleanupPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Resource("clustercleanuppolicies"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *clusterCleanupPolicies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Resource("clustercleanuppolicies"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched clusterCleanupPolicy. +func (c *clusterCleanupPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterCleanupPolicy, err error) { + result = &v1alpha1.ClusterCleanupPolicy{} + err = c.client.Patch(pt). + Resource("clustercleanuppolicies"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/doc.go b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/doc.go new file mode 100644 index 000000000000..df51baa4d4c1 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1alpha1 diff --git a/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/doc.go b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/doc.go new file mode 100644 index 000000000000..16f44399065e --- /dev/null +++ b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_cleanuppolicy.go b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_cleanuppolicy.go new file mode 100644 index 000000000000..14161db932a1 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_cleanuppolicy.go @@ -0,0 +1,142 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeCleanupPolicies implements CleanupPolicyInterface +type FakeCleanupPolicies struct { + Fake *FakeKyvernoV1alpha1 + ns string +} + +var cleanuppoliciesResource = schema.GroupVersionResource{Group: "kyverno.io", Version: "v1alpha1", Resource: "cleanuppolicies"} + +var cleanuppoliciesKind = schema.GroupVersionKind{Group: "kyverno.io", Version: "v1alpha1", Kind: "CleanupPolicy"} + +// Get takes name of the cleanupPolicy, and returns the corresponding cleanupPolicy object, and an error if there is any. +func (c *FakeCleanupPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.CleanupPolicy, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(cleanuppoliciesResource, c.ns, name), &v1alpha1.CleanupPolicy{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.CleanupPolicy), err +} + +// List takes label and field selectors, and returns the list of CleanupPolicies that match those selectors. +func (c *FakeCleanupPolicies) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.CleanupPolicyList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(cleanuppoliciesResource, cleanuppoliciesKind, c.ns, opts), &v1alpha1.CleanupPolicyList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.CleanupPolicyList{ListMeta: obj.(*v1alpha1.CleanupPolicyList).ListMeta} + for _, item := range obj.(*v1alpha1.CleanupPolicyList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested cleanupPolicies. +func (c *FakeCleanupPolicies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(cleanuppoliciesResource, c.ns, opts)) + +} + +// Create takes the representation of a cleanupPolicy and creates it. Returns the server's representation of the cleanupPolicy, and an error, if there is any. +func (c *FakeCleanupPolicies) Create(ctx context.Context, cleanupPolicy *v1alpha1.CleanupPolicy, opts v1.CreateOptions) (result *v1alpha1.CleanupPolicy, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(cleanuppoliciesResource, c.ns, cleanupPolicy), &v1alpha1.CleanupPolicy{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.CleanupPolicy), err +} + +// Update takes the representation of a cleanupPolicy and updates it. Returns the server's representation of the cleanupPolicy, and an error, if there is any. +func (c *FakeCleanupPolicies) Update(ctx context.Context, cleanupPolicy *v1alpha1.CleanupPolicy, opts v1.UpdateOptions) (result *v1alpha1.CleanupPolicy, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(cleanuppoliciesResource, c.ns, cleanupPolicy), &v1alpha1.CleanupPolicy{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.CleanupPolicy), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeCleanupPolicies) UpdateStatus(ctx context.Context, cleanupPolicy *v1alpha1.CleanupPolicy, opts v1.UpdateOptions) (*v1alpha1.CleanupPolicy, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(cleanuppoliciesResource, "status", c.ns, cleanupPolicy), &v1alpha1.CleanupPolicy{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.CleanupPolicy), err +} + +// Delete takes name of the cleanupPolicy and deletes it. Returns an error if one occurs. +func (c *FakeCleanupPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(cleanuppoliciesResource, c.ns, name, opts), &v1alpha1.CleanupPolicy{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeCleanupPolicies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(cleanuppoliciesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.CleanupPolicyList{}) + return err +} + +// Patch applies the patch and returns the patched cleanupPolicy. +func (c *FakeCleanupPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.CleanupPolicy, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(cleanuppoliciesResource, c.ns, name, pt, data, subresources...), &v1alpha1.CleanupPolicy{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.CleanupPolicy), err +} diff --git a/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_clustercleanuppolicy.go b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_clustercleanuppolicy.go new file mode 100644 index 000000000000..e87e940eef92 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_clustercleanuppolicy.go @@ -0,0 +1,133 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeClusterCleanupPolicies implements ClusterCleanupPolicyInterface +type FakeClusterCleanupPolicies struct { + Fake *FakeKyvernoV1alpha1 +} + +var clustercleanuppoliciesResource = schema.GroupVersionResource{Group: "kyverno.io", Version: "v1alpha1", Resource: "clustercleanuppolicies"} + +var clustercleanuppoliciesKind = schema.GroupVersionKind{Group: "kyverno.io", Version: "v1alpha1", Kind: "ClusterCleanupPolicy"} + +// Get takes name of the clusterCleanupPolicy, and returns the corresponding clusterCleanupPolicy object, and an error if there is any. +func (c *FakeClusterCleanupPolicies) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ClusterCleanupPolicy, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(clustercleanuppoliciesResource, name), &v1alpha1.ClusterCleanupPolicy{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterCleanupPolicy), err +} + +// List takes label and field selectors, and returns the list of ClusterCleanupPolicies that match those selectors. +func (c *FakeClusterCleanupPolicies) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ClusterCleanupPolicyList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(clustercleanuppoliciesResource, clustercleanuppoliciesKind, opts), &v1alpha1.ClusterCleanupPolicyList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.ClusterCleanupPolicyList{ListMeta: obj.(*v1alpha1.ClusterCleanupPolicyList).ListMeta} + for _, item := range obj.(*v1alpha1.ClusterCleanupPolicyList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested clusterCleanupPolicies. +func (c *FakeClusterCleanupPolicies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(clustercleanuppoliciesResource, opts)) +} + +// Create takes the representation of a clusterCleanupPolicy and creates it. Returns the server's representation of the clusterCleanupPolicy, and an error, if there is any. +func (c *FakeClusterCleanupPolicies) Create(ctx context.Context, clusterCleanupPolicy *v1alpha1.ClusterCleanupPolicy, opts v1.CreateOptions) (result *v1alpha1.ClusterCleanupPolicy, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(clustercleanuppoliciesResource, clusterCleanupPolicy), &v1alpha1.ClusterCleanupPolicy{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterCleanupPolicy), err +} + +// Update takes the representation of a clusterCleanupPolicy and updates it. Returns the server's representation of the clusterCleanupPolicy, and an error, if there is any. +func (c *FakeClusterCleanupPolicies) Update(ctx context.Context, clusterCleanupPolicy *v1alpha1.ClusterCleanupPolicy, opts v1.UpdateOptions) (result *v1alpha1.ClusterCleanupPolicy, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(clustercleanuppoliciesResource, clusterCleanupPolicy), &v1alpha1.ClusterCleanupPolicy{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterCleanupPolicy), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeClusterCleanupPolicies) UpdateStatus(ctx context.Context, clusterCleanupPolicy *v1alpha1.ClusterCleanupPolicy, opts v1.UpdateOptions) (*v1alpha1.ClusterCleanupPolicy, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(clustercleanuppoliciesResource, "status", clusterCleanupPolicy), &v1alpha1.ClusterCleanupPolicy{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterCleanupPolicy), err +} + +// Delete takes name of the clusterCleanupPolicy and deletes it. Returns an error if one occurs. +func (c *FakeClusterCleanupPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteActionWithOptions(clustercleanuppoliciesResource, name, opts), &v1alpha1.ClusterCleanupPolicy{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeClusterCleanupPolicies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(clustercleanuppoliciesResource, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.ClusterCleanupPolicyList{}) + return err +} + +// Patch applies the patch and returns the patched clusterCleanupPolicy. +func (c *FakeClusterCleanupPolicies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ClusterCleanupPolicy, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(clustercleanuppoliciesResource, name, pt, data, subresources...), &v1alpha1.ClusterCleanupPolicy{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterCleanupPolicy), err +} diff --git a/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_kyverno_client.go b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_kyverno_client.go new file mode 100644 index 000000000000..9a8943e0de97 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/fake/fake_kyverno_client.go @@ -0,0 +1,44 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeKyvernoV1alpha1 struct { + *testing.Fake +} + +func (c *FakeKyvernoV1alpha1) CleanupPolicies(namespace string) v1alpha1.CleanupPolicyInterface { + return &FakeCleanupPolicies{c, namespace} +} + +func (c *FakeKyvernoV1alpha1) ClusterCleanupPolicies() v1alpha1.ClusterCleanupPolicyInterface { + return &FakeClusterCleanupPolicies{c} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeKyvernoV1alpha1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/generated_expansion.go new file mode 100644 index 000000000000..619568a95c62 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/generated_expansion.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +type CleanupPolicyExpansion interface{} + +type ClusterCleanupPolicyExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/kyverno_client.go b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/kyverno_client.go new file mode 100644 index 000000000000..88fc9dd16bc6 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/kyverno/v1alpha1/kyverno_client.go @@ -0,0 +1,112 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "net/http" + + v1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" + "github.com/kyverno/kyverno/pkg/client/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type KyvernoV1alpha1Interface interface { + RESTClient() rest.Interface + CleanupPoliciesGetter + ClusterCleanupPoliciesGetter +} + +// KyvernoV1alpha1Client is used to interact with features provided by the kyverno.io group. +type KyvernoV1alpha1Client struct { + restClient rest.Interface +} + +func (c *KyvernoV1alpha1Client) CleanupPolicies(namespace string) CleanupPolicyInterface { + return newCleanupPolicies(c, namespace) +} + +func (c *KyvernoV1alpha1Client) ClusterCleanupPolicies() ClusterCleanupPolicyInterface { + return newClusterCleanupPolicies(c) +} + +// NewForConfig creates a new KyvernoV1alpha1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*KyvernoV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new KyvernoV1alpha1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*KyvernoV1alpha1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &KyvernoV1alpha1Client{client}, nil +} + +// NewForConfigOrDie creates a new KyvernoV1alpha1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *KyvernoV1alpha1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new KyvernoV1alpha1Client for the given RESTClient. +func New(c rest.Interface) *KyvernoV1alpha1Client { + return &KyvernoV1alpha1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1alpha1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *KyvernoV1alpha1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index 9ef9add59a45..0c88a3e6ee98 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -22,6 +22,7 @@ import ( "fmt" v1 "github.com/kyverno/kyverno/api/kyverno/v1" + v1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" v1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2" v1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2" @@ -63,6 +64,12 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case v1.SchemeGroupVersion.WithResource("policies"): return &genericInformer{resource: resource.GroupResource(), informer: f.Kyverno().V1().Policies().Informer()}, nil + // Group=kyverno.io, Version=v1alpha1 + case v1alpha1.SchemeGroupVersion.WithResource("cleanuppolicies"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Kyverno().V1alpha1().CleanupPolicies().Informer()}, nil + case v1alpha1.SchemeGroupVersion.WithResource("clustercleanuppolicies"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Kyverno().V1alpha1().ClusterCleanupPolicies().Informer()}, nil + // Group=kyverno.io, Version=v1alpha2 case v1alpha2.SchemeGroupVersion.WithResource("admissionreports"): return &genericInformer{resource: resource.GroupResource(), informer: f.Kyverno().V1alpha2().AdmissionReports().Informer()}, nil diff --git a/pkg/client/informers/externalversions/kyverno/interface.go b/pkg/client/informers/externalversions/kyverno/interface.go index 749c186593d8..3f99ec71cf01 100644 --- a/pkg/client/informers/externalversions/kyverno/interface.go +++ b/pkg/client/informers/externalversions/kyverno/interface.go @@ -21,6 +21,7 @@ package kyverno import ( internalinterfaces "github.com/kyverno/kyverno/pkg/client/informers/externalversions/internalinterfaces" v1 "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1" + v1alpha1 "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1alpha1" v1alpha2 "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1alpha2" v1beta1 "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1beta1" ) @@ -33,6 +34,8 @@ type Interface interface { V1beta1() v1beta1.Interface // V1alpha2 provides access to shared informers for resources in V1alpha2. V1alpha2() v1alpha2.Interface + // V1alpha1 provides access to shared informers for resources in V1alpha1. + V1alpha1() v1alpha1.Interface } type group struct { @@ -60,3 +63,8 @@ func (g *group) V1beta1() v1beta1.Interface { func (g *group) V1alpha2() v1alpha2.Interface { return v1alpha2.New(g.factory, g.namespace, g.tweakListOptions) } + +// V1alpha1 returns a new v1alpha1.Interface. +func (g *group) V1alpha1() v1alpha1.Interface { + return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/pkg/client/informers/externalversions/kyverno/v1alpha1/cleanuppolicy.go b/pkg/client/informers/externalversions/kyverno/v1alpha1/cleanuppolicy.go new file mode 100644 index 000000000000..aa8d9602601c --- /dev/null +++ b/pkg/client/informers/externalversions/kyverno/v1alpha1/cleanuppolicy.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + kyvernov1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" + versioned "github.com/kyverno/kyverno/pkg/client/clientset/versioned" + internalinterfaces "github.com/kyverno/kyverno/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// CleanupPolicyInformer provides access to a shared informer and lister for +// CleanupPolicies. +type CleanupPolicyInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.CleanupPolicyLister +} + +type cleanupPolicyInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewCleanupPolicyInformer constructs a new informer for CleanupPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCleanupPolicyInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCleanupPolicyInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredCleanupPolicyInformer constructs a new informer for CleanupPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCleanupPolicyInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.KyvernoV1alpha1().CleanupPolicies(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.KyvernoV1alpha1().CleanupPolicies(namespace).Watch(context.TODO(), options) + }, + }, + &kyvernov1alpha1.CleanupPolicy{}, + resyncPeriod, + indexers, + ) +} + +func (f *cleanupPolicyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCleanupPolicyInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cleanupPolicyInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&kyvernov1alpha1.CleanupPolicy{}, f.defaultInformer) +} + +func (f *cleanupPolicyInformer) Lister() v1alpha1.CleanupPolicyLister { + return v1alpha1.NewCleanupPolicyLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/kyverno/v1alpha1/clustercleanuppolicy.go b/pkg/client/informers/externalversions/kyverno/v1alpha1/clustercleanuppolicy.go new file mode 100644 index 000000000000..b35788d4c637 --- /dev/null +++ b/pkg/client/informers/externalversions/kyverno/v1alpha1/clustercleanuppolicy.go @@ -0,0 +1,89 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + kyvernov1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" + versioned "github.com/kyverno/kyverno/pkg/client/clientset/versioned" + internalinterfaces "github.com/kyverno/kyverno/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ClusterCleanupPolicyInformer provides access to a shared informer and lister for +// ClusterCleanupPolicies. +type ClusterCleanupPolicyInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.ClusterCleanupPolicyLister +} + +type clusterCleanupPolicyInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// NewClusterCleanupPolicyInformer constructs a new informer for ClusterCleanupPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewClusterCleanupPolicyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterCleanupPolicyInformer(client, resyncPeriod, indexers, nil) +} + +// NewFilteredClusterCleanupPolicyInformer constructs a new informer for ClusterCleanupPolicy type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredClusterCleanupPolicyInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.KyvernoV1alpha1().ClusterCleanupPolicies().List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.KyvernoV1alpha1().ClusterCleanupPolicies().Watch(context.TODO(), options) + }, + }, + &kyvernov1alpha1.ClusterCleanupPolicy{}, + resyncPeriod, + indexers, + ) +} + +func (f *clusterCleanupPolicyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterCleanupPolicyInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *clusterCleanupPolicyInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&kyvernov1alpha1.ClusterCleanupPolicy{}, f.defaultInformer) +} + +func (f *clusterCleanupPolicyInformer) Lister() v1alpha1.ClusterCleanupPolicyLister { + return v1alpha1.NewClusterCleanupPolicyLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/kyverno/v1alpha1/interface.go b/pkg/client/informers/externalversions/kyverno/v1alpha1/interface.go new file mode 100644 index 000000000000..394e8eeaee6f --- /dev/null +++ b/pkg/client/informers/externalversions/kyverno/v1alpha1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + internalinterfaces "github.com/kyverno/kyverno/pkg/client/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // CleanupPolicies returns a CleanupPolicyInformer. + CleanupPolicies() CleanupPolicyInformer + // ClusterCleanupPolicies returns a ClusterCleanupPolicyInformer. + ClusterCleanupPolicies() ClusterCleanupPolicyInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// CleanupPolicies returns a CleanupPolicyInformer. +func (v *version) CleanupPolicies() CleanupPolicyInformer { + return &cleanupPolicyInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ClusterCleanupPolicies returns a ClusterCleanupPolicyInformer. +func (v *version) ClusterCleanupPolicies() ClusterCleanupPolicyInformer { + return &clusterCleanupPolicyInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/client/listers/kyverno/v1alpha1/cleanuppolicy.go b/pkg/client/listers/kyverno/v1alpha1/cleanuppolicy.go new file mode 100644 index 000000000000..bb915a2b0ad4 --- /dev/null +++ b/pkg/client/listers/kyverno/v1alpha1/cleanuppolicy.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CleanupPolicyLister helps list CleanupPolicies. +// All objects returned here must be treated as read-only. +type CleanupPolicyLister interface { + // List lists all CleanupPolicies in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.CleanupPolicy, err error) + // CleanupPolicies returns an object that can list and get CleanupPolicies. + CleanupPolicies(namespace string) CleanupPolicyNamespaceLister + CleanupPolicyListerExpansion +} + +// cleanupPolicyLister implements the CleanupPolicyLister interface. +type cleanupPolicyLister struct { + indexer cache.Indexer +} + +// NewCleanupPolicyLister returns a new CleanupPolicyLister. +func NewCleanupPolicyLister(indexer cache.Indexer) CleanupPolicyLister { + return &cleanupPolicyLister{indexer: indexer} +} + +// List lists all CleanupPolicies in the indexer. +func (s *cleanupPolicyLister) List(selector labels.Selector) (ret []*v1alpha1.CleanupPolicy, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.CleanupPolicy)) + }) + return ret, err +} + +// CleanupPolicies returns an object that can list and get CleanupPolicies. +func (s *cleanupPolicyLister) CleanupPolicies(namespace string) CleanupPolicyNamespaceLister { + return cleanupPolicyNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// CleanupPolicyNamespaceLister helps list and get CleanupPolicies. +// All objects returned here must be treated as read-only. +type CleanupPolicyNamespaceLister interface { + // List lists all CleanupPolicies in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.CleanupPolicy, err error) + // Get retrieves the CleanupPolicy from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.CleanupPolicy, error) + CleanupPolicyNamespaceListerExpansion +} + +// cleanupPolicyNamespaceLister implements the CleanupPolicyNamespaceLister +// interface. +type cleanupPolicyNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all CleanupPolicies in the indexer for a given namespace. +func (s cleanupPolicyNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.CleanupPolicy, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.CleanupPolicy)) + }) + return ret, err +} + +// Get retrieves the CleanupPolicy from the indexer for a given namespace and name. +func (s cleanupPolicyNamespaceLister) Get(name string) (*v1alpha1.CleanupPolicy, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("cleanuppolicy"), name) + } + return obj.(*v1alpha1.CleanupPolicy), nil +} diff --git a/pkg/client/listers/kyverno/v1alpha1/clustercleanuppolicy.go b/pkg/client/listers/kyverno/v1alpha1/clustercleanuppolicy.go new file mode 100644 index 000000000000..60d67a15b60c --- /dev/null +++ b/pkg/client/listers/kyverno/v1alpha1/clustercleanuppolicy.go @@ -0,0 +1,68 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterCleanupPolicyLister helps list ClusterCleanupPolicies. +// All objects returned here must be treated as read-only. +type ClusterCleanupPolicyLister interface { + // List lists all ClusterCleanupPolicies in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.ClusterCleanupPolicy, err error) + // Get retrieves the ClusterCleanupPolicy from the index for a given name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.ClusterCleanupPolicy, error) + ClusterCleanupPolicyListerExpansion +} + +// clusterCleanupPolicyLister implements the ClusterCleanupPolicyLister interface. +type clusterCleanupPolicyLister struct { + indexer cache.Indexer +} + +// NewClusterCleanupPolicyLister returns a new ClusterCleanupPolicyLister. +func NewClusterCleanupPolicyLister(indexer cache.Indexer) ClusterCleanupPolicyLister { + return &clusterCleanupPolicyLister{indexer: indexer} +} + +// List lists all ClusterCleanupPolicies in the indexer. +func (s *clusterCleanupPolicyLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterCleanupPolicy, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ClusterCleanupPolicy)) + }) + return ret, err +} + +// Get retrieves the ClusterCleanupPolicy from the index for a given name. +func (s *clusterCleanupPolicyLister) Get(name string) (*v1alpha1.ClusterCleanupPolicy, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("clustercleanuppolicy"), name) + } + return obj.(*v1alpha1.ClusterCleanupPolicy), nil +} diff --git a/pkg/client/listers/kyverno/v1alpha1/expansion_generated.go b/pkg/client/listers/kyverno/v1alpha1/expansion_generated.go new file mode 100644 index 000000000000..7d8989e5b27e --- /dev/null +++ b/pkg/client/listers/kyverno/v1alpha1/expansion_generated.go @@ -0,0 +1,31 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +// CleanupPolicyListerExpansion allows custom methods to be added to +// CleanupPolicyLister. +type CleanupPolicyListerExpansion interface{} + +// CleanupPolicyNamespaceListerExpansion allows custom methods to be added to +// CleanupPolicyNamespaceLister. +type CleanupPolicyNamespaceListerExpansion interface{} + +// ClusterCleanupPolicyListerExpansion allows custom methods to be added to +// ClusterCleanupPolicyLister. +type ClusterCleanupPolicyListerExpansion interface{} diff --git a/pkg/clients/wrappers/clientset.go b/pkg/clients/wrappers/clientset.go index e1ab599a0661..a4400bda843e 100644 --- a/pkg/clients/wrappers/clientset.go +++ b/pkg/clients/wrappers/clientset.go @@ -3,10 +3,12 @@ package kyvernoclient import ( "github.com/kyverno/kyverno/pkg/client/clientset/versioned" versionedkyvernov1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1" + versionedkyvernov1alpha1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha1" versionedkyvernov1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha2" versionedkyvernov1beta1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1beta1" versionedpolicyreportv1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/policyreport/v1alpha2" wrappedkyvernov1 "github.com/kyverno/kyverno/pkg/clients/wrappers/kyverno/v1" + wrappedkyvernov1alpha1 "github.com/kyverno/kyverno/pkg/clients/wrappers/kyverno/v1alpha1" wrappedkyvernov1alpha2 "github.com/kyverno/kyverno/pkg/clients/wrappers/kyverno/v1alpha2" wrappedkyvernov1beta1 "github.com/kyverno/kyverno/pkg/clients/wrappers/kyverno/v1beta1" wrappedwgpolicyk8sv1alpha2 "github.com/kyverno/kyverno/pkg/clients/wrappers/policyreport/v1alpha2" @@ -19,6 +21,7 @@ type clientset struct { kyvernoV1 versionedkyvernov1.KyvernoV1Interface kyvernoV1beta1 versionedkyvernov1beta1.KyvernoV1beta1Interface kyvernoV1alpha2 versionedkyvernov1alpha2.KyvernoV1alpha2Interface + kyvernoV1alpha1 versionedkyvernov1alpha1.KyvernoV1alpha1Interface wgpolicyk8sV1alpha2 versionedpolicyreportv1alpha2.Wgpolicyk8sV1alpha2Interface } @@ -34,6 +37,10 @@ func (c *clientset) KyvernoV1alpha2() versionedkyvernov1alpha2.KyvernoV1alpha2In return c.kyvernoV1alpha2 } +func (c *clientset) KyvernoV1alpha1() versionedkyvernov1alpha1.KyvernoV1alpha1Interface { + return c.kyvernoV1alpha1 +} + func (c *clientset) Wgpolicyk8sV1alpha2() versionedpolicyreportv1alpha2.Wgpolicyk8sV1alpha2Interface { return c.wgpolicyk8sV1alpha2 } @@ -48,6 +55,7 @@ func NewForConfig(c *rest.Config, m metrics.MetricsConfigManager) (versioned.Int kyvernoV1: wrappedkyvernov1.Wrap(kClientset.KyvernoV1(), m), kyvernoV1beta1: wrappedkyvernov1beta1.Wrap(kClientset.KyvernoV1beta1(), m), kyvernoV1alpha2: wrappedkyvernov1alpha2.Wrap(kClientset.KyvernoV1alpha2(), m), + kyvernoV1alpha1: wrappedkyvernov1alpha1.Wrap(kClientset.KyvernoV1alpha1(), m), wgpolicyk8sV1alpha2: wrappedwgpolicyk8sv1alpha2.Wrap(kClientset.Wgpolicyk8sV1alpha2(), m), }, nil } diff --git a/pkg/clients/wrappers/kyverno/v1alpha1/kyverno_client.go b/pkg/clients/wrappers/kyverno/v1alpha1/kyverno_client.go new file mode 100644 index 000000000000..91424af6044f --- /dev/null +++ b/pkg/clients/wrappers/kyverno/v1alpha1/kyverno_client.go @@ -0,0 +1,48 @@ +package v1alpha1 + +import ( + kyvernov1alpha1 "github.com/kyverno/kyverno/api/kyverno/v1alpha1" + "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha1" + "github.com/kyverno/kyverno/pkg/metrics" + controllerutils "github.com/kyverno/kyverno/pkg/utils/controller" + "k8s.io/client-go/rest" +) + +type client struct { + inner v1alpha1.KyvernoV1alpha1Interface + metrics metrics.MetricsConfigManager +} + +func (c *client) CleanupPolicies(namespace string) v1alpha1.CleanupPolicyInterface { + recorder := metrics.NamespacedClientQueryRecorder(c.metrics, namespace, "CleanupPolicy", metrics.KyvernoClient) + return struct { + controllerutils.ObjectClient[*kyvernov1alpha1.CleanupPolicy] + controllerutils.ListClient[*kyvernov1alpha1.CleanupPolicyList] + controllerutils.StatusClient[*kyvernov1alpha1.CleanupPolicy] + }{ + metrics.ObjectClient[*kyvernov1alpha1.CleanupPolicy](recorder, c.inner.CleanupPolicies(namespace)), + metrics.ListClient[*kyvernov1alpha1.CleanupPolicyList](recorder, c.inner.CleanupPolicies(namespace)), + metrics.StatusClient[*kyvernov1alpha1.CleanupPolicy](recorder, c.inner.CleanupPolicies(namespace)), + } +} + +func (c *client) ClusterCleanupPolicies() v1alpha1.ClusterCleanupPolicyInterface { + recorder := metrics.NamespacedClientQueryRecorder(c.metrics, "", "ClusterCleanupPolicy", metrics.KyvernoClient) + return struct { + controllerutils.ObjectClient[*kyvernov1alpha1.ClusterCleanupPolicy] + controllerutils.ListClient[*kyvernov1alpha1.ClusterCleanupPolicyList] + controllerutils.StatusClient[*kyvernov1alpha1.ClusterCleanupPolicy] + }{ + metrics.ObjectClient[*kyvernov1alpha1.ClusterCleanupPolicy](recorder, c.inner.ClusterCleanupPolicies()), + metrics.ListClient[*kyvernov1alpha1.ClusterCleanupPolicyList](recorder, c.inner.ClusterCleanupPolicies()), + metrics.StatusClient[*kyvernov1alpha1.ClusterCleanupPolicy](recorder, c.inner.ClusterCleanupPolicies()), + } +} + +func (c *client) RESTClient() rest.Interface { + return c.inner.RESTClient() +} + +func Wrap(inner v1alpha1.KyvernoV1alpha1Interface, metrics metrics.MetricsConfigManager) v1alpha1.KyvernoV1alpha1Interface { + return &client{inner, metrics} +} From 060f7bb873d3c33a4340a1937bd960ca91453b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Tue, 8 Nov 2022 10:35:08 +0100 Subject: [PATCH 32/55] refactor: admission response utils (#5234) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - refactor: admission response utils - unit tests Signed-off-by: Charles-Edouard Brétéché --- pkg/utils/admission/response.go | 30 +++++ pkg/utils/admission/response_test.go | 169 +++++++++++++++++++++++++++ pkg/utils/admission/utils.go | 75 ------------ pkg/webhooks/handlers/protect.go | 5 +- pkg/webhooks/handlers/verify.go | 4 +- pkg/webhooks/policy/handlers.go | 11 +- pkg/webhooks/resource/handlers.go | 30 ++--- pkg/webhooks/resource/utils.go | 4 +- 8 files changed, 223 insertions(+), 105 deletions(-) create mode 100644 pkg/utils/admission/response.go create mode 100644 pkg/utils/admission/response_test.go diff --git a/pkg/utils/admission/response.go b/pkg/utils/admission/response.go new file mode 100644 index 000000000000..6f0b79195ace --- /dev/null +++ b/pkg/utils/admission/response.go @@ -0,0 +1,30 @@ +package admission + +import ( + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Response(err error, warnings ...string) *admissionv1.AdmissionResponse { + response := &admissionv1.AdmissionResponse{ + Allowed: err == nil, + } + if err != nil { + response.Result = &metav1.Status{ + Status: metav1.StatusFailure, + Message: err.Error(), + } + } + response.Warnings = warnings + return response +} + +func ResponseSuccess(warnings ...string) *admissionv1.AdmissionResponse { + return Response(nil, warnings...) +} + +func MutationResponse(patch []byte, warnings ...string) *admissionv1.AdmissionResponse { + response := ResponseSuccess(warnings...) + response.Patch = patch + return response +} diff --git a/pkg/utils/admission/response_test.go b/pkg/utils/admission/response_test.go new file mode 100644 index 000000000000..ff595c72f968 --- /dev/null +++ b/pkg/utils/admission/response_test.go @@ -0,0 +1,169 @@ +package admission + +import ( + "errors" + "reflect" + "testing" + + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestResponse(t *testing.T) { + type args struct { + err error + warnings []string + } + tests := []struct { + name string + args args + want *admissionv1.AdmissionResponse + }{{ + name: "no error, no warnings", + args: args{ + err: nil, + warnings: nil, + }, + want: &admissionv1.AdmissionResponse{ + Allowed: true, + }, + }, { + name: "no error, warnings", + args: args{ + err: nil, + warnings: []string{"foo", "bar"}, + }, + want: &admissionv1.AdmissionResponse{ + Allowed: true, + Warnings: []string{"foo", "bar"}, + }, + }, { + name: "error, no warnings", + args: args{ + err: errors.New("an error has occured"), + warnings: nil, + }, + want: &admissionv1.AdmissionResponse{ + Allowed: false, + Result: &metav1.Status{ + Status: metav1.StatusFailure, + Message: "an error has occured", + }, + }, + }, { + name: "error, warnings", + args: args{ + err: errors.New("an error has occured"), + warnings: []string{"foo", "bar"}, + }, + want: &admissionv1.AdmissionResponse{ + Allowed: false, + Result: &metav1.Status{ + Status: metav1.StatusFailure, + Message: "an error has occured", + }, + Warnings: []string{"foo", "bar"}, + }, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Response(tt.args.err, tt.args.warnings...); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Response() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestResponseSuccess(t *testing.T) { + type args struct { + warnings []string + } + tests := []struct { + name string + args args + want *admissionv1.AdmissionResponse + }{{ + name: "no warnings", + args: args{ + warnings: nil, + }, + want: &admissionv1.AdmissionResponse{ + Allowed: true, + }, + }, { + name: "warnings", + args: args{ + warnings: []string{"foo", "bar"}, + }, + want: &admissionv1.AdmissionResponse{ + Allowed: true, + Warnings: []string{"foo", "bar"}, + }, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ResponseSuccess(tt.args.warnings...); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ResponseSuccess() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestMutationResponse(t *testing.T) { + type args struct { + patch []byte + warnings []string + } + tests := []struct { + name string + args args + want *admissionv1.AdmissionResponse + }{{ + name: "no patch, no warnings", + args: args{ + patch: nil, + warnings: nil, + }, + want: &admissionv1.AdmissionResponse{ + Allowed: true, + }, + }, { + name: "no patch, warnings", + args: args{ + patch: nil, + warnings: []string{"foo", "bar"}, + }, + want: &admissionv1.AdmissionResponse{ + Allowed: true, + Warnings: []string{"foo", "bar"}, + }, + }, { + name: "patch, no warnings", + args: args{ + patch: []byte{1, 2, 3, 4}, + warnings: nil, + }, + want: &admissionv1.AdmissionResponse{ + Allowed: true, + Patch: []byte{1, 2, 3, 4}, + }, + }, { + name: "patch, warnings", + args: args{ + patch: []byte{1, 2, 3, 4}, + warnings: []string{"foo", "bar"}, + }, + want: &admissionv1.AdmissionResponse{ + Allowed: true, + Patch: []byte{1, 2, 3, 4}, + Warnings: []string{"foo", "bar"}, + }, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := MutationResponse(tt.args.patch, tt.args.warnings...); !reflect.DeepEqual(got, tt.want) { + t.Errorf("MutationResponse() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/utils/admission/utils.go b/pkg/utils/admission/utils.go index a4ac9d62bd64..f2a3e8f81b0c 100644 --- a/pkg/utils/admission/utils.go +++ b/pkg/utils/admission/utils.go @@ -6,7 +6,6 @@ import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" admissionv1 "k8s.io/api/admission/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func UnmarshalPolicy(kind string, raw []byte) (kyvernov1.PolicyInterface, error) { @@ -42,68 +41,6 @@ func GetPolicies(request *admissionv1.AdmissionRequest) (kyvernov1.PolicyInterfa return policy, nil, nil } -func Response(allowed bool) *admissionv1.AdmissionResponse { - r := &admissionv1.AdmissionResponse{ - Allowed: allowed, - } - return r -} - -func ResponseWithMessage(allowed bool, msg string) *admissionv1.AdmissionResponse { - r := Response(allowed) - r.Result = &metav1.Status{ - Message: msg, - } - return r -} - -func ResponseWithMessageAndPatch(allowed bool, msg string, patch []byte) *admissionv1.AdmissionResponse { - r := ResponseWithMessage(allowed, msg) - r.Patch = patch - return r -} - -func ResponseStatus(allowed bool, status, msg string) *admissionv1.AdmissionResponse { - r := Response(allowed) - r.Result = &metav1.Status{ - Status: status, - Message: msg, - } - return r -} - -func ResponseFailure(msg string) *admissionv1.AdmissionResponse { - return ResponseStatus(false, metav1.StatusFailure, msg) -} - -func ResponseSuccess() *admissionv1.AdmissionResponse { - return Response(true) -} - -func ResponseSuccessWithWarnings(warnings []string) *admissionv1.AdmissionResponse { - r := Response(true) - r.Warnings = warnings - return r -} - -func ResponseSuccessWithPatch(patch []byte) *admissionv1.AdmissionResponse { - r := Response(true) - if len(patch) > 0 { - r.Patch = patch - } - return r -} - -func ResponseSuccessWithPatchAndWarnings(patch []byte, warnings []string) *admissionv1.AdmissionResponse { - r := Response(true) - if len(patch) > 0 { - r.Patch = patch - } - - r.Warnings = warnings - return r -} - func GetResourceName(request *admissionv1.AdmissionRequest) string { resourceName := request.Kind.Kind + "/" + request.Name if request.Namespace != "" { @@ -111,15 +48,3 @@ func GetResourceName(request *admissionv1.AdmissionRequest) string { } return resourceName } - -func ValidationResponse(err error, warnings ...string) *admissionv1.AdmissionResponse { - response := Response(err == nil) - if err != nil { - response.Result = &metav1.Status{ - Status: metav1.StatusFailure, - Message: err.Error(), - } - } - response.Warnings = warnings - return response -} diff --git a/pkg/webhooks/handlers/protect.go b/pkg/webhooks/handlers/protect.go index c927aac423a6..2c0b7aef2353 100644 --- a/pkg/webhooks/handlers/protect.go +++ b/pkg/webhooks/handlers/protect.go @@ -1,6 +1,7 @@ package handlers import ( + "errors" "fmt" "time" @@ -18,14 +19,14 @@ func Protect(inner AdmissionHandler) AdmissionHandler { newResource, oldResource, err := utils.ExtractResources(nil, request) if err != nil { logger.Error(err, "Failed to extract resources") - return admissionutils.ResponseFailure(err.Error()) + return admissionutils.Response(err) } for _, resource := range []unstructured.Unstructured{newResource, oldResource} { resLabels := resource.GetLabels() if resLabels[kyvernov1.LabelAppManagedBy] == kyvernov1.ValueKyvernoApp { if request.UserInfo.Username != fmt.Sprintf("system:serviceaccount:%s:%s", config.KyvernoNamespace(), config.KyvernoServiceAccountName()) { logger.Info("Access to the resource not authorized, this is a kyverno managed resource and should be altered only by kyverno") - return admissionutils.ResponseFailure("A kyverno managed resource can only be modified by kyverno") + return admissionutils.Response(errors.New("A kyverno managed resource can only be modified by kyverno")) } } } diff --git a/pkg/webhooks/handlers/verify.go b/pkg/webhooks/handlers/verify.go index 67bca2304708..0738e871ad85 100644 --- a/pkg/webhooks/handlers/verify.go +++ b/pkg/webhooks/handlers/verify.go @@ -19,8 +19,8 @@ func Verify() AdmissionHandler { bytes, err := patch.ToPatchBytes() if err != nil { logger.Error(err, "failed to build patch bytes") - return admissionutils.ResponseFailure(err.Error()) + return admissionutils.Response(err) } - return admissionutils.ResponseSuccessWithPatch(bytes) + return admissionutils.MutationResponse(bytes) } } diff --git a/pkg/webhooks/policy/handlers.go b/pkg/webhooks/policy/handlers.go index dfbfc3291587..79f058598a0f 100644 --- a/pkg/webhooks/policy/handlers.go +++ b/pkg/webhooks/policy/handlers.go @@ -1,7 +1,6 @@ package policy import ( - "fmt" "time" "github.com/go-logr/logr" @@ -28,21 +27,21 @@ func NewHandlers(client dclient.Interface, openApiManager openapi.Manager) webho func (h *handlers) Validate(logger logr.Logger, request *admissionv1.AdmissionRequest, _ time.Time) *admissionv1.AdmissionResponse { if request.SubResource != "" { logger.V(4).Info("skip policy validation on status update") - return admissionutils.Response(true) + return admissionutils.ResponseSuccess() } policy, _, err := admissionutils.GetPolicies(request) if err != nil { logger.Error(err, "failed to unmarshal policies from admission request") - return admissionutils.ResponseWithMessage(true, fmt.Sprintf("failed to validate policy, check kyverno controller logs for details: %v", err)) + return admissionutils.Response(err) } warnings, err := policyvalidate.Validate(policy, h.client, false, h.openApiManager) if err != nil { logger.Error(err, "policy validation errors") - return admissionutils.ResponseWithMessage(false, err.Error()) + return admissionutils.Response(err) } - return admissionutils.ValidationResponse(err, warnings...) + return admissionutils.Response(err, warnings...) } func (h *handlers) Mutate(logger logr.Logger, request *admissionv1.AdmissionRequest, _ time.Time) *admissionv1.AdmissionResponse { - return admissionutils.Response(true) + return admissionutils.ResponseSuccess() } diff --git a/pkg/webhooks/resource/handlers.go b/pkg/webhooks/resource/handlers.go index daf7970d9d6c..09481ff4716c 100644 --- a/pkg/webhooks/resource/handlers.go +++ b/pkg/webhooks/resource/handlers.go @@ -1,6 +1,7 @@ package resource import ( + "errors" "time" "github.com/go-logr/logr" @@ -133,18 +134,13 @@ func (h *handlers) Validate(logger logr.Logger, request *admissionv1.AdmissionRe ok, msg, warnings := vh.HandleValidation(h.metricsConfig, request, policies, policyContext, namespaceLabels, startTime) if !ok { logger.Info("admission request denied") - return admissionutils.ResponseFailure(msg) + return admissionutils.Response(errors.New(msg)) } defer h.handleDelete(logger, request) go h.createUpdateRequests(logger, request, policyContext, generatePolicies, mutatePolicies, startTime) - if warnings != nil { - return admissionutils.ResponseSuccessWithWarnings(warnings) - } - - logger.V(4).Info("completed validating webhook") - return admissionutils.ResponseSuccess() + return admissionutils.Response(nil, warnings...) } func (h *handlers) Mutate(logger logr.Logger, request *admissionv1.AdmissionRequest, failurePolicy string, startTime time.Time) *admissionv1.AdmissionResponse { @@ -167,7 +163,7 @@ func (h *handlers) Mutate(logger logr.Logger, request *admissionv1.AdmissionRequ policyContext, err := h.pcBuilder.Build(request, mutatePolicies...) if err != nil { logger.Error(err, "failed to build policy context") - return admissionutils.ResponseFailure(err.Error()) + return admissionutils.Response(err) } // update container images to a canonical form if err := enginectx.MutateResourceWithImageInfo(request.Object.Raw, policyContext.JSONContext); err != nil { @@ -177,30 +173,26 @@ func (h *handlers) Mutate(logger logr.Logger, request *admissionv1.AdmissionRequ mutatePatches, mutateWarnings, err := mh.HandleMutation(h.metricsConfig, request, mutatePolicies, policyContext, startTime) if err != nil { logger.Error(err, "mutation failed") - return admissionutils.ResponseFailure(err.Error()) + return admissionutils.Response(err) } newRequest := patchRequest(mutatePatches, request, logger) // rebuild context to process images updated via mutate policies policyContext, err = h.pcBuilder.Build(newRequest, mutatePolicies...) if err != nil { logger.Error(err, "failed to build policy context") - return admissionutils.ResponseFailure(err.Error()) + return admissionutils.Response(err) } ivh := imageverification.NewImageVerificationHandler(logger, h.kyvernoClient, h.eventGen, h.admissionReports) imagePatches, imageVerifyWarnings, err := ivh.Handle(h.metricsConfig, newRequest, verifyImagesPolicies, policyContext) if err != nil { logger.Error(err, "image verification failed") - return admissionutils.ResponseFailure(err.Error()) + return admissionutils.Response(err) } patch := jsonutils.JoinPatches(mutatePatches, imagePatches) - if len(mutateWarnings) > 0 || len(imageVerifyWarnings) > 0 { - warnings := append(mutateWarnings, imageVerifyWarnings...) - logger.V(2).Info("mutation webhook", "warnings", warnings) - return admissionutils.ResponseSuccessWithPatchAndWarnings(patch, warnings) - } - admissionResponse := admissionutils.ResponseSuccessWithPatch(patch) - logger.V(4).Info("completed mutating webhook", "response", admissionResponse) - return admissionResponse + var warnings []string + warnings = append(warnings, mutateWarnings...) + warnings = append(warnings, imageVerifyWarnings...) + return admissionutils.MutationResponse(patch, warnings...) } func (h *handlers) handleDelete(logger logr.Logger, request *admissionv1.AdmissionRequest) { diff --git a/pkg/webhooks/resource/utils.go b/pkg/webhooks/resource/utils.go index 10daa5be4bfa..62579fe0764d 100644 --- a/pkg/webhooks/resource/utils.go +++ b/pkg/webhooks/resource/utils.go @@ -1,6 +1,8 @@ package resource import ( + "errors" + "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" @@ -18,7 +20,7 @@ type updateRequestResponse struct { func errorResponse(logger logr.Logger, err error, message string) *admissionv1.AdmissionResponse { logger.Error(err, message) - return admissionutils.ResponseFailure(message + ": " + err.Error()) + return admissionutils.Response(errors.New(message + ": " + err.Error())) } func patchRequest(patches []byte, request *admissionv1.AdmissionRequest, logger logr.Logger) *admissionv1.AdmissionRequest { From b71c0004d0d15a30a1df6bbf939bda73c73a0905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Tue, 8 Nov 2022 12:36:13 +0100 Subject: [PATCH 33/55] fix: account for error rules in mutation webhook (#5264) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: account for error rules in mutation webhook Signed-off-by: Charles-Edouard Brétéché * add test Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- pkg/engine/response/response.go | 8 ++--- pkg/webhooks/resource/mutation/mutation.go | 2 +- .../kuttl/issues/5136/01-assert.yaml | 9 ++++++ .../kuttl/issues/5136/01-manifests.yaml | 29 +++++++++++++++++++ .../kuttl/issues/5136/02-script.yaml | 14 +++++++++ .../kuttl/issues/5136/03-errors.yaml | 4 +++ .../kuttl/issues/5136/04-manifests.yaml | 29 +++++++++++++++++++ .../kuttl/issues/5136/05-assert.yaml | 7 +++++ .../conformance/kuttl/issues/5136/05-pod.yaml | 10 +++++++ .../kuttl/issues/5136/99-cleanup.yaml | 4 +++ .../kuttl/issues/5136/resource.yaml | 10 +++++++ 11 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 test/conformance/kuttl/issues/5136/01-assert.yaml create mode 100644 test/conformance/kuttl/issues/5136/01-manifests.yaml create mode 100644 test/conformance/kuttl/issues/5136/02-script.yaml create mode 100644 test/conformance/kuttl/issues/5136/03-errors.yaml create mode 100644 test/conformance/kuttl/issues/5136/04-manifests.yaml create mode 100644 test/conformance/kuttl/issues/5136/05-assert.yaml create mode 100644 test/conformance/kuttl/issues/5136/05-pod.yaml create mode 100644 test/conformance/kuttl/issues/5136/99-cleanup.yaml create mode 100644 test/conformance/kuttl/issues/5136/resource.yaml diff --git a/pkg/engine/response/response.go b/pkg/engine/response/response.go index d3c83cb5b7b4..22cb77c1f5f9 100644 --- a/pkg/engine/response/response.go +++ b/pkg/engine/response/response.go @@ -196,12 +196,12 @@ func (er EngineResponse) GetPatches() [][]byte { // GetFailedRules returns failed rules func (er EngineResponse) GetFailedRules() []string { - return er.getRules(RuleStatusFail) + return er.getRules(func(status RuleStatus) bool { return status == RuleStatusFail || status == RuleStatusError }) } // GetSuccessRules returns success rules func (er EngineResponse) GetSuccessRules() []string { - return er.getRules(RuleStatusPass) + return er.getRules(func(status RuleStatus) bool { return status == RuleStatusPass }) } // GetResourceSpec returns resourceSpec of er @@ -215,10 +215,10 @@ func (er EngineResponse) GetResourceSpec() ResourceSpec { } } -func (er EngineResponse) getRules(status RuleStatus) []string { +func (er EngineResponse) getRules(predicate func(RuleStatus) bool) []string { var rules []string for _, r := range er.PolicyResponse.Rules { - if r.Status == status { + if predicate(r.Status) { rules = append(rules, r.Name) } } diff --git a/pkg/webhooks/resource/mutation/mutation.go b/pkg/webhooks/resource/mutation/mutation.go index 65a382bc6081..bebdc562571d 100644 --- a/pkg/webhooks/resource/mutation/mutation.go +++ b/pkg/webhooks/resource/mutation/mutation.go @@ -152,7 +152,7 @@ func (h *mutationHandler) applyMutation(request *admissionv1.AdmissionRequest, p engineResponse := engine.Mutate(policyContext) policyPatches := engineResponse.GetPatches() - if !engineResponse.IsSuccessful() && len(engineResponse.GetFailedRules()) > 0 { + if !engineResponse.IsSuccessful() { return nil, nil, fmt.Errorf("failed to apply policy %s rules %v", policyContext.Policy.GetName(), engineResponse.GetFailedRules()) } diff --git a/test/conformance/kuttl/issues/5136/01-assert.yaml b/test/conformance/kuttl/issues/5136/01-assert.yaml new file mode 100644 index 000000000000..8150b81d4c76 --- /dev/null +++ b/test/conformance/kuttl/issues/5136/01-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: propagate-cost-labels-from-namespace +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/issues/5136/01-manifests.yaml b/test/conformance/kuttl/issues/5136/01-manifests.yaml new file mode 100644 index 000000000000..ec2377eb57ab --- /dev/null +++ b/test/conformance/kuttl/issues/5136/01-manifests.yaml @@ -0,0 +1,29 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: propagate-cost-labels-from-namespace +spec: + failurePolicy: Ignore + rules: + - name: add-cost-labels + context: + - name: namespaceLabels + apiCall: + urlPath: "/api/v1/namespaces/{{request.namespace}}" + jmesPath: metadata.labels + match: + any: + - resources: + kinds: + - Pod + - Deployment + - StatefulSet + - DaemonSet + - Job + - CronJob + mutate: + patchStrategicMerge: + metadata: + labels: + cost.starfleet.evtech/project: "{{namespaceLabels.\"cost.starfleet.evtech/project\"}}" + cost.starfleet.evtech/application: "{{request.object.metadata.labels.\"cost.starfleet.evtech/application\" || namespaceLabels.\"cost.starfleet.evtech/application\"}}" diff --git a/test/conformance/kuttl/issues/5136/02-script.yaml b/test/conformance/kuttl/issues/5136/02-script.yaml new file mode 100644 index 000000000000..f5eac058ed9e --- /dev/null +++ b/test/conformance/kuttl/issues/5136/02-script.yaml @@ -0,0 +1,14 @@ +## Checks that the manifests.yaml file CANNOT be successfully created. If it can, fail the test as this is incorrect. + +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: +- script: | + if kubectl apply -f resource.yaml + then + echo "Tested failed. Resource was allowed." + exit 1 + else + echo "Test succeeded. Resource was blocked." + exit 0 + fi diff --git a/test/conformance/kuttl/issues/5136/03-errors.yaml b/test/conformance/kuttl/issues/5136/03-errors.yaml new file mode 100644 index 000000000000..d321f81e984c --- /dev/null +++ b/test/conformance/kuttl/issues/5136/03-errors.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Pod +metadata: + name: webserver diff --git a/test/conformance/kuttl/issues/5136/04-manifests.yaml b/test/conformance/kuttl/issues/5136/04-manifests.yaml new file mode 100644 index 000000000000..80983ca4e376 --- /dev/null +++ b/test/conformance/kuttl/issues/5136/04-manifests.yaml @@ -0,0 +1,29 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: propagate-cost-labels-from-namespace +spec: + failurePolicy: Ignore + rules: + - name: add-cost-labels + context: + - name: namespaceLabels + apiCall: + urlPath: "/api/v1/namespaces/{{request.namespace}}" + jmesPath: metadata.labels + match: + any: + - resources: + kinds: + - Pod + - Deployment + - StatefulSet + - DaemonSet + - Job + - CronJob + mutate: + patchStrategicMerge: + metadata: + labels: + cost.starfleet.evtech/project: "{{namespaceLabels.\"cost.starfleet.evtech/project\" || 'empty'}}" + cost.starfleet.evtech/application: "{{request.object.metadata.labels.\"cost.starfleet.evtech/application\" || namespaceLabels.\"cost.starfleet.evtech/application\" || 'empty'}}" diff --git a/test/conformance/kuttl/issues/5136/05-assert.yaml b/test/conformance/kuttl/issues/5136/05-assert.yaml new file mode 100644 index 000000000000..067b6d0ef6b6 --- /dev/null +++ b/test/conformance/kuttl/issues/5136/05-assert.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Pod +metadata: + name: webserver + labels: + cost.starfleet.evtech/project: empty + cost.starfleet.evtech/application: empty diff --git a/test/conformance/kuttl/issues/5136/05-pod.yaml b/test/conformance/kuttl/issues/5136/05-pod.yaml new file mode 100644 index 000000000000..e3c498af49fd --- /dev/null +++ b/test/conformance/kuttl/issues/5136/05-pod.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: webserver +spec: + containers: + - name: webserver + image: nginx:latest + ports: + - containerPort: 80 diff --git a/test/conformance/kuttl/issues/5136/99-cleanup.yaml b/test/conformance/kuttl/issues/5136/99-cleanup.yaml new file mode 100644 index 000000000000..c55a443a093c --- /dev/null +++ b/test/conformance/kuttl/issues/5136/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml,resource.yaml,05-pod.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/issues/5136/resource.yaml b/test/conformance/kuttl/issues/5136/resource.yaml new file mode 100644 index 000000000000..e3c498af49fd --- /dev/null +++ b/test/conformance/kuttl/issues/5136/resource.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: webserver +spec: + containers: + - name: webserver + image: nginx:latest + ports: + - containerPort: 80 From 78fb926862b22d76438cf3017832d769b4704ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Tue, 8 Nov 2022 15:27:49 +0100 Subject: [PATCH 34/55] fix: add missing test suite to kuttl (#5268) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: add missing test suite to kuttl Signed-off-by: Charles-Edouard Brétéché * fix path Signed-off-by: Charles-Edouard Brétéché * readme Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- test/conformance/kuttl/kuttl-test.yaml | 13 +++++++------ .../defaulting-namespace-labels}/01-assert.yaml | 0 .../defaulting-namespace-labels}/01-manifests.yaml | 0 .../defaulting-namespace-labels}/02-script.yaml | 0 .../defaulting-namespace-labels}/03-errors.yaml | 0 .../defaulting-namespace-labels}/04-manifests.yaml | 0 .../defaulting-namespace-labels}/05-assert.yaml | 0 .../defaulting-namespace-labels}/05-pod.yaml | 0 .../defaulting-namespace-labels}/99-cleanup.yaml | 0 .../defaulting-namespace-labels/README.md | 13 +++++++++++++ .../defaulting-namespace-labels}/resource.yaml | 0 11 files changed, 20 insertions(+), 6 deletions(-) rename test/conformance/kuttl/{issues/5136 => mutate/clusterpolicy/cornercases/defaulting-namespace-labels}/01-assert.yaml (100%) rename test/conformance/kuttl/{issues/5136 => mutate/clusterpolicy/cornercases/defaulting-namespace-labels}/01-manifests.yaml (100%) rename test/conformance/kuttl/{issues/5136 => mutate/clusterpolicy/cornercases/defaulting-namespace-labels}/02-script.yaml (100%) rename test/conformance/kuttl/{issues/5136 => mutate/clusterpolicy/cornercases/defaulting-namespace-labels}/03-errors.yaml (100%) rename test/conformance/kuttl/{issues/5136 => mutate/clusterpolicy/cornercases/defaulting-namespace-labels}/04-manifests.yaml (100%) rename test/conformance/kuttl/{issues/5136 => mutate/clusterpolicy/cornercases/defaulting-namespace-labels}/05-assert.yaml (100%) rename test/conformance/kuttl/{issues/5136 => mutate/clusterpolicy/cornercases/defaulting-namespace-labels}/05-pod.yaml (100%) rename test/conformance/kuttl/{issues/5136 => mutate/clusterpolicy/cornercases/defaulting-namespace-labels}/99-cleanup.yaml (100%) create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/README.md rename test/conformance/kuttl/{issues/5136 => mutate/clusterpolicy/cornercases/defaulting-namespace-labels}/resource.yaml (100%) diff --git a/test/conformance/kuttl/kuttl-test.yaml b/test/conformance/kuttl/kuttl-test.yaml index acd3a798229f..f88eaa277680 100644 --- a/test/conformance/kuttl/kuttl-test.yaml +++ b/test/conformance/kuttl/kuttl-test.yaml @@ -1,24 +1,25 @@ apiVersion: kuttl.dev/v1beta1 kind: TestSuite testDirs: - # Generate tests +# Generate tests # - ./test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync - ./test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync - ./test/conformance/kuttl/generate/clusterpolicy/standard/data/sync - ./test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync - ./test/conformance/kuttl/generate/clusterpolicy/cornercases - # Mutate tests +# Mutate tests - ./test/conformance/kuttl/mutate/clusterpolicy/standard - ./test/conformance/kuttl/mutate/clusterpolicy/standard/existing - # Validate tests +- ./test/conformance/kuttl/mutate/clusterpolicy/cornercases +# Validate tests - ./test/conformance/kuttl/validate/clusterpolicy/standard/audit - ./test/conformance/kuttl/validate/clusterpolicy/standard/enforce - ./test/conformance/kuttl/validate/clusterpolicy/cornercases - # verifyImages tests +# Verify image tests - ./test/conformance/kuttl/verifyImages/clusterpolicy/standard - # Report tests +# Report tests - ./test/conformance/kuttl/reports/admission - ./test/conformance/kuttl/reports/background startKIND: false # timeout: 15 -parallel: 1 \ No newline at end of file +parallel: 1 diff --git a/test/conformance/kuttl/issues/5136/01-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/01-assert.yaml similarity index 100% rename from test/conformance/kuttl/issues/5136/01-assert.yaml rename to test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/01-assert.yaml diff --git a/test/conformance/kuttl/issues/5136/01-manifests.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/01-manifests.yaml similarity index 100% rename from test/conformance/kuttl/issues/5136/01-manifests.yaml rename to test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/01-manifests.yaml diff --git a/test/conformance/kuttl/issues/5136/02-script.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/02-script.yaml similarity index 100% rename from test/conformance/kuttl/issues/5136/02-script.yaml rename to test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/02-script.yaml diff --git a/test/conformance/kuttl/issues/5136/03-errors.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/03-errors.yaml similarity index 100% rename from test/conformance/kuttl/issues/5136/03-errors.yaml rename to test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/03-errors.yaml diff --git a/test/conformance/kuttl/issues/5136/04-manifests.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/04-manifests.yaml similarity index 100% rename from test/conformance/kuttl/issues/5136/04-manifests.yaml rename to test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/04-manifests.yaml diff --git a/test/conformance/kuttl/issues/5136/05-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/05-assert.yaml similarity index 100% rename from test/conformance/kuttl/issues/5136/05-assert.yaml rename to test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/05-assert.yaml diff --git a/test/conformance/kuttl/issues/5136/05-pod.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/05-pod.yaml similarity index 100% rename from test/conformance/kuttl/issues/5136/05-pod.yaml rename to test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/05-pod.yaml diff --git a/test/conformance/kuttl/issues/5136/99-cleanup.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/99-cleanup.yaml similarity index 100% rename from test/conformance/kuttl/issues/5136/99-cleanup.yaml rename to test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/99-cleanup.yaml diff --git a/test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/README.md b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/README.md new file mode 100644 index 000000000000..6d5d9f3cca33 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/README.md @@ -0,0 +1,13 @@ +## Description + +This tests checks that if namespace labels used in a policy are not present the resource is NOT created. +If the expected labels are defaulted in the policy the resource creation should work fine. + +## Expected Behavior + +The first part of the test checks that the resource fails to create if namespace labels are not present. +Then the policy is updated to use default values when namespace labels are missing, then the resource should be created without issue. + +## Reference Issue(s) + +5136 diff --git a/test/conformance/kuttl/issues/5136/resource.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/resource.yaml similarity index 100% rename from test/conformance/kuttl/issues/5136/resource.yaml rename to test/conformance/kuttl/mutate/clusterpolicy/cornercases/defaulting-namespace-labels/resource.yaml From 0baf496659aa58f50e7b1201feb9cb0ce4e204f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Tue, 8 Nov 2022 16:05:49 +0100 Subject: [PATCH 35/55] chore: add kuttl autogen tests (#5253) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché --- .../deployment-statefulset-job/01-assert.yaml | 66 +++++++++++++ .../01-manifests.yaml | 31 ++++++ .../deployment-statefulset-job/02-errors.yaml | 92 +++++++++++++++++ .../99-cleanup.yaml | 4 + .../deployment-statefulset-job/README.md | 7 ++ .../kuttl/autogen/none/01-assert.yaml | 35 +++++++ .../kuttl/autogen/none/01-manifests.yaml | 31 ++++++ .../kuttl/autogen/none/02-errors.yaml | 98 +++++++++++++++++++ .../kuttl/autogen/none/99-cleanup.yaml | 4 + test/conformance/kuttl/autogen/none/README.md | 7 ++ .../kuttl/autogen/only-cronjob/01-assert.yaml | 66 +++++++++++++ .../autogen/only-cronjob/01-manifests.yaml | 31 ++++++ .../kuttl/autogen/only-cronjob/02-errors.yaml | 98 +++++++++++++++++++ .../autogen/only-cronjob/99-cleanup.yaml | 4 + .../kuttl/autogen/only-cronjob/README.md | 7 ++ .../autogen/only-deployment/01-assert.yaml | 62 ++++++++++++ .../autogen/only-deployment/01-manifests.yaml | 31 ++++++ .../autogen/only-deployment/02-errors.yaml | 98 +++++++++++++++++++ .../autogen/only-deployment/99-cleanup.yaml | 4 + .../kuttl/autogen/only-deployment/README.md | 7 ++ .../autogen/should-autogen/01-assert.yaml | 98 +++++++++++++++++++ .../autogen/should-autogen/01-manifests.yaml | 29 ++++++ .../autogen/should-autogen/99-cleanup.yaml | 4 + .../kuttl/autogen/should-autogen/README.md | 7 ++ .../autogen/should-not-autogen/01-assert.yaml | 36 +++++++ .../should-not-autogen/01-manifests.yaml | 30 ++++++ .../autogen/should-not-autogen/02-errors.yaml | 98 +++++++++++++++++++ .../should-not-autogen/99-cleanup.yaml | 4 + .../autogen/should-not-autogen/README.md | 7 ++ test/conformance/kuttl/kuttl-test.yaml | 2 + 30 files changed, 1098 insertions(+) create mode 100644 test/conformance/kuttl/autogen/deployment-statefulset-job/01-assert.yaml create mode 100644 test/conformance/kuttl/autogen/deployment-statefulset-job/01-manifests.yaml create mode 100644 test/conformance/kuttl/autogen/deployment-statefulset-job/02-errors.yaml create mode 100644 test/conformance/kuttl/autogen/deployment-statefulset-job/99-cleanup.yaml create mode 100644 test/conformance/kuttl/autogen/deployment-statefulset-job/README.md create mode 100644 test/conformance/kuttl/autogen/none/01-assert.yaml create mode 100644 test/conformance/kuttl/autogen/none/01-manifests.yaml create mode 100644 test/conformance/kuttl/autogen/none/02-errors.yaml create mode 100644 test/conformance/kuttl/autogen/none/99-cleanup.yaml create mode 100644 test/conformance/kuttl/autogen/none/README.md create mode 100644 test/conformance/kuttl/autogen/only-cronjob/01-assert.yaml create mode 100644 test/conformance/kuttl/autogen/only-cronjob/01-manifests.yaml create mode 100644 test/conformance/kuttl/autogen/only-cronjob/02-errors.yaml create mode 100644 test/conformance/kuttl/autogen/only-cronjob/99-cleanup.yaml create mode 100644 test/conformance/kuttl/autogen/only-cronjob/README.md create mode 100644 test/conformance/kuttl/autogen/only-deployment/01-assert.yaml create mode 100644 test/conformance/kuttl/autogen/only-deployment/01-manifests.yaml create mode 100644 test/conformance/kuttl/autogen/only-deployment/02-errors.yaml create mode 100644 test/conformance/kuttl/autogen/only-deployment/99-cleanup.yaml create mode 100644 test/conformance/kuttl/autogen/only-deployment/README.md create mode 100644 test/conformance/kuttl/autogen/should-autogen/01-assert.yaml create mode 100644 test/conformance/kuttl/autogen/should-autogen/01-manifests.yaml create mode 100644 test/conformance/kuttl/autogen/should-autogen/99-cleanup.yaml create mode 100644 test/conformance/kuttl/autogen/should-autogen/README.md create mode 100644 test/conformance/kuttl/autogen/should-not-autogen/01-assert.yaml create mode 100644 test/conformance/kuttl/autogen/should-not-autogen/01-manifests.yaml create mode 100644 test/conformance/kuttl/autogen/should-not-autogen/02-errors.yaml create mode 100644 test/conformance/kuttl/autogen/should-not-autogen/99-cleanup.yaml create mode 100644 test/conformance/kuttl/autogen/should-not-autogen/README.md diff --git a/test/conformance/kuttl/autogen/deployment-statefulset-job/01-assert.yaml b/test/conformance/kuttl/autogen/deployment-statefulset-job/01-assert.yaml new file mode 100644 index 000000000000..d77c7c27d04d --- /dev/null +++ b/test/conformance/kuttl/autogen/deployment-statefulset-job/01-assert.yaml @@ -0,0 +1,66 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + autogen: + rules: + - match: + resources: + kinds: + - Deployment + - StatefulSet + - Job + name: autogen-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Deployment + - StatefulSet + - Job + name: autogen-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + template: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/deployment-statefulset-job/01-manifests.yaml b/test/conformance/kuttl/autogen/deployment-statefulset-job/01-manifests.yaml new file mode 100644 index 000000000000..b4eee88cae05 --- /dev/null +++ b/test/conformance/kuttl/autogen/deployment-statefulset-job/01-manifests.yaml @@ -0,0 +1,31 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag + annotations: + pod-policies.kyverno.io/autogen-controllers: Deployment,StatefulSet,Job +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/deployment-statefulset-job/02-errors.yaml b/test/conformance/kuttl/autogen/deployment-statefulset-job/02-errors.yaml new file mode 100644 index 000000000000..716a335e1b88 --- /dev/null +++ b/test/conformance/kuttl/autogen/deployment-statefulset-job/02-errors.yaml @@ -0,0 +1,92 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + autogen: + rules: + - match: + resources: + kinds: + - DaemonSet + name: autogen-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - DaemonSet + name: autogen-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + template: + spec: + containers: + - image: '!*:latest' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/deployment-statefulset-job/99-cleanup.yaml b/test/conformance/kuttl/autogen/deployment-statefulset-job/99-cleanup.yaml new file mode 100644 index 000000000000..15c3c4905153 --- /dev/null +++ b/test/conformance/kuttl/autogen/deployment-statefulset-job/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/autogen/deployment-statefulset-job/README.md b/test/conformance/kuttl/autogen/deployment-statefulset-job/README.md new file mode 100644 index 000000000000..3a78e08db0cd --- /dev/null +++ b/test/conformance/kuttl/autogen/deployment-statefulset-job/README.md @@ -0,0 +1,7 @@ +## Description + +The policy should contain autogen rules for deployments, statefulsets and jobs because it has the `pod-policies.kyverno.io/autogen-controllers: Deployment,StatefulSet,Job` annotation. + +## Expected Behavior + +The policy gets created and contains autogen rules for deployments, statefulsets and jobs in the status. diff --git a/test/conformance/kuttl/autogen/none/01-assert.yaml b/test/conformance/kuttl/autogen/none/01-assert.yaml new file mode 100644 index 000000000000..d086f07da7b0 --- /dev/null +++ b/test/conformance/kuttl/autogen/none/01-assert.yaml @@ -0,0 +1,35 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + autogen: {} diff --git a/test/conformance/kuttl/autogen/none/01-manifests.yaml b/test/conformance/kuttl/autogen/none/01-manifests.yaml new file mode 100644 index 000000000000..cccf64655a7b --- /dev/null +++ b/test/conformance/kuttl/autogen/none/01-manifests.yaml @@ -0,0 +1,31 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag + annotations: + pod-policies.kyverno.io/autogen-controllers: none +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/none/02-errors.yaml b/test/conformance/kuttl/autogen/none/02-errors.yaml new file mode 100644 index 000000000000..ebcf018dd5f1 --- /dev/null +++ b/test/conformance/kuttl/autogen/none/02-errors.yaml @@ -0,0 +1,98 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + autogen: + rules: + - match: + resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + name: autogen-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + name: autogen-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + template: + spec: + containers: + - image: '!*:latest' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/none/99-cleanup.yaml b/test/conformance/kuttl/autogen/none/99-cleanup.yaml new file mode 100644 index 000000000000..15c3c4905153 --- /dev/null +++ b/test/conformance/kuttl/autogen/none/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/autogen/none/README.md b/test/conformance/kuttl/autogen/none/README.md new file mode 100644 index 000000000000..b7c8e1c1badc --- /dev/null +++ b/test/conformance/kuttl/autogen/none/README.md @@ -0,0 +1,7 @@ +## Description + +The policy should contain no autogen rules because it has the `pod-policies.kyverno.io/autogen-controllers: none` annotation. + +## Expected Behavior + +The policy gets created and have no autogen rules recorded in the status. diff --git a/test/conformance/kuttl/autogen/only-cronjob/01-assert.yaml b/test/conformance/kuttl/autogen/only-cronjob/01-assert.yaml new file mode 100644 index 000000000000..28eac2520df2 --- /dev/null +++ b/test/conformance/kuttl/autogen/only-cronjob/01-assert.yaml @@ -0,0 +1,66 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + autogen: + rules: + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/only-cronjob/01-manifests.yaml b/test/conformance/kuttl/autogen/only-cronjob/01-manifests.yaml new file mode 100644 index 000000000000..47cdc47fa45c --- /dev/null +++ b/test/conformance/kuttl/autogen/only-cronjob/01-manifests.yaml @@ -0,0 +1,31 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag + annotations: + pod-policies.kyverno.io/autogen-controllers: CronJob +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/only-cronjob/02-errors.yaml b/test/conformance/kuttl/autogen/only-cronjob/02-errors.yaml new file mode 100644 index 000000000000..ebcf018dd5f1 --- /dev/null +++ b/test/conformance/kuttl/autogen/only-cronjob/02-errors.yaml @@ -0,0 +1,98 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + autogen: + rules: + - match: + resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + name: autogen-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + name: autogen-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + template: + spec: + containers: + - image: '!*:latest' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/only-cronjob/99-cleanup.yaml b/test/conformance/kuttl/autogen/only-cronjob/99-cleanup.yaml new file mode 100644 index 000000000000..15c3c4905153 --- /dev/null +++ b/test/conformance/kuttl/autogen/only-cronjob/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/autogen/only-cronjob/README.md b/test/conformance/kuttl/autogen/only-cronjob/README.md new file mode 100644 index 000000000000..31f14a054bd7 --- /dev/null +++ b/test/conformance/kuttl/autogen/only-cronjob/README.md @@ -0,0 +1,7 @@ +## Description + +The policy should contain a single autogen rule for cronjobs because it has the `pod-policies.kyverno.io/autogen-controllers: CronJob` annotation. + +## Expected Behavior + +The policy gets created and contains a single autogen rule for cronjobs in the status. diff --git a/test/conformance/kuttl/autogen/only-deployment/01-assert.yaml b/test/conformance/kuttl/autogen/only-deployment/01-assert.yaml new file mode 100644 index 000000000000..a0116c6aa349 --- /dev/null +++ b/test/conformance/kuttl/autogen/only-deployment/01-assert.yaml @@ -0,0 +1,62 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + autogen: + rules: + - match: + resources: + kinds: + - Deployment + name: autogen-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Deployment + name: autogen-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + template: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/only-deployment/01-manifests.yaml b/test/conformance/kuttl/autogen/only-deployment/01-manifests.yaml new file mode 100644 index 000000000000..d4e4277e0c70 --- /dev/null +++ b/test/conformance/kuttl/autogen/only-deployment/01-manifests.yaml @@ -0,0 +1,31 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag + annotations: + pod-policies.kyverno.io/autogen-controllers: Deployment +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/only-deployment/02-errors.yaml b/test/conformance/kuttl/autogen/only-deployment/02-errors.yaml new file mode 100644 index 000000000000..ebcf018dd5f1 --- /dev/null +++ b/test/conformance/kuttl/autogen/only-deployment/02-errors.yaml @@ -0,0 +1,98 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + autogen: + rules: + - match: + resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + name: autogen-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + name: autogen-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + template: + spec: + containers: + - image: '!*:latest' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/only-deployment/99-cleanup.yaml b/test/conformance/kuttl/autogen/only-deployment/99-cleanup.yaml new file mode 100644 index 000000000000..15c3c4905153 --- /dev/null +++ b/test/conformance/kuttl/autogen/only-deployment/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/autogen/only-deployment/README.md b/test/conformance/kuttl/autogen/only-deployment/README.md new file mode 100644 index 000000000000..c86e02570505 --- /dev/null +++ b/test/conformance/kuttl/autogen/only-deployment/README.md @@ -0,0 +1,7 @@ +## Description + +The policy should contain a single autogen rule for deployments because it has the `pod-policies.kyverno.io/autogen-controllers: Deployment` annotation. + +## Expected Behavior + +The policy gets created and contains a single autogen rule for deployments in the status. diff --git a/test/conformance/kuttl/autogen/should-autogen/01-assert.yaml b/test/conformance/kuttl/autogen/should-autogen/01-assert.yaml new file mode 100644 index 000000000000..ebcf018dd5f1 --- /dev/null +++ b/test/conformance/kuttl/autogen/should-autogen/01-assert.yaml @@ -0,0 +1,98 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + autogen: + rules: + - match: + resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + name: autogen-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + name: autogen-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + template: + spec: + containers: + - image: '!*:latest' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/should-autogen/01-manifests.yaml b/test/conformance/kuttl/autogen/should-autogen/01-manifests.yaml new file mode 100644 index 000000000000..a16d370b814e --- /dev/null +++ b/test/conformance/kuttl/autogen/should-autogen/01-manifests.yaml @@ -0,0 +1,29 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/should-autogen/99-cleanup.yaml b/test/conformance/kuttl/autogen/should-autogen/99-cleanup.yaml new file mode 100644 index 000000000000..15c3c4905153 --- /dev/null +++ b/test/conformance/kuttl/autogen/should-autogen/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/autogen/should-autogen/README.md b/test/conformance/kuttl/autogen/should-autogen/README.md new file mode 100644 index 000000000000..bbbe68d45f39 --- /dev/null +++ b/test/conformance/kuttl/autogen/should-autogen/README.md @@ -0,0 +1,7 @@ +## Description + +The policy should contain all autogen rules. + +## Expected Behavior + +The policy gets created and contains all autogen rules in the status. diff --git a/test/conformance/kuttl/autogen/should-not-autogen/01-assert.yaml b/test/conformance/kuttl/autogen/should-not-autogen/01-assert.yaml new file mode 100644 index 000000000000..64947c5f0fcf --- /dev/null +++ b/test/conformance/kuttl/autogen/should-not-autogen/01-assert.yaml @@ -0,0 +1,36 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + - Deployment + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + autogen: {} diff --git a/test/conformance/kuttl/autogen/should-not-autogen/01-manifests.yaml b/test/conformance/kuttl/autogen/should-not-autogen/01-manifests.yaml new file mode 100644 index 000000000000..18b4b5cdfbeb --- /dev/null +++ b/test/conformance/kuttl/autogen/should-not-autogen/01-manifests.yaml @@ -0,0 +1,30 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + - Deployment + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/should-not-autogen/02-errors.yaml b/test/conformance/kuttl/autogen/should-not-autogen/02-errors.yaml new file mode 100644 index 000000000000..ebcf018dd5f1 --- /dev/null +++ b/test/conformance/kuttl/autogen/should-not-autogen/02-errors.yaml @@ -0,0 +1,98 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-latest-tag +spec: + validationFailureAction: audit + rules: + - match: + resources: + kinds: + - Pod + name: require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - Pod + name: validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + containers: + - image: '!*:latest' +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready + autogen: + rules: + - match: + resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + name: autogen-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-require-image-tag + validate: + message: An image tag is required. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '*:*' + - match: + resources: + kinds: + - DaemonSet + - Deployment + - Job + - StatefulSet + name: autogen-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + template: + spec: + containers: + - image: '!*:latest' + - match: + resources: + kinds: + - CronJob + name: autogen-cronjob-validate-image-tag + validate: + message: Using a mutable image tag e.g. 'latest' is not allowed. + pattern: + spec: + jobTemplate: + spec: + template: + spec: + containers: + - image: '!*:latest' diff --git a/test/conformance/kuttl/autogen/should-not-autogen/99-cleanup.yaml b/test/conformance/kuttl/autogen/should-not-autogen/99-cleanup.yaml new file mode 100644 index 000000000000..15c3c4905153 --- /dev/null +++ b/test/conformance/kuttl/autogen/should-not-autogen/99-cleanup.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/autogen/should-not-autogen/README.md b/test/conformance/kuttl/autogen/should-not-autogen/README.md new file mode 100644 index 000000000000..3e7d26726f3f --- /dev/null +++ b/test/conformance/kuttl/autogen/should-not-autogen/README.md @@ -0,0 +1,7 @@ +## Description + +The policy should not contain autogen rules as autogen should not apply to the policy (it's not a `Pod` only policy). + +## Expected Behavior + +The policy gets created and contains no autogen rules in the status. diff --git a/test/conformance/kuttl/kuttl-test.yaml b/test/conformance/kuttl/kuttl-test.yaml index f88eaa277680..6a70c68ef2d8 100644 --- a/test/conformance/kuttl/kuttl-test.yaml +++ b/test/conformance/kuttl/kuttl-test.yaml @@ -1,6 +1,8 @@ apiVersion: kuttl.dev/v1beta1 kind: TestSuite testDirs: +# Autogen tests +- ./test/conformance/kuttl/autogen # Generate tests # - ./test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync - ./test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync From f5c7c68bacc7277f6b82747e7878dde1db094924 Mon Sep 17 00:00:00 2001 From: Chip Zoller Date: Tue, 8 Nov 2022 10:52:42 -0500 Subject: [PATCH 36/55] add test instructions (#5271) Signed-off-by: Chip Zoller Signed-off-by: Chip Zoller --- CONTRIBUTING.md | 2 +- test/conformance/kuttl/README.md | 70 ++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 test/conformance/kuttl/README.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b362843e5275..6bfb62babd3a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,7 +46,7 @@ In the process of submitting your PRs, please read and abide by the template pro 1. Provide Proof Manifests allowing the maintainers and other contributors to verify your changes without requiring they understand the nuances of all your code. 2. For new or changed functionality, this typically requires documentation and so raise a corresponding issue (or, better yet, raise a separate PR) on the [documentation repository](https://github.com/kyverno/website). -3. Test your change with the [Kyverno CLI](https://kyverno.io/docs/kyverno-cli/) and provide a test manifest in the proper format. If your feature/fix does not work with the CLI, a separate issue requesting CLI support must be made. +3. Test your change with the [Kyverno CLI](https://kyverno.io/docs/kyverno-cli/) and provide a test manifest in the proper format. If your feature/fix does not work with the CLI, a separate issue requesting CLI support must be made. For changes which can be tested as an end user, we require conformance/e2e tests by using the `kuttl` tool. See [here](https://github.com/kyverno/kyverno/tree/main/test/conformance/kuttl/README.md) for a specific guide on how and when to write these tests. 4. Indicate which release this PR is triaged for (maintainers). This step is important especially for the documentation maintainers in order to understand when and where the necessary changes should be made. #### How to Create a PR diff --git a/test/conformance/kuttl/README.md b/test/conformance/kuttl/README.md new file mode 100644 index 000000000000..94120ad45934 --- /dev/null +++ b/test/conformance/kuttl/README.md @@ -0,0 +1,70 @@ +# Testing with `kuttl` + +This document explains conformance and end-to-end (e2e) tests using the `kuttl` tool, when test coverage is required or beneficial, and how contributors may write these tests. + +## Overview + +Kyverno uses [`kuttl`](https://github.com/kudobuilder/kuttl) for performing tests on a live Kubernetes environment with the current code of Kyverno running inside it. The official documentation for this tool is located [here](https://kuttl.dev/). `kuttl` is a Kubernetes testing tool that is capable of submitting resources to a cluster and checking the state of those resources. By comparing that state with declarations defined in other files, `kuttl` can determine whether the observed state is "correct" and either pass or fail based upon this. It also has abilities to run commands or whole scripts. `kuttl` tests work by defining a number of different YAML files with a numerical prefix and co-locating these files in a single directory. Each directory represents a "test case". Files within this directory are evaluated/executed in numerical order. If a failure is encountered at any step in the process, the test is halted and a failure reported. The benefit of `kuttl` is that test cases may be easily and quickly written with no knowledge of a programming language required. + +## How Tests Are Conducted + +Kyverno uses `kuttl` tests to check behavior against incoming code in the form of PRs. Upon every PR, the following automated actions occur in GitHub Actions: + +1. A KinD cluster is built. +2. Kyverno is built from source incorporating the changes in your PR. +3. Kyverno is installed into the KinD cluster. +4. Kuttl executes all test cases against the live environment. + +## When Tests Are Required + +Tests are required for any PR which: + +1. Introduces a new capability +2. Enhances an existing capability +3. Fixes an issue +4. Makes a behavioral change + +Test cases are required for any of the above which can be tested and verified from an end-user (black box) perspective. Tests are also required _at the same time_ as when a PR is proposed. Unless there are special circumstances, tests may not follow a PR which introduces any of the following items in the list. This is because it is too easy to forget to write a test and then it never happens. Tests should always be considered a part of a responsible development process and not an after thought or "extra". + +## Organizing Tests + +Organization of tests is critical to ensure we have an accounting of what exists. With the eventuality of hundreds of test cases, they must be organized to be useful. Please look at the [existing directory structure](https://github.com/kyverno/kyverno/tree/main/test/conformance/kuttl) to identify a suitable location for your tests. Tests are typically organized with the following structure, though this is subject to change. + +``` +. +├── generate +│ └── clusterpolicy +│ ├── cornercases +│ │ ├── test_case_01 +│ │ │ ├── .yaml +│ │ └── test_case_02 +│ │ ├── .yaml +│ └── standard +│ ├── clone +│ │ ├── nosync +│ │ │ ├── test_case_03 +``` + +PRs which address issues will typically go into the `cornercases` directory separated by `clusterpolicy` or `policy` depending on which it addresses. If both, it can go under `cornercases`. PRs which add net new functionality such as a new rule type or significant capability should have basic tests under the `standard` directory. Standard tests test for generic behavior and NOT an esoteric combination of inputs/events to expose a problem. For example, an example of a standard test is to ensure that a ClusterPolicy with a single validate rule can successfully be created. Unless the contents are highly specific, this is a standard test which should be organized under the `standard` directory. + +## Writing Tests + +To make writing test cases even easier, we have provided an example [here](https://github.com/kyverno/kyverno/tree/main/test/conformance/kuttl/aaa_template_resources) under the `scaffold` directory which may be copied-and-pasted to a new test case (directory) based upon the organizational structure outlined above. Additional `kuttl` test files may be found in either `commands` or `scripts` with some common test files for Kyverno. + +It is imperative you modify `README.md` for each test case and follow the template provided. The template looks like the following: + +```markdown +## Description + +This is a description of what my test does and why it needs to do it. + +## Expected Behavior + +This is the expected behavior of my test. Although it's assumed the test, overall, should pass/succeed, be specific about what the internal behavior is which leads to that result. + +## Reference Issue(s) + +1234 +``` + +For some best practices we have identified, see the best practices document [here](https://github.com/kyverno/kyverno/blob/main/test/conformance/kuttl/aaa_template_resources/BEST_PRACTICES.md). From 80c78a54395971f7d101a176c9fd930a5c7668ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Tue, 8 Nov 2022 17:52:57 +0100 Subject: [PATCH 37/55] fix: keep admission warnings (#5269) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Co-authored-by: Vyankatesh Kudtarkar --- pkg/webhooks/policy/handlers.go | 2 +- pkg/webhooks/resource/handlers.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/webhooks/policy/handlers.go b/pkg/webhooks/policy/handlers.go index 79f058598a0f..4e8dfeeb75b4 100644 --- a/pkg/webhooks/policy/handlers.go +++ b/pkg/webhooks/policy/handlers.go @@ -37,7 +37,7 @@ func (h *handlers) Validate(logger logr.Logger, request *admissionv1.AdmissionRe warnings, err := policyvalidate.Validate(policy, h.client, false, h.openApiManager) if err != nil { logger.Error(err, "policy validation errors") - return admissionutils.Response(err) + return admissionutils.Response(err, warnings...) } return admissionutils.Response(err, warnings...) } diff --git a/pkg/webhooks/resource/handlers.go b/pkg/webhooks/resource/handlers.go index 09481ff4716c..b84b25908ffe 100644 --- a/pkg/webhooks/resource/handlers.go +++ b/pkg/webhooks/resource/handlers.go @@ -134,13 +134,13 @@ func (h *handlers) Validate(logger logr.Logger, request *admissionv1.AdmissionRe ok, msg, warnings := vh.HandleValidation(h.metricsConfig, request, policies, policyContext, namespaceLabels, startTime) if !ok { logger.Info("admission request denied") - return admissionutils.Response(errors.New(msg)) + return admissionutils.Response(errors.New(msg), warnings...) } defer h.handleDelete(logger, request) go h.createUpdateRequests(logger, request, policyContext, generatePolicies, mutatePolicies, startTime) - return admissionutils.Response(nil, warnings...) + return admissionutils.ResponseSuccess(warnings...) } func (h *handlers) Mutate(logger logr.Logger, request *admissionv1.AdmissionRequest, failurePolicy string, startTime time.Time) *admissionv1.AdmissionResponse { From 83235ed10d94f0e9ea3f4c61e517c3adfa5b05d8 Mon Sep 17 00:00:00 2001 From: Sandesh More <34198712+sandeshlmore@users.noreply.github.com> Date: Wed, 9 Nov 2022 13:07:11 +0530 Subject: [PATCH 38/55] fix: resource schema validation in policies under any/all match (#5246) Signed-off-by: Sandesh More Signed-off-by: Sandesh More --- pkg/openapi/manager.go | 10 ++++++++++ pkg/openapi/manager_test.go | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/pkg/openapi/manager.go b/pkg/openapi/manager.go index ceb7d710e687..772b40f8cdc0 100644 --- a/pkg/openapi/manager.go +++ b/pkg/openapi/manager.go @@ -124,6 +124,16 @@ func (o *manager) ValidatePolicyMutation(policy kyvernov1.PolicyInterface) error for _, kind := range rule.MatchResources.Kinds { kindToRules[kind] = append(kindToRules[kind], rule) } + for _, resourceFilter := range rule.MatchResources.Any { + for _, kind := range resourceFilter.Kinds { + kindToRules[kind] = append(kindToRules[kind], rule) + } + } + for _, resourceFilter := range rule.MatchResources.All { + for _, kind := range resourceFilter.Kinds { + kindToRules[kind] = append(kindToRules[kind], rule) + } + } } } diff --git a/pkg/openapi/manager_test.go b/pkg/openapi/manager_test.go index dae3167320ba..fa9640ae5bf3 100644 --- a/pkg/openapi/manager_test.go +++ b/pkg/openapi/manager_test.go @@ -13,31 +13,57 @@ func Test_ValidateMutationPolicy(t *testing.T) { tcs := []struct { description string policy []byte - errMessage string + mustSucceed bool }{ { description: "Policy with mutating imagePullPolicy Overlay", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"set-image-pull-policy-2"},"spec":{"rules":[{"name":"set-image-pull-policy-2","match":{"resources":{"kinds":["Pod"]}},"mutate":{"patchStrategicMerge":{"spec":{"containers":[{"(name)":"*","imagePullPolicy":"Always"}]}}}}]}}`), + mustSucceed: true, }, { description: "Policy with mutating imagePullPolicy Overlay, type of value is different (does not throw error since all numbers are also strings according to swagger)", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"set-image-pull-policy-2"},"spec":{"rules":[{"name":"set-image-pull-policy-2","match":{"resources":{"kinds":["Pod"]}},"mutate":{"patchStrategicMerge":{"spec":{"containers":[{"(image)":"*","imagePullPolicy":80}]}}}}]}}`), + mustSucceed: true, }, { description: "Policy with patches", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"policy-endpoints"},"spec":{"rules":[{"name":"pEP","match":{"resources":{"kinds":["Endpoints"],"selector":{"matchLabels":{"label":"test"}}}},"mutate":{"patches": "[{\"path\":\"/subsets/0/ports/0/port\",\"op\":\"replace\",\"value\":9663},{\"path\":\"/metadata/labels/isMutated\",\"op\":\"add\",\"value\":\"true\"}]}}]" }}`), + mustSucceed: true, }, { description: "Dealing with nested variables", policy: []byte(`{"apiVersion":"kyverno.io/v1","kind":"ClusterPolicy","metadata":{"name":"add-ns-access-controls","annotations":{"policies.kyverno.io/category":"Workload Isolation","policies.kyverno.io/description":"Create roles and role bindings for a new namespace"}},"spec":{"background":false,"rules":[{"name":"add-sa-annotation","match":{"resources":{"kinds":["Namespace"]}},"mutate":{"overlay":{"metadata":{"annotations":{"nirmata.io/ns-creator":"{{serviceAccountName-{{something}}}}"}}}}},{"name":"generate-owner-role","match":{"resources":{"kinds":["Namespace"]}},"preconditions":[{"key":"{{request.userInfo.username}}","operator":"NotEqual","value":""},{"key":"{{serviceAccountName}}","operator":"NotEqual","value":""},{"key":"{{serviceAccountNamespace}}","operator":"NotEqual","value":""}],"generate":{"kind":"ClusterRole","name":"ns-owner-{{request.object.metadata.name{{something}}}}-{{request.userInfo.username}}","data":{"metadata":{"annotations":{"nirmata.io/ns-creator":"{{serviceAccountName}}"}},"rules":[{"apiGroups":[""],"resources":["namespaces"],"verbs":["delete"],"resourceNames":["{{request.object.metadata.name}}"]}]}}},{"name":"generate-owner-role-binding","match":{"resources":{"kinds":["Namespace"]}},"preconditions":[{"key":"{{request.userInfo.username}}","operator":"NotEqual","value":""},{"key":"{{serviceAccountName}}","operator":"NotEqual","value":""},{"key":"{{serviceAccountNamespace}}","operator":"NotEqual","value":""}],"generate":{"kind":"ClusterRoleBinding","name":"ns-owner-{{request.object.metadata.name}}-{{request.userInfo.username}}-binding","data":{"metadata":{"annotations":{"nirmata.io/ns-creator":"{{serviceAccountName}}"}},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"ClusterRole","name":"ns-owner-{{request.object.metadata.name}}-{{request.userInfo.username}}"},"subjects":[{"kind":"ServiceAccount","name":"{{serviceAccountName}}","namespace":"{{serviceAccountNamespace}}"}]}}},{"name":"generate-admin-role-binding","match":{"resources":{"kinds":["Namespace"]}},"preconditions":[{"key":"{{request.userInfo.username}}","operator":"NotEqual","value":""},{"key":"{{serviceAccountName}}","operator":"NotEqual","value":""},{"key":"{{serviceAccountNamespace}}","operator":"NotEqual","value":""}],"generate":{"kind":"RoleBinding","name":"ns-admin-{{request.object.metadata.name}}-{{request.userInfo.username}}-binding","namespace":"{{request.object.metadata.name}}","data":{"metadata":{"annotations":{"nirmata.io/ns-creator":"{{serviceAccountName}}"}},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"ClusterRole","name":"admin"},"subjects":[{"kind":"ServiceAccount","name":"{{serviceAccountName}}","namespace":"{{serviceAccountNamespace}}"}]}}}]}}`), + mustSucceed: true, }, { description: "Policy with patchesJson6902 and added element at the beginning of a list", policy: []byte(`{"apiVersion": "kyverno.io/v1","kind": "ClusterPolicy","metadata": {"name": "pe"},"spec": {"rules": [{"name": "pe","match": {"resources": {"kinds": ["Endpoints"]}},"mutate": {"patchesJson6902": "- path: \"/subsets/0/addresses/0\"\n op: add\n value: {\"ip\":\"123\"}\n- path: \"/subsets/1/addresses/0\"\n op: add\n value: {\"ip\":\"123\"}"}}]}}`), + mustSucceed: true, }, { description: "Policy with patchesJson6902 and added element at the end of a list", policy: []byte(`{"apiVersion": "kyverno.io/v1","kind": "ClusterPolicy","metadata": {"name": "pe"},"spec": {"rules": [{"name": "pe","match": {"resources": {"kinds": ["Endpoints"]}},"mutate": {"patchesJson6902": "- path: \"/subsets/0/addresses/-\"\n op: add\n value: {\"ip\":\"123\"}\n- path: \"/subsets/1/addresses/-\"\n op: add\n value: {\"ip\":\"123\"}"}}]}}`), + mustSucceed: true, + }, + { + description: "Invalid policy with patchStrategicMerge and new match schema(any)", + policy: []byte(`{"apiVersion":"kyverno.io\/v1","kind":"ClusterPolicy","metadata":{"name":"mutate-pod"},"spec":{"rules":[{"name":"mutate-pod","match":{"any":[{"resources":{"kinds":["Pod"]}}]},"mutate":{"patchStrategicMerge":{"spec":{"pod":"incorrect"}}}}]}}`), + mustSucceed: false, + }, + { + description: "Invalid policy with patchStrategicMerge and new match schema(all)", + policy: []byte(`{"apiVersion":"kyverno.io\/v1","kind":"ClusterPolicy","metadata":{"name":"mutate-pod"},"spec":{"rules":[{"name":"mutate-pod","match":{"all":[{"resources":{"kinds":["Pod"]}}]},"mutate":{"patchStrategicMerge":{"spec":{"pod":"incorrect"}}}}]}}`), + mustSucceed: false, + }, + { + description: "Valid policy with patchStrategicMerge and new match schema(any)", + policy: []byte(`{"apiVersion":"kyverno.io\/v1","kind":"ClusterPolicy","metadata":{"name":"set-image-pull-policy"},"spec":{"rules":[{"name":"set-image-pull-policy","match":{"any":[{"resources":{"kinds":["Pod"]}}]},"mutate":{"patchStrategicMerge":{"spec":{"containers":[{"(image)":"*:latest","imagePullPolicy":"IfNotPresent"}]}}}}]}}`), + mustSucceed: true, + }, + { + description: "Valid policy with patchStrategicMerge and new match schema(all)", + policy: []byte(`{"apiVersion":"kyverno.io\/v1","kind":"ClusterPolicy","metadata":{"name":"set-image-pull-policy"},"spec":{"rules":[{"name":"set-image-pull-policy","match":{"all":[{"resources":{"kinds":["Pod"]}}]},"mutate":{"patchStrategicMerge":{"spec":{"containers":[{"(image)":"*:latest","imagePullPolicy":"IfNotPresent"}]}}}}]}}`), + mustSucceed: true, }, } @@ -46,15 +72,15 @@ func Test_ValidateMutationPolicy(t *testing.T) { for i, tc := range tcs { policy := v1.ClusterPolicy{} _ = json.Unmarshal(tc.policy, &policy) - var errMessage string err := o.ValidatePolicyMutation(&policy) if err != nil { errMessage = err.Error() } - - if errMessage != tc.errMessage { - t.Errorf("\nTestcase [%v] failed:\nExpected Error: %v\nGot Error: %v", i+1, tc.errMessage, errMessage) + if tc.mustSucceed { + assert.NilError(t, err, "\nTestcase [%v] failed: Expected no error, Got error: %v", i+1, errMessage) + } else { + assert.Assert(t, err != nil, "\nTestcase [%v] failed: Expected error to have occurred", i+1) } } From cc8f643767a9b8f355a0b87ffdc5a673a424af8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 9 Nov 2022 11:52:20 +0100 Subject: [PATCH 39/55] refactor: admission metrics (counter and latency) (#5245) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: move all middlewares in handlers sub package Signed-off-by: Charles-Edouard Brétéché * refactor: admission metrics (counter and latency) Signed-off-by: Charles-Edouard Brétéché * builder Signed-off-by: Charles-Edouard Brétéché * fix Signed-off-by: Charles-Edouard Brétéché * cleanup Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- cmd/kyverno/main.go | 1 + .../admissionrequests/admissionRequests.go | 41 ++------ .../admissionReviewDuration.go | 44 ++------- pkg/webhooks/handlers/admission.go | 6 +- pkg/webhooks/handlers/dump.go | 9 +- pkg/webhooks/handlers/filter.go | 6 +- pkg/webhooks/handlers/metrics.go | 23 +++++ pkg/webhooks/handlers/protect.go | 9 +- .../resource/generation/generation.go | 12 --- pkg/webhooks/resource/mutation/mutation.go | 6 -- pkg/webhooks/resource/updaterequest.go | 13 +-- .../resource/validation/validation.go | 8 -- pkg/webhooks/server.go | 99 +++++++++++-------- pkg/webhooks/utils/metrics.go | 45 --------- 14 files changed, 127 insertions(+), 195 deletions(-) create mode 100644 pkg/webhooks/handlers/metrics.go diff --git a/cmd/kyverno/main.go b/cmd/kyverno/main.go index 32318a5a41eb..46a129fa04e2 100644 --- a/cmd/kyverno/main.go +++ b/cmd/kyverno/main.go @@ -756,6 +756,7 @@ func main() { policyHandlers, resourceHandlers, configuration, + metricsConfig, webhooks.DebugModeOptions{ DumpPayload: dumpPayload, }, diff --git a/pkg/metrics/admissionrequests/admissionRequests.go b/pkg/metrics/admissionrequests/admissionRequests.go index 2e88051608ee..44f35e22c784 100644 --- a/pkg/metrics/admissionrequests/admissionRequests.go +++ b/pkg/metrics/admissionrequests/admissionRequests.go @@ -2,52 +2,27 @@ package admissionrequests import ( "fmt" + "strings" - "github.com/kyverno/kyverno/pkg/engine/response" "github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/utils" + admissionv1 "k8s.io/api/admission/v1" ) -func registerAdmissionRequestsMetric( - m *metrics.MetricsConfig, - resourceKind, resourceNamespace string, - resourceRequestOperation metrics.ResourceRequestOperation, -) error { +func registerAdmissionRequestsMetric(m *metrics.MetricsConfig, resourceKind, resourceNamespace string, resourceRequestOperation metrics.ResourceRequestOperation) { includeNamespaces, excludeNamespaces := m.Config.GetIncludeNamespaces(), m.Config.GetExcludeNamespaces() if (resourceNamespace != "" && resourceNamespace != "-") && utils.ContainsString(excludeNamespaces, resourceNamespace) { m.Log.V(2).Info(fmt.Sprintf("Skipping the registration of kyverno_admission_requests_total metric as the operation belongs to the namespace '%s' which is one of 'namespaces.exclude' %+v in values.yaml", resourceNamespace, excludeNamespaces)) - return nil + return } if (resourceNamespace != "" && resourceNamespace != "-") && len(includeNamespaces) > 0 && !utils.ContainsString(includeNamespaces, resourceNamespace) { m.Log.V(2).Info(fmt.Sprintf("Skipping the registration of kyverno_admission_requests_total metric as the operation belongs to the namespace '%s' which is not one of 'namespaces.include' %+v in values.yaml", resourceNamespace, includeNamespaces)) - return nil + return } - m.RecordAdmissionRequests(resourceKind, resourceNamespace, resourceRequestOperation) - - return nil } -func ProcessEngineResponses(m *metrics.MetricsConfig, engineResponses []*response.EngineResponse, resourceRequestOperation metrics.ResourceRequestOperation) error { - if len(engineResponses) == 0 { - return nil - } - resourceNamespace, resourceKind := engineResponses[0].PolicyResponse.Resource.Namespace, engineResponses[0].PolicyResponse.Resource.Kind - validateRulesCount, mutateRulesCount, generateRulesCount := 0, 0, 0 - for _, e := range engineResponses { - for _, rule := range e.PolicyResponse.Rules { - switch rule.Type { - case "Validation": - validateRulesCount++ - case "Mutation": - mutateRulesCount++ - case "Generation": - generateRulesCount++ - } - } - } - if validateRulesCount == 0 && mutateRulesCount == 0 && generateRulesCount == 0 { - return nil - } - return registerAdmissionRequestsMetric(m, resourceKind, resourceNamespace, resourceRequestOperation) +func Process(m *metrics.MetricsConfig, request *admissionv1.AdmissionRequest) { + op := strings.ToLower(string(request.Operation)) + registerAdmissionRequestsMetric(m, request.Kind.Kind, request.Namespace, metrics.ResourceRequestOperation(op)) } diff --git a/pkg/metrics/admissionreviewduration/admissionReviewDuration.go b/pkg/metrics/admissionreviewduration/admissionReviewDuration.go index 36f50e2ccde4..ec00247ec2b1 100644 --- a/pkg/metrics/admissionreviewduration/admissionReviewDuration.go +++ b/pkg/metrics/admissionreviewduration/admissionReviewDuration.go @@ -2,54 +2,28 @@ package admissionreviewduration import ( "fmt" + "strings" - "github.com/kyverno/kyverno/pkg/engine/response" "github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/utils" + admissionv1 "k8s.io/api/admission/v1" ) -func registerAdmissionReviewDurationMetric( - m *metrics.MetricsConfig, - resourceKind, resourceNamespace string, - resourceRequestOperation metrics.ResourceRequestOperation, - admissionRequestLatency float64, -) error { +func registerAdmissionReviewDurationMetric(m *metrics.MetricsConfig, resourceKind, resourceNamespace string, resourceRequestOperation metrics.ResourceRequestOperation, admissionRequestLatency float64) { includeNamespaces, excludeNamespaces := m.Config.GetIncludeNamespaces(), m.Config.GetExcludeNamespaces() if (resourceNamespace != "" && resourceNamespace != "-") && utils.ContainsString(excludeNamespaces, resourceNamespace) { m.Log.V(2).Info(fmt.Sprintf("Skipping the registration of kyverno_admission_review_duration_seconds metric as the operation belongs to the namespace '%s' which is one of 'namespaces.exclude' %+v in values.yaml", resourceNamespace, excludeNamespaces)) - return nil + return } if (resourceNamespace != "" && resourceNamespace != "-") && len(includeNamespaces) > 0 && !utils.ContainsString(includeNamespaces, resourceNamespace) { m.Log.V(2).Info(fmt.Sprintf("Skipping the registration of kyverno_admission_review_duration_seconds metric as the operation belongs to the namespace '%s' which is not one of 'namespaces.include' %+v in values.yaml", resourceNamespace, includeNamespaces)) - return nil + return } - m.RecordAdmissionReviewDuration(resourceKind, resourceNamespace, string(resourceRequestOperation), admissionRequestLatency) - - return nil } -func ProcessEngineResponses(m *metrics.MetricsConfig, engineResponses []*response.EngineResponse, admissionReviewLatencyDuration int64, resourceRequestOperation metrics.ResourceRequestOperation) error { - if len(engineResponses) == 0 { - return nil - } - resourceNamespace, resourceKind := engineResponses[0].PolicyResponse.Resource.Namespace, engineResponses[0].PolicyResponse.Resource.Kind - validateRulesCount, mutateRulesCount, generateRulesCount := 0, 0, 0 - for _, e := range engineResponses { - for _, rule := range e.PolicyResponse.Rules { - switch rule.Type { - case "Validation": - validateRulesCount++ - case "Mutation": - mutateRulesCount++ - case "Generation": - generateRulesCount++ - } - } - } - if validateRulesCount == 0 && mutateRulesCount == 0 && generateRulesCount == 0 { - return nil - } - admissionReviewLatencyDurationInSeconds := float64(admissionReviewLatencyDuration) / float64(1000*1000*1000) - return registerAdmissionReviewDurationMetric(m, resourceKind, resourceNamespace, resourceRequestOperation, admissionReviewLatencyDurationInSeconds) +func Process(m *metrics.MetricsConfig, request *admissionv1.AdmissionRequest, latency int64) { + op := strings.ToLower(string(request.Operation)) + admissionReviewLatencyDurationInSeconds := float64(latency) / float64(1000*1000*1000) + registerAdmissionReviewDurationMetric(m, request.Kind.Kind, request.Namespace, metrics.ResourceRequestOperation(op), admissionReviewLatencyDurationInSeconds) } diff --git a/pkg/webhooks/handlers/admission.go b/pkg/webhooks/handlers/admission.go index 1ca1fca2c806..4b72b6b5c7e5 100644 --- a/pkg/webhooks/handlers/admission.go +++ b/pkg/webhooks/handlers/admission.go @@ -15,7 +15,11 @@ import ( type AdmissionHandler func(logr.Logger, *admissionv1.AdmissionRequest, time.Time) *admissionv1.AdmissionResponse -func Admission(logger logr.Logger, inner AdmissionHandler) http.HandlerFunc { +func (h AdmissionHandler) WithAdmission(logger logr.Logger) http.HandlerFunc { + return withAdmission(logger, h) +} + +func withAdmission(logger logr.Logger, inner AdmissionHandler) http.HandlerFunc { return func(writer http.ResponseWriter, request *http.Request) { ctx := request.Context() startTime := time.Now() diff --git a/pkg/webhooks/handlers/dump.go b/pkg/webhooks/handlers/dump.go index 1f3005564e96..682f88bea51c 100644 --- a/pkg/webhooks/handlers/dump.go +++ b/pkg/webhooks/handlers/dump.go @@ -93,7 +93,14 @@ func redactPayload(payload *admissionRequestPayload) (*admissionRequestPayload, return payload, nil } -func Dump(inner AdmissionHandler) AdmissionHandler { +func (h AdmissionHandler) WithDump(enabled bool) AdmissionHandler { + if !enabled { + return h + } + return withDump(h) +} + +func withDump(inner AdmissionHandler) AdmissionHandler { return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { response := inner(logger, request, startTime) dumpPayload(logger, request, response) diff --git a/pkg/webhooks/handlers/filter.go b/pkg/webhooks/handlers/filter.go index 77f97b4c3f4b..24a70952f149 100644 --- a/pkg/webhooks/handlers/filter.go +++ b/pkg/webhooks/handlers/filter.go @@ -8,7 +8,11 @@ import ( admissionv1 "k8s.io/api/admission/v1" ) -func Filter(c config.Configuration, inner AdmissionHandler) AdmissionHandler { +func (h AdmissionHandler) WithFilter(configuration config.Configuration) AdmissionHandler { + return withFilter(configuration, h) +} + +func withFilter(c config.Configuration, inner AdmissionHandler) AdmissionHandler { return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { if c.ToFilter(request.Kind.Kind, request.Namespace, request.Name) { return nil diff --git a/pkg/webhooks/handlers/metrics.go b/pkg/webhooks/handlers/metrics.go new file mode 100644 index 000000000000..8cd8d84890a9 --- /dev/null +++ b/pkg/webhooks/handlers/metrics.go @@ -0,0 +1,23 @@ +package handlers + +import ( + "time" + + "github.com/go-logr/logr" + "github.com/kyverno/kyverno/pkg/metrics" + admissionRequests "github.com/kyverno/kyverno/pkg/metrics/admissionrequests" + admissionReviewDuration "github.com/kyverno/kyverno/pkg/metrics/admissionreviewduration" + admissionv1 "k8s.io/api/admission/v1" +) + +func (h AdmissionHandler) WithMetrics(metricsConfig *metrics.MetricsConfig) AdmissionHandler { + return withMetrics(metricsConfig, h) +} + +func withMetrics(metricsConfig *metrics.MetricsConfig, inner AdmissionHandler) AdmissionHandler { + return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { + defer admissionReviewDuration.Process(metricsConfig, request, int64(time.Since(startTime))) + admissionRequests.Process(metricsConfig, request) + return inner(logger, request, startTime) + } +} diff --git a/pkg/webhooks/handlers/protect.go b/pkg/webhooks/handlers/protect.go index 2c0b7aef2353..51e63dd6a01e 100644 --- a/pkg/webhooks/handlers/protect.go +++ b/pkg/webhooks/handlers/protect.go @@ -14,7 +14,14 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) -func Protect(inner AdmissionHandler) AdmissionHandler { +func (h AdmissionHandler) WithProtection(enabled bool) AdmissionHandler { + if !enabled { + return h + } + return withProtection(h) +} + +func withProtection(inner AdmissionHandler) AdmissionHandler { return func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { newResource, oldResource, err := utils.ExtractResources(nil, request) if err != nil { diff --git a/pkg/webhooks/resource/generation/generation.go b/pkg/webhooks/resource/generation/generation.go index daa93ed429c0..90d37226a819 100644 --- a/pkg/webhooks/resource/generation/generation.go +++ b/pkg/webhooks/resource/generation/generation.go @@ -38,9 +38,6 @@ type GenerationHandler interface { []kyvernov1.PolicyInterface, *engine.PolicyContext, time.Time, - *chan int64, - *chan []*response.EngineResponse, - *chan []*response.EngineResponse, ) } @@ -84,9 +81,6 @@ func (h *generationHandler) Handle( policies []kyvernov1.PolicyInterface, policyContext *engine.PolicyContext, admissionRequestTimestamp time.Time, - latencySender *chan int64, - generateEngineResponsesSenderForAdmissionReviewDurationMetric *chan []*response.EngineResponse, - generateEngineResponsesSenderForAdmissionRequestsCountMetric *chan []*response.EngineResponse, ) { h.log.V(6).Info("update request") @@ -132,12 +126,6 @@ func (h *generationHandler) Handle( if request.Operation == admissionv1.Update { h.HandleUpdatesForGenerateRules(request, policies) } - - // sending the admission request latency to other goroutine (reporting the metrics) over the channel - admissionReviewLatencyDuration := int64(time.Since(admissionRequestTimestamp)) - *latencySender <- admissionReviewLatencyDuration - *generateEngineResponsesSenderForAdmissionReviewDurationMetric <- engineResponses - *generateEngineResponsesSenderForAdmissionRequestsCountMetric <- engineResponses } // HandleUpdatesForGenerateRules handles admission-requests for update diff --git a/pkg/webhooks/resource/mutation/mutation.go b/pkg/webhooks/resource/mutation/mutation.go index bebdc562571d..ab812aaa2a75 100644 --- a/pkg/webhooks/resource/mutation/mutation.go +++ b/pkg/webhooks/resource/mutation/mutation.go @@ -70,13 +70,7 @@ func (h *mutationHandler) HandleMutation( if err != nil { return nil, nil, err } - h.log.V(6).Info("", "generated patches", string(mutatePatches)) - - admissionReviewLatencyDuration := int64(time.Since(admissionRequestTimestamp)) - go webhookutils.RegisterAdmissionReviewDurationMetricMutate(h.log, metricsConfig, string(request.Operation), mutateEngineResponses, admissionReviewLatencyDuration) - go webhookutils.RegisterAdmissionRequestsMetricMutate(h.log, metricsConfig, string(request.Operation), mutateEngineResponses) - return mutatePatches, webhookutils.GetWarningMessages(mutateEngineResponses), nil } diff --git a/pkg/webhooks/resource/updaterequest.go b/pkg/webhooks/resource/updaterequest.go index 6e060ba1675d..0fab3b88ba13 100644 --- a/pkg/webhooks/resource/updaterequest.go +++ b/pkg/webhooks/resource/updaterequest.go @@ -17,16 +17,9 @@ import ( // createUpdateRequests applies generate and mutateExisting policies, and creates update requests for background reconcile func (h *handlers) createUpdateRequests(logger logr.Logger, request *admissionv1.AdmissionRequest, policyContext *engine.PolicyContext, generatePolicies, mutatePolicies []kyvernov1.PolicyInterface, ts time.Time) { - admissionReviewCompletionLatencyChannel := make(chan int64, 1) - generateEngineResponsesSenderForAdmissionReviewDurationMetric := make(chan []*response.EngineResponse, 1) - generateEngineResponsesSenderForAdmissionRequestsCountMetric := make(chan []*response.EngineResponse, 1) - gh := generation.NewGenerationHandler(logger, h.client, h.kyvernoClient, h.nsLister, h.urLister, h.urGenerator, h.urUpdater, h.eventGen) go h.handleMutateExisting(logger, request, mutatePolicies, policyContext, ts) - go gh.Handle(h.metricsConfig, request, generatePolicies, policyContext, ts, &admissionReviewCompletionLatencyChannel, &generateEngineResponsesSenderForAdmissionReviewDurationMetric, &generateEngineResponsesSenderForAdmissionRequestsCountMetric) - - go webhookutils.RegisterAdmissionReviewDurationMetricGenerate(logger, h.metricsConfig, string(request.Operation), &admissionReviewCompletionLatencyChannel, &generateEngineResponsesSenderForAdmissionReviewDurationMetric) - go webhookutils.RegisterAdmissionRequestsMetricGenerate(logger, h.metricsConfig, string(request.Operation), &generateEngineResponsesSenderForAdmissionRequestsCountMetric) + go gh.Handle(h.metricsConfig, request, generatePolicies, policyContext, ts) } func (h *handlers) handleMutateExisting(logger logr.Logger, request *admissionv1.AdmissionRequest, policies []kyvernov1.PolicyInterface, policyContext *engine.PolicyContext, admissionRequestTimestamp time.Time) { @@ -75,8 +68,4 @@ func (h *handlers) handleMutateExisting(logger logr.Logger, request *admissionv1 h.eventGen.Add(events...) } } - - admissionReviewLatencyDuration := int64(time.Since(admissionRequestTimestamp)) - go webhookutils.RegisterAdmissionReviewDurationMetricMutate(logger, h.metricsConfig, string(request.Operation), engineResponses, admissionReviewLatencyDuration) - go webhookutils.RegisterAdmissionRequestsMetricMutate(logger, h.metricsConfig, string(request.Operation), engineResponses) } diff --git a/pkg/webhooks/resource/validation/validation.go b/pkg/webhooks/resource/validation/validation.go index 2518f007c047..6813c8a3e3da 100644 --- a/pkg/webhooks/resource/validation/validation.go +++ b/pkg/webhooks/resource/validation/validation.go @@ -123,23 +123,15 @@ func (v *validationHandler) HandleValidation( if blocked { logger.V(4).Info("admission request blocked") - v.generateMetrics(request, admissionRequestTimestamp, engineResponses, metricsConfig, logger) return false, webhookutils.GetBlockedMessages(engineResponses), nil } - v.generateMetrics(request, admissionRequestTimestamp, engineResponses, metricsConfig, logger) go v.handleAudit(policyContext.NewResource, request, namespaceLabels, engineResponses...) warnings := webhookutils.GetWarningMessages(engineResponses) return true, "", warnings } -func (v *validationHandler) generateMetrics(request *admissionv1.AdmissionRequest, admissionRequestTimestamp time.Time, engineResponses []*response.EngineResponse, metricsConfig *metrics.MetricsConfig, logger logr.Logger) { - admissionReviewLatencyDuration := int64(time.Since(admissionRequestTimestamp)) - go webhookutils.RegisterAdmissionReviewDurationMetricValidate(logger, metricsConfig, string(request.Operation), engineResponses, admissionReviewLatencyDuration) - go webhookutils.RegisterAdmissionRequestsMetricValidate(logger, metricsConfig, string(request.Operation), engineResponses) -} - func (v *validationHandler) buildAuditResponses(resource unstructured.Unstructured, request *admissionv1.AdmissionRequest, namespaceLabels map[string]string) ([]*response.EngineResponse, error) { policies := v.pCache.GetPolicies(policycache.ValidateAudit, request.Kind.Kind, request.Namespace) policyContext, err := v.pcBuilder.Build(request, policies...) diff --git a/pkg/webhooks/server.go b/pkg/webhooks/server.go index 2846b49f42da..169182cba522 100644 --- a/pkg/webhooks/server.go +++ b/pkg/webhooks/server.go @@ -10,6 +10,7 @@ import ( "github.com/julienschmidt/httprouter" "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/logging" + "github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/toggle" controllerutils "github.com/kyverno/kyverno/pkg/utils/controller" runtimeutils "github.com/kyverno/kyverno/pkg/utils/runtime" @@ -66,6 +67,7 @@ func NewServer( policyHandlers PolicyHandlers, resourceHandlers ResourceHandlers, configuration config.Configuration, + metricsConfig *metrics.MetricsConfig, debugModeOpts DebugModeOptions, tlsProvider TlsProvider, mwcClient controllerutils.DeleteClient[*admissionregistrationv1.MutatingWebhookConfiguration], @@ -77,11 +79,32 @@ func NewServer( resourceLogger := logger.WithName("resource") policyLogger := logger.WithName("policy") verifyLogger := logger.WithName("verify") - registerWebhookHandlers(resourceLogger.WithName("mutate"), mux, config.MutatingWebhookServicePath, configuration, resourceHandlers.Mutate, debugModeOpts) - registerWebhookHandlers(resourceLogger.WithName("validate"), mux, config.ValidatingWebhookServicePath, configuration, resourceHandlers.Validate, debugModeOpts) - mux.HandlerFunc("POST", config.PolicyMutatingWebhookServicePath, admission(policyLogger.WithName("mutate"), filter(configuration, policyHandlers.Mutate), debugModeOpts)) - mux.HandlerFunc("POST", config.PolicyValidatingWebhookServicePath, admission(policyLogger.WithName("validate"), filter(configuration, policyHandlers.Validate), debugModeOpts)) - mux.HandlerFunc("POST", config.VerifyMutatingWebhookServicePath, admission(verifyLogger.WithName("mutate"), handlers.Verify(), DebugModeOptions{})) + registerWebhookHandlers(resourceLogger.WithName("mutate"), mux, config.MutatingWebhookServicePath, configuration, metricsConfig, resourceHandlers.Mutate, debugModeOpts) + registerWebhookHandlers(resourceLogger.WithName("validate"), mux, config.ValidatingWebhookServicePath, configuration, metricsConfig, resourceHandlers.Validate, debugModeOpts) + mux.HandlerFunc( + "POST", + config.PolicyMutatingWebhookServicePath, + handlers.AdmissionHandler(policyHandlers.Mutate). + WithFilter(configuration). + WithDump(debugModeOpts.DumpPayload). + WithMetrics(metricsConfig). + WithAdmission(policyLogger.WithName("mutate")), + ) + mux.HandlerFunc( + "POST", + config.PolicyValidatingWebhookServicePath, + handlers.AdmissionHandler(policyHandlers.Validate). + WithFilter(configuration). + WithDump(debugModeOpts.DumpPayload). + WithMetrics(metricsConfig). + WithAdmission(policyLogger.WithName("validate")), + ) + mux.HandlerFunc( + "POST", + config.VerifyMutatingWebhookServicePath, + handlers.Verify(). + WithAdmission(verifyLogger.WithName("mutate")), + ) mux.HandlerFunc("GET", config.LivenessServicePath, handlers.Probe(runtime.IsLive)) mux.HandlerFunc("GET", config.ReadinessServicePath, handlers.Probe(runtime.IsReady)) return &server{ @@ -170,53 +193,49 @@ func (s *server) cleanup(ctx context.Context) { close(s.cleanUp) } -func dump(inner handlers.AdmissionHandler, debugModeOpts DebugModeOptions) handlers.AdmissionHandler { - // debug mode not enabled, no need to add debug middleware - if !debugModeOpts.DumpPayload { - return inner - } - return handlers.Dump(inner) -} - -func protect(inner handlers.AdmissionHandler) handlers.AdmissionHandler { - if !toggle.ProtectManagedResources.Enabled() { - return inner - } - return handlers.Protect(inner) -} - -func filter(configuration config.Configuration, inner handlers.AdmissionHandler) handlers.AdmissionHandler { - return handlers.Filter(configuration, inner) -} - -func admission(logger logr.Logger, inner handlers.AdmissionHandler, debugModeOpts DebugModeOptions) http.HandlerFunc { - return handlers.Admission(logger, dump(protect(inner), debugModeOpts)) -} - func registerWebhookHandlers( logger logr.Logger, mux *httprouter.Router, basePath string, configuration config.Configuration, + metricsConfig *metrics.MetricsConfig, handlerFunc func(logr.Logger, *admissionv1.AdmissionRequest, string, time.Time) *admissionv1.AdmissionResponse, debugModeOpts DebugModeOptions, ) { - mux.HandlerFunc("POST", basePath, admission(logger, filter( - configuration, - func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { + mux.HandlerFunc( + "POST", + basePath, + handlers.AdmissionHandler(func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { return handlerFunc(logger, request, "all", startTime) - }), debugModeOpts), + }). + WithFilter(configuration). + WithProtection(toggle.ProtectManagedResources.Enabled()). + WithDump(debugModeOpts.DumpPayload). + WithMetrics(metricsConfig). + WithAdmission(logger), ) - mux.HandlerFunc("POST", basePath+"/fail", admission(logger, filter( - configuration, - func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { + mux.HandlerFunc( + "POST", + basePath+"/fail", + handlers.AdmissionHandler(func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { return handlerFunc(logger, request, "fail", startTime) - }), debugModeOpts), + }). + WithFilter(configuration). + WithProtection(toggle.ProtectManagedResources.Enabled()). + WithDump(debugModeOpts.DumpPayload). + WithMetrics(metricsConfig). + WithAdmission(logger), ) - mux.HandlerFunc("POST", basePath+"/ignore", admission(logger, filter( - configuration, - func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { + mux.HandlerFunc( + "POST", + basePath+"/ignore", + handlers.AdmissionHandler(func(logger logr.Logger, request *admissionv1.AdmissionRequest, startTime time.Time) *admissionv1.AdmissionResponse { return handlerFunc(logger, request, "ignore", startTime) - }), debugModeOpts), + }). + WithFilter(configuration). + WithProtection(toggle.ProtectManagedResources.Enabled()). + WithDump(debugModeOpts.DumpPayload). + WithMetrics(metricsConfig). + WithAdmission(logger), ) } diff --git a/pkg/webhooks/utils/metrics.go b/pkg/webhooks/utils/metrics.go index 9d2d36beb28f..8f9fa6594130 100644 --- a/pkg/webhooks/utils/metrics.go +++ b/pkg/webhooks/utils/metrics.go @@ -7,8 +7,6 @@ import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/engine/response" "github.com/kyverno/kyverno/pkg/metrics" - admissionRequests "github.com/kyverno/kyverno/pkg/metrics/admissionrequests" - admissionReviewDuration "github.com/kyverno/kyverno/pkg/metrics/admissionreviewduration" policyExecutionDuration "github.com/kyverno/kyverno/pkg/metrics/policyexecutionduration" policyResults "github.com/kyverno/kyverno/pkg/metrics/policyresults" ) @@ -25,49 +23,6 @@ func registerMetric(logger logr.Logger, m string, requestOperation string, r rep } } -// ADMISSION REVIEW - -func RegisterAdmissionReviewDurationMetricMutate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, engineResponses []*response.EngineResponse, admissionReviewLatencyDuration int64) { - registerMetric(logger, "kyverno_admission_review_duration_seconds", requestOperation, func(op metrics.ResourceRequestOperation) error { - return admissionReviewDuration.ProcessEngineResponses(metricsConfig, engineResponses, admissionReviewLatencyDuration, op) - }) -} - -func RegisterAdmissionReviewDurationMetricGenerate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, latencyReceiver *chan int64, engineResponsesReceiver *chan []*response.EngineResponse) { - defer close(*latencyReceiver) - defer close(*engineResponsesReceiver) - registerMetric(logger, "kyverno_admission_review_duration_seconds", requestOperation, func(op metrics.ResourceRequestOperation) error { - return admissionReviewDuration.ProcessEngineResponses(metricsConfig, <-(*engineResponsesReceiver), <-(*latencyReceiver), op) - }) -} - -func RegisterAdmissionReviewDurationMetricValidate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, engineResponses []*response.EngineResponse, admissionReviewLatencyDuration int64) { - registerMetric(logger, "kyverno_admission_review_duration_seconds", requestOperation, func(op metrics.ResourceRequestOperation) error { - return admissionReviewDuration.ProcessEngineResponses(metricsConfig, engineResponses, admissionReviewLatencyDuration, op) - }) -} - -// ADMISSION REQUEST - -func RegisterAdmissionRequestsMetricMutate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, engineResponses []*response.EngineResponse) { - registerMetric(logger, "kyverno_admission_requests_total", requestOperation, func(op metrics.ResourceRequestOperation) error { - return admissionRequests.ProcessEngineResponses(metricsConfig, engineResponses, op) - }) -} - -func RegisterAdmissionRequestsMetricGenerate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, engineResponsesReceiver *chan []*response.EngineResponse) { - defer close(*engineResponsesReceiver) - registerMetric(logger, "kyverno_admission_requests_total", requestOperation, func(op metrics.ResourceRequestOperation) error { - return admissionRequests.ProcessEngineResponses(metricsConfig, <-(*engineResponsesReceiver), op) - }) -} - -func RegisterAdmissionRequestsMetricValidate(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, engineResponses []*response.EngineResponse) { - registerMetric(logger, "kyverno_admission_requests_total", requestOperation, func(op metrics.ResourceRequestOperation) error { - return admissionRequests.ProcessEngineResponses(metricsConfig, engineResponses, op) - }) -} - // POLICY RESULTS func RegisterPolicyResultsMetricMutation(logger logr.Logger, metricsConfig *metrics.MetricsConfig, requestOperation string, policy kyvernov1.PolicyInterface, engineResponse response.EngineResponse) { From ff5e0a361c7ec13238b17af1568d205fbf82b9c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 9 Nov 2022 12:37:00 +0100 Subject: [PATCH 40/55] feat: add flag to control leader election frequency (#5172) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add flag to control leader election frequency Signed-off-by: Charles-Edouard Brétéché * changelog Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché Co-authored-by: shuting --- CHANGELOG.md | 1 + cmd/initContainer/main.go | 1 + cmd/kyverno/main.go | 3 +++ pkg/leaderelection/leaderelection.go | 10 ++++++---- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e080f40272c8..6ba14c6fefce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Note - Flag `autogenInternals` was removed, policy mutation has been removed. +- Flag `leaderElectionRetryPeriod` was added to control leader election renewal frequency (default value is `2s`). - Support upper case `Audit` and `Enforce` in `.spec.validationFailureAction` of the Kyverno policy, failure actions `audit` and `enforce` are deprecated and will be removed in `v1.11.0`. ## v1.8.1-rc3 diff --git a/cmd/initContainer/main.go b/cmd/initContainer/main.go index 5dacffc59515..4ec7e82b9813 100644 --- a/cmd/initContainer/main.go +++ b/cmd/initContainer/main.go @@ -174,6 +174,7 @@ func main() { config.KyvernoNamespace(), kubeClient, config.KyvernoPodName(), + leaderelection.DefaultRetryPeriod, run, nil, ) diff --git a/cmd/kyverno/main.go b/cmd/kyverno/main.go index 46a129fa04e2..bb9ebbf1f76b 100644 --- a/cmd/kyverno/main.go +++ b/cmd/kyverno/main.go @@ -96,6 +96,7 @@ var ( backgroundScanWorkers int logFormat string dumpPayload bool + leaderElectionRetryPeriod time.Duration // DEPRECATED: remove in 1.9 splitPolicyReport bool ) @@ -130,6 +131,7 @@ func parseFlags() error { flag.BoolVar(&admissionReports, "admissionReports", true, "Enable or disable admission reports.") flag.IntVar(&reportsChunkSize, "reportsChunkSize", 1000, "Max number of results in generated reports, reports will be split accordingly if there are more results to be stored.") flag.IntVar(&backgroundScanWorkers, "backgroundScanWorkers", backgroundscancontroller.Workers, "Configure the number of background scan workers.") + flag.DurationVar(&leaderElectionRetryPeriod, "leaderElectionRetryPeriod", leaderelection.DefaultRetryPeriod, "Configure leader election retry period.") // DEPRECATED: remove in 1.9 flag.BoolVar(&splitPolicyReport, "splitPolicyReport", false, "This is deprecated, please don't use it, will be removed in v1.9.") if err := flag.Set("v", "2"); err != nil { @@ -658,6 +660,7 @@ func main() { config.KyvernoNamespace(), kubeClientLeaderElection, config.KyvernoPodName(), + leaderElectionRetryPeriod, func(ctx context.Context) { logger := logger.WithName("leader") // validate config diff --git a/pkg/leaderelection/leaderelection.go b/pkg/leaderelection/leaderelection.go index bc56faf01f35..50107f788e35 100644 --- a/pkg/leaderelection/leaderelection.go +++ b/pkg/leaderelection/leaderelection.go @@ -13,6 +13,8 @@ import ( "k8s.io/client-go/tools/leaderelection/resourcelock" ) +const DefaultRetryPeriod = 2 * time.Second + type Interface interface { // Run is a blocking call that runs a leader election Run(ctx context.Context) @@ -46,7 +48,7 @@ type config struct { log logr.Logger } -func New(log logr.Logger, name, namespace string, kubeClient kubernetes.Interface, id string, startWork func(context.Context), stopWork func()) (Interface, error) { +func New(log logr.Logger, name, namespace string, kubeClient kubernetes.Interface, id string, retryPeriod time.Duration, startWork func(context.Context), stopWork func()) (Interface, error) { lock, err := resourcelock.New( resourcelock.LeasesResourceLock, namespace, @@ -72,9 +74,9 @@ func New(log logr.Logger, name, namespace string, kubeClient kubernetes.Interfac e.leaderElectionCfg = leaderelection.LeaderElectionConfig{ Lock: e.lock, ReleaseOnCancel: true, - LeaseDuration: 15 * time.Second, - RenewDeadline: 10 * time.Second, - RetryPeriod: 2 * time.Second, + LeaseDuration: 6 * retryPeriod, + RenewDeadline: 5 * retryPeriod, + RetryPeriod: retryPeriod, Callbacks: leaderelection.LeaderCallbacks{ OnStartedLeading: func(ctx context.Context) { atomic.StoreInt64(&e.isLeader, 1) From a1e9856846daff4fc55ba8fd0b23328b8ec8f935 Mon Sep 17 00:00:00 2001 From: yinka Date: Wed, 9 Nov 2022 16:10:27 +0100 Subject: [PATCH 41/55] fix: make zapr compatible with klog's -v argument (#5166) * make zapr compatible with klog's -v argument Signed-off-by: damilola olayinka * remove zap logger's NameKey Signed-off-by: damilola olayinka Signed-off-by: damilola olayinka --- cmd/initContainer/main.go | 8 +++++++- cmd/kyverno/main.go | 8 +++++++- pkg/logging/log.go | 9 ++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/cmd/initContainer/main.go b/cmd/initContainer/main.go index 4ec7e82b9813..046fa91aa94d 100644 --- a/cmd/initContainer/main.go +++ b/cmd/initContainer/main.go @@ -10,6 +10,7 @@ import ( "fmt" "os" "os/signal" + "strconv" "sync" "syscall" "time" @@ -65,7 +66,12 @@ func main() { os.Exit(1) } // setup logger - if err := logging.Setup(logFormat); err != nil { + logLevel, err := strconv.Atoi(flag.Lookup("v").Value.String()) + if err != nil { + fmt.Println("failed to setup logger", err) + os.Exit(1) + } + if err := logging.Setup(logFormat, logLevel); err != nil { fmt.Println("could not setup logger", err) os.Exit(1) } diff --git a/cmd/kyverno/main.go b/cmd/kyverno/main.go index bb9ebbf1f76b..5016a570bf36 100644 --- a/cmd/kyverno/main.go +++ b/cmd/kyverno/main.go @@ -10,6 +10,7 @@ import ( _ "net/http/pprof" // #nosec "os" "os/signal" + "strconv" "strings" "sync" "syscall" @@ -519,7 +520,12 @@ func main() { os.Exit(1) } // setup logger - if err := logging.Setup(logFormat); err != nil { + logLevel, err := strconv.Atoi(flag.Lookup("v").Value.String()) + if err != nil { + fmt.Println("failed to setup logger", err) + os.Exit(1) + } + if err := logging.Setup(logFormat, logLevel); err != nil { fmt.Println("failed to setup logger", err) os.Exit(1) } diff --git a/pkg/logging/log.go b/pkg/logging/log.go index a501fda99b0f..3e770a4ec73e 100644 --- a/pkg/logging/log.go +++ b/pkg/logging/log.go @@ -12,6 +12,7 @@ import ( "github.com/go-logr/logr" "github.com/go-logr/zapr" "go.uber.org/zap" + "go.uber.org/zap/zapcore" "k8s.io/klog/v2" "k8s.io/klog/v2/klogr" "sigs.k8s.io/controller-runtime/pkg/log" @@ -43,14 +44,16 @@ func Init(flags *flag.FlagSet) { // Setup configures the logger with the supplied log format. // It returns an error if the JSON logger could not be initialized or passed logFormat is not recognized. -// LogLevel parameter is used to configure zap. -func Setup(logFormat string) error { +func Setup(logFormat string, level int) error { switch logFormat { case TextFormat: // in text mode we use FormatSerialize format globalLog = klogr.New() case JSONFormat: - zapLog, err := zap.NewProduction() + zc := zap.NewProductionConfig() + // Zap's levels get more and less verbose as the number gets smaller and higher respectively (DebugLevel is -1, InfoLevel is 0, WarnLevel is 1, and so on). + zc.Level = zap.NewAtomicLevelAt(zapcore.Level(-1 * level)) + zapLog, err := zc.Build() if err != nil { return err } From 0d37be25e4ebe16291d92a208e90a642252d15d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 9 Nov 2022 23:57:55 +0100 Subject: [PATCH 42/55] chore: update kuttl (#5285) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9f9415db5535..e3339d257530 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ HELM_DOCS_VERSION := v1.11.0 KO := $(TOOLS_DIR)/ko KO_VERSION := main #e93dbee8540f28c45ec9a2b8aec5ef8e43123966 KUTTL := $(TOOLS_DIR)/kubectl-kuttl -KUTTL_VERSION := v0.13.0 +KUTTL_VERSION := v0.14.0 TOOLS := $(KIND) $(CONTROLLER_GEN) $(CLIENT_GEN) $(LISTER_GEN) $(INFORMER_GEN) $(OPENAPI_GEN) $(GEN_CRD_API_REFERENCE_DOCS) $(GO_ACC) $(KUSTOMIZE) $(GOIMPORTS) $(HELM) $(HELM_DOCS) $(KO) $(KUTTL) ifeq ($(GOOS), darwin) SED := gsed From 37948f179e03e75d0eabb4f23feb2bad67c34144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Thu, 10 Nov 2022 00:53:48 +0100 Subject: [PATCH 43/55] fix: kuttl test external-service (#5287) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- .../cornercases/external-metrics/00-keda.yaml | 6 ++++++ .../external-metrics/01-cluster-policy.yaml | 6 ++++++ .../external-metrics/02-policy.yaml | 6 ++++++ .../external-metrics/02-sleep.yaml | 5 ----- .../external-metrics/03-assert.yaml | 9 --------- .../external-metrics/99-cleanup.yaml | 4 ---- ...-assert.yaml => cluster-policy-ready.yaml} | 5 ++++- ...clusterpolicy.yaml => cluster-policy.yaml} | 0 .../external-metrics/keda-ready.yaml | 19 +++++++++++++++++++ .../{01-manifests.yaml => keda.yaml} | 2 -- .../{05-assert.yaml => policy-ready.yaml} | 5 ++++- .../{05-policy.yaml => policy.yaml} | 0 12 files changed, 45 insertions(+), 22 deletions(-) create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/00-keda.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/01-cluster-policy.yaml create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/02-policy.yaml delete mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/02-sleep.yaml delete mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/03-assert.yaml delete mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/99-cleanup.yaml rename test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/{04-assert.yaml => cluster-policy-ready.yaml} (57%) rename test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/{04-clusterpolicy.yaml => cluster-policy.yaml} (100%) create mode 100644 test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/keda-ready.yaml rename test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/{01-manifests.yaml => keda.yaml} (99%) rename test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/{05-assert.yaml => policy-ready.yaml} (63%) rename test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/{05-policy.yaml => policy.yaml} (100%) diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/00-keda.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/00-keda.yaml new file mode 100644 index 000000000000..05d2215faf3a --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/00-keda.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- keda.yaml +assert: +- keda-ready.yaml diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/01-cluster-policy.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/01-cluster-policy.yaml new file mode 100644 index 000000000000..70b5a38aa194 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/01-cluster-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- cluster-policy.yaml +assert: +- cluster-policy-ready.yaml diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/02-policy.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/02-policy.yaml new file mode 100644 index 000000000000..57ffd5631d21 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/02-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/02-sleep.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/02-sleep.yaml deleted file mode 100644 index f34516fc2df9..000000000000 --- a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/02-sleep.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# Need to wait for the KEDA images to be pulled, Pods run, and external metrics API group to be properly registered and served. -apiVersion: kuttl.dev/v1beta1 -kind: TestStep -commands: - - command: sleep 20 \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/03-assert.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/03-assert.yaml deleted file mode 100644 index c2ade741b961..000000000000 --- a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/03-assert.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: keda-metrics-apiserver - namespace: keda -status: - availableReplicas: 1 - readyReplicas: 1 - replicas: 1 \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/99-cleanup.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/99-cleanup.yaml deleted file mode 100644 index 1eb8dbd55835..000000000000 --- a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/99-cleanup.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: kuttl.dev/v1beta1 -kind: TestStep -commands: - - command: kubectl delete -f 01-manifests.yaml,04-clusterpolicy.yaml,05-policy.yaml --force --wait=false --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-assert.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/cluster-policy-ready.yaml similarity index 57% rename from test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-assert.yaml rename to test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/cluster-policy-ready.yaml index 9d36296cef03..5770a6453cc2 100644 --- a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-assert.yaml +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/cluster-policy-ready.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: external-metrics-policy status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-clusterpolicy.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/cluster-policy.yaml similarity index 100% rename from test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/04-clusterpolicy.yaml rename to test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/cluster-policy.yaml diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/keda-ready.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/keda-ready.yaml new file mode 100644 index 000000000000..059335ea54b7 --- /dev/null +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/keda-ready.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: keda-metrics-apiserver + namespace: keda +status: + availableReplicas: 1 + readyReplicas: 1 + replicas: 1 +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: scaledobjects.keda.sh +--- +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + name: v1beta1.external.metrics.k8s.io diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/01-manifests.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/keda.yaml similarity index 99% rename from test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/01-manifests.yaml rename to test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/keda.yaml index 02598d5442bd..982f28457324 100644 --- a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/01-manifests.yaml +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/keda.yaml @@ -12,7 +12,6 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.9.0 - creationTimestamp: null labels: app.kubernetes.io/part-of: keda-operator app.kubernetes.io/version: 2.8.0 @@ -411,7 +410,6 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - creationTimestamp: null labels: app.kubernetes.io/name: keda-operator app.kubernetes.io/part-of: keda-operator diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-assert.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/policy-ready.yaml similarity index 63% rename from test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-assert.yaml rename to test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/policy-ready.yaml index 1f89a4d15997..a963ab024bb2 100644 --- a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-assert.yaml +++ b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/policy-ready.yaml @@ -4,4 +4,7 @@ metadata: name: external-metrics-policy-default namespace: default status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-policy.yaml b/test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/policy.yaml similarity index 100% rename from test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/05-policy.yaml rename to test/conformance/kuttl/validate/clusterpolicy/cornercases/external-metrics/policy.yaml From 14e6aa4bbacff2016612a967227f043f4aad5b6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Thu, 10 Nov 2022 09:43:51 +0100 Subject: [PATCH 44/55] fix: check policy is ready in kuttl tests (#5286) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- .../kuttl/aaa_template_resources/scaffold/01-assert.yaml | 5 ++++- .../cornercases/clone-role-and-rolebinding/01-assert.yaml | 5 ++++- .../cornercases/data-role-and-rolebinding/01-assert.yaml | 5 ++++- .../clusterpolicy/standard/keyed-basic/01-assert.yaml | 5 ++++- .../mutateDigest-noverifyDigest-norequired/01-assert.yaml | 5 ++++- .../nomutateDigest-verifyDigest-norequired/01-assert.yaml | 5 ++++- 6 files changed, 24 insertions(+), 6 deletions(-) diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/01-assert.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/01-assert.yaml index 7f1d7387c9b0..7e9f14965b97 100644 --- a/test/conformance/kuttl/aaa_template_resources/scaffold/01-assert.yaml +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: add-labels status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/01-assert.yaml index ef8b3de63821..b19561440ac0 100644 --- a/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/01-assert.yaml +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/clone-role-and-rolebinding/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: gen-clone-role-policy status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/01-assert.yaml index 4047f4fc55f9..61361d638ccb 100644 --- a/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/01-assert.yaml +++ b/test/conformance/kuttl/generate/clusterpolicy/cornercases/data-role-and-rolebinding/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: gen-role-policy status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/01-assert.yaml index 99a0cad5253f..a2d2cc907ea8 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/01-assert.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/keyed-basic/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: keyed-basic-policy status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/01-assert.yaml index 7d7c5b7da2a9..3a68a73a0b9a 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/01-assert.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/mutateDigest-noverifyDigest-norequired/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: mutatedigest-policy status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/01-assert.yaml index 7d7c5b7da2a9..3a68a73a0b9a 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/01-assert.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/nomutateDigest-verifyDigest-norequired/01-assert.yaml @@ -3,4 +3,7 @@ kind: ClusterPolicy metadata: name: mutatedigest-policy status: - ready: true \ No newline at end of file + conditions: + - reason: Succeeded + status: "True" + type: Ready From 72dee76c066bc145ed0f996890db4dd13a5ec8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Thu, 10 Nov 2022 10:36:08 +0100 Subject: [PATCH 45/55] fix: image extractor kuttl tests (#5293) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- .../00-crd.yaml | 6 +++ .../01-policy.yaml | 6 +++ .../02-task.yaml | 15 +++--- .../03-assert.yaml | 7 --- .../99-cleanup.yaml | 4 -- .../crd-ready.yaml | 4 ++ .../imageExtractors-complex-keyless/crd.yaml | 24 +++++++++ .../{01-assert.yaml => policy-ready.yaml} | 0 .../{01-manifests.yaml => policy.yaml} | 32 +---------- .../imageExtractors-complex-keyless/task.yaml | 8 +++ .../imageExtractors-complex/00-crd.yaml | 6 +++ .../imageExtractors-complex/01-policy.yaml | 6 +++ .../imageExtractors-complex/03-errors.yaml | 1 - .../imageExtractors-complex/99-cleanup.yaml | 4 -- .../imageExtractors-complex/badtask.yaml | 1 - .../imageExtractors-complex/crd-ready.yaml | 4 ++ .../standard/imageExtractors-complex/crd.yaml | 24 +++++++++ .../{01-assert.yaml => policy-ready.yaml} | 0 .../{01-manifests.yaml => policy.yaml} | 30 ----------- .../standard/imageExtractors-none/00-crd.yaml | 6 +++ .../imageExtractors-none/01-manifests.yaml | 54 ------------------- .../imageExtractors-none/01-policy.yaml | 6 +++ .../imageExtractors-none/02-task.yaml | 15 +++--- .../imageExtractors-none/99-cleanup.yaml | 4 -- .../imageExtractors-none/crd-ready.yaml | 4 ++ .../standard/imageExtractors-none/crd.yaml | 24 +++++++++ .../{01-assert.yaml => policy-ready.yaml} | 0 .../standard/imageExtractors-none/policy.yaml | 24 +++++++++ .../{03-assert.yaml => task.yaml} | 5 +- .../imageExtractors-simple/00-crd.yaml | 6 +++ .../imageExtractors-simple/01-policy.yaml | 6 +++ .../imageExtractors-simple/03-errors.yaml | 5 -- .../imageExtractors-simple/99-cleanup.yaml | 4 -- .../imageExtractors-simple/badtask.yaml | 1 - .../imageExtractors-simple/crd-ready.yaml | 4 ++ .../standard/imageExtractors-simple/crd.yaml | 24 +++++++++ .../{01-assert.yaml => policy-ready.yaml} | 0 .../{01-manifests.yaml => policy.yaml} | 31 ----------- 38 files changed, 209 insertions(+), 196 deletions(-) create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/00-crd.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-policy.yaml delete mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/03-assert.yaml delete mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/crd-ready.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/crd.yaml rename test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/{01-assert.yaml => policy-ready.yaml} (100%) rename test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/{01-manifests.yaml => policy.yaml} (56%) create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/task.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/00-crd.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-policy.yaml delete mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/crd-ready.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/crd.yaml rename test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/{01-assert.yaml => policy-ready.yaml} (100%) rename test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/{01-manifests.yaml => policy.yaml} (57%) create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/00-crd.yaml delete mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-manifests.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-policy.yaml delete mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/crd-ready.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/crd.yaml rename test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/{01-assert.yaml => policy-ready.yaml} (100%) create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/policy.yaml rename test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/{03-assert.yaml => task.yaml} (53%) create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/00-crd.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-policy.yaml delete mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/03-errors.yaml delete mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/99-cleanup.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/crd-ready.yaml create mode 100644 test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/crd.yaml rename test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/{01-assert.yaml => policy-ready.yaml} (100%) rename test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/{01-manifests.yaml => policy.yaml} (54%) diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/00-crd.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/00-crd.yaml new file mode 100644 index 000000000000..3bb734b3d162 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/00-crd.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- crd.yaml +assert: +- crd-ready.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-policy.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-policy.yaml new file mode 100644 index 000000000000..57ffd5631d21 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/02-task.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/02-task.yaml index 797d2f4dd945..9906380e826f 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/02-task.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/02-task.yaml @@ -1,9 +1,6 @@ -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: example-task-name - namespace: tekton-test -spec: - steps: - - name: cosign - image: ghcr.io/sigstore/cosign/cosign@sha256:33a6a55d2f1354bc989b791974cf4ee00a900ab9e4e54b393962321758eee3c6 \ No newline at end of file +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- task.yaml +assert: +- task.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/03-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/03-assert.yaml deleted file mode 100644 index 00a796d51627..000000000000 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/03-assert.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: example-task-name - namespace: tekton-test - annotations: - kyverno.io/verify-images: '{"ghcr.io/sigstore/cosign/cosign@sha256:33a6a55d2f1354bc989b791974cf4ee00a900ab9e4e54b393962321758eee3c6":true}' \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/99-cleanup.yaml deleted file mode 100644 index 901039dff198..000000000000 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/99-cleanup.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: kuttl.dev/v1beta1 -kind: TestStep -commands: - - command: kubectl delete -f 01-manifests.yaml,02-task.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/crd-ready.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/crd-ready.yaml new file mode 100644 index 000000000000..f592e6b44d11 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/crd-ready.yaml @@ -0,0 +1,4 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tasks.tekton.dev diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/crd.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/crd.yaml new file mode 100644 index 000000000000..145b9e0120fa --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/crd.yaml @@ -0,0 +1,24 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tasks.tekton.dev +spec: + group: tekton.dev + preserveUnknownFields: false + versions: + - name: v1beta1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + subresources: + status: {} + names: + kind: Task + plural: tasks + categories: + - tekton + - tekton-pipelines + scope: Namespaced diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/policy-ready.yaml similarity index 100% rename from test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-assert.yaml rename to test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/policy-ready.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/policy.yaml similarity index 56% rename from test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-manifests.yaml rename to test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/policy.yaml index bf239d5aaeb4..c9bd3c8d5391 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/01-manifests.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/policy.yaml @@ -1,33 +1,3 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: tekton-test ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: tasks.tekton.dev -spec: - group: tekton.dev - preserveUnknownFields: false - versions: - - name: v1beta1 - served: true - storage: true - schema: - openAPIV3Schema: - type: object - x-kubernetes-preserve-unknown-fields: true - subresources: - status: {} - names: - kind: Task - plural: tasks - categories: - - tekton - - tekton-pipelines - scope: Namespaced ---- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: @@ -60,4 +30,4 @@ spec: subject: "https://github.com/*" rekor: url: https://rekor.sigstore.dev - required: true \ No newline at end of file + required: true diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/task.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/task.yaml new file mode 100644 index 000000000000..d70f7c06f211 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex-keyless/task.yaml @@ -0,0 +1,8 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: example-task-name +spec: + steps: + - name: cosign + image: ghcr.io/sigstore/cosign/cosign@sha256:33a6a55d2f1354bc989b791974cf4ee00a900ab9e4e54b393962321758eee3c6 diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/00-crd.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/00-crd.yaml new file mode 100644 index 000000000000..3bb734b3d162 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/00-crd.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- crd.yaml +assert: +- crd-ready.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-policy.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-policy.yaml new file mode 100644 index 000000000000..57ffd5631d21 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/03-errors.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/03-errors.yaml index de1b3f099bfe..7d55f37d42e3 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/03-errors.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/03-errors.yaml @@ -2,4 +2,3 @@ apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: example-task-name - namespace: tekton-test \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/99-cleanup.yaml deleted file mode 100644 index 15c3c4905153..000000000000 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/99-cleanup.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: kuttl.dev/v1beta1 -kind: TestStep -commands: - - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/badtask.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/badtask.yaml index 192d130a6bf2..e7e28c800cea 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/badtask.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/badtask.yaml @@ -2,7 +2,6 @@ apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: example-task-name - namespace: tekton-test spec: steps: - name: ubuntu-example diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/crd-ready.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/crd-ready.yaml new file mode 100644 index 000000000000..f592e6b44d11 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/crd-ready.yaml @@ -0,0 +1,4 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tasks.tekton.dev diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/crd.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/crd.yaml new file mode 100644 index 000000000000..145b9e0120fa --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/crd.yaml @@ -0,0 +1,24 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tasks.tekton.dev +spec: + group: tekton.dev + preserveUnknownFields: false + versions: + - name: v1beta1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + subresources: + status: {} + names: + kind: Task + plural: tasks + categories: + - tekton + - tekton-pipelines + scope: Namespaced diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/policy-ready.yaml similarity index 100% rename from test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-assert.yaml rename to test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/policy-ready.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/policy.yaml similarity index 57% rename from test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-manifests.yaml rename to test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/policy.yaml index a14488e3a1d2..03bb24770add 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/01-manifests.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-complex/policy.yaml @@ -1,33 +1,3 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: tekton-test ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: tasks.tekton.dev -spec: - group: tekton.dev - preserveUnknownFields: false - versions: - - name: v1beta1 - served: true - storage: true - schema: - openAPIV3Schema: - type: object - x-kubernetes-preserve-unknown-fields: true - subresources: - status: {} - names: - kind: Task - plural: tasks - categories: - - tekton - - tekton-pipelines - scope: Namespaced ---- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/00-crd.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/00-crd.yaml new file mode 100644 index 000000000000..3bb734b3d162 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/00-crd.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- crd.yaml +assert: +- crd-ready.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-manifests.yaml deleted file mode 100644 index b643df8eb35e..000000000000 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-manifests.yaml +++ /dev/null @@ -1,54 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: tekton-test ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: tasks.tekton.dev -spec: - group: tekton.dev - preserveUnknownFields: false - versions: - - name: v1beta1 - served: true - storage: true - schema: - openAPIV3Schema: - type: object - x-kubernetes-preserve-unknown-fields: true - subresources: - status: {} - names: - kind: Task - plural: tasks - categories: - - tekton - - tekton-pipelines - scope: Namespaced ---- -apiVersion: kyverno.io/v1 -kind: ClusterPolicy -metadata: - name: tasks-no-extractor -spec: - validationFailureAction: enforce - rules: - - name: verify-images - match: - any: - - resources: - kinds: - - tekton.dev/v1beta1/Task - preconditions: - - key: "{{request.operation}}" - operator: NotEquals - value: DELETE - verifyImages: - - image: "*" - key: |- - -----BEGIN PUBLIC KEY----- - MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM - 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== - -----END PUBLIC KEY----- \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-policy.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-policy.yaml new file mode 100644 index 000000000000..57ffd5631d21 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/02-task.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/02-task.yaml index 192d130a6bf2..9906380e826f 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/02-task.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/02-task.yaml @@ -1,9 +1,6 @@ -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: example-task-name - namespace: tekton-test -spec: - steps: - - name: ubuntu-example - image: ubuntu:bionic +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- task.yaml +assert: +- task.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/99-cleanup.yaml deleted file mode 100644 index 901039dff198..000000000000 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/99-cleanup.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: kuttl.dev/v1beta1 -kind: TestStep -commands: - - command: kubectl delete -f 01-manifests.yaml,02-task.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/crd-ready.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/crd-ready.yaml new file mode 100644 index 000000000000..f592e6b44d11 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/crd-ready.yaml @@ -0,0 +1,4 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tasks.tekton.dev diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/crd.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/crd.yaml new file mode 100644 index 000000000000..145b9e0120fa --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/crd.yaml @@ -0,0 +1,24 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tasks.tekton.dev +spec: + group: tekton.dev + preserveUnknownFields: false + versions: + - name: v1beta1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + subresources: + status: {} + names: + kind: Task + plural: tasks + categories: + - tekton + - tekton-pipelines + scope: Namespaced diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/policy-ready.yaml similarity index 100% rename from test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/01-assert.yaml rename to test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/policy-ready.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/policy.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/policy.yaml new file mode 100644 index 000000000000..5a1a35c1c9fb --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/policy.yaml @@ -0,0 +1,24 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: tasks-no-extractor +spec: + validationFailureAction: enforce + rules: + - name: verify-images + match: + any: + - resources: + kinds: + - tekton.dev/v1beta1/Task + preconditions: + - key: "{{request.operation}}" + operator: NotEquals + value: DELETE + verifyImages: + - image: "*" + key: |- + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM + 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== + -----END PUBLIC KEY----- diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/03-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/task.yaml similarity index 53% rename from test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/03-assert.yaml rename to test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/task.yaml index de1b3f099bfe..e7e28c800cea 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/03-assert.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-none/task.yaml @@ -2,4 +2,7 @@ apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: example-task-name - namespace: tekton-test \ No newline at end of file +spec: + steps: + - name: ubuntu-example + image: ubuntu:bionic diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/00-crd.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/00-crd.yaml new file mode 100644 index 000000000000..3bb734b3d162 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/00-crd.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- crd.yaml +assert: +- crd-ready.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-policy.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-policy.yaml new file mode 100644 index 000000000000..57ffd5631d21 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/03-errors.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/03-errors.yaml deleted file mode 100644 index de1b3f099bfe..000000000000 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/03-errors.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: tekton.dev/v1beta1 -kind: Task -metadata: - name: example-task-name - namespace: tekton-test \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/99-cleanup.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/99-cleanup.yaml deleted file mode 100644 index 15c3c4905153..000000000000 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/99-cleanup.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: kuttl.dev/v1beta1 -kind: TestStep -commands: - - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/badtask.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/badtask.yaml index 192d130a6bf2..e7e28c800cea 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/badtask.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/badtask.yaml @@ -2,7 +2,6 @@ apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: example-task-name - namespace: tekton-test spec: steps: - name: ubuntu-example diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/crd-ready.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/crd-ready.yaml new file mode 100644 index 000000000000..f592e6b44d11 --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/crd-ready.yaml @@ -0,0 +1,4 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tasks.tekton.dev diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/crd.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/crd.yaml new file mode 100644 index 000000000000..145b9e0120fa --- /dev/null +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/crd.yaml @@ -0,0 +1,24 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: tasks.tekton.dev +spec: + group: tekton.dev + preserveUnknownFields: false + versions: + - name: v1beta1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + subresources: + status: {} + names: + kind: Task + plural: tasks + categories: + - tekton + - tekton-pipelines + scope: Namespaced diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-assert.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/policy-ready.yaml similarity index 100% rename from test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-assert.yaml rename to test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/policy-ready.yaml diff --git a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-manifests.yaml b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/policy.yaml similarity index 54% rename from test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-manifests.yaml rename to test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/policy.yaml index b59928742a01..c6d77d0cb9f8 100644 --- a/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/01-manifests.yaml +++ b/test/conformance/kuttl/verifyImages/clusterpolicy/standard/imageExtractors-simple/policy.yaml @@ -1,33 +1,3 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: tekton-test ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - name: tasks.tekton.dev -spec: - group: tekton.dev - preserveUnknownFields: false - versions: - - name: v1beta1 - served: true - storage: true - schema: - openAPIV3Schema: - type: object - x-kubernetes-preserve-unknown-fields: true - subresources: - status: {} - names: - kind: Task - plural: tasks - categories: - - tekton - - tekton-pipelines - scope: Namespaced ---- apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: @@ -55,4 +25,3 @@ spec: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== -----END PUBLIC KEY----- ---- From ef421a33ed9f046cceeb9620e252080fb784966c Mon Sep 17 00:00:00 2001 From: Prateek Pandey Date: Thu, 10 Nov 2022 17:13:24 +0530 Subject: [PATCH 46/55] fix: allow delete of clone target resource with synchronize false (#5161) Signed-off-by: prateekpandey14 --- pkg/background/generate/generate.go | 29 ++++++++++++++++++++++---- test/conformance/kuttl/kuttl-test.yaml | 2 +- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/pkg/background/generate/generate.go b/pkg/background/generate/generate.go index 7a57270761c3..32eef8f0a44c 100644 --- a/pkg/background/generate/generate.go +++ b/pkg/background/generate/generate.go @@ -423,7 +423,7 @@ func applyRule(log logr.Logger, client dclient.Interface, rule kyvernov1.Rule, r logger := log.WithValues("genKind", genKind, "genAPIVersion", genAPIVersion, "genNamespace", genNamespace, "genName", genName) if rule.Generation.Clone.Name != "" { - cresp, mode, err = manageClone(logger, genAPIVersion, genKind, genNamespace, genName, policy.GetName(), rule.Generation, client) + cresp, mode, err = manageClone(logger, genAPIVersion, genKind, genNamespace, genName, policy.GetName(), ur, rule.Generation, client) rdatas = append(rdatas, GenerateResponse{ Data: cresp, Action: mode, @@ -434,7 +434,7 @@ func applyRule(log logr.Logger, client dclient.Interface, rule kyvernov1.Rule, r Error: err, }) } else if len(rule.Generation.CloneList.Kinds) != 0 { - rdatas = manageCloneList(logger, genNamespace, policy.GetName(), rule.Generation, client) + rdatas = manageCloneList(logger, genNamespace, policy.GetName(), ur, rule.Generation, client) } else { dresp, mode, err = manageData(logger, genAPIVersion, genKind, genNamespace, genName, rule.Generation.RawData, rule.Generation.Synchronize, ur, client) rdatas = append(rdatas, GenerateResponse{ @@ -618,7 +618,7 @@ func manageData(log logr.Logger, apiVersion, kind, namespace, name string, data return updateObj.UnstructuredContent(), Update, nil } -func manageClone(log logr.Logger, apiVersion, kind, namespace, name, policy string, clone kyvernov1.Generation, client dclient.Interface) (map[string]interface{}, ResourceMode, error) { +func manageClone(log logr.Logger, apiVersion, kind, namespace, name, policy string, ur kyvernov1beta1.UpdateRequest, clone kyvernov1.Generation, client dclient.Interface) (map[string]interface{}, ResourceMode, error) { // resource namespace can be nil in case of clusters scope resource rNamespace := clone.Clone.Namespace if rNamespace == "" { @@ -640,6 +640,16 @@ func manageClone(log logr.Logger, apiVersion, kind, namespace, name, policy stri if err != nil { return nil, Skip, fmt.Errorf("source resource %s %s/%s/%s not found. %v", apiVersion, kind, rNamespace, rName, err) } + + // check if cloned resource exists + cobj, err := client.GetResource(apiVersion, kind, namespace, name) + if err != nil { + if apierrors.IsNotFound(err) && len(ur.Status.GeneratedResources) != 0 && !clone.Synchronize { + log.V(4).Info("synchronization is disabled, recreation will be skipped", "resource", cobj) + return nil, Skip, nil + } + } + // remove ownerReferences when cloning resources to other namespace if rNamespace != namespace && obj.GetOwnerReferences() != nil { obj.SetOwnerReferences(nil) @@ -663,7 +673,7 @@ func manageClone(log logr.Logger, apiVersion, kind, namespace, name, policy stri return obj.UnstructuredContent(), Create, nil } -func manageCloneList(log logr.Logger, namespace, policy string, clone kyvernov1.Generation, client dclient.Interface) []GenerateResponse { +func manageCloneList(log logr.Logger, namespace, policy string, ur kyvernov1beta1.UpdateRequest, clone kyvernov1.Generation, client dclient.Interface) []GenerateResponse { var response []GenerateResponse rNamespace := clone.CloneList.Namespace @@ -713,6 +723,17 @@ func manageCloneList(log logr.Logger, namespace, policy string, clone kyvernov1. return response } + // check if cloned resource exists + cobj, err := client.GetResource(apiVersion, kind, namespace, rName.GetName()) + if apierrors.IsNotFound(err) && len(ur.Status.GeneratedResources) != 0 && !clone.Synchronize { + log.V(4).Info("synchronization is disabled, recreation will be skipped", "resource", cobj) + response = append(response, GenerateResponse{ + Data: nil, + Action: Skip, + Error: nil, + }) + } + // remove ownerReferences when cloning resources to other namespace if rNamespace != namespace && obj.GetOwnerReferences() != nil { obj.SetOwnerReferences(nil) diff --git a/test/conformance/kuttl/kuttl-test.yaml b/test/conformance/kuttl/kuttl-test.yaml index 6a70c68ef2d8..f147af23df4b 100644 --- a/test/conformance/kuttl/kuttl-test.yaml +++ b/test/conformance/kuttl/kuttl-test.yaml @@ -4,7 +4,7 @@ testDirs: # Autogen tests - ./test/conformance/kuttl/autogen # Generate tests -# - ./test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync +- ./test/conformance/kuttl/generate/clusterpolicy/standard/clone/nosync - ./test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync - ./test/conformance/kuttl/generate/clusterpolicy/standard/data/sync - ./test/conformance/kuttl/generate/clusterpolicy/standard/data/nosync From d86faa5832145bac99e818632d60447921c57736 Mon Sep 17 00:00:00 2001 From: Prateek Pandey Date: Thu, 10 Nov 2022 18:35:39 +0530 Subject: [PATCH 47/55] tests: add kuttl tests for multiple clone generate (#5280) * tests: add kuttl tests for multiple clone generate Signed-off-by: prateekpandey14 * bump kuttl version v1.13.1 Signed-off-by: prateekpandey14 * fix review comments Signed-off-by: prateekpandey14 * remove cleanup of image-verify tests Signed-off-by: prateekpandey14 Signed-off-by: prateekpandey14 --- .../01-assert.yaml | 9 ++++ .../01-manifests.yaml | 54 +++++++++++++++++++ .../02-assert.yaml | 11 ++++ .../cpol-clone-list-sync-create/02-ns.yaml | 4 ++ .../cpol-clone-list-sync-create/README.md | 11 ++++ 5 files changed, 89 insertions(+) create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/01-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/01-manifests.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/02-assert.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/02-ns.yaml create mode 100644 test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/README.md diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/01-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/01-assert.yaml new file mode 100644 index 000000000000..0bd6979f59b3 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/01-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: sync-secret-with-multi-clone +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/01-manifests.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/01-manifests.yaml new file mode 100644 index 000000000000..d4b52d937e5d --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/01-manifests.yaml @@ -0,0 +1,54 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: sync-secret-with-multi-clone +spec: + generateExistingOnPolicyUpdate: true + rules: + - name: sync-secret + match: + any: + - resources: + kinds: + - Namespace + exclude: + any: + - resources: + namespaces: + - kube-system + - default + - kube-public + - kyverno + generate: + namespace: "{{request.object.metadata.name}}" + synchronize : true + cloneList: + namespace: default + kinds: + - v1/Secret + - v1/ConfigMap + selector: + matchLabels: + allowedToBeCloned: "true" +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: bootstap-config + namespace: default + labels: + allowedToBeCloned: "true" +data: + initial_lives: "15" +--- +apiVersion: v1 +kind: Secret +metadata: + name: image-secret + namespace: default + labels: + allowedToBeCloned: "true" +type: kubernetes.io/basic-auth +stringData: + username: admin + password: t0p-Secret-super diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/02-assert.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/02-assert.yaml new file mode 100644 index 000000000000..ae058e2b30ca --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/02-assert.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Secret +metadata: + name: image-secret + namespace: prod +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: bootstap-config + namespace: prod diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/02-ns.yaml b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/02-ns.yaml new file mode 100644 index 000000000000..f1ded585a826 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/02-ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: prod \ No newline at end of file diff --git a/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/README.md b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/README.md new file mode 100644 index 000000000000..acfc8d8ea885 --- /dev/null +++ b/test/conformance/kuttl/generate/clusterpolicy/standard/clone/sync/cpol-clone-list-sync-create/README.md @@ -0,0 +1,11 @@ +## Description + +This test ensures that creation of a multiple target resource created by a ClusterPolicy `generate.cloneList` rule. If it is not generated, the test fails. + +## Expected Behavior + +The cloned Secret and ConfigMap from the default namespace should exists in newly created namespace. + +## Reference Issue(s) + +N/A \ No newline at end of file From 7a15231a1c587f81c7f2637ff0e53b4ddcf61d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Thu, 10 Nov 2022 14:49:22 +0100 Subject: [PATCH 48/55] fix: reduce startup probe delay (#5296) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché Co-authored-by: Prateek Pandey --- charts/kyverno/values.yaml | 6 +++--- config/install.yaml | 6 +++--- config/manifest/deployment.yaml | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/charts/kyverno/values.yaml b/charts/kyverno/values.yaml index 1dac0f0ffcda..d7a88467d883 100644 --- a/charts/kyverno/values.yaml +++ b/charts/kyverno/values.yaml @@ -240,9 +240,9 @@ startupProbe: path: /health/liveness port: 9443 scheme: HTTPS - failureThreshold: 12 - initialDelaySeconds: 30 - periodSeconds: 10 + failureThreshold: 20 + initialDelaySeconds: 2 + periodSeconds: 6 # -- Liveness probe. # The block is directly forwarded into the deployment, so you can use whatever livenessProbe configuration you want. diff --git a/config/install.yaml b/config/install.yaml index 44b29211eba3..4dd42fe5371e 100644 --- a/config/install.yaml +++ b/config/install.yaml @@ -29242,13 +29242,13 @@ spec: seccompProfile: type: RuntimeDefault startupProbe: - failureThreshold: 12 + failureThreshold: 20 httpGet: path: /health/liveness port: 9443 scheme: HTTPS - initialDelaySeconds: 30 - periodSeconds: 10 + initialDelaySeconds: 2 + periodSeconds: 6 volumeMounts: - mountPath: /.sigstore name: sigstore diff --git a/config/manifest/deployment.yaml b/config/manifest/deployment.yaml index aa79ac7e1e71..8a81593b27c8 100755 --- a/config/manifest/deployment.yaml +++ b/config/manifest/deployment.yaml @@ -128,9 +128,9 @@ spec: path: /health/liveness port: 9443 scheme: HTTPS - failureThreshold: 12 - initialDelaySeconds: 30 - periodSeconds: 10 + failureThreshold: 20 + initialDelaySeconds: 2 + periodSeconds: 6 livenessProbe: httpGet: path: /health/liveness From 67f7d7af2455f46e4936ddd26f48a0e948abb2dc Mon Sep 17 00:00:00 2001 From: Chip Zoller Date: Thu, 10 Nov 2022 09:25:51 -0500 Subject: [PATCH 49/55] Update kuttl test scaffolding (#5303) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add test instructions Signed-off-by: Chip Zoller * update scaffolding Signed-off-by: Chip Zoller Signed-off-by: Chip Zoller Co-authored-by: Charles-Edouard Brétéché --- .../kuttl/aaa_template_resources/BEST_PRACTICES.md | 2 +- .../kuttl/aaa_template_resources/scaffold/01-policy.yaml | 6 ++++++ .../kuttl/aaa_template_resources/scaffold/02-resource.yaml | 6 ++++++ .../kuttl/aaa_template_resources/scaffold/99-cleanup.yaml | 4 ---- .../scaffold/{01-assert.yaml => policy-ready.yaml} | 2 +- .../scaffold/{01-manifests.yaml => policy.yaml} | 2 +- .../aaa_template_resources/scaffold/resource-mutated.yaml | 7 +++++++ 7 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 test/conformance/kuttl/aaa_template_resources/scaffold/01-policy.yaml create mode 100644 test/conformance/kuttl/aaa_template_resources/scaffold/02-resource.yaml delete mode 100644 test/conformance/kuttl/aaa_template_resources/scaffold/99-cleanup.yaml rename test/conformance/kuttl/aaa_template_resources/scaffold/{01-assert.yaml => policy-ready.yaml} (89%) rename test/conformance/kuttl/aaa_template_resources/scaffold/{01-manifests.yaml => policy.yaml} (93%) create mode 100644 test/conformance/kuttl/aaa_template_resources/scaffold/resource-mutated.yaml diff --git a/test/conformance/kuttl/aaa_template_resources/BEST_PRACTICES.md b/test/conformance/kuttl/aaa_template_resources/BEST_PRACTICES.md index c245e1ada616..7a989411b104 100644 --- a/test/conformance/kuttl/aaa_template_resources/BEST_PRACTICES.md +++ b/test/conformance/kuttl/aaa_template_resources/BEST_PRACTICES.md @@ -1,6 +1,6 @@ # Some Best Practices * Don't put anything in index `00` so it can be used in the future. -* Put clean-up as index `99` so it's always last no matter how many steps. +* A final clean-up stage/file is not needed unless a resource was created using a Script. Use scripts sparingly! * The `*-errors.yaml` file, like an `*-assert.yaml` file only performs an existence check, not a creation check. * One test can contain both positive and negative tests by extending the test case. No need to write separate. \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/01-policy.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/01-policy.yaml new file mode 100644 index 000000000000..f3857739b00f --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/01-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-ready.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/02-resource.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/02-resource.yaml new file mode 100644 index 000000000000..7e08de156a43 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/02-resource.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- resource.yaml +assert: +- resource-mutated.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/99-cleanup.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/99-cleanup.yaml deleted file mode 100644 index 15c3c4905153..000000000000 --- a/test/conformance/kuttl/aaa_template_resources/scaffold/99-cleanup.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: kuttl.dev/v1beta1 -kind: TestStep -commands: - - command: kubectl delete -f 01-manifests.yaml --force --wait=true --ignore-not-found=true \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/01-assert.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/policy-ready.yaml similarity index 89% rename from test/conformance/kuttl/aaa_template_resources/scaffold/01-assert.yaml rename to test/conformance/kuttl/aaa_template_resources/scaffold/policy-ready.yaml index 7e9f14965b97..d483722c1f0f 100644 --- a/test/conformance/kuttl/aaa_template_resources/scaffold/01-assert.yaml +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/policy-ready.yaml @@ -6,4 +6,4 @@ status: conditions: - reason: Succeeded status: "True" - type: Ready + type: Ready \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/01-manifests.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/policy.yaml similarity index 93% rename from test/conformance/kuttl/aaa_template_resources/scaffold/01-manifests.yaml rename to test/conformance/kuttl/aaa_template_resources/scaffold/policy.yaml index 970b4aa5c439..efcd7c18f97a 100644 --- a/test/conformance/kuttl/aaa_template_resources/scaffold/01-manifests.yaml +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/policy.yaml @@ -16,4 +16,4 @@ spec: patchStrategicMerge: metadata: labels: - foo: bar + foo: bar \ No newline at end of file diff --git a/test/conformance/kuttl/aaa_template_resources/scaffold/resource-mutated.yaml b/test/conformance/kuttl/aaa_template_resources/scaffold/resource-mutated.yaml new file mode 100644 index 000000000000..dcb47a5770a8 --- /dev/null +++ b/test/conformance/kuttl/aaa_template_resources/scaffold/resource-mutated.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: testingsecret + namespace: default + labels: + foo: bar \ No newline at end of file From 977dcc38a248cfe2b312e1892e3af7c05e087752 Mon Sep 17 00:00:00 2001 From: Prateek Pandey Date: Thu, 10 Nov 2022 20:40:29 +0530 Subject: [PATCH 50/55] fix: set rule response status as skip if precondition failed (#5162) exisiting UpdateRequest gets delete if precondition failed for the matched rule in case of skip rule response. Signed-off-by: Prateek Pandey Signed-off-by: Prateek Pandey --- pkg/engine/background.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg/engine/background.go b/pkg/engine/background.go index d1bde7fd963d..73b55c7bb9ad 100644 --- a/pkg/engine/background.go +++ b/pkg/engine/background.go @@ -131,7 +131,15 @@ func filterRule(rule kyvernov1.Rule, policyContext *PolicyContext) *response.Rul // evaluate pre-conditions if !variables.EvaluateConditions(logger, ctx, copyConditions) { logger.V(4).Info("skip rule as preconditions are not met", "rule", ruleCopy.Name) - return nil + return &response.RuleResponse{ + Name: ruleCopy.Name, + Type: ruleType, + Status: response.RuleStatusSkip, + RuleStats: response.RuleStats{ + ProcessingTime: time.Since(startTime), + RuleExecutionTimestamp: startTime.Unix(), + }, + } } // build rule Response From 19f0e7ebfe66c9e211097fb406d8949a7aecec1f Mon Sep 17 00:00:00 2001 From: Tobias Dahlberg Date: Thu, 10 Nov 2022 17:03:45 +0100 Subject: [PATCH 51/55] fix: add parsing of json pointers to support special chars (#3578 #3616) (#4767) * Added jsonpointer package that supports parsing of paths and JSON pointers that can yield either a JSON pointer string or JMESPath string. * Replaced the use of `strings.Split` and `strings.Join` in places where paths are converted to JMESPaths. Signed-off-by: Tobias Dahlberg Signed-off-by: Tobias Dahlberg Co-authored-by: shuting Co-authored-by: Prateek Pandey Co-authored-by: Vyankatesh Kudtarkar --- pkg/engine/imageVerify.go | 6 +- pkg/engine/jsonutils/traverse.go | 3 +- pkg/engine/mutation_test.go | 366 ++++++++++++++++++++++++++ pkg/engine/utils/utils.go | 29 -- pkg/engine/utils/utils_test.go | 8 - pkg/engine/variables/vars.go | 27 +- pkg/engine/variables/vars_test.go | 12 - pkg/utils/jsonpointer/pointer.go | 244 +++++++++++++++++ pkg/utils/jsonpointer/pointer_test.go | 227 ++++++++++++++++ 9 files changed, 848 insertions(+), 74 deletions(-) create mode 100644 pkg/utils/jsonpointer/pointer.go create mode 100644 pkg/utils/jsonpointer/pointer_test.go diff --git a/pkg/engine/imageVerify.go b/pkg/engine/imageVerify.go index aa747b77f966..7b42ad293357 100644 --- a/pkg/engine/imageVerify.go +++ b/pkg/engine/imageVerify.go @@ -14,11 +14,11 @@ import ( "github.com/kyverno/kyverno/pkg/cosign" "github.com/kyverno/kyverno/pkg/engine/context" "github.com/kyverno/kyverno/pkg/engine/response" - engineUtils "github.com/kyverno/kyverno/pkg/engine/utils" "github.com/kyverno/kyverno/pkg/engine/variables" "github.com/kyverno/kyverno/pkg/logging" "github.com/kyverno/kyverno/pkg/registryclient" apiutils "github.com/kyverno/kyverno/pkg/utils/api" + "github.com/kyverno/kyverno/pkg/utils/jsonpointer" "github.com/kyverno/kyverno/pkg/utils/wildcard" "github.com/pkg/errors" "go.uber.org/multierr" @@ -170,8 +170,8 @@ func (iv *imageVerifier) verify(imageVerify kyvernov1.ImageVerification, images continue } - jmespath := engineUtils.JsonPointerToJMESPath(imageInfo.Pointer) - changed, err := iv.policyContext.JSONContext.HasChanged(jmespath) + pointer := jsonpointer.ParsePath(imageInfo.Pointer).JMESPath() + changed, err := iv.policyContext.JSONContext.HasChanged(pointer) if err == nil && !changed { iv.logger.V(4).Info("no change in image, skipping check", "image", image) continue diff --git a/pkg/engine/jsonutils/traverse.go b/pkg/engine/jsonutils/traverse.go index 738e48454806..136fe403b90a 100644 --- a/pkg/engine/jsonutils/traverse.go +++ b/pkg/engine/jsonutils/traverse.go @@ -3,6 +3,7 @@ package jsonutils import ( "fmt" "strconv" + "strings" "github.com/kyverno/kyverno/pkg/utils" ) @@ -101,7 +102,7 @@ func (t *Traversal) traverseObject(object map[string]interface{}, path string) ( } } - value, err := t.traverseJSON(element, path+"/"+key) + value, err := t.traverseJSON(element, path+"/"+strings.ReplaceAll(key, "/", `\/`)) if err != nil { return nil, err } diff --git a/pkg/engine/mutation_test.go b/pkg/engine/mutation_test.go index 6097af4f2bb4..7125f4e71654 100644 --- a/pkg/engine/mutation_test.go +++ b/pkg/engine/mutation_test.go @@ -1587,3 +1587,369 @@ func Test_RuleSelectorMutate(t *testing.T) { t.Error("rule 1 patches dont match") } } + +func Test_SpecialCharacters(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + policyRaw []byte + documentRaw []byte + want [][]byte + }{ + { + name: "regex_replace", + policyRaw: []byte(`{ + "apiVersion": "kyverno.io/v1", + "kind": "ClusterPolicy", + "metadata": { + "name": "regex-replace-all-demo" + }, + "spec": { + "background": false, + "rules": [ + { + "name": "retention-adjust", + "match": { + "any": [ + { + "resources": { + "kinds": [ + "Deployment" + ] + } + } + ] + }, + "mutate": { + "patchStrategicMerge": { + "metadata": { + "labels": { + "retention": "{{ regex_replace_all('([0-9])([0-9])', '{{ @ }}', '${1}0') }}" + } + } + } + } + } + ] + } +}`), + documentRaw: []byte(`{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "name": "busybox", + "labels": { + "app": "busybox", + "retention": "days_37" + } + }, + "spec": { + "replicas": 3, + "selector": { + "matchLabels": { + "app": "busybox" + } + }, + "template": { + "metadata": { + "labels": { + "app": "busybox" + } + }, + "spec": { + "containers": [ + { + "image": "busybox:1.28", + "name": "busybox", + "command": [ + "sleep", + "9999" + ] + } + ] + } + } + } +}`), + want: [][]byte{ + []byte(`{"op":"replace","path":"/metadata/labels/retention","value":"days_30"}`), + }, + }, + { + name: "regex_replace_with_slash", + policyRaw: []byte(`{ + "apiVersion": "kyverno.io/v1", + "kind": "ClusterPolicy", + "metadata": { + "name": "regex-replace-all-demo" + }, + "spec": { + "background": false, + "rules": [ + { + "name": "retention-adjust", + "match": { + "any": [ + { + "resources": { + "kinds": [ + "Deployment" + ] + } + } + ] + }, + "mutate": { + "patchStrategicMerge": { + "metadata": { + "labels": { + "corp.com/retention": "{{ regex_replace_all('([0-9])([0-9])', '{{ @ }}', '${1}0') }}" + } + } + } + } + } + ] + } +}`), + documentRaw: []byte(`{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "name": "busybox", + "labels": { + "app": "busybox", + "corp.com/retention": "days_37" + } + }, + "spec": { + "replicas": 3, + "selector": { + "matchLabels": { + "app": "busybox" + } + }, + "template": { + "metadata": { + "labels": { + "app": "busybox" + } + }, + "spec": { + "containers": [ + { + "image": "busybox:1.28", + "name": "busybox", + "command": [ + "sleep", + "9999" + ] + } + ] + } + } + } +}`), + want: [][]byte{ + []byte(`{"op":"replace","path":"/metadata/labels/corp.com~1retention","value":"days_30"}`), + }, + }, + { + name: "regex_replace_with_hyphen", + policyRaw: []byte(`{ + "apiVersion": "kyverno.io/v1", + "kind": "ClusterPolicy", + "metadata": { + "name": "regex-replace-all-demo" + }, + "spec": { + "background": false, + "rules": [ + { + "name": "retention-adjust", + "match": { + "any": [ + { + "resources": { + "kinds": [ + "Deployment" + ] + } + } + ] + }, + "mutate": { + "patchStrategicMerge": { + "metadata": { + "labels": { + "corp-retention": "{{ regex_replace_all('([0-9])([0-9])', '{{ @ }}', '${1}0') }}" + } + } + } + } + } + ] + } +}`), + documentRaw: []byte(`{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "name": "busybox", + "labels": { + "app": "busybox", + "corp-retention": "days_37" + } + }, + "spec": { + "replicas": 3, + "selector": { + "matchLabels": { + "app": "busybox" + } + }, + "template": { + "metadata": { + "labels": { + "app": "busybox" + } + }, + "spec": { + "containers": [ + { + "image": "busybox:1.28", + "name": "busybox", + "command": [ + "sleep", + "9999" + ] + } + ] + } + } + } +}`), + want: [][]byte{ + []byte(`{"op":"replace","path":"/metadata/labels/corp-retention","value":"days_30"}`), + }, + }, + { + name: "to_upper_with_hyphen", + policyRaw: []byte(`{ + "apiVersion": "kyverno.io/v1", + "kind": "ClusterPolicy", + "metadata": { + "name": "to-upper-demo" + }, + "spec": { + "rules": [ + { + "name": "format-deploy-zone", + "match": { + "any": [ + { + "resources": { + "kinds": [ + "Deployment" + ] + } + } + ] + }, + "mutate": { + "patchStrategicMerge": { + "metadata": { + "labels": { + "deploy-zone": "{{ to_upper('{{@}}') }}" + } + } + } + } + } + ] + } +}`), + documentRaw: []byte(`{ + "apiVersion": "apps/v1", + "kind": "Deployment", + "metadata": { + "name": "busybox", + "labels": { + "app": "busybox", + "deploy-zone": "eu-central-1" + } + }, + "spec": { + "replicas": 3, + "selector": { + "matchLabels": { + "app": "busybox" + } + }, + "template": { + "metadata": { + "labels": { + "app": "busybox" + } + }, + "spec": { + "containers": [ + { + "image": "busybox:1.28", + "name": "busybox", + "command": [ + "sleep", + "9999" + ] + } + ] + } + } + } +}`), + want: [][]byte{ + []byte(`{"op":"replace","path":"/metadata/labels/deploy-zone","value":"EU-CENTRAL-1"}`), + }, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + // Parse policy document. + var policy kyverno.ClusterPolicy + if err := json.Unmarshal(tt.policyRaw, &policy); err != nil { + t.Error(err) + } + + // Parse resource document. + resource, err := utils.ConvertToUnstructured(tt.documentRaw) + if err != nil { + t.Fatalf("ConvertToUnstructured() error = %v", err) + } + + // Create JSON context and add the resource. + ctx := context.NewContext() + err = ctx.AddResource(resource.Object) + if err != nil { + t.Fatalf("ctx.AddResource() error = %v", err) + } + + // Create policy context. + policyContext := &PolicyContext{ + Policy: &policy, + JSONContext: ctx, + NewResource: *resource, + } + + // Mutate and make sure that we got the expected amount of rules. + patches := Mutate(policyContext).GetPatches() + if !reflect.DeepEqual(patches, tt.want) { + t.Errorf("Mutate() got patches %s, expected %s", patches, tt.want) + } + }) + } +} diff --git a/pkg/engine/utils/utils.go b/pkg/engine/utils/utils.go index 6df018b33f71..7ec66a1a2d2e 100644 --- a/pkg/engine/utils/utils.go +++ b/pkg/engine/utils/utils.go @@ -1,10 +1,6 @@ package utils import ( - "fmt" - "strconv" - "strings" - jsonpatch "github.com/evanphx/json-patch/v5" commonAnchor "github.com/kyverno/kyverno/pkg/engine/anchor" "github.com/kyverno/kyverno/pkg/logging" @@ -72,28 +68,3 @@ func GetAnchorsFromMap(anchorsMap map[string]interface{}) map[string]interface{} return result } - -func JsonPointerToJMESPath(jsonPointer string) string { - var sb strings.Builder - tokens := strings.Split(jsonPointer, "/") - i := 0 - for _, t := range tokens { - if t == "" { - continue - } - - if _, err := strconv.Atoi(t); err == nil { - sb.WriteString(fmt.Sprintf("[%s]", t)) - continue - } - - if i > 0 { - sb.WriteString(".") - } - - sb.WriteString(t) - i++ - } - - return sb.String() -} diff --git a/pkg/engine/utils/utils_test.go b/pkg/engine/utils/utils_test.go index 536780fb2958..173228350390 100644 --- a/pkg/engine/utils/utils_test.go +++ b/pkg/engine/utils/utils_test.go @@ -27,11 +27,3 @@ func TestGetAnchorsFromMap_ThereAreNoAnchors(t *testing.T) { actualMap := GetAnchorsFromMap(unmarshalled) assert.Equal(t, len(actualMap), 0) } - -func Test_JsonPointerToJMESPath(t *testing.T) { - assert.Equal(t, "a.b.c[1].d", JsonPointerToJMESPath("a/b/c/1//d")) - assert.Equal(t, "a.b.c[1].d", JsonPointerToJMESPath("/a/b/c/1/d")) - assert.Equal(t, "a.b.c[1].d", JsonPointerToJMESPath("/a/b/c/1/d/")) - assert.Equal(t, "a[1].b.c[1].d", JsonPointerToJMESPath("a/1/b/c/1/d")) - assert.Equal(t, "a[1].b.c[1].d[2]", JsonPointerToJMESPath("/a/1/b/c/1/d/2/")) -} diff --git a/pkg/engine/variables/vars.go b/pkg/engine/variables/vars.go index ce9e41bed614..ecc35d454161 100644 --- a/pkg/engine/variables/vars.go +++ b/pkg/engine/variables/vars.go @@ -15,6 +15,7 @@ import ( "github.com/kyverno/kyverno/pkg/engine/context" jsonUtils "github.com/kyverno/kyverno/pkg/engine/jsonutils" "github.com/kyverno/kyverno/pkg/engine/operator" + "github.com/kyverno/kyverno/pkg/utils/jsonpointer" ) var RegexVariables = regexp.MustCompile(`(?:^|[^\\])(\{\{(?:\{[^{}]*\}|[^{}])*\}\})`) @@ -352,13 +353,11 @@ func substituteVariablesIfAny(log logr.Logger, ctx context.EvalInterface, vr Var if _, err := ctx.Query("target"); err != nil { pathPrefix = "request.object" } - path := getJMESPath(data.Path) - var val string - if strings.HasPrefix(path, "[") { - val = fmt.Sprintf("%s%s", pathPrefix, path) - } else { - val = fmt.Sprintf("%s.%s", pathPrefix, path) - } + + // Convert path to JMESPath for current identifier. + // Skip 2 elements (e.g. mutate.overlay | validate.pattern) plus "foreach" if it is part of the pointer. + // Prefix the pointer with pathPrefix. + val := jsonpointer.ParsePath(data.Path).SkipPast("foreach").SkipN(2).Prepend(strings.Split(pathPrefix, ".")...).JMESPath() variable = strings.Replace(variable, "@", val, -1) } @@ -421,20 +420,6 @@ func IsDeleteRequest(ctx context.EvalInterface) bool { return false } -var regexPathDigit = regexp.MustCompile(`\.?([\d])\.?`) - -// getJMESPath converts path to JMESPath format -func getJMESPath(rawPath string) string { - tokens := strings.Split(rawPath, "/")[3:] // skip "/" + 2 elements (e.g. mutate.overlay | validate.pattern) - if strings.Contains(rawPath, "foreach") { - tokens = strings.Split(rawPath, "/")[5:] // skip "/" + 4 elements (e.g. mutate.foreach/list/overlay | validate.mutate.foreach/list/pattern) - } - path := strings.Join(tokens, ".") - b := regexPathDigit.ReplaceAll([]byte(path), []byte("[$1].")) - result := strings.Trim(string(b), ".") - return result -} - func substituteVarInPattern(prefix, pattern, variable string, value interface{}) (string, error) { var stringToSubstitute string diff --git a/pkg/engine/variables/vars_test.go b/pkg/engine/variables/vars_test.go index 445bf2cf8643..7fd5b8da5094 100644 --- a/pkg/engine/variables/vars_test.go +++ b/pkg/engine/variables/vars_test.go @@ -1177,15 +1177,3 @@ func Test_ReplacingEscpNestedVariableWhenDeleting(t *testing.T) { assert.Equal(t, fmt.Sprintf("%v", pattern), "{{request.object.metadata.annotations.target}}") } - -func Test_getJMESPath(t *testing.T) { - assert.Equal(t, "spec.containers[0]", getJMESPath("/validate/pattern/spec/containers/0")) - assert.Equal(t, "spec.containers[0].volumes[1]", getJMESPath("/validate/pattern/spec/containers/0/volumes/1")) - assert.Equal(t, "[0]", getJMESPath("/mutate/overlay/0")) -} - -func Test_getJMESPathForForeach(t *testing.T) { - assert.Equal(t, "spec.containers[0]", getJMESPath("/validate/foreach/0/pattern/spec/containers/0")) - assert.Equal(t, "spec.containers[0].volumes[1]", getJMESPath("/validate/foreach/0/pattern/spec/containers/0/volumes/1")) - assert.Equal(t, "[0]", getJMESPath("/mutate/foreach/0/overlay/0")) -} diff --git a/pkg/utils/jsonpointer/pointer.go b/pkg/utils/jsonpointer/pointer.go new file mode 100644 index 000000000000..99e53e18ac24 --- /dev/null +++ b/pkg/utils/jsonpointer/pointer.go @@ -0,0 +1,244 @@ +package jsonpointer + +import ( + "fmt" + "strconv" + "strings" + "unicode" + "unicode/utf8" + + "k8s.io/utils/strings/slices" +) + +// Pointer is a JSON pointer that can be retrieved as either as a RFC6901 string or as a JMESPath formatted string. +type Pointer []string + +// unquoted identifiers must only contain these characters. +var unquotedFirstCharRangeTable = &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: '(', Hi: '(', Stride: 1}, // Special non-standard. Used by policy documents for matching attributes. + {Lo: 'A', Hi: 'Z', Stride: 1}, + {Lo: '_', Hi: '_', Stride: 1}, + {Lo: 'a', Hi: 'z', Stride: 1}, + }, +} + +// unquoted identifiers can contain any combination of these runes. +var unquotedStringRangeTable = &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: ')', Hi: ')', Stride: 1}, // Special non-standard. Used by policy documents for matching attributes. + {Lo: '0', Hi: '9', Stride: 1}, + {Lo: 'A', Hi: 'Z', Stride: 1}, + {Lo: '_', Hi: '_', Stride: 1}, + {Lo: 'a', Hi: 'z', Stride: 1}, + }, +} + +// a quoted identifier can contain any of these characters as is. +var unescapedCharRangeTable = &unicode.RangeTable{ + R16: []unicode.Range16{ + {Lo: 0x20, Hi: 0x21, Stride: 1}, + {Lo: 0x23, Hi: 0x5B, Stride: 1}, + {Lo: 0x5D, Hi: 0x1EFF, Stride: 1}, + }, + R32: []unicode.Range32{ + {Lo: 0x1000, Hi: 0x10FFFF, Stride: 1}, + }, + LatinOffset: 0x1EFF - unicode.MaxLatin1, +} + +// some special characters must be escaped to be possible to use inside a quoted identifier. +var escapeCharMap = map[rune]string{ + '"': `\"`, // quotation mark + '\\': `\\`, // reverse solidus + '/': `\/`, // solidus + '\b': `\b`, // backspace + '\f': `\f`, // form feed + '\n': `\n`, // line feed + '\r': `\r`, // carriage return + '\t': `\t`, // tab +} + +const initialCapacity = 10 // pointers should start with a non-zero capacity to lower the amount of re-allocations done by append. + +// New will return an empty Pointer. +func New() Pointer { + return make([]string, 0, initialCapacity) +} + +// Parse will parse the string as a JSON pointer according to RFC 6901. +func Parse(s string) Pointer { + pointer := New() + + replacer := strings.NewReplacer("~1", "/", "~0", "~", `\\`, `\`, `\"`, `"`) + + for _, component := range strings.FieldsFunc(s, func(r rune) bool { + return r == '/' + }) { + pointer = append(pointer, replacer.Replace(component)) + } + + return pointer +} + +// ParsePath will parse the raw path and return it in the form of a Pointer. +func ParsePath(rawPath string) Pointer { + // Start with a slice with a non-zero capacity to avoid reallocation for most paths. + pointer := New() + + // Use a string builder and a flush function to append path components to the slice. + sb := strings.Builder{} + + flush := func() { + s := sb.String() + if s != "" { + pointer = append(pointer, s) + } + sb.Reset() + } + + var pos int + var escaped, quoted bool + + for i, width := 0, 0; i <= len(rawPath); i += width { + var r rune + r, width = utf8.DecodeRuneInString(rawPath[i:]) + if r == utf8.RuneError && width == 1 { + break + } + + switch { + case escaped: // previous character was a backslash. + sb.WriteRune(r) + escaped = !escaped + case r == '\\': // escape character + escaped = !escaped + case r == '"': // quoted strings + if quoted { + s, _ := strconv.Unquote(rawPath[pos : i+width]) + sb.WriteString(s) + } + quoted = !quoted + case r == '/' && !quoted: + flush() + case r == utf8.RuneError: // end of string + flush() + return pointer + default: + sb.WriteRune(r) + } + + pos = i + width + } + + // This is unreachable but we must return something. + return pointer +} + +// JMESPath will return the Pointer in the form of a JMESPath string. +func (p Pointer) JMESPath() string { + sb := strings.Builder{} + + for _, component := range p { + // Components that are valid unsigned integers are treated as indices. + if _, err := strconv.ParseUint(component, 10, 64); err == nil { + sb.WriteRune('[') + sb.WriteString(component) + sb.WriteRune(']') + continue + } + + // Write a dot before we write anything, as long as buffer is not empty. + if sb.Len() > 0 { + sb.WriteRune('.') + } + + // If the component starts with a character that is valid as an initial character for an identifier + // and the remaining characters are also valid for an unquoted identifier then we can append it to + // the JMESPath as is. + if ch, _ := utf8.DecodeRuneInString(component); unicode.Is(unquotedFirstCharRangeTable, ch) && + strings.IndexFunc(component, func(r rune) bool { + return !unicode.Is(unquotedStringRangeTable, r) + }) == -1 { + sb.WriteString(component) + continue + } + + // The component contains characters that are not allowed for unquoted identifiers, so we need to take some extra + // steps to ensure that it's a valid, quoted identifier. + sb.WriteRune('"') + for _, r := range component { + // Any character in the range table of allowed runes can be written as is. + if unicode.Is(unescapedCharRangeTable, r) { + sb.WriteRune(r) + continue + } + + // Convert special characters to their escaped sequence. + if escaped, ok := escapeCharMap[r]; ok { + sb.WriteString(escaped) + continue + } + + // All other characters must be written as unicode escape sequences ay 16 bits a piece. + if i := utf8.RuneLen(r); i <= 2 { + // Rune is 1 or 2 bytes. + _, _ = fmt.Fprintf(&sb, "\\u%04x", r&0xffff) + } else { + _, _ = fmt.Fprintf(&sb, "\\u%04x", r&0xffff) + _, _ = fmt.Fprintf(&sb, "\\u%04x", r>>16) + } + } + sb.WriteRune('"') + } + + // Return the JMESPath. + return sb.String() +} + +// String will return the pointer as a string (RFC6901). +func (p Pointer) String() string { + sb := strings.Builder{} + + replacer := strings.NewReplacer("~", "~0", "/", "~1", `\`, `\\`, `"`, `\"`) + + for _, component := range p { + if sb.Len() > 0 { + sb.WriteRune('/') + } + + _, _ = replacer.WriteString(&sb, component) + } + + // Return the pointer. + return sb.String() +} + +// Append will return a Pointer with the strings appended. +func (p Pointer) Append(s ...string) Pointer { + return append(p, s...) +} + +// Prepend will return a Pointer prefixed with the specified strings. +func (p Pointer) Prepend(s ...string) Pointer { + return append(s, p...) +} + +// AppendPath will parse the string as a JSON pointer and return a new pointer. +func (p Pointer) AppendPath(s string) Pointer { + return append(p, ParsePath(s)...) +} + +// SkipN will return a new Pointer where the first N element are stripped. +func (p Pointer) SkipN(n int) Pointer { + if n > len(p)-1 { + return []string{} + } + + return p[n:] +} + +// SkipPast will return a new Pointer where every element upto and including the specified string has been stripped off. +func (p Pointer) SkipPast(s string) Pointer { + return p[slices.Index(p, s)+1:] +} diff --git a/pkg/utils/jsonpointer/pointer_test.go b/pkg/utils/jsonpointer/pointer_test.go new file mode 100644 index 000000000000..08024e2ea8b6 --- /dev/null +++ b/pkg/utils/jsonpointer/pointer_test.go @@ -0,0 +1,227 @@ +package jsonpointer + +import ( + "reflect" + "testing" +) + +func TestParsePath(t *testing.T) { + type args struct { + rawPath string + } + tests := []struct { + name string + args args + want Pointer + }{ + { + name: "plain", + args: args{ + rawPath: "a/b/c", + }, + want: []string{"a", "b", "c"}, + }, + { + name: "hyphen", + args: args{ + rawPath: "a/b-b/c", + }, + want: []string{"a", "b-b", "c"}, + }, + { + name: "quotes", + args: args{ + rawPath: `a/"b/b"/c`, + }, + want: []string{"a", "b/b", "c"}, + }, + { + name: "escaped_slash", + args: args{ + rawPath: `a/b\/b/c`, + }, + want: []string{"a", "b/b", "c"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ParsePath(tt.args.rawPath); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ParsePath() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPointer_Append(t *testing.T) { + type args struct { + s []string + } + tests := []struct { + name string + p Pointer + args args + want Pointer + }{ + { + p: []string{"a", "b"}, + args: args{ + s: []string{"c", "d"}, + }, + want: []string{"a", "b", "c", "d"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.p.Append(tt.args.s...); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Append() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPointer_AppendPath(t *testing.T) { + type args struct { + s string + } + tests := []struct { + name string + p Pointer + args args + want Pointer + }{ + { + name: "", + p: []string{"a", "b", "c"}, + args: args{ + s: `d/e\/e/f`, + }, + want: []string{"a", "b", "c", "d", "e/e", "f"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.p.AppendPath(tt.args.s); !reflect.DeepEqual(got, tt.want) { + t.Errorf("AppendPath() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPointer_JMESPath(t *testing.T) { + tests := []struct { + name string + p Pointer + want string + }{ + { + p: []string{"a", "b", "c", "3", "e/e", "f"}, + want: `a.b.c[3]."e/e".f`, + }, + { + p: []string{"a", "b", "c", "3", "e/e", "f"}, + want: `a.b.c[3]."e/e".f`, + }, + { + name: "hangul", + p: []string{"a", "바나나", "c", "3", "e/e", "f"}, + want: `a."바나나".c[3]."e/e".f`, + }, + { + name: "tab", + p: []string{"a", "a\tb", "c"}, + want: `a."a\tb".c`, + }, + { + name: "bell", + p: []string{"a", "a\aa", "c", "3", "e/e", "f"}, + want: `a."a\u0007a".c[3]."e/e".f`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.p.JMESPath(); got != tt.want { + t.Errorf("JMESPath() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPointer_String(t *testing.T) { + tests := []struct { + name string + p Pointer + want string + }{ + { + p: []string{"a", "b", "c"}, + want: "a/b/c", + }, + { + p: []string{"a", "b/b", "c~c"}, + want: `a/b~1b/c~0c`, + }, + { + p: []string{"a", `b\b`, `c"c`}, + want: `a/b\\b/c\"c`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.p.String(); got != tt.want { + t.Errorf("String() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPointer_Prepend(t *testing.T) { + type args struct { + s []string + } + tests := []struct { + name string + p Pointer + args args + want Pointer + }{ + { + p: []string{"c", "d", "e"}, + args: args{ + s: []string{"a", "b"}, + }, + want: []string{"a", "b", "c", "d", "e"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.p.Prepend(tt.args.s...); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Prepend() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestParse(t *testing.T) { + type args struct { + s string + } + tests := []struct { + name string + args args + want Pointer + }{ + { + args: args{ + s: "a/b~1c/~0d", + }, + want: []string{"a", "b/c", "~d"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Parse(tt.args.s); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Parse() = %v, want %v", got, tt.want) + } + }) + } +} From fcca45b1cf321fcdd302c2ef09b86d605846e11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Thu, 10 Nov 2022 18:01:56 +0100 Subject: [PATCH 52/55] fix: send notification when stoping watching resource in reports system (#5298) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: send notification when stoping watching resource in reports system Signed-off-by: Charles-Edouard Brétéché * add kuttl test Signed-off-by: Charles-Edouard Brétéché * rework Signed-off-by: Charles-Edouard Brétéché * readme Signed-off-by: Charles-Edouard Brétéché Signed-off-by: Charles-Edouard Brétéché --- pkg/controllers/report/resource/controller.go | 10 +++++++--- .../00-policy.yaml | 6 ++++++ .../01-pod.yaml | 4 ++++ .../02-background-scan-report.yaml | 4 ++++ .../03-delete-report.yaml | 8 ++++++++ .../background-scan-report-deletion/README.md | 13 +++++++++++++ .../background-scan-report-assert.yaml | 14 ++++++++++++++ .../background-scan-report-error.yaml | 7 +++++++ .../background-scan-report-deletion/pod.yaml | 13 +++++++++++++ .../policy-assert.yaml | 9 +++++++++ .../policy.yaml | 18 ++++++++++++++++++ 11 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 test/conformance/kuttl/reports/background/background-scan-report-deletion/00-policy.yaml create mode 100644 test/conformance/kuttl/reports/background/background-scan-report-deletion/01-pod.yaml create mode 100644 test/conformance/kuttl/reports/background/background-scan-report-deletion/02-background-scan-report.yaml create mode 100644 test/conformance/kuttl/reports/background/background-scan-report-deletion/03-delete-report.yaml create mode 100644 test/conformance/kuttl/reports/background/background-scan-report-deletion/README.md create mode 100644 test/conformance/kuttl/reports/background/background-scan-report-deletion/background-scan-report-assert.yaml create mode 100644 test/conformance/kuttl/reports/background/background-scan-report-deletion/background-scan-report-error.yaml create mode 100644 test/conformance/kuttl/reports/background/background-scan-report-deletion/pod.yaml create mode 100644 test/conformance/kuttl/reports/background/background-scan-report-deletion/policy-assert.yaml create mode 100644 test/conformance/kuttl/reports/background/background-scan-report-deletion/policy.yaml diff --git a/pkg/controllers/report/resource/controller.go b/pkg/controllers/report/resource/controller.go index 1599fb26e0db..51f388e1c699 100644 --- a/pkg/controllers/report/resource/controller.go +++ b/pkg/controllers/report/resource/controller.go @@ -197,12 +197,16 @@ func (c *controller) updateDynamicWatchers(ctx context.Context) error { } } } + oldDynamicWatcher := c.dynamicWatchers + c.dynamicWatchers = dynamicWatchers // shutdown remaining watcher - for gvr, watcher := range c.dynamicWatchers { + for gvr, watcher := range oldDynamicWatcher { watcher.watcher.Stop() - delete(c.dynamicWatchers, gvr) + delete(oldDynamicWatcher, gvr) + for uid, resource := range watcher.hashes { + c.notify(uid, watcher.gvk, resource) + } } - c.dynamicWatchers = dynamicWatchers return nil } diff --git a/test/conformance/kuttl/reports/background/background-scan-report-deletion/00-policy.yaml b/test/conformance/kuttl/reports/background/background-scan-report-deletion/00-policy.yaml new file mode 100644 index 000000000000..b088ed7601b5 --- /dev/null +++ b/test/conformance/kuttl/reports/background/background-scan-report-deletion/00-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- policy.yaml +assert: +- policy-assert.yaml diff --git a/test/conformance/kuttl/reports/background/background-scan-report-deletion/01-pod.yaml b/test/conformance/kuttl/reports/background/background-scan-report-deletion/01-pod.yaml new file mode 100644 index 000000000000..581b58e74288 --- /dev/null +++ b/test/conformance/kuttl/reports/background/background-scan-report-deletion/01-pod.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: +- pod.yaml diff --git a/test/conformance/kuttl/reports/background/background-scan-report-deletion/02-background-scan-report.yaml b/test/conformance/kuttl/reports/background/background-scan-report-deletion/02-background-scan-report.yaml new file mode 100644 index 000000000000..c53f75c4ac15 --- /dev/null +++ b/test/conformance/kuttl/reports/background/background-scan-report-deletion/02-background-scan-report.yaml @@ -0,0 +1,4 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +assert: +- background-scan-report-assert.yaml \ No newline at end of file diff --git a/test/conformance/kuttl/reports/background/background-scan-report-deletion/03-delete-report.yaml b/test/conformance/kuttl/reports/background/background-scan-report-deletion/03-delete-report.yaml new file mode 100644 index 000000000000..2983b4a9150a --- /dev/null +++ b/test/conformance/kuttl/reports/background/background-scan-report-deletion/03-delete-report.yaml @@ -0,0 +1,8 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: podsecurity-subrule-restricted +error: +- background-scan-report-error.yaml diff --git a/test/conformance/kuttl/reports/background/background-scan-report-deletion/README.md b/test/conformance/kuttl/reports/background/background-scan-report-deletion/README.md new file mode 100644 index 000000000000..e61d07927bc0 --- /dev/null +++ b/test/conformance/kuttl/reports/background/background-scan-report-deletion/README.md @@ -0,0 +1,13 @@ +## Description + +This test creates a policy and a pod, it then expects a background scan report to be created for the pod. +When the policy is deleted, the background scan report should also be deleted. + +## Steps + +1. - Create a cluster policy + - Assert the policy becomes ready +1. - Create a pod +1. - Assert a background scan report is created for the pod and contains the right summary +1. - Delete the policy + - Assert the background scan report is deleted for the pod diff --git a/test/conformance/kuttl/reports/background/background-scan-report-deletion/background-scan-report-assert.yaml b/test/conformance/kuttl/reports/background/background-scan-report-deletion/background-scan-report-assert.yaml new file mode 100644 index 000000000000..adcfed50343c --- /dev/null +++ b/test/conformance/kuttl/reports/background/background-scan-report-deletion/background-scan-report-assert.yaml @@ -0,0 +1,14 @@ +apiVersion: kyverno.io/v1alpha2 +kind: BackgroundScanReport +metadata: + ownerReferences: + - apiVersion: v1 + kind: Pod + name: badpod01 +spec: + summary: + error: 0 + fail: 1 + pass: 0 + skip: 0 + warn: 0 diff --git a/test/conformance/kuttl/reports/background/background-scan-report-deletion/background-scan-report-error.yaml b/test/conformance/kuttl/reports/background/background-scan-report-deletion/background-scan-report-error.yaml new file mode 100644 index 000000000000..a3ddbbea2f6b --- /dev/null +++ b/test/conformance/kuttl/reports/background/background-scan-report-deletion/background-scan-report-error.yaml @@ -0,0 +1,7 @@ +apiVersion: kyverno.io/v1alpha2 +kind: BackgroundScanReport +metadata: + ownerReferences: + - apiVersion: v1 + kind: Pod + name: badpod01 diff --git a/test/conformance/kuttl/reports/background/background-scan-report-deletion/pod.yaml b/test/conformance/kuttl/reports/background/background-scan-report-deletion/pod.yaml new file mode 100644 index 000000000000..2b73ac5fb5ce --- /dev/null +++ b/test/conformance/kuttl/reports/background/background-scan-report-deletion/pod.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: badpod01 +spec: + containers: + - name: container01 + image: dummyimagename + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault diff --git a/test/conformance/kuttl/reports/background/background-scan-report-deletion/policy-assert.yaml b/test/conformance/kuttl/reports/background/background-scan-report-deletion/policy-assert.yaml new file mode 100644 index 000000000000..c21f7dd31075 --- /dev/null +++ b/test/conformance/kuttl/reports/background/background-scan-report-deletion/policy-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: podsecurity-subrule-restricted +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/reports/background/background-scan-report-deletion/policy.yaml b/test/conformance/kuttl/reports/background/background-scan-report-deletion/policy.yaml new file mode 100644 index 000000000000..87c0e5f7bdaf --- /dev/null +++ b/test/conformance/kuttl/reports/background/background-scan-report-deletion/policy.yaml @@ -0,0 +1,18 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: podsecurity-subrule-restricted +spec: + background: true + rules: + - match: + any: + - resources: + kinds: + - Pod + name: restricted + validate: + podSecurity: + level: restricted + version: latest + validationFailureAction: audit From 6091af6fba247b829734cab868a73f028cfbf709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Fri, 11 Nov 2022 07:46:27 +0100 Subject: [PATCH 53/55] fix: wrong logger used (#5311) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché --- go.mod | 2 - go.sum | 79 ------------------------------------- pkg/policy/updaterequest.go | 5 +-- pkg/policy/validate.go | 3 +- 4 files changed, 3 insertions(+), 86 deletions(-) diff --git a/go.mod b/go.mod index 409012aab468..7162b07e082f 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,6 @@ require ( github.com/evanphx/json-patch v5.6.0+incompatible github.com/evanphx/json-patch/v5 v5.6.0 github.com/fatih/color v1.13.0 - github.com/gardener/controller-manager-library v0.2.0 github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 github.com/go-git/go-billy/v5 v5.3.1 github.com/go-git/go-git/v5 v5.4.2 @@ -93,7 +92,6 @@ require ( github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect - github.com/Masterminds/semver v1.5.0 // indirect github.com/Microsoft/go-winio v0.6.0 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad // indirect diff --git a/go.sum b/go.sum index 1e0e54c6e7b8..74406307c035 100644 --- a/go.sum +++ b/go.sum @@ -203,12 +203,10 @@ github.com/IGLOU-EU/go-wildcard v1.0.3/go.mod h1:/qeV4QLmydCbwH0UMQJmXDryrFKJknW github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Masterminds/sprig v2.16.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= @@ -245,7 +243,6 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= -github.com/ahmetb/gen-crd-api-reference-docs v0.1.5/go.mod h1:P/XzJ+c2+khJKNKABcm2biRwk2QAuwbLf8DlXuaL7WM= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/jsonschema v0.0.0-20180308105923-f2c93856175a/go.mod h1:qpebaTNSsyUn5rPSJMsfqEtDw71TTggXM6stUDI16HA= github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= @@ -309,7 +306,6 @@ github.com/apex/log v1.1.4/go.mod h1:AlpoD9aScyQfJDVHmLMEcx4oU6LqzkWp4Mg9GdAcEvQ github.com/apex/logs v0.0.4/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo= github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE= github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys= -github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30/go.mod h1:4AJxUpXUhv4N+ziTvIcWWXgeorXpxPZOfk9HdEVr96M= github.com/aquilax/truncate v1.0.0 h1:UgIGS8U/aZ4JyOJ2h3xcF5cSQ06+gGBnjxH2RUHJe0U= github.com/aquilax/truncate v1.0.0/go.mod h1:BeMESIDMlvlS3bmg4BVvBbbZUNwWtS8uzYPAKXwwhLw= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= @@ -504,13 +500,9 @@ github.com/containerd/stargz-snapshotter/estargz v0.12.0 h1:idtwRTLjk2erqiYhPWy2 github.com/containerd/stargz-snapshotter/estargz v0.12.0/go.mod h1:AIQ59TewBFJ4GOPEQXujcrJ/EKxh5xXZegW1rkR1P/M= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= -github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.17+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-oidc/v3 v3.0.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= @@ -527,7 +519,6 @@ github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -548,7 +539,6 @@ github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3E github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg= github.com/danieljoos/wincred v1.1.1/go.mod h1:gSBQmTx6G0VmLowygiA7ZD0p0E09HJ68vta8z/RT2d0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= -github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -578,7 +568,6 @@ github.com/docker/cli v20.10.9+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHv github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20200319182547-c7ad2b866182/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= @@ -629,7 +618,6 @@ github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E github.com/esimonov/ifshort v1.0.2/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE= github.com/etcd-io/gofail v0.0.0-20190801230047-ad7f989257ca/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE= github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= -github.com/evanphx/json-patch v4.0.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -673,8 +661,6 @@ github.com/fullstorydev/grpcurl v1.8.7 h1:xJWosq3BQovQ4QrdPO72OrPiWuGgEsxY8ldYsJ github.com/fullstorydev/grpcurl v1.8.7/go.mod h1:pVtM4qe3CMoLaIzYS8uvTuDj2jVYmXqMUkZeijnXp/E= github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E= github.com/gabriel-vasile/mimetype v1.3.1/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8= -github.com/gardener/controller-manager-library v0.2.0 h1:MyxL0k10lwBf8TXkbnuN+oEOkHwCNhp3SKj+ad2w62s= -github.com/gardener/controller-manager-library v0.2.0/go.mod h1:oCK7fW2VpsMhmUh5c6cOhsN8p9Tth1OM3rRtogDF11k= github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -908,7 +894,6 @@ github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSC github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.5/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= github.com/gobuffalo/flect v0.2.2/go.mod h1:vmkQwuZYhN5Pc4ljYQZzP+1sq+NEkK+lh20jmEmX3jc= github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= @@ -941,7 +926,6 @@ github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -976,7 +960,6 @@ github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71 github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v0.0.0-20181025225059-d3de96c4c28e/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -1073,7 +1056,6 @@ github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVgg github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= github.com/google/go-replayers/httpreplay v0.1.0/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= -github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -1142,7 +1124,6 @@ github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK github.com/googleapis/gax-go/v2 v2.5.1 h1:kBRZU0PSuI7PspsSb/ChWoVResUcwNVIdpB049pKTiw= github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= -github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.3/go.mod h1:TRWw1s4gxBGjSe301Dai3c7wXJAZy57+/6tawkOvqHQ= @@ -1177,11 +1158,9 @@ github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnq github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= -github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= @@ -1189,7 +1168,6 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaW github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.2/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -1303,7 +1281,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= @@ -1362,7 +1339,6 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -1571,7 +1547,6 @@ github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/f github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= @@ -1651,7 +1626,6 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -1836,7 +1810,6 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -1928,7 +1901,6 @@ github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= -github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.5-0.20210205191134-5ec6847320e5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= @@ -1991,7 +1963,6 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -2103,7 +2074,6 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= -github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= @@ -2267,7 +2237,6 @@ go.opentelemetry.io/proto/otlp v0.16.0 h1:WHzDWdXUvbc5bG2ObdrGfaNpQz7ft7QN9HHmJl go.opentelemetry.io/proto/otlp v0.16.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= -go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -2284,7 +2253,6 @@ go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= @@ -2294,7 +2262,6 @@ go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95a go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= @@ -2363,9 +2330,7 @@ golang.org/x/crypto v0.0.0-20221012134737-56aed061732a h1:NmSIgad6KjE6VvHciPZuNR golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= @@ -2408,7 +2373,6 @@ golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2433,7 +2397,6 @@ golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -2548,7 +2511,6 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 h1:cu5kTvlzcw1Q5S9f5ip1/cpiB4nXvw1XYzFPGgzLUOY= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2696,7 +2658,6 @@ golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220919170432-7a66f970e087 h1:tPwmk4vmvVCMdr98VgL4JH+qZxPL8fqlUOHnyOM8N3w= golang.org/x/term v0.0.0-20220919170432-7a66f970e087/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2729,8 +2690,6 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190213192042-740235f6c0d8/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -2859,10 +2818,7 @@ golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNq gomodules.xyz/jsonpatch/v2 v2.1.0/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -3175,7 +3131,6 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -3197,39 +3152,29 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.4/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48= -k8s.io/api v0.16.4/go.mod h1:AtzMnsR45tccQss5q8RnF+W8L81DH6XwXwo/joEx9u0= k8s.io/api v0.19.7/go.mod h1:KTryDUT3l6Mtv7K2J2486PNL9DBns3wOYTkGR+iz63Y= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8= k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg= k8s.io/api v0.25.2 h1:v6G8RyFcwf0HR5jQGIAYlvtRNrxMJQG1xJzaSeVnIS8= k8s.io/api v0.25.2/go.mod h1:qP1Rn4sCVFwx/xIhe+we2cwBLTXNcheRyYXwajonhy0= -k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783/go.mod h1:xvae1SZB3E17UpV59AWc271W/Ph25N+bjPyR63X6tPY= -k8s.io/apiextensions-apiserver v0.16.4/go.mod h1:HYQwjujEkXmQNhap2C9YDdIVOSskGZ3et0Mvjcyjbto= k8s.io/apiextensions-apiserver v0.19.7/go.mod h1:XJNNtjISNNePDEUClHt/igzMpQcmjVVh88QH+PKztPU= k8s.io/apiextensions-apiserver v0.20.1/go.mod h1:ntnrZV+6a3dB504qwC5PN/Yg9PBiDNt1EVqbW2kORVk= k8s.io/apiextensions-apiserver v0.20.2/go.mod h1:F6TXp389Xntt+LUq3vw6HFOLttPa0V8821ogLGwb6Zs= k8s.io/apiextensions-apiserver v0.25.2 h1:8uOQX17RE7XL02ngtnh3TgifY7EhekpK+/piwzQNnBo= k8s.io/apiextensions-apiserver v0.25.2/go.mod h1:iRwwRDlWPfaHhuBfQ0WMa5skdQfrE18QXJaJvIDLvE8= k8s.io/apimachinery v0.0.0-20190703205208-4cfb76a8bf76/go.mod h1:M2fZgZL9DbLfeJaPBCDqSqNsdsmLN+V29knYJnIXlMA= -k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655/go.mod h1:nL6pwRT8NgfF8TT68DBI8uEePRt89cSvoXUVqbkWHq4= -k8s.io/apimachinery v0.16.4/go.mod h1:llRdnznGEAqC3DcNm6yEj472xaFVfLM7hnYofMb12tQ= k8s.io/apimachinery v0.19.7/go.mod h1:6sRbGRAVY5DOCuZwB5XkqguBqpqLU6q/kOaOdk29z6Q= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.21.3/go.mod h1:H/IM+5vH9kZRNJ4l3x/fXP/5bOPJaVP/guptnZPeCFI= k8s.io/apimachinery v0.25.2 h1:WbxfAjCx+AeN8Ilp9joWnyJ6xu9OMeS/fsfjK/5zaQs= k8s.io/apimachinery v0.25.2/go.mod h1:hqqA1X0bsgsxI6dXsJ4HnNTBOmJNxyPp8dw3u2fSHwA= -k8s.io/apiserver v0.0.0-20190918160949-bfa5e2e684ad/go.mod h1:XPCXEwhjaFN29a8NldXA901ElnKeKLrLtREO9ZhFyhg= -k8s.io/apiserver v0.16.4/go.mod h1:kbLJOak655g6W7C+muqu1F76u9wnEycfKMqbVaXIdAc= k8s.io/apiserver v0.19.7/go.mod h1:DmWVQggNePspa+vSsVytVbS3iBSDTXdJVt0akfHacKk= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.2/go.mod h1:2nKd93WyMhZx4Hp3RfgH2K5PhwyTrprrkWYnI7id7jA= k8s.io/cli-runtime v0.25.2 h1:XOx+SKRjBpYMLY/J292BHTkmyDffl/qOx3YSuFZkTuc= k8s.io/cli-runtime v0.25.2/go.mod h1:OQx3+/0st6x5YpkkJQlEWLC73V0wHsOFMC1/roxV8Oc= -k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90/go.mod h1:J69/JveO6XESwVgG53q3Uz5OSfgsv4uxpScmmyYOOlk= -k8s.io/client-go v0.16.4/go.mod h1:ZgxhFDxSnoKY0J0U2/Y1C8obKDdlhGPZwA7oHH863Ok= k8s.io/client-go v0.19.7/go.mod h1:iytGI7S3kmv6bWnn+bSQUE4VlrEi4YFssvVB7J7Hvqg= k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= k8s.io/client-go v0.20.2/go.mod h1:kH5brqWqp7HDxUFKoEgiI4v8G1xzbe9giaCenUWJzgE= @@ -3237,31 +3182,20 @@ k8s.io/client-go v0.21.3/go.mod h1:+VPhCgTsaFmGILxR/7E1N0S+ryO010QBeNCv5JwRGYU= k8s.io/client-go v0.25.2 h1:SUPp9p5CwM0yXGQrwYurw9LWz+YtMwhWd0GqOsSiefo= k8s.io/client-go v0.25.2/go.mod h1:i7cNU7N+yGQmJkewcRD2+Vuj4iz7b30kI8OcL3horQ4= k8s.io/cloud-provider v0.19.7/go.mod h1:aO/VpUwkG+JQN7ZXc5WBLZ5NBXuq/Y5B6vri6U94PZ8= -k8s.io/code-generator v0.0.0-20190912054826-cd179ad6a269/go.mod h1:V5BD6M4CyaN5m+VthcclXWsVcT1Hu+glwa1bi3MIsyE= -k8s.io/code-generator v0.16.4/go.mod h1:mJUgkl06XV4kstAnLHAIzJPVCOzVR+ZcfPIv4fUsFCY= k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= k8s.io/code-generator v0.20.1/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= k8s.io/code-generator v0.20.2/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg= -k8s.io/component-base v0.0.0-20190918160511-547f6c5d7090/go.mod h1:933PBGtQFJky3TEwYx4aEPZ4IxqhWh3R6DCmzqIn1hA= -k8s.io/component-base v0.16.4/go.mod h1:GYQ+4hlkEwdlpAp59Ztc4gYuFhdoZqiAJD1unYDJ3FM= k8s.io/component-base v0.19.7/go.mod h1:YX8spPBgwl3I6UGcSdQiEMAqRMSUsGQOW7SEr4+Qa3U= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= k8s.io/component-base v0.20.2/go.mod h1:pzFtCiwe/ASD0iV7ySMu8SYVJjCapNM9bjvk7ptpKh0= k8s.io/component-base v0.25.2 h1:Nve/ZyHLUBHz1rqwkjXm/Re6IniNa5k7KgzxZpTfSQY= k8s.io/component-base v0.25.2/go.mod h1:90W21YMr+Yjg7MX+DohmZLzjsBtaxQDDwaX4YxDkl60= k8s.io/csi-translation-lib v0.19.7/go.mod h1:WghizPQuzuygr2WdpgN2EjcNpDD2V4EAbxFXsgHgSBk= -k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/helm v2.11.0+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= -k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= @@ -3271,8 +3205,6 @@ k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= -k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= -k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kube-openapi v0.0.0-20210113233702-8566a335510f/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= @@ -3282,10 +3214,8 @@ k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhkl k8s.io/kubectl v0.25.2 h1:2993lTeVimxKSWx/7z2PiJxUILygRa3tmC4QhFaeioA= k8s.io/kubectl v0.25.2/go.mod h1:eoBGJtKUj7x38KXelz+dqVtbtbKwCqyKzJWmBHU0prg= k8s.io/legacy-cloud-providers v0.19.7/go.mod h1:dsZk4gH9QIwAtHQ8CK0Ps257xlfgoXE3tMkMNhW2xDU= -k8s.io/metrics v0.16.4/go.mod h1:dckkfqvaASo+NrzEmp8ST8yCc9hGt7lx9ABAILyDHx8= k8s.io/pod-security-admission v0.25.2 h1:sR3cU0fkfPQIXYIZllukBjLu8iElRl8R0Bskxsi15EU= k8s.io/pod-security-admission v0.25.2/go.mod h1:v3wLmYecYm4nJB/w2Qu2jBcmI3OaMwsUmcks7vibDnA= -k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= @@ -3295,11 +3225,6 @@ knative.dev/hack v0.0.0-20210325223819-b6ab329907d3/go.mod h1:PHt8x8yX5Z9pPquBEf knative.dev/hack v0.0.0-20210428122153-93ad9129c268/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI= knative.dev/pkg v0.0.0-20210331065221-952fdd90dbb0/go.mod h1:PD5g8hUCXq6iR3tILjmZeJBvQfXGnHMPKryq54qHJhg= knative.dev/pkg v0.0.0-20210510175900-4564797bf3b7/go.mod h1:fIl4l4OmZodkElyaHoT0LCF5wT+3+P/kinawQ4XlLtE= -modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= -modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= -modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= -modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= -modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= @@ -3317,7 +3242,6 @@ sigs.k8s.io/controller-runtime v0.8.2/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf sigs.k8s.io/controller-runtime v0.8.3/go.mod h1:U/l+DUopBc1ecfRZ5aviA9JDmGFQKvLf5YkZNx2e0sU= sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ= sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI= -sigs.k8s.io/controller-tools v0.2.4/go.mod h1:m/ztfQNocGYBgTTCmFdnK94uVvgxeZeE3LtJvd/jIzA= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM= @@ -3326,9 +3250,6 @@ sigs.k8s.io/kustomize/kyaml v0.13.9 h1:Qz53EAaFFANyNgyOEJbT/yoIHygK40/ZcvU3rgry2 sigs.k8s.io/kustomize/kyaml v0.13.9/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4= sigs.k8s.io/release-utils v0.7.3 h1:6pS8x6c5RmdUgR9qcg1LO6hjUzuE4Yo9TGZ3DemrZdM= sigs.k8s.io/release-utils v0.7.3/go.mod h1:n0mVez/1PZYZaZUTJmxewxH3RJ/Lf7JUDh7TG1CASOE= -sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= -sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= -sigs.k8s.io/structured-merge-diff v1.0.1/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= diff --git a/pkg/policy/updaterequest.go b/pkg/policy/updaterequest.go index 9ca229adcd7e..5bc2ff6e8d4e 100644 --- a/pkg/policy/updaterequest.go +++ b/pkg/policy/updaterequest.go @@ -4,7 +4,6 @@ import ( "context" "fmt" - "github.com/gardener/controller-manager-library/pkg/logger" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" common "github.com/kyverno/kyverno/pkg/background/common" @@ -129,7 +128,7 @@ func (pc *PolicyController) handleUpdateRequest(ur *kyvernov1beta1.UpdateRequest func (pc *PolicyController) listMutateURs(policyKey string, trigger *unstructured.Unstructured) []*kyvernov1beta1.UpdateRequest { mutateURs, err := pc.urLister.List(labels.SelectorFromSet(common.MutateLabelsSet(policyKey, trigger))) if err != nil { - logger.Error(err, "failed to list update request for mutate policy") + pc.log.Error(err, "failed to list update request for mutate policy") } return mutateURs } @@ -137,7 +136,7 @@ func (pc *PolicyController) listMutateURs(policyKey string, trigger *unstructure func (pc *PolicyController) listGenerateURs(policyKey string, trigger *unstructured.Unstructured) []*kyvernov1beta1.UpdateRequest { generateURs, err := pc.urLister.List(labels.SelectorFromSet(common.GenerateLabelsSet(policyKey, trigger))) if err != nil { - logger.Error(err, "failed to list update request for generate policy") + pc.log.Error(err, "failed to list update request for generate policy") } return generateURs } diff --git a/pkg/policy/validate.go b/pkg/policy/validate.go index 19d2c8560318..75d46232480b 100644 --- a/pkg/policy/validate.go +++ b/pkg/policy/validate.go @@ -11,7 +11,6 @@ import ( "github.com/distribution/distribution/reference" jsonpatch "github.com/evanphx/json-patch/v5" - "github.com/gardener/controller-manager-library/pkg/logger" "github.com/jmespath/go-jmespath" "github.com/jmoiron/jsonq" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" @@ -158,7 +157,7 @@ func Validate(policy kyvernov1.PolicyInterface, client dclient.Interface, mock b if discovery.IsGroupDiscoveryFailedError(err) { err := err.(*discovery.ErrGroupDiscoveryFailed) for gv, err := range err.Groups { - logger.Error(err, "failed to list api resources", "group", gv) + logging.Error(err, "failed to list api resources", "group", gv) } } else { return warnings, err From 001db94d87acaf6b06be4cf7fd51e457d8f86720 Mon Sep 17 00:00:00 2001 From: Eric Miller Date: Fri, 11 Nov 2022 01:19:49 -0600 Subject: [PATCH 54/55] Fix issue where CLI test command ignores failures (#5189) Closes #5187 The test command was resetting the return value to "pass", even if it was already marked failed, in some cases. This solves by moving the "pass" into an else-if clause. Signed-off-by: Eric Miller Signed-off-by: Eric Miller Co-authored-by: Vyankatesh Kudtarkar Co-authored-by: shuting --- cmd/cli/kubectl-kyverno/test/test_command.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cmd/cli/kubectl-kyverno/test/test_command.go b/cmd/cli/kubectl-kyverno/test/test_command.go index ecb3b2a4b652..100deb8f3921 100644 --- a/cmd/cli/kubectl-kyverno/test/test_command.go +++ b/cmd/cli/kubectl-kyverno/test/test_command.go @@ -67,7 +67,7 @@ applying 1 policy to 2 resources... kyverno test . Executing limit-containers-per-pod... -applying 1 policy to 4 resources... +applying 1 policy to 4 resources... │───│──────────────────────────│──────────────────────────────────────│─────────────────────────────│────────│ │ # │ POLICY │ RULE │ RESOURCE │ RESULT │ @@ -84,7 +84,7 @@ Test Summary: 4 tests passed and 0 tests failed kyverno test . --test-case-selector "policy=disallow-latest-tag, rule=require-image-tag, resource=test-require-image-tag-pass" Executing test-simple... -applying 1 policy to 1 resource... +applying 1 policy to 1 resource... │───│─────────────────────│───────────────────│─────────────────────────────────────────│────────│ │ # │ POLICY │ RULE │ RESOURCE │ RESULT │ @@ -787,9 +787,7 @@ func getAndCompareResource(path string, engineResource unstructured.Unstructured if err != nil { log.Log.V(3).Info(resourceType+" mismatch", "error", err.Error()) status = "fail" - } - - if matched == "" { + } else if matched == "" { status = "pass" } return status From 97a2b9a9a3e9e91184b710b117934871029f9265 Mon Sep 17 00:00:00 2001 From: Tobias Dahlberg Date: Fri, 11 Nov 2022 10:45:23 +0100 Subject: [PATCH 55/55] test: add kuttl tests for jmespath special chars (#5310) * Adds tests for fixes in #4767 Signed-off-by: Tobias Dahlberg Signed-off-by: Tobias Dahlberg Co-authored-by: shuting --- .../00-policy.yaml | 6 ++++ .../01-deployment.yaml | 6 ++++ .../jmespath-with-special-chars/README.md | 12 ++++++++ .../policy-assert.yaml | 9 ++++++ .../jmespath-with-special-chars/policy.yaml | 28 +++++++++++++++++++ .../resources-assert.yaml | 7 +++++ .../resources.yaml | 12 ++++++++ 7 files changed, 80 insertions(+) create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/00-policy.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/01-deployment.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/README.md create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/policy-assert.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/policy.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/resources-assert.yaml create mode 100644 test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/resources.yaml diff --git a/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/00-policy.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/00-policy.yaml new file mode 100644 index 000000000000..404ce85387df --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/00-policy.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - policy.yaml +assert: + - policy-assert.yaml diff --git a/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/01-deployment.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/01-deployment.yaml new file mode 100644 index 000000000000..525d7b544ccd --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/01-deployment.yaml @@ -0,0 +1,6 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +apply: + - resources.yaml +assert: + - resources-assert.yaml diff --git a/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/README.md b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/README.md new file mode 100644 index 000000000000..3c948b961598 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/README.md @@ -0,0 +1,12 @@ +## Description + +This test checks that document references with special characters in their names are supported. + +## Expected Behavior + +JMESPath references generated when documents are traversed are escaped properly according to the JMESPath standard. + +## Reference Issue(s) + +3578 +3616 diff --git a/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/policy-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/policy-assert.yaml new file mode 100644 index 000000000000..85dd54eef75a --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/policy-assert.yaml @@ -0,0 +1,9 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: jmespath-with-special-chars-demo +status: + conditions: + - reason: Succeeded + status: "True" + type: Ready diff --git a/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/policy.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/policy.yaml new file mode 100644 index 000000000000..ce91a05aeb71 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/policy.yaml @@ -0,0 +1,28 @@ +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: jmespath-with-special-chars-demo +spec: + rules: + - name: format-deploy-zone + match: + any: + - resources: + kinds: + - Pod + mutate: + patchStrategicMerge: + metadata: + labels: + deploy-zone: "{{ to_upper('{{@}}') }}" + - name: retention-adjust + match: + any: + - resources: + kinds: + - Pod + mutate: + patchStrategicMerge: + metadata: + labels: + corp.com/retention: "{{ regex_replace_all('([0-9])([0-9])', '{{ @ }}', '${1}0') }}" diff --git a/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/resources-assert.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/resources-assert.yaml new file mode 100644 index 000000000000..0505829a4015 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/resources-assert.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Pod +metadata: + name: busybox + labels: + deploy-zone: FRANKFURT + corp.com/retention: days_30 diff --git a/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/resources.yaml b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/resources.yaml new file mode 100644 index 000000000000..63f79ab966f3 --- /dev/null +++ b/test/conformance/kuttl/mutate/clusterpolicy/cornercases/jmespath-with-special-chars/resources.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + name: busybox + labels: + deploy-zone: frankfurt + corp.com/retention: days_37 +spec: + containers: + - name: busybox + image: busybox:stable + command: ["sleep", "600"]