diff --git a/go.mod b/go.mod index 548d38e671..a3055844b4 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( k8s.io/kubelet v0.35.0 k8s.io/mount-utils v0.35.0 k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 - sigs.k8s.io/controller-runtime v0.22.4 + sigs.k8s.io/controller-runtime v0.23.0 sigs.k8s.io/e2e-framework v0.6.0 sigs.k8s.io/yaml v1.6.0 ) diff --git a/go.sum b/go.sum index da6659cac1..10cf47aded 100644 --- a/go.sum +++ b/go.sum @@ -404,8 +404,8 @@ k8s.io/mount-utils v0.35.0 h1:UDE8RDeqmQh1u/yRd+GZC2EpDibiyAfmMEsm43lKNQI= k8s.io/mount-utils v0.35.0/go.mod h1:ppC4d+mUpfbAJr/V2E8vvxeCEckNM+S5b0kQBQjd3Pw= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.22.4 h1:GEjV7KV3TY8e+tJ2LCTxUTanW4z/FmNB7l327UfMq9A= -sigs.k8s.io/controller-runtime v0.22.4/go.mod h1:+QX1XUpTXN4mLoblf4tqr5CQcyHPAki2HLXqQMY6vh8= +sigs.k8s.io/controller-runtime v0.23.0 h1:Ubi7klJWiwEWqDY+odSVZiFA0aDSevOCXpa38yCSYu8= +sigs.k8s.io/controller-runtime v0.23.0/go.mod h1:DBOIr9NsprUqCZ1ZhsuJ0wAnQSIxY/C6VjZbmLgw0j0= sigs.k8s.io/e2e-framework v0.6.0 h1:p7hFzHnLKO7eNsWGI2AbC1Mo2IYxidg49BiT4njxkrM= sigs.k8s.io/e2e-framework v0.6.0/go.mod h1:IREnCHnKgRCioLRmNi0hxSJ1kJ+aAdjEKK/gokcZu4k= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= diff --git a/pkg/api/latest/dynakube/dynakube_webhook.go b/pkg/api/latest/dynakube/dynakube_webhook.go deleted file mode 100644 index c358977f15..0000000000 --- a/pkg/api/latest/dynakube/dynakube_webhook.go +++ /dev/null @@ -1,13 +0,0 @@ -package dynakube - -import ( - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -func SetupWebhookWithManager(mgr ctrl.Manager, validator admission.CustomValidator) error { - return ctrl.NewWebhookManagedBy(mgr). - For(&DynaKube{}). - WithValidator(validator). // will create an endpoint at /validate-dynatrace-com-v1beta6-dynakube - Complete() -} diff --git a/pkg/api/v1alpha1/edgeconnect/edgeconnect_webhook.go b/pkg/api/v1alpha1/edgeconnect/edgeconnect_webhook.go deleted file mode 100644 index e7001ae841..0000000000 --- a/pkg/api/v1alpha1/edgeconnect/edgeconnect_webhook.go +++ /dev/null @@ -1,13 +0,0 @@ -package edgeconnect - -import ( - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -func SetupWebhookWithManager(mgr ctrl.Manager, validator admission.CustomValidator) error { - return ctrl.NewWebhookManagedBy(mgr). - For(&EdgeConnect{}). - WithValidator(validator). // will create an endpoint at /validate-dynatrace-com-v1alpha1-edgeconnect - Complete() -} diff --git a/pkg/api/v1alpha2/edgeconnect/edgeconnect_webhook.go b/pkg/api/v1alpha2/edgeconnect/edgeconnect_webhook.go deleted file mode 100644 index 4b4dbbf1b8..0000000000 --- a/pkg/api/v1alpha2/edgeconnect/edgeconnect_webhook.go +++ /dev/null @@ -1,13 +0,0 @@ -package edgeconnect - -import ( - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -func SetupWebhookWithManager(mgr ctrl.Manager, validator admission.CustomValidator) error { - return ctrl.NewWebhookManagedBy(mgr). - For(&EdgeConnect{}). - WithValidator(validator). // will create an endpoint at /validate-dynatrace-com-v1alpha2-edgeconnect - Complete() -} diff --git a/pkg/api/v1beta3/dynakube/dynakube_webhook.go b/pkg/api/v1beta3/dynakube/dynakube_webhook.go deleted file mode 100644 index a20d2975fa..0000000000 --- a/pkg/api/v1beta3/dynakube/dynakube_webhook.go +++ /dev/null @@ -1,13 +0,0 @@ -package dynakube - -import ( - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -func SetupWebhookWithManager(mgr ctrl.Manager, validator admission.CustomValidator) error { - return ctrl.NewWebhookManagedBy(mgr). - For(&DynaKube{}). - WithValidator(validator). // will create an endpoint at /validate-dynatrace-com-v1beta3-dynakube - Complete() -} diff --git a/pkg/api/v1beta4/dynakube/dynakube_webhook.go b/pkg/api/v1beta4/dynakube/dynakube_webhook.go deleted file mode 100644 index e09373cbc9..0000000000 --- a/pkg/api/v1beta4/dynakube/dynakube_webhook.go +++ /dev/null @@ -1,13 +0,0 @@ -package dynakube - -import ( - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -func SetupWebhookWithManager(mgr ctrl.Manager, validator admission.CustomValidator) error { - return ctrl.NewWebhookManagedBy(mgr). - For(&DynaKube{}). - WithValidator(validator). // will create an endpoint at /validate-dynatrace-com-v1beta4-dynakube - Complete() -} diff --git a/pkg/api/v1beta5/dynakube/dynakube_webhook.go b/pkg/api/v1beta5/dynakube/dynakube_webhook.go deleted file mode 100644 index 797f673e37..0000000000 --- a/pkg/api/v1beta5/dynakube/dynakube_webhook.go +++ /dev/null @@ -1,13 +0,0 @@ -package dynakube - -import ( - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/webhook/admission" -) - -func SetupWebhookWithManager(mgr ctrl.Manager, validator admission.CustomValidator) error { - return ctrl.NewWebhookManagedBy(mgr). - For(&DynaKube{}). - WithValidator(validator). // will create an endpoint at /validate-dynatrace-com-v1beta5-dynakube - Complete() -} diff --git a/pkg/api/validation/dynakube/activegate.go b/pkg/api/validation/dynakube/activegate.go index 984aeb5fd0..4d3845a80e 100644 --- a/pkg/api/validation/dynakube/activegate.go +++ b/pkg/api/validation/dynakube/activegate.go @@ -22,7 +22,7 @@ Make sure you don't duplicate an Activegate capability in your custom resource. warningMissingActiveGateMemoryLimit = `ActiveGate specification missing memory limits. Can cause excess memory usage.` ) -func duplicateActiveGateCapabilities(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func duplicateActiveGateCapabilities(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if dk.ActiveGate().IsEnabled() { capabilities := dk.Spec.ActiveGate.Capabilities duplicateChecker := map[activegate.CapabilityDisplayName]bool{} @@ -41,7 +41,7 @@ func duplicateActiveGateCapabilities(_ context.Context, _ *Validator, dk *dynaku return "" } -func invalidActiveGateCapabilities(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func invalidActiveGateCapabilities(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if dk.ActiveGate().IsEnabled() { capabilities := dk.Spec.ActiveGate.Capabilities for _, capability := range capabilities { @@ -56,7 +56,7 @@ func invalidActiveGateCapabilities(_ context.Context, _ *Validator, dk *dynakube return "" } -func missingActiveGateMemoryLimit(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func missingActiveGateMemoryLimit(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if dk.ActiveGate().IsEnabled() && !memoryLimitSet(dk.Spec.ActiveGate.Resources) { return warningMissingActiveGateMemoryLimit @@ -73,7 +73,7 @@ func activeGateMutuallyExclusivePVCSettings(dk *dynakube.DynaKube) bool { return dk.Spec.ActiveGate.UseEphemeralVolume && dk.Spec.ActiveGate.VolumeClaimTemplate != nil } -func mutuallyExclusiveActiveGatePVsettings(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func mutuallyExclusiveActiveGatePVsettings(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if activeGateMutuallyExclusivePVCSettings(dk) { log.Info("requested dynakube specifies mutually exclusive VolumeClaimTemplate settings for ActiveGate.", "name", dk.Name, "namespace", dk.Namespace) diff --git a/pkg/api/validation/dynakube/api_url.go b/pkg/api/validation/dynakube/api_url.go index 5bb1f2e67e..3ed5832db1 100644 --- a/pkg/api/validation/dynakube/api_url.go +++ b/pkg/api/validation/dynakube/api_url.go @@ -24,7 +24,7 @@ const ( errorMutatedAPIURL = `The DynaKube's specification mutated the API URL although it is immutable. Please delete the CR and then apply a new one` ) -func NoAPIURL(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func NoAPIURL(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { apiURL := dk.Spec.APIURL if apiURL == ExampleAPIURL { @@ -42,7 +42,7 @@ func NoAPIURL(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { return "" } -func IsInvalidAPIURL(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func IsInvalidAPIURL(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { apiURL := dk.Spec.APIURL if !strings.HasSuffix(apiURL, "/api") { @@ -72,7 +72,7 @@ func IsInvalidAPIURL(_ context.Context, _ *Validator, dk *dynakube.DynaKube) str return "" } -func IsThirdGenAPIUrl(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func IsThirdGenAPIUrl(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if strings.Contains(dk.APIURL(), ".apps.") { return errorThirdGenAPIURL } @@ -80,7 +80,7 @@ func IsThirdGenAPIUrl(_ context.Context, _ *Validator, dk *dynakube.DynaKube) st return "" } -func IsMutatedAPIURL(_ context.Context, _ *Validator, oldDk *dynakube.DynaKube, newDk *dynakube.DynaKube) string { +func IsMutatedAPIURL(_ context.Context, _ *validatorClient, oldDk *dynakube.DynaKube, newDk *dynakube.DynaKube) string { if oldDk.Spec.APIURL != newDk.Spec.APIURL { return errorMutatedAPIURL } diff --git a/pkg/api/validation/dynakube/databases.go b/pkg/api/validation/dynakube/databases.go index 8316a1a670..ab30cc8c2f 100644 --- a/pkg/api/validation/dynakube/databases.go +++ b/pkg/api/validation/dynakube/databases.go @@ -22,7 +22,7 @@ const ( warningHostPathDatabaseVolumeDetected = `Host path database volume detected. If you're on OpenShift, mounting host path volumes will be prohibited by the SCC and cause silent failures. If you still want to do this, make sure to create and bind corresponding roles.` ) -func missingDatabaseExecutorImage(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func missingDatabaseExecutorImage(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.Extensions().IsDatabasesEnabled() { return "" } @@ -36,7 +36,7 @@ func missingDatabaseExecutorImage(_ context.Context, _ *Validator, dk *dynakube. return "" } -func conflictingOrInvalidDatabasesVolumeMounts(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func conflictingOrInvalidDatabasesVolumeMounts(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.Extensions().IsDatabasesEnabled() { return "" } @@ -71,7 +71,7 @@ func conflictingOrInvalidDatabasesVolumeMounts(_ context.Context, _ *Validator, return "" } -func hostPathDatabaseVolumeFound(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func hostPathDatabaseVolumeFound(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.Extensions().IsDatabasesEnabled() { return "" } @@ -89,7 +89,7 @@ func hostPathDatabaseVolumeFound(_ context.Context, _ *Validator, dk *dynakube.D return "" } -func unusedDatabasesVolume(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func unusedDatabasesVolume(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.Extensions().IsDatabasesEnabled() { return "" } diff --git a/pkg/api/validation/dynakube/dynakube_name.go b/pkg/api/validation/dynakube/dynakube_name.go index 5ee4d4415d..e3cbd9b6b3 100644 --- a/pkg/api/validation/dynakube/dynakube_name.go +++ b/pkg/api/validation/dynakube/dynakube_name.go @@ -42,7 +42,7 @@ const ( maxNameLengthForKSPM = maxDaemonSetNameLength - len(consts.NodeCollectorNameSuffix) ) -func nameInvalid(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func nameInvalid(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if dk.Name == "" { // Make unit testing easier. This can never happen in an actual cluster. return "" diff --git a/pkg/api/validation/dynakube/eec.go b/pkg/api/validation/dynakube/eec.go index 143d6714eb..954bc2875f 100644 --- a/pkg/api/validation/dynakube/eec.go +++ b/pkg/api/validation/dynakube/eec.go @@ -14,7 +14,7 @@ const ( warningConflictingAPIURLForExtensions = `You are already using a Dynakube ('%s') that enables extensions. Having multiple Dynakubes with same '.spec.apiUrl' and '.spec.extensions' enabled can have severe side-effects on “sum” and “count” metrics and cause double-billing.` ) -func extensionControllerImage(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func extensionControllerImage(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.Extensions().IsAnyEnabled() { return "" } @@ -28,13 +28,13 @@ func extensionControllerImage(_ context.Context, _ *Validator, dk *dynakube.Dyna return "" } -func conflictingAPIURLForExtensions(ctx context.Context, dv *Validator, dk *dynakube.DynaKube) string { +func conflictingAPIURLForExtensions(ctx context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { if !dk.Extensions().IsAnyEnabled() { return "" } validDynakubes := &dynakube.DynaKubeList{} - if err := dv.apiReader.List(ctx, validDynakubes, &client.ListOptions{Namespace: dk.Namespace}); err != nil { + if err := vc.apiReader.List(ctx, validDynakubes, &client.ListOptions{Namespace: dk.Namespace}); err != nil { log.Info("error occurred while listing dynakubes", "err", err.Error()) return "" @@ -53,7 +53,7 @@ func conflictingAPIURLForExtensions(ctx context.Context, dv *Validator, dk *dyna return "" } -func extensionControllerPVCStorageDevice(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func extensionControllerPVCStorageDevice(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.Extensions().IsAnyEnabled() { return "" } diff --git a/pkg/api/validation/dynakube/extensions.go b/pkg/api/validation/dynakube/extensions.go index a225866d00..b6036bff72 100644 --- a/pkg/api/validation/dynakube/extensions.go +++ b/pkg/api/validation/dynakube/extensions.go @@ -10,7 +10,7 @@ const ( warningExtensionsWithoutK8SMonitoring = "The Dynakube is configured with extensions without an ActiveGate with `kubernetes-monitoring` enabled or the `automatic-kubernetes-api-monitoring` feature flag. You need to ensure that Kubernetes monitoring is setup for this cluster." ) -func extensionsWithoutK8SMonitoring(ctx context.Context, dv *Validator, dk *dynakube.DynaKube) string { +func extensionsWithoutK8SMonitoring(ctx context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { if dk.Extensions().IsAnyEnabled() && (!dk.ActiveGate().IsKubernetesMonitoringEnabled() || !dk.FF().IsAutomaticK8sAPIMonitoring()) { return warningExtensionsWithoutK8SMonitoring } diff --git a/pkg/api/validation/dynakube/featureflag.go b/pkg/api/validation/dynakube/featureflag.go index a9ff39a1d6..9aa9dd983a 100644 --- a/pkg/api/validation/dynakube/featureflag.go +++ b/pkg/api/validation/dynakube/featureflag.go @@ -19,7 +19,7 @@ var deprecatedFeatureFlags = []string{ exp.AGDisableUpdatesKey, //nolint:staticcheck } -func deprecatedFeatureFlag(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func deprecatedFeatureFlag(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { results := strings.Builder{} for _, flag := range deprecatedFeatureFlags { diff --git a/pkg/api/validation/dynakube/image.go b/pkg/api/validation/dynakube/image.go index eba17be425..d9407cefec 100644 --- a/pkg/api/validation/dynakube/image.go +++ b/pkg/api/validation/dynakube/image.go @@ -13,7 +13,7 @@ const ( errorUnparsableImageRef = `Custom %s image can't be parsed, make sure it's a valid image reference.` ) -func imageFieldHasTenantImage(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func imageFieldHasTenantImage(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { type imageField struct { value string section string diff --git a/pkg/api/validation/dynakube/istio.go b/pkg/api/validation/dynakube/istio.go index cab11ad2f3..0f7824588d 100644 --- a/pkg/api/validation/dynakube/istio.go +++ b/pkg/api/validation/dynakube/istio.go @@ -12,9 +12,9 @@ const ( errorFailToInitIstioClient = `Failed to initialize istio client` ) -func noResourcesAvailable(_ context.Context, dv *Validator, dk *dynakube.DynaKube) string { +func noResourcesAvailable(_ context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { if dk.Spec.EnableIstio { - istioClient, err := istio.NewClient(dv.cfg, dk) + istioClient, err := istio.NewClient(vc.cfg, dk) if err != nil { return errorFailToInitIstioClient } diff --git a/pkg/api/validation/dynakube/kspm.go b/pkg/api/validation/dynakube/kspm.go index ef4d6e1661..3623b93f90 100644 --- a/pkg/api/validation/dynakube/kspm.go +++ b/pkg/api/validation/dynakube/kspm.go @@ -18,7 +18,7 @@ const ( errorKSPMRelativeHostPath = `The Dynakube's specification specifies KSPM, relative path found on the MappedHostPath list. Use absolute paths only. Relative path: %s` ) -func tooManyAGReplicas(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func tooManyAGReplicas(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if dk.KSPM().IsEnabled() && dk.ActiveGate().GetReplicas() > 1 { return errorTooManyAGReplicas } @@ -26,7 +26,7 @@ func tooManyAGReplicas(_ context.Context, _ *Validator, dk *dynakube.DynaKube) s return "" } -func kspmWithoutK8SMonitoring(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func kspmWithoutK8SMonitoring(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if dk.KSPM().IsEnabled() && (!dk.ActiveGate().IsKubernetesMonitoringEnabled() || !dk.FF().IsAutomaticK8sAPIMonitoring()) { return errorKSPMMissingKubemon } @@ -34,7 +34,7 @@ func kspmWithoutK8SMonitoring(_ context.Context, _ *Validator, dk *dynakube.Dyna return "" } -func missingKSPMImage(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func missingKSPMImage(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.KSPM().IsEnabled() { return "" } @@ -46,7 +46,7 @@ func missingKSPMImage(_ context.Context, _ *Validator, dk *dynakube.DynaKube) st return "" } -func noMappedHostPaths(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func noMappedHostPaths(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.KSPM().IsEnabled() { return "" } @@ -58,7 +58,7 @@ func noMappedHostPaths(_ context.Context, _ *Validator, dk *dynakube.DynaKube) s return "" } -func mappedHostPathsWithRootPath(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func mappedHostPathsWithRootPath(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.KSPM().IsEnabled() { return "" } @@ -72,7 +72,7 @@ func mappedHostPathsWithRootPath(_ context.Context, _ *Validator, dk *dynakube.D return "" } -func relativeMappedHostPaths(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func relativeMappedHostPaths(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.KSPM().IsEnabled() { return "" } diff --git a/pkg/api/validation/dynakube/logmonitoring.go b/pkg/api/validation/dynakube/logmonitoring.go index fa874e4013..814198b444 100644 --- a/pkg/api/validation/dynakube/logmonitoring.go +++ b/pkg/api/validation/dynakube/logmonitoring.go @@ -12,7 +12,7 @@ const ( errorLogMonitoringMissingImage = `The Dynakube's specification specifies standalone Log monitoring, but no image repository/tag is configured.` ) -func logMonitoringWithoutK8SMonitoring(ctx context.Context, dv *Validator, dk *dynakube.DynaKube) string { +func logMonitoringWithoutK8SMonitoring(ctx context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { if dk.LogMonitoring().IsEnabled() && (!dk.ActiveGate().IsKubernetesMonitoringEnabled() || !dk.FF().IsAutomaticK8sAPIMonitoring()) { return warningLogMonitoringWithoutK8SMonitoring } @@ -20,7 +20,7 @@ func logMonitoringWithoutK8SMonitoring(ctx context.Context, dv *Validator, dk *d return "" } -func ignoredLogMonitoringTemplate(ctx context.Context, dv *Validator, dk *dynakube.DynaKube) string { +func ignoredLogMonitoringTemplate(ctx context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { if dk.LogMonitoring().IsStandalone() { return "" } @@ -32,7 +32,7 @@ func ignoredLogMonitoringTemplate(ctx context.Context, dv *Validator, dk *dynaku return "" } -func missingLogMonitoringImage(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func missingLogMonitoringImage(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.LogMonitoring().IsStandalone() { return "" } diff --git a/pkg/api/validation/dynakube/metadata_enrichment.go b/pkg/api/validation/dynakube/metadata_enrichment.go index f399be47c1..b7e4ad1d7b 100644 --- a/pkg/api/validation/dynakube/metadata_enrichment.go +++ b/pkg/api/validation/dynakube/metadata_enrichment.go @@ -10,7 +10,7 @@ const ( warningMetadataEnrichmentDisabledForInjection = "metadataEnrichment.enabled is set to false, but OneAgent injection is enabled (applicationMonitoring/cloudNativeFullstack). Metadata enrichment will still be applied and this setting is ignored." ) -func disabledMetadataEnrichmentForInjectionModes(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func disabledMetadataEnrichmentForInjectionModes(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if dk.Spec.MetadataEnrichment.Enabled == nil || *dk.Spec.MetadataEnrichment.Enabled { return "" } diff --git a/pkg/api/validation/dynakube/module_test.go b/pkg/api/validation/dynakube/module_test.go index eb994740bd..f9813c429f 100644 --- a/pkg/api/validation/dynakube/module_test.go +++ b/pkg/api/validation/dynakube/module_test.go @@ -206,7 +206,7 @@ func TestIsModuleDisabled(t *testing.T) { for _, test := range testCases { t.Run(test.title, func(t *testing.T) { - errMsg := test.moduleFunc(ctx, &Validator{modules: test.modules}, &test.dk) + errMsg := test.moduleFunc(ctx, &validatorClient{modules: test.modules}, &test.dk) assert.Equal(t, test.expectedMessage, errMsg) }) } diff --git a/pkg/api/validation/dynakube/modules.go b/pkg/api/validation/dynakube/modules.go index 5ecd440318..d24e139984 100644 --- a/pkg/api/validation/dynakube/modules.go +++ b/pkg/api/validation/dynakube/modules.go @@ -18,50 +18,50 @@ var ( errorKSPMDependsOnKubernetesMonitoringModule = installconfig.GetDependentModuleValidationErrorMessage("KubernetesMonitoring", "KSPM") ) -func isOneAgentModuleDisabled(_ context.Context, v *Validator, dk *dynakube.DynaKube) string { - if dk.OneAgent().IsDaemonsetRequired() && !v.modules.OneAgent { +func isOneAgentModuleDisabled(_ context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { + if dk.OneAgent().IsDaemonsetRequired() && !vc.modules.OneAgent { return errorOneAgentModuleDisabled } return "" } -func isActiveGateModuleDisabled(_ context.Context, v *Validator, dk *dynakube.DynaKube) string { - if dk.ActiveGate().IsEnabled() && !v.modules.ActiveGate { +func isActiveGateModuleDisabled(_ context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { + if dk.ActiveGate().IsEnabled() && !vc.modules.ActiveGate { return errorActiveGateModuleDisabled } - if dk.ActiveGate().IsKubernetesMonitoringEnabled() && !v.modules.KubernetesMonitoring { + if dk.ActiveGate().IsKubernetesMonitoringEnabled() && !vc.modules.KubernetesMonitoring { return errorKubernetesMonitoringModuleDisabled } return "" } -func isExtensionsModuleDisabled(_ context.Context, v *Validator, dk *dynakube.DynaKube) string { - if dk.Extensions().IsAnyEnabled() && !v.modules.Extensions { +func isExtensionsModuleDisabled(_ context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { + if dk.Extensions().IsAnyEnabled() && !vc.modules.Extensions { return errorExtensionsModuleDisabled } return "" } -func isLogMonitoringModuleDisabled(_ context.Context, v *Validator, dk *dynakube.DynaKube) string { - if dk.LogMonitoring().IsEnabled() && !v.modules.LogMonitoring { +func isLogMonitoringModuleDisabled(_ context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { + if dk.LogMonitoring().IsEnabled() && !vc.modules.LogMonitoring { return errorLogMonitoringModuleDisabled } return "" } -func isKSPMDisabled(_ context.Context, v *Validator, dk *dynakube.DynaKube) string { +func isKSPMDisabled(_ context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { if dk.KSPM().IsEnabled() { errs := []string{} - if !v.modules.KSPM { + if !vc.modules.KSPM { errs = append(errs, errorKSPMModuleDisabled) } - if !v.modules.KubernetesMonitoring { + if !vc.modules.KubernetesMonitoring { errs = append(errs, errorKSPMDependsOnKubernetesMonitoringModule) } diff --git a/pkg/api/validation/dynakube/namespace_selector.go b/pkg/api/validation/dynakube/namespace_selector.go index 70963aaaa1..a04336fc71 100644 --- a/pkg/api/validation/dynakube/namespace_selector.go +++ b/pkg/api/validation/dynakube/namespace_selector.go @@ -17,12 +17,12 @@ Make sure the namespaceSelector doesn't conflict with other Dynakubes namespaceS errorNamespaceSelectorMatchLabelsViolateLabelSpec = "The DynaKube's namespaceSelector contains matchLabels that are not conform to spec." ) -func conflictingNamespaceSelector(ctx context.Context, dv *Validator, dk *dynakube.DynaKube) string { +func conflictingNamespaceSelector(ctx context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { if !dk.OneAgent().IsAppInjectionNeeded() && !dk.MetadataEnrichment().IsEnabled() { return "" } - dkMapper := mapper.NewDynakubeMapper(ctx, nil, dv.apiReader, dk.Namespace, dk) + dkMapper := mapper.NewDynakubeMapper(ctx, nil, vc.apiReader, dk.Namespace, dk) _, err := dkMapper.MatchingNamespaces() if err != nil && err.Error() == mapper.ErrorConflictingNamespace { @@ -34,7 +34,7 @@ func conflictingNamespaceSelector(ctx context.Context, dv *Validator, dk *dynaku return "" } -func namespaceSelectorViolateLabelSpec(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func namespaceSelectorViolateLabelSpec(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { errs := validation.ValidateLabelSelector(dk.OneAgent().GetNamespaceSelector(), validation.LabelSelectorValidationOptions{AllowInvalidLabelValueInSelector: false}, field.NewPath("spec", "namespaceSelector")) if len(errs) == 0 { return "" diff --git a/pkg/api/validation/dynakube/oneagent.go b/pkg/api/validation/dynakube/oneagent.go index b1fc6a6d22..e0ac000a11 100644 --- a/pkg/api/validation/dynakube/oneagent.go +++ b/pkg/api/validation/dynakube/oneagent.go @@ -42,7 +42,7 @@ Use a nodeSelector to avoid this conflict. Conflicting DynaKubes: %s` errorSameHostTagMultipleTimes = "Providing the same tag(s) (%s) multiple times with --set-host-tag is not allowed." ) -func conflictingOneAgentConfiguration(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func conflictingOneAgentConfiguration(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { counter := 0 if dk.OneAgent().IsApplicationMonitoringMode() { counter += 1 @@ -69,13 +69,13 @@ func conflictingOneAgentConfiguration(_ context.Context, _ *Validator, dk *dynak return "" } -func conflictingOneAgentNodeSelector(ctx context.Context, dv *Validator, dk *dynakube.DynaKube) string { +func conflictingOneAgentNodeSelector(ctx context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { if !dk.OneAgent().IsDaemonsetRequired() && !dk.LogMonitoring().IsStandalone() { return "" } validDynakubes := &dynakube.DynaKubeList{} - if err := dv.apiReader.List(ctx, validDynakubes, &client.ListOptions{Namespace: dk.Namespace}); err != nil { + if err := vc.apiReader.List(ctx, validDynakubes, &client.ListOptions{Namespace: dk.Namespace}); err != nil { log.Info("error occurred while listing dynakubes", "err", err.Error()) return "" @@ -128,8 +128,8 @@ func mapKeysToString(m map[string]bool, sep string) string { return strings.Join(keys, sep) } -func imageFieldSetWithoutCSIFlag(_ context.Context, v *Validator, dk *dynakube.DynaKube) string { - if !v.modules.CSIDriver && !dk.FF().IsNodeImagePull() { +func imageFieldSetWithoutCSIFlag(_ context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { + if !vc.modules.CSIDriver && !dk.FF().IsNodeImagePull() { if dk.OneAgent().IsApplicationMonitoringMode() && len(dk.Spec.OneAgent.ApplicationMonitoring.CodeModulesImage) > 0 { return errorImageFieldSetWithoutCSIFlag } @@ -142,7 +142,7 @@ func imageFieldSetWithoutCSIFlag(_ context.Context, v *Validator, dk *dynakube.D return "" } -func missingCodeModulesImage(_ context.Context, v *Validator, dk *dynakube.DynaKube) string { +func missingCodeModulesImage(_ context.Context, vc *validatorClient, dk *dynakube.DynaKube) string { if dk.OneAgent().IsAppInjectionNeeded() && dk.FF().IsNodeImagePull() && len(dk.OneAgent().GetCustomCodeModulesImage()) == 0 { @@ -173,7 +173,7 @@ func hasOneAgentVolumeStorageEnabled(dk *dynakube.DynaKube) (isEnabled bool, isS return } -func unsupportedOneAgentImage(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func unsupportedOneAgentImage(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if k8senv.Find(dk.OneAgent().GetEnvironment(), oneagentInstallerScriptURLEnvVarName) != nil || k8senv.Find(dk.OneAgent().GetEnvironment(), oneagentInstallerTokenEnvVarName) != nil { return warningOneAgentInstallerEnvVars @@ -182,7 +182,7 @@ func unsupportedOneAgentImage(_ context.Context, _ *Validator, dk *dynakube.Dyna return "" } -func conflictingOneAgentVolumeStorageSettings(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func conflictingOneAgentVolumeStorageSettings(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { volumeStorageEnabled, volumeStorageSet := hasOneAgentVolumeStorageEnabled(dk) if dk.OneAgent().IsReadOnlyFSSupported() && volumeStorageSet && !volumeStorageEnabled { return errorVolumeStorageReadOnlyModeConflict @@ -191,7 +191,7 @@ func conflictingOneAgentVolumeStorageSettings(_ context.Context, _ *Validator, d return "" } -func conflictingHostGroupSettings(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func conflictingHostGroupSettings(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if dk.OneAgent().GetHostGroupAsParam() != "" { return warningHostGroupConflict } @@ -199,7 +199,7 @@ func conflictingHostGroupSettings(_ context.Context, _ *Validator, dk *dynakube. return "" } -func deprecatedAutoUpdate(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func deprecatedAutoUpdate(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { oa := dk.OneAgent() if oa.IsClassicFullStackMode() && dk.RemovedFields().AutoUpdate.Get() != nil { return warningDeprecatedAutoUpdate @@ -216,7 +216,7 @@ func deprecatedAutoUpdate(_ context.Context, _ *Validator, dk *dynakube.DynaKube return "" } -func isOneAgentVersionValid(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func isOneAgentVersionValid(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { agentVersion := dk.OneAgent().GetCustomVersion() if agentVersion == "" { return "" @@ -235,7 +235,7 @@ func isOneAgentVersionValid(_ context.Context, _ *Validator, dk *dynakube.DynaKu return "" } -func duplicateOneAgentArguments(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func duplicateOneAgentArguments(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { args := dk.OneAgent().GetArgumentsMap() if args == nil { return "" @@ -254,7 +254,7 @@ func duplicateOneAgentArguments(_ context.Context, _ *Validator, dk *dynakube.Dy return "" } -func forbiddenHostIDSourceArgument(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func forbiddenHostIDSourceArgument(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { args := dk.OneAgent().GetArgumentsMap() if args == nil { return "" diff --git a/pkg/api/validation/dynakube/proxy_url.go b/pkg/api/validation/dynakube/proxy_url.go index a9b3448cee..e91354afd4 100644 --- a/pkg/api/validation/dynakube/proxy_url.go +++ b/pkg/api/validation/dynakube/proxy_url.go @@ -16,7 +16,7 @@ const ( errorMissingProxySecret = `Error occurred while reading PROXY secret indicated in the Dynakube specification` ) -func invalidActiveGateProxyURL(ctx context.Context, dv *Validator, dk *dynakube.DynaKube) string { +func invalidActiveGateProxyURL(ctx context.Context, dv *validatorClient, dk *dynakube.DynaKube) string { if dk.Spec.Proxy != nil { proxyURL, err := dk.Proxy(ctx, dv.apiReader) if err != nil { diff --git a/pkg/api/validation/dynakube/telemetryservice.go b/pkg/api/validation/dynakube/telemetryservice.go index 6ace590baa..eab722974e 100644 --- a/pkg/api/validation/dynakube/telemetryservice.go +++ b/pkg/api/validation/dynakube/telemetryservice.go @@ -27,7 +27,7 @@ const ( errorOtelCollectorMissingImage = `The Dynakube's specification specifies the OTel Collector, but no image repository/tag is configured.` ) -func emptyTelemetryIngestProtocolsList(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func emptyTelemetryIngestProtocolsList(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.TelemetryIngest().IsEnabled() { return "" } @@ -41,7 +41,7 @@ func emptyTelemetryIngestProtocolsList(_ context.Context, _ *Validator, dk *dyna return "" } -func unknownTelemetryIngestProtocols(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func unknownTelemetryIngestProtocols(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.TelemetryIngest().IsEnabled() { return "" } @@ -63,7 +63,7 @@ func unknownTelemetryIngestProtocols(_ context.Context, _ *Validator, dk *dynaku return "" } -func duplicatedTelemetryIngestProtocols(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func duplicatedTelemetryIngestProtocols(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.TelemetryIngest().IsEnabled() { return "" } @@ -95,7 +95,7 @@ func duplicatedTelemetryIngestProtocols(_ context.Context, _ *Validator, dk *dyn return "" } -func invalidTelemetryIngestName(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func invalidTelemetryIngestName(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.TelemetryIngest().IsEnabled() { return "" } @@ -117,7 +117,7 @@ func invalidTelemetryIngestNameErrorMessage() string { return fmt.Sprintf(errorTelemetryIngestNoDNS1053Label, validation.DNS1035LabelMaxLength) } -func conflictingTelemetryIngestServiceNames(ctx context.Context, dv *Validator, dk *dynakube.DynaKube) string { +func conflictingTelemetryIngestServiceNames(ctx context.Context, dv *validatorClient, dk *dynakube.DynaKube) string { if !dk.TelemetryIngest().IsEnabled() { return "" } @@ -152,7 +152,7 @@ func conflictingTelemetryIngestServiceNames(ctx context.Context, dv *Validator, return "" } -func forbiddenTelemetryIngestServiceNameSuffix(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func forbiddenTelemetryIngestServiceNameSuffix(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.TelemetryIngest().IsEnabled() { return "" } @@ -173,7 +173,7 @@ func forbiddenTelemetryIngestServiceNameSuffix(_ context.Context, _ *Validator, return "" } -func missingOtelCollectorImage(_ context.Context, _ *Validator, dk *dynakube.DynaKube) string { +func missingOtelCollectorImage(_ context.Context, _ *validatorClient, dk *dynakube.DynaKube) string { if !dk.TelemetryIngest().IsEnabled() && !dk.Extensions().IsPrometheusEnabled() { return "" } diff --git a/pkg/api/validation/dynakube/validation.go b/pkg/api/validation/dynakube/validation.go index 8aa660b14a..5d6eb95161 100644 --- a/pkg/api/validation/dynakube/validation.go +++ b/pkg/api/validation/dynakube/validation.go @@ -11,13 +11,20 @@ import ( v1beta5 "github.com/Dynatrace/dynatrace-operator/pkg/api/v1beta5/dynakube" "github.com/Dynatrace/dynatrace-operator/pkg/api/validation" "github.com/Dynatrace/dynatrace-operator/pkg/util/installconfig" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) -type Validator struct { +type DynaKubeType interface { + *v1beta3.DynaKube | *v1beta4.DynaKube | *v1beta5.DynaKube | *dynakube.DynaKube +} + +type validator[T DynaKubeType] struct { + *validatorClient +} + +type validatorClient struct { apiReader client.Reader cfg *rest.Config modules installconfig.Modules @@ -88,18 +95,24 @@ var ( } ) -type validatorFunc func(ctx context.Context, dv *Validator, dk *dynakube.DynaKube) string -type updateValidatorFunc func(ctx context.Context, dv *Validator, oldDk *dynakube.DynaKube, newDk *dynakube.DynaKube) string +type validatorFunc func(ctx context.Context, dv *validatorClient, dk *dynakube.DynaKube) string +type updateValidatorFunc func(ctx context.Context, dv *validatorClient, oldDk *dynakube.DynaKube, newDk *dynakube.DynaKube) string -func New(apiReader client.Reader, cfg *rest.Config) admission.CustomValidator { - return &Validator{ +func newGenericValidator[T DynaKubeType](vi *validatorClient) *validator[T] { + return &validator[T]{ + validatorClient: vi, + } +} + +func newClient(apiReader client.Reader, cfg *rest.Config) *validatorClient { + return &validatorClient{ apiReader: apiReader, cfg: cfg, modules: installconfig.GetModules(), } } -func (v *Validator) ValidateCreate(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { +func (v *validator[T]) ValidateCreate(ctx context.Context, obj T) (warnings admission.Warnings, err error) { dk, err := getDynakube(obj) if err != nil { return @@ -115,7 +128,7 @@ func (v *Validator) ValidateCreate(ctx context.Context, obj runtime.Object) (war return } -func (v *Validator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (warnings admission.Warnings, err error) { +func (v *validator[T]) ValidateUpdate(ctx context.Context, oldObj, newObj T) (warnings admission.Warnings, err error) { oldDk, err := getDynakube(oldObj) if err != nil { return @@ -138,15 +151,15 @@ func (v *Validator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.O return } -func (v *Validator) ValidateDelete(ctx context.Context, obj runtime.Object) (warnings admission.Warnings, err error) { +func (v *validator[T]) ValidateDelete(ctx context.Context, obj T) (warnings admission.Warnings, err error) { return nil, nil } -func (v *Validator) runValidators(ctx context.Context, validators []validatorFunc, dk *dynakube.DynaKube) []string { +func (v *validator[T]) runValidators(ctx context.Context, validators []validatorFunc, dk *dynakube.DynaKube) []string { results := []string{} for _, validate := range validators { - if errMsg := validate(ctx, v, dk); errMsg != "" { + if errMsg := validate(ctx, v.validatorClient, dk); errMsg != "" { results = append(results, errMsg) } } @@ -154,11 +167,11 @@ func (v *Validator) runValidators(ctx context.Context, validators []validatorFun return results } -func (v *Validator) runUpdateValidators(ctx context.Context, updateValidators []updateValidatorFunc, oldDk *dynakube.DynaKube, newDk *dynakube.DynaKube) []string { +func (v *validator[T]) runUpdateValidators(ctx context.Context, updateValidators []updateValidatorFunc, oldDk *dynakube.DynaKube, newDk *dynakube.DynaKube) []string { results := []string{} for _, validate := range updateValidators { - if errMsg := validate(ctx, v, oldDk, newDk); errMsg != "" { + if errMsg := validate(ctx, v.validatorClient, oldDk, newDk); errMsg != "" { results = append(results, errMsg) } } @@ -166,10 +179,10 @@ func (v *Validator) runUpdateValidators(ctx context.Context, updateValidators [] return results } -func getDynakube(obj runtime.Object) (dk *dynakube.DynaKube, err error) { +func getDynakube[T DynaKubeType](obj T) (dk *dynakube.DynaKube, err error) { dk = &dynakube.DynaKube{} - switch v := obj.(type) { + switch v := any(obj).(type) { case *dynakube.DynaKube: dk = v case *v1beta5.DynaKube: @@ -179,10 +192,6 @@ func getDynakube(obj runtime.Object) (dk *dynakube.DynaKube, err error) { case *v1beta3.DynaKube: err = v.ConvertTo(dk) default: - if gvk := obj.GetObjectKind().GroupVersionKind(); !gvk.Empty() { - return nil, fmt.Errorf("unknown object %s", gvk) - } - return nil, fmt.Errorf("unknown object %T", obj) } diff --git a/pkg/api/validation/dynakube/validation_test.go b/pkg/api/validation/dynakube/validation_test.go index 5d580d57d7..93c3dd7829 100644 --- a/pkg/api/validation/dynakube/validation_test.go +++ b/pkg/api/validation/dynakube/validation_test.go @@ -284,10 +284,12 @@ func runValidators(dk *dynakube.DynaKube, other ...client.Object) (admission.War clt = fake.NewClient(other...) } - validator := &Validator{ - apiReader: clt, - cfg: &rest.Config{}, - modules: installconfig.GetModules(), + validator := &validator[*dynakube.DynaKube]{ + validatorClient: &validatorClient{ + apiReader: clt, + cfg: &rest.Config{}, + modules: installconfig.GetModules(), + }, } return validator.ValidateCreate(context.Background(), dk) @@ -299,10 +301,12 @@ func runUpdateValidators(oldDk *dynakube.DynaKube, newDk *dynakube.DynaKube, oth clt = fake.NewClient(other...) } - validator := &Validator{ - apiReader: clt, - cfg: &rest.Config{}, - modules: installconfig.GetModules(), + validator := &validator[*dynakube.DynaKube]{ + validatorClient: &validatorClient{ + apiReader: clt, + cfg: &rest.Config{}, + modules: installconfig.GetModules(), + }, } return validator.ValidateUpdate(context.Background(), oldDk, newDk) diff --git a/pkg/api/validation/dynakube/webhook.go b/pkg/api/validation/dynakube/webhook.go index c4add2f1d3..dc9b382660 100644 --- a/pkg/api/validation/dynakube/webhook.go +++ b/pkg/api/validation/dynakube/webhook.go @@ -9,19 +9,35 @@ import ( ) func SetupWebhookWithManager(mgr ctrl.Manager) error { - validator := New(mgr.GetAPIReader(), mgr.GetConfig()) + validatorImpl := newClient(mgr.GetAPIReader(), mgr.GetConfig()) - if err := v1beta3.SetupWebhookWithManager(mgr, validator); err != nil { + v1beta3Validator := newGenericValidator[*v1beta3.DynaKube](validatorImpl) + if err := ctrl.NewWebhookManagedBy(mgr, &v1beta3.DynaKube{}). + WithValidator(v1beta3Validator). // will create an endpoint at /validate-dynatrace-com-v1beta3-dynakube + Complete(); err != nil { return err } - if err := v1beta4.SetupWebhookWithManager(mgr, validator); err != nil { + v1beta4Validator := newGenericValidator[*v1beta4.DynaKube](validatorImpl) + if err := ctrl.NewWebhookManagedBy(mgr, &v1beta4.DynaKube{}). + WithValidator(v1beta4Validator). // will create an endpoint at /validate-dynatrace-com-v1beta4-dynakube + Complete(); err != nil { return err } - if err := v1beta5.SetupWebhookWithManager(mgr, validator); err != nil { + v1beta5Validator := newGenericValidator[*v1beta5.DynaKube](validatorImpl) + if err := ctrl.NewWebhookManagedBy(mgr, &v1beta5.DynaKube{}). + WithValidator(v1beta5Validator). // will create an endpoint at /validate-dynatrace-com-v1beta4-dynakube + Complete(); err != nil { return err } - return latest.SetupWebhookWithManager(mgr, validator) + latestValidator := newGenericValidator[*latest.DynaKube](validatorImpl) + if err := ctrl.NewWebhookManagedBy(mgr, &latest.DynaKube{}). + WithValidator(latestValidator). // will create an endpoint at /validate-dynatrace-com-v1beta4-dynakube + Complete(); err != nil { + return err + } + + return nil } diff --git a/pkg/api/validation/edgeconnect/api_server.go b/pkg/api/validation/edgeconnect/api_server.go index 7232f63680..c9f1143ab6 100644 --- a/pkg/api/validation/edgeconnect/api_server.go +++ b/pkg/api/validation/edgeconnect/api_server.go @@ -14,7 +14,7 @@ const ( ` errorMissingAllowedSuffixAPIServer = `The EdgeConnect's specification has an invalid apiServer value set. - Example valid values: + Example valid values: - For prod: ".apps.dynatrace.com" - For dev: ".dev.apps.dynatracelabs.com" - For sprint: ".sprint.apps.dynatracelabs.com" @@ -35,7 +35,7 @@ var ( } ) -func isAllowedSuffixAPIServer(_ context.Context, _ *Validator, ec *edgeconnect.EdgeConnect) string { +func isAllowedSuffixAPIServer(_ context.Context, _ *validatorClient, ec *edgeconnect.EdgeConnect) string { for _, suffix := range allowedSuffix { if strings.HasSuffix(ec.Spec.APIServer, suffix) { hostnameWithDomains := strings.FieldsFunc(suffix, @@ -59,7 +59,7 @@ func isAllowedSuffixAPIServer(_ context.Context, _ *Validator, ec *edgeconnect.E return errorMissingAllowedSuffixAPIServer } -func checkAPIServerProtocolNotSet(_ context.Context, _ *Validator, ec *edgeconnect.EdgeConnect) string { +func checkAPIServerProtocolNotSet(_ context.Context, _ *validatorClient, ec *edgeconnect.EdgeConnect) string { parsedURL, err := url.Parse(ec.Spec.APIServer) if err != nil { log.Info("API Server URL is not a valid URL", "err", err.Error()) diff --git a/pkg/api/validation/edgeconnect/automation_validation.go b/pkg/api/validation/edgeconnect/automation_validation.go index 6a49097f0f..d217de7504 100644 --- a/pkg/api/validation/edgeconnect/automation_validation.go +++ b/pkg/api/validation/edgeconnect/automation_validation.go @@ -10,7 +10,7 @@ const ( errorAutomationRequiresProvisioner = `When enabling Kubernetes automation using provisioner mode is mandatory! Please enable spec.oauth.provisioner and provide a resp. OAuth client configuration.` ) -func automationRequiresProvisionerValidation(_ context.Context, _ *Validator, ec *edgeconnect.EdgeConnect) string { +func automationRequiresProvisionerValidation(_ context.Context, _ *validatorClient, ec *edgeconnect.EdgeConnect) string { if ec.Spec.KubernetesAutomation != nil && ec.Spec.KubernetesAutomation.Enabled && !ec.Spec.OAuth.Provisioner { return errorAutomationRequiresProvisioner } diff --git a/pkg/api/validation/edgeconnect/host_patterns.go b/pkg/api/validation/edgeconnect/host_patterns.go index 07685d2af6..1c011730b9 100644 --- a/pkg/api/validation/edgeconnect/host_patterns.go +++ b/pkg/api/validation/edgeconnect/host_patterns.go @@ -10,7 +10,7 @@ const ( errorHostPattersIsRequired = `hostPatterns is required when using provisioner mode` ) -func checkHostPatternsValue(_ context.Context, _ *Validator, ec *edgeconnect.EdgeConnect) string { +func checkHostPatternsValue(_ context.Context, _ *validatorClient, ec *edgeconnect.EdgeConnect) string { if ec.IsProvisionerModeEnabled() && len(ec.Spec.HostPatterns) == 0 && !ec.IsK8SAutomationEnabled() { return errorHostPattersIsRequired } diff --git a/pkg/api/validation/edgeconnect/module.go b/pkg/api/validation/edgeconnect/module.go index 045920ffcd..81b287fbac 100644 --- a/pkg/api/validation/edgeconnect/module.go +++ b/pkg/api/validation/edgeconnect/module.go @@ -11,7 +11,7 @@ var ( errorModuleDisabled = installconfig.GetModuleValidationErrorMessage("EdgeConnect") ) -func isModuleDisabled(_ context.Context, v *Validator, _ *edgeconnect.EdgeConnect) string { +func isModuleDisabled(_ context.Context, v *validatorClient, _ *edgeconnect.EdgeConnect) string { if v.modules.EdgeConnect { return "" } diff --git a/pkg/api/validation/edgeconnect/module_test.go b/pkg/api/validation/edgeconnect/module_test.go index a874a49754..693ea5028b 100644 --- a/pkg/api/validation/edgeconnect/module_test.go +++ b/pkg/api/validation/edgeconnect/module_test.go @@ -12,12 +12,12 @@ func TestIsModuleDisabled(t *testing.T) { ctx := context.Background() t.Run("module disabled => error", func(t *testing.T) { - errMsg := isModuleDisabled(ctx, &Validator{modules: installconfig.Modules{EdgeConnect: false}}, nil) + errMsg := isModuleDisabled(ctx, &validatorClient{modules: installconfig.Modules{EdgeConnect: false}}, nil) assert.Equal(t, errorModuleDisabled, errMsg) }) t.Run("module enabled => no error", func(t *testing.T) { - errMsg := isModuleDisabled(ctx, &Validator{modules: installconfig.Modules{EdgeConnect: true}}, nil) + errMsg := isModuleDisabled(ctx, &validatorClient{modules: installconfig.Modules{EdgeConnect: true}}, nil) assert.Empty(t, errMsg) }) } diff --git a/pkg/api/validation/edgeconnect/name.go b/pkg/api/validation/edgeconnect/name.go index 3c3dbdf7ba..aadf43abc3 100644 --- a/pkg/api/validation/edgeconnect/name.go +++ b/pkg/api/validation/edgeconnect/name.go @@ -12,7 +12,7 @@ const ( The limit is necessary because kubernetes uses the name of some resources for the label value, which has a limit of 63 characters. (see https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set)` ) -func nameTooLong(_ context.Context, _ *Validator, ec *edgeconnect.EdgeConnect) string { +func nameTooLong(_ context.Context, _ *validatorClient, ec *edgeconnect.EdgeConnect) string { edgeConnectName := ec.Name if edgeConnectName != "" && len(edgeConnectName) > edgeconnect.MaxNameLength { return fmt.Sprintf(errorNameTooLong, edgeconnect.MaxNameLength) diff --git a/pkg/api/validation/edgeconnect/service_account.go b/pkg/api/validation/edgeconnect/service_account.go index 2b97880c3d..1021882478 100644 --- a/pkg/api/validation/edgeconnect/service_account.go +++ b/pkg/api/validation/edgeconnect/service_account.go @@ -11,7 +11,7 @@ const ( ` ) -func isInvalidServiceName(_ context.Context, _ *Validator, edgeConnectCR *edgeconnect.EdgeConnect) string { +func isInvalidServiceName(_ context.Context, _ *validatorClient, edgeConnectCR *edgeconnect.EdgeConnect) string { if edgeConnectCR.GetServiceAccountName() == "" { return errorInvalidServiceName } diff --git a/pkg/api/validation/edgeconnect/validation.go b/pkg/api/validation/edgeconnect/validation.go index 63c41d962c..6fbf38cf75 100644 --- a/pkg/api/validation/edgeconnect/validation.go +++ b/pkg/api/validation/edgeconnect/validation.go @@ -15,13 +15,17 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) -type Validator struct { +type validator[T runtime.Object] struct { + *validatorClient +} + +type validatorClient struct { apiReader client.Reader cfg *rest.Config modules installconfig.Modules } -type validatorFunc func(ctx context.Context, dv *Validator, ec *edgeconnect.EdgeConnect) string +type validatorFunc func(ctx context.Context, dv *validatorClient, ec *edgeconnect.EdgeConnect) string var validatorErrorFuncs = []validatorFunc{ isModuleDisabled, @@ -33,15 +37,18 @@ var validatorErrorFuncs = []validatorFunc{ automationRequiresProvisionerValidation, } -func New(apiReader client.Reader, cfg *rest.Config) admission.CustomValidator { - return &Validator{ +func newValidator[T runtime.Object](vc *validatorClient) *validator[T] { + return &validator[T]{validatorClient: vc} +} + +func newClient(apiReader client.Reader, cfg *rest.Config) *validatorClient { + return &validatorClient{ apiReader: apiReader, cfg: cfg, - modules: installconfig.GetModules(), - } + modules: installconfig.GetModules()} } -func (v *Validator) ValidateCreate(ctx context.Context, obj runtime.Object) (_ admission.Warnings, err error) { +func (v *validator[T]) ValidateCreate(ctx context.Context, obj T) (_ admission.Warnings, err error) { ec, err := getEdgeConnect(obj) if err != nil { return @@ -56,7 +63,7 @@ func (v *Validator) ValidateCreate(ctx context.Context, obj runtime.Object) (_ a return } -func (v *Validator) ValidateUpdate(ctx context.Context, _, newObj runtime.Object) (warnings admission.Warnings, err error) { +func (v *validator[T]) ValidateUpdate(ctx context.Context, _, newObj T) (warnings admission.Warnings, err error) { ec, err := getEdgeConnect(newObj) if err != nil { return @@ -71,15 +78,15 @@ func (v *Validator) ValidateUpdate(ctx context.Context, _, newObj runtime.Object return } -func (v *Validator) ValidateDelete(_ context.Context, _ runtime.Object) (warnings admission.Warnings, err error) { +func (v *validator[T]) ValidateDelete(_ context.Context, _ T) (warnings admission.Warnings, err error) { return nil, nil } -func (v *Validator) runValidators(ctx context.Context, validators []validatorFunc, ec *edgeconnect.EdgeConnect) []string { +func (v *validator[T]) runValidators(ctx context.Context, validators []validatorFunc, ec *edgeconnect.EdgeConnect) []string { results := []string{} for _, validate := range validators { - if errMsg := validate(ctx, v, ec); errMsg != "" { + if errMsg := validate(ctx, v.validatorClient, ec); errMsg != "" { results = append(results, errMsg) } } diff --git a/pkg/api/validation/edgeconnect/validation_test.go b/pkg/api/validation/edgeconnect/validation_test.go index e716d73531..89049bb345 100644 --- a/pkg/api/validation/edgeconnect/validation_test.go +++ b/pkg/api/validation/edgeconnect/validation_test.go @@ -35,10 +35,12 @@ func runValidators(ec *edgeconnect.EdgeConnect, other ...client.Object) (admissi clt = fake.NewClient(other...) } - validator := &Validator{ - apiReader: clt, - cfg: &rest.Config{}, - modules: installconfig.GetModules(), + validator := &validator[*edgeconnect.EdgeConnect]{ + validatorClient: &validatorClient{ + apiReader: clt, + cfg: &rest.Config{}, + modules: installconfig.GetModules(), + }, } return validator.ValidateCreate(context.Background(), ec) diff --git a/pkg/api/validation/edgeconnect/webhook.go b/pkg/api/validation/edgeconnect/webhook.go index 07d44704b0..a93a3a01e3 100644 --- a/pkg/api/validation/edgeconnect/webhook.go +++ b/pkg/api/validation/edgeconnect/webhook.go @@ -7,11 +7,19 @@ import ( ) func SetupWebhookWithManager(mgr ctrl.Manager) error { - validator := New(mgr.GetAPIReader(), mgr.GetConfig()) + validatorClient := newClient(mgr.GetAPIReader(), mgr.GetConfig()) - if err := v1alpha1.SetupWebhookWithManager(mgr, validator); err != nil { + if err := ctrl.NewWebhookManagedBy(mgr, &v1alpha1.EdgeConnect{}). + WithValidator(newValidator[*v1alpha1.EdgeConnect](validatorClient)). // will create an endpoint at /validate-dynatrace-com-v1alpha1-edgeconnect + Complete(); err != nil { return err } - return v1alpha2.SetupWebhookWithManager(mgr, validator) + if err := ctrl.NewWebhookManagedBy(mgr, &v1alpha2.EdgeConnect{}). + WithValidator(newValidator[*v1alpha2.EdgeConnect](validatorClient)). // will create an endpoint at /validate-dynatrace-com-v1alpha2-edgeconnect + Complete(); err != nil { + return err + } + + return nil } diff --git a/pkg/controllers/dynakube/controller.go b/pkg/controllers/dynakube/controller.go index 30347b487b..30ac1a5e0f 100644 --- a/pkg/controllers/dynakube/controller.go +++ b/pkg/controllers/dynakube/controller.go @@ -42,7 +42,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/rest" - "k8s.io/client-go/tools/record" + "k8s.io/client-go/tools/events" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/manager" @@ -66,10 +66,10 @@ func Add(mgr manager.Manager, _ string) error { } func NewController(mgr manager.Manager, clusterID string) *Controller { - return NewDynaKubeController(mgr.GetClient(), mgr.GetAPIReader(), mgr.GetEventRecorderFor(controllerName), mgr.GetConfig(), clusterID) + return NewDynaKubeController(mgr.GetClient(), mgr.GetAPIReader(), mgr.GetEventRecorder(controllerName), mgr.GetConfig(), clusterID) } -func NewDynaKubeController(kubeClient client.Client, apiReader client.Reader, eventRecorder record.EventRecorder, config *rest.Config, clusterID string) *Controller { +func NewDynaKubeController(kubeClient client.Client, apiReader client.Reader, eventRecorder events.EventRecorder, config *rest.Config, clusterID string) *Controller { return &Controller{ client: kubeClient, apiReader: apiReader, @@ -122,7 +122,7 @@ type Controller struct { // that reads objects from the cache and writes to the api-server client client.Client apiReader client.Reader - eventRecorder record.EventRecorder + eventRecorder events.EventRecorder k8sEntityReconciler k8sEntityReconciler kspmReconciler dynakubeReconciler diff --git a/pkg/controllers/edgeconnect/controller.go b/pkg/controllers/edgeconnect/controller.go index b56d495711..475d045813 100644 --- a/pkg/controllers/edgeconnect/controller.go +++ b/pkg/controllers/edgeconnect/controller.go @@ -32,7 +32,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/rest" - "k8s.io/client-go/tools/record" + "k8s.io/client-go/tools/events" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -66,7 +66,7 @@ type Controller struct { // that reads objects from the cache and writes to the api-server client client.Client apiReader client.Reader - eventRecorder record.EventRecorder + eventRecorder events.EventRecorder registryClientBuilder registry.ClientBuilder config *rest.Config timeProvider *timeprovider.Provider @@ -82,7 +82,7 @@ func NewController(mgr manager.Manager) *Controller { return &Controller{ client: mgr.GetClient(), apiReader: mgr.GetAPIReader(), - eventRecorder: mgr.GetEventRecorderFor(controllerName), + eventRecorder: mgr.GetEventRecorder(controllerName), registryClientBuilder: registry.NewClient, config: mgr.GetConfig(), timeProvider: timeprovider.New(), diff --git a/pkg/util/kubernetes/objects/k8sevent/event.go b/pkg/util/kubernetes/objects/k8sevent/event.go index 24e11d9110..0d1bd8e88c 100644 --- a/pkg/util/kubernetes/objects/k8sevent/event.go +++ b/pkg/util/kubernetes/objects/k8sevent/event.go @@ -2,15 +2,22 @@ package k8sevent import ( corev1 "k8s.io/api/core/v1" - "k8s.io/client-go/tools/record" + "k8s.io/client-go/tools/events" "sigs.k8s.io/controller-runtime/pkg/client" ) const ( - crdVersionMismatchReason = "CRDVersionMismatch" - crdVersionMismatchMessage = "The CustomResourceDefinition doesn't match version with the operator. Please update the CRD to avoid potential issues." + crdVersionMismatchReason = "CRDVersionMismatch" + crdVersionMismatchNote = "The CustomResourceDefinition doesn't match version with the operator" + crdVersionMismatchAction = "Please update the CRD to avoid potential issues" ) -func SendCRDVersionMismatch(eventRecorder record.EventRecorder, object client.Object) { - eventRecorder.Event(object, corev1.EventTypeWarning, crdVersionMismatchReason, crdVersionMismatchMessage) +func SendCRDVersionMismatch(eventRecorder events.EventRecorder, object client.Object) { + eventRecorder.Eventf( + object, + nil, + corev1.EventTypeWarning, + crdVersionMismatchReason, + crdVersionMismatchAction, + crdVersionMismatchNote) } diff --git a/pkg/util/kubernetes/objects/k8sevent/event_test.go b/pkg/util/kubernetes/objects/k8sevent/event_test.go index 71946f61df..0ae4fe6fbc 100644 --- a/pkg/util/kubernetes/objects/k8sevent/event_test.go +++ b/pkg/util/kubernetes/objects/k8sevent/event_test.go @@ -9,12 +9,12 @@ import ( "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/record" + "k8s.io/client-go/tools/events" ) func TestSendCRDVersionMismatch(t *testing.T) { t.Run("sends event for DynaKube object", func(t *testing.T) { - recorder := record.NewFakeRecorder(10) + recorder := events.NewFakeRecorder(10) dk := &dynakube.DynaKube{ ObjectMeta: metav1.ObjectMeta{ Name: "test-dynakube", @@ -28,14 +28,14 @@ func TestSendCRDVersionMismatch(t *testing.T) { case event := <-recorder.Events: assert.Contains(t, event, corev1.EventTypeWarning) assert.Contains(t, event, crdVersionMismatchReason) - assert.Contains(t, event, crdVersionMismatchMessage) + assert.Contains(t, event, crdVersionMismatchNote) default: t.Fatal("Expected event to be recorded, but none was found") } }) t.Run("sends event for EdgeConnect object", func(t *testing.T) { - recorder := record.NewFakeRecorder(10) + recorder := events.NewFakeRecorder(10) ec := &edgeconnect.EdgeConnect{ ObjectMeta: metav1.ObjectMeta{ Name: "test-edgeconnect", @@ -49,14 +49,14 @@ func TestSendCRDVersionMismatch(t *testing.T) { case event := <-recorder.Events: assert.Contains(t, event, corev1.EventTypeWarning) assert.Contains(t, event, crdVersionMismatchReason) - assert.Contains(t, event, crdVersionMismatchMessage) + assert.Contains(t, event, crdVersionMismatchNote) default: t.Fatal("Expected event to be recorded, but none was found") } }) t.Run("works with any client.Object", func(t *testing.T) { - recorder := record.NewFakeRecorder(10) + recorder := events.NewFakeRecorder(10) // Use a generic Kubernetes object to ensure interface compatibility pod := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/webhook/mutation/pod/events/events.go b/pkg/webhook/mutation/pod/events/events.go index c279367207..f4778186c8 100644 --- a/pkg/webhook/mutation/pod/events/events.go +++ b/pkg/webhook/mutation/pod/events/events.go @@ -5,7 +5,7 @@ import ( dtwebhook "github.com/Dynatrace/dynatrace-operator/pkg/webhook/mutation/pod/mutator" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/record" + "k8s.io/client-go/tools/events" ) const ( @@ -18,10 +18,10 @@ const ( type EventRecorder struct { dk *dynakube.DynaKube pod *corev1.Pod - recorder record.EventRecorder + recorder events.EventRecorder } -func NewRecorder(recorder record.EventRecorder) EventRecorder { +func NewRecorder(recorder events.EventRecorder) EventRecorder { return EventRecorder{recorder: recorder} } @@ -32,6 +32,7 @@ func (er *EventRecorder) Setup(mutationRequest *dtwebhook.MutationRequest) { func (er *EventRecorder) SendPodInjectEvent() { er.recorder.Eventf(er.dk, + nil, // no related obj corev1.EventTypeNormal, injectEvent, "Injecting the necessary info into pod %s in namespace %s", er.pod.GenerateName, er.pod.Namespace) @@ -39,6 +40,7 @@ func (er *EventRecorder) SendPodInjectEvent() { func (er *EventRecorder) SendPodUpdateEvent() { er.recorder.Eventf(er.dk, + nil, // no related obj corev1.EventTypeNormal, updatePodEvent, "Updating pod %s in namespace %s with missing containers", er.pod.GenerateName, er.pod.Namespace) @@ -48,6 +50,7 @@ func (er *EventRecorder) SendMissingDynaKubeEvent(namespaceName, dynakubeName st template := "Namespace '%s' is assigned to DynaKube instance '%s' but this instance doesn't exist" er.recorder.Eventf( &dynakube.DynaKube{ObjectMeta: metav1.ObjectMeta{Name: dynakubeName, Namespace: namespaceName}}, + nil, // no related obj corev1.EventTypeWarning, missingDynakubeEvent, template, namespaceName, dynakubeName) diff --git a/pkg/webhook/mutation/pod/handler/injection/init_test.go b/pkg/webhook/mutation/pod/handler/injection/init_test.go index 1c2bcec8e2..f4a6db2a1a 100644 --- a/pkg/webhook/mutation/pod/handler/injection/init_test.go +++ b/pkg/webhook/mutation/pod/handler/injection/init_test.go @@ -20,7 +20,7 @@ import ( "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/record" + toolsEvents "k8s.io/client-go/tools/events" "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -200,7 +200,7 @@ func createTestHandler(oaMut, metaMut dtwebhook.Mutator, objects ...client.Objec handler := New( fakeClient, fakeClient, - events.NewRecorder(record.NewFakeRecorder(10)), + events.NewRecorder(toolsEvents.NewFakeRecorder(10)), testWebhookImage, false, metaMut, diff --git a/pkg/webhook/mutation/pod/register.go b/pkg/webhook/mutation/pod/register.go index bc0361f2ac..317ab56a9d 100644 --- a/pkg/webhook/mutation/pod/register.go +++ b/pkg/webhook/mutation/pod/register.go @@ -24,7 +24,7 @@ import ( ) func registerInjectEndpoint(ctx context.Context, mgr manager.Manager, webhookNamespace string, webhookPodName string, isOpenShift bool) error { - eventRecorder := events.NewRecorder(mgr.GetEventRecorderFor("dynatrace-webhook")) + eventRecorder := events.NewRecorder(mgr.GetEventRecorder("dynatrace-webhook")) kubeConfig := mgr.GetConfig() kubeClient := mgr.GetClient() apiReader := mgr.GetAPIReader() diff --git a/pkg/webhook/mutation/pod/webhook_test.go b/pkg/webhook/mutation/pod/webhook_test.go index 64382c0061..94f63d4e07 100644 --- a/pkg/webhook/mutation/pod/webhook_test.go +++ b/pkg/webhook/mutation/pod/webhook_test.go @@ -19,7 +19,7 @@ import ( "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/tools/record" + toolsEvents "k8s.io/client-go/tools/events" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" ) @@ -245,7 +245,7 @@ func createTestWebhook(t *testing.T, injectionHandler, otlpHandler handler.Handl fakeClient := fake.NewClient(objects...) wh, err := newWebhook(fakeClient, fakeClient, fakeClient, - events.NewRecorder(record.NewFakeRecorder(10)), decoder, getTestWebhookPod(t), false) + events.NewRecorder(toolsEvents.NewFakeRecorder(10)), decoder, getTestWebhookPod(t), false) require.NoError(t, err)