diff --git a/.golangci.yml b/.golangci.yml index 1d9fc3aa4b8..0aefde28436 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -55,7 +55,6 @@ linters: # Need to check - nlreturn # [too strict and mostly code is not more readable] checks for a new line before return and branch statements to increase code clarity - goerr113 # [too strict] checks the errors handling expressions - - contextcheck # Requires to pass context to all function. # To be fixed - gocognit # https://github.com/opendatahub-io/opendatahub-operator/issues/709 diff --git a/Makefile b/Makefile index 1a873d08346..a395ce8e82c 100644 --- a/Makefile +++ b/Makefile @@ -349,7 +349,7 @@ toolbox: ## Create a toolbox instance with the proper Golang and Operator SDK ve toolbox create opendatahub-toolbox --image localhost/opendatahub-toolbox:latest # Run tests. -TEST_SRC=./controllers/... ./tests/integration/... ./pkg/... +TEST_SRC ?= ./controllers/... ./tests/integration/... ./pkg/... .PHONY: envtest envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. diff --git a/components/codeflare/codeflare.go b/components/codeflare/codeflare.go index 6d2df29413a..353c7609b21 100644 --- a/components/codeflare/codeflare.go +++ b/components/codeflare/codeflare.go @@ -35,11 +35,11 @@ type CodeFlare struct { components.Component `json:""` } -func (c *CodeFlare) OverrideManifests(_ string) error { +func (c *CodeFlare) OverrideManifests(ctx context.Context, _ string) error { // If devflags are set, update default manifests path if len(c.DevFlags.Manifests) != 0 { manifestConfig := c.DevFlags.Manifests[0] - if err := deploy.DownloadManifests(ComponentName, manifestConfig); err != nil { + if err := deploy.DownloadManifests(ctx, ComponentName, manifestConfig); err != nil { return err } // If overlay is defined, update paths @@ -76,7 +76,7 @@ func (c *CodeFlare) ReconcileComponent(ctx context.Context, if enabled { if c.DevFlags != nil { // Download manifests and update paths - if err := c.OverrideManifests(string(platform)); err != nil { + if err := c.OverrideManifests(ctx, string(platform)); err != nil { return err } } @@ -84,7 +84,7 @@ func (c *CodeFlare) ReconcileComponent(ctx context.Context, // Both ODH and RHOAI should have the same operator name dependentOperator := CodeflareOperator - if found, err := cluster.OperatorExists(cli, dependentOperator); err != nil { + if found, err := cluster.OperatorExists(ctx, cli, dependentOperator); err != nil { return fmt.Errorf("operator exists throws error %w", err) } else if found { return fmt.Errorf("operator %s is found. Please uninstall the operator before enabling %s component", @@ -100,7 +100,7 @@ func (c *CodeFlare) ReconcileComponent(ctx context.Context, } // Deploy Codeflare - if err := deploy.DeployManifestsFromPath(cli, owner, //nolint:revive,nolintlint + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, //nolint:revive,nolintlint CodeflarePath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { @@ -121,7 +121,7 @@ func (c *CodeFlare) ReconcileComponent(ctx context.Context, if err := c.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, ComponentName); err != nil { return err } - if err := deploy.DeployManifestsFromPath(cli, owner, + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, filepath.Join(deploy.DefaultManifestPath, "monitoring", "prometheus", "apps"), dscispec.Monitoring.Namespace, "prometheus", true); err != nil { diff --git a/components/component.go b/components/component.go index 41d675a40c1..c796e9483d0 100644 --- a/components/component.go +++ b/components/component.go @@ -44,7 +44,7 @@ func (c *Component) GetManagementState() operatorv1.ManagementState { return c.ManagementState } -func (c *Component) Cleanup(_ client.Client, _ *dsciv1.DSCInitializationSpec) error { +func (c *Component) Cleanup(_ context.Context, _ client.Client, _ *dsciv1.DSCInitializationSpec) error { // noop return nil } @@ -81,10 +81,10 @@ type ManifestsConfig struct { type ComponentInterface interface { ReconcileComponent(ctx context.Context, cli client.Client, logger logr.Logger, owner metav1.Object, DSCISpec *dsciv1.DSCInitializationSpec, platform cluster.Platform, currentComponentStatus bool) error - Cleanup(cli client.Client, DSCISpec *dsciv1.DSCInitializationSpec) error + Cleanup(ctx context.Context, cli client.Client, DSCISpec *dsciv1.DSCInitializationSpec) error GetComponentName() string GetManagementState() operatorv1.ManagementState - OverrideManifests(platform string) error + OverrideManifests(ctx context.Context, platform string) error UpdatePrometheusConfig(cli client.Client, enable bool, component string) error ConfigComponentLogger(logger logr.Logger, component string, dscispec *dsciv1.DSCInitializationSpec) logr.Logger } diff --git a/components/dashboard/dashboard.go b/components/dashboard/dashboard.go index d6cf50cfc8f..d83d51b3787 100644 --- a/components/dashboard/dashboard.go +++ b/components/dashboard/dashboard.go @@ -51,11 +51,11 @@ type Dashboard struct { components.Component `json:""` } -func (d *Dashboard) OverrideManifests(platform string) error { +func (d *Dashboard) OverrideManifests(ctx context.Context, platform string) error { // If devflags are set, update default manifests path if len(d.DevFlags.Manifests) != 0 { manifestConfig := d.DevFlags.Manifests[0] - if err := deploy.DownloadManifests(ComponentName, manifestConfig); err != nil { + if err := deploy.DownloadManifests(ctx, ComponentName, manifestConfig); err != nil { return err } // If overlay is defined, update paths @@ -113,12 +113,12 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context, } if d.DevFlags != nil { // Download manifests and update paths - if err := d.OverrideManifests(string(platform)); err != nil { + if err := d.OverrideManifests(ctx, string(platform)); err != nil { return err } } // 1. Deploy CRDs - if err := d.deployCRDsForPlatform(cli, owner, dscispec.ApplicationsNamespace, platform); err != nil { + if err := d.deployCRDsForPlatform(ctx, cli, owner, dscispec.ApplicationsNamespace, platform); err != nil { return fmt.Errorf("failed to deploy Dashboard CRD: %w", err) } @@ -154,12 +154,12 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context, return fmt.Errorf("failed to create access-secret for anaconda: %w", err) } // overlay which including ../../base + anaconda-ce-validator - if err := deploy.DeployManifestsFromPath(cli, owner, PathSupported, dscispec.ApplicationsNamespace, ComponentNameSupported, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, PathSupported, dscispec.ApplicationsNamespace, ComponentNameSupported, enabled); err != nil { return fmt.Errorf("failed to apply manifests from %s: %w", PathSupported, err) } // Apply RHOAI specific configs, e.g anaconda screct and cronjob and ISV - if err := d.applyRHOAISpecificConfigs(cli, owner, dscispec.ApplicationsNamespace, platform); err != nil { + if err := d.applyRHOAISpecificConfigs(ctx, cli, owner, dscispec.ApplicationsNamespace, platform); err != nil { return err } // consolelink @@ -181,7 +181,7 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context, if err := d.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, ComponentNameSupported); err != nil { return err } - if err := deploy.DeployManifestsFromPath(cli, owner, + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, filepath.Join(deploy.DefaultManifestPath, "monitoring", "prometheus", "apps"), dscispec.Monitoring.Namespace, "prometheus", true); err != nil { @@ -192,11 +192,11 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context, return nil default: // base - if err := deploy.DeployManifestsFromPath(cli, owner, Path, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, Path, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { return err } // ISV - if err := deploy.DeployManifestsFromPath(cli, owner, PathISV, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, PathISV, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { return err } // consolelink @@ -208,16 +208,16 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context, } } -func (d *Dashboard) deployCRDsForPlatform(cli client.Client, owner metav1.Object, namespace string, platform cluster.Platform) error { +func (d *Dashboard) deployCRDsForPlatform(ctx context.Context, cli client.Client, owner metav1.Object, namespace string, platform cluster.Platform) error { componentName := ComponentName if platform == cluster.SelfManagedRhods || platform == cluster.ManagedRhods { componentName = ComponentNameSupported } // we only deploy CRD, we do not remove CRD - return deploy.DeployManifestsFromPath(cli, owner, PathCRDs, namespace, componentName, true) + return deploy.DeployManifestsFromPath(ctx, cli, owner, PathCRDs, namespace, componentName, true) } -func (d *Dashboard) applyRHOAISpecificConfigs(cli client.Client, owner metav1.Object, namespace string, platform cluster.Platform) error { +func (d *Dashboard) applyRHOAISpecificConfigs(ctx context.Context, cli client.Client, owner metav1.Object, namespace string, platform cluster.Platform) error { enabled := d.ManagementState == operatorv1.Managed // set proper group name @@ -230,7 +230,7 @@ func (d *Dashboard) applyRHOAISpecificConfigs(cli client.Client, owner metav1.Ob if err := common.ReplaceStringsInFile(dashboardConfig, map[string]string{"": adminGroups}); err != nil { return err } - if err := deploy.DeployManifestsFromPath(cli, owner, PathODHDashboardConfig, namespace, ComponentNameSupported, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, PathODHDashboardConfig, namespace, ComponentNameSupported, enabled); err != nil { return fmt.Errorf("failed to create OdhDashboardConfig from %s: %w", PathODHDashboardConfig, err) } // ISV @@ -238,7 +238,7 @@ func (d *Dashboard) applyRHOAISpecificConfigs(cli client.Client, owner metav1.Ob if platform == cluster.ManagedRhods { path = PathISVAddOn } - if err := deploy.DeployManifestsFromPath(cli, owner, path, namespace, ComponentNameSupported, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, path, namespace, ComponentNameSupported, enabled); err != nil { return fmt.Errorf("failed to set dashboard ISV from %s : %w", Path, err) } return nil @@ -278,7 +278,7 @@ func (d *Dashboard) deployConsoleLink(ctx context.Context, cli client.Client, ow } enabled := d.ManagementState == operatorv1.Managed - if err := deploy.DeployManifestsFromPath(cli, owner, PathConsoleLink, namespace, componentName, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, PathConsoleLink, namespace, componentName, enabled); err != nil { return fmt.Errorf("failed to set dashboard consolelink %s : %w", pathConsoleLink, err) } diff --git a/components/datasciencepipelines/datasciencepipelines.go b/components/datasciencepipelines/datasciencepipelines.go index 0344ba039af..25297decfec 100644 --- a/components/datasciencepipelines/datasciencepipelines.go +++ b/components/datasciencepipelines/datasciencepipelines.go @@ -38,11 +38,11 @@ type DataSciencePipelines struct { components.Component `json:""` } -func (d *DataSciencePipelines) OverrideManifests(_ string) error { +func (d *DataSciencePipelines) OverrideManifests(ctx context.Context, _ string) error { // If devflags are set, update default manifests path if len(d.DevFlags.Manifests) != 0 { manifestConfig := d.DevFlags.Manifests[0] - if err := deploy.DownloadManifests(ComponentName, manifestConfig); err != nil { + if err := deploy.DownloadManifests(ctx, ComponentName, manifestConfig); err != nil { return err } // If overlay is defined, update paths @@ -94,7 +94,7 @@ func (d *DataSciencePipelines) ReconcileComponent(ctx context.Context, if enabled { if d.DevFlags != nil { // Download manifests and update paths - if err := d.OverrideManifests(string(platform)); err != nil { + if err := d.OverrideManifests(ctx, string(platform)); err != nil { return err } } @@ -116,7 +116,7 @@ func (d *DataSciencePipelines) ReconcileComponent(ctx context.Context, if platform == cluster.OpenDataHub || platform == "" { manifestsPath = filepath.Join(OverlayPath, "odh") } - if err := deploy.DeployManifestsFromPath(cli, owner, manifestsPath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, manifestsPath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { return err } l.Info("apply manifests done") @@ -135,7 +135,7 @@ func (d *DataSciencePipelines) ReconcileComponent(ctx context.Context, if err := d.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, ComponentName); err != nil { return err } - if err := deploy.DeployManifestsFromPath(cli, owner, + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, filepath.Join(deploy.DefaultManifestPath, "monitoring", "prometheus", "apps"), dscispec.Monitoring.Namespace, "prometheus", true); err != nil { diff --git a/components/kserve/kserve.go b/components/kserve/kserve.go index 7ccb2d7af0c..eae806056f7 100644 --- a/components/kserve/kserve.go +++ b/components/kserve/kserve.go @@ -56,13 +56,13 @@ type Kserve struct { DefaultDeploymentMode DefaultDeploymentMode `json:"defaultDeploymentMode,omitempty"` } -func (k *Kserve) OverrideManifests(_ string) error { +func (k *Kserve) OverrideManifests(ctx context.Context, _ string) error { // Download manifests if defined by devflags // Go through each manifest and set the overlays if defined for _, subcomponent := range k.DevFlags.Manifests { if strings.Contains(subcomponent.URI, DependentComponentName) { // Download subcomponent - if err := deploy.DownloadManifests(DependentComponentName, subcomponent); err != nil { + if err := deploy.DownloadManifests(ctx, DependentComponentName, subcomponent); err != nil { return err } // If overlay is defined, update paths @@ -75,7 +75,7 @@ func (k *Kserve) OverrideManifests(_ string) error { if strings.Contains(subcomponent.URI, ComponentName) { // Download subcomponent - if err := deploy.DownloadManifests(ComponentName, subcomponent); err != nil { + if err := deploy.DownloadManifests(ctx, ComponentName, subcomponent); err != nil { return err } // If overlay is defined, update paths @@ -109,17 +109,17 @@ func (k *Kserve) ReconcileComponent(ctx context.Context, cli client.Client, monitoringEnabled := dscispec.Monitoring.ManagementState == operatorv1.Managed if !enabled { - if err := k.removeServerlessFeatures(dscispec); err != nil { + if err := k.removeServerlessFeatures(ctx, dscispec); err != nil { return err } } else { // Configure dependencies - if err := k.configureServerless(cli, dscispec); err != nil { + if err := k.configureServerless(ctx, cli, dscispec); err != nil { return err } if k.DevFlags != nil { // Download manifests and update paths - if err := k.OverrideManifests(string(platform)); err != nil { + if err := k.OverrideManifests(ctx, string(platform)); err != nil { return err } } @@ -132,11 +132,11 @@ func (k *Kserve) ReconcileComponent(ctx context.Context, cli client.Client, } } - if err := k.configureServiceMesh(cli, dscispec); err != nil { + if err := k.configureServiceMesh(ctx, cli, dscispec); err != nil { return fmt.Errorf("failed configuring service mesh while reconciling kserve component. cause: %w", err) } - if err := deploy.DeployManifestsFromPath(cli, owner, Path, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, Path, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { return fmt.Errorf("failed to apply manifests from %s : %w", Path, err) } @@ -159,7 +159,7 @@ func (k *Kserve) ReconcileComponent(ctx context.Context, cli client.Client, } } - if err := deploy.DeployManifestsFromPath(cli, owner, DependentPath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, DependentPath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { if !strings.Contains(err.Error(), "spec.selector") || !strings.Contains(err.Error(), "field is immutable") { // explicitly ignore error if error contains keywords "spec.selector" and "field is immutable" and return all other error. return err @@ -185,10 +185,10 @@ func (k *Kserve) ReconcileComponent(ctx context.Context, cli client.Client, return nil } -func (k *Kserve) Cleanup(cli client.Client, instance *dsciv1.DSCInitializationSpec) error { - if removeServerlessErr := k.removeServerlessFeatures(instance); removeServerlessErr != nil { +func (k *Kserve) Cleanup(ctx context.Context, cli client.Client, instance *dsciv1.DSCInitializationSpec) error { + if removeServerlessErr := k.removeServerlessFeatures(ctx, instance); removeServerlessErr != nil { return removeServerlessErr } - return k.removeServiceMeshConfigurations(cli, instance) + return k.removeServiceMeshConfigurations(ctx, cli, instance) } diff --git a/components/kserve/kserve_config_handler.go b/components/kserve/kserve_config_handler.go index 3bc91db1657..e5f5b538415 100644 --- a/components/kserve/kserve_config_handler.go +++ b/components/kserve/kserve_config_handler.go @@ -114,14 +114,14 @@ func (k *Kserve) setDefaultDeploymentMode(ctx context.Context, cli client.Client return nil } -func (k *Kserve) configureServerless(_ client.Client, instance *dsciv1.DSCInitializationSpec) error { +func (k *Kserve) configureServerless(ctx context.Context, _ client.Client, instance *dsciv1.DSCInitializationSpec) error { switch k.Serving.ManagementState { case operatorv1.Unmanaged: // Bring your own CR fmt.Println("Serverless CR is not configured by the operator, we won't do anything") case operatorv1.Removed: // we remove serving CR fmt.Println("existing Serverless CR (owned by operator) will be removed") - if err := k.removeServerlessFeatures(instance); err != nil { + if err := k.removeServerlessFeatures(ctx, instance); err != nil { return err } @@ -133,15 +133,15 @@ func (k *Kserve) configureServerless(_ client.Client, instance *dsciv1.DSCInitia serverlessFeatures := feature.ComponentFeaturesHandler(k.GetComponentName(), instance, k.configureServerlessFeatures()) - if err := serverlessFeatures.Apply(); err != nil { + if err := serverlessFeatures.Apply(ctx); err != nil { return err } } return nil } -func (k *Kserve) removeServerlessFeatures(instance *dsciv1.DSCInitializationSpec) error { +func (k *Kserve) removeServerlessFeatures(ctx context.Context, instance *dsciv1.DSCInitializationSpec) error { serverlessFeatures := feature.ComponentFeaturesHandler(k.GetComponentName(), instance, k.configureServerlessFeatures()) - return serverlessFeatures.Delete() + return serverlessFeatures.Delete(ctx) } diff --git a/components/kserve/serverless_setup.go b/components/kserve/serverless_setup.go index cc1ec4bfb7e..e71f7d5a95d 100644 --- a/components/kserve/serverless_setup.go +++ b/components/kserve/serverless_setup.go @@ -1,6 +1,7 @@ package kserve import ( + "context" "path" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature" @@ -70,7 +71,7 @@ func (k *Kserve) configureServerlessFeatures() feature.FeaturesProvider { } func PopulateComponentSettings(k *Kserve) feature.Action { - return func(f *feature.Feature) error { + return func(_ context.Context, f *feature.Feature) error { f.Spec.Serving = &k.Serving return nil } diff --git a/components/kserve/servicemesh_setup.go b/components/kserve/servicemesh_setup.go index 9c5388adc02..56f53aa23dc 100644 --- a/components/kserve/servicemesh_setup.go +++ b/components/kserve/servicemesh_setup.go @@ -1,6 +1,7 @@ package kserve import ( + "context" "fmt" "path" @@ -13,28 +14,28 @@ import ( "github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature/servicemesh" ) -func (k *Kserve) configureServiceMesh(c client.Client, dscispec *dsciv1.DSCInitializationSpec) error { +func (k *Kserve) configureServiceMesh(ctx context.Context, c client.Client, dscispec *dsciv1.DSCInitializationSpec) error { if dscispec.ServiceMesh != nil { if dscispec.ServiceMesh.ManagementState == operatorv1.Managed && k.GetManagementState() == operatorv1.Managed { - serviceMeshInitializer := feature.ComponentFeaturesHandler(k.GetComponentName(), dscispec, k.defineServiceMeshFeatures(c)) - return serviceMeshInitializer.Apply() + serviceMeshInitializer := feature.ComponentFeaturesHandler(k.GetComponentName(), dscispec, k.defineServiceMeshFeatures(ctx, c)) + return serviceMeshInitializer.Apply(ctx) } if dscispec.ServiceMesh.ManagementState == operatorv1.Unmanaged && k.GetManagementState() == operatorv1.Managed { return nil } } - return k.removeServiceMeshConfigurations(c, dscispec) + return k.removeServiceMeshConfigurations(ctx, c, dscispec) } -func (k *Kserve) removeServiceMeshConfigurations(cli client.Client, dscispec *dsciv1.DSCInitializationSpec) error { - serviceMeshInitializer := feature.ComponentFeaturesHandler(k.GetComponentName(), dscispec, k.defineServiceMeshFeatures(cli)) - return serviceMeshInitializer.Delete() +func (k *Kserve) removeServiceMeshConfigurations(ctx context.Context, cli client.Client, dscispec *dsciv1.DSCInitializationSpec) error { + serviceMeshInitializer := feature.ComponentFeaturesHandler(k.GetComponentName(), dscispec, k.defineServiceMeshFeatures(ctx, cli)) + return serviceMeshInitializer.Delete(ctx) } -func (k *Kserve) defineServiceMeshFeatures(cli client.Client) feature.FeaturesProvider { +func (k *Kserve) defineServiceMeshFeatures(ctx context.Context, cli client.Client) feature.FeaturesProvider { return func(handler *feature.FeaturesHandler) error { - authorinoInstalled, err := cluster.SubscriptionExists(cli, "authorino-operator") + authorinoInstalled, err := cluster.SubscriptionExists(ctx, cli, "authorino-operator") if err != nil { return fmt.Errorf("failed to list subscriptions %w", err) } diff --git a/components/kueue/kueue.go b/components/kueue/kueue.go index 32f358608ec..e6e3807d2b9 100644 --- a/components/kueue/kueue.go +++ b/components/kueue/kueue.go @@ -31,11 +31,11 @@ type Kueue struct { components.Component `json:""` } -func (k *Kueue) OverrideManifests(_ string) error { +func (k *Kueue) OverrideManifests(ctx context.Context, _ string) error { // If devflags are set, update default manifests path if len(k.DevFlags.Manifests) != 0 { manifestConfig := k.DevFlags.Manifests[0] - if err := deploy.DownloadManifests(ComponentName, manifestConfig); err != nil { + if err := deploy.DownloadManifests(ctx, ComponentName, manifestConfig); err != nil { return err } // If overlay is defined, update paths @@ -65,7 +65,7 @@ func (k *Kueue) ReconcileComponent(ctx context.Context, cli client.Client, logge if enabled { if k.DevFlags != nil { // Download manifests and update paths - if err := k.OverrideManifests(string(platform)); err != nil { + if err := k.OverrideManifests(ctx, string(platform)); err != nil { return err } } @@ -76,7 +76,7 @@ func (k *Kueue) ReconcileComponent(ctx context.Context, cli client.Client, logge } } // Deploy Kueue Operator - if err := deploy.DeployManifestsFromPath(cli, owner, Path, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, Path, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { return fmt.Errorf("failed to apply manifetss %s: %w", Path, err) } l.Info("apply manifests done") @@ -92,7 +92,7 @@ func (k *Kueue) ReconcileComponent(ctx context.Context, cli client.Client, logge if err := k.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, ComponentName); err != nil { return err } - if err := deploy.DeployManifestsFromPath(cli, owner, + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, filepath.Join(deploy.DefaultManifestPath, "monitoring", "prometheus", "apps"), dscispec.Monitoring.Namespace, "prometheus", true); err != nil { diff --git a/components/modelmeshserving/modelmeshserving.go b/components/modelmeshserving/modelmeshserving.go index 7bd68c90ab9..ce094172740 100644 --- a/components/modelmeshserving/modelmeshserving.go +++ b/components/modelmeshserving/modelmeshserving.go @@ -35,12 +35,12 @@ type ModelMeshServing struct { components.Component `json:""` } -func (m *ModelMeshServing) OverrideManifests(_ string) error { +func (m *ModelMeshServing) OverrideManifests(ctx context.Context, _ string) error { // Go through each manifest and set the overlays if defined for _, subcomponent := range m.DevFlags.Manifests { if strings.Contains(subcomponent.URI, DependentComponentName) { // Download subcomponent - if err := deploy.DownloadManifests(DependentComponentName, subcomponent); err != nil { + if err := deploy.DownloadManifests(ctx, DependentComponentName, subcomponent); err != nil { return err } // If overlay is defined, update paths @@ -53,7 +53,7 @@ func (m *ModelMeshServing) OverrideManifests(_ string) error { if strings.Contains(subcomponent.URI, ComponentName) { // Download subcomponent - if err := deploy.DownloadManifests(ComponentName, subcomponent); err != nil { + if err := deploy.DownloadManifests(ctx, ComponentName, subcomponent); err != nil { return err } // If overlay is defined, update paths @@ -100,7 +100,7 @@ func (m *ModelMeshServing) ReconcileComponent(ctx context.Context, if enabled { if m.DevFlags != nil { // Download manifests and update paths - if err := m.OverrideManifests(string(platform)); err != nil { + if err := m.OverrideManifests(ctx, string(platform)); err != nil { return err } } @@ -120,7 +120,7 @@ func (m *ModelMeshServing) ReconcileComponent(ctx context.Context, } } - if err := deploy.DeployManifestsFromPath(cli, owner, Path, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, Path, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { return fmt.Errorf("failed to apply manifests from %s : %w", Path, err) } l.WithValues("Path", Path).Info("apply manifests done for modelmesh") @@ -137,7 +137,7 @@ func (m *ModelMeshServing) ReconcileComponent(ctx context.Context, } } } - if err := deploy.DeployManifestsFromPath(cli, owner, DependentPath, dscispec.ApplicationsNamespace, m.GetComponentName(), enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, DependentPath, dscispec.ApplicationsNamespace, m.GetComponentName(), enabled); err != nil { // explicitly ignore error if error contains keywords "spec.selector" and "field is immutable" and return all other error. if !strings.Contains(err.Error(), "spec.selector") || !strings.Contains(err.Error(), "field is immutable") { return err @@ -162,7 +162,7 @@ func (m *ModelMeshServing) ReconcileComponent(ctx context.Context, if err := m.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, DependentComponentName); err != nil { return err } - if err := deploy.DeployManifestsFromPath(cli, owner, + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, filepath.Join(deploy.DefaultManifestPath, "monitoring", "prometheus", "apps"), dscispec.Monitoring.Namespace, "prometheus", true); err != nil { diff --git a/components/modelregistry/modelregistry.go b/components/modelregistry/modelregistry.go index 69a19e60632..b20a7a97582 100644 --- a/components/modelregistry/modelregistry.go +++ b/components/modelregistry/modelregistry.go @@ -36,11 +36,11 @@ type ModelRegistry struct { components.Component `json:""` } -func (m *ModelRegistry) OverrideManifests(_ string) error { +func (m *ModelRegistry) OverrideManifests(ctx context.Context, _ string) error { // If devflags are set, update default manifests path if len(m.DevFlags.Manifests) != 0 { manifestConfig := m.DevFlags.Manifests[0] - if err := deploy.DownloadManifests(ComponentName, manifestConfig); err != nil { + if err := deploy.DownloadManifests(ctx, ComponentName, manifestConfig); err != nil { return err } // If overlay is defined, update paths @@ -71,7 +71,7 @@ func (m *ModelRegistry) ReconcileComponent(ctx context.Context, cli client.Clien if enabled { if m.DevFlags != nil { // Download manifests and update paths - if err := m.OverrideManifests(string(platform)); err != nil { + if err := m.OverrideManifests(ctx, string(platform)); err != nil { return err } } @@ -91,13 +91,13 @@ func (m *ModelRegistry) ReconcileComponent(ctx context.Context, cli client.Clien } } // Deploy ModelRegistry Operator - if err := deploy.DeployManifestsFromPath(cli, owner, Path, dscispec.ApplicationsNamespace, m.GetComponentName(), enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, Path, dscispec.ApplicationsNamespace, m.GetComponentName(), enabled); err != nil { return err } l.Info("apply manifests done") // Create additional model registry resources, componentEnabled=true because these extras are never deleted! - if err := deploy.DeployManifestsFromPath(cli, owner, Path+"/extras", dscispec.ApplicationsNamespace, m.GetComponentName(), true); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, Path+"/extras", dscispec.ApplicationsNamespace, m.GetComponentName(), true); err != nil { return err } l.Info("apply extra manifests done") diff --git a/components/ray/ray.go b/components/ray/ray.go index 13d850b6a2c..8e582f7711e 100644 --- a/components/ray/ray.go +++ b/components/ray/ray.go @@ -33,11 +33,11 @@ type Ray struct { components.Component `json:""` } -func (r *Ray) OverrideManifests(_ string) error { +func (r *Ray) OverrideManifests(ctx context.Context, _ string) error { // If devflags are set, update default manifests path if len(r.DevFlags.Manifests) != 0 { manifestConfig := r.DevFlags.Manifests[0] - if err := deploy.DownloadManifests(ComponentName, manifestConfig); err != nil { + if err := deploy.DownloadManifests(ctx, ComponentName, manifestConfig); err != nil { return err } // If overlay is defined, update paths @@ -70,7 +70,7 @@ func (r *Ray) ReconcileComponent(ctx context.Context, cli client.Client, logger if enabled { if r.DevFlags != nil { // Download manifests and update paths - if err := r.OverrideManifests(string(platform)); err != nil { + if err := r.OverrideManifests(ctx, string(platform)); err != nil { return err } } @@ -81,7 +81,7 @@ func (r *Ray) ReconcileComponent(ctx context.Context, cli client.Client, logger } } // Deploy Ray Operator - if err := deploy.DeployManifestsFromPath(cli, owner, RayPath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, RayPath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { return fmt.Errorf("failed to apply manifets from %s : %w", RayPath, err) } l.Info("apply manifests done") @@ -97,7 +97,7 @@ func (r *Ray) ReconcileComponent(ctx context.Context, cli client.Client, logger if err := r.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, ComponentName); err != nil { return err } - if err := deploy.DeployManifestsFromPath(cli, owner, + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, filepath.Join(deploy.DefaultManifestPath, "monitoring", "prometheus", "apps"), dscispec.Monitoring.Namespace, "prometheus", true); err != nil { diff --git a/components/trainingoperator/trainingoperator.go b/components/trainingoperator/trainingoperator.go index d7796a24915..b7e68e243c2 100644 --- a/components/trainingoperator/trainingoperator.go +++ b/components/trainingoperator/trainingoperator.go @@ -33,11 +33,11 @@ type TrainingOperator struct { components.Component `json:""` } -func (r *TrainingOperator) OverrideManifests(_ string) error { +func (r *TrainingOperator) OverrideManifests(ctx context.Context, _ string) error { // If devflags are set, update default manifests path if len(r.DevFlags.Manifests) != 0 { manifestConfig := r.DevFlags.Manifests[0] - if err := deploy.DownloadManifests(ComponentName, manifestConfig); err != nil { + if err := deploy.DownloadManifests(ctx, ComponentName, manifestConfig); err != nil { return err } // If overlay is defined, update paths @@ -70,7 +70,7 @@ func (r *TrainingOperator) ReconcileComponent(ctx context.Context, cli client.Cl if enabled { if r.DevFlags != nil { // Download manifests and update paths - if err := r.OverrideManifests(string(platform)); err != nil { + if err := r.OverrideManifests(ctx, string(platform)); err != nil { return err } } @@ -81,7 +81,7 @@ func (r *TrainingOperator) ReconcileComponent(ctx context.Context, cli client.Cl } } // Deploy Training Operator - if err := deploy.DeployManifestsFromPath(cli, owner, TrainingOperatorPath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, TrainingOperatorPath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { return err } l.Info("apply manifests done") @@ -98,7 +98,7 @@ func (r *TrainingOperator) ReconcileComponent(ctx context.Context, cli client.Cl if err := r.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, ComponentName); err != nil { return err } - if err := deploy.DeployManifestsFromPath(cli, owner, + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, filepath.Join(deploy.DefaultManifestPath, "monitoring", "prometheus", "apps"), dscispec.Monitoring.Namespace, "prometheus", true); err != nil { diff --git a/components/trustyai/trustyai.go b/components/trustyai/trustyai.go index 3f7a4bed7c4..7bd452541cf 100644 --- a/components/trustyai/trustyai.go +++ b/components/trustyai/trustyai.go @@ -33,11 +33,11 @@ type TrustyAI struct { components.Component `json:""` } -func (t *TrustyAI) OverrideManifests(_ string) error { +func (t *TrustyAI) OverrideManifests(ctx context.Context, _ string) error { // If devflags are set, update default manifests path if len(t.DevFlags.Manifests) != 0 { manifestConfig := t.DevFlags.Manifests[0] - if err := deploy.DownloadManifests(ComponentPathName, manifestConfig); err != nil { + if err := deploy.DownloadManifests(ctx, ComponentPathName, manifestConfig); err != nil { return err } // If overlay is defined, update paths @@ -68,7 +68,7 @@ func (t *TrustyAI) ReconcileComponent(ctx context.Context, cli client.Client, lo if enabled { if t.DevFlags != nil { // Download manifests and update paths - if err := t.OverrideManifests(string(platform)); err != nil { + if err := t.OverrideManifests(ctx, string(platform)); err != nil { return err } } @@ -79,7 +79,7 @@ func (t *TrustyAI) ReconcileComponent(ctx context.Context, cli client.Client, lo } } // Deploy TrustyAI Operator - if err := deploy.DeployManifestsFromPath(cli, owner, Path, dscispec.ApplicationsNamespace, t.GetComponentName(), enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, Path, dscispec.ApplicationsNamespace, t.GetComponentName(), enabled); err != nil { return err } l.Info("apply manifests done") @@ -95,7 +95,7 @@ func (t *TrustyAI) ReconcileComponent(ctx context.Context, cli client.Client, lo if err := t.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, ComponentName); err != nil { return err } - if err := deploy.DeployManifestsFromPath(cli, owner, + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, filepath.Join(deploy.DefaultManifestPath, "monitoring", "prometheus", "apps"), dscispec.Monitoring.Namespace, "prometheus", true); err != nil { diff --git a/components/workbenches/workbenches.go b/components/workbenches/workbenches.go index 7b5bef9037c..ac950d54528 100644 --- a/components/workbenches/workbenches.go +++ b/components/workbenches/workbenches.go @@ -40,13 +40,13 @@ type Workbenches struct { components.Component `json:""` } -func (w *Workbenches) OverrideManifests(platform string) error { +func (w *Workbenches) OverrideManifests(ctx context.Context, platform string) error { // Download manifests if defined by devflags // Go through each manifest and set the overlays if defined for _, subcomponent := range w.DevFlags.Manifests { if strings.Contains(subcomponent.URI, DependentComponentName) { // Download subcomponent - if err := deploy.DownloadManifests(DependentComponentName, subcomponent); err != nil { + if err := deploy.DownloadManifests(ctx, DependentComponentName, subcomponent); err != nil { return err } // If overlay is defined, update paths @@ -65,7 +65,7 @@ func (w *Workbenches) OverrideManifests(platform string) error { if strings.Contains(subcomponent.ContextDir, "components/odh-notebook-controller") { // Download subcomponent - if err := deploy.DownloadManifests("odh-notebook-controller/odh-notebook-controller", subcomponent); err != nil { + if err := deploy.DownloadManifests(ctx, "odh-notebook-controller/odh-notebook-controller", subcomponent); err != nil { return err } // If overlay is defined, update paths @@ -78,7 +78,7 @@ func (w *Workbenches) OverrideManifests(platform string) error { if strings.Contains(subcomponent.ContextDir, "components/notebook-controller") { // Download subcomponent - if err := deploy.DownloadManifests("odh-notebook-controller/kf-notebook-controller", subcomponent); err != nil { + if err := deploy.DownloadManifests(ctx, "odh-notebook-controller/kf-notebook-controller", subcomponent); err != nil { return err } // If overlay is defined, update paths @@ -113,7 +113,7 @@ func (w *Workbenches) ReconcileComponent(ctx context.Context, cli client.Client, if enabled { if w.DevFlags != nil { // Download manifests and update paths - if err := w.OverrideManifests(string(platform)); err != nil { + if err := w.OverrideManifests(ctx, string(platform)); err != nil { return err } } @@ -131,7 +131,7 @@ func (w *Workbenches) ReconcileComponent(ctx context.Context, cli client.Client, return err } } - if err := deploy.DeployManifestsFromPath(cli, owner, notebookControllerPath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, notebookControllerPath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { return fmt.Errorf("failed to apply manifetss %s: %w", notebookControllerPath, err) } l.WithValues("Path", notebookControllerPath).Info("apply manifests done NBC") @@ -155,7 +155,7 @@ func (w *Workbenches) ReconcileComponent(ctx context.Context, cli client.Client, var manifestsPath string if platform == cluster.OpenDataHub || platform == "" { // only for ODH after transit to kubeflow repo - if err := deploy.DeployManifestsFromPath(cli, owner, + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, kfnotebookControllerPath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { @@ -165,7 +165,7 @@ func (w *Workbenches) ReconcileComponent(ctx context.Context, cli client.Client, } else { manifestsPath = notebookImagesPathSupported } - if err := deploy.DeployManifestsFromPath(cli, owner, + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, manifestsPath, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { @@ -185,7 +185,7 @@ func (w *Workbenches) ReconcileComponent(ctx context.Context, cli client.Client, if err := w.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, ComponentName); err != nil { return err } - if err := deploy.DeployManifestsFromPath(cli, owner, + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, filepath.Join(deploy.DefaultManifestPath, "monitoring", "prometheus", "apps"), dscispec.Monitoring.Namespace, "prometheus", true); err != nil { diff --git a/controllers/datasciencecluster/datasciencecluster_controller.go b/controllers/datasciencecluster/datasciencecluster_controller.go index 4a40d9ef3eb..7a0b49dd97c 100644 --- a/controllers/datasciencecluster/datasciencecluster_controller.go +++ b/controllers/datasciencecluster/datasciencecluster_controller.go @@ -84,7 +84,7 @@ func (r *DataScienceClusterReconciler) Reconcile(ctx context.Context, req ctrl.R r.Log.Info("Reconciling DataScienceCluster resources", "Request.Name", req.Name) // Get information on version - currentOperatorReleaseVersion, err := cluster.GetRelease(r.Client) + currentOperatorReleaseVersion, err := cluster.GetRelease(ctx, r.Client) if err != nil { r.Log.Error(err, "failed to get operator release version") return ctrl.Result{}, err @@ -136,7 +136,7 @@ func (r *DataScienceClusterReconciler) Reconcile(ctx context.Context, req ctrl.R } } for _, component := range allComponents { - if err := component.Cleanup(r.Client, r.DataScienceCluster.DSCISpec); err != nil { + if err := component.Cleanup(ctx, r.Client, r.DataScienceCluster.DSCISpec); err != nil { return ctrl.Result{}, err } } @@ -187,7 +187,7 @@ func (r *DataScienceClusterReconciler) Reconcile(ctx context.Context, req ctrl.R } else { r.Log.Info("Finalization DataScienceCluster start deleting instance", "name", instance.Name, "finalizer", finalizerName) for _, component := range allComponents { - if err := component.Cleanup(r.Client, r.DataScienceCluster.DSCISpec); err != nil { + if err := component.Cleanup(ctx, r.Client, r.DataScienceCluster.DSCISpec); err != nil { return ctrl.Result{}, err } } @@ -308,7 +308,7 @@ func (r *DataScienceClusterReconciler) reconcileSubComponent(ctx context.Context } // Reconcile component // Get platform - platform, err := cluster.GetPlatform(r.Client) + platform, err := cluster.GetPlatform(ctx, r.Client) if err != nil { r.Log.Error(err, "Failed to determine platform") return instance, err @@ -425,7 +425,7 @@ var modelMeshGeneralPredicates = predicate.Funcs{ } // SetupWithManager sets up the controller with the Manager. -func (r *DataScienceClusterReconciler) SetupWithManager(mgr ctrl.Manager) error { +func (r *DataScienceClusterReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(&dsc.DataScienceCluster{}). Owns(&corev1.Namespace{}). @@ -447,60 +447,65 @@ func (r *DataScienceClusterReconciler) SetupWithManager(mgr ctrl.Manager) error Owns(&admv1.MutatingWebhookConfiguration{}). Owns(&admv1.ValidatingWebhookConfiguration{}, builder.WithPredicates(modelMeshwebhookPredicates)). Owns(&corev1.ServiceAccount{}, builder.WithPredicates(saPredicates)). - Watches(&source.Kind{Type: &dsci.DSCInitialization{}}, handler.EnqueueRequestsFromMapFunc(r.watchDataScienceClusterForDSCI)). - Watches(&source.Kind{Type: &corev1.ConfigMap{}}, handler.EnqueueRequestsFromMapFunc(r.watchDataScienceClusterResources), builder.WithPredicates(configMapPredicates)). - Watches(&source.Kind{Type: &apiextensionsv1.CustomResourceDefinition{}}, handler.EnqueueRequestsFromMapFunc(r.watchDataScienceClusterResources), + Watches(&source.Kind{Type: &dsci.DSCInitialization{}}, handler.EnqueueRequestsFromMapFunc(r.watchDataScienceClusterForDSCI(ctx))). + Watches(&source.Kind{Type: &corev1.ConfigMap{}}, handler.EnqueueRequestsFromMapFunc(r.watchDataScienceClusterResources(ctx)), builder.WithPredicates(configMapPredicates)). + Watches(&source.Kind{Type: &apiextensionsv1.CustomResourceDefinition{}}, handler.EnqueueRequestsFromMapFunc(r.watchDataScienceClusterResources(ctx)), builder.WithPredicates(argoWorkflowCRDPredicates)). - Watches(&source.Kind{Type: &corev1.Secret{}}, handler.EnqueueRequestsFromMapFunc(r.watchDefaultIngressSecret), builder.WithPredicates(defaultIngressCertSecretPredicates)). + Watches(&source.Kind{Type: &corev1.Secret{}}, handler.EnqueueRequestsFromMapFunc(r.watchDefaultIngressSecret(ctx)), builder.WithPredicates(defaultIngressCertSecretPredicates)). // this predicates prevents meaningless reconciliations from being triggered WithEventFilter(predicate.Or(predicate.GenerationChangedPredicate{}, predicate.LabelChangedPredicate{})). Complete(r) } -func (r *DataScienceClusterReconciler) watchDataScienceClusterForDSCI(a client.Object) []reconcile.Request { - requestName, err := r.getRequestName() - if err != nil { +func (r *DataScienceClusterReconciler) watchDataScienceClusterForDSCI(ctx context.Context) func(client.Object) []reconcile.Request { + return func(a client.Object) []reconcile.Request { + requestName, err := r.getRequestName(ctx) + if err != nil { + return nil + } + // When DSCI CR gets created, trigger reconcile function + if a.GetObjectKind().GroupVersionKind().Kind == "DSCInitialization" || a.GetName() == "default-dsci" { + return []reconcile.Request{{ + NamespacedName: types.NamespacedName{Name: requestName}, + }} + } return nil } - // When DSCI CR gets created, trigger reconcile function - if a.GetObjectKind().GroupVersionKind().Kind == "DSCInitialization" || a.GetName() == "default-dsci" { - return []reconcile.Request{{ - NamespacedName: types.NamespacedName{Name: requestName}, - }} - } - return nil } -func (r *DataScienceClusterReconciler) watchDataScienceClusterResources(a client.Object) []reconcile.Request { - requestName, err := r.getRequestName() - if err != nil { - return nil - } - if a.GetObjectKind().GroupVersionKind().Kind == "CustomResourceDefinition" || a.GetName() == "ArgoWorkflowCRD" { - return []reconcile.Request{{ - NamespacedName: types.NamespacedName{Name: requestName}, - }} - } +func (r *DataScienceClusterReconciler) watchDataScienceClusterResources(ctx context.Context) func(client.Object) []reconcile.Request { + return func(a client.Object) []reconcile.Request { + requestName, err := r.getRequestName(ctx) + if err != nil { + return nil + } - // Trigger reconcile function when uninstall configmap is created - operatorNs, err := cluster.GetOperatorNamespace() - if err != nil { - return nil - } - if a.GetNamespace() == operatorNs { - cmLabels := a.GetLabels() - if val, ok := cmLabels[upgrade.DeleteConfigMapLabel]; ok && val == "true" { + if a.GetObjectKind().GroupVersionKind().Kind == "CustomResourceDefinition" || a.GetName() == "ArgoWorkflowCRD" { return []reconcile.Request{{ NamespacedName: types.NamespacedName{Name: requestName}, }} } + + // Trigger reconcile function when uninstall configmap is created + operatorNs, err := cluster.GetOperatorNamespace() + if err != nil { + return nil + } + if a.GetNamespace() == operatorNs { + cmLabels := a.GetLabels() + if val, ok := cmLabels[upgrade.DeleteConfigMapLabel]; ok && val == "true" { + return []reconcile.Request{{ + NamespacedName: types.NamespacedName{Name: requestName}, + }} + } + } + return nil } - return nil } -func (r *DataScienceClusterReconciler) getRequestName() (string, error) { +func (r *DataScienceClusterReconciler) getRequestName(ctx context.Context) (string, error) { instanceList := &dsc.DataScienceClusterList{} - err := r.Client.List(context.TODO(), instanceList) + err := r.Client.List(ctx, instanceList) if err != nil { return "", err } @@ -530,23 +535,25 @@ var argoWorkflowCRDPredicates = predicate.Funcs{ }, } -func (r *DataScienceClusterReconciler) watchDefaultIngressSecret(a client.Object) []reconcile.Request { - requestName, err := r.getRequestName() - if err != nil { - return nil - } - // When ingress secret gets created/deleted, trigger reconcile function - ingressCtrl, err := cluster.FindAvailableIngressController(context.TODO(), r.Client) - if err != nil { +func (r *DataScienceClusterReconciler) watchDefaultIngressSecret(ctx context.Context) func(client.Object) []reconcile.Request { + return func(a client.Object) []reconcile.Request { + requestName, err := r.getRequestName(ctx) + if err != nil { + return nil + } + // When ingress secret gets created/deleted, trigger reconcile function + ingressCtrl, err := cluster.FindAvailableIngressController(ctx, r.Client) + if err != nil { + return nil + } + defaultIngressSecretName := cluster.GetDefaultIngressCertSecretName(ingressCtrl) + if a.GetName() == defaultIngressSecretName && a.GetNamespace() == "openshift-ingress" { + return []reconcile.Request{{ + NamespacedName: types.NamespacedName{Name: requestName}, + }} + } return nil } - defaultIngressSecretName := cluster.GetDefaultIngressCertSecretName(ingressCtrl) - if a.GetName() == defaultIngressSecretName && a.GetNamespace() == "openshift-ingress" { - return []reconcile.Request{{ - NamespacedName: types.NamespacedName{Name: requestName}, - }} - } - return nil } // defaultIngressCertSecretPredicates filters delete and create events to trigger reconcile when default ingress cert secret is expired diff --git a/controllers/dscinitialization/dscinitialization_controller.go b/controllers/dscinitialization/dscinitialization_controller.go index 602dcdd26bb..b511b0306ad 100644 --- a/controllers/dscinitialization/dscinitialization_controller.go +++ b/controllers/dscinitialization/dscinitialization_controller.go @@ -79,7 +79,7 @@ type DSCInitializationReconciler struct { //nolint:golint,revive // Readability func (r *DSCInitializationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { //nolint:funlen,gocyclo,maintidx r.Log.Info("Reconciling DSCInitialization.", "DSCInitialization Request.Name", req.Name) - currentOperatorReleaseVersion, err := cluster.GetRelease(r.Client) + currentOperatorReleaseVersion, err := cluster.GetRelease(ctx, r.Client) if err != nil { r.Log.Error(err, "failed to get operator release version") return ctrl.Result{}, err @@ -111,7 +111,7 @@ func (r *DSCInitializationReconciler) Reconcile(ctx context.Context, req ctrl.Re } } else { r.Log.Info("Finalization DSCInitialization start deleting instance", "name", instance.Name, "finalizer", finalizerName) - if err := r.removeServiceMesh(instance); err != nil { + if err := r.removeServiceMesh(ctx, instance); err != nil { return reconcile.Result{}, err } if controllerutil.ContainsFinalizer(instance, finalizerName) { @@ -156,7 +156,7 @@ func (r *DSCInitializationReconciler) Reconcile(ctx context.Context, req ctrl.Re managementStateChangeTrustedCA = false // Get platform - platform, err := cluster.GetPlatform(r.Client) + platform, err := cluster.GetPlatform(ctx, r.Client) if err != nil { r.Log.Error(err, "Failed to determine platform (managed vs self-managed)") @@ -229,14 +229,14 @@ func (r *DSCInitializationReconciler) Reconcile(ctx context.Context, req ctrl.Re } if instance.Spec.Monitoring.ManagementState == operatorv1.Managed { r.Log.Info("Monitoring enabled, won't apply changes", "cluster", "Self-Managed RHODS Mode") - err = r.configureCommonMonitoring(instance) + err = r.configureCommonMonitoring(ctx, instance) if err != nil { return reconcile.Result{}, err } } case cluster.ManagedRhods: osdConfigsPath := filepath.Join(deploy.DefaultManifestPath, "osd-configs") - err = deploy.DeployManifestsFromPath(r.Client, instance, osdConfigsPath, r.ApplicationsNamespace, "osd", true) + err = deploy.DeployManifestsFromPath(ctx, r.Client, instance, osdConfigsPath, r.ApplicationsNamespace, "osd", true) if err != nil { r.Log.Error(err, "Failed to apply osd specific configs from manifests", "Manifests path", osdConfigsPath) r.Recorder.Eventf(instance, corev1.EventTypeWarning, "DSCInitializationReconcileError", "Failed to apply "+osdConfigsPath) @@ -249,7 +249,7 @@ func (r *DSCInitializationReconciler) Reconcile(ctx context.Context, req ctrl.Re if err != nil { return reconcile.Result{}, err } - err = r.configureCommonMonitoring(instance) + err = r.configureCommonMonitoring(ctx, instance) if err != nil { return reconcile.Result{}, err } @@ -265,7 +265,7 @@ func (r *DSCInitializationReconciler) Reconcile(ctx context.Context, req ctrl.Re } // Apply Service Mesh configurations - if errServiceMesh := r.configureServiceMesh(instance); errServiceMesh != nil { + if errServiceMesh := r.configureServiceMesh(ctx, instance); errServiceMesh != nil { return reconcile.Result{}, errServiceMesh } @@ -285,7 +285,7 @@ func (r *DSCInitializationReconciler) Reconcile(ctx context.Context, req ctrl.Re } // SetupWithManager sets up the controller with the Manager. -func (r *DSCInitializationReconciler) SetupWithManager(mgr ctrl.Manager) error { +func (r *DSCInitializationReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). // add predicates prevents meaningless reconciliations from being triggered // not use WithEventFilter() because it conflict with secret and configmap predicate @@ -303,7 +303,7 @@ func (r *DSCInitializationReconciler) SetupWithManager(mgr ctrl.Manager) error { Owns(&corev1.ServiceAccount{}, builder.WithPredicates(predicate.Or(predicate.GenerationChangedPredicate{}, predicate.LabelChangedPredicate{}))). Owns(&corev1.Service{}, builder.WithPredicates(predicate.Or(predicate.GenerationChangedPredicate{}, predicate.LabelChangedPredicate{}))). Owns(&routev1.Route{}, builder.WithPredicates(predicate.Or(predicate.GenerationChangedPredicate{}, predicate.LabelChangedPredicate{}))). - Watches(&source.Kind{Type: &dscv1.DataScienceCluster{}}, handler.EnqueueRequestsFromMapFunc(r.watchDSCResource), builder.WithPredicates(DSCDeletionPredicate)). + Watches(&source.Kind{Type: &dscv1.DataScienceCluster{}}, handler.EnqueueRequestsFromMapFunc(r.watchDSCResource(ctx)), builder.WithPredicates(DSCDeletionPredicate)). Watches(&source.Kind{Type: &corev1.Secret{}}, handler.EnqueueRequestsFromMapFunc(r.watchMonitoringSecretResource), builder.WithPredicates(SecretContentChangedPredicate)). Watches(&source.Kind{Type: &corev1.ConfigMap{}}, handler.EnqueueRequestsFromMapFunc(r.watchMonitoringConfigMapResource), builder.WithPredicates(CMContentChangedPredicate)). Complete(r) @@ -369,16 +369,18 @@ func (r *DSCInitializationReconciler) watchMonitoringSecretResource(a client.Obj return nil } -func (r *DSCInitializationReconciler) watchDSCResource(_ client.Object) []reconcile.Request { - instanceList := &dscv1.DataScienceClusterList{} - if err := r.Client.List(context.TODO(), instanceList); err != nil { - // do not handle if cannot get list - return nil - } - if len(instanceList.Items) == 0 && !upgrade.HasDeleteConfigMap(context.TODO(), r.Client) { - r.Log.Info("Found no DSC instance in cluster but not in uninstalltion process, reset monitoring stack config") +func (r *DSCInitializationReconciler) watchDSCResource(ctx context.Context) func(client.Object) []reconcile.Request { + return func(_ client.Object) []reconcile.Request { + instanceList := &dscv1.DataScienceClusterList{} + if err := r.Client.List(ctx, instanceList); err != nil { + // do not handle if cannot get list + return nil + } + if len(instanceList.Items) == 0 && !upgrade.HasDeleteConfigMap(ctx, r.Client) { + r.Log.Info("Found no DSC instance in cluster but not in uninstalltion process, reset monitoring stack config") - return []reconcile.Request{{NamespacedName: types.NamespacedName{Name: "backup"}}} + return []reconcile.Request{{NamespacedName: types.NamespacedName{Name: "backup"}}} + } + return nil } - return nil } diff --git a/controllers/dscinitialization/dscinitialization_test.go b/controllers/dscinitialization/dscinitialization_test.go index 18cff610e46..be84691b31a 100644 --- a/controllers/dscinitialization/dscinitialization_test.go +++ b/controllers/dscinitialization/dscinitialization_test.go @@ -30,12 +30,13 @@ var _ = Describe("DataScienceCluster initialization", func() { Context("Creation of related resources", func() { // must be default as instance name, or it will break - BeforeEach(func() { + BeforeEach(func(ctx context.Context) { // when desiredDsci := createDSCI(operatorv1.Managed, operatorv1.Managed, monitoringNamespace) - Expect(k8sClient.Create(context.Background(), desiredDsci)).Should(Succeed()) + Expect(k8sClient.Create(ctx, desiredDsci)).Should(Succeed()) foundDsci := &dsci.DSCInitialization{} Eventually(dscInitializationIsReady(applicationName, workingNamespace, foundDsci)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) @@ -43,10 +44,11 @@ var _ = Describe("DataScienceCluster initialization", func() { AfterEach(cleanupResources) - It("Should create default application namespace", func() { + It("Should create default application namespace", func(ctx context.Context) { // then foundApplicationNamespace := &corev1.Namespace{} Eventually(namespaceExists(applicationNamespace, foundApplicationNamespace)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) @@ -54,10 +56,11 @@ var _ = Describe("DataScienceCluster initialization", func() { }) // Currently commented out in the DSCI reconcile - setting test to Pending - It("Should create default network policy", func() { + It("Should create default network policy", func(ctx context.Context) { // then foundNetworkPolicy := &netv1.NetworkPolicy{} Eventually(objectExists(applicationNamespace, applicationNamespace, foundNetworkPolicy)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) @@ -66,10 +69,11 @@ var _ = Describe("DataScienceCluster initialization", func() { Expect(foundNetworkPolicy.Spec.PolicyTypes[0]).To(Equal(netv1.PolicyTypeIngress)) }) - It("Should create default rolebinding", func() { + It("Should create default rolebinding", func(ctx context.Context) { // then foundRoleBinding := &authv1.RoleBinding{} Eventually(objectExists(applicationNamespace, applicationNamespace, foundRoleBinding)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) @@ -91,10 +95,11 @@ var _ = Describe("DataScienceCluster initialization", func() { Expect(foundRoleBinding.RoleRef).To(Equal(expectedRoleRef)) }) - It("Should create default configmap", func() { + It("Should create default configmap", func(ctx context.Context) { // then foundConfigMap := &corev1.ConfigMap{} Eventually(objectExists(configmapName, applicationNamespace, foundConfigMap)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) @@ -110,34 +115,37 @@ var _ = Describe("DataScienceCluster initialization", func() { AfterEach(cleanupResources) const monitoringNamespace2 = "test-monitoring-ns2" const applicationName = "default-dsci" - It("Should not create monitoring namespace if monitoring is disabled", func() { + It("Should not create monitoring namespace if monitoring is disabled", func(ctx context.Context) { // when desiredDsci := createDSCI(operatorv1.Removed, operatorv1.Managed, monitoringNamespace2) - Expect(k8sClient.Create(context.Background(), desiredDsci)).Should(Succeed()) + Expect(k8sClient.Create(ctx, desiredDsci)).Should(Succeed()) foundDsci := &dsci.DSCInitialization{} Eventually(dscInitializationIsReady(applicationName, workingNamespace, foundDsci)). - WithTimeout(timeout). + WithContext(ctx). WithPolling(interval). Should(BeTrue()) // then foundMonitoringNamespace := &corev1.Namespace{} Eventually(namespaceExists(monitoringNamespace2, foundMonitoringNamespace)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeFalse()) }) - It("Should create default monitoring namespace if monitoring enabled", func() { + It("Should create default monitoring namespace if monitoring enabled", func(ctx context.Context) { // when desiredDsci := createDSCI(operatorv1.Managed, operatorv1.Managed, monitoringNamespace2) - Expect(k8sClient.Create(context.Background(), desiredDsci)).Should(Succeed()) + Expect(k8sClient.Create(ctx, desiredDsci)).Should(Succeed()) foundDsci := &dsci.DSCInitialization{} Eventually(dscInitializationIsReady(applicationName, workingNamespace, foundDsci)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) // then foundMonitoringNamespace := &corev1.Namespace{} Eventually(namespaceExists(monitoringNamespace2, foundMonitoringNamespace)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) @@ -149,7 +157,7 @@ var _ = Describe("DataScienceCluster initialization", func() { AfterEach(cleanupResources) const applicationName = "default-dsci" - It("Should not update rolebinding if it exists", func() { + It("Should not update rolebinding if it exists", func(ctx context.Context) { // given desiredRoleBinding := &authv1.RoleBinding{ @@ -168,18 +176,20 @@ var _ = Describe("DataScienceCluster initialization", func() { Name: "system:openshift:scc:anyuid", }, } - Expect(k8sClient.Create(context.Background(), desiredRoleBinding)).Should(Succeed()) + Expect(k8sClient.Create(ctx, desiredRoleBinding)).Should(Succeed()) createdRoleBinding := &authv1.RoleBinding{} Eventually(objectExists(applicationNamespace, applicationNamespace, createdRoleBinding)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) // when desiredDsci := createDSCI(operatorv1.Managed, operatorv1.Managed, monitoringNamespace) - Expect(k8sClient.Create(context.Background(), desiredDsci)).Should(Succeed()) + Expect(k8sClient.Create(ctx, desiredDsci)).Should(Succeed()) foundDsci := &dsci.DSCInitialization{} Eventually(dscInitializationIsReady(applicationName, workingNamespace, foundDsci)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) @@ -187,6 +197,7 @@ var _ = Describe("DataScienceCluster initialization", func() { // then foundRoleBinding := &authv1.RoleBinding{} Eventually(objectExists(applicationNamespace, applicationNamespace, foundRoleBinding)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) @@ -194,7 +205,7 @@ var _ = Describe("DataScienceCluster initialization", func() { Expect(foundRoleBinding.Subjects).To(BeNil()) }) - It("Should not update configmap if it exists", func() { + It("Should not update configmap if it exists", func(ctx context.Context) { // given desiredConfigMap := &corev1.ConfigMap{ @@ -208,18 +219,20 @@ var _ = Describe("DataScienceCluster initialization", func() { }, Data: map[string]string{"namespace": "existing-data"}, } - Expect(k8sClient.Create(context.Background(), desiredConfigMap)).Should(Succeed()) + Expect(k8sClient.Create(ctx, desiredConfigMap)).Should(Succeed()) createdConfigMap := &corev1.ConfigMap{} Eventually(objectExists(configmapName, applicationNamespace, createdConfigMap)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) // when desiredDsci := createDSCI(operatorv1.Managed, operatorv1.Managed, monitoringNamespace) - Expect(k8sClient.Create(context.Background(), desiredDsci)).Should(Succeed()) + Expect(k8sClient.Create(ctx, desiredDsci)).Should(Succeed()) foundDsci := &dsci.DSCInitialization{} Eventually(dscInitializationIsReady(applicationName, workingNamespace, foundDsci)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) @@ -227,6 +240,7 @@ var _ = Describe("DataScienceCluster initialization", func() { // then foundConfigMap := &corev1.ConfigMap{} Eventually(objectExists(configmapName, applicationNamespace, foundConfigMap)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) @@ -235,7 +249,7 @@ var _ = Describe("DataScienceCluster initialization", func() { Expect(foundConfigMap.Data).ToNot(Equal(map[string]string{"namespace": applicationNamespace})) }) - It("Should not update namespace if it exists", func() { + It("Should not update namespace if it exists", func(ctx context.Context) { anotherNamespace := "test-another-ns" // given @@ -244,18 +258,20 @@ var _ = Describe("DataScienceCluster initialization", func() { Name: anotherNamespace, }, } - Expect(k8sClient.Create(context.Background(), desiredNamespace)).Should(Succeed()) + Expect(k8sClient.Create(ctx, desiredNamespace)).Should(Succeed()) createdNamespace := &corev1.Namespace{} Eventually(namespaceExists(anotherNamespace, createdNamespace)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) // when desiredDsci := createDSCI(operatorv1.Managed, operatorv1.Managed, monitoringNamespace) - Expect(k8sClient.Create(context.Background(), desiredDsci)).Should(Succeed()) + Expect(k8sClient.Create(ctx, desiredDsci)).Should(Succeed()) foundDsci := &dsci.DSCInitialization{} Eventually(dscInitializationIsReady(applicationName, workingNamespace, foundDsci)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) @@ -263,6 +279,7 @@ var _ = Describe("DataScienceCluster initialization", func() { // then foundApplicationNamespace := &corev1.Namespace{} Eventually(namespaceExists(anotherNamespace, foundApplicationNamespace)). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) @@ -272,36 +289,40 @@ var _ = Describe("DataScienceCluster initialization", func() { }) }) -func cleanupResources() { +func cleanupResources(ctx context.Context) { defaultNamespace := client.InNamespace(workingNamespace) appNamespace := client.InNamespace(applicationNamespace) - Expect(k8sClient.DeleteAllOf(context.TODO(), &dsci.DSCInitialization{}, defaultNamespace)).To(Succeed()) + Expect(k8sClient.DeleteAllOf(ctx, &dsci.DSCInitialization{}, defaultNamespace)).To(Succeed()) - Expect(k8sClient.DeleteAllOf(context.TODO(), &netv1.NetworkPolicy{}, appNamespace)).To(Succeed()) - Expect(k8sClient.DeleteAllOf(context.TODO(), &corev1.ConfigMap{}, appNamespace)).To(Succeed()) - Expect(k8sClient.DeleteAllOf(context.TODO(), &authv1.RoleBinding{}, appNamespace)).To(Succeed()) - Expect(k8sClient.DeleteAllOf(context.TODO(), &authv1.ClusterRoleBinding{}, appNamespace)).To(Succeed()) + Expect(k8sClient.DeleteAllOf(ctx, &netv1.NetworkPolicy{}, appNamespace)).To(Succeed()) + Expect(k8sClient.DeleteAllOf(ctx, &corev1.ConfigMap{}, appNamespace)).To(Succeed()) + Expect(k8sClient.DeleteAllOf(ctx, &authv1.RoleBinding{}, appNamespace)).To(Succeed()) + Expect(k8sClient.DeleteAllOf(ctx, &authv1.ClusterRoleBinding{}, appNamespace)).To(Succeed()) Eventually(noInstanceExistsIn(workingNamespace, &dsci.DSCInitializationList{})). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) Eventually(noInstanceExistsIn(applicationNamespace, &authv1.ClusterRoleBindingList{})). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) Eventually(noInstanceExistsIn(applicationNamespace, &authv1.RoleBindingList{})). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) Eventually(noInstanceExistsIn(applicationNamespace, &corev1.ConfigMapList{})). + WithContext(ctx). WithTimeout(timeout). WithPolling(interval). Should(BeTrue()) } -func noInstanceExistsIn(namespace string, list client.ObjectList) func() bool { - return func() bool { +func noInstanceExistsIn(namespace string, list client.ObjectList) func(ctx context.Context) bool { + return func(ctx context.Context) bool { if err := k8sClient.List(ctx, list, &client.ListOptions{Namespace: namespace}); err != nil { return false } @@ -310,17 +331,17 @@ func noInstanceExistsIn(namespace string, list client.ObjectList) func() bool { } } -func namespaceExists(ns string, obj client.Object) func() bool { - return func() bool { - err := k8sClient.Get(context.Background(), client.ObjectKey{Name: ns}, obj) +func namespaceExists(ns string, obj client.Object) func(ctx context.Context) bool { + return func(ctx context.Context) bool { + err := k8sClient.Get(ctx, client.ObjectKey{Name: ns}, obj) return err == nil } } -func objectExists(ns string, name string, obj client.Object) func() bool { //nolint:unparam - return func() bool { - err := k8sClient.Get(context.Background(), client.ObjectKey{Name: ns, Namespace: name}, obj) +func objectExists(ns string, name string, obj client.Object) func(ctx context.Context) bool { //nolint:unparam + return func(ctx context.Context) bool { + err := k8sClient.Get(ctx, client.ObjectKey{Name: ns, Namespace: name}, obj) return err == nil } @@ -349,9 +370,9 @@ func createDSCI(enableMonitoring operatorv1.ManagementState, enableTrustedCABund } } -func dscInitializationIsReady(ns string, name string, dsciObj *dsci.DSCInitialization) func() bool { //nolint:unparam - return func() bool { - _ = k8sClient.Get(context.Background(), client.ObjectKey{Name: ns, Namespace: name}, dsciObj) +func dscInitializationIsReady(ns string, name string, dsciObj *dsci.DSCInitialization) func(ctx context.Context) bool { //nolint:unparam + return func(ctx context.Context) bool { + _ = k8sClient.Get(ctx, client.ObjectKey{Name: ns, Namespace: name}, dsciObj) return dsciObj.Status.Phase == readyPhase } diff --git a/controllers/dscinitialization/monitoring.go b/controllers/dscinitialization/monitoring.go index e6097c75d04..5ba81231a33 100644 --- a/controllers/dscinitialization/monitoring.go +++ b/controllers/dscinitialization/monitoring.go @@ -130,7 +130,7 @@ func configureAlertManager(ctx context.Context, dsciInit *dsci.DSCInitialization // r.Log.Info("Success: inject alertmanage-configs.yaml") // special handling for dev-mod - consolelinkDomain, err := cluster.GetDomain(r.Client) + consolelinkDomain, err := cluster.GetDomain(ctx, r.Client) if err != nil { return fmt.Errorf("error getting console route URL : %w", err) } @@ -181,7 +181,7 @@ func configureAlertManager(ctx context.Context, dsciInit *dsci.DSCInitialization return err } // r.Log.Info("Success: update alertmanage-configs.yaml with email") - err = deploy.DeployManifestsFromPath(r.Client, dsciInit, alertManagerPath, dsciInit.Spec.Monitoring.Namespace, "alertmanager", true) + err = deploy.DeployManifestsFromPath(ctx, r.Client, dsciInit, alertManagerPath, dsciInit.Spec.Monitoring.Namespace, "alertmanager", true) if err != nil { r.Log.Error(err, "error to deploy manifests", "path", alertManagerPath) return err @@ -208,7 +208,7 @@ func configurePrometheus(ctx context.Context, dsciInit *dsci.DSCInitialization, return err } // Update prometheus-config for dashboard, dsp and workbench - consolelinkDomain, err := cluster.GetDomain(r.Client) + consolelinkDomain, err := cluster.GetDomain(ctx, r.Client) if err != nil { return fmt.Errorf("error getting console route URL : %w", err) } @@ -225,6 +225,7 @@ func configurePrometheus(ctx context.Context, dsciInit *dsci.DSCInitialization, // Deploy prometheus manifests from prometheus/apps if err = deploy.DeployManifestsFromPath( + ctx, r.Client, dsciInit, prometheusConfigPath, @@ -328,7 +329,7 @@ func configurePrometheus(ctx context.Context, dsciInit *dsci.DSCInitialization, } } - err = deploy.DeployManifestsFromPath(r.Client, dsciInit, prometheusManifestsPath, + err = deploy.DeployManifestsFromPath(ctx, r.Client, dsciInit, prometheusManifestsPath, dsciInit.Spec.Monitoring.Namespace, "prometheus", true) if err != nil { r.Log.Error(err, "error to deploy manifests for prometheus", "path", prometheusManifestsPath) @@ -373,7 +374,7 @@ func configureBlackboxExporter(ctx context.Context, dsciInit *dsci.DSCInitializa blackBoxPath := filepath.Join(deploy.DefaultManifestPath, "monitoring", "blackbox-exporter") if apierrs.IsNotFound(err) || strings.Contains(consoleRoute.Spec.Host, "redhat.com") { - if err := deploy.DeployManifestsFromPath(r.Client, + if err := deploy.DeployManifestsFromPath(ctx, r.Client, dsciInit, filepath.Join(blackBoxPath, "internal"), dsciInit.Spec.Monitoring.Namespace, @@ -383,7 +384,7 @@ func configureBlackboxExporter(ctx context.Context, dsciInit *dsci.DSCInitializa return err } } else { - if err := deploy.DeployManifestsFromPath(r.Client, + if err := deploy.DeployManifestsFromPath(ctx, r.Client, dsciInit, filepath.Join(blackBoxPath, "external"), dsciInit.Spec.Monitoring.Namespace, @@ -432,10 +433,11 @@ func createMonitoringProxySecret(ctx context.Context, cli client.Client, name st return nil } -func (r *DSCInitializationReconciler) configureCommonMonitoring(dsciInit *dsci.DSCInitialization) error { +func (r *DSCInitializationReconciler) configureCommonMonitoring(ctx context.Context, dsciInit *dsci.DSCInitialization) error { // configure segment.io segmentPath := filepath.Join(deploy.DefaultManifestPath, "monitoring", "segment") if err := deploy.DeployManifestsFromPath( + ctx, r.Client, dsciInit, segmentPath, @@ -458,6 +460,7 @@ func (r *DSCInitializationReconciler) configureCommonMonitoring(dsciInit *dsci.D } // do not set monitoring namespace here, it is hardcoded by manifests if err := deploy.DeployManifestsFromPath( + ctx, r.Client, dsciInit, monitoringBasePath, diff --git a/controllers/dscinitialization/servicemesh_setup.go b/controllers/dscinitialization/servicemesh_setup.go index fbf3981a004..49b24478be4 100644 --- a/controllers/dscinitialization/servicemesh_setup.go +++ b/controllers/dscinitialization/servicemesh_setup.go @@ -1,6 +1,7 @@ package dscinitialization import ( + "context" "fmt" "path" @@ -15,7 +16,7 @@ import ( "github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature/servicemesh" ) -func (r *DSCInitializationReconciler) configureServiceMesh(instance *dsciv1.DSCInitialization) error { +func (r *DSCInitializationReconciler) configureServiceMesh(ctx context.Context, instance *dsciv1.DSCInitialization) error { serviceMeshManagementState := operatorv1.Removed if instance.Spec.ServiceMesh != nil { serviceMeshManagementState = instance.Spec.ServiceMesh.ManagementState @@ -30,14 +31,14 @@ func (r *DSCInitializationReconciler) configureServiceMesh(instance *dsciv1.DSCI r.serviceMeshCapability(instance, serviceMeshCondition(status.ConfiguredReason, "Service Mesh configured")), } - authzCapability, err := r.authorizationCapability(instance, authorizationCondition(status.ConfiguredReason, "Service Mesh Authorization configured")) + authzCapability, err := r.authorizationCapability(ctx, instance, authorizationCondition(status.ConfiguredReason, "Service Mesh Authorization configured")) if err != nil { return err } capabilities = append(capabilities, authzCapability) for _, capability := range capabilities { - capabilityErr := capability.Apply() + capabilityErr := capability.Apply(ctx) if capabilityErr != nil { r.Log.Error(capabilityErr, "failed applying service mesh resources") r.Recorder.Eventf(instance, corev1.EventTypeWarning, "DSCInitializationReconcileError", "failed applying service mesh resources") @@ -49,14 +50,15 @@ func (r *DSCInitializationReconciler) configureServiceMesh(instance *dsciv1.DSCI r.Log.Info("ServiceMesh CR is not configured by the operator, we won't do anything") case operatorv1.Removed: r.Log.Info("existing ServiceMesh CR (owned by operator) will be removed") - if err := r.removeServiceMesh(instance); err != nil { + if err := r.removeServiceMesh(ctx, instance); err != nil { return err } } + return nil } -func (r *DSCInitializationReconciler) removeServiceMesh(instance *dsciv1.DSCInitialization) error { +func (r *DSCInitializationReconciler) removeServiceMesh(ctx context.Context, instance *dsciv1.DSCInitialization) error { // on condition of Managed, do not handle Removed when set to Removed it trigger DSCI reconcile to clean up if instance.Spec.ServiceMesh == nil { return nil @@ -66,7 +68,7 @@ func (r *DSCInitializationReconciler) removeServiceMesh(instance *dsciv1.DSCInit r.serviceMeshCapability(instance, serviceMeshCondition(status.RemovedReason, "Service Mesh removed")), } - authzCapability, err := r.authorizationCapability(instance, authorizationCondition(status.RemovedReason, "Service Mesh Authorization removed")) + authzCapability, err := r.authorizationCapability(ctx, instance, authorizationCondition(status.RemovedReason, "Service Mesh Authorization removed")) if err != nil { return err } @@ -74,7 +76,7 @@ func (r *DSCInitializationReconciler) removeServiceMesh(instance *dsciv1.DSCInit capabilities = append(capabilities, authzCapability) for _, capability := range capabilities { - capabilityErr := capability.Delete() + capabilityErr := capability.Delete(ctx) if capabilityErr != nil { r.Log.Error(capabilityErr, "failed deleting service mesh resources") r.Recorder.Eventf(instance, corev1.EventTypeWarning, "DSCInitializationReconcileError", "failed deleting service mesh resources") @@ -93,8 +95,8 @@ func (r *DSCInitializationReconciler) serviceMeshCapability(instance *dsciv1.DSC ) } -func (r *DSCInitializationReconciler) authorizationCapability(instance *dsciv1.DSCInitialization, condition *conditionsv1.Condition) (*feature.HandlerWithReporter[*dsciv1.DSCInitialization], error) { //nolint:lll // Reason: generics are long - authorinoInstalled, err := cluster.SubscriptionExists(r.Client, "authorino-operator") +func (r *DSCInitializationReconciler) authorizationCapability(ctx context.Context, instance *dsciv1.DSCInitialization, condition *conditionsv1.Condition) (*feature.HandlerWithReporter[*dsciv1.DSCInitialization], error) { //nolint:lll // Reason: generics are long + authorinoInstalled, err := cluster.SubscriptionExists(ctx, r.Client, "authorino-operator") if err != nil { return nil, fmt.Errorf("failed to list subscriptions %w", err) } @@ -191,16 +193,16 @@ func (r *DSCInitializationReconciler) authorizationFeatures(instance *dsciv1.DSC ). PostConditions( feature.WaitForPodsToBeReady(serviceMeshSpec.ControlPlane.Namespace), - func(f *feature.Feature) error { - return feature.WaitForPodsToBeReady(handler.DSCInitializationSpec.ServiceMesh.Auth.Namespace)(f) + func(ctx context.Context, f *feature.Feature) error { + return feature.WaitForPodsToBeReady(handler.DSCInitializationSpec.ServiceMesh.Auth.Namespace)(ctx, f) }, - func(f *feature.Feature) error { + func(ctx context.Context, f *feature.Feature) error { // We do not have the control over deployment resource creation. // It is created by Authorino operator using Authorino CR // // To make it part of Service Mesh we have to patch it with injection // enabled instead, otherwise it will not have proxy pod injected. - return f.ApplyManifest(path.Join(Templates.AuthorinoDir, "deployment.injection.patch.tmpl.yaml")) + return f.ApplyManifest(ctx, path.Join(Templates.AuthorinoDir, "deployment.injection.patch.tmpl.yaml")) }, ). OnDelete( diff --git a/controllers/dscinitialization/suite_test.go b/controllers/dscinitialization/suite_test.go index 2518753301f..7314c677742 100644 --- a/controllers/dscinitialization/suite_test.go +++ b/controllers/dscinitialization/suite_test.go @@ -59,8 +59,8 @@ var ( cfg *rest.Config k8sClient client.Client testEnv *envtest.Environment - ctx context.Context - cancel context.CancelFunc + gCtx context.Context + gCancel context.CancelFunc ) const ( @@ -77,8 +77,11 @@ func TestDataScienceClusterInitialization(t *testing.T) { var testScheme = runtime.NewScheme() var _ = BeforeSuite(func() { - ctx, cancel = context.WithCancel(context.TODO()) + // can't use suite's context as the manager should survive the function + gCtx, gCancel = context.WithCancel(context.Background()) + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + By("bootstrapping test environment") rootPath, pathErr := envtestutil.FindProjectRoot() Expect(pathErr).ToNot(HaveOccurred(), pathErr) @@ -114,7 +117,7 @@ var _ = BeforeSuite(func() { utilruntime.Must(userv1.Install(testScheme)) utilruntime.Must(kfdefv1.AddToScheme(testScheme)) utilruntime.Must(monitoringv1.AddToScheme(testScheme)) - //+kubebuilder:scaffold:scheme + // +kubebuilder:scaffold:scheme k8sClient, err = client.New(cfg, client.Options{Scheme: testScheme}) Expect(err).NotTo(HaveOccurred()) @@ -133,19 +136,19 @@ var _ = BeforeSuite(func() { Scheme: testScheme, Log: ctrl.Log.WithName("controllers").WithName("DSCInitialization"), Recorder: mgr.GetEventRecorderFor("dscinitialization-controller"), - }).SetupWithManager(mgr) + }).SetupWithManager(gCtx, mgr) Expect(err).ToNot(HaveOccurred()) go func() { defer GinkgoRecover() - err = mgr.Start(ctx) + err = mgr.Start(gCtx) Expect(err).ToNot(HaveOccurred(), "Failed to run manager") }() }) var _ = AfterSuite(func() { - cancel() + gCancel() By("tearing down the test environment") err := testEnv.Stop() Expect(err).NotTo(HaveOccurred()) diff --git a/controllers/dscinitialization/utils.go b/controllers/dscinitialization/utils.go index f585d11d3ec..bf54f7f20a4 100644 --- a/controllers/dscinitialization/utils.go +++ b/controllers/dscinitialization/utils.go @@ -191,25 +191,25 @@ func (r *DSCInitializationReconciler) createDefaultRoleBinding(ctx context.Conte } func (r *DSCInitializationReconciler) reconcileDefaultNetworkPolicy(ctx context.Context, name string, dscInit *dsci.DSCInitialization) error { - platform, err := cluster.GetPlatform(r.Client) + platform, err := cluster.GetPlatform(ctx, r.Client) if err != nil { return err } if platform == cluster.ManagedRhods || platform == cluster.SelfManagedRhods { // Deploy networkpolicy for operator namespace - err = deploy.DeployManifestsFromPath(r.Client, dscInit, networkpolicyPath+"/operator", "redhat-ods-operator", "networkpolicy", true) + err = deploy.DeployManifestsFromPath(ctx, r.Client, dscInit, networkpolicyPath+"/operator", "redhat-ods-operator", "networkpolicy", true) if err != nil { r.Log.Error(err, "error to set networkpolicy in operator namespace", "path", networkpolicyPath) return err } // Deploy networkpolicy for monitoring namespace - err = deploy.DeployManifestsFromPath(r.Client, dscInit, networkpolicyPath+"/monitoring", dscInit.Spec.Monitoring.Namespace, "networkpolicy", true) + err = deploy.DeployManifestsFromPath(ctx, r.Client, dscInit, networkpolicyPath+"/monitoring", dscInit.Spec.Monitoring.Namespace, "networkpolicy", true) if err != nil { r.Log.Error(err, "error to set networkpolicy in monitroing namespace", "path", networkpolicyPath) return err } // Deploy networkpolicy for applications namespace - err = deploy.DeployManifestsFromPath(r.Client, dscInit, networkpolicyPath+"/applications", dscInit.Spec.ApplicationsNamespace, "networkpolicy", true) + err = deploy.DeployManifestsFromPath(ctx, r.Client, dscInit, networkpolicyPath+"/applications", dscInit.Spec.ApplicationsNamespace, "networkpolicy", true) if err != nil { r.Log.Error(err, "error to set networkpolicy in applications namespace", "path", networkpolicyPath) return err diff --git a/controllers/status/reporter.go b/controllers/status/reporter.go index 347a5d97fdb..d9efd87bc95 100644 --- a/controllers/status/reporter.go +++ b/controllers/status/reporter.go @@ -32,8 +32,8 @@ func NewStatusReporter[T client.Object](cli client.Client, object T, determine D } // ReportCondition updates the status of the object using the determineCondition function. -func (r *Reporter[T]) ReportCondition(optionalErr error) (T, error) { - return UpdateWithRetry[T](context.Background(), r.client, r.object, r.determineCondition(optionalErr)) +func (r *Reporter[T]) ReportCondition(ctx context.Context, optionalErr error) (T, error) { + return UpdateWithRetry[T](ctx, r.client, r.object, r.determineCondition(optionalErr)) } // SaveStatusFunc is a function that allow to define custom logic of updating status of a concrete resource object. diff --git a/controllers/webhook/webhook_suite_test.go b/controllers/webhook/webhook_suite_test.go index 6c9d6dcc0c8..aebc4a1431d 100644 --- a/controllers/webhook/webhook_suite_test.go +++ b/controllers/webhook/webhook_suite_test.go @@ -64,8 +64,8 @@ const ( var cfg *rest.Config var k8sClient client.Client var testEnv *envtest.Environment -var ctx context.Context -var cancel context.CancelFunc +var gCtx context.Context +var gCancel context.CancelFunc func TestAPIs(t *testing.T) { RegisterFailHandler(Fail) @@ -74,9 +74,10 @@ func TestAPIs(t *testing.T) { } var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + // can't use suite's context as the manager should survive the function + gCtx, gCancel = context.WithCancel(context.Background()) - ctx, cancel = context.WithCancel(context.TODO()) + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) By("bootstrapping test environment") testEnv = &envtest.Environment{ @@ -122,11 +123,11 @@ var _ = BeforeSuite(func() { (&webhook.OpenDataHubWebhook{}).SetupWithManager(mgr) - //+kubebuilder:scaffold:webhook + // +kubebuilder:scaffold:webhook go func() { defer GinkgoRecover() - err = mgr.Start(ctx) + err = mgr.Start(gCtx) Expect(err).NotTo(HaveOccurred()) }() @@ -145,25 +146,26 @@ var _ = BeforeSuite(func() { }) var _ = AfterSuite(func() { - cancel() + gCancel() + By("tearing down the test environment") err := testEnv.Stop() Expect(err).NotTo(HaveOccurred()) }) var _ = Describe("DSC/DSCI webhook", func() { - It("Should not have more than one DSCI instance in the cluster", func() { + It("Should not have more than one DSCI instance in the cluster", func(ctx context.Context) { desiredDsci := newDSCI(nameBase + "-dsci-1") - Expect(k8sClient.Create(context.Background(), desiredDsci)).Should(Succeed()) + Expect(k8sClient.Create(ctx, desiredDsci)).Should(Succeed()) desiredDsci2 := newDSCI(nameBase + "-dsci-2") - Expect(k8sClient.Create(context.Background(), desiredDsci2)).ShouldNot(Succeed()) + Expect(k8sClient.Create(ctx, desiredDsci2)).ShouldNot(Succeed()) }) - It("Should block creation of second DSC instance", func() { + It("Should block creation of second DSC instance", func(ctx context.Context) { dscSpec := newDSC(nameBase+"-dsc-1", namespace) - Expect(k8sClient.Create(context.Background(), dscSpec)).Should(Succeed()) + Expect(k8sClient.Create(ctx, dscSpec)).Should(Succeed()) dscSpec = newDSC(nameBase+"-dsc-2", namespace) - Expect(k8sClient.Create(context.Background(), dscSpec)).ShouldNot(Succeed()) + Expect(k8sClient.Create(ctx, dscSpec)).ShouldNot(Succeed()) }) }) diff --git a/main.go b/main.go index 409af0c853b..ecf0cd7125b 100644 --- a/main.go +++ b/main.go @@ -71,7 +71,7 @@ var ( ) func init() { //nolint:gochecknoinits - //+kubebuilder:scaffold:scheme + // +kubebuilder:scaffold:scheme utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(dsci.AddToScheme(scheme)) utilruntime.Must(dsc.AddToScheme(scheme)) @@ -119,6 +119,9 @@ func main() { //nolint:funlen ctrl.SetLogger(logger.ConfigLoggers(logmode)) + // root context + ctx := ctrl.SetupSignalHandler() + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ // single pod does not need to have LeaderElection Scheme: scheme, MetricsBindAddress: metricsAddr, @@ -138,7 +141,7 @@ func main() { //nolint:funlen Log: logger.LogWithLevel(ctrl.Log.WithName(operatorName).WithName("controllers").WithName("DSCInitialization"), logmode), Recorder: mgr.GetEventRecorderFor("dscinitialization-controller"), ApplicationsNamespace: dscApplicationsNamespace, - }).SetupWithManager(mgr); err != nil { + }).SetupWithManager(ctx, mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "DSCInitiatlization") os.Exit(1) } @@ -153,7 +156,7 @@ func main() { //nolint:funlen }, }, Recorder: mgr.GetEventRecorderFor("datasciencecluster-controller"), - }).SetupWithManager(mgr); err != nil { + }).SetupWithManager(ctx, mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "DataScienceCluster") os.Exit(1) } @@ -192,7 +195,7 @@ func main() { //nolint:funlen os.Exit(1) } // Get operator platform - platform, err := cluster.GetPlatform(setupClient) + platform, err := cluster.GetPlatform(ctx, setupClient) if err != nil { setupLog.Error(err, "error getting platform") os.Exit(1) @@ -219,7 +222,7 @@ func main() { //nolint:funlen // Create default DSC CR for managed RHODS if platform == cluster.ManagedRhods { var createDefaultDSCFunc manager.RunnableFunc = func(ctx context.Context) error { - err := upgrade.CreateDefaultDSC(context.TODO(), setupClient) + err := upgrade.CreateDefaultDSC(ctx, setupClient) if err != nil { setupLog.Error(err, "unable to create default DSC CR by the operator") } @@ -254,7 +257,7 @@ func main() { //nolint:funlen } setupLog.Info("starting manager") - if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + if err := mgr.Start(ctx); err != nil { setupLog.Error(err, "problem running manager") os.Exit(1) } diff --git a/pkg/cluster/cluster_config.go b/pkg/cluster/cluster_config.go index 274abae0c97..cad4328a7af 100644 --- a/pkg/cluster/cluster_config.go +++ b/pkg/cluster/cluster_config.go @@ -20,11 +20,11 @@ import ( // +kubebuilder:rbac:groups="config.openshift.io",resources=ingresses,verbs=get -func GetDomain(c client.Client) (string, error) { +func GetDomain(ctx context.Context, c client.Client) (string, error) { ingress := &unstructured.Unstructured{} ingress.SetGroupVersionKind(gvk.OpenshiftIngress) - if err := c.Get(context.TODO(), client.ObjectKey{ + if err := c.Get(ctx, client.ObjectKey{ Namespace: "", Name: "cluster", }, ingress); err != nil { @@ -67,14 +67,14 @@ func GetClusterServiceVersion(ctx context.Context, c client.Client, watchNameSpa type Platform string // detectSelfManaged detects if it is Self Managed Rhods or OpenDataHub. -func detectSelfManaged(cli client.Client) (Platform, error) { +func detectSelfManaged(ctx context.Context, cli client.Client) (Platform, error) { variants := map[string]Platform{ "opendatahub-operator": OpenDataHub, "rhods-operator": SelfManagedRhods, } for k, v := range variants { - exists, err := OperatorExists(cli, k) + exists, err := OperatorExists(ctx, cli, k) if err != nil { return Unknown, err } @@ -87,15 +87,15 @@ func detectSelfManaged(cli client.Client) (Platform, error) { } // detectManagedRHODS checks if CRD add-on exists and contains string ManagedRhods. -func detectManagedRHODS(cli client.Client) (Platform, error) { +func detectManagedRHODS(ctx context.Context, cli client.Client) (Platform, error) { catalogSourceCRD := &apiextv1.CustomResourceDefinition{} - err := cli.Get(context.TODO(), client.ObjectKey{Name: "catalogsources.operators.coreos.com"}, catalogSourceCRD) + err := cli.Get(ctx, client.ObjectKey{Name: "catalogsources.operators.coreos.com"}, catalogSourceCRD) if err != nil { return "", client.IgnoreNotFound(err) } expectedCatlogSource := &ofapi.CatalogSourceList{} - err = cli.List(context.TODO(), expectedCatlogSource) + err = cli.List(ctx, expectedCatlogSource) if err != nil { return Unknown, err } @@ -110,16 +110,16 @@ func detectManagedRHODS(cli client.Client) (Platform, error) { return "", nil } -func GetPlatform(cli client.Client) (Platform, error) { +func GetPlatform(ctx context.Context, cli client.Client) (Platform, error) { // First check if its addon installation to return 'ManagedRhods, nil' - if platform, err := detectManagedRHODS(cli); err != nil { + if platform, err := detectManagedRHODS(ctx, cli); err != nil { return Unknown, err } else if platform == ManagedRhods { return ManagedRhods, nil } // check and return whether ODH or self-managed platform - return detectSelfManaged(cli) + return detectSelfManaged(ctx, cli) } // Release includes information on operator version and platform @@ -129,7 +129,7 @@ type Release struct { Version version.OperatorVersion `json:"version,omitempty"` } -func GetRelease(cli client.Client) (Release, error) { +func GetRelease(ctx context.Context, cli client.Client) (Release, error) { initRelease := Release{ // dummy version set to name "", version 0.0.0 Version: version.OperatorVersion{ @@ -137,7 +137,7 @@ func GetRelease(cli client.Client) (Release, error) { }, } // Set platform - platform, err := GetPlatform(cli) + platform, err := GetPlatform(ctx, cli) if err != nil { return initRelease, err } @@ -155,7 +155,7 @@ func GetRelease(cli client.Client) (Release, error) { fmt.Printf("Falling back to dummy version: %v\n", err) return initRelease, nil } - csv, err := GetClusterServiceVersion(context.TODO(), cli, operatorNamespace) + csv, err := GetClusterServiceVersion(ctx, cli, operatorNamespace) if apierrs.IsNotFound(err) { // hide not found, return default return initRelease, nil diff --git a/pkg/cluster/cluster_operations_int_test.go b/pkg/cluster/cluster_operations_int_test.go index e8883e21f69..c6385829b67 100644 --- a/pkg/cluster/cluster_operations_int_test.go +++ b/pkg/cluster/cluster_operations_int_test.go @@ -31,13 +31,13 @@ var _ = Describe("Creating cluster resources", func() { objectCleaner = envtestutil.CreateCleaner(envTestClient, envTest.Config, timeout, interval) }) - It("should create namespace if it does not exist", func() { + It("should create namespace if it does not exist", func(ctx context.Context) { // given namespace := envtestutil.AppendRandomNameTo("new-ns") - defer objectCleaner.DeleteAll(&v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}) + defer objectCleaner.DeleteAll(ctx, &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}) // when - ns, err := cluster.CreateNamespace(context.Background(), envTestClient, namespace) + ns, err := cluster.CreateNamespace(ctx, envTestClient, namespace) // then Expect(err).ToNot(HaveOccurred()) @@ -45,7 +45,7 @@ var _ = Describe("Creating cluster resources", func() { Expect(ns.ObjectMeta.Generation).To(BeZero()) }) - It("should not try to create namespace if it does already exist", func() { + It("should not try to create namespace if it does already exist", func(ctx context.Context) { // given namespace := envtestutil.AppendRandomNameTo("existing-ns") newNamespace := &v1.Namespace{ @@ -53,24 +53,24 @@ var _ = Describe("Creating cluster resources", func() { Name: namespace, }, } - Expect(envTestClient.Create(context.Background(), newNamespace)).To(Succeed()) - defer objectCleaner.DeleteAll(newNamespace) + Expect(envTestClient.Create(ctx, newNamespace)).To(Succeed()) + defer objectCleaner.DeleteAll(ctx, newNamespace) // when - existingNamespace, err := cluster.CreateNamespace(context.Background(), envTestClient, namespace) + existingNamespace, err := cluster.CreateNamespace(ctx, envTestClient, namespace) // then Expect(err).ToNot(HaveOccurred()) Expect(existingNamespace).To(Equal(newNamespace)) }) - It("should set labels", func() { + It("should set labels", func(ctx context.Context) { // given namespace := envtestutil.AppendRandomNameTo("new-ns-with-labels") - defer objectCleaner.DeleteAll(&v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}) + defer objectCleaner.DeleteAll(ctx, &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}) // when - nsWithLabels, err := cluster.CreateNamespace(context.Background(), envTestClient, namespace, cluster.WithLabels("opendatahub.io/test-label", "true")) + nsWithLabels, err := cluster.CreateNamespace(ctx, envTestClient, namespace, cluster.WithLabels("opendatahub.io/test-label", "true")) // then Expect(err).ToNot(HaveOccurred()) @@ -92,7 +92,7 @@ var _ = Describe("Creating cluster resources", func() { Namespace: "default", } - It("should create configmap with labels and owner reference", func() { + It("should create configmap with labels and owner reference", func(ctx context.Context) { // given configMap := &v1.ConfigMap{ ObjectMeta: configMapMeta, @@ -103,7 +103,7 @@ var _ = Describe("Creating cluster resources", func() { // when err := cluster.CreateOrUpdateConfigMap( - context.Background(), + ctx, envTestClient, configMap, cluster.WithLabels(labels.K8SCommon.PartOf, "opendatahub"), @@ -115,11 +115,11 @@ var _ = Describe("Creating cluster resources", func() { }), ) Expect(err).ToNot(HaveOccurred()) - defer objectCleaner.DeleteAll(configMap) + defer objectCleaner.DeleteAll(ctx, configMap) // then actualConfigMap := &v1.ConfigMap{} - Expect(envTestClient.Get(context.Background(), ctrlruntime.ObjectKeyFromObject(configMap), actualConfigMap)).To(Succeed()) + Expect(envTestClient.Get(ctx, ctrlruntime.ObjectKeyFromObject(configMap), actualConfigMap)).To(Succeed()) Expect(actualConfigMap.Labels).To(HaveKeyWithValue(labels.K8SCommon.PartOf, "opendatahub")) getOwnerRefName := func(reference metav1.OwnerReference) string { return reference.Name @@ -127,10 +127,10 @@ var _ = Describe("Creating cluster resources", func() { Expect(actualConfigMap.OwnerReferences[0]).To(WithTransform(getOwnerRefName, Equal("default"))) }) - It("should be able to update existing config map", func() { + It("should be able to update existing config map", func(ctx context.Context) { // given createErr := cluster.CreateOrUpdateConfigMap( - context.Background(), + ctx, envTestClient, &v1.ConfigMap{ ObjectMeta: configMapMeta, @@ -152,17 +152,17 @@ var _ = Describe("Creating cluster resources", func() { } updateErr := cluster.CreateOrUpdateConfigMap( - context.Background(), + ctx, envTestClient, updatedConfigMap, cluster.WithLabels("test-step", "update-existing-configmap"), ) Expect(updateErr).ToNot(HaveOccurred()) - defer objectCleaner.DeleteAll(updatedConfigMap) + defer objectCleaner.DeleteAll(ctx, updatedConfigMap) // then actualConfigMap := &v1.ConfigMap{} - Expect(envTestClient.Get(context.Background(), ctrlruntime.ObjectKeyFromObject(updatedConfigMap), actualConfigMap)).To(Succeed()) + Expect(envTestClient.Get(ctx, ctrlruntime.ObjectKeyFromObject(updatedConfigMap), actualConfigMap)).To(Succeed()) Expect(actualConfigMap.Data).To(HaveKeyWithValue("test-key", "new-value")) Expect(actualConfigMap.Data).To(HaveKeyWithValue("new-key", "sth-new")) Expect(actualConfigMap.Labels).To(HaveKeyWithValue("test-step", "update-existing-configmap")) diff --git a/pkg/cluster/cluster_operations_suite_int_test.go b/pkg/cluster/cluster_operations_suite_int_test.go index b553fd83a3a..a40ba23b595 100644 --- a/pkg/cluster/cluster_operations_suite_int_test.go +++ b/pkg/cluster/cluster_operations_suite_int_test.go @@ -1,7 +1,6 @@ package cluster_test import ( - "context" "testing" v1 "k8s.io/api/core/v1" @@ -19,8 +18,6 @@ import ( var ( envTestClient client.Client envTest *envtest.Environment - ctx context.Context - cancel context.CancelFunc ) var testScheme = runtime.NewScheme() @@ -31,8 +28,6 @@ func TestClusterOperationsIntegration(t *testing.T) { } var _ = BeforeSuite(func() { - ctx, cancel = context.WithCancel(context.TODO()) - opts := zap.Options{Development: true} logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseFlagOptions(&opts))) @@ -53,6 +48,5 @@ var _ = BeforeSuite(func() { var _ = AfterSuite(func() { By("Tearing down the test environment") - cancel() Expect(envTest.Stop()).To(Succeed()) }) diff --git a/pkg/cluster/operator.go b/pkg/cluster/operator.go index 6eb2df75ded..94b2ff5d324 100644 --- a/pkg/cluster/operator.go +++ b/pkg/cluster/operator.go @@ -12,18 +12,18 @@ import ( // GetSubscription checks if a Subscription for the operator exists in the given namespace. // if exists, return object; otherwise, return error. -func GetSubscription(cli client.Client, namespace string, name string) (*v1alpha1.Subscription, error) { +func GetSubscription(ctx context.Context, cli client.Client, namespace string, name string) (*v1alpha1.Subscription, error) { sub := &v1alpha1.Subscription{} - if err := cli.Get(context.TODO(), client.ObjectKey{Namespace: namespace, Name: name}, sub); err != nil { + if err := cli.Get(ctx, client.ObjectKey{Namespace: namespace, Name: name}, sub); err != nil { // real error or 'not found' both return here return nil, err } return sub, nil } -func SubscriptionExists(cli client.Client, name string) (bool, error) { +func SubscriptionExists(ctx context.Context, cli client.Client, name string) (bool, error) { subscriptionList := &v1alpha1.SubscriptionList{} - if err := cli.List(context.TODO(), subscriptionList); err != nil { + if err := cli.List(ctx, subscriptionList); err != nil { return false, err } @@ -37,13 +37,13 @@ func SubscriptionExists(cli client.Client, name string) (bool, error) { // DeleteExistingSubscription deletes given Subscription if it exists // Do not error if the Subscription does not exist. -func DeleteExistingSubscription(cli client.Client, operatorNs string, subsName string) error { - sub, err := GetSubscription(cli, operatorNs, subsName) +func DeleteExistingSubscription(ctx context.Context, cli client.Client, operatorNs string, subsName string) error { + sub, err := GetSubscription(ctx, cli, operatorNs, subsName) if err != nil { return client.IgnoreNotFound(err) } - if err := cli.Delete(context.TODO(), sub); client.IgnoreNotFound(err) != nil { + if err := cli.Delete(ctx, sub); client.IgnoreNotFound(err) != nil { return fmt.Errorf("error deleting subscription %s: %w", sub.Name, err) } @@ -53,9 +53,9 @@ func DeleteExistingSubscription(cli client.Client, operatorNs string, subsName s // OperatorExists checks if an Operator with 'operatorPrefix' is installed. // Return true if found it, false if not. // if we need to check exact version of the operator installed, can append vX.Y.Z later. -func OperatorExists(cli client.Client, operatorPrefix string) (bool, error) { +func OperatorExists(ctx context.Context, cli client.Client, operatorPrefix string) (bool, error) { opConditionList := &v2.OperatorConditionList{} - err := cli.List(context.TODO(), opConditionList) + err := cli.List(ctx, opConditionList) if err != nil { return false, err } diff --git a/pkg/deploy/deploy.go b/pkg/deploy/deploy.go index 74597df213b..ee44b209fb7 100644 --- a/pkg/deploy/deploy.go +++ b/pkg/deploy/deploy.go @@ -57,10 +57,10 @@ const ( // DownloadManifests function performs following tasks: // 1. It takes component URI and only downloads folder specified by component.ContextDir field // 2. It saves the manifests in the odh-manifests/component-name/ folder. -func DownloadManifests(componentName string, manifestConfig components.ManifestsConfig) error { +func DownloadManifests(ctx context.Context, componentName string, manifestConfig components.ManifestsConfig) error { // Get the component repo from the given url // e.g. https://github.com/example/tarball/master - req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, manifestConfig.URI, nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, manifestConfig.URI, nil) if err != nil { return err } @@ -145,7 +145,7 @@ func DownloadManifests(componentName string, manifestConfig components.Manifests return err } -func DeployManifestsFromPath(cli client.Client, owner metav1.Object, manifestPath string, namespace string, componentName string, componentEnabled bool) error { //nolint:golint,revive,lll +func DeployManifestsFromPath(ctx context.Context, cli client.Client, owner metav1.Object, manifestPath string, namespace string, componentName string, componentEnabled bool) error { //nolint:golint,revive,lll // Render the Kustomize manifests k := krusty.MakeKustomizer(krusty.MakeDefaultOptions()) fs := filesys.MakeFsOnDisk() @@ -181,7 +181,7 @@ func DeployManifestsFromPath(cli client.Client, owner metav1.Object, manifestPat } // Create / apply / delete resources in the cluster for _, obj := range objs { - err = manageResource(context.TODO(), cli, obj, owner, namespace, componentName, componentEnabled) + err = manageResource(ctx, cli, obj, owner, namespace, componentName, componentEnabled) if err != nil { return err } diff --git a/pkg/feature/conditions.go b/pkg/feature/conditions.go index 10dd22c0954..be86b4c0fb4 100644 --- a/pkg/feature/conditions.go +++ b/pkg/feature/conditions.go @@ -40,8 +40,8 @@ func (e *MissingOperatorError) Error() string { } func EnsureOperatorIsInstalled(operatorName string) Action { - return func(f *Feature) error { - if found, err := cluster.SubscriptionExists(f.Client, operatorName); !found || err != nil { + return func(ctx context.Context, f *Feature) error { + if found, err := cluster.SubscriptionExists(ctx, f.Client, operatorName); !found || err != nil { return fmt.Errorf( "failed to find the pre-requisite operator subscription %q, please ensure operator is installed. %w", operatorName, @@ -53,13 +53,13 @@ func EnsureOperatorIsInstalled(operatorName string) Action { } func WaitForPodsToBeReady(namespace string) Action { - return func(f *Feature) error { + return func(ctx context.Context, f *Feature) error { f.Log.Info("waiting for pods to become ready", "namespace", namespace, "duration (s)", duration.Seconds()) - return wait.PollUntilContextTimeout(context.TODO(), interval, duration, false, func(ctx context.Context) (bool, error) { + return wait.PollUntilContextTimeout(ctx, interval, duration, false, func(ctx context.Context) (bool, error) { var podList corev1.PodList - err := f.Client.List(context.TODO(), &podList, client.InNamespace(namespace)) + err := f.Client.List(ctx, &podList, client.InNamespace(namespace)) if err != nil { return false, err } @@ -103,14 +103,14 @@ func WaitForPodsToBeReady(namespace string) Action { } func WaitForResourceToBeCreated(namespace string, gvk schema.GroupVersionKind) Action { - return func(f *Feature) error { + return func(ctx context.Context, f *Feature) error { f.Log.Info("waiting for resource to be created", "namespace", namespace, "resource", gvk) - return wait.PollUntilContextTimeout(context.TODO(), interval, duration, false, func(ctx context.Context) (bool, error) { + return wait.PollUntilContextTimeout(ctx, interval, duration, false, func(ctx context.Context) (bool, error) { list := &unstructured.UnstructuredList{} list.SetGroupVersionKind(gvk) - err := f.Client.List(context.TODO(), list, client.InNamespace(namespace), client.Limit(1)) + err := f.Client.List(ctx, list, client.InNamespace(namespace), client.Limit(1)) if err != nil { f.Log.Error(err, "failed waiting for resource", "namespace", namespace, "resource", gvk) diff --git a/pkg/feature/feature.go b/pkg/feature/feature.go index 590c02e4f77..4366751f8ad 100644 --- a/pkg/feature/feature.go +++ b/pkg/feature/feature.go @@ -48,35 +48,35 @@ func newFeature(name string) *Feature { } // Action is a func type which can be used for different purposes while having access to Feature struct. -type Action func(feature *Feature) error +type Action func(ctx context.Context, feature *Feature) error -func (f *Feature) Apply() error { +func (f *Feature) Apply(ctx context.Context) error { if !f.Enabled { return nil } - if trackerErr := f.createFeatureTracker(); trackerErr != nil { + if trackerErr := f.createFeatureTracker(ctx); trackerErr != nil { return trackerErr } - if _, updateErr := status.UpdateWithRetry(context.Background(), f.Client, f.Tracker, func(saved *featurev1.FeatureTracker) { + if _, updateErr := status.UpdateWithRetry(ctx, f.Client, f.Tracker, func(saved *featurev1.FeatureTracker) { status.SetProgressingCondition(&saved.Status.Conditions, string(featurev1.ConditionReason.FeatureCreated), fmt.Sprintf("Applying feature [%s]", f.Name)) saved.Status.Phase = status.PhaseProgressing }); updateErr != nil { return updateErr } - applyErr := f.applyFeature() - _, reportErr := createFeatureTrackerStatusReporter(f).ReportCondition(applyErr) + applyErr := f.applyFeature(ctx) + _, reportErr := createFeatureTrackerStatusReporter(f).ReportCondition(ctx, applyErr) return multierror.Append(applyErr, reportErr).ErrorOrNil() } -func (f *Feature) applyFeature() error { +func (f *Feature) applyFeature(ctx context.Context) error { var multiErr *multierror.Error for _, precondition := range f.preconditions { - multiErr = multierror.Append(multiErr, precondition(f)) + multiErr = multierror.Append(multiErr, precondition(ctx, f)) } if preconditionsErr := multiErr.ErrorOrNil(); preconditionsErr != nil { @@ -84,14 +84,14 @@ func (f *Feature) applyFeature() error { } for _, loader := range f.loaders { - multiErr = multierror.Append(multiErr, loader(f)) + multiErr = multierror.Append(multiErr, loader(ctx, f)) } if dataLoadErr := multiErr.ErrorOrNil(); dataLoadErr != nil { return &withConditionReasonError{reason: featurev1.ConditionReason.LoadTemplateData, err: dataLoadErr} } for _, resource := range f.resources { - if resourceCreateErr := resource(f); resourceCreateErr != nil { + if resourceCreateErr := resource(ctx, f); resourceCreateErr != nil { return &withConditionReasonError{reason: featurev1.ConditionReason.ResourceCreation, err: resourceCreateErr} } } @@ -109,13 +109,13 @@ func (f *Feature) applyFeature() error { manifest.MarkAsManaged(objs) } - if err := apply(objs); err != nil { + if err := apply(ctx, objs); err != nil { return &withConditionReasonError{reason: featurev1.ConditionReason.ApplyManifests, err: err} } } for _, postcondition := range f.postconditions { - multiErr = multierror.Append(multiErr, postcondition(f)) + multiErr = multierror.Append(multiErr, postcondition(ctx, f)) } if postConditionErr := multiErr.ErrorOrNil(); postConditionErr != nil { return &withConditionReasonError{reason: featurev1.ConditionReason.PostConditions, err: postConditionErr} @@ -124,7 +124,7 @@ func (f *Feature) applyFeature() error { return nil } -func (f *Feature) Cleanup() error { +func (f *Feature) Cleanup(ctx context.Context) error { if !f.Enabled { return nil } @@ -135,32 +135,32 @@ func (f *Feature) Cleanup() error { var cleanupErrors *multierror.Error for _, cleanupFunc := range f.cleanups { - cleanupErrors = multierror.Append(cleanupErrors, cleanupFunc(f)) + cleanupErrors = multierror.Append(cleanupErrors, cleanupFunc(ctx, f)) } return cleanupErrors.ErrorOrNil() } -type applier func(objects []*unstructured.Unstructured) error +type applier func(ctx context.Context, objects []*unstructured.Unstructured) error func (f *Feature) createApplier(m Manifest) applier { switch manifest := m.(type) { case *templateManifest: if manifest.patch { - return func(objects []*unstructured.Unstructured) error { - return patchResources(f.Client, objects) + return func(ctx context.Context, objects []*unstructured.Unstructured) error { + return patchResources(ctx, f.Client, objects) } } case *rawManifest: if manifest.patch { - return func(objects []*unstructured.Unstructured) error { - return patchResources(f.Client, objects) + return func(ctx context.Context, objects []*unstructured.Unstructured) error { + return patchResources(ctx, f.Client, objects) } } } - return func(objects []*unstructured.Unstructured) error { - return applyResources(f.Client, objects, OwnedBy(f)) + return func(ctx context.Context, objects []*unstructured.Unstructured) error { + return applyResources(ctx, f.Client, objects, OwnedBy(f)) } } @@ -168,7 +168,7 @@ func (f *Feature) addCleanup(cleanupFuncs ...Action) { f.cleanups = append(f.cleanups, cleanupFuncs...) } -func (f *Feature) ApplyManifest(path string) error { +func (f *Feature) ApplyManifest(ctx context.Context, path string) error { m, err := loadManifestsFrom(f.fsys, path) if err != nil { return err @@ -186,7 +186,7 @@ func (f *Feature) ApplyManifest(path string) error { manifest.MarkAsManaged(objs) } - if err = apply(objs); err != nil { + if err = apply(ctx, objs); err != nil { return errors.WithStack(err) } } diff --git a/pkg/feature/feature_tracker_handler.go b/pkg/feature/feature_tracker_handler.go index af1ccc13548..19a54f117b1 100644 --- a/pkg/feature/feature_tracker_handler.go +++ b/pkg/feature/feature_tracker_handler.go @@ -30,10 +30,10 @@ func (e *withConditionReasonError) Error() string { // createFeatureTracker instantiates FeatureTracker for a given Feature. It's a cluster-scoped resource used // to track creation and removal of all owned resources which belong to this Feature. // All resources which particular feature is composed of will have this object attached as an OwnerReference. -func (f *Feature) createFeatureTracker() error { - tracker, err := f.getFeatureTracker() +func (f *Feature) createFeatureTracker(ctx context.Context) error { + tracker, err := f.getFeatureTracker(ctx) if k8serrors.IsNotFound(err) { - if err := f.Client.Create(context.TODO(), tracker); err != nil { + if err := f.Client.Create(ctx, tracker); err != nil { return err } } else if err != nil { @@ -49,15 +49,15 @@ func (f *Feature) createFeatureTracker() error { return nil } -func removeFeatureTracker(f *Feature) error { - if err := getFeatureTrackerIfAbsent(f); err != nil { +func removeFeatureTracker(ctx context.Context, f *Feature) error { + if err := getFeatureTrackerIfAbsent(ctx, f); err != nil { return client.IgnoreNotFound(err) } - return deleteTracker(f) + return deleteTracker(ctx, f) } -func (f *Feature) getFeatureTracker() (*featurev1.FeatureTracker, error) { +func (f *Feature) getFeatureTracker(ctx context.Context) (*featurev1.FeatureTracker, error) { tracker := featurev1.NewFeatureTracker(f.Name, f.Spec.AppNamespace) tracker.Spec = featurev1.FeatureTrackerSpec{ @@ -65,18 +65,18 @@ func (f *Feature) getFeatureTracker() (*featurev1.FeatureTracker, error) { AppNamespace: f.Spec.AppNamespace, } - err := f.Client.Get(context.Background(), client.ObjectKeyFromObject(tracker), tracker) + err := f.Client.Get(ctx, client.ObjectKeyFromObject(tracker), tracker) return tracker, err } -func deleteTracker(f *Feature) error { - return client.IgnoreNotFound(f.Client.Delete(context.Background(), f.Tracker)) +func deleteTracker(ctx context.Context, f *Feature) error { + return client.IgnoreNotFound(f.Client.Delete(ctx, f.Tracker)) } -func getFeatureTrackerIfAbsent(f *Feature) error { +func getFeatureTrackerIfAbsent(ctx context.Context, f *Feature) error { var err error - f.Tracker, err = f.getFeatureTracker() + f.Tracker, err = f.getFeatureTracker(ctx) return err } diff --git a/pkg/feature/handler.go b/pkg/feature/handler.go index 67af83fe642..554c9fd4fd8 100644 --- a/pkg/feature/handler.go +++ b/pkg/feature/handler.go @@ -2,6 +2,7 @@ package feature import ( + "context" "fmt" "github.com/hashicorp/go-multierror" @@ -13,8 +14,8 @@ import ( ) type featureHandler interface { - Apply() error - Delete() error + Apply(ctx context.Context) error + Delete(ctx context.Context) error } var _ featureHandler = (*FeaturesHandler)(nil) @@ -49,17 +50,17 @@ func NewHandlerWithReporter[T client.Object](handler *FeaturesHandler, reporter } } -func (h HandlerWithReporter[T]) Apply() error { - applyErr := h.handler.Apply() - _, reportErr := h.reporter.ReportCondition(applyErr) +func (h HandlerWithReporter[T]) Apply(ctx context.Context) error { + applyErr := h.handler.Apply(ctx) + _, reportErr := h.reporter.ReportCondition(ctx, applyErr) // We could have failed during Apply phase as well as during reporting. // We should return both errors to the caller. return multierror.Append(applyErr, reportErr).ErrorOrNil() } -func (h HandlerWithReporter[T]) Delete() error { - deleteErr := h.handler.Delete() - _, reportErr := h.reporter.ReportCondition(deleteErr) +func (h HandlerWithReporter[T]) Delete(ctx context.Context) error { + deleteErr := h.handler.Delete(ctx) + _, reportErr := h.reporter.ReportCondition(ctx, deleteErr) // We could have failed during Delete phase as well as during reporting. // We should return both errors to the caller. return multierror.Append(deleteErr, reportErr).ErrorOrNil() @@ -85,7 +86,7 @@ func ComponentFeaturesHandler(componentName string, spec *v1.DSCInitializationSp } } -func (fh *FeaturesHandler) Apply() error { +func (fh *FeaturesHandler) Apply(ctx context.Context) error { for _, featuresProvider := range fh.featuresProviders { if err := featuresProvider(fh); err != nil { return fmt.Errorf("apply phase failed when applying features: %w", err) @@ -94,7 +95,7 @@ func (fh *FeaturesHandler) Apply() error { var applyErrors *multierror.Error for _, f := range fh.features { - applyErrors = multierror.Append(applyErrors, f.Apply()) + applyErrors = multierror.Append(applyErrors, f.Apply(ctx)) } return applyErrors.ErrorOrNil() @@ -104,7 +105,7 @@ func (fh *FeaturesHandler) Apply() error { // For instance, this allows for the undoing patches before its deletion. // This approach assumes that Features are either instantiated in the correct sequence // or are self-contained. -func (fh *FeaturesHandler) Delete() error { +func (fh *FeaturesHandler) Delete(ctx context.Context) error { for _, featuresProvider := range fh.featuresProviders { if err := featuresProvider(fh); err != nil { return fmt.Errorf("delete phase failed when wiring Feature instances: %w", err) @@ -113,7 +114,7 @@ func (fh *FeaturesHandler) Delete() error { var cleanupErrors *multierror.Error for i := len(fh.features) - 1; i >= 0; i-- { - cleanupErrors = multierror.Append(cleanupErrors, fh.features[i].Cleanup()) + cleanupErrors = multierror.Append(cleanupErrors, fh.features[i].Cleanup(ctx)) } return cleanupErrors.ErrorOrNil() diff --git a/pkg/feature/raw_resources.go b/pkg/feature/raw_resources.go index 3b88b42e82c..06025943bb9 100644 --- a/pkg/feature/raw_resources.go +++ b/pkg/feature/raw_resources.go @@ -29,7 +29,7 @@ const ( YamlSeparator = "(?m)^---[ \t]*$" ) -func applyResources(cli client.Client, objects []*unstructured.Unstructured, metaOptions ...cluster.MetaOptions) error { +func applyResources(ctx context.Context, cli client.Client, objects []*unstructured.Unstructured, metaOptions ...cluster.MetaOptions) error { for _, object := range objects { for _, opt := range metaOptions { if err := opt(object); err != nil { @@ -40,14 +40,14 @@ func applyResources(cli client.Client, objects []*unstructured.Unstructured, met name := object.GetName() namespace := object.GetNamespace() - err := cli.Get(context.TODO(), k8stypes.NamespacedName{Name: name, Namespace: namespace}, object.DeepCopy()) + err := cli.Get(ctx, k8stypes.NamespacedName{Name: name, Namespace: namespace}, object.DeepCopy()) if client.IgnoreNotFound(err) != nil { return fmt.Errorf("failed to get object %s/%s: %w", namespace, name, err) } if err != nil { // object does not exist and should be created - if createErr := cli.Create(context.TODO(), object); client.IgnoreAlreadyExists(createErr) != nil { + if createErr := cli.Create(ctx, object); client.IgnoreAlreadyExists(createErr) != nil { return fmt.Errorf("failed to create object %s/%s: %w", namespace, name, createErr) } } @@ -55,7 +55,7 @@ func applyResources(cli client.Client, objects []*unstructured.Unstructured, met isManaged, isAnnotated := object.GetAnnotations()[annotations.ManagedByODHOperator] if isAnnotated && isManaged == "true" { // update the object since we manage it - if updateErr := cli.Update(context.TODO(), object); updateErr != nil { + if updateErr := cli.Update(ctx, object); updateErr != nil { return fmt.Errorf("failed to update object %s/%s: %w", namespace, name, updateErr) } } @@ -64,7 +64,7 @@ func applyResources(cli client.Client, objects []*unstructured.Unstructured, met return nil } -func patchResources(cli client.Client, patches []*unstructured.Unstructured) error { +func patchResources(ctx context.Context, cli client.Client, patches []*unstructured.Unstructured) error { for _, patch := range patches { // Convert the individual resource patch to JSON patchAsJSON, err := patch.MarshalJSON() @@ -72,7 +72,7 @@ func patchResources(cli client.Client, patches []*unstructured.Unstructured) err return fmt.Errorf("error converting yaml to json: %w", err) } - if err = cli.Patch(context.TODO(), patch, client.RawPatch(k8stypes.MergePatchType, patchAsJSON)); err != nil { + if err = cli.Patch(ctx, patch, client.RawPatch(k8stypes.MergePatchType, patchAsJSON)); err != nil { return fmt.Errorf("failed patching resource: %w", err) } } diff --git a/pkg/feature/resources.go b/pkg/feature/resources.go index 814849d73e8..7b89881c9a7 100644 --- a/pkg/feature/resources.go +++ b/pkg/feature/resources.go @@ -9,8 +9,8 @@ import ( // CreateNamespaceIfNotExists will create a namespace with the given name if it does not exist yet. // It does not set ownership nor apply extra metadata to the existing namespace. func CreateNamespaceIfNotExists(namespace string) Action { - return func(f *Feature) error { - _, err := cluster.CreateNamespace(context.TODO(), f.Client, namespace) + return func(ctx context.Context, f *Feature) error { + _, err := cluster.CreateNamespace(ctx, f.Client, namespace) return err } diff --git a/pkg/feature/serverless/conditions.go b/pkg/feature/serverless/conditions.go index 86f0561e812..a6dea6117f2 100644 --- a/pkg/feature/serverless/conditions.go +++ b/pkg/feature/serverless/conditions.go @@ -15,11 +15,11 @@ const ( KnativeServingNamespace = "knative-serving" ) -func EnsureServerlessAbsent(f *feature.Feature) error { +func EnsureServerlessAbsent(ctx context.Context, f *feature.Feature) error { list := &unstructured.UnstructuredList{} list.SetGroupVersionKind(gvk.KnativeServing) - if err := f.Client.List(context.TODO(), list, client.InNamespace("")); err != nil { + if err := f.Client.List(ctx, list, client.InNamespace("")); err != nil { return fmt.Errorf("failed to list KnativeServings: %w", err) } @@ -45,8 +45,8 @@ func EnsureServerlessAbsent(f *feature.Feature) error { return fmt.Errorf("existing KNativeServing resource was found; integrating to an existing installation is not supported") } -func EnsureServerlessOperatorInstalled(f *feature.Feature) error { - if err := feature.EnsureOperatorIsInstalled("serverless-operator")(f); err != nil { +func EnsureServerlessOperatorInstalled(ctx context.Context, f *feature.Feature) error { + if err := feature.EnsureOperatorIsInstalled("serverless-operator")(ctx, f); err != nil { return fmt.Errorf("failed to find the pre-requisite KNative Serving Operator subscription, please ensure Serverless Operator is installed. %w", err) } diff --git a/pkg/feature/serverless/loaders.go b/pkg/feature/serverless/loaders.go index 58867b29f99..c0845b226b5 100644 --- a/pkg/feature/serverless/loaders.go +++ b/pkg/feature/serverless/loaders.go @@ -1,6 +1,7 @@ package serverless import ( + "context" "fmt" "strings" @@ -10,7 +11,7 @@ import ( const DefaultCertificateSecretName = "knative-serving-cert" -func ServingDefaultValues(f *feature.Feature) error { +func ServingDefaultValues(_ context.Context, f *feature.Feature) error { certificateSecretName := strings.TrimSpace(f.Spec.Serving.IngressGateway.Certificate.SecretName) if len(certificateSecretName) == 0 { certificateSecretName = DefaultCertificateSecretName @@ -20,11 +21,11 @@ func ServingDefaultValues(f *feature.Feature) error { return nil } -func ServingIngressDomain(f *feature.Feature) error { +func ServingIngressDomain(ctx context.Context, f *feature.Feature) error { domain := strings.TrimSpace(f.Spec.Serving.IngressGateway.Domain) if len(domain) == 0 { var errDomain error - domain, errDomain = cluster.GetDomain(f.Client) + domain, errDomain = cluster.GetDomain(ctx, f.Client) if errDomain != nil { return fmt.Errorf("failed to fetch OpenShift domain to generate certificate for Serverless: %w", errDomain) } diff --git a/pkg/feature/serverless/resources.go b/pkg/feature/serverless/resources.go index bd74bc05ff1..5b9f3d3d0f9 100644 --- a/pkg/feature/serverless/resources.go +++ b/pkg/feature/serverless/resources.go @@ -8,10 +8,10 @@ import ( "github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature" ) -func ServingCertificateResource(f *feature.Feature) error { +func ServingCertificateResource(ctx context.Context, f *feature.Feature) error { switch certType := f.Spec.Serving.IngressGateway.Certificate.Type; certType { case infrav1.SelfSigned: - return cluster.CreateSelfSignedCertificate(context.TODO(), f.Client, + return cluster.CreateSelfSignedCertificate(ctx, f.Client, f.Spec.KnativeCertificateSecret, f.Spec.KnativeIngressDomain, f.Spec.ControlPlane.Namespace, @@ -19,6 +19,6 @@ func ServingCertificateResource(f *feature.Feature) error { case infrav1.Provided: return nil default: - return cluster.PropagateDefaultIngressCertificate(context.TODO(), f.Client, f.Spec.KnativeCertificateSecret, f.Spec.ControlPlane.Namespace) + return cluster.PropagateDefaultIngressCertificate(ctx, f.Client, f.Spec.KnativeCertificateSecret, f.Spec.ControlPlane.Namespace) } } diff --git a/pkg/feature/servicemesh/cleanup.go b/pkg/feature/servicemesh/cleanup.go index e35bebf5be1..da5de8b1951 100644 --- a/pkg/feature/servicemesh/cleanup.go +++ b/pkg/feature/servicemesh/cleanup.go @@ -11,14 +11,14 @@ import ( "github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature" ) -func RemoveExtensionProvider(f *feature.Feature) error { +func RemoveExtensionProvider(ctx context.Context, f *feature.Feature) error { ossmAuthzProvider := fmt.Sprintf("%s-auth-provider", f.Spec.AppNamespace) mesh := f.Spec.ControlPlane smcp := &unstructured.Unstructured{} smcp.SetGroupVersionKind(gvk.ServiceMeshControlPlane) - if err := f.Client.Get(context.TODO(), client.ObjectKey{ + if err := f.Client.Get(ctx, client.ObjectKey{ Namespace: mesh.Namespace, Name: mesh.Name, }, smcp); err != nil { @@ -51,5 +51,5 @@ func RemoveExtensionProvider(f *feature.Feature) error { } } - return f.Client.Update(context.TODO(), smcp) + return f.Client.Update(ctx, smcp) } diff --git a/pkg/feature/servicemesh/conditions.go b/pkg/feature/servicemesh/conditions.go index 482540990bf..942b4070b80 100644 --- a/pkg/feature/servicemesh/conditions.go +++ b/pkg/feature/servicemesh/conditions.go @@ -23,32 +23,32 @@ const ( ) // EnsureAuthNamespaceExists creates a namespace for the Authorization provider and set ownership so it will be garbage collected when the operator is uninstalled. -func EnsureAuthNamespaceExists(f *feature.Feature) error { +func EnsureAuthNamespaceExists(ctx context.Context, f *feature.Feature) error { if resolveNsErr := ResolveAuthNamespace(f); resolveNsErr != nil { return resolveNsErr } - _, err := cluster.CreateNamespace(context.TODO(), f.Client, f.Spec.Auth.Namespace, feature.OwnedBy(f), cluster.WithLabels(labels.ODH.OwnedNamespace, "true")) + _, err := cluster.CreateNamespace(ctx, f.Client, f.Spec.Auth.Namespace, feature.OwnedBy(f), cluster.WithLabels(labels.ODH.OwnedNamespace, "true")) return err } -func EnsureServiceMeshOperatorInstalled(f *feature.Feature) error { - if err := feature.EnsureOperatorIsInstalled("servicemeshoperator")(f); err != nil { +func EnsureServiceMeshOperatorInstalled(ctx context.Context, f *feature.Feature) error { + if err := feature.EnsureOperatorIsInstalled("servicemeshoperator")(ctx, f); err != nil { return fmt.Errorf("failed to find the pre-requisite Service Mesh Operator subscription, please ensure Service Mesh Operator is installed. %w", err) } return nil } -func EnsureServiceMeshInstalled(f *feature.Feature) error { - if err := EnsureServiceMeshOperatorInstalled(f); err != nil { +func EnsureServiceMeshInstalled(ctx context.Context, f *feature.Feature) error { + if err := EnsureServiceMeshOperatorInstalled(ctx, f); err != nil { return err } smcp := f.Spec.ControlPlane.Name smcpNs := f.Spec.ControlPlane.Namespace - if err := WaitForControlPlaneToBeReady(f); err != nil { + if err := WaitForControlPlaneToBeReady(ctx, f); err != nil { f.Log.Error(err, "failed waiting for control plane being ready", "control-plane", smcp, "namespace", smcpNs) return multierror.Append(err, errors.New("service mesh control plane is not ready")).ErrorOrNil() @@ -57,14 +57,14 @@ func EnsureServiceMeshInstalled(f *feature.Feature) error { return nil } -func WaitForControlPlaneToBeReady(f *feature.Feature) error { +func WaitForControlPlaneToBeReady(ctx context.Context, f *feature.Feature) error { smcp := f.Spec.ControlPlane.Name smcpNs := f.Spec.ControlPlane.Namespace f.Log.Info("waiting for control plane components to be ready", "control-plane", smcp, "namespace", smcpNs, "duration (s)", duration.Seconds()) - return wait.PollUntilContextTimeout(context.TODO(), interval, duration, false, func(ctx context.Context) (bool, error) { - ready, err := CheckControlPlaneComponentReadiness(f.Client, smcp, smcpNs) + return wait.PollUntilContextTimeout(ctx, interval, duration, false, func(ctx context.Context) (bool, error) { + ready, err := CheckControlPlaneComponentReadiness(ctx, f.Client, smcp, smcpNs) if ready { f.Log.Info("done waiting for control plane components to be ready", "control-plane", smcp, "namespace", smcpNs) @@ -74,10 +74,10 @@ func WaitForControlPlaneToBeReady(f *feature.Feature) error { }) } -func CheckControlPlaneComponentReadiness(c client.Client, smcpName, smcpNs string) (bool, error) { +func CheckControlPlaneComponentReadiness(ctx context.Context, c client.Client, smcpName, smcpNs string) (bool, error) { smcpObj := &unstructured.Unstructured{} smcpObj.SetGroupVersionKind(gvk.ServiceMeshControlPlane) - err := c.Get(context.TODO(), client.ObjectKey{ + err := c.Get(ctx, client.ObjectKey{ Namespace: smcpNs, Name: smcpName, }, smcpObj) diff --git a/pkg/feature/servicemesh/loaders.go b/pkg/feature/servicemesh/loaders.go index 8d61dc4aae0..0d966e24d79 100644 --- a/pkg/feature/servicemesh/loaders.go +++ b/pkg/feature/servicemesh/loaders.go @@ -1,6 +1,7 @@ package servicemesh import ( + "context" "strings" "github.com/pkg/errors" @@ -9,10 +10,10 @@ import ( "github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature" ) -func ClusterDetails(f *feature.Feature) error { +func ClusterDetails(ctx context.Context, f *feature.Feature) error { data := f.Spec - if domain, err := cluster.GetDomain(f.Client); err == nil { + if domain, err := cluster.GetDomain(ctx, f.Client); err == nil { data.Domain = domain } else { return errors.WithStack(err) diff --git a/pkg/feature/servicemesh/resources.go b/pkg/feature/servicemesh/resources.go index 57f78118251..5b6f6579d28 100644 --- a/pkg/feature/servicemesh/resources.go +++ b/pkg/feature/servicemesh/resources.go @@ -13,7 +13,7 @@ import ( // MeshRefs stores service mesh configuration in the config map, so it can // be easily accessed by other components which rely on this information. -func MeshRefs(f *feature.Feature) error { +func MeshRefs(ctx context.Context, f *feature.Feature) error { meshConfig := f.Spec.ControlPlane namespace := f.Spec.AppNamespace @@ -23,7 +23,7 @@ func MeshRefs(f *feature.Feature) error { } return cluster.CreateOrUpdateConfigMap( - context.TODO(), + ctx, f.Client, &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ @@ -38,7 +38,7 @@ func MeshRefs(f *feature.Feature) error { // AuthRefs stores authorization configuration in the config map, so it can // be easily accessed by other components which rely on this information. -func AuthRefs(f *feature.Feature) error { +func AuthRefs(ctx context.Context, f *feature.Feature) error { audiences := f.Spec.Auth.Audiences appNamespace := f.Spec.AppNamespace authNamespace := f.Spec.Auth.Namespace @@ -57,7 +57,7 @@ func AuthRefs(f *feature.Feature) error { } return cluster.CreateOrUpdateConfigMap( - context.TODO(), + ctx, f.Client, &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/upgrade/uninstallation.go b/pkg/upgrade/uninstallation.go index b4a69164dbb..09cd4946eeb 100644 --- a/pkg/upgrade/uninstallation.go +++ b/pkg/upgrade/uninstallation.go @@ -24,7 +24,7 @@ const ( // OperatorUninstall deletes all the externally generated resources. This includes monitoring resources and applications // installed by KfDef. func OperatorUninstall(ctx context.Context, cli client.Client) error { - platform, err := cluster.GetPlatform(cli) + platform, err := cluster.GetPlatform(ctx, cli) if err != nil { return err } @@ -80,7 +80,7 @@ func OperatorUninstall(ctx context.Context, cli client.Client) error { subsName = "rhods-operator" } if platform != cluster.ManagedRhods { - if err := cluster.DeleteExistingSubscription(cli, operatorNs, subsName); err != nil { + if err := cluster.DeleteExistingSubscription(ctx, cli, operatorNs, subsName); err != nil { return err } } diff --git a/pkg/upgrade/upgrade.go b/pkg/upgrade/upgrade.go index ab2248e5c25..57a9636e953 100644 --- a/pkg/upgrade/upgrade.go +++ b/pkg/upgrade/upgrade.go @@ -267,7 +267,7 @@ func CleanupExistingResource(ctx context.Context, cli client.Client, platform cl multiErr = multierror.Append(multiErr, deleteResources(ctx, cli, &odhDocJPH)) // only apply on RHOAI since ODH has a different way to create this CR by dashboard if platform == cluster.SelfManagedRhods || platform == cluster.ManagedRhods { - if err := unsetOwnerReference(cli, "odh-dashboard-config", dscApplicationsNamespace); err != nil { + if err := unsetOwnerReference(ctx, cli, "odh-dashboard-config", dscApplicationsNamespace); err != nil { return err } } @@ -442,14 +442,14 @@ func removOdhApplicationsCR(ctx context.Context, cli client.Client, gvk schema.G return nil } -func unsetOwnerReference(cli client.Client, instanceName string, applicationNS string) error { +func unsetOwnerReference(ctx context.Context, cli client.Client, instanceName string, applicationNS string) error { crd := &apiextv1.CustomResourceDefinition{} - if err := cli.Get(context.TODO(), client.ObjectKey{Name: "odhdashboardconfigs.opendatahub.io"}, crd); err != nil { + if err := cli.Get(ctx, client.ObjectKey{Name: "odhdashboardconfigs.opendatahub.io"}, crd); err != nil { return client.IgnoreNotFound(err) } odhObject := &unstructured.Unstructured{} odhObject.SetGroupVersionKind(gvk.OdhDashboardConfig) - if err := cli.Get(context.TODO(), client.ObjectKey{ + if err := cli.Get(ctx, client.ObjectKey{ Namespace: applicationNS, Name: instanceName, }, odhObject); err != nil { @@ -458,23 +458,23 @@ func unsetOwnerReference(cli client.Client, instanceName string, applicationNS s if odhObject.GetOwnerReferences() != nil { // set to nil as updates odhObject.SetOwnerReferences(nil) - if err := cli.Update(context.TODO(), odhObject); err != nil { + if err := cli.Update(ctx, odhObject); err != nil { return fmt.Errorf("error unset ownerreference for CR %s : %w", instanceName, err) } } return nil } -func RemoveLabel(cli client.Client, objectName string, labelKey string) error { +func RemoveLabel(ctx context.Context, cli client.Client, objectName string, labelKey string) error { foundNamespace := &corev1.Namespace{} - if err := cli.Get(context.TODO(), client.ObjectKey{Name: objectName}, foundNamespace); err != nil { + if err := cli.Get(ctx, client.ObjectKey{Name: objectName}, foundNamespace); err != nil { if apierrs.IsNotFound(err) { return nil } return fmt.Errorf("could not get %s namespace: %w", objectName, err) } delete(foundNamespace.Labels, labelKey) - if err := cli.Update(context.TODO(), foundNamespace); err != nil { + if err := cli.Update(ctx, foundNamespace); err != nil { return fmt.Errorf("error removing %s from %s : %w", labelKey, objectName, err) } return nil diff --git a/tests/e2e/dsc_cfmap_deletion_test.go b/tests/e2e/dsc_cfmap_deletion_test.go index 48e783fd944..8739621d730 100644 --- a/tests/e2e/dsc_cfmap_deletion_test.go +++ b/tests/e2e/dsc_cfmap_deletion_test.go @@ -1,7 +1,6 @@ package e2e_test import ( - "context" "fmt" "testing" @@ -70,7 +69,7 @@ func (tc *testContext) testOwnedNamespacesAllExist() error { } func removeDeletionConfigMap(tc *testContext) { - _ = tc.kubeClient.CoreV1().ConfigMaps(tc.operatorNamespace).Delete(context.TODO(), "delete-self-managed", metav1.DeleteOptions{}) + _ = tc.kubeClient.CoreV1().ConfigMaps(tc.operatorNamespace).Delete(tc.ctx, "delete-self-managed", metav1.DeleteOptions{}) } func createDeletionConfigMap(tc *testContext, enableDeletion string) error { @@ -85,14 +84,14 @@ func createDeletionConfigMap(tc *testContext, enableDeletion string) error { } configMaps := tc.kubeClient.CoreV1().ConfigMaps(configMap.Namespace) - if _, err := configMaps.Get(context.TODO(), configMap.Name, metav1.GetOptions{}); err != nil { + if _, err := configMaps.Get(tc.ctx, configMap.Name, metav1.GetOptions{}); err != nil { switch { case k8serrors.IsNotFound(err): - if _, err = configMaps.Create(context.TODO(), configMap, metav1.CreateOptions{}); err != nil { + if _, err = configMaps.Create(tc.ctx, configMap, metav1.CreateOptions{}); err != nil { return err } case k8serrors.IsAlreadyExists(err): - if _, err = configMaps.Update(context.TODO(), configMap, metav1.UpdateOptions{}); err != nil { + if _, err = configMaps.Update(tc.ctx, configMap, metav1.UpdateOptions{}); err != nil { return err } default: diff --git a/tests/e2e/dsc_creation_test.go b/tests/e2e/dsc_creation_test.go index 7a129a016e3..ffe4222b3a8 100644 --- a/tests/e2e/dsc_creation_test.go +++ b/tests/e2e/dsc_creation_test.go @@ -105,7 +105,7 @@ func (tc *testContext) testDSCICreation() error { if err != nil { if errors.IsNotFound(err) { nberr := wait.PollUntilContextTimeout(tc.ctx, tc.resourceRetryInterval, tc.resourceCreationTimeout, false, func(ctx context.Context) (bool, error) { - creationErr := tc.customClient.Create(tc.ctx, tc.testDSCI) + creationErr := tc.customClient.Create(ctx, tc.testDSCI) if creationErr != nil { log.Printf("error creating DSCI resource %v: %v, trying again", tc.testDSCI.Name, creationErr) @@ -129,7 +129,7 @@ func waitDSCReady(tc *testContext) error { key := types.NamespacedName{Name: tc.testDsc.Name} dsc := &dsc.DataScienceCluster{} - err := tc.customClient.Get(tc.ctx, key, dsc) + err := tc.customClient.Get(ctx, key, dsc) if err != nil { return false, err } @@ -165,7 +165,7 @@ func (tc *testContext) testDSCCreation() error { if err != nil { if errors.IsNotFound(err) { nberr := wait.PollUntilContextTimeout(tc.ctx, tc.resourceRetryInterval, tc.resourceCreationTimeout, false, func(ctx context.Context) (bool, error) { - creationErr := tc.customClient.Create(tc.ctx, tc.testDsc) + creationErr := tc.customClient.Create(ctx, tc.testDsc) if creationErr != nil { log.Printf("error creating DSC resource %v: %v, trying again", tc.testDsc.Name, creationErr) @@ -283,7 +283,7 @@ func (tc *testContext) testAllApplicationCreation(t *testing.T) error { //nolint func (tc *testContext) testApplicationCreation(component components.ComponentInterface) error { err := wait.PollUntilContextTimeout(tc.ctx, tc.resourceRetryInterval, tc.resourceCreationTimeout, false, func(ctx context.Context) (bool, error) { // TODO: see if checking deployment is a good test, CF does not create deployment - appList, err := tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).List(context.TODO(), metav1.ListOptions{ + appList, err := tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).List(ctx, metav1.ListOptions{ LabelSelector: odhLabelPrefix + component.GetComponentName(), }) if err != nil { @@ -368,7 +368,7 @@ func (tc *testContext) validateDSC() error { func (tc *testContext) testOwnerrefrences() error { // Test any one of the apps if tc.testDsc.Spec.Components.Dashboard.ManagementState == operatorv1.Managed { - appDeployments, err := tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).List(context.TODO(), metav1.ListOptions{ + appDeployments, err := tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).List(tc.ctx, metav1.ListOptions{ LabelSelector: odhLabelPrefix + tc.testDsc.Spec.Components.Dashboard.GetComponentName(), }) if err != nil { @@ -421,7 +421,7 @@ func (tc *testContext) testDefaultCertsAvailable() error { func (tc *testContext) testUpdateComponentReconcile() error { // Test Updating Dashboard Replicas - appDeployments, err := tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).List(context.TODO(), metav1.ListOptions{ + appDeployments, err := tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).List(tc.ctx, metav1.ListOptions{ LabelSelector: odhLabelPrefix + tc.testDsc.Spec.Components.Dashboard.GetComponentName(), }) if err != nil { @@ -440,7 +440,7 @@ func (tc *testContext) testUpdateComponentReconcile() error { }, Status: autoscalingv1.ScaleStatus{}, } - retrievedDep, err := tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).UpdateScale(context.TODO(), testDeployment.Name, patchedReplica, metav1.UpdateOptions{}) + retrievedDep, err := tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).UpdateScale(tc.ctx, testDeployment.Name, patchedReplica, metav1.UpdateOptions{}) if err != nil { return fmt.Errorf("error patching component resources : %w", err) } @@ -450,7 +450,7 @@ func (tc *testContext) testUpdateComponentReconcile() error { // Sleep for 40 seconds to allow the operator to reconcile time.Sleep(4 * tc.resourceRetryInterval) - revertedDep, err := tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).Get(context.TODO(), testDeployment.Name, metav1.GetOptions{}) + revertedDep, err := tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).Get(tc.ctx, testDeployment.Name, metav1.GetOptions{}) if err != nil { return fmt.Errorf("error getting component resource after reconcile: %w", err) } @@ -467,7 +467,7 @@ func (tc *testContext) testUpdateDSCComponentEnabled() error { var dashboardDeploymentName string if tc.testDsc.Spec.Components.Dashboard.ManagementState == operatorv1.Managed { - appDeployments, err := tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).List(context.TODO(), metav1.ListOptions{ + appDeployments, err := tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).List(tc.ctx, metav1.ListOptions{ LabelSelector: odhLabelPrefix + tc.testDsc.Spec.Components.Dashboard.GetComponentName(), }) if err != nil { @@ -494,7 +494,7 @@ func (tc *testContext) testUpdateDSCComponentEnabled() error { tc.testDsc.Spec.Components.Dashboard.ManagementState = operatorv1.Removed // Try to update - err = tc.customClient.Update(context.TODO(), tc.testDsc) + err = tc.customClient.Update(tc.ctx, tc.testDsc) // Return err itself here (not wrapped inside another error) // so that RetryOnConflict can identify it correctly. if err != nil { @@ -509,7 +509,7 @@ func (tc *testContext) testUpdateDSCComponentEnabled() error { // Sleep for 40 seconds to allow the operator to reconcile time.Sleep(4 * tc.resourceRetryInterval) - _, err = tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).Get(context.TODO(), dashboardDeploymentName, metav1.GetOptions{}) + _, err = tc.kubeClient.AppsV1().Deployments(tc.applicationsNamespace).Get(tc.ctx, dashboardDeploymentName, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { return nil // correct result: should not find deployment after we disable it already diff --git a/tests/e2e/helper_test.go b/tests/e2e/helper_test.go index 55738c619ed..8813459df2e 100644 --- a/tests/e2e/helper_test.go +++ b/tests/e2e/helper_test.go @@ -45,7 +45,7 @@ const ( func (tc *testContext) waitForControllerDeployment(name string, replicas int32) error { err := wait.PollUntilContextTimeout(tc.ctx, tc.resourceRetryInterval, tc.resourceCreationTimeout, false, func(ctx context.Context) (bool, error) { - controllerDeployment, err := tc.kubeClient.AppsV1().Deployments(tc.operatorNamespace).Get(tc.ctx, name, metav1.GetOptions{}) + controllerDeployment, err := tc.kubeClient.AppsV1().Deployments(tc.operatorNamespace).Get(ctx, name, metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { return false, nil @@ -194,7 +194,7 @@ func (tc *testContext) validateCRD(crdName string) error { Name: crdName, } err := wait.PollUntilContextTimeout(tc.ctx, tc.resourceRetryInterval, tc.resourceCreationTimeout, false, func(ctx context.Context) (bool, error) { - err := tc.customClient.Get(context.TODO(), obj, crd) + err := tc.customClient.Get(ctx, obj, crd) if err != nil { if errors.IsNotFound(err) { return false, nil @@ -223,7 +223,7 @@ func (tc *testContext) wait(isReady func(ctx context.Context) (bool, error)) err return wait.PollUntilContextTimeout(tc.ctx, tc.resourceRetryInterval, tc.resourceCreationTimeout, true, isReady) } -func getCSV(cli client.Client, name string, namespace string) (*ofapi.ClusterServiceVersion, error) { +func getCSV(ctx context.Context, cli client.Client, name string, namespace string) (*ofapi.ClusterServiceVersion, error) { isMatched := func(csv *ofapi.ClusterServiceVersion, name string) bool { return strings.Contains(csv.ObjectMeta.Name, name) } @@ -232,7 +232,7 @@ func getCSV(cli client.Client, name string, namespace string) (*ofapi.ClusterSer Namespace: namespace, } csvList := &ofapi.ClusterServiceVersionList{} - err := cli.List(context.TODO(), csvList, opt) + err := cli.List(ctx, csvList, opt) if err != nil { return nil, err } @@ -283,7 +283,7 @@ func waitCSV(tc *testContext, name string, ns string) error { timeout := tc.resourceCreationTimeout * 3 // just empirical value isReady := func(ctx context.Context) (bool, error) { - csv, err := getCSV(tc.customClient, name, ns) + csv, err := getCSV(ctx, tc.customClient, name, ns) if errors.IsNotFound(err) { return false, nil } diff --git a/tests/envtestutil/cleaner.go b/tests/envtestutil/cleaner.go index 366f4b3e10a..0d57699f224 100644 --- a/tests/envtestutil/cleaner.go +++ b/tests/envtestutil/cleaner.go @@ -41,10 +41,10 @@ func CreateCleaner(c client.Client, config *rest.Config, timeout, interval time. } } -func (c *Cleaner) DeleteAll(objects ...client.Object) { +func (c *Cleaner) DeleteAll(ctx context.Context, objects ...client.Object) { for _, obj := range objects { obj := obj - Expect(client.IgnoreNotFound(c.client.Delete(context.Background(), obj))).Should(Succeed()) + Expect(client.IgnoreNotFound(c.client.Delete(ctx, obj))).Should(Succeed()) if ns, ok := obj.(*corev1.Namespace); ok { // Normally the kube-controller-manager would handle finalization @@ -88,14 +88,14 @@ func (c *Cleaner) DeleteAll(objects ...client.Object) { for _, gvk := range namespacedGVKs { var u unstructured.Unstructured u.SetGroupVersionKind(gvk) - err := c.client.DeleteAllOf(context.Background(), &u, client.InNamespace(ns.Name)) + err := c.client.DeleteAllOf(ctx, &u, client.InNamespace(ns.Name)) Expect(client.IgnoreNotFound(ignoreMethodNotAllowed(err))).ShouldNot(HaveOccurred()) } Eventually(func() error { key := client.ObjectKeyFromObject(ns) - if err := c.client.Get(context.Background(), key, ns); err != nil { + if err := c.client.Get(ctx, key, ns); err != nil { return client.IgnoreNotFound(err) } // remove `kubernetes` finalizer @@ -110,7 +110,7 @@ func (c *Cleaner) DeleteAll(objects ...client.Object) { // We have to use the k8s.io/client-go library here to expose // ability to patch the /finalize subresource on the namespace - _, err = c.clientset.CoreV1().Namespaces().Finalize(context.Background(), ns, metav1.UpdateOptions{}) + _, err = c.clientset.CoreV1().Namespaces().Finalize(ctx, ns, metav1.UpdateOptions{}) return err }). @@ -121,7 +121,7 @@ func (c *Cleaner) DeleteAll(objects ...client.Object) { Eventually(func() metav1.StatusReason { key := client.ObjectKeyFromObject(obj) - if err := c.client.Get(context.Background(), key, obj); err != nil { + if err := c.client.Get(ctx, key, obj); err != nil { return apierrors.ReasonForError(err) } diff --git a/tests/integration/features/cleanup_int_test.go b/tests/integration/features/cleanup_int_test.go index ee7cfe140b9..0db55d0a5a9 100644 --- a/tests/integration/features/cleanup_int_test.go +++ b/tests/integration/features/cleanup_int_test.go @@ -53,23 +53,25 @@ var _ = Describe("feature cleanup", func() { }) - It("should successfully create resource and associated feature tracker", func() { + It("should successfully create resource and associated feature tracker", func(ctx context.Context) { // when - Expect(featuresHandler.Apply()).Should(Succeed()) + Expect(featuresHandler.Apply(ctx)).Should(Succeed()) // then Eventually(createdSecretHasOwnerReferenceToOwningFeature(namespace, secretName)). + WithContext(ctx). WithTimeout(fixtures.Timeout). WithPolling(fixtures.Interval). Should(Succeed()) }) - It("should remove feature tracker on clean-up", func() { + It("should remove feature tracker on clean-up", func(ctx context.Context) { // when - Expect(featuresHandler.Delete()).To(Succeed()) + Expect(featuresHandler.Delete(ctx)).To(Succeed()) // then Eventually(createdSecretHasOwnerReferenceToOwningFeature(namespace, secretName)). + WithContext(ctx). WithTimeout(fixtures.Timeout). WithPolling(fixtures.Interval). Should(WithTransform(errors.IsNotFound, BeTrue())) @@ -79,11 +81,11 @@ var _ = Describe("feature cleanup", func() { }) -func createdSecretHasOwnerReferenceToOwningFeature(namespace, secretName string) func() error { - return func() error { +func createdSecretHasOwnerReferenceToOwningFeature(namespace, secretName string) func(context.Context) error { + return func(ctx context.Context) error { secret, err := envTestClientset.CoreV1(). Secrets(namespace). - Get(context.TODO(), secretName, metav1.GetOptions{}) + Get(ctx, secretName, metav1.GetOptions{}) if err != nil { return err @@ -104,7 +106,7 @@ func createdSecretHasOwnerReferenceToOwningFeature(namespace, secretName string) } tracker := &featurev1.FeatureTracker{} - return envTestClient.Get(context.Background(), client.ObjectKey{ + return envTestClient.Get(ctx, client.ObjectKey{ Name: trackerName, }, tracker) } diff --git a/tests/integration/features/features_suite_int_test.go b/tests/integration/features/features_suite_int_test.go index be0396d6705..a55d3324620 100644 --- a/tests/integration/features/features_suite_int_test.go +++ b/tests/integration/features/features_suite_int_test.go @@ -1,7 +1,6 @@ package features_test import ( - "context" "fmt" "path/filepath" "testing" @@ -28,8 +27,6 @@ var ( envTestClient client.Client envTestClientset *kubernetes.Clientset envTest *envtest.Environment - ctx context.Context - cancel context.CancelFunc ) var testScheme = runtime.NewScheme() @@ -40,9 +37,6 @@ func TestFeaturesIntegration(t *testing.T) { } var _ = BeforeSuite(func() { - - ctx, cancel = context.WithCancel(context.TODO()) - opts := zap.Options{Development: true} logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseFlagOptions(&opts))) @@ -90,6 +84,5 @@ var _ = BeforeSuite(func() { var _ = AfterSuite(func() { By("Tearing down the test environment") - cancel() Expect(envTest.Stop()).To(Succeed()) }) diff --git a/tests/integration/features/fixtures/cluster_test_fixtures.go b/tests/integration/features/fixtures/cluster_test_fixtures.go index cf1e153f7f6..bfc7e2c1079 100644 --- a/tests/integration/features/fixtures/cluster_test_fixtures.go +++ b/tests/integration/features/fixtures/cluster_test_fixtures.go @@ -17,28 +17,28 @@ import ( "github.com/opendatahub-io/opendatahub-operator/v2/pkg/feature" ) -func CreateSubscription(client client.Client, namespace, subscriptionYaml string) error { +func CreateSubscription(ctx context.Context, client client.Client, namespace, subscriptionYaml string) error { subscription := &ofapiv1alpha1.Subscription{} if err := yaml.Unmarshal([]byte(subscriptionYaml), subscription); err != nil { return err } ns := NewNamespace(namespace) - if err := CreateOrUpdateNamespace(client, ns); err != nil { + if err := CreateOrUpdateNamespace(ctx, client, ns); err != nil { return err } - return createOrUpdateSubscription(client, subscription) + return createOrUpdateSubscription(ctx, client, subscription) } -func CreateOrUpdateNamespace(client client.Client, ns *v1.Namespace) error { - _, err := controllerutil.CreateOrUpdate(context.Background(), client, ns, func() error { +func CreateOrUpdateNamespace(ctx context.Context, client client.Client, ns *v1.Namespace) error { + _, err := controllerutil.CreateOrUpdate(ctx, client, ns, func() error { return nil }) return err } -func createOrUpdateSubscription(client client.Client, subscription *ofapiv1alpha1.Subscription) error { - _, err := controllerutil.CreateOrUpdate(context.Background(), client, subscription, func() error { +func createOrUpdateSubscription(ctx context.Context, client client.Client, subscription *ofapiv1alpha1.Subscription) error { + _, err := controllerutil.CreateOrUpdate(ctx, client, subscription, func() error { return nil }) return err @@ -52,24 +52,24 @@ func NewNamespace(name string) *v1.Namespace { } } -func GetNamespace(client client.Client, namespace string) (*v1.Namespace, error) { +func GetNamespace(ctx context.Context, client client.Client, namespace string) (*v1.Namespace, error) { ns := NewNamespace(namespace) - err := client.Get(context.Background(), types.NamespacedName{Name: namespace}, ns) + err := client.Get(ctx, types.NamespacedName{Name: namespace}, ns) return ns, err } -func GetService(client client.Client, namespace, name string) (*v1.Service, error) { +func GetService(ctx context.Context, client client.Client, namespace, name string) (*v1.Service, error) { svc := &v1.Service{} - err := client.Get(context.Background(), types.NamespacedName{ + err := client.Get(ctx, types.NamespacedName{ Name: name, Namespace: namespace, }, svc) return svc, err } -func CreateSecret(name, namespace string) func(f *feature.Feature) error { - return func(f *feature.Feature) error { +func CreateSecret(name, namespace string) func(ctx context.Context, f *feature.Feature) error { + return func(ctx context.Context, f *feature.Feature) error { secret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -83,13 +83,13 @@ func CreateSecret(name, namespace string) func(f *feature.Feature) error { }, } - return f.Client.Create(context.TODO(), secret) + return f.Client.Create(ctx, secret) } } -func GetFeatureTracker(cli client.Client, appNamespace, featureName string) (*featurev1.FeatureTracker, error) { +func GetFeatureTracker(ctx context.Context, cli client.Client, appNamespace, featureName string) (*featurev1.FeatureTracker, error) { tracker := featurev1.NewFeatureTracker(featureName, appNamespace) - err := cli.Get(context.Background(), client.ObjectKey{ + err := cli.Get(ctx, client.ObjectKey{ Name: tracker.Name, }, tracker) diff --git a/tests/integration/features/manifests_int_test.go b/tests/integration/features/manifests_int_test.go index 4b148c27d25..139610b6032 100644 --- a/tests/integration/features/manifests_int_test.go +++ b/tests/integration/features/manifests_int_test.go @@ -25,23 +25,23 @@ var _ = Describe("Manifest sources", func() { namespace *corev1.Namespace ) - BeforeEach(func() { + BeforeEach(func(ctx context.Context) { objectCleaner = envtestutil.CreateCleaner(envTestClient, envTest.Config, fixtures.Timeout, fixtures.Interval) nsName := envtestutil.AppendRandomNameTo("smcp-ns") var err error - namespace, err = cluster.CreateNamespace(context.Background(), envTestClient, nsName) + namespace, err = cluster.CreateNamespace(ctx, envTestClient, nsName) Expect(err).ToNot(HaveOccurred()) dsci = fixtures.NewDSCInitialization(nsName) dsci.Spec.ServiceMesh.ControlPlane.Namespace = namespace.Name }) - AfterEach(func() { - objectCleaner.DeleteAll(namespace) + AfterEach(func(ctx context.Context) { + objectCleaner.DeleteAll(ctx, namespace) }) - It("should be able to process an embedded YAML file", func() { + It("should be able to process an embedded YAML file", func(ctx context.Context) { // given featuresHandler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { createNamespaceErr := feature.CreateFeature("create-namespace"). @@ -57,16 +57,16 @@ var _ = Describe("Manifest sources", func() { }) // when - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) // then - embeddedNs, err := fixtures.GetNamespace(envTestClient, "embedded-test-ns") - defer objectCleaner.DeleteAll(embeddedNs) + embeddedNs, err := fixtures.GetNamespace(ctx, envTestClient, "embedded-test-ns") + defer objectCleaner.DeleteAll(ctx, embeddedNs) Expect(err).ToNot(HaveOccurred()) Expect(embeddedNs.Name).To(Equal("embedded-test-ns")) }) - It("should be able to process an embedded template file", func() { + It("should be able to process an embedded template file", func(ctx context.Context) { // given featuresHandler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { createServiceErr := feature.CreateFeature("create-local-gw-svc"). @@ -82,10 +82,10 @@ var _ = Describe("Manifest sources", func() { }) // when - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) // then - service, err := fixtures.GetService(envTestClient, namespace.Name, "knative-local-gateway") + service, err := fixtures.GetService(ctx, envTestClient, namespace.Name, "knative-local-gateway") Expect(err).ToNot(HaveOccurred()) Expect(service.Name).To(Equal("knative-local-gateway")) }) @@ -95,7 +95,7 @@ kind: Namespace metadata: name: real-file-test-ns` - It("should source manifests from a specified temporary directory within the file system", func() { + It("should source manifests from a specified temporary directory within the file system", func(ctx context.Context) { // given tempDir := GinkgoT().TempDir() @@ -115,11 +115,11 @@ metadata: }) // when - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) // then - realNs, err := fixtures.GetNamespace(envTestClient, "real-file-test-ns") - defer objectCleaner.DeleteAll(realNs) + realNs, err := fixtures.GetNamespace(ctx, envTestClient, "real-file-test-ns") + defer objectCleaner.DeleteAll(ctx, realNs) Expect(err).ToNot(HaveOccurred()) Expect(realNs.Name).To(Equal("real-file-test-ns")) }) diff --git a/tests/integration/features/preconditions_int_test.go b/tests/integration/features/preconditions_int_test.go index 32d2942c0c3..323b5a1d5f1 100644 --- a/tests/integration/features/preconditions_int_test.go +++ b/tests/integration/features/preconditions_int_test.go @@ -34,11 +34,11 @@ var _ = Describe("feature preconditions", func() { dsci = fixtures.NewDSCInitialization(namespace) }) - It("should create namespace if it does not exist", func() { + It("should create namespace if it does not exist", func(ctx context.Context) { // given - _, err := fixtures.GetNamespace(envTestClient, namespace) + _, err := fixtures.GetNamespace(ctx, envTestClient, namespace) Expect(errors.IsNotFound(err)).To(BeTrue()) - defer objectCleaner.DeleteAll(&v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}) + defer objectCleaner.DeleteAll(ctx, &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}) // when featuresHandler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { @@ -54,11 +54,11 @@ var _ = Describe("feature preconditions", func() { }) // then - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) // and Eventually(func() error { - _, err := fixtures.GetNamespace(envTestClient, namespace) + _, err := fixtures.GetNamespace(ctx, envTestClient, namespace) return err }). WithTimeout(fixtures.Timeout). @@ -66,16 +66,16 @@ var _ = Describe("feature preconditions", func() { Should(Succeed()) }) - It("should not try to create namespace if it does already exist", func() { + It("should not try to create namespace if it does already exist", func(ctx context.Context) { // given ns := fixtures.NewNamespace(namespace) - Expect(envTestClient.Create(context.Background(), ns)).To(Succeed()) + Expect(envTestClient.Create(ctx, ns)).To(Succeed()) Eventually(func() error { - _, err := fixtures.GetNamespace(envTestClient, namespace) + _, err := fixtures.GetNamespace(ctx, envTestClient, namespace) return err }).WithTimeout(fixtures.Timeout).WithPolling(fixtures.Interval).Should(Succeed()) // wait for ns to actually get created - defer objectCleaner.DeleteAll(ns) + defer objectCleaner.DeleteAll(ctx, ns) // when featuresHandler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { @@ -91,7 +91,7 @@ var _ = Describe("feature preconditions", func() { }) // then - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) }) diff --git a/tests/integration/features/resources_int_test.go b/tests/integration/features/resources_int_test.go index d69bad77c7c..961d4c458e6 100644 --- a/tests/integration/features/resources_int_test.go +++ b/tests/integration/features/resources_int_test.go @@ -27,14 +27,14 @@ var _ = Describe("Applying and updating resources", func() { dummyAnnotation string ) - BeforeEach(func() { + BeforeEach(func(ctx context.Context) { objectCleaner = envtestutil.CreateCleaner(envTestClient, envTest.Config, fixtures.Timeout, fixtures.Interval) testNamespace = "test-namespace" dummyAnnotation = "fake-anno" var err error - namespace, err = cluster.CreateNamespace(context.Background(), envTestClient, testNamespace) + namespace, err = cluster.CreateNamespace(ctx, envTestClient, testNamespace) Expect(err).ToNot(HaveOccurred()) dsci = fixtures.NewDSCInitialization(testNamespace) @@ -42,67 +42,67 @@ var _ = Describe("Applying and updating resources", func() { }) When("a feature is managed", func() { - It("should reconcile the object to its managed state", func() { + It("should reconcile the object to its managed state", func(ctx context.Context) { // given managed feature - featuresHandler := createAndApplyFeature(dsci, true, "create-local-gw-svc", "local-gateway-svc.tmpl.yaml") + featuresHandler := createAndApplyFeature(ctx, dsci, true, "create-local-gw-svc", "local-gateway-svc.tmpl.yaml") // expect created svc to have managed annotation - service := getServiceAndExpectAnnotations(envTestClient, testNamespace, "knative-local-gateway", map[string]string{ + service := getServiceAndExpectAnnotations(ctx, envTestClient, testNamespace, "knative-local-gateway", map[string]string{ "example-annotation": "", annotations.ManagedByODHOperator: "true", }) // modify managed service - modifyAndExpectUpdate(envTestClient, service, "example-annotation", dummyAnnotation) + modifyAndExpectUpdate(ctx, envTestClient, service, "example-annotation", dummyAnnotation) // expect that modification is reconciled away - Expect(featuresHandler.Apply()).To(Succeed()) - verifyAnnotation(envTestClient, testNamespace, service.Name, "example-annotation", "") + Expect(featuresHandler.Apply(ctx)).To(Succeed()) + verifyAnnotation(ctx, envTestClient, testNamespace, service.Name, "example-annotation", "") }) }) When("a feature is unmanaged", func() { - It("should not reconcile the object", func() { + It("should not reconcile the object", func(ctx context.Context) { // given unmanaged feature - featuresHandler := createAndApplyFeature(dsci, false, "create-local-gw-svc", "local-gateway-svc.tmpl.yaml") + featuresHandler := createAndApplyFeature(ctx, dsci, false, "create-local-gw-svc", "local-gateway-svc.tmpl.yaml") // modify unmanaged service object - service, err := fixtures.GetService(envTestClient, testNamespace, "knative-local-gateway") + service, err := fixtures.GetService(ctx, envTestClient, testNamespace, "knative-local-gateway") Expect(err).ToNot(HaveOccurred()) - modifyAndExpectUpdate(envTestClient, service, "example-annotation", dummyAnnotation) + modifyAndExpectUpdate(ctx, envTestClient, service, "example-annotation", dummyAnnotation) // expect modification to remain after "reconcile" - Expect(featuresHandler.Apply()).To(Succeed()) - verifyAnnotation(envTestClient, testNamespace, service.Name, "example-annotation", dummyAnnotation) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) + verifyAnnotation(ctx, envTestClient, testNamespace, service.Name, "example-annotation", dummyAnnotation) }) }) When("a feature is unmanaged but the object is marked as managed", func() { - It("should reconcile this object", func() { + It("should reconcile this object", func(ctx context.Context) { // given unmanaged feature but object marked with managed annotation - featuresHandler := createAndApplyFeature(dsci, false, "create-managed-svc", "managed-svc.yaml") + featuresHandler := createAndApplyFeature(ctx, dsci, false, "create-managed-svc", "managed-svc.yaml") // expect service to have managed annotation - service := getServiceAndExpectAnnotations(envTestClient, testNamespace, "managed-svc", map[string]string{ + service := getServiceAndExpectAnnotations(ctx, envTestClient, testNamespace, "managed-svc", map[string]string{ "example-annotation": "", annotations.ManagedByODHOperator: "true", }) // modify managed service - modifyAndExpectUpdate(envTestClient, service, "example-annotation", dummyAnnotation) + modifyAndExpectUpdate(ctx, envTestClient, service, "example-annotation", dummyAnnotation) // expect that modification is reconciled away - Expect(featuresHandler.Apply()).To(Succeed()) - verifyAnnotation(envTestClient, testNamespace, service.Name, "example-annotation", "") + Expect(featuresHandler.Apply(ctx)).To(Succeed()) + verifyAnnotation(ctx, envTestClient, testNamespace, service.Name, "example-annotation", "") }) }) - AfterEach(func() { - objectCleaner.DeleteAll(namespace) + AfterEach(func(ctx context.Context) { + objectCleaner.DeleteAll(ctx, namespace) }) }) -func createAndApplyFeature(dsci *dsciv1.DSCInitialization, managed bool, featureName, yamlFile string) *feature.FeaturesHandler { +func createAndApplyFeature(ctx context.Context, dsci *dsciv1.DSCInitialization, managed bool, featureName, yamlFile string) *feature.FeaturesHandler { featuresHandler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { creator := feature.CreateFeature(featureName). For(handler). @@ -114,12 +114,12 @@ func createAndApplyFeature(dsci *dsciv1.DSCInitialization, managed bool, feature } return creator.Load() }) - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) return featuresHandler } -func getServiceAndExpectAnnotations(testClient client.Client, namespace, serviceName string, annotations map[string]string) *v1.Service { - service, err := fixtures.GetService(testClient, namespace, serviceName) +func getServiceAndExpectAnnotations(ctx context.Context, testClient client.Client, namespace, serviceName string, annotations map[string]string) *v1.Service { + service, err := fixtures.GetService(ctx, testClient, namespace, serviceName) Expect(err).ToNot(HaveOccurred()) for key, val := range annotations { Expect(service.Annotations[key]).To(Equal(val)) @@ -127,16 +127,16 @@ func getServiceAndExpectAnnotations(testClient client.Client, namespace, service return service } -func modifyAndExpectUpdate(client client.Client, service *v1.Service, annotationKey, newValue string) { +func modifyAndExpectUpdate(ctx context.Context, client client.Client, service *v1.Service, annotationKey, newValue string) { if service.Annotations == nil { service.Annotations = make(map[string]string) } service.Annotations[annotationKey] = newValue - Expect(client.Update(context.Background(), service)).To(Succeed()) + Expect(client.Update(ctx, service)).To(Succeed()) } -func verifyAnnotation(client client.Client, namespace, serviceName, annotationKey, expectedValue string) { - updatedService, err := fixtures.GetService(client, namespace, serviceName) +func verifyAnnotation(ctx context.Context, client client.Client, namespace, serviceName, annotationKey, expectedValue string) { + updatedService, err := fixtures.GetService(ctx, client, namespace, serviceName) Expect(err).ToNot(HaveOccurred()) Expect(updatedService.Annotations[annotationKey]).To(Equal(expectedValue)) } diff --git a/tests/integration/features/serverless_feature_test.go b/tests/integration/features/serverless_feature_test.go index 32690e2d0b6..91e2655dfb9 100644 --- a/tests/integration/features/serverless_feature_test.go +++ b/tests/integration/features/serverless_feature_test.go @@ -46,7 +46,7 @@ var _ = Describe("Serverless feature", func() { When("operator is not installed", func() { - It("should fail on precondition check", func() { + It("should fail on precondition check", func(ctx context.Context) { // given featuresHandler := feature.ComponentFeaturesHandler(kserveComponent.GetComponentName(), &dsci.Spec, func(handler *feature.FeaturesHandler) error { verificationFeatureErr := feature.CreateFeature("no-serverless-operator-check"). @@ -61,7 +61,7 @@ var _ = Describe("Serverless feature", func() { }) // when - applyErr := featuresHandler.Apply() + applyErr := featuresHandler.Apply(ctx) // then Expect(applyErr).To(MatchError(ContainSubstring("failed to find the pre-requisite operator subscription \"serverless-operator\""))) @@ -72,8 +72,8 @@ var _ = Describe("Serverless feature", func() { var knativeServingCrdObj *apiextensionsv1.CustomResourceDefinition - BeforeEach(func() { - err := fixtures.CreateSubscription(envTestClient, "openshift-serverless", fixtures.KnativeServingSubscription) + BeforeEach(func(ctx context.Context) { + err := fixtures.CreateSubscription(ctx, envTestClient, "openshift-serverless", fixtures.KnativeServingSubscription) Expect(err).ToNot(HaveOccurred()) // Create KNativeServing the CRD @@ -81,19 +81,19 @@ var _ = Describe("Serverless feature", func() { Expect(yaml.Unmarshal([]byte(fixtures.KnativeServingCrd), knativeServingCrdObj)).To(Succeed()) c, err := client.New(envTest.Config, client.Options{}) Expect(err).ToNot(HaveOccurred()) - Expect(c.Create(context.TODO(), knativeServingCrdObj)).To(Succeed()) + Expect(c.Create(ctx, knativeServingCrdObj)).To(Succeed()) crdOptions := envtest.CRDInstallOptions{PollInterval: fixtures.Interval, MaxTime: fixtures.Timeout} err = envtest.WaitForCRDs(envTest.Config, []*apiextensionsv1.CustomResourceDefinition{knativeServingCrdObj}, crdOptions) Expect(err).ToNot(HaveOccurred()) }) - AfterEach(func() { + AfterEach(func(ctx context.Context) { // Delete KNativeServing CRD - objectCleaner.DeleteAll(knativeServingCrdObj) + objectCleaner.DeleteAll(ctx, knativeServingCrdObj) }) - It("should succeed checking operator installation using precondition", func() { + It("should succeed checking operator installation using precondition", func(ctx context.Context) { // when featuresHandler := feature.ComponentFeaturesHandler(kserveComponent.GetComponentName(), &dsci.Spec, func(handler *feature.FeaturesHandler) error { verificationFeatureErr := feature.CreateFeature("serverless-operator-check"). @@ -108,10 +108,10 @@ var _ = Describe("Serverless feature", func() { }) // then - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) }) - It("should succeed if serving is not installed for KNative serving precondition", func() { + It("should succeed if serving is not installed for KNative serving precondition", func(ctx context.Context) { // when featuresHandler := feature.ComponentFeaturesHandler(kserveComponent.GetComponentName(), &dsci.Spec, func(handler *feature.FeaturesHandler) error { verificationFeatureErr := feature.CreateFeature("no-serving-installed-yet"). @@ -126,20 +126,20 @@ var _ = Describe("Serverless feature", func() { }) // then - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) }) - It("should fail if serving is already installed for KNative serving precondition", func() { + It("should fail if serving is already installed for KNative serving precondition", func(ctx context.Context) { // given ns := envtestutil.AppendRandomNameTo(fixtures.TestNamespacePrefix) nsResource := fixtures.NewNamespace(ns) - Expect(envTestClient.Create(context.TODO(), nsResource)).To(Succeed()) - defer objectCleaner.DeleteAll(nsResource) + Expect(envTestClient.Create(ctx, nsResource)).To(Succeed()) + defer objectCleaner.DeleteAll(ctx, nsResource) knativeServing := &unstructured.Unstructured{} Expect(yaml.Unmarshal([]byte(fixtures.KnativeServingInstance), knativeServing)).To(Succeed()) knativeServing.SetNamespace(nsResource.Name) - Expect(envTestClient.Create(context.TODO(), knativeServing)).To(Succeed()) + Expect(envTestClient.Create(ctx, knativeServing)).To(Succeed()) // when featuresHandler := feature.ComponentFeaturesHandler(kserveComponent.GetComponentName(), &dsci.Spec, func(handler *feature.FeaturesHandler) error { @@ -155,7 +155,7 @@ var _ = Describe("Serverless feature", func() { }) // then - Expect(featuresHandler.Apply()).ToNot(Succeed()) + Expect(featuresHandler.Apply(ctx)).ToNot(Succeed()) }) }) @@ -180,37 +180,37 @@ var _ = Describe("Serverless feature", func() { Context("ingress gateway TLS secret name", func() { - It("should set default value when value is empty in the DSCI", func() { + It("should set default value when value is empty in the DSCI", func(ctx context.Context) { // Default value is blank -> testFeature.Spec.Serving.IngressGateway.Certificate.SecretName = "" - Expect(serverless.ServingDefaultValues(testFeature)).To(Succeed()) + Expect(serverless.ServingDefaultValues(ctx, testFeature)).To(Succeed()) Expect(testFeature.Spec.KnativeCertificateSecret).To(Equal(serverless.DefaultCertificateSecretName)) }) - It("should use user value when set in the DSCI", func() { + It("should use user value when set in the DSCI", func(ctx context.Context) { testFeature.Spec.Serving.IngressGateway.Certificate.SecretName = "fooBar" - Expect(serverless.ServingDefaultValues(testFeature)).To(Succeed()) + Expect(serverless.ServingDefaultValues(ctx, testFeature)).To(Succeed()) Expect(testFeature.Spec.KnativeCertificateSecret).To(Equal("fooBar")) }) }) Context("ingress domain name suffix", func() { - It("should use OpenShift ingress domain when value is empty in the DSCI", func() { + It("should use OpenShift ingress domain when value is empty in the DSCI", func(ctx context.Context) { // Create KNativeServing the CRD osIngressResource := &unstructured.Unstructured{} Expect(yaml.Unmarshal([]byte(fixtures.OpenshiftClusterIngress), osIngressResource)).ToNot(HaveOccurred()) c, err := client.New(envTest.Config, client.Options{}) Expect(err).ToNot(HaveOccurred()) - Expect(c.Create(context.TODO(), osIngressResource)).To(Succeed()) + Expect(c.Create(ctx, osIngressResource)).To(Succeed()) // Default value is blank -> testFeature.Spec.Serving.IngressGateway.Domain = "" - Expect(serverless.ServingIngressDomain(testFeature)).To(Succeed()) + Expect(serverless.ServingIngressDomain(ctx, testFeature)).To(Succeed()) Expect(testFeature.Spec.KnativeIngressDomain).To(Equal("*.foo.io")) }) - It("should use user value when set in the DSCI", func() { + It("should use user value when set in the DSCI", func(ctx context.Context) { testFeature.Spec.Serving.IngressGateway.Domain = fixtures.TestDomainFooCom - Expect(serverless.ServingIngressDomain(testFeature)).To(Succeed()) + Expect(serverless.ServingIngressDomain(ctx, testFeature)).To(Succeed()) Expect(testFeature.Spec.KnativeIngressDomain).To(Equal(fixtures.TestDomainFooCom)) }) }) @@ -222,19 +222,19 @@ var _ = Describe("Serverless feature", func() { namespace *corev1.Namespace ) - BeforeEach(func() { + BeforeEach(func(ctx context.Context) { ns := envtestutil.AppendRandomNameTo(fixtures.TestNamespacePrefix) namespace = fixtures.NewNamespace(ns) - Expect(envTestClient.Create(context.TODO(), namespace)).To(Succeed()) + Expect(envTestClient.Create(ctx, namespace)).To(Succeed()) dsci.Spec.ServiceMesh.ControlPlane.Namespace = ns }) - AfterEach(func() { - objectCleaner.DeleteAll(namespace) + AfterEach(func(ctx context.Context) { + objectCleaner.DeleteAll(ctx, namespace) }) - It("should create a TLS secret if certificate is SelfSigned", func() { + It("should create a TLS secret if certificate is SelfSigned", func(ctx context.Context) { // given kserveComponent.Serving.IngressGateway.Certificate.Type = infrav1.SelfSigned kserveComponent.Serving.IngressGateway.Domain = fixtures.TestDomainFooCom @@ -257,11 +257,11 @@ var _ = Describe("Serverless feature", func() { }) // when - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) // then Eventually(func() error { - secret, err := envTestClientset.CoreV1().Secrets(namespace.Name).Get(context.TODO(), serverless.DefaultCertificateSecretName, metav1.GetOptions{}) + secret, err := envTestClientset.CoreV1().Secrets(namespace.Name).Get(ctx, serverless.DefaultCertificateSecretName, metav1.GetOptions{}) if err != nil { return err } @@ -274,7 +274,7 @@ var _ = Describe("Serverless feature", func() { }).WithTimeout(fixtures.Timeout).WithPolling(fixtures.Interval).Should(Succeed()) }) - It("should not create any TLS secret if certificate is user provided", func() { + It("should not create any TLS secret if certificate is user provided", func(ctx context.Context) { // given kserveComponent.Serving.IngressGateway.Certificate.Type = infrav1.Provided kserveComponent.Serving.IngressGateway.Domain = fixtures.TestDomainFooCom @@ -296,11 +296,11 @@ var _ = Describe("Serverless feature", func() { }) // when - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) // then Consistently(func() error { - list, err := envTestClientset.CoreV1().Secrets(namespace.Name).List(context.TODO(), metav1.ListOptions{}) + list, err := envTestClientset.CoreV1().Secrets(namespace.Name).List(ctx, metav1.ListOptions{}) if err != nil || len(list.Items) != 0 { return fmt.Errorf("list len: %d, error: %w", len(list.Items), err) } diff --git a/tests/integration/features/servicemesh_feature_test.go b/tests/integration/features/servicemesh_feature_test.go index 92a9d3f7701..25ff95abccb 100644 --- a/tests/integration/features/servicemesh_feature_test.go +++ b/tests/integration/features/servicemesh_feature_test.go @@ -48,7 +48,7 @@ var _ = Describe("Service Mesh setup", func() { When("operator is not installed", func() { - It("should fail using precondition check", func() { + It("should fail using precondition check", func(ctx context.Context) { // given featuresHandler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { verificationFeatureErr := feature.CreateFeature("no-service-mesh-operator-check"). @@ -63,7 +63,7 @@ var _ = Describe("Service Mesh setup", func() { }) // when - applyErr := featuresHandler.Apply() + applyErr := featuresHandler.Apply(ctx) // then Expect(applyErr).To(MatchError(ContainSubstring("failed to find the pre-requisite operator subscription \"servicemeshoperator\""))) @@ -73,17 +73,17 @@ var _ = Describe("Service Mesh setup", func() { When("operator is installed", func() { var smcpCrdObj *apiextensionsv1.CustomResourceDefinition - BeforeEach(func() { - err := fixtures.CreateSubscription(envTestClient, "openshift-operators", fixtures.OssmSubscription) + BeforeEach(func(ctx context.Context) { + err := fixtures.CreateSubscription(ctx, envTestClient, "openshift-operators", fixtures.OssmSubscription) Expect(err).ToNot(HaveOccurred()) - smcpCrdObj = installServiceMeshCRD() + smcpCrdObj = installServiceMeshCRD(ctx) }) - AfterEach(func() { - objectCleaner.DeleteAll(smcpCrdObj) + AfterEach(func(ctx context.Context) { + objectCleaner.DeleteAll(ctx, smcpCrdObj) }) - It("should succeed using precondition check", func() { + It("should succeed using precondition check", func(ctx context.Context) { // when featuresHandler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { verificationFeatureErr := feature.CreateFeature("service-mesh-operator-check"). @@ -98,21 +98,21 @@ var _ = Describe("Service Mesh setup", func() { }) // when - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) }) - It("should find installed Service Mesh Control Plane", func() { + It("should find installed Service Mesh Control Plane", func(ctx context.Context) { // given c, err := client.New(envTest.Config, client.Options{}) Expect(err).ToNot(HaveOccurred()) ns := envtestutil.AppendRandomNameTo(fixtures.TestNamespacePrefix) nsResource := fixtures.NewNamespace(ns) - Expect(c.Create(context.Background(), nsResource)).To(Succeed()) - defer objectCleaner.DeleteAll(nsResource) + Expect(c.Create(ctx, nsResource)).To(Succeed()) + defer objectCleaner.DeleteAll(ctx, nsResource) - createServiceMeshControlPlane("test-name", ns) + createServiceMeshControlPlane(ctx, "test-name", ns) dsci.Spec.ServiceMesh.ControlPlane.Namespace = ns dsci.Spec.ServiceMesh.ControlPlane.Name = "test-name" @@ -130,10 +130,10 @@ var _ = Describe("Service Mesh setup", func() { }) // then - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) }) - It("should fail to find Service Mesh Control Plane if not present", func() { + It("should fail to find Service Mesh Control Plane if not present", func(ctx context.Context) { // given dsci.Spec.ServiceMesh.ControlPlane.Name = "test-name" @@ -151,7 +151,7 @@ var _ = Describe("Service Mesh setup", func() { }) // then - Expect(featuresHandler.Apply()).To(MatchError(ContainSubstring("failed to find Service Mesh Control Plane"))) + Expect(featuresHandler.Apply(ctx)).To(MatchError(ContainSubstring("failed to find Service Mesh Control Plane"))) }) }) @@ -170,8 +170,8 @@ var _ = Describe("Service Mesh setup", func() { name = "minimal" ) - BeforeEach(func() { - smcpCrdObj = installServiceMeshCRD() + BeforeEach(func(ctx context.Context) { + smcpCrdObj = installServiceMeshCRD(ctx) objectCleaner = envtestutil.CreateCleaner(envTestClient, envTest.Config, fixtures.Timeout, fixtures.Interval) dsci = fixtures.NewDSCInitialization(namespace) @@ -181,19 +181,19 @@ var _ = Describe("Service Mesh setup", func() { serviceMeshSpec.ControlPlane.Namespace = namespace }) - AfterEach(func() { - objectCleaner.DeleteAll(smcpCrdObj) + AfterEach(func(ctx context.Context) { + objectCleaner.DeleteAll(ctx, smcpCrdObj) }) - It("should be able to remove external provider on cleanup", func() { + It("should be able to remove external provider on cleanup", func(ctx context.Context) { // given ns := fixtures.NewNamespace(namespace) - Expect(envTestClient.Create(context.Background(), ns)).To(Succeed()) - defer objectCleaner.DeleteAll(ns) + Expect(envTestClient.Create(ctx, ns)).To(Succeed()) + defer objectCleaner.DeleteAll(ctx, ns) serviceMeshSpec.Auth.Namespace = "auth-provider" - createServiceMeshControlPlane(name, namespace) + createServiceMeshControlPlane(ctx, name, namespace) handler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { return feature.CreateFeature("control-plane-with-external-authz-provider"). @@ -209,8 +209,8 @@ var _ = Describe("Service Mesh setup", func() { // when By("verifying extension provider has been added after applying feature", func() { - Expect(handler.Apply()).To(Succeed()) - serviceMeshControlPlane, err := getServiceMeshControlPlane(namespace, name) + Expect(handler.Apply(ctx)).To(Succeed()) + serviceMeshControlPlane, err := getServiceMeshControlPlane(ctx, namespace, name) Expect(err).ToNot(HaveOccurred()) extensionProviders, found, err := unstructured.NestedSlice(serviceMeshControlPlane.Object, "spec", "techPreview", "meshConfig", "extensionProviders") @@ -232,17 +232,17 @@ var _ = Describe("Service Mesh setup", func() { // then By("verifying that extension provider has been removed and namespace is gone too", func() { - Expect(handler.Delete()).To(Succeed()) + Expect(handler.Delete(ctx)).To(Succeed()) Eventually(func() []interface{} { - serviceMeshControlPlane, err := getServiceMeshControlPlane(namespace, name) + serviceMeshControlPlane, err := getServiceMeshControlPlane(ctx, namespace, name) Expect(err).ToNot(HaveOccurred()) extensionProviders, found, err := unstructured.NestedSlice(serviceMeshControlPlane.Object, "spec", "techPreview", "meshConfig", "extensionProviders") Expect(err).ToNot(HaveOccurred()) Expect(found).To(BeTrue()) - _, err = fixtures.GetNamespace(envTestClient, serviceMeshSpec.Auth.Namespace) + _, err = fixtures.GetNamespace(ctx, envTestClient, serviceMeshSpec.Auth.Namespace) Expect(errors.IsNotFound(err)).To(BeTrue()) return extensionProviders @@ -259,10 +259,10 @@ var _ = Describe("Service Mesh setup", func() { }) }) -func installServiceMeshCRD() *apiextensionsv1.CustomResourceDefinition { +func installServiceMeshCRD(ctx context.Context) *apiextensionsv1.CustomResourceDefinition { smcpCrdObj := &apiextensionsv1.CustomResourceDefinition{} Expect(yaml.Unmarshal([]byte(fixtures.ServiceMeshControlPlaneCRD), smcpCrdObj)).ToNot(HaveOccurred()) - Expect(envTestClient.Create(context.TODO(), smcpCrdObj)).ToNot(HaveOccurred()) + Expect(envTestClient.Create(ctx, smcpCrdObj)).ToNot(HaveOccurred()) crdOptions := envtest.CRDInstallOptions{PollInterval: fixtures.Interval, MaxTime: fixtures.Timeout} Expect(envtest.WaitForCRDs(envTest.Config, []*apiextensionsv1.CustomResourceDefinition{smcpCrdObj}, crdOptions)).To(Succeed()) @@ -270,7 +270,7 @@ func installServiceMeshCRD() *apiextensionsv1.CustomResourceDefinition { return smcpCrdObj } -func createServiceMeshControlPlane(name, namespace string) { +func createServiceMeshControlPlane(ctx context.Context, name string, namespace string) { serviceMeshControlPlane := &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "maistra.io/v2", @@ -282,13 +282,13 @@ func createServiceMeshControlPlane(name, namespace string) { "spec": map[string]interface{}{}, }, } - Expect(createSMCPInCluster(serviceMeshControlPlane, namespace)).To(Succeed()) + Expect(createSMCPInCluster(ctx, serviceMeshControlPlane, namespace)).To(Succeed()) } -func createSMCPInCluster(smcpObj *unstructured.Unstructured, namespace string) error { +func createSMCPInCluster(ctx context.Context, smcpObj *unstructured.Unstructured, namespace string) error { smcpObj.SetGroupVersionKind(gvk.ServiceMeshControlPlane) smcpObj.SetNamespace(namespace) - if err := envTestClient.Create(context.TODO(), smcpObj); err != nil { + if err := envTestClient.Create(ctx, smcpObj); err != nil { return err } @@ -318,14 +318,14 @@ func createSMCPInCluster(smcpObj *unstructured.Unstructured, namespace string) e return err } - return envTestClient.Status().Update(context.TODO(), update) + return envTestClient.Status().Update(ctx, update) } -func getServiceMeshControlPlane(namespace, name string) (*unstructured.Unstructured, error) { +func getServiceMeshControlPlane(ctx context.Context, namespace string, name string) (*unstructured.Unstructured, error) { smcpObj := &unstructured.Unstructured{} smcpObj.SetGroupVersionKind(gvk.ServiceMeshControlPlane) - err := envTestClient.Get(context.TODO(), client.ObjectKey{ + err := envTestClient.Get(ctx, client.ObjectKey{ Namespace: namespace, Name: name, }, smcpObj) diff --git a/tests/integration/features/tracker_int_test.go b/tests/integration/features/tracker_int_test.go index c9aa9b796e5..3291a2b6b1d 100644 --- a/tests/integration/features/tracker_int_test.go +++ b/tests/integration/features/tracker_int_test.go @@ -1,6 +1,7 @@ package features_test import ( + "context" "fmt" conditionsv1 "github.com/openshift/custom-resource-status/conditions/v1" @@ -31,7 +32,7 @@ var _ = Describe("Feature tracking capability", func() { Context("Reporting progress when applying Feature", func() { - It("should indicate successful installation in FeatureTracker through Status conditions", func() { + It("should indicate successful installation in FeatureTracker through Status conditions", func(ctx context.Context) { featuresHandler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { verificationFeatureErr := feature.CreateFeature("always-working-feature"). For(handler). @@ -44,10 +45,10 @@ var _ = Describe("Feature tracking capability", func() { }) // when - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) // then - featureTracker, err := fixtures.GetFeatureTracker(envTestClient, appNamespace, "always-working-feature") + featureTracker, err := fixtures.GetFeatureTracker(ctx, envTestClient, appNamespace, "always-working-feature") Expect(err).ToNot(HaveOccurred()) Expect(featureTracker.Status.Phase).To(Equal(status.PhaseReady)) Expect(featureTracker.Status.Conditions).To(ContainElement( @@ -59,13 +60,13 @@ var _ = Describe("Feature tracking capability", func() { )) }) - It("should indicate when failure occurs in preconditions through Status conditions", func() { + It("should indicate when failure occurs in preconditions through Status conditions", func(ctx context.Context) { // given featuresHandler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { verificationFeatureErr := feature.CreateFeature("precondition-fail"). For(handler). UsingConfig(envTest.Config). - PreConditions(func(f *feature.Feature) error { + PreConditions(func(_ context.Context, f *feature.Feature) error { return fmt.Errorf("during test always fail") }). Load() @@ -76,10 +77,10 @@ var _ = Describe("Feature tracking capability", func() { }) // when - Expect(featuresHandler.Apply()).ToNot(Succeed()) + Expect(featuresHandler.Apply(ctx)).ToNot(Succeed()) // then - featureTracker, err := fixtures.GetFeatureTracker(envTestClient, appNamespace, "precondition-fail") + featureTracker, err := fixtures.GetFeatureTracker(ctx, envTestClient, appNamespace, "precondition-fail") Expect(err).ToNot(HaveOccurred()) Expect(featureTracker.Status.Phase).To(Equal(status.PhaseError)) Expect(featureTracker.Status.Conditions).To(ContainElement( @@ -91,13 +92,13 @@ var _ = Describe("Feature tracking capability", func() { )) }) - It("should indicate when failure occurs in post-conditions through Status conditions", func() { + It("should indicate when failure occurs in post-conditions through Status conditions", func(ctx context.Context) { // given featuresHandler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { verificationFeatureErr := feature.CreateFeature("post-condition-failure"). For(handler). UsingConfig(envTest.Config). - PostConditions(func(f *feature.Feature) error { + PostConditions(func(_ context.Context, f *feature.Feature) error { return fmt.Errorf("during test always fail") }). Load() @@ -108,10 +109,10 @@ var _ = Describe("Feature tracking capability", func() { }) // when - Expect(featuresHandler.Apply()).ToNot(Succeed()) + Expect(featuresHandler.Apply(ctx)).ToNot(Succeed()) // then - featureTracker, err := fixtures.GetFeatureTracker(envTestClient, appNamespace, "post-condition-failure") + featureTracker, err := fixtures.GetFeatureTracker(ctx, envTestClient, appNamespace, "post-condition-failure") Expect(err).ToNot(HaveOccurred()) Expect(featureTracker.Status.Phase).To(Equal(status.PhaseError)) Expect(featureTracker.Status.Conditions).To(ContainElement( @@ -126,7 +127,7 @@ var _ = Describe("Feature tracking capability", func() { Context("adding metadata of FeatureTracker origin", func() { - It("should correctly indicate source in the feature tracker", func() { + It("should correctly indicate source in the feature tracker", func(ctx context.Context) { // given featuresHandler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { emptyFeatureErr := feature.CreateFeature("always-working-feature"). @@ -140,10 +141,10 @@ var _ = Describe("Feature tracking capability", func() { }) // when - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) // then - featureTracker, err := fixtures.GetFeatureTracker(envTestClient, appNamespace, "always-working-feature") + featureTracker, err := fixtures.GetFeatureTracker(ctx, envTestClient, appNamespace, "always-working-feature") Expect(err).ToNot(HaveOccurred()) Expect(featureTracker.Spec.Source).To( MatchFields(IgnoreExtras, Fields{ @@ -153,7 +154,7 @@ var _ = Describe("Feature tracking capability", func() { ) }) - It("should correctly indicate app namespace in the feature tracker", func() { + It("should correctly indicate app namespace in the feature tracker", func(ctx context.Context) { // given featuresHandler := feature.ClusterFeaturesHandler(dsci, func(handler *feature.FeaturesHandler) error { emptyFeatureErr := feature.CreateFeature("empty-feature"). @@ -167,10 +168,10 @@ var _ = Describe("Feature tracking capability", func() { }) // when - Expect(featuresHandler.Apply()).To(Succeed()) + Expect(featuresHandler.Apply(ctx)).To(Succeed()) // then - featureTracker, err := fixtures.GetFeatureTracker(envTestClient, appNamespace, "empty-feature") + featureTracker, err := fixtures.GetFeatureTracker(ctx, envTestClient, appNamespace, "empty-feature") Expect(err).ToNot(HaveOccurred()) Expect(featureTracker.Spec.AppNamespace).To(Equal("default")) })