diff --git a/components/codeflare/codeflare.go b/components/codeflare/codeflare.go index 5b94e14cda1..83a92da4794 100644 --- a/components/codeflare/codeflare.go +++ b/components/codeflare/codeflare.go @@ -51,7 +51,7 @@ func (c *CodeFlare) GetComponentName() string { // Verifies that CodeFlare implements ComponentInterface. var _ components.ComponentInterface = (*CodeFlare)(nil) -func (c *CodeFlare) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec) error { +func (c *CodeFlare) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, _ bool) error { var imageParamMap = map[string]string{ "odh-codeflare-operator-controller-image": "RELATED_IMAGE_ODH_CODEFLARE_OPERATOR_IMAGE", // no need mcad, embedded in cfo "namespace": dscispec.ApplicationsNamespace, diff --git a/components/component.go b/components/component.go index ecd25480364..81b259acb47 100644 --- a/components/component.go +++ b/components/component.go @@ -75,7 +75,7 @@ type ManifestsConfig struct { } type ComponentInterface interface { - ReconcileComponent(cli client.Client, owner metav1.Object, DSCISpec *dsciv1.DSCInitializationSpec) error + ReconcileComponent(cli client.Client, owner metav1.Object, DSCISpec *dsciv1.DSCInitializationSpec, currentComponentStatus bool) error Cleanup(cli client.Client, DSCISpec *dsciv1.DSCInitializationSpec) error GetComponentName() string GetManagementState() operatorv1.ManagementState diff --git a/components/dashboard/dashboard.go b/components/dashboard/dashboard.go index 1ba5d114546..d2482467662 100644 --- a/components/dashboard/dashboard.go +++ b/components/dashboard/dashboard.go @@ -10,6 +10,8 @@ import ( operatorv1 "github.com/openshift/api/operator/v1" routev1 "github.com/openshift/api/route/v1" + v1 "k8s.io/api/core/v1" + apierrs "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -73,7 +75,8 @@ func (d *Dashboard) GetComponentName() string { // Verifies that Dashboard implements ComponentInterface. var _ components.ComponentInterface = (*Dashboard)(nil) -func (d *Dashboard) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec) error { +//nolint:gocyclo +func (d *Dashboard) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, currentComponentStatus bool) error { var imageParamMap = map[string]string{ "odh-dashboard-image": "RELATED_IMAGE_ODH_DASHBOARD_IMAGE", } @@ -87,6 +90,9 @@ func (d *Dashboard) ReconcileComponent(cli client.Client, owner metav1.Object, d // Update Default rolebinding if enabled { + if err := d.cleanOauthClientSecrets(cli, dscispec, currentComponentStatus); err != nil { + return err + } // Download manifests and update paths if err := d.OverrideManifests(string(platform)); err != nil { return err @@ -259,3 +265,28 @@ func (d *Dashboard) deployConsoleLink(cli client.Client, owner metav1.Object, na return nil } + +func (d *Dashboard) cleanOauthClientSecrets(cli client.Client, dscispec *dsciv1.DSCInitializationSpec, currentComponentStatus bool) error { + // Remove previous oauth-client secrets + // Check if component is going from state of `Not Installed --> Installed` + // Assumption: Component is currently set to enabled + if !currentComponentStatus { + // Delete client secrets from previous installation + oauthClientSecret := &v1.Secret{} + err := cli.Get(context.TODO(), client.ObjectKey{ + Namespace: dscispec.ApplicationsNamespace, + Name: "dashboard-oauth-client", + }, oauthClientSecret) + if err != nil { + if !apierrs.IsNotFound(err) { + return err + } + } else { + err := cli.Delete(context.TODO(), oauthClientSecret) + if err != nil { + return fmt.Errorf("error deleting oauth client secret: %v", err) + } + } + } + return nil +} diff --git a/components/datasciencepipelines/datasciencepipelines.go b/components/datasciencepipelines/datasciencepipelines.go index c134c39452e..bf0f4e74457 100644 --- a/components/datasciencepipelines/datasciencepipelines.go +++ b/components/datasciencepipelines/datasciencepipelines.go @@ -48,7 +48,7 @@ func (d *DataSciencePipelines) GetComponentName() string { // Verifies that Dashboard implements ComponentInterface. var _ components.ComponentInterface = (*DataSciencePipelines)(nil) -func (d *DataSciencePipelines) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec) error { +func (d *DataSciencePipelines) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, _ bool) error { var imageParamMap = map[string]string{ "IMAGES_APISERVER": "RELATED_IMAGE_ODH_ML_PIPELINES_API_SERVER_IMAGE", "IMAGES_ARTIFACT": "RELATED_IMAGE_ODH_ML_PIPELINES_ARTIFACT_MANAGER_IMAGE", diff --git a/components/kserve/kserve.go b/components/kserve/kserve.go index 2679c2fcbc8..036eca76561 100644 --- a/components/kserve/kserve.go +++ b/components/kserve/kserve.go @@ -72,7 +72,7 @@ func (k *Kserve) GetComponentName() string { // Verifies that Kserve implements ComponentInterface. var _ components.ComponentInterface = (*Kserve)(nil) -func (k *Kserve) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec) error { +func (k *Kserve) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, _ bool) error { // paramMap for Kserve to use. var imageParamMap = map[string]string{} diff --git a/components/modelmeshserving/modelmeshserving.go b/components/modelmeshserving/modelmeshserving.go index 7b5819dd078..79e72e753ad 100644 --- a/components/modelmeshserving/modelmeshserving.go +++ b/components/modelmeshserving/modelmeshserving.go @@ -2,7 +2,6 @@ package modelmeshserving import ( - "context" "path/filepath" "strings" @@ -67,7 +66,7 @@ func (m *ModelMeshServing) GetComponentName() string { // Verifies that Dashboard implements ComponentInterface. var _ components.ComponentInterface = (*ModelMeshServing)(nil) -func (m *ModelMeshServing) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec) error { +func (m *ModelMeshServing) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, _ bool) error { var imageParamMap = map[string]string{ "odh-mm-rest-proxy": "RELATED_IMAGE_ODH_MM_REST_PROXY_IMAGE", "odh-modelmesh-runtime-adapter": "RELATED_IMAGE_ODH_MODELMESH_RUNTIME_ADAPTER_IMAGE", @@ -136,15 +135,6 @@ func (m *ModelMeshServing) ReconcileComponent(cli client.Client, owner metav1.Ob } } - // Get monitoring namespace - dscInit := &dsciv1.DSCInitialization{} - err = cli.Get(context.TODO(), client.ObjectKey{ - Name: "default", - }, dscInit) - if err != nil { - return err - } - // CloudService Monitoring handling if platform == deploy.ManagedRhods { // first model-mesh rules diff --git a/components/ray/ray.go b/components/ray/ray.go index d470270c776..b89c903c7e4 100644 --- a/components/ray/ray.go +++ b/components/ray/ray.go @@ -48,7 +48,7 @@ func (r *Ray) GetComponentName() string { // Verifies that Ray implements ComponentInterface. var _ components.ComponentInterface = (*Ray)(nil) -func (r *Ray) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec) error { +func (r *Ray) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, _ bool) error { var imageParamMap = map[string]string{ "odh-kuberay-operator-controller-image": "RELATED_IMAGE_ODH_KUBERAY_OPERATOR_CONTROLLER_IMAGE", "namespace": dscispec.ApplicationsNamespace, diff --git a/components/trustyai/trustyai.go b/components/trustyai/trustyai.go index 9d5aaff98a8..08c98a5519e 100644 --- a/components/trustyai/trustyai.go +++ b/components/trustyai/trustyai.go @@ -47,7 +47,7 @@ func (t *TrustyAI) GetComponentName() string { // Verifies that TrustyAI implements ComponentInterface. var _ components.ComponentInterface = (*TrustyAI)(nil) -func (t *TrustyAI) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec) error { +func (t *TrustyAI) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, _ bool) error { var imageParamMap = map[string]string{ "trustyaiServiceImage": "RELATED_IMAGE_ODH_TRUSTYAI_SERVICE_IMAGE", "trustyaiOperatorImage": "RELATED_IMAGE_ODH_TRUSTYAI_SERVICE_OPERATOR_IMAGE", diff --git a/components/workbenches/workbenches.go b/components/workbenches/workbenches.go index 89b71515ab7..5576a717b8a 100644 --- a/components/workbenches/workbenches.go +++ b/components/workbenches/workbenches.go @@ -92,7 +92,7 @@ func (w *Workbenches) GetComponentName() string { // Verifies that Workbench implements ComponentInterface. var _ components.ComponentInterface = (*Workbenches)(nil) -func (w *Workbenches) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsci.DSCInitializationSpec) error { +func (w *Workbenches) ReconcileComponent(cli client.Client, owner metav1.Object, dscispec *dsci.DSCInitializationSpec, _ bool) error { var imageParamMap = map[string]string{ "odh-notebook-controller-image": "RELATED_IMAGE_ODH_NOTEBOOK_CONTROLLER_IMAGE", "odh-kf-notebook-controller-image": "RELATED_IMAGE_ODH_KF_NOTEBOOK_CONTROLLER_IMAGE", diff --git a/controllers/datasciencecluster/datasciencecluster_controller.go b/controllers/datasciencecluster/datasciencecluster_controller.go index 92f74b0f324..41fc08df1e7 100644 --- a/controllers/datasciencecluster/datasciencecluster_controller.go +++ b/controllers/datasciencecluster/datasciencecluster_controller.go @@ -271,7 +271,7 @@ func (r *DataScienceClusterReconciler) reconcileSubComponent(ctx context.Context } // Reconcile component - err = component.ReconcileComponent(r.Client, instance, r.DataScienceCluster.DSCISpec) + err = component.ReconcileComponent(r.Client, instance, r.DataScienceCluster.DSCISpec, instance.Status.InstalledComponents[componentName]) if err != nil { // reconciliation failed: log errors, raise event and update status accordingly diff --git a/controllers/secretgenerator/secretgenerator_controller.go b/controllers/secretgenerator/secretgenerator_controller.go index 4dbc87b674d..8960de68c68 100644 --- a/controllers/secretgenerator/secretgenerator_controller.go +++ b/controllers/secretgenerator/secretgenerator_controller.go @@ -19,6 +19,7 @@ package secretgenerator import ( "context" + "encoding/json" "fmt" "time" @@ -227,8 +228,16 @@ func (r *SecretGeneratorReconciler) createOAuthClient(ctx context.Context, name err := r.Client.Create(ctx, oauthClient) if err != nil { if apierrs.IsAlreadyExists(err) { - secGenLog.Info("OAuth client resource already exists", "name", oauthClient.Name) - + secGenLog.Info("OAuth client resource already exists, patch it", "name", oauthClient.Name) + data, err := json.Marshal(oauthClient) + if err != nil { + return fmt.Errorf("failed to get DataScienceCluster custom resource data: %v", err) + } + err = r.Client.Patch(context.TODO(), oauthClient, client.RawPatch(types.ApplyPatchType, data), + client.ForceOwnership, client.FieldOwner("opendatahub-operator")) + if err != nil { + return err + } return nil } } diff --git a/main.go b/main.go index 70cf4679f2b..6b2d25ca2b5 100644 --- a/main.go +++ b/main.go @@ -180,14 +180,12 @@ func main() { //nolint:funlen if !disableDSCConfig { if err = upgrade.CreateDefaultDSCI(setupClient, platform, dscApplicationsNamespace, dscMonitoringNamespace); err != nil { setupLog.Error(err, "unable to create initial setup for the operator") - os.Exit(1) } } // Apply update from legacy operator if err = upgrade.UpdateFromLegacyVersion(setupClient, platform); err != nil { setupLog.Error(err, "unable to update from legacy operator version") - os.Exit(1) } if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { diff --git a/pkg/upgrade/upgrade.go b/pkg/upgrade/upgrade.go index d64548b9d22..bf1342d8854 100644 --- a/pkg/upgrade/upgrade.go +++ b/pkg/upgrade/upgrade.go @@ -220,6 +220,14 @@ func CreateDefaultDSCI(cli client.Client, platform deploy.Platform, appNamespace Spec: *defaultDsciSpec, } + patchedDSCI := &dsci.DSCInitialization{ + TypeMeta: metav1.TypeMeta{ + Kind: "DSCInitialization", + APIVersion: "dscinitialization.opendatahub.io/v1", + }, + Spec: *defaultDsciSpec, + } + instances := &dsci.DSCInitializationList{} if err := cli.List(context.TODO(), instances); err != nil { return err @@ -227,14 +235,16 @@ func CreateDefaultDSCI(cli client.Client, platform deploy.Platform, appNamespace switch { case len(instances.Items) > 1: - return fmt.Errorf("only one instance of DSCInitialization object is allowed. Please delete other instances ") + fmt.Printf("only one instance of DSCInitialization object is allowed. Please delete other instances ") + return nil case len(instances.Items) == 1: if platform == deploy.ManagedRhods || platform == deploy.SelfManagedRhods { - data, err := json.Marshal(defaultDsciSpec) + data, err := json.Marshal(patchedDSCI) if err != nil { return err } - err = cli.Patch(context.TODO(), defaultDsci, client.RawPatch(types.ApplyPatchType, data), + existingDSCI := &instances.Items[0] + err = cli.Patch(context.TODO(), existingDSCI, client.RawPatch(types.ApplyPatchType, data), client.ForceOwnership, client.FieldOwner("opendatahub-operator")) if err != nil { return err