diff --git a/.golangci.yml b/.golangci.yml index 97812b23f1..b1db6b5a98 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -57,7 +57,7 @@ linters-settings: alias: $1$2 - pkg: k8s.io/api/(\w+)/(v[\w\d]+) alias: $1$2 - - pkg: github.com/kyverno/kyverno/pkg/dclient + - pkg: github.com/kyverno/kyverno/pkg/clients/dclient alias: dclient - pkg: github.com/kyverno/kyverno/pkg/client/clientset/versioned alias: kyvernoclient diff --git a/cmd/cli/kubectl-kyverno/apply/apply_command.go b/cmd/cli/kubectl-kyverno/apply/apply_command.go index dd7b634cc9..ea3fa3e8a5 100644 --- a/cmd/cli/kubectl-kyverno/apply/apply_command.go +++ b/cmd/cli/kubectl-kyverno/apply/apply_command.go @@ -12,7 +12,7 @@ import ( "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common" sanitizederror "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/sanitizedError" "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/openapi" policy2 "github.com/kyverno/kyverno/pkg/policy" "github.com/kyverno/kyverno/pkg/policyreport" @@ -185,7 +185,7 @@ func applyCommandHelper(resourcePaths []string, userInfoPath string, cluster boo if err != nil { return rc, resources, skipInvalidPolicies, pvInfos, err } - dClient, err = dclient.NewClient(restConfig, kubeClient, 15*time.Minute, make(chan struct{})) + dClient, err = dclient.NewClient(restConfig, kubeClient, nil, 15*time.Minute, make(chan struct{})) if err != nil { return rc, resources, skipInvalidPolicies, pvInfos, err } diff --git a/cmd/cli/kubectl-kyverno/test/test_command.go b/cmd/cli/kubectl-kyverno/test/test_command.go index 99cc257636..790495745f 100644 --- a/cmd/cli/kubectl-kyverno/test/test_command.go +++ b/cmd/cli/kubectl-kyverno/test/test_command.go @@ -25,7 +25,7 @@ import ( "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store" "github.com/kyverno/kyverno/pkg/autogen" "github.com/kyverno/kyverno/pkg/background/generate" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/engine/response" "github.com/kyverno/kyverno/pkg/openapi" policy2 "github.com/kyverno/kyverno/pkg/policy" diff --git a/cmd/cli/kubectl-kyverno/utils/common/common.go b/cmd/cli/kubectl-kyverno/utils/common/common.go index d9cf7c6bdf..162ff36f86 100644 --- a/cmd/cli/kubectl-kyverno/utils/common/common.go +++ b/cmd/cli/kubectl-kyverno/utils/common/common.go @@ -22,7 +22,7 @@ import ( "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store" "github.com/kyverno/kyverno/pkg/autogen" "github.com/kyverno/kyverno/pkg/background/generate" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/engine" engineContext "github.com/kyverno/kyverno/pkg/engine/context" "github.com/kyverno/kyverno/pkg/engine/response" diff --git a/cmd/cli/kubectl-kyverno/utils/common/fetch.go b/cmd/cli/kubectl-kyverno/utils/common/fetch.go index 1832fbacd9..5b709b7765 100644 --- a/cmd/cli/kubectl-kyverno/utils/common/fetch.go +++ b/cmd/cli/kubectl-kyverno/utils/common/fetch.go @@ -12,7 +12,7 @@ import ( "github.com/go-git/go-billy/v5" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/autogen" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" engineutils "github.com/kyverno/kyverno/pkg/engine/utils" yamlutils "github.com/kyverno/kyverno/pkg/utils/yaml" "golang.org/x/text/cases" diff --git a/cmd/initContainer/main.go b/cmd/initContainer/main.go index 881adbad8e..f4797f1419 100644 --- a/cmd/initContainer/main.go +++ b/cmd/initContainer/main.go @@ -13,8 +13,8 @@ import ( kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/leaderelection" "github.com/kyverno/kyverno/pkg/policyreport" "github.com/kyverno/kyverno/pkg/signal" @@ -91,7 +91,7 @@ func main() { // DYNAMIC CLIENT // - client for all registered resources - client, err := dclient.NewClient(clientConfig, kubeClient, 15*time.Minute, stopCh) + client, err := dclient.NewClient(clientConfig, kubeClient, nil, 15*time.Minute, stopCh) if err != nil { setupLog.Error(err, "Failed to create client") os.Exit(1) diff --git a/cmd/kyverno/main.go b/cmd/kyverno/main.go index 2ef43e1000..4cb3d8848b 100644 --- a/cmd/kyverno/main.go +++ b/cmd/kyverno/main.go @@ -13,15 +13,15 @@ import ( "github.com/kyverno/kyverno/pkg/background" generatecleanup "github.com/kyverno/kyverno/pkg/background/generate/cleanup" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernoinformer "github.com/kyverno/kyverno/pkg/client/informers/externalversions" + "github.com/kyverno/kyverno/pkg/clients/dclient" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/common" "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/controllers/certmanager" configcontroller "github.com/kyverno/kyverno/pkg/controllers/config" policycachecontroller "github.com/kyverno/kyverno/pkg/controllers/policycache" "github.com/kyverno/kyverno/pkg/cosign" - "github.com/kyverno/kyverno/pkg/dclient" event "github.com/kyverno/kyverno/pkg/event" "github.com/kyverno/kyverno/pkg/leaderelection" "github.com/kyverno/kyverno/pkg/metrics" @@ -130,17 +130,43 @@ func main() { setupLog.Error(err, "Failed to build kubeconfig") os.Exit(1) } - kyvernoClient, err := kyvernoclient.NewForConfig(clientConfig) - if err != nil { - setupLog.Error(err, "Failed to create client") - os.Exit(1) - } + kubeClient, err := kubernetes.NewForConfig(clientConfig) if err != nil { setupLog.Error(err, "Failed to create kubernetes client") os.Exit(1) } - dynamicClient, err := dclient.NewClient(clientConfig, kubeClient, 15*time.Minute, stopCh) + + // Metrics Configuration + var metricsConfig *metrics.MetricsConfig + metricsConfigData, err := config.NewMetricsConfigData(kubeClient) + if err != nil { + setupLog.Error(err, "failed to fetch metrics config") + os.Exit(1) + } + + metricsAddr := ":" + metricsPort + metricsConfig, metricsServerMux, metricsPusher, err := metrics.InitMetrics( + disableMetricsExport, + otel, + metricsAddr, + otelCollector, + metricsConfigData, + transportCreds, + kubeClient, + log.Log.WithName("Metrics"), + ) + if err != nil { + setupLog.Error(err, "failed to initialize metrics") + os.Exit(1) + } + + kyvernoClient, err := kyvernoclient.NewForConfig(clientConfig, metricsConfig) + if err != nil { + setupLog.Error(err, "Failed to create client") + os.Exit(1) + } + dynamicClient, err := dclient.NewClient(clientConfig, kubeClient, metricsConfig, 15*time.Minute, stopCh) if err != nil { setupLog.Error(err, "Failed to create dynamic client") os.Exit(1) @@ -152,8 +178,6 @@ func main() { os.Exit(1) } - var metricsConfig *metrics.MetricsConfig - if profile { addr := ":" + profilePort setupLog.V(2).Info("Enable profiling, see details at https://github.com/kyverno/kyverno/wiki/Profiling-Kyverno-on-Kubernetes", "port", profilePort) @@ -168,7 +192,7 @@ func main() { // informer factories kubeInformer := kubeinformers.NewSharedInformerFactory(kubeClient, resyncPeriod) kubeKyvernoInformer := kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, resyncPeriod, kubeinformers.WithNamespace(config.KyvernoNamespace())) - kyvernoInformer := kyvernoinformer.NewSharedInformerFactory(kyvernoClient, policyControllerResyncPeriod) + kyvernoInformer := kyvernoinformer.NewSharedInformerFactory(kyvernoClient.VersionedClient(), policyControllerResyncPeriod) // utils kyvernoV1 := kyvernoInformer.Kyverno().V1() @@ -177,6 +201,21 @@ func main() { var registryOptions []registryclient.Option + if otel == "grpc" { + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer metrics.ShutDownController(ctx, metricsPusher) + defer cancel() + } + + if otel == "prometheus" { + go func() { + setupLog.Info("Enabling Metrics for Kyverno", "address", metricsAddr) + if err := http.ListenAndServe(metricsAddr, metricsServerMux); err != nil { + setupLog.Error(err, "failed to enable metrics", "address", metricsAddr) + } + }() + } + // load image registry secrets secrets := strings.Split(imagePullSecrets, ",") if imagePullSecrets != "" && len(secrets) > 0 { @@ -211,8 +250,8 @@ func main() { eventGenerator := event.NewEventGenerator(dynamicClient, kyvernoV1.ClusterPolicies(), kyvernoV1.Policies(), maxQueuedEvents, log.Log.WithName("EventGenerator")) // POLICY Report GENERATOR - reportReqGen := policyreport.NewReportChangeRequestGenerator(kyvernoClient, - dynamicClient, + reportReqGen := policyreport.NewReportChangeRequestGenerator( + kyvernoClient, kyvernoV1alpha2.ReportChangeRequests(), kyvernoV1alpha2.ClusterReportChangeRequests(), kyvernoV1.ClusterPolicies(), @@ -223,7 +262,6 @@ func main() { prgen, err := policyreport.NewReportGenerator( kyvernoClient, - dynamicClient, kyvernoInformer.Wgpolicyk8s().V1alpha2().ClusterPolicyReports(), kyvernoInformer.Wgpolicyk8s().V1alpha2().PolicyReports(), kyvernoV1alpha2.ReportChangeRequests(), @@ -247,6 +285,7 @@ func main() { kubeKyvernoInformer.Apps().V1().Deployments(), kyvernoV1.ClusterPolicies(), kyvernoV1.Policies(), + metricsConfig, serverIP, int32(webhookTimeout), debug, @@ -268,44 +307,6 @@ func main() { } configurationController := configcontroller.NewController(configuration, kubeKyvernoInformer.Core().V1().ConfigMaps()) - metricsConfigData, err := config.NewMetricsConfigData(kubeClient) - if err != nil { - setupLog.Error(err, "failed to fetch metrics config") - os.Exit(1) - } - - // Metrics Configuration - metricsAddr := ":" + metricsPort - metricsConfig, metricsServerMux, metricsPusher, err := metrics.InitMetrics( - disableMetricsExport, - otel, - metricsAddr, - otelCollector, - metricsConfigData, - transportCreds, - kubeClient, - log.Log.WithName("Metrics"), - ) - if err != nil { - setupLog.Error(err, "failed to initialize metrics") - os.Exit(1) - } - - if otel == "grpc" { - ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) - defer metrics.ShutDownController(ctx, metricsPusher) - defer cancel() - } - - if otel == "prometheus" { - go func() { - setupLog.V(2).Info("Enabling Metrics for Kyverno", "address", metricsAddr) - if err := http.ListenAndServe(metricsAddr, metricsServerMux); err != nil { - setupLog.Error(err, "failed to enable metrics", "address", metricsAddr) - } - }() - } - // Tracing Configuration if enableTracing { setupLog.V(2).Info("Enabling tracing for Kyverno...") @@ -324,7 +325,6 @@ func main() { // - process policy on existing resources // - status aggregator: receives stats when a policy is applied & updates the policy status policyCtrl, err := policy.NewPolicyController( - kubeClient, kyvernoClient, dynamicClient, kyvernoV1.ClusterPolicies(), @@ -347,7 +347,6 @@ func main() { urgen := webhookgenerate.NewGenerator(kyvernoClient, kyvernoV1beta1.UpdateRequests()) urc := background.NewController( - kubeClient, kyvernoClient, dynamicClient, kyvernoV1.ClusterPolicies(), @@ -360,7 +359,6 @@ func main() { ) grcc := generatecleanup.NewController( - kubeClient, kyvernoClient, dynamicClient, kyvernoV1.ClusterPolicies(), diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go index a23aa80dff..de8092d116 100644 --- a/pkg/auth/auth.go +++ b/pkg/auth/auth.go @@ -4,7 +4,7 @@ import ( "fmt" "reflect" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" authorizationv1 "k8s.io/api/authorization/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/auth/auth_test.go b/pkg/auth/auth_test.go index 89c6ba8544..951bd88fc1 100644 --- a/pkg/auth/auth_test.go +++ b/pkg/auth/auth_test.go @@ -6,7 +6,7 @@ package auth // "github.com/golang/glog" // "github.com/kyverno/kyverno/pkg/config" -// dclient "github.com/kyverno/kyverno/pkg/dclient" +// dclient "github.com/kyverno/kyverno/pkg/clients/dclient" // "github.com/kyverno/kyverno/pkg/signal" // ) diff --git a/pkg/background/common/context.go b/pkg/background/common/context.go index 81e5bdb2eb..36538a8b59 100644 --- a/pkg/background/common/context.go +++ b/pkg/background/common/context.go @@ -7,8 +7,8 @@ import ( "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/engine" "github.com/kyverno/kyverno/pkg/engine/context" utils "github.com/kyverno/kyverno/pkg/utils" diff --git a/pkg/background/common/resource.go b/pkg/background/common/resource.go index 838cd99d13..9bbff6395d 100644 --- a/pkg/background/common/resource.go +++ b/pkg/background/common/resource.go @@ -6,8 +6,8 @@ import ( logr "github.com/go-logr/logr" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/common" - "github.com/kyverno/kyverno/pkg/dclient" admissionv1 "k8s.io/api/admission/v1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/pkg/background/common/status.go b/pkg/background/common/status.go index c96a79c9c5..681c1c25cb 100644 --- a/pkg/background/common/status.go +++ b/pkg/background/common/status.go @@ -3,8 +3,8 @@ package common import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" ) // StatusControlInterface provides interface to update status subresource diff --git a/pkg/background/common/util.go b/pkg/background/common/util.go index 133d677835..fe9c00c267 100644 --- a/pkg/background/common/util.go +++ b/pkg/background/common/util.go @@ -6,8 +6,8 @@ import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/config" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" diff --git a/pkg/background/generate/cleanup/controller.go b/pkg/background/generate/cleanup/controller.go index d19be4766c..172d4037e6 100644 --- a/pkg/background/generate/cleanup/controller.go +++ b/pkg/background/generate/cleanup/controller.go @@ -7,14 +7,14 @@ import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1" kyvernov1beta1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1beta1" kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1" kyvernov1beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1" + "github.com/kyverno/kyverno/pkg/clients/dclient" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" pkgCommon "github.com/kyverno/kyverno/pkg/common" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -22,7 +22,6 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" corev1informers "k8s.io/client-go/informers/core/v1" - "k8s.io/client-go/kubernetes" corev1listers "k8s.io/client-go/listers/core/v1" "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" @@ -61,7 +60,6 @@ type controller struct { // NewController returns a new controller instance to manage generate-requests func NewController( - kubeClient kubernetes.Interface, kyvernoclient kyvernoclient.Interface, client dclient.Interface, pInformer kyvernov1informers.ClusterPolicyInformer, diff --git a/pkg/background/generate/cleanup/utils.go b/pkg/background/generate/cleanup/utils.go index f310b639cd..ba03486f78 100644 --- a/pkg/background/generate/cleanup/utils.go +++ b/pkg/background/generate/cleanup/utils.go @@ -3,7 +3,7 @@ package cleanup import ( "github.com/go-logr/logr" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" apierrors "k8s.io/apimachinery/pkg/api/errors" ) diff --git a/pkg/background/generate/generate.go b/pkg/background/generate/generate.go index 304c9cb234..a33216b15c 100644 --- a/pkg/background/generate/generate.go +++ b/pkg/background/generate/generate.go @@ -15,12 +15,12 @@ import ( kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" "github.com/kyverno/kyverno/pkg/autogen" "github.com/kyverno/kyverno/pkg/background/common" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1" kyvernov1beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1" + "github.com/kyverno/kyverno/pkg/clients/dclient" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" pkgcommon "github.com/kyverno/kyverno/pkg/common" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/engine" "github.com/kyverno/kyverno/pkg/engine/context" "github.com/kyverno/kyverno/pkg/engine/response" @@ -50,7 +50,8 @@ type GenerateController struct { configuration config.Configuration eventGen event.Interface - log logr.Logger + + log logr.Logger } // NewGenerateController returns an instance of the Generate-Request Controller diff --git a/pkg/background/mutate/mutate.go b/pkg/background/mutate/mutate.go index c00fbd4664..630f832c4d 100644 --- a/pkg/background/mutate/mutate.go +++ b/pkg/background/mutate/mutate.go @@ -9,8 +9,8 @@ import ( kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" "github.com/kyverno/kyverno/pkg/background/common" kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/engine" "github.com/kyverno/kyverno/pkg/engine/response" "github.com/kyverno/kyverno/pkg/event" @@ -34,7 +34,8 @@ type MutateExistingController struct { configuration config.Configuration eventGen event.Interface - log logr.Logger + + log logr.Logger } // NewMutateExistingController returns an instance of the MutateExistingController diff --git a/pkg/background/update_request_controller.go b/pkg/background/update_request_controller.go index dad7a6d9a8..33f23819d4 100644 --- a/pkg/background/update_request_controller.go +++ b/pkg/background/update_request_controller.go @@ -10,13 +10,13 @@ import ( common "github.com/kyverno/kyverno/pkg/background/common" "github.com/kyverno/kyverno/pkg/background/generate" "github.com/kyverno/kyverno/pkg/background/mutate" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1" kyvernov1beta1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1beta1" kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1" kyvernov1beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1" + "github.com/kyverno/kyverno/pkg/clients/dclient" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/event" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -24,7 +24,6 @@ import ( "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" corev1informers "k8s.io/client-go/informers/core/v1" - "k8s.io/client-go/kubernetes" corev1listers "k8s.io/client-go/listers/core/v1" "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/retry" @@ -64,7 +63,6 @@ type controller struct { // NewController returns an instance of the Generate-Request Controller func NewController( - kubeClient kubernetes.Interface, kyvernoClient kyvernoclient.Interface, client dclient.Interface, cpolInformer kyvernov1informers.ClusterPolicyInformer, diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index 5752ca53ba..876339f7a9 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -25,13 +25,11 @@ import ( 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" - discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" ) type Interface interface { - Discovery() discovery.DiscoveryInterface KyvernoV1() kyvernov1.KyvernoV1Interface KyvernoV1beta1() kyvernov1beta1.KyvernoV1beta1Interface KyvernoV1alpha2() kyvernov1alpha2.KyvernoV1alpha2Interface @@ -41,7 +39,6 @@ type Interface interface { // Clientset contains the clients for groups. Each group has exactly one // version included in a Clientset. type Clientset struct { - *discovery.DiscoveryClient kyvernoV1 *kyvernov1.KyvernoV1Client kyvernoV1beta1 *kyvernov1beta1.KyvernoV1beta1Client kyvernoV1alpha2 *kyvernov1alpha2.KyvernoV1alpha2Client @@ -68,14 +65,6 @@ func (c *Clientset) Wgpolicyk8sV1alpha2() wgpolicyk8sv1alpha2.Wgpolicyk8sV1alpha return c.wgpolicyk8sV1alpha2 } -// Discovery retrieves the DiscoveryClient -func (c *Clientset) Discovery() discovery.DiscoveryInterface { - if c == nil { - return nil - } - return c.DiscoveryClient -} - // NewForConfig creates a new Clientset for the given config. // If config's RateLimiter is not set and QPS and Burst are acceptable, // NewForConfig will generate a rate-limiter in configShallowCopy. @@ -106,10 +95,6 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { return nil, err } - cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) - if err != nil { - return nil, err - } return &cs, nil } @@ -122,7 +107,6 @@ func NewForConfigOrDie(c *rest.Config) *Clientset { cs.kyvernoV1alpha2 = kyvernov1alpha2.NewForConfigOrDie(c) cs.wgpolicyk8sV1alpha2 = wgpolicyk8sv1alpha2.NewForConfigOrDie(c) - cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) return &cs } @@ -134,6 +118,5 @@ func New(c rest.Interface) *Clientset { cs.kyvernoV1alpha2 = kyvernov1alpha2.New(c) cs.wgpolicyk8sV1alpha2 = wgpolicyk8sv1alpha2.New(c) - cs.DiscoveryClient = discovery.NewDiscoveryClient(c) return &cs } diff --git a/pkg/client/clientset/versioned/fake/register.go b/pkg/client/clientset/versioned/fake/register.go index a93604b6d1..cf3c1a08f4 100644 --- a/pkg/client/clientset/versioned/fake/register.go +++ b/pkg/client/clientset/versioned/fake/register.go @@ -43,14 +43,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{ // 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 9fbeaa98f0..776190e352 100644 --- a/pkg/client/clientset/versioned/scheme/register.go +++ b/pkg/client/clientset/versioned/scheme/register.go @@ -43,14 +43,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{ // 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/dclient/client.go b/pkg/clients/dclient/client.go similarity index 87% rename from pkg/dclient/client.go rename to pkg/clients/dclient/client.go index 114dfdda45..0261e1a438 100644 --- a/pkg/dclient/client.go +++ b/pkg/clients/dclient/client.go @@ -6,6 +6,7 @@ import ( "fmt" "time" + "github.com/kyverno/kyverno/pkg/metrics" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -25,8 +26,6 @@ type Interface interface { NewDynamicSharedInformerFactory(time.Duration) dynamicinformer.DynamicSharedInformerFactory // GetEventsInterface provides typed interface for events GetEventsInterface() (corev1.EventInterface, error) - // GetCSRInterface provides type interface for CSR - GetCSRInterface() (certsv1beta1.CertificateSigningRequestInterface, error) // GetDynamicInterface fetches underlying dynamic interface GetDynamicInterface() dynamic.Interface // Discovery return the discovery client implementation @@ -49,6 +48,8 @@ type Interface interface { UpdateResource(apiVersion string, kind string, namespace string, obj interface{}, dryRun bool) (*unstructured.Unstructured, error) // UpdateStatusResource updates the resource "status" subresource UpdateStatusResource(apiVersion string, kind string, namespace string, obj interface{}, dryRun bool) (*unstructured.Unstructured, error) + // RecordClientQuery publish the client query to the metric + RecordClientQuery(clientQueryOperation metrics.ClientQueryOperation, clientType metrics.ClientType, resourceKind string, resourceNamespace string) } // Client enables interaction with k8 resource @@ -57,11 +58,12 @@ type client struct { discoveryClient IDiscovery clientConfig *rest.Config kclient kubernetes.Interface + metricsConfig metrics.MetricsConfigManager restClient rest.Interface } // NewClient creates new instance of client -func NewClient(config *rest.Config, kclient *kubernetes.Clientset, resync time.Duration, stopCh <-chan struct{}) (Interface, error) { +func NewClient(config *rest.Config, kclient *kubernetes.Clientset, metricsConfig metrics.MetricsConfigManager, resync time.Duration, stopCh <-chan struct{}) (Interface, error) { dclient, err := dynamic.NewForConfig(config) if err != nil { return nil, err @@ -72,6 +74,11 @@ func NewClient(config *rest.Config, kclient *kubernetes.Clientset, resync time.D kclient: kclient, restClient: kclient.RESTClient(), } + + if metricsConfig != nil { + client.metricsConfig = metricsConfig + } + // Set discovery client discoveryClient := &serverPreferredResources{ cachedClient: memory.NewMemCacheClient(kclient.Discovery()), @@ -130,6 +137,7 @@ func (c *client) getGroupVersionMapper(apiVersion string, kind string) schema.Gr // GetResource returns the resource in unstructured/json format func (c *client) GetResource(apiVersion string, kind string, namespace string, name string, subresources ...string) (*unstructured.Unstructured, error) { + c.RecordClientQuery(metrics.ClientGet, metrics.KubeDynamicClient, kind, namespace) return c.getResourceInterface(apiVersion, kind, namespace).Get(context.TODO(), name, metav1.GetOptions{}, subresources...) } @@ -142,6 +150,7 @@ func (c *client) RawAbsPath(path string) ([]byte, error) { // PatchResource patches the resource func (c *client) PatchResource(apiVersion string, kind string, namespace string, name string, patch []byte) (*unstructured.Unstructured, error) { + c.RecordClientQuery(metrics.ClientUpdate, metrics.KubeDynamicClient, kind, namespace) return c.getResourceInterface(apiVersion, kind, namespace).Patch(context.TODO(), name, types.JSONPatchType, patch, metav1.PatchOptions{}) } @@ -158,6 +167,7 @@ func (c *client) ListResource(apiVersion string, kind string, namespace string, options = metav1.ListOptions{LabelSelector: metav1.FormatLabelSelector(lselector)} } + c.RecordClientQuery(metrics.ClientList, metrics.KubeDynamicClient, kind, namespace) return c.getResourceInterface(apiVersion, kind, namespace).List(context.TODO(), options) } @@ -167,6 +177,7 @@ func (c *client) DeleteResource(apiVersion string, kind string, namespace string if dryRun { options = metav1.DeleteOptions{DryRun: []string{metav1.DryRunAll}} } + c.RecordClientQuery(metrics.ClientDelete, metrics.KubeDynamicClient, kind, namespace) return c.getResourceInterface(apiVersion, kind, namespace).Delete(context.TODO(), name, options) } @@ -178,6 +189,7 @@ func (c *client) CreateResource(apiVersion string, kind string, namespace string } // convert typed to unstructured obj if unstructuredObj, err := kubeutils.ConvertToUnstructured(obj); err == nil && unstructuredObj != nil { + c.RecordClientQuery(metrics.ClientCreate, metrics.KubeDynamicClient, kind, namespace) return c.getResourceInterface(apiVersion, kind, namespace).Create(context.TODO(), unstructuredObj, options) } return nil, fmt.Errorf("unable to create resource ") @@ -191,6 +203,7 @@ func (c *client) UpdateResource(apiVersion string, kind string, namespace string } // convert typed to unstructured obj if unstructuredObj, err := kubeutils.ConvertToUnstructured(obj); err == nil && unstructuredObj != nil { + c.RecordClientQuery(metrics.ClientUpdate, metrics.KubeDynamicClient, kind, namespace) return c.getResourceInterface(apiVersion, kind, namespace).Update(context.TODO(), unstructuredObj, options) } return nil, fmt.Errorf("unable to update resource ") @@ -204,6 +217,7 @@ func (c *client) UpdateStatusResource(apiVersion string, kind string, namespace } // convert typed to unstructured obj if unstructuredObj, err := kubeutils.ConvertToUnstructured(obj); err == nil && unstructuredObj != nil { + c.RecordClientQuery(metrics.ClientUpdateStatus, metrics.KubeDynamicClient, kind, namespace) return c.getResourceInterface(apiVersion, kind, namespace).UpdateStatus(context.TODO(), unstructuredObj, options) } return nil, fmt.Errorf("unable to update resource ") @@ -218,3 +232,10 @@ func (c *client) Discovery() IDiscovery { func (c *client) SetDiscovery(discoveryClient IDiscovery) { c.discoveryClient = discoveryClient } + +func (c *client) RecordClientQuery(clientQueryOperation metrics.ClientQueryOperation, clientType metrics.ClientType, resourceKind string, resourceNamespace string) { + if c.metricsConfig == nil { + return + } + c.metricsConfig.RecordClientQueries(clientQueryOperation, clientType, resourceKind, resourceNamespace) +} diff --git a/pkg/dclient/client_test.go b/pkg/clients/dclient/client_test.go similarity index 92% rename from pkg/dclient/client_test.go rename to pkg/clients/dclient/client_test.go index 2a8baecb9c..893ed8883a 100644 --- a/pkg/dclient/client_test.go +++ b/pkg/clients/dclient/client_test.go @@ -116,14 +116,3 @@ func TestEventInterface(t *testing.T) { t.Errorf("Testing Event interface not working: %s", err) } } -func TestCSRInterface(t *testing.T) { - f := newFixture(t) - iCSR, err := f.client.GetCSRInterface() - if err != nil { - t.Errorf("GetCSRInterface not working: %s", err) - } - _, err = iCSR.List(context.TODO(), metav1.ListOptions{}) - if err != nil { - t.Errorf("Testing CSR interface not working: %s", err) - } -} diff --git a/pkg/dclient/discovery.go b/pkg/clients/dclient/discovery.go similarity index 100% rename from pkg/dclient/discovery.go rename to pkg/clients/dclient/discovery.go diff --git a/pkg/dclient/discovery_test.go b/pkg/clients/dclient/discovery_test.go similarity index 100% rename from pkg/dclient/discovery_test.go rename to pkg/clients/dclient/discovery_test.go diff --git a/pkg/dclient/fake.go b/pkg/clients/dclient/fake.go similarity index 100% rename from pkg/dclient/fake.go rename to pkg/clients/dclient/fake.go diff --git a/pkg/dclient/log.go b/pkg/clients/dclient/log.go similarity index 100% rename from pkg/dclient/log.go rename to pkg/clients/dclient/log.go diff --git a/pkg/dclient/utils.go b/pkg/clients/dclient/utils.go similarity index 100% rename from pkg/dclient/utils.go rename to pkg/clients/dclient/utils.go diff --git a/pkg/clients/wrappers/clientset.go b/pkg/clients/wrappers/clientset.go new file mode 100644 index 0000000000..294840ff73 --- /dev/null +++ b/pkg/clients/wrappers/clientset.go @@ -0,0 +1,82 @@ +package kyvernoclient + +import ( + "github.com/kyverno/kyverno/pkg/client/clientset/versioned" + kyvernov1 "github.com/kyverno/kyverno/pkg/clients/wrappers/kyverno/v1" + kyvernov1alpha2 "github.com/kyverno/kyverno/pkg/clients/wrappers/kyverno/v1alpha2" + kyvernov1beta1 "github.com/kyverno/kyverno/pkg/clients/wrappers/kyverno/v1beta1" + wgpolicyk8sv1alpha2 "github.com/kyverno/kyverno/pkg/clients/wrappers/policyreport/v1alpha2" + "github.com/kyverno/kyverno/pkg/clients/wrappers/utils" + "github.com/kyverno/kyverno/pkg/metrics" + "k8s.io/client-go/rest" +) + +type Interface interface { + VersionedClient() versioned.Interface + KyvernoV1() kyvernov1.KyvernoV1Interface + KyvernoV1beta1() kyvernov1beta1.KyvernoV1beta1Interface + KyvernoV1alpha2() kyvernov1alpha2.KyvernoV1alpha2Interface + Wgpolicyk8sV1alpha2() wgpolicyk8sv1alpha2.Wgpolicyk8sV1alpha2Interface +} + +type Clientset struct { + versionedClient versioned.Interface + kyvernoV1 *kyvernov1.KyvernoV1Client + kyvernoV1beta1 *kyvernov1beta1.KyvernoV1beta1Client + kyvernoV1alpha2 *kyvernov1alpha2.KyvernoV1alpha2Client + wgpolicyk8sV1alpha2 *wgpolicyk8sv1alpha2.Wgpolicyk8sV1alpha2Client +} + +func (c *Clientset) VersionedClient() versioned.Interface { + return c.versionedClient +} + +func (c *Clientset) KyvernoV1() kyvernov1.KyvernoV1Interface { + return c.kyvernoV1 +} + +func (c *Clientset) KyvernoV1beta1() kyvernov1beta1.KyvernoV1beta1Interface { + return c.kyvernoV1beta1 +} + +func (c *Clientset) KyvernoV1alpha2() kyvernov1alpha2.KyvernoV1alpha2Interface { + return c.kyvernoV1alpha2 +} + +func (c *Clientset) Wgpolicyk8sV1alpha2() wgpolicyk8sv1alpha2.Wgpolicyk8sV1alpha2Interface { + return c.wgpolicyk8sV1alpha2 +} + +func NewForConfig(c *rest.Config, m *metrics.MetricsConfig) (*Clientset, error) { + var cs Clientset + clientQueryMetric := utils.NewClientQueryMetric(m) + + kClientset, err := versioned.NewForConfig(c) + if err != nil { + return nil, err + } + + cs.versionedClient = kClientset + + cs.kyvernoV1 = kyvernov1.NewForConfig( + kClientset.KyvernoV1().RESTClient(), + kClientset.KyvernoV1(), + clientQueryMetric) + + cs.kyvernoV1beta1 = kyvernov1beta1.NewForConfig( + kClientset.KyvernoV1beta1().RESTClient(), + kClientset.KyvernoV1beta1(), + clientQueryMetric) + + cs.kyvernoV1alpha2 = kyvernov1alpha2.NewForConfig( + kClientset.KyvernoV1alpha2().RESTClient(), + kClientset.KyvernoV1alpha2(), + clientQueryMetric) + + cs.wgpolicyk8sV1alpha2 = wgpolicyk8sv1alpha2.NewForConfig( + kClientset.Wgpolicyk8sV1alpha2().RESTClient(), + kClientset.Wgpolicyk8sV1alpha2(), + clientQueryMetric) + + return &cs, nil +} diff --git a/pkg/clients/wrappers/kyverno/v1/clusterpolicy.go b/pkg/clients/wrappers/kyverno/v1/clusterpolicy.go new file mode 100644 index 0000000000..badf3d5c46 --- /dev/null +++ b/pkg/clients/wrappers/kyverno/v1/clusterpolicy.go @@ -0,0 +1,89 @@ +package v1 + +import ( + "context" + + kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" + versionedkyvernov1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1" + "github.com/kyverno/kyverno/pkg/clients/wrappers/utils" + "github.com/kyverno/kyverno/pkg/metrics" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/rest" +) + +type ClusterPoliciesGetter interface { + ClusterPolicies() ClusterPoliciesControlInterface +} + +type ClusterPoliciesControlInterface interface { + Create(ctx context.Context, clusterPolicy *kyvernov1.ClusterPolicy, opts metav1.CreateOptions) (*kyvernov1.ClusterPolicy, error) + Update(ctx context.Context, clusterPolicy *kyvernov1.ClusterPolicy, opts metav1.UpdateOptions) (*kyvernov1.ClusterPolicy, error) + UpdateStatus(ctx context.Context, clusterPolicy *kyvernov1.ClusterPolicy, opts metav1.UpdateOptions) (*kyvernov1.ClusterPolicy, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*kyvernov1.ClusterPolicy, error) + List(ctx context.Context, opts metav1.ListOptions) (*kyvernov1.ClusterPolicyList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *kyvernov1.ClusterPolicy, err error) +} + +type clusterPoliciesControl struct { + client rest.Interface + cpolClient versionedkyvernov1.ClusterPoliciesGetter + clientQueryMetric utils.ClientQueryMetric +} + +func newClusterPolicies(c *KyvernoV1Client) *clusterPoliciesControl { + return &clusterPoliciesControl{ + client: c.RESTClient(), + cpolClient: c.kyvernov1Interface, + clientQueryMetric: c.clientQueryMetric, + } +} + +func (c *clusterPoliciesControl) Create(ctx context.Context, clusterPolicy *kyvernov1.ClusterPolicy, opts metav1.CreateOptions) (*kyvernov1.ClusterPolicy, error) { + c.clientQueryMetric.Record(metrics.ClientCreate, metrics.KyvernoClient, "ClusterPolicy", "") + return c.cpolClient.ClusterPolicies().Create(ctx, clusterPolicy, opts) +} + +func (c *clusterPoliciesControl) Update(ctx context.Context, clusterPolicy *kyvernov1.ClusterPolicy, opts metav1.UpdateOptions) (*kyvernov1.ClusterPolicy, error) { + c.clientQueryMetric.Record(metrics.ClientUpdate, metrics.KyvernoClient, "ClusterPolicy", "") + return c.cpolClient.ClusterPolicies().Update(ctx, clusterPolicy, opts) +} + +func (c *clusterPoliciesControl) UpdateStatus(ctx context.Context, clusterPolicy *kyvernov1.ClusterPolicy, opts metav1.UpdateOptions) (*kyvernov1.ClusterPolicy, error) { + c.clientQueryMetric.Record(metrics.ClientUpdateStatus, metrics.KyvernoClient, "ClusterPolicy", "") + return c.cpolClient.ClusterPolicies().UpdateStatus(ctx, clusterPolicy, opts) +} + +func (c *clusterPoliciesControl) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + c.clientQueryMetric.Record(metrics.ClientDelete, metrics.KyvernoClient, "ClusterPolicy", "") + return c.cpolClient.ClusterPolicies().Delete(ctx, name, opts) +} + +func (c *clusterPoliciesControl) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + c.clientQueryMetric.Record(metrics.ClientDeleteCollection, metrics.KyvernoClient, "ClusterPolicy", "") + return c.cpolClient.ClusterPolicies().DeleteCollection(ctx, opts, listOpts) +} + +func (c *clusterPoliciesControl) Get(ctx context.Context, name string, opts metav1.GetOptions) (*kyvernov1.ClusterPolicy, error) { + c.clientQueryMetric.Record(metrics.ClientGet, metrics.KyvernoClient, "ClusterPolicy", "") + return c.cpolClient.ClusterPolicies().Get(ctx, name, opts) +} + +func (c *clusterPoliciesControl) List(ctx context.Context, opts metav1.ListOptions) (*kyvernov1.ClusterPolicyList, error) { + c.clientQueryMetric.Record(metrics.ClientList, metrics.KyvernoClient, "ClusterPolicy", "") + return c.cpolClient.ClusterPolicies().List(ctx, opts) +} + +func (c *clusterPoliciesControl) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + c.clientQueryMetric.Record(metrics.ClientWatch, metrics.KyvernoClient, "ClusterPolicy", "") + return c.cpolClient.ClusterPolicies().Watch(ctx, opts) +} + +func (c *clusterPoliciesControl) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *kyvernov1.ClusterPolicy, err error) { + c.clientQueryMetric.Record(metrics.ClientPatch, metrics.KyvernoClient, "ClusterPolicy", "") + return c.cpolClient.ClusterPolicies().Patch(ctx, name, pt, data, opts, subresources...) +} diff --git a/pkg/clients/wrappers/kyverno/v1/kyverno_client.go b/pkg/clients/wrappers/kyverno/v1/kyverno_client.go new file mode 100644 index 0000000000..94b9b1671f --- /dev/null +++ b/pkg/clients/wrappers/kyverno/v1/kyverno_client.go @@ -0,0 +1,40 @@ +package v1 + +import ( + kyvernov1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1" + "github.com/kyverno/kyverno/pkg/clients/wrappers/utils" + "k8s.io/client-go/rest" +) + +type KyvernoV1Interface interface { + RESTClient() rest.Interface + ClusterPoliciesGetter + PoliciesGetter +} + +type KyvernoV1Client struct { + restClient rest.Interface + kyvernov1Interface kyvernov1.KyvernoV1Interface + clientQueryMetric utils.ClientQueryMetric +} + +func (c *KyvernoV1Client) ClusterPolicies() ClusterPoliciesControlInterface { + return newClusterPolicies(c) +} + +func (c *KyvernoV1Client) Policies(namespace string) PoliciesControlInterface { + return newPolicies(c, namespace) +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *KyvernoV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} + +func NewForConfig(restClient rest.Interface, kyvernov1Interface kyvernov1.KyvernoV1Interface, m utils.ClientQueryMetric) *KyvernoV1Client { + return &KyvernoV1Client{restClient, kyvernov1Interface, m} +} diff --git a/pkg/clients/wrappers/kyverno/v1/policy.go b/pkg/clients/wrappers/kyverno/v1/policy.go new file mode 100644 index 0000000000..b9df259088 --- /dev/null +++ b/pkg/clients/wrappers/kyverno/v1/policy.go @@ -0,0 +1,91 @@ +package v1 + +import ( + "context" + + kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" + versionedv1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1" + "github.com/kyverno/kyverno/pkg/clients/wrappers/utils" + "github.com/kyverno/kyverno/pkg/metrics" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/rest" +) + +type PoliciesGetter interface { + Policies(namespace string) PoliciesControlInterface +} + +type PoliciesControlInterface interface { + Create(ctx context.Context, policy *kyvernov1.Policy, opts metav1.CreateOptions) (*kyvernov1.Policy, error) + Update(ctx context.Context, policy *kyvernov1.Policy, opts metav1.UpdateOptions) (*kyvernov1.Policy, error) + UpdateStatus(ctx context.Context, policy *kyvernov1.Policy, opts metav1.UpdateOptions) (*kyvernov1.Policy, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*kyvernov1.Policy, error) + List(ctx context.Context, opts metav1.ListOptions) (*kyvernov1.PolicyList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *kyvernov1.Policy, err error) +} + +type policiesControl struct { + client rest.Interface + polClient versionedv1.PoliciesGetter + clientQueryMetric utils.ClientQueryMetric + ns string +} + +func newPolicies(c *KyvernoV1Client, namespace string) *policiesControl { + return &policiesControl{ + client: c.RESTClient(), + polClient: c.kyvernov1Interface, + clientQueryMetric: c.clientQueryMetric, + ns: namespace, + } +} + +func (c *policiesControl) Create(ctx context.Context, policy *kyvernov1.Policy, opts metav1.CreateOptions) (*kyvernov1.Policy, error) { + c.clientQueryMetric.Record(metrics.ClientCreate, metrics.KyvernoClient, "Policy", c.ns) + return c.polClient.Policies(c.ns).Create(ctx, policy, opts) +} + +func (c *policiesControl) Update(ctx context.Context, policy *kyvernov1.Policy, opts metav1.UpdateOptions) (*kyvernov1.Policy, error) { + c.clientQueryMetric.Record(metrics.ClientUpdate, metrics.KyvernoClient, "Policy", c.ns) + return c.polClient.Policies(c.ns).Update(ctx, policy, opts) +} + +func (c *policiesControl) UpdateStatus(ctx context.Context, policy *kyvernov1.Policy, opts metav1.UpdateOptions) (*kyvernov1.Policy, error) { + c.clientQueryMetric.Record(metrics.ClientUpdateStatus, metrics.KyvernoClient, "Policy", c.ns) + return c.polClient.Policies(c.ns).UpdateStatus(ctx, policy, opts) +} + +func (c *policiesControl) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + c.clientQueryMetric.Record(metrics.ClientDelete, metrics.KyvernoClient, "Policy", c.ns) + return c.polClient.Policies(c.ns).Delete(ctx, name, opts) +} + +func (c *policiesControl) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + c.clientQueryMetric.Record(metrics.ClientDeleteCollection, metrics.KyvernoClient, "Policy", c.ns) + return c.polClient.Policies(c.ns).DeleteCollection(ctx, opts, listOpts) +} + +func (c *policiesControl) Get(ctx context.Context, name string, opts metav1.GetOptions) (*kyvernov1.Policy, error) { + c.clientQueryMetric.Record(metrics.ClientGet, metrics.KyvernoClient, "Policy", c.ns) + return c.polClient.Policies(c.ns).Get(ctx, name, opts) +} + +func (c *policiesControl) List(ctx context.Context, opts metav1.ListOptions) (*kyvernov1.PolicyList, error) { + c.clientQueryMetric.Record(metrics.ClientList, metrics.KyvernoClient, "Policy", c.ns) + return c.polClient.Policies(c.ns).List(ctx, opts) +} + +func (c *policiesControl) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + c.clientQueryMetric.Record(metrics.ClientWatch, metrics.KyvernoClient, "Policy", c.ns) + return c.polClient.Policies(c.ns).Watch(ctx, opts) +} + +func (c *policiesControl) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *kyvernov1.Policy, err error) { + c.clientQueryMetric.Record(metrics.ClientPatch, metrics.KyvernoClient, "Policy", c.ns) + return c.polClient.Policies(c.ns).Patch(ctx, name, pt, data, opts, subresources...) +} diff --git a/pkg/clients/wrappers/kyverno/v1alpha2/clusterreportchangerequest.go b/pkg/clients/wrappers/kyverno/v1alpha2/clusterreportchangerequest.go new file mode 100644 index 0000000000..52b7bb9f15 --- /dev/null +++ b/pkg/clients/wrappers/kyverno/v1alpha2/clusterreportchangerequest.go @@ -0,0 +1,83 @@ +package v1alpha2 + +import ( + "context" + + "github.com/kyverno/kyverno/api/kyverno/v1alpha2" + kyvernov1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha2" + "github.com/kyverno/kyverno/pkg/clients/wrappers/utils" + "github.com/kyverno/kyverno/pkg/metrics" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/rest" +) + +type ClusterReportChangeRequestsGetter interface { + ClusterReportChangeRequests() ClusterReportChangeRequestControlInterface +} + +type ClusterReportChangeRequestControlInterface interface { + Create(ctx context.Context, clusterReportChangeRequest *v1alpha2.ClusterReportChangeRequest, opts metav1.CreateOptions) (*v1alpha2.ClusterReportChangeRequest, error) + Update(ctx context.Context, clusterReportChangeRequest *v1alpha2.ClusterReportChangeRequest, opts metav1.UpdateOptions) (*v1alpha2.ClusterReportChangeRequest, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1alpha2.ClusterReportChangeRequest, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1alpha2.ClusterReportChangeRequestList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1alpha2.ClusterReportChangeRequest, err error) +} + +type clusterReportChangeRequestControl struct { + client rest.Interface + crcrClient kyvernov1alpha2.ClusterReportChangeRequestsGetter + clientQueryMetric utils.ClientQueryMetric +} + +func newClusterReportChangeRequests(c *KyvernoV1alpha2Client) *clusterReportChangeRequestControl { + return &clusterReportChangeRequestControl{ + client: c.RESTClient(), + crcrClient: c.kyvernov1alpha2Interface, + clientQueryMetric: c.clientQueryMetric, + } +} + +func (c *clusterReportChangeRequestControl) Create(ctx context.Context, clusterReportChangeRequest *v1alpha2.ClusterReportChangeRequest, opts metav1.CreateOptions) (*v1alpha2.ClusterReportChangeRequest, error) { + c.clientQueryMetric.Record(metrics.ClientCreate, metrics.KyvernoClient, "ClusterReportChangeRequest", "") + return c.crcrClient.ClusterReportChangeRequests().Create(ctx, clusterReportChangeRequest, opts) +} + +func (c *clusterReportChangeRequestControl) Update(ctx context.Context, clusterReportChangeRequest *v1alpha2.ClusterReportChangeRequest, opts metav1.UpdateOptions) (*v1alpha2.ClusterReportChangeRequest, error) { + c.clientQueryMetric.Record(metrics.ClientUpdate, metrics.KyvernoClient, "ClusterReportChangeRequest", "") + return c.crcrClient.ClusterReportChangeRequests().Update(ctx, clusterReportChangeRequest, opts) +} + +func (c *clusterReportChangeRequestControl) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + c.clientQueryMetric.Record(metrics.ClientDelete, metrics.KyvernoClient, "ClusterReportChangeRequest", "") + return c.crcrClient.ClusterReportChangeRequests().Delete(ctx, name, opts) +} + +func (c *clusterReportChangeRequestControl) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + c.clientQueryMetric.Record(metrics.ClientDeleteCollection, metrics.KyvernoClient, "ClusterReportChangeRequest", "") + return c.crcrClient.ClusterReportChangeRequests().DeleteCollection(ctx, opts, listOpts) +} + +func (c *clusterReportChangeRequestControl) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1alpha2.ClusterReportChangeRequest, error) { + c.clientQueryMetric.Record(metrics.ClientGet, metrics.KyvernoClient, "ClusterReportChangeRequest", "") + return c.crcrClient.ClusterReportChangeRequests().Get(ctx, name, opts) +} + +func (c *clusterReportChangeRequestControl) List(ctx context.Context, opts metav1.ListOptions) (*v1alpha2.ClusterReportChangeRequestList, error) { + c.clientQueryMetric.Record(metrics.ClientList, metrics.KyvernoClient, "ClusterReportChangeRequest", "") + return c.crcrClient.ClusterReportChangeRequests().List(ctx, opts) +} + +func (c *clusterReportChangeRequestControl) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + c.clientQueryMetric.Record(metrics.ClientWatch, metrics.KyvernoClient, "ClusterReportChangeRequest", "") + return c.crcrClient.ClusterReportChangeRequests().Watch(ctx, opts) +} + +func (c *clusterReportChangeRequestControl) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1alpha2.ClusterReportChangeRequest, err error) { + c.clientQueryMetric.Record(metrics.ClientPatch, metrics.KyvernoClient, "ClusterReportChangeRequest", "") + return c.crcrClient.ClusterReportChangeRequests().Patch(ctx, name, pt, data, opts, subresources...) +} diff --git a/pkg/clients/wrappers/kyverno/v1alpha2/kyverno_client.go b/pkg/clients/wrappers/kyverno/v1alpha2/kyverno_client.go new file mode 100644 index 0000000000..48146ee5a5 --- /dev/null +++ b/pkg/clients/wrappers/kyverno/v1alpha2/kyverno_client.go @@ -0,0 +1,40 @@ +package v1alpha2 + +import ( + kyvernov1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha2" + "github.com/kyverno/kyverno/pkg/clients/wrappers/utils" + "k8s.io/client-go/rest" +) + +type KyvernoV1alpha2Interface interface { + RESTClient() rest.Interface + ClusterReportChangeRequestsGetter + ReportChangeRequestsGetter +} + +type KyvernoV1alpha2Client struct { + restClient rest.Interface + kyvernov1alpha2Interface kyvernov1alpha2.KyvernoV1alpha2Interface + clientQueryMetric utils.ClientQueryMetric +} + +func (c *KyvernoV1alpha2Client) ClusterReportChangeRequests() ClusterReportChangeRequestControlInterface { + return newClusterReportChangeRequests(c) +} + +func (c *KyvernoV1alpha2Client) ReportChangeRequests(namespace string) ReportChangeRequestControlInterface { + return newReportChangeRequests(c, namespace) +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *KyvernoV1alpha2Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} + +func NewForConfig(restClient rest.Interface, kyvernov1alpha2Interface kyvernov1alpha2.KyvernoV1alpha2Interface, m utils.ClientQueryMetric) *KyvernoV1alpha2Client { + return &KyvernoV1alpha2Client{restClient, kyvernov1alpha2Interface, m} +} diff --git a/pkg/clients/wrappers/kyverno/v1alpha2/reportchangerequest.go b/pkg/clients/wrappers/kyverno/v1alpha2/reportchangerequest.go new file mode 100644 index 0000000000..6efed0e1e1 --- /dev/null +++ b/pkg/clients/wrappers/kyverno/v1alpha2/reportchangerequest.go @@ -0,0 +1,85 @@ +package v1alpha2 + +import ( + "context" + + "github.com/kyverno/kyverno/api/kyverno/v1alpha2" + kyvernov1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1alpha2" + "github.com/kyverno/kyverno/pkg/clients/wrappers/utils" + "github.com/kyverno/kyverno/pkg/metrics" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/rest" +) + +type ReportChangeRequestsGetter interface { + ReportChangeRequests(namespace string) ReportChangeRequestControlInterface +} + +type ReportChangeRequestControlInterface interface { + Create(ctx context.Context, creportChangeRequest *v1alpha2.ReportChangeRequest, opts metav1.CreateOptions) (*v1alpha2.ReportChangeRequest, error) + Update(ctx context.Context, creportChangeRequest *v1alpha2.ReportChangeRequest, opts metav1.UpdateOptions) (*v1alpha2.ReportChangeRequest, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1alpha2.ReportChangeRequest, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1alpha2.ReportChangeRequestList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1alpha2.ReportChangeRequest, err error) +} + +type reportChangeRequestControl struct { + client rest.Interface + rcrClient kyvernov1alpha2.ReportChangeRequestsGetter + clientQueryMetric utils.ClientQueryMetric + ns string +} + +func newReportChangeRequests(c *KyvernoV1alpha2Client, namespace string) *reportChangeRequestControl { + return &reportChangeRequestControl{ + client: c.RESTClient(), + rcrClient: c.kyvernov1alpha2Interface, + clientQueryMetric: c.clientQueryMetric, + ns: namespace, + } +} + +func (c *reportChangeRequestControl) Create(ctx context.Context, reportChangeRequest *v1alpha2.ReportChangeRequest, opts metav1.CreateOptions) (*v1alpha2.ReportChangeRequest, error) { + c.clientQueryMetric.Record(metrics.ClientCreate, metrics.KyvernoClient, "ReportChangeRequest", c.ns) + return c.rcrClient.ReportChangeRequests(c.ns).Create(ctx, reportChangeRequest, opts) +} + +func (c *reportChangeRequestControl) Update(ctx context.Context, reportChangeRequest *v1alpha2.ReportChangeRequest, opts metav1.UpdateOptions) (*v1alpha2.ReportChangeRequest, error) { + c.clientQueryMetric.Record(metrics.ClientUpdate, metrics.KyvernoClient, "ReportChangeRequest", c.ns) + return c.rcrClient.ReportChangeRequests(c.ns).Update(ctx, reportChangeRequest, opts) +} + +func (c *reportChangeRequestControl) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + c.clientQueryMetric.Record(metrics.ClientDelete, metrics.KyvernoClient, "ReportChangeRequest", c.ns) + return c.rcrClient.ReportChangeRequests(c.ns).Delete(ctx, name, opts) +} + +func (c *reportChangeRequestControl) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + c.clientQueryMetric.Record(metrics.ClientDeleteCollection, metrics.KyvernoClient, "ReportChangeRequest", c.ns) + return c.rcrClient.ReportChangeRequests(c.ns).DeleteCollection(ctx, opts, listOpts) +} + +func (c *reportChangeRequestControl) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1alpha2.ReportChangeRequest, error) { + c.clientQueryMetric.Record(metrics.ClientGet, metrics.KyvernoClient, "ReportChangeRequest", c.ns) + return c.rcrClient.ReportChangeRequests(c.ns).Get(ctx, name, opts) +} + +func (c *reportChangeRequestControl) List(ctx context.Context, opts metav1.ListOptions) (*v1alpha2.ReportChangeRequestList, error) { + c.clientQueryMetric.Record(metrics.ClientList, metrics.KyvernoClient, "ReportChangeRequest", c.ns) + return c.rcrClient.ReportChangeRequests(c.ns).List(ctx, opts) +} + +func (c *reportChangeRequestControl) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + c.clientQueryMetric.Record(metrics.ClientWatch, metrics.KyvernoClient, "ReportChangeRequest", c.ns) + return c.rcrClient.ReportChangeRequests(c.ns).Watch(ctx, opts) +} + +func (c *reportChangeRequestControl) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1alpha2.ReportChangeRequest, err error) { + c.clientQueryMetric.Record(metrics.ClientPatch, metrics.KyvernoClient, "ReportChangeRequest", c.ns) + return c.rcrClient.ReportChangeRequests(c.ns).Patch(ctx, name, pt, data, opts, subresources...) +} diff --git a/pkg/clients/wrappers/kyverno/v1beta1/kyverno_client.go b/pkg/clients/wrappers/kyverno/v1beta1/kyverno_client.go new file mode 100644 index 0000000000..bdaacc8d5b --- /dev/null +++ b/pkg/clients/wrappers/kyverno/v1beta1/kyverno_client.go @@ -0,0 +1,33 @@ +package v1beta1 + +import ( + kyvernov1beta1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1beta1" + "github.com/kyverno/kyverno/pkg/clients/wrappers/utils" + "k8s.io/client-go/rest" +) + +type KyvernoV1beta1Interface interface { + RESTClient() rest.Interface + UpdateRequestsGetter +} + +type KyvernoV1beta1Client struct { + restClient rest.Interface + kyvernov1beta1Interface kyvernov1beta1.KyvernoV1beta1Interface + clientQueryMetric utils.ClientQueryMetric +} + +func (c *KyvernoV1beta1Client) UpdateRequests(namespace string) UpdateRequestControlInterface { + return newUpdateRequests(c, namespace) +} + +func (c *KyvernoV1beta1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} + +func NewForConfig(restClient rest.Interface, kyvernov1beta1Interface kyvernov1beta1.KyvernoV1beta1Interface, m utils.ClientQueryMetric) *KyvernoV1beta1Client { + return &KyvernoV1beta1Client{restClient, kyvernov1beta1Interface, m} +} diff --git a/pkg/clients/wrappers/kyverno/v1beta1/updaterequest.go b/pkg/clients/wrappers/kyverno/v1beta1/updaterequest.go new file mode 100644 index 0000000000..8207eef52a --- /dev/null +++ b/pkg/clients/wrappers/kyverno/v1beta1/updaterequest.go @@ -0,0 +1,91 @@ +package v1beta1 + +import ( + "context" + + "github.com/kyverno/kyverno/api/kyverno/v1beta1" + kyvernov1beta1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/kyverno/v1beta1" + "github.com/kyverno/kyverno/pkg/clients/wrappers/utils" + "github.com/kyverno/kyverno/pkg/metrics" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/rest" +) + +type UpdateRequestsGetter interface { + UpdateRequests(namespace string) UpdateRequestControlInterface +} + +type UpdateRequestControlInterface interface { + Create(ctx context.Context, updateRequest *v1beta1.UpdateRequest, opts metav1.CreateOptions) (*v1beta1.UpdateRequest, error) + Update(ctx context.Context, updateRequest *v1beta1.UpdateRequest, opts metav1.UpdateOptions) (*v1beta1.UpdateRequest, error) + UpdateStatus(ctx context.Context, updateRequest *v1beta1.UpdateRequest, opts metav1.UpdateOptions) (*v1beta1.UpdateRequest, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.UpdateRequest, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.UpdateRequestList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1beta1.UpdateRequest, err error) +} + +type updateRequestsControl struct { + client rest.Interface + urClient kyvernov1beta1.UpdateRequestsGetter + clientQueryMetric utils.ClientQueryMetric + ns string +} + +func newUpdateRequests(c *KyvernoV1beta1Client, namespace string) *updateRequestsControl { + return &updateRequestsControl{ + client: c.RESTClient(), + urClient: c.kyvernov1beta1Interface, + clientQueryMetric: c.clientQueryMetric, + ns: namespace, + } +} + +func (c *updateRequestsControl) Create(ctx context.Context, updateRequest *v1beta1.UpdateRequest, opts metav1.CreateOptions) (*v1beta1.UpdateRequest, error) { + c.clientQueryMetric.Record(metrics.ClientCreate, metrics.KyvernoClient, "UpdateRequest", c.ns) + return c.urClient.UpdateRequests(c.ns).Create(ctx, updateRequest, opts) +} + +func (c *updateRequestsControl) Update(ctx context.Context, updateRequest *v1beta1.UpdateRequest, opts metav1.UpdateOptions) (*v1beta1.UpdateRequest, error) { + c.clientQueryMetric.Record(metrics.ClientUpdate, metrics.KyvernoClient, "UpdateRequest", c.ns) + return c.urClient.UpdateRequests(c.ns).Update(ctx, updateRequest, opts) +} + +func (c *updateRequestsControl) UpdateStatus(ctx context.Context, updateRequest *v1beta1.UpdateRequest, opts metav1.UpdateOptions) (*v1beta1.UpdateRequest, error) { + c.clientQueryMetric.Record(metrics.ClientUpdateStatus, metrics.KyvernoClient, "UpdateRequest", c.ns) + return c.urClient.UpdateRequests(c.ns).UpdateStatus(ctx, updateRequest, opts) +} + +func (c *updateRequestsControl) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + c.clientQueryMetric.Record(metrics.ClientDelete, metrics.KyvernoClient, "UpdateRequest", c.ns) + return c.urClient.UpdateRequests(c.ns).Delete(ctx, name, opts) +} + +func (c *updateRequestsControl) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + c.clientQueryMetric.Record(metrics.ClientDeleteCollection, metrics.KyvernoClient, "UpdateRequest", c.ns) + return c.urClient.UpdateRequests(c.ns).DeleteCollection(ctx, opts, listOpts) +} + +func (c *updateRequestsControl) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1beta1.UpdateRequest, error) { + c.clientQueryMetric.Record(metrics.ClientGet, metrics.KyvernoClient, "UpdateRequest", c.ns) + return c.urClient.UpdateRequests(c.ns).Get(ctx, name, opts) +} + +func (c *updateRequestsControl) List(ctx context.Context, opts metav1.ListOptions) (*v1beta1.UpdateRequestList, error) { + c.clientQueryMetric.Record(metrics.ClientCreate, metrics.KyvernoClient, "UpdateRequest", c.ns) + return c.urClient.UpdateRequests(c.ns).List(ctx, opts) +} + +func (c *updateRequestsControl) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + c.clientQueryMetric.Record(metrics.ClientWatch, metrics.KyvernoClient, "UpdateRequest", c.ns) + return c.urClient.UpdateRequests(c.ns).Watch(ctx, opts) +} + +func (c *updateRequestsControl) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1beta1.UpdateRequest, err error) { + c.clientQueryMetric.Record(metrics.ClientPatch, metrics.KyvernoClient, "UpdateRequest", c.ns) + return c.urClient.UpdateRequests(c.ns).Patch(ctx, name, pt, data, opts, subresources...) +} diff --git a/pkg/clients/wrappers/policyreport/v1alpha2/clusterpolicyreport.go b/pkg/clients/wrappers/policyreport/v1alpha2/clusterpolicyreport.go new file mode 100644 index 0000000000..163f13e6fd --- /dev/null +++ b/pkg/clients/wrappers/policyreport/v1alpha2/clusterpolicyreport.go @@ -0,0 +1,83 @@ +package v1alpha2 + +import ( + "context" + + "github.com/kyverno/kyverno/api/policyreport/v1alpha2" + policyreportv1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/policyreport/v1alpha2" + "github.com/kyverno/kyverno/pkg/clients/wrappers/utils" + "github.com/kyverno/kyverno/pkg/metrics" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/rest" +) + +type ClusterPolicyReportsGetter interface { + ClusterPolicyReports() ClusterPolicyReportControlInterface +} + +type ClusterPolicyReportControlInterface interface { + Create(ctx context.Context, clusterPolicyReport *v1alpha2.ClusterPolicyReport, opts metav1.CreateOptions) (*v1alpha2.ClusterPolicyReport, error) + Update(ctx context.Context, clusterPolicyReport *v1alpha2.ClusterPolicyReport, opts metav1.UpdateOptions) (*v1alpha2.ClusterPolicyReport, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1alpha2.ClusterPolicyReport, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1alpha2.ClusterPolicyReportList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1alpha2.ClusterPolicyReport, err error) +} + +type clusterPolicyReportsControl struct { + client rest.Interface + cpolrClient policyreportv1alpha2.ClusterPolicyReportsGetter + clientQueryMetric utils.ClientQueryMetric +} + +func newClusterPolicyReports(c *Wgpolicyk8sV1alpha2Client) *clusterPolicyReportsControl { + return &clusterPolicyReportsControl{ + client: c.RESTClient(), + cpolrClient: c.wgpolicyk8sV1alpha2Interface, + clientQueryMetric: c.clientQueryMetric, + } +} + +func (c *clusterPolicyReportsControl) Create(ctx context.Context, clusterPolicyReport *v1alpha2.ClusterPolicyReport, opts metav1.CreateOptions) (*v1alpha2.ClusterPolicyReport, error) { + c.clientQueryMetric.Record(metrics.ClientCreate, metrics.PolicyReportClient, "ClusterPolicyReport", "") + return c.cpolrClient.ClusterPolicyReports().Create(ctx, clusterPolicyReport, opts) +} + +func (c *clusterPolicyReportsControl) Update(ctx context.Context, clusterPolicyReport *v1alpha2.ClusterPolicyReport, opts metav1.UpdateOptions) (*v1alpha2.ClusterPolicyReport, error) { + c.clientQueryMetric.Record(metrics.ClientUpdate, metrics.PolicyReportClient, "ClusterPolicyReport", "") + return c.cpolrClient.ClusterPolicyReports().Update(ctx, clusterPolicyReport, opts) +} + +func (c *clusterPolicyReportsControl) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + c.clientQueryMetric.Record(metrics.ClientDelete, metrics.PolicyReportClient, "ClusterPolicyReport", "") + return c.cpolrClient.ClusterPolicyReports().Delete(ctx, name, opts) +} + +func (c *clusterPolicyReportsControl) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + c.clientQueryMetric.Record(metrics.ClientDeleteCollection, metrics.PolicyReportClient, "ClusterPolicyReport", "") + return c.cpolrClient.ClusterPolicyReports().DeleteCollection(ctx, opts, listOpts) +} + +func (c *clusterPolicyReportsControl) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1alpha2.ClusterPolicyReport, error) { + c.clientQueryMetric.Record(metrics.ClientGet, metrics.PolicyReportClient, "ClusterPolicyReport", "") + return c.cpolrClient.ClusterPolicyReports().Get(ctx, name, opts) +} + +func (c *clusterPolicyReportsControl) List(ctx context.Context, opts metav1.ListOptions) (*v1alpha2.ClusterPolicyReportList, error) { + c.clientQueryMetric.Record(metrics.ClientList, metrics.PolicyReportClient, "ClusterPolicyReport", "") + return c.cpolrClient.ClusterPolicyReports().List(ctx, opts) +} + +func (c *clusterPolicyReportsControl) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + c.clientQueryMetric.Record(metrics.ClientWatch, metrics.PolicyReportClient, "ClusterPolicyReport", "") + return c.cpolrClient.ClusterPolicyReports().Watch(ctx, opts) +} + +func (c *clusterPolicyReportsControl) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1alpha2.ClusterPolicyReport, err error) { + c.clientQueryMetric.Record(metrics.ClientPatch, metrics.PolicyReportClient, "ClusterPolicyReport", "") + return c.cpolrClient.ClusterPolicyReports().Patch(ctx, name, pt, data, opts, subresources...) +} diff --git a/pkg/clients/wrappers/policyreport/v1alpha2/policyreport.go b/pkg/clients/wrappers/policyreport/v1alpha2/policyreport.go new file mode 100644 index 0000000000..dfa0e477cd --- /dev/null +++ b/pkg/clients/wrappers/policyreport/v1alpha2/policyreport.go @@ -0,0 +1,86 @@ +package v1alpha2 + +import ( + "context" + + "github.com/kyverno/kyverno/api/policyreport/v1alpha2" + policyreportv1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/policyreport/v1alpha2" + "github.com/kyverno/kyverno/pkg/clients/wrappers/utils" + "github.com/kyverno/kyverno/pkg/metrics" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/rest" +) + +type PolicyReportsGetter interface { + PolicyReports(namespace string) PolicyReportControlInterface +} + +type PolicyReportControlInterface interface { + Create(ctx context.Context, policyReport *v1alpha2.PolicyReport, opts metav1.CreateOptions) (*v1alpha2.PolicyReport, error) + Update(ctx context.Context, policyReport *v1alpha2.PolicyReport, opts metav1.UpdateOptions) (*v1alpha2.PolicyReport, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1alpha2.PolicyReport, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1alpha2.PolicyReportList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1alpha2.PolicyReport, err error) +} + +type policyReportsControl struct { + client rest.Interface + polrClient policyreportv1alpha2.PolicyReportsGetter + clientQueryMetric utils.ClientQueryMetric + ns string +} + +// newPolicyReports returns a PolicyReports +func newPolicyReports(c *Wgpolicyk8sV1alpha2Client, namespace string) *policyReportsControl { + return &policyReportsControl{ + client: c.RESTClient(), + polrClient: c.wgpolicyk8sV1alpha2Interface, + clientQueryMetric: c.clientQueryMetric, + ns: namespace, + } +} + +func (c *policyReportsControl) Create(ctx context.Context, policyReport *v1alpha2.PolicyReport, opts metav1.CreateOptions) (*v1alpha2.PolicyReport, error) { + c.clientQueryMetric.Record(metrics.ClientCreate, metrics.PolicyReportClient, "PolicyReport", c.ns) + return c.polrClient.PolicyReports(c.ns).Create(ctx, policyReport, opts) +} + +func (c *policyReportsControl) Update(ctx context.Context, policyReport *v1alpha2.PolicyReport, opts metav1.UpdateOptions) (*v1alpha2.PolicyReport, error) { + c.clientQueryMetric.Record(metrics.ClientUpdate, metrics.PolicyReportClient, "PolicyReport", c.ns) + return c.polrClient.PolicyReports(c.ns).Update(ctx, policyReport, opts) +} + +func (c *policyReportsControl) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + c.clientQueryMetric.Record(metrics.ClientDelete, metrics.PolicyReportClient, "PolicyReport", c.ns) + return c.polrClient.PolicyReports(c.ns).Delete(ctx, name, opts) +} + +func (c *policyReportsControl) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + c.clientQueryMetric.Record(metrics.ClientDeleteCollection, metrics.PolicyReportClient, "PolicyReport", c.ns) + return c.polrClient.PolicyReports(c.ns).DeleteCollection(ctx, opts, listOpts) +} + +func (c *policyReportsControl) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1alpha2.PolicyReport, error) { + c.clientQueryMetric.Record(metrics.ClientGet, metrics.PolicyReportClient, "PolicyReport", c.ns) + return c.polrClient.PolicyReports(c.ns).Get(ctx, name, opts) +} + +func (c *policyReportsControl) List(ctx context.Context, opts metav1.ListOptions) (*v1alpha2.PolicyReportList, error) { + c.clientQueryMetric.Record(metrics.ClientList, metrics.PolicyReportClient, "PolicyReport", c.ns) + return c.polrClient.PolicyReports(c.ns).List(ctx, opts) +} + +func (c *policyReportsControl) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + c.clientQueryMetric.Record(metrics.ClientWatch, metrics.PolicyReportClient, "PolicyReport", c.ns) + return c.polrClient.PolicyReports(c.ns).Watch(ctx, opts) +} + +func (c *policyReportsControl) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1alpha2.PolicyReport, err error) { + c.clientQueryMetric.Record(metrics.ClientPatch, metrics.PolicyReportClient, "PolicyReport", c.ns) + return c.polrClient.PolicyReports(c.ns).Patch(ctx, name, pt, data, opts, subresources...) +} diff --git a/pkg/clients/wrappers/policyreport/v1alpha2/policyreport_client.go b/pkg/clients/wrappers/policyreport/v1alpha2/policyreport_client.go new file mode 100644 index 0000000000..4a4edbb850 --- /dev/null +++ b/pkg/clients/wrappers/policyreport/v1alpha2/policyreport_client.go @@ -0,0 +1,38 @@ +package v1alpha2 + +import ( + policyreportv1alpha2 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/typed/policyreport/v1alpha2" + "github.com/kyverno/kyverno/pkg/clients/wrappers/utils" + "k8s.io/client-go/rest" +) + +type Wgpolicyk8sV1alpha2Interface interface { + RESTClient() rest.Interface + ClusterPolicyReportsGetter + PolicyReportsGetter +} + +type Wgpolicyk8sV1alpha2Client struct { + restClient rest.Interface + wgpolicyk8sV1alpha2Interface policyreportv1alpha2.Wgpolicyk8sV1alpha2Interface + clientQueryMetric utils.ClientQueryMetric +} + +func (c *Wgpolicyk8sV1alpha2Client) ClusterPolicyReports() ClusterPolicyReportControlInterface { + return newClusterPolicyReports(c) +} + +func (c *Wgpolicyk8sV1alpha2Client) PolicyReports(namespace string) PolicyReportControlInterface { + return newPolicyReports(c, namespace) +} + +func (c *Wgpolicyk8sV1alpha2Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} + +func NewForConfig(restClient rest.Interface, wgpolicyk8sV1alpha2Interface policyreportv1alpha2.Wgpolicyk8sV1alpha2Interface, m utils.ClientQueryMetric) *Wgpolicyk8sV1alpha2Client { + return &Wgpolicyk8sV1alpha2Client{restClient, wgpolicyk8sV1alpha2Interface, m} +} diff --git a/pkg/clients/wrappers/utils/metric.go b/pkg/clients/wrappers/utils/metric.go new file mode 100644 index 0000000000..2c0d091c26 --- /dev/null +++ b/pkg/clients/wrappers/utils/metric.go @@ -0,0 +1,24 @@ +package utils + +import "github.com/kyverno/kyverno/pkg/metrics" + +type ClientQueryMetric interface { + Record(clientQueryOperation metrics.ClientQueryOperation, clientType metrics.ClientType, resourceKind string, resourceNamespace string) +} + +type metricsConfig struct { + metricsConfig *metrics.MetricsConfig +} + +func NewClientQueryMetric(m *metrics.MetricsConfig) ClientQueryMetric { + return &metricsConfig{ + metricsConfig: m, + } +} + +func (c *metricsConfig) Record(clientQueryOperation metrics.ClientQueryOperation, clientType metrics.ClientType, resourceKind string, resourceNamespace string) { + if c.metricsConfig == nil { + return + } + c.metricsConfig.RecordClientQueries(clientQueryOperation, clientType, resourceKind, resourceNamespace) +} diff --git a/pkg/common/common.go b/pkg/common/common.go index 558b4a1fdf..c64c64da1f 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -7,9 +7,9 @@ import ( "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" enginutils "github.com/kyverno/kyverno/pkg/engine/utils" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" diff --git a/pkg/engine/jsonContext.go b/pkg/engine/jsonContext.go index 9e8895caf5..7aff646cab 100644 --- a/pkg/engine/jsonContext.go +++ b/pkg/engine/jsonContext.go @@ -337,7 +337,6 @@ func loadResourceList(ctx *PolicyContext, p *APIPath) ([]byte, error) { if err != nil { return nil, err } - return l.MarshalJSON() } diff --git a/pkg/engine/k8smanifest.go b/pkg/engine/k8smanifest.go index 9aa8731de7..1ca703f5e6 100644 --- a/pkg/engine/k8smanifest.go +++ b/pkg/engine/k8smanifest.go @@ -16,8 +16,8 @@ import ( "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/auth" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/engine/response" "github.com/pkg/errors" "github.com/sigstore/k8s-manifest-sigstore/pkg/k8smanifest" diff --git a/pkg/engine/loadtargets.go b/pkg/engine/loadtargets.go index 84ddae86eb..c5b23eafec 100644 --- a/pkg/engine/loadtargets.go +++ b/pkg/engine/loadtargets.go @@ -75,6 +75,7 @@ func getTargets(target kyvernov1.ResourceSpec, ctx *PolicyContext, logger logr.L if err != nil { return nil, fmt.Errorf("failed to get target %s/%s %s/%s : %v", target.APIVersion, target.Kind, namespace, name, err) } + return []unstructured.Unstructured{*obj}, nil } diff --git a/pkg/engine/mutation_test.go b/pkg/engine/mutation_test.go index 9ece0ea0c9..6097af4f2b 100644 --- a/pkg/engine/mutation_test.go +++ b/pkg/engine/mutation_test.go @@ -8,7 +8,7 @@ import ( kyverno "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/store" - client "github.com/kyverno/kyverno/pkg/dclient" + client "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/engine/context" "github.com/kyverno/kyverno/pkg/engine/response" "github.com/kyverno/kyverno/pkg/engine/utils" diff --git a/pkg/engine/policyContext.go b/pkg/engine/policyContext.go index b133d2dce5..9e22d57290 100644 --- a/pkg/engine/policyContext.go +++ b/pkg/engine/policyContext.go @@ -3,7 +3,7 @@ package engine import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/engine/context" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) diff --git a/pkg/event/controller.go b/pkg/event/controller.go index 9e16ba151a..5e8bc253a1 100644 --- a/pkg/event/controller.go +++ b/pkg/event/controller.go @@ -7,7 +7,7 @@ import ( "github.com/kyverno/kyverno/pkg/client/clientset/versioned/scheme" kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1" kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" corev1 "k8s.io/api/core/v1" errors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" diff --git a/pkg/metrics/common_types.go b/pkg/metrics/common_types.go index d0b1dd7cd2..975b66b987 100644 --- a/pkg/metrics/common_types.go +++ b/pkg/metrics/common_types.go @@ -55,3 +55,26 @@ const ( ResourceDeleted ResourceRequestOperation = "delete" ResourceConnected ResourceRequestOperation = "connect" ) + +type ClientQueryOperation string + +const ( + ClientCreate ClientQueryOperation = "create" + ClientGet ClientQueryOperation = "get" + ClientList ClientQueryOperation = "list" + ClientUpdate ClientQueryOperation = "update" + ClientUpdateStatus ClientQueryOperation = "update_status" + ClientDelete ClientQueryOperation = "delete" + ClientDeleteCollection ClientQueryOperation = "delete_collection" + ClientWatch ClientQueryOperation = "watch" + ClientPatch ClientQueryOperation = "patch" +) + +type ClientType string + +const ( + KubeDynamicClient ClientType = "dynamic" + KubeClient ClientType = "kubeclient" + KyvernoClient ClientType = "kyverno" + PolicyReportClient ClientType = "policyreport" +) diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 7f47c62d69..304ad65cd3 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -39,50 +39,67 @@ type MetricsConfig struct { policyExecutionDurationMetric syncfloat64.Histogram admissionRequestsMetric syncint64.Counter admissionReviewDurationMetric syncfloat64.Histogram + clientQueriesMetric syncint64.Counter // config Config *kconfig.MetricsConfigData Log logr.Logger } +type MetricsConfigManager interface { + RecordPolicyResults(policyValidationMode PolicyValidationMode, policyType PolicyType, policyBackgroundMode PolicyBackgroundMode, policyNamespace string, policyName string, resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation, ruleName string, ruleResult RuleResult, ruleType RuleType, ruleExecutionCause RuleExecutionCause) + 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) + RecordAdmissionReviewDuration(resourceKind string, resourceNamespace string, resourceRequestOperation string, admissionRequestLatency float64) + RecordClientQueries(clientQueryOperation ClientQueryOperation, clientType ClientType, resourceKind string, resourceNamespace string) +} + func initializeMetrics(m *MetricsConfig) (*MetricsConfig, error) { var err error meter := global.MeterProvider().Meter(meterName) m.policyResultsMetric, err = meter.SyncInt64().Counter("kyverno_policy_results_total", instrument.WithDescription("can be used to track the results associated with the policies applied in the user’s cluster, at the level from rule to policy to admission requests")) if err != nil { - m.Log.Error(err, "Failed to create instrument") + m.Log.Error(err, "Failed to create instrument, kyverno_policy_results_total") return nil, err } m.policyChangesMetric, err = meter.SyncInt64().Counter("kyverno_policy_changes_total", instrument.WithDescription("can be used to track all the changes associated with the Kyverno policies present on the cluster such as creation, updates and deletions")) if err != nil { - m.Log.Error(err, "Failed to create instrument") + m.Log.Error(err, "Failed to create instrument, kyverno_policy_changes_total") return nil, err } m.admissionRequestsMetric, err = meter.SyncInt64().Counter("kyverno_admission_requests_total", instrument.WithDescription("can be used to track the number of admission requests encountered by Kyverno in the cluster")) if err != nil { - m.Log.Error(err, "Failed to create instrument") + m.Log.Error(err, "Failed to create instrument, kyverno_admission_requests_total") return nil, err } m.policyExecutionDurationMetric, err = meter.SyncFloat64().Histogram("kyverno_policy_execution_duration_seconds", instrument.WithDescription("can be used to track the latencies (in seconds) associated with the execution/processing of the individual rules under Kyverno policies whenever they evaluate incoming resource requests")) if err != nil { - m.Log.Error(err, "Failed to create instrument") + m.Log.Error(err, "Failed to create instrument, kyverno_policy_execution_duration_seconds") return nil, err } m.admissionReviewDurationMetric, err = meter.SyncFloat64().Histogram("kyverno_admission_review_duration_seconds", instrument.WithDescription("can be used to track the latencies (in seconds) associated with the entire individual admission review. For example, if an incoming request trigger, say, five policies, this metric will track the e2e latency associated with the execution of all those policies")) if err != nil { - m.Log.Error(err, "Failed to create instrument") + m.Log.Error(err, "Failed to create instrument, kyverno_admission_review_duration_seconds") return nil, err } // Register Async Callbacks m.policyRuleInfoMetric, err = meter.AsyncFloat64().Gauge("kyverno_policy_rule_info_total", instrument.WithDescription("can be used to track the info of the rules or/and policies present in the cluster. 0 means the rule doesn't exist and has been deleted, 1 means the rule is currently existent in the cluster")) if err != nil { - m.Log.Error(err, "Failed to create instrument") + m.Log.Error(err, "Failed to create instrument, kyverno_policy_rule_info_total") + return nil, err + } + + m.clientQueriesMetric, err = meter.SyncInt64().Counter("kyverno_client_queries_total", instrument.WithDescription("can be used to track the number of client queries sent from Kyverno to the API-server")) + if err != nil { + m.Log.Error(err, "Failed to create instrument, kyverno_client_queries_total") return nil, err } @@ -192,6 +209,7 @@ func NewPrometheusConfig(metricsConfigData *kconfig.MetricsConfigData, processor.WithMemory(true), ), controller.WithResource(res), + controller.WithCollectPeriod(10*time.Second), ) exporter, err := prometheus.New(config, c) @@ -277,7 +295,7 @@ func (m *MetricsConfig) RecordPolicyRuleInfo(policyValidationMode PolicyValidati m.policyRuleInfoMetric.Observe(ctx, metricValue, commonLabels...) } -func (m MetricsConfig) RecordAdmissionRequests(resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation) { +func (m *MetricsConfig) RecordAdmissionRequests(resourceKind string, resourceNamespace string, resourceRequestOperation ResourceRequestOperation) { ctx := context.Background() commonLabels := []attribute.KeyValue{ @@ -325,3 +343,16 @@ func (m *MetricsConfig) RecordAdmissionReviewDuration(resourceKind string, resou m.admissionReviewDurationMetric.Record(ctx, admissionRequestLatency, commonLabels...) } + +func (m *MetricsConfig) RecordClientQueries(clientQueryOperation ClientQueryOperation, clientType ClientType, resourceKind string, resourceNamespace string) { + ctx := context.Background() + + commonLabels := []attribute.KeyValue{ + attribute.String("operation", string(clientQueryOperation)), + attribute.String("client_type", string(clientType)), + attribute.String("resource_kind", resourceKind), + attribute.String("resource_namespace", resourceNamespace), + } + + m.clientQueriesMetric.Add(ctx, 1, commonLabels...) +} diff --git a/pkg/openapi/crdSync.go b/pkg/openapi/crdSync.go index 23ed2c7f99..6b4c0bccf9 100644 --- a/pkg/openapi/crdSync.go +++ b/pkg/openapi/crdSync.go @@ -9,7 +9,8 @@ import ( "github.com/googleapis/gnostic/compiler" openapiv2 "github.com/googleapis/gnostic/openapiv2" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" + "github.com/kyverno/kyverno/pkg/metrics" util "github.com/kyverno/kyverno/pkg/utils" "github.com/pkg/errors" "gopkg.in/yaml.v3" @@ -98,6 +99,8 @@ func (c *crdSync) sync() { Version: "v1", Resource: "customresourcedefinitions", }).List(context.TODO(), metav1.ListOptions{}) + + c.client.RecordClientQuery(metrics.ClientList, metrics.KubeDynamicClient, "CustomResourceDefinition", "") if err != nil { log.Log.Error(err, "could not fetch crd's from server") return diff --git a/pkg/policy/actions.go b/pkg/policy/actions.go index cae1cdf47c..200d6eb932 100644 --- a/pkg/policy/actions.go +++ b/pkg/policy/actions.go @@ -4,7 +4,7 @@ import ( "fmt" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/policy/generate" "github.com/kyverno/kyverno/pkg/policy/mutate" "github.com/kyverno/kyverno/pkg/policy/validate" diff --git a/pkg/policy/apply.go b/pkg/policy/apply.go index 205938c26f..a11793b7bd 100644 --- a/pkg/policy/apply.go +++ b/pkg/policy/apply.go @@ -9,7 +9,7 @@ import ( jsonpatch "github.com/evanphx/json-patch/v5" "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/engine" "github.com/kyverno/kyverno/pkg/engine/context" "github.com/kyverno/kyverno/pkg/engine/response" diff --git a/pkg/policy/common.go b/pkg/policy/common.go index 75292dca1d..14449a6741 100644 --- a/pkg/policy/common.go +++ b/pkg/policy/common.go @@ -50,7 +50,6 @@ func (pc *PolicyController) getResourceList(kind, namespace string, labelSelecto log.Error(err, "failed to list resources", "kind", k, "namespace", namespace) return nil } - return resourceList } diff --git a/pkg/policy/generate/auth.go b/pkg/policy/generate/auth.go index ab83c4f975..3fd4dc9674 100644 --- a/pkg/policy/generate/auth.go +++ b/pkg/policy/generate/auth.go @@ -3,7 +3,7 @@ package generate import ( "github.com/go-logr/logr" "github.com/kyverno/kyverno/pkg/auth" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" ) // Operations provides methods to performing operations on resource diff --git a/pkg/policy/generate/validate.go b/pkg/policy/generate/validate.go index 37c6e344b1..b9fc289c93 100644 --- a/pkg/policy/generate/validate.go +++ b/pkg/policy/generate/validate.go @@ -6,7 +6,7 @@ import ( "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" commonAnchors "github.com/kyverno/kyverno/pkg/engine/anchor" "github.com/kyverno/kyverno/pkg/engine/variables" "github.com/kyverno/kyverno/pkg/policy/common" diff --git a/pkg/policy/policy_controller.go b/pkg/policy/policy_controller.go index edd2f9ecff..62a75901a7 100644 --- a/pkg/policy/policy_controller.go +++ b/pkg/policy/policy_controller.go @@ -15,14 +15,14 @@ import ( utilscommon "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common" "github.com/kyverno/kyverno/pkg/autogen" common "github.com/kyverno/kyverno/pkg/background/common" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" "github.com/kyverno/kyverno/pkg/client/clientset/versioned/scheme" kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1" kyvernov1beta1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1beta1" kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1" kyvernov1beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1" + "github.com/kyverno/kyverno/pkg/clients/dclient" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/event" "github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/policyreport" @@ -36,7 +36,6 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/wait" corev1informers "k8s.io/client-go/informers/core/v1" - "k8s.io/client-go/kubernetes" typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" corev1listers "k8s.io/client-go/listers/core/v1" "k8s.io/client-go/tools/cache" @@ -101,7 +100,6 @@ type PolicyController struct { // NewPolicyController create a new PolicyController func NewPolicyController( - kubeClient kubernetes.Interface, kyvernoClient kyvernoclient.Interface, client dclient.Interface, pInformer kyvernov1informers.ClusterPolicyInformer, @@ -504,6 +502,7 @@ func generateTriggers(client dclient.Interface, rule kyvernov1.Rule, log logr.Lo mlist, err := client.ListResource("", kind, "", rule.MatchResources.Selector) if err != nil { log.Error(err, "failed to list matched resource") + continue } list.Items = append(list.Items, mlist.Items...) } diff --git a/pkg/policy/report.go b/pkg/policy/report.go index d36daa2ec2..f67bd30f9c 100644 --- a/pkg/policy/report.go +++ b/pkg/policy/report.go @@ -8,9 +8,9 @@ import ( "github.com/go-logr/logr" "github.com/kyverno/kyverno/api/policyreport/v1alpha2" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1alpha2listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1alpha2" policyreportv1alpha2listers "github.com/kyverno/kyverno/pkg/client/listers/policyreport/v1alpha2" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/engine/response" "github.com/kyverno/kyverno/pkg/event" diff --git a/pkg/policy/validate.go b/pkg/policy/validate.go index 100db75b56..77e2a2b165 100644 --- a/pkg/policy/validate.go +++ b/pkg/policy/validate.go @@ -15,7 +15,7 @@ import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/utils/common" "github.com/kyverno/kyverno/pkg/autogen" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/engine" "github.com/kyverno/kyverno/pkg/engine/context" "github.com/kyverno/kyverno/pkg/engine/variables" diff --git a/pkg/policyreport/changerequestcreator.go b/pkg/policyreport/changerequestcreator.go index fa018d2ac1..63c799b97b 100644 --- a/pkg/policyreport/changerequestcreator.go +++ b/pkg/policyreport/changerequestcreator.go @@ -9,7 +9,7 @@ import ( "time" "github.com/go-logr/logr" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/toggle" "github.com/patrickmn/go-cache" diff --git a/pkg/policyreport/policyreport.go b/pkg/policyreport/policyreport.go index 0f98b3a736..4f5e798933 100644 --- a/pkg/policyreport/policyreport.go +++ b/pkg/policyreport/policyreport.go @@ -10,9 +10,9 @@ import ( "github.com/cornelk/hashmap" kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2" policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1alpha2listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1alpha2" policyreportv1alpha2listers "github.com/kyverno/kyverno/pkg/client/listers/policyreport/v1alpha2" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/config" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/pkg/policyreport/reportcontroller.go b/pkg/policyreport/reportcontroller.go index 29f6cd8645..d9b58c43a0 100644 --- a/pkg/policyreport/reportcontroller.go +++ b/pkg/policyreport/reportcontroller.go @@ -10,13 +10,12 @@ import ( "github.com/go-logr/logr" kyvernov1alpha2 "github.com/kyverno/kyverno/api/kyverno/v1alpha2" policyreportv1alpha2 "github.com/kyverno/kyverno/api/policyreport/v1alpha2" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1alpha2informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1alpha2" policyreportv1alpha2informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/policyreport/v1alpha2" kyvernov1alpha2listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1alpha2" policyreportv1alpha2listers "github.com/kyverno/kyverno/pkg/client/listers/policyreport/v1alpha2" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/toggle" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" "github.com/kyverno/kyverno/pkg/version" @@ -56,7 +55,6 @@ var LabelSelector = &metav1.LabelSelector{ // ReportGenerator creates policy report type ReportGenerator struct { pclient kyvernoclient.Interface - client dclient.Interface clusterReportInformer policyreportv1alpha2informers.ClusterPolicyReportInformer reportInformer policyreportv1alpha2informers.PolicyReportInformer @@ -85,7 +83,6 @@ type ReportGenerator struct { // NewReportGenerator returns a new instance of policy report generator func NewReportGenerator( pclient kyvernoclient.Interface, - dclient dclient.Interface, clusterReportInformer policyreportv1alpha2informers.ClusterPolicyReportInformer, reportInformer policyreportv1alpha2informers.PolicyReportInformer, reportReqInformer kyvernov1alpha2informers.ReportChangeRequestInformer, @@ -96,7 +93,6 @@ func NewReportGenerator( ) (*ReportGenerator, error) { gen := &ReportGenerator{ pclient: pclient, - client: dclient, clusterReportInformer: clusterReportInformer, reportInformer: reportInformer, reportReqInformer: reportReqInformer, @@ -524,24 +520,17 @@ func (g *ReportGenerator) removeFromClusterPolicyReport(policyName, ruleName str } func (g *ReportGenerator) removeFromPolicyReport(policyName, ruleName string) error { - namespaces, err := g.client.ListResource("", "Namespace", "", nil) - if err != nil { - return fmt.Errorf("unable to list namespace %v", err) - } - selector, err := metav1.LabelSelectorAsSelector(LabelSelector) if err != nil { g.log.Error(err, "failed to build labelSelector") } policyReports := []*policyreportv1alpha2.PolicyReport{} - for _, ns := range namespaces.Items { - reports, err := g.reportLister.PolicyReports(ns.GetName()).List(selector) - if err != nil { - return fmt.Errorf("unable to list policyReport for namespace %s %v", ns.GetName(), err) - } - policyReports = append(policyReports, reports...) + reports, err := g.reportLister.PolicyReports(metav1.NamespaceAll).List(selector) + if err != nil { + return fmt.Errorf("unable to list policyReport %v", err) } + policyReports = append(policyReports, reports...) for _, r := range policyReports { newRes := []policyreportv1alpha2.PolicyReportResult{} diff --git a/pkg/policyreport/reportrequest.go b/pkg/policyreport/reportrequest.go index 42ac552edd..35bf9bce30 100644 --- a/pkg/policyreport/reportrequest.go +++ b/pkg/policyreport/reportrequest.go @@ -10,12 +10,11 @@ import ( "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1" kyvernov1alpha2informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1alpha2" kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1" kyvernov1alpha2listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1alpha2" - "github.com/kyverno/kyverno/pkg/dclient" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/engine/response" cmap "github.com/orcaman/concurrent-map" utilruntime "k8s.io/apimachinery/pkg/util/runtime" @@ -31,8 +30,6 @@ const ( // Generator creates report request type Generator struct { - dclient dclient.Interface - reportChangeRequestLister kyvernov1alpha2listers.ReportChangeRequestLister clusterReportChangeRequestLister kyvernov1alpha2listers.ClusterReportChangeRequestLister @@ -64,7 +61,6 @@ type Generator struct { // NewReportChangeRequestGenerator returns a new instance of report request generator func NewReportChangeRequestGenerator(client kyvernoclient.Interface, - dclient dclient.Interface, reportReqInformer kyvernov1alpha2informers.ReportChangeRequestInformer, clusterReportReqInformer kyvernov1alpha2informers.ClusterReportChangeRequestInformer, cpolInformer kyvernov1informers.ClusterPolicyInformer, @@ -73,7 +69,6 @@ func NewReportChangeRequestGenerator(client kyvernoclient.Interface, log logr.Logger, ) *Generator { gen := Generator{ - dclient: dclient, clusterReportChangeRequestLister: clusterReportReqInformer.Lister(), reportChangeRequestLister: reportReqInformer.Lister(), changeRequestMapper: newChangeRequestMapper(), diff --git a/pkg/testrunner/scenario.go b/pkg/testrunner/scenario.go index 2eefcdd315..2f7b0d95db 100644 --- a/pkg/testrunner/scenario.go +++ b/pkg/testrunner/scenario.go @@ -12,7 +12,7 @@ import ( "testing" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/engine" "github.com/kyverno/kyverno/pkg/engine/context" "github.com/kyverno/kyverno/pkg/engine/response" diff --git a/pkg/tls/reader.go b/pkg/tls/reader.go index ff5a86c341..11ba0cb394 100644 --- a/pkg/tls/reader.go +++ b/pkg/tls/reader.go @@ -4,6 +4,7 @@ import ( "context" "github.com/kyverno/kyverno/pkg/config" + "github.com/kyverno/kyverno/pkg/metrics" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -13,9 +14,10 @@ import ( var ErrorsNotFound = "root CA certificate not found" // ReadRootCASecret returns the RootCA from the pre-defined secret -func ReadRootCASecret(client kubernetes.Interface) ([]byte, error) { +func ReadRootCASecret(client kubernetes.Interface, metricsConfig metrics.MetricsConfigManager) ([]byte, error) { sname := GenerateRootCASecretName() stlsca, err := client.CoreV1().Secrets(config.KyvernoNamespace()).Get(context.TODO(), sname, metav1.GetOptions{}) + metricsConfig.RecordClientQueries(metrics.ClientGet, metrics.KubeClient, "Secret", config.KyvernoNamespace()) if err != nil { return nil, err } diff --git a/pkg/utils/util.go b/pkg/utils/util.go index e615d77f39..a6d60fbbe2 100644 --- a/pkg/utils/util.go +++ b/pkg/utils/util.go @@ -8,7 +8,7 @@ import ( "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" engineutils "github.com/kyverno/kyverno/pkg/engine/utils" wildcard "github.com/kyverno/kyverno/pkg/utils/wildcard" "github.com/pkg/errors" diff --git a/pkg/webhookconfig/common.go b/pkg/webhookconfig/common.go index 4ea93c70cf..12081b307a 100644 --- a/pkg/webhookconfig/common.go +++ b/pkg/webhookconfig/common.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/kyverno/kyverno/pkg/config" + "github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/tls" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" appsv1 "k8s.io/api/apps/v1" @@ -52,7 +53,7 @@ func (wrc *Register) readCaData() []byte { // Check if ca is defined in the secret tls-ca // assume the key and signed cert have been defined in secret tls.kyverno - if caData, err = tls.ReadRootCASecret(wrc.kubeClient); err == nil { + if caData, err = tls.ReadRootCASecret(wrc.kubeClient, wrc.metricsConfig); err == nil { logger.V(4).Info("read CA from secret") return caData } @@ -78,6 +79,7 @@ func (wrc *Register) GetKubePolicyClusterRoleName() (*rbacv1.ClusterRole, error) }, } clusterRoles, err := wrc.kubeClient.RbacV1().ClusterRoles().List(context.TODO(), metav1.ListOptions{LabelSelector: metav1.FormatLabelSelector(selector)}) + wrc.metricsConfig.RecordClientQueries(metrics.ClientList, metrics.KubeClient, "ClusterRole", "") if err != nil { return nil, err } diff --git a/pkg/webhookconfig/configmanager.go b/pkg/webhookconfig/configmanager.go index 7b930287d2..1547a37582 100644 --- a/pkg/webhookconfig/configmanager.go +++ b/pkg/webhookconfig/configmanager.go @@ -10,11 +10,12 @@ import ( "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" "github.com/kyverno/kyverno/pkg/autogen" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1" kyvernov1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1" + "github.com/kyverno/kyverno/pkg/clients/dclient" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/toggle" "github.com/kyverno/kyverno/pkg/utils" kubeutils "github.com/kyverno/kyverno/pkg/utils/kube" @@ -58,6 +59,8 @@ type webhookConfigManager struct { // queue queue workqueue.RateLimitingInterface + metricsConfig metrics.MetricsConfigManager + // serverIP used to get the name of debug webhooks serverIP string autoUpdateWebhooks bool @@ -84,6 +87,7 @@ func newWebhookConfigManager( npInformer kyvernov1informers.PolicyInformer, mwcInformer admissionregistrationv1informers.MutatingWebhookConfigurationInformer, vwcInformer admissionregistrationv1informers.ValidatingWebhookConfigurationInformer, + metricsConfig metrics.MetricsConfigManager, serverIP string, autoUpdateWebhooks bool, createDefaultWebhook chan<- string, @@ -102,6 +106,7 @@ func newWebhookConfigManager( npLister: npInformer.Lister(), mutateLister: mwcInformer.Lister(), validateLister: vwcInformer.Lister(), + metricsConfig: metricsConfig, queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "configmanager"), wildcardPolicy: 0, serverIP: serverIP, @@ -458,6 +463,7 @@ func (m *webhookConfigManager) updateMutatingWebhookConfiguration(webhookName st } } if _, err := m.kubeClient.AdmissionregistrationV1().MutatingWebhookConfigurations().Update(context.TODO(), resourceWebhook, metav1.UpdateOptions{}); err != nil { + m.metricsConfig.RecordClientQueries(metrics.ClientUpdate, metrics.KubeClient, kindMutating, "") return errors.Wrapf(err, "unable to update: %s", resourceWebhook.GetName()) } logger.V(4).Info("successfully updated the webhook configuration") @@ -485,6 +491,7 @@ func (m *webhookConfigManager) updateValidatingWebhookConfiguration(webhookName } } if _, err := m.kubeClient.AdmissionregistrationV1().ValidatingWebhookConfigurations().Update(context.TODO(), resourceWebhook, metav1.UpdateOptions{}); err != nil { + m.metricsConfig.RecordClientQueries(metrics.ClientUpdate, metrics.KubeClient, kindValidating, "") return errors.Wrapf(err, "unable to update: %s", resourceWebhook.GetName()) } logger.V(4).Info("successfully updated the webhook configuration") diff --git a/pkg/webhookconfig/registration.go b/pkg/webhookconfig/registration.go index da50916e1c..f666c3d495 100644 --- a/pkg/webhookconfig/registration.go +++ b/pkg/webhookconfig/registration.go @@ -10,10 +10,11 @@ import ( "time" "github.com/go-logr/logr" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1" + "github.com/kyverno/kyverno/pkg/clients/dclient" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/utils" "github.com/pkg/errors" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" @@ -49,6 +50,8 @@ type Register struct { vwcLister admissionregistrationv1listers.ValidatingWebhookConfigurationLister kDeplLister appsv1listers.DeploymentLister + metricsConfig metrics.MetricsConfigManager + // channels stopCh <-chan struct{} UpdateWebhookChan chan bool @@ -75,6 +78,7 @@ func NewRegister( kDeplInformer appsv1informers.DeploymentInformer, pInformer kyvernov1informers.ClusterPolicyInformer, npInformer kyvernov1informers.PolicyInformer, + metricsConfig metrics.MetricsConfigManager, serverIP string, webhookTimeout int32, debug bool, @@ -89,6 +93,7 @@ func NewRegister( mwcLister: mwcInformer.Lister(), vwcLister: vwcInformer.Lister(), kDeplLister: kDeplInformer.Lister(), + metricsConfig: metricsConfig, UpdateWebhookChan: make(chan bool), createDefaultWebhook: make(chan string), stopCh: stopCh, @@ -99,7 +104,7 @@ func NewRegister( autoUpdateWebhooks: autoUpdateWebhooks, } - register.manage = newWebhookConfigManager(client.Discovery(), kubeClient, kyvernoClient, pInformer, npInformer, mwcInformer, vwcInformer, serverIP, register.autoUpdateWebhooks, register.createDefaultWebhook, stopCh, log.WithName("WebhookConfigManager")) + register.manage = newWebhookConfigManager(client.Discovery(), kubeClient, kyvernoClient, pInformer, npInformer, mwcInformer, vwcInformer, metricsConfig, serverIP, register.autoUpdateWebhooks, register.createDefaultWebhook, stopCh, log.WithName("WebhookConfigManager")) return register } @@ -167,6 +172,7 @@ func (wrc *Register) Remove(cleanupKyvernoResource bool, wg *sync.WaitGroup) { defer wg.Done() // delete Lease object to let init container do the cleanup if err := wrc.kubeClient.CoordinationV1().Leases(config.KyvernoNamespace()).Delete(context.TODO(), "kyvernopre-lock", metav1.DeleteOptions{}); err != nil && errorsapi.IsNotFound(err) { + wrc.metricsConfig.RecordClientQueries(metrics.ClientDelete, metrics.KubeClient, "Lease", config.KyvernoNamespace()) wrc.log.WithName("cleanup").Error(err, "failed to clean up Lease lock") } if cleanupKyvernoResource { @@ -223,6 +229,8 @@ func (wrc *Register) UpdateWebhooksCaBundle() error { caData := wrc.readCaData() m := wrc.kubeClient.AdmissionregistrationV1().MutatingWebhookConfigurations() v := wrc.kubeClient.AdmissionregistrationV1().ValidatingWebhookConfigurations() + + wrc.metricsConfig.RecordClientQueries(metrics.ClientList, metrics.KubeClient, kindMutating, "") if list, err := m.List(context.TODO(), metav1.ListOptions{LabelSelector: metav1.FormatLabelSelector(selector)}); err != nil { return err } else { @@ -232,10 +240,13 @@ func (wrc *Register) UpdateWebhooksCaBundle() error { copy.Webhooks[r].ClientConfig.CABundle = caData } if _, err := m.Update(context.TODO(), ©, metav1.UpdateOptions{}); err != nil { + wrc.metricsConfig.RecordClientQueries(metrics.ClientUpdate, metrics.KubeClient, kindMutating, "") return err } } } + + wrc.metricsConfig.RecordClientQueries(metrics.ClientList, metrics.KubeClient, kindValidating, "") if list, err := v.List(context.TODO(), metav1.ListOptions{LabelSelector: metav1.FormatLabelSelector(selector)}); err != nil { return err } else { @@ -244,6 +255,8 @@ func (wrc *Register) UpdateWebhooksCaBundle() error { for r := range copy.Webhooks { copy.Webhooks[r].ClientConfig.CABundle = caData } + + wrc.metricsConfig.RecordClientQueries(metrics.ClientUpdate, metrics.KubeClient, kindValidating, "") if _, err := v.Update(context.TODO(), ©, metav1.UpdateOptions{}); err != nil { return err } @@ -297,6 +310,7 @@ func (wrc *Register) UpdateWebhookConfigurations(configHandler config.Configurat func (wrc *Register) ValidateWebhookConfigurations(namespace, name string) error { logger := wrc.log.WithName("ValidateWebhookConfigurations") cm, err := wrc.kubeClient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), name, metav1.GetOptions{}) + wrc.metricsConfig.RecordClientQueries(metrics.ClientGet, metrics.KubeClient, "ConfigMap", namespace) if err != nil { logger.Error(err, "unable to fetch ConfigMap", "namespace", namespace, "name", name) return nil @@ -312,6 +326,8 @@ func (wrc *Register) ValidateWebhookConfigurations(namespace, name string) error func (wrc *Register) createMutatingWebhookConfiguration(config *admissionregistrationv1.MutatingWebhookConfiguration) error { logger := wrc.log.WithValues("kind", kindMutating, "name", config.Name) + + wrc.metricsConfig.RecordClientQueries(metrics.ClientCreate, metrics.KubeClient, kindMutating, "") if _, err := wrc.kubeClient.AdmissionregistrationV1().MutatingWebhookConfigurations().Create(context.TODO(), config, metav1.CreateOptions{}); err != nil { if errorsapi.IsAlreadyExists(err) { logger.V(6).Info("resource mutating webhook configuration already exists", "name", config.Name) @@ -326,6 +342,8 @@ func (wrc *Register) createMutatingWebhookConfiguration(config *admissionregistr func (wrc *Register) createValidatingWebhookConfiguration(config *admissionregistrationv1.ValidatingWebhookConfiguration) error { logger := wrc.log.WithValues("kind", kindValidating, "name", config.Name) + + wrc.metricsConfig.RecordClientQueries(metrics.ClientCreate, metrics.KubeClient, kindValidating, "") if _, err := wrc.kubeClient.AdmissionregistrationV1().ValidatingWebhookConfigurations().Create(context.TODO(), config, metav1.CreateOptions{}); err != nil { if errorsapi.IsAlreadyExists(err) { logger.V(6).Info("resource validating webhook configuration already exists", "name", config.Name) @@ -395,6 +413,7 @@ func (wrc *Register) createVerifyMutatingWebhookConfiguration(caData []byte) err func (wrc *Register) checkEndpoint() error { endpoint, err := wrc.kubeClient.CoreV1().Endpoints(config.KyvernoNamespace()).Get(context.TODO(), config.KyvernoServiceName(), metav1.GetOptions{}) + wrc.metricsConfig.RecordClientQueries(metrics.ClientGet, metrics.KubeClient, "EndPoint", config.KyvernoNamespace()) if err != nil { return fmt.Errorf("failed to get endpoint %s/%s: %v", config.KyvernoNamespace(), config.KyvernoServiceName(), err) } @@ -404,6 +423,7 @@ func (wrc *Register) checkEndpoint() error { }, } pods, err := wrc.kubeClient.CoreV1().Pods(config.KyvernoNamespace()).List(context.TODO(), metav1.ListOptions{LabelSelector: metav1.FormatLabelSelector(selector)}) + wrc.metricsConfig.RecordClientQueries(metrics.ClientList, metrics.KubeClient, "Pod", config.KyvernoNamespace()) if err != nil { return fmt.Errorf("failed to list Kyverno Pod: %v", err) } @@ -441,6 +461,7 @@ func (wrc *Register) updateResourceValidatingWebhookConfiguration(webhookCfg con wrc.log.V(4).Info("namespaceSelector unchanged, skip updating validatingWebhookConfigurations") return nil } + wrc.metricsConfig.RecordClientQueries(metrics.ClientUpdate, metrics.KubeClient, kindValidating, "") if _, err := wrc.kubeClient.AdmissionregistrationV1().ValidatingWebhookConfigurations().Update(context.TODO(), copy, metav1.UpdateOptions{}); err != nil { return err } @@ -462,6 +483,8 @@ func (wrc *Register) updateResourceMutatingWebhookConfiguration(webhookCfg confi wrc.log.V(4).Info("namespaceSelector unchanged, skip updating mutatingWebhookConfigurations") return nil } + + wrc.metricsConfig.RecordClientQueries(metrics.ClientUpdate, metrics.KubeClient, kindMutating, "") if _, err := wrc.kubeClient.AdmissionregistrationV1().MutatingWebhookConfigurations().Update(context.TODO(), copy, metav1.UpdateOptions{}); err != nil { return err } @@ -506,6 +529,7 @@ func (wrc *Register) updateMutatingWebhookConfiguration(targetConfig *admissionr } // Update the current configuration. currentConfiguration.Webhooks = newWebhooks + wrc.metricsConfig.RecordClientQueries(metrics.ClientUpdate, metrics.KubeClient, kindMutating, "") if _, err := wrc.kubeClient.AdmissionregistrationV1().MutatingWebhookConfigurations().Update(context.TODO(), currentConfiguration, metav1.UpdateOptions{}); err != nil { return err } @@ -550,6 +574,7 @@ func (wrc *Register) updateValidatingWebhookConfiguration(targetConfig *admissio } // Update the current configuration. currentConfiguration.Webhooks = newWebhooks + wrc.metricsConfig.RecordClientQueries(metrics.ClientUpdate, metrics.KubeClient, kindValidating, "") if _, err := wrc.kubeClient.AdmissionregistrationV1().ValidatingWebhookConfigurations().Update(context.TODO(), currentConfiguration, metav1.UpdateOptions{}); err != nil { return err } @@ -560,6 +585,7 @@ func (wrc *Register) updateValidatingWebhookConfiguration(targetConfig *admissio func (wrc *Register) ShouldCleanupKyvernoResource() bool { logger := wrc.log.WithName("cleanupKyvernoResource") deploy, err := wrc.kubeClient.AppsV1().Deployments(config.KyvernoNamespace()).Get(context.TODO(), config.KyvernoDeploymentName(), metav1.GetOptions{}) + wrc.metricsConfig.RecordClientQueries(metrics.ClientGet, metrics.KubeClient, "Deployment", config.KyvernoNamespace()) if err != nil { if errorsapi.IsNotFound(err) { logger.Info("Kyverno deployment not found, cleanup Kyverno resources") @@ -626,6 +652,7 @@ func (wrc *Register) removeMutatingWebhookConfiguration(name string) { } else { logger.Info("webhook configuration deleted") } + wrc.metricsConfig.RecordClientQueries(metrics.ClientDelete, metrics.KubeClient, kindMutating, "") } func (wrc *Register) removeValidatingWebhookConfiguration(name string) { @@ -635,4 +662,5 @@ func (wrc *Register) removeValidatingWebhookConfiguration(name string) { } else { logger.Info("webhook configuration deleted") } + wrc.metricsConfig.RecordClientQueries(metrics.ClientDelete, metrics.KubeClient, kindValidating, "") } diff --git a/pkg/webhooks/policy/handlers.go b/pkg/webhooks/policy/handlers.go index 454a2e1b75..d0db1712c3 100644 --- a/pkg/webhooks/policy/handlers.go +++ b/pkg/webhooks/policy/handlers.go @@ -6,7 +6,7 @@ import ( "time" "github.com/go-logr/logr" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/openapi" policyvalidate "github.com/kyverno/kyverno/pkg/policy" "github.com/kyverno/kyverno/pkg/policymutation" diff --git a/pkg/webhooks/resource/fake.go b/pkg/webhooks/resource/fake.go index 40d8f7c34a..e91dc191f4 100644 --- a/pkg/webhooks/resource/fake.go +++ b/pkg/webhooks/resource/fake.go @@ -5,8 +5,8 @@ import ( fakekyvernov1 "github.com/kyverno/kyverno/pkg/client/clientset/versioned/fake" kyvernoinformers "github.com/kyverno/kyverno/pkg/client/informers/externalversions" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/event" "github.com/kyverno/kyverno/pkg/metrics" "github.com/kyverno/kyverno/pkg/openapi" @@ -32,7 +32,6 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) webhook return &handlers{ client: dclient.NewEmptyFakeClient(), - kyvernoClient: fakekyvernov1.NewSimpleClientset(), configuration: config.NewFakeConfig(), metricsConfig: metricsConfig, pCache: policyCache, diff --git a/pkg/webhooks/resource/handlers.go b/pkg/webhooks/resource/handlers.go index 592c443c2d..2e381ecf57 100644 --- a/pkg/webhooks/resource/handlers.go +++ b/pkg/webhooks/resource/handlers.go @@ -8,11 +8,11 @@ import ( "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1" + "github.com/kyverno/kyverno/pkg/clients/dclient" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/common" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/engine" enginectx "github.com/kyverno/kyverno/pkg/engine/context" "github.com/kyverno/kyverno/pkg/engine/response" diff --git a/pkg/webhooks/resource/utils.go b/pkg/webhooks/resource/utils.go index b251714125..b53a730c4b 100644 --- a/pkg/webhooks/resource/utils.go +++ b/pkg/webhooks/resource/utils.go @@ -9,7 +9,7 @@ import ( kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" "github.com/kyverno/kyverno/pkg/autogen" - "github.com/kyverno/kyverno/pkg/dclient" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/engine" enginectx "github.com/kyverno/kyverno/pkg/engine/context" "github.com/kyverno/kyverno/pkg/engine/response" diff --git a/pkg/webhooks/resource/validate_audit.go b/pkg/webhooks/resource/validate_audit.go index 2997979284..2a9aa4096d 100644 --- a/pkg/webhooks/resource/validate_audit.go +++ b/pkg/webhooks/resource/validate_audit.go @@ -6,9 +6,9 @@ import ( "github.com/go-logr/logr" "github.com/kyverno/kyverno/api/kyverno/v1beta1" + "github.com/kyverno/kyverno/pkg/clients/dclient" "github.com/kyverno/kyverno/pkg/common" "github.com/kyverno/kyverno/pkg/config" - "github.com/kyverno/kyverno/pkg/dclient" "github.com/kyverno/kyverno/pkg/engine" "github.com/kyverno/kyverno/pkg/event" "github.com/kyverno/kyverno/pkg/metrics" diff --git a/pkg/webhooks/updaterequest/generator.go b/pkg/webhooks/updaterequest/generator.go index 0954591d43..64fda52958 100644 --- a/pkg/webhooks/updaterequest/generator.go +++ b/pkg/webhooks/updaterequest/generator.go @@ -7,9 +7,9 @@ import ( backoff "github.com/cenkalti/backoff" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" "github.com/kyverno/kyverno/pkg/background/common" - kyvernoclient "github.com/kyverno/kyverno/pkg/client/clientset/versioned" kyvernov1beta1informers "github.com/kyverno/kyverno/pkg/client/informers/externalversions/kyverno/v1beta1" kyvernov1beta1listers "github.com/kyverno/kyverno/pkg/client/listers/kyverno/v1beta1" + kyvernoclient "github.com/kyverno/kyverno/pkg/clients/wrappers" "github.com/kyverno/kyverno/pkg/config" admissionv1 "k8s.io/api/admission/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"