diff --git a/bundle/manifests/opendatahub-operator.clusterserviceversion.yaml b/bundle/manifests/opendatahub-operator.clusterserviceversion.yaml index 1948ad60e69..7f08cff8ee3 100644 --- a/bundle/manifests/opendatahub-operator.clusterserviceversion.yaml +++ b/bundle/manifests/opendatahub-operator.clusterserviceversion.yaml @@ -15,7 +15,7 @@ metadata: "app.kubernetes.io/name": "datasciencecluster", "app.kubernetes.io/part-of": "opendatahub-operator" }, - "name": "default" + "name": "default-dsc" }, "spec": { "components": { @@ -57,7 +57,7 @@ metadata: "app.kubernetes.io/name": "dscinitialization", "app.kubernetes.io/part-of": "opendatahub-operator" }, - "name": "default" + "name": "default-dsci" }, "spec": { "applicationsNamespace": "opendatahub", diff --git a/config/samples/console_v1_odhquickstarts.yaml b/config/samples/console_v1_odhquickstarts.yaml deleted file mode 100644 index 40a487c2ab6..00000000000 --- a/config/samples/console_v1_odhquickstarts.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: console.openshift.io/v1 -kind: OdhQuickStart -metadata: - annotations: - internal.config.kubernetes.io/previousKinds: OdhQuickStart - internal.config.kubernetes.io/previousNames: create-jupyter-notebook - internal.config.kubernetes.io/previousNamespaces: default - opendatahub.io/categories: 'Getting started,Notebook environments' - name: create-jupyter-notebook-sample - namespace: opendatahub - labels: - app.kubernetes.io/part-of: odh-dashboard - app.kubernetes.io/name: odh-dashboard - app.kubernetes.io/instance: odh-dashboard-sample - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: odh-dashboard -spec: - durationMinutes: 5 - appName: jupyterhub - displayName: Creating a Jupyter notebook \ No newline at end of file diff --git a/config/samples/dashboard_v1_odhapplications.yaml b/config/samples/dashboard_v1_odhapplications.yaml deleted file mode 100644 index bd9a61a37b6..00000000000 --- a/config/samples/dashboard_v1_odhapplications.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: dashboard.opendatahub.io/v1 -kind: OdhApplication -metadata: - name: jupyterhub-sample - namespace: opendatahub - labels: - app.kubernetes.io/part-of: odh-dashboard - app.kubernetes.io/name: odh-dashboard - app.kubernetes.io/instance: odh-dashboard-sample - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: odh-dashboard -spec: - getStartedLink: 'https://jupyterhub.readthedocs.io/en/stable/getting-started/index.html' - route: jupyterhub - displayName: JupyterHub - provider: Jupyter - docsLink: 'https://jupyter.org/hub' - quickStart: create-jupyter-notebook - getStartedMarkDown: >- - # MarkDown Description \ No newline at end of file diff --git a/config/samples/dashboard_v1_odhdocuments.yaml b/config/samples/dashboard_v1_odhdocuments.yaml deleted file mode 100644 index 8a7307864af..00000000000 --- a/config/samples/dashboard_v1_odhdocuments.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: dashboard.opendatahub.io/v1 -kind: OdhDocument -metadata: - name: jupyterhub-view-installed-packages-sample - namespace: opendatahub - labels: - app.kubernetes.io/part-of: odh-dashboard - app.kubernetes.io/name: odh-dashboard - app.kubernetes.io/instance: odh-dashboard-sample - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: odh-dashboard -spec: - appName: jupyter - durationMinutes: 15 - type: how-to - url: "https://url.sample.com" \ No newline at end of file diff --git a/config/samples/datasciencecluster_v1_datasciencecluster.yaml b/config/samples/datasciencecluster_v1_datasciencecluster.yaml index a44d74945f0..2941c437667 100644 --- a/config/samples/datasciencecluster_v1_datasciencecluster.yaml +++ b/config/samples/datasciencecluster_v1_datasciencecluster.yaml @@ -1,7 +1,7 @@ apiVersion: datasciencecluster.opendatahub.io/v1 kind: DataScienceCluster metadata: - name: default + name: default-dsc labels: app.kubernetes.io/name: datasciencecluster app.kubernetes.io/instance: default diff --git a/config/samples/dscinitialization_v1_dscinitialization.yaml b/config/samples/dscinitialization_v1_dscinitialization.yaml index cb0d24da046..83e04c2749e 100644 --- a/config/samples/dscinitialization_v1_dscinitialization.yaml +++ b/config/samples/dscinitialization_v1_dscinitialization.yaml @@ -7,7 +7,7 @@ metadata: app.kubernetes.io/part-of: opendatahub-operator app.kubernetes.io/managed-by: kustomize app.kubernetes.io/created-by: opendatahub-operator - name: default + name: default-dsci spec: monitoring: managementState: "Managed" diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index c2df9084f5f..51284dc78c5 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -5,8 +5,4 @@ kind: Kustomization resources: - datasciencecluster_v1_datasciencecluster.yaml - dscinitialization_v1_dscinitialization.yaml -- opendatahub_v1alpha1_odhdashboardconfigs.yaml -- dashboard_v1_odhdocuments.yaml -- dashboard_v1_odhapplications.yaml -- console_v1_odhquickstarts.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/opendatahub_v1alpha1_odhdashboardconfigs.yaml b/config/samples/opendatahub_v1alpha1_odhdashboardconfigs.yaml deleted file mode 100644 index 1294f28ebb2..00000000000 --- a/config/samples/opendatahub_v1alpha1_odhdashboardconfigs.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: opendatahub.io/v1alpha -kind: OdhDashboardConfig -metadata: - labels: - opendatahub.io/dashboard: 'true' - app.kubernetes.io/part-of: odh-dashboard - app.kubernetes.io/name: odh-dashboard - app.kubernetes.io/instance: odh-dashboard-sample - app.kubernetes.io/managed-by: kustomize - app.kubernetes.io/created-by: odh-dashboard - name: odh-dashboard-config-sample - namespace: opendatahub -spec: - dashboardConfig: - groupsConfig: - adminGroups: odh-admins - allowedGroups: 'system:authenticated' - notebookController: - enabled: true - templateOrder: [] - templateDisablement: [] diff --git a/controllers/dscinitialization/dscinitialization_controller.go b/controllers/dscinitialization/dscinitialization_controller.go index 1d144c8e870..ca07cbf2a47 100644 --- a/controllers/dscinitialization/dscinitialization_controller.go +++ b/controllers/dscinitialization/dscinitialization_controller.go @@ -83,33 +83,18 @@ func (r *DSCInitializationReconciler) Reconcile(ctx context.Context, req ctrl.Re return ctrl.Result{}, err } - if len(instances.Items) > 1 { - // check if multiple instances of DSCInitialization, exit with error - message := fmt.Sprintf("only one instance of DSCInitialization object is allowed. Update existing instance name %s", req.Name) - - return ctrl.Result{}, errors.New(message) - } - - if len(instances.Items) == 0 { - // DSCInitialization instance not found + var instance *dsciv1.DSCInitialization + switch { + case len(instances.Items) == 0: return ctrl.Result{}, nil - } - - instance := &instances.Items[0] - if instance.Name != "default" { - message := fmt.Sprintf("Should update existing instance name %s to 'default'", instance.Name) - - return ctrl.Result{}, errors.New(message) - } - - if len(instances.Items) > 1 { + case len(instances.Items) == 1: + instance = &instances.Items[0] + case len(instances.Items) > 1: message := fmt.Sprintf("only one instance of DSCInitialization object is allowed. Update existing instance name %s", req.Name) - _, _ = r.updateStatus(ctx, instance, func(saved *dsciv1.DSCInitialization) { status.SetErrorCondition(&saved.Status.Conditions, status.DuplicateDSCInitialization, message) saved.Status.Phase = status.PhaseError }) - return ctrl.Result{}, errors.New(message) } diff --git a/controllers/dscinitialization/dscinitialization_test.go b/controllers/dscinitialization/dscinitialization_test.go index 1e6f131fb42..2e33d814e93 100644 --- a/controllers/dscinitialization/dscinitialization_test.go +++ b/controllers/dscinitialization/dscinitialization_test.go @@ -28,7 +28,7 @@ const ( var _ = Describe("DataScienceCluster initialization", func() { Context("Creation of related resources", func() { // must be default as instance name, or it will break - const applicationName = "default" + const applicationName = "default-dsci" BeforeEach(func() { // when desiredDsci := createDSCI(applicationName, operatorv1.Managed, monitoringNamespace) @@ -92,7 +92,7 @@ var _ = Describe("DataScienceCluster initialization", func() { Context("Monitoring Resource", func() { AfterEach(cleanupResources) const monitoringNamespace2 = "test-monitoring-ns2" - const applicationName = "default" + const applicationName = "default-dsci" It("Should not create monitoring namespace if monitoring is disabled", func() { // when desiredDsci := createDSCI(applicationName, operatorv1.Removed, monitoringNamespace2) @@ -118,19 +118,7 @@ var _ = Describe("DataScienceCluster initialization", func() { Context("Handling existing resources", func() { AfterEach(cleanupResources) - const applicationName = "default" - - It("Should not create DSCI instance if name not 'default'", func() { - wrongApplicationName := "default2" - // when - desiredDsci := createDSCI(wrongApplicationName, operatorv1.Managed, monitoringNamespace) - Expect(k8sClient.Create(context.Background(), desiredDsci)).Should(Succeed()) - foundDsciList := &dsci.DSCInitializationList{} - - // then - Expect(len(foundDsciList.Items)).To(Equal(0)) - Eventually(dscInitializationIsReady(wrongApplicationName, workingNamespace, desiredDsci), timeout, interval).Should(BeFalse()) - }) + const applicationName = "default-dsci" It("Should not have more than one DSCI instance in the cluster", func() { diff --git a/main.go b/main.go index 61ce4d5c0b8..70cf4679f2b 100644 --- a/main.go +++ b/main.go @@ -17,14 +17,11 @@ limitations under the License. package main import ( - "context" - "encoding/json" "flag" "os" addonv1alpha1 "github.com/openshift/addon-operator/apis/addons/v1alpha1" ocv1 "github.com/openshift/api/oauth/v1" - operatorv1 "github.com/openshift/api/operator/v1" routev1 "github.com/openshift/api/route/v1" ocuserv1 "github.com/openshift/api/user/v1" ofapiv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" @@ -34,10 +31,7 @@ import ( netv1 "k8s.io/api/networking/v1" authv1 "k8s.io/api/rbac/v1" apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" @@ -162,48 +156,6 @@ func main() { //nolint:funlen os.Exit(1) } - // Check if user opted for disabling DSC configuration - _, disableDSCConfig := os.LookupEnv("DISABLE_DSC_CONFIG") - if !disableDSCConfig { - // Create DSCInitialization CR if it's not present - c := mgr.GetClient() - releaseDscInitialization := &dsci.DSCInitialization{ - TypeMeta: metav1.TypeMeta{ - Kind: "DSCInitialization", - APIVersion: "dscinitialization.opendatahub.io/v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - }, - Spec: dsci.DSCInitializationSpec{ - ApplicationsNamespace: dscApplicationsNamespace, - Monitoring: dsci.Monitoring{ - ManagementState: operatorv1.Managed, - Namespace: dscMonitoringNamespace, - }, - }, - } - err = c.Create(context.TODO(), releaseDscInitialization) - switch { - case err == nil: - setupLog.Info("created DscInitialization resource") - case errors.IsAlreadyExists(err): - // Update if already exists - setupLog.Info("DscInitialization resource already exists. Updating it.") - data, err := json.Marshal(releaseDscInitialization) - if err != nil { - setupLog.Error(err, "failed to get DscInitialization custom resource data") - } - err = c.Patch(context.TODO(), releaseDscInitialization, client.RawPatch(types.ApplyPatchType, data), - client.ForceOwnership, client.FieldOwner("opendatahub-operator")) - if err != nil { - setupLog.Error(err, "failed to update DscInitialization custom resource") - } - default: - setupLog.Error(err, "failed to create DscInitialization custom resource") - os.Exit(1) - } - } // Create new uncached client to run initial setup setupCfg, err := config.GetConfig() if err != nil { @@ -223,6 +175,15 @@ func main() { //nolint:funlen os.Exit(1) } + // Check if user opted for disabling DSC configuration + _, disableDSCConfig := os.LookupEnv("DISABLE_DSC_CONFIG") + 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") diff --git a/pkg/upgrade/upgrade.go b/pkg/upgrade/upgrade.go index 20163a5cd4c..d64548b9d22 100644 --- a/pkg/upgrade/upgrade.go +++ b/pkg/upgrade/upgrade.go @@ -144,13 +144,14 @@ func HasDeleteConfigMap(c client.Client) bool { // createDefaultDSC creates a default instance of DSC. // Note: When the platform is not Managed, and a DSC instance already exists, the function doesn't re-create/update the resource. func CreateDefaultDSC(cli client.Client, platform deploy.Platform) error { + // Set the default DSC name depending on the platform releaseDataScienceCluster := &dsc.DataScienceCluster{ TypeMeta: metav1.TypeMeta{ Kind: "DataScienceCluster", APIVersion: "datasciencecluster.opendatahub.io/v1", }, ObjectMeta: metav1.ObjectMeta{ - Name: "default", + Name: "default-dsc", }, Spec: dsc.DataScienceClusterSpec{ Components: dsc.Components{ @@ -170,13 +171,13 @@ func CreateDefaultDSC(cli client.Client, platform deploy.Platform) error { Component: components.Component{ManagementState: operatorv1.Removed}, }, CodeFlare: codeflare.CodeFlare{ - Component: components.Component{ManagementState: operatorv1.Managed}, + Component: components.Component{ManagementState: operatorv1.Removed}, }, Ray: ray.Ray{ - Component: components.Component{ManagementState: operatorv1.Managed}, + Component: components.Component{ManagementState: operatorv1.Removed}, }, TrustyAI: trustyai.TrustyAI{ - Component: components.Component{ManagementState: operatorv1.Managed}, + Component: components.Component{ManagementState: operatorv1.Removed}, }, }, }, @@ -186,28 +187,67 @@ func CreateDefaultDSC(cli client.Client, platform deploy.Platform) error { case err == nil: fmt.Printf("created DataScienceCluster resource") case apierrs.IsAlreadyExists(err): - // Update if already exists - if platform == deploy.ManagedRhods { - fmt.Printf("DataScienceCluster resource already exists in Managed. Updating it.") - data, err := json.Marshal(releaseDataScienceCluster) + // Do not update the DSC if it already exists + fmt.Printf("DataScienceCluster resource already exists. It will not be updated with default DSC.") + return nil + default: + return fmt.Errorf("failed to create DataScienceCluster custom resource: %v", err) + } + + return nil +} + +// createDefaultDSCI creates a default instance of DSCI +// If there exists an instance already, it patches the DSCISpec with default values +// Note: DSCI CR modifcations are not supported, as it is the initial prereq setting for the components +func CreateDefaultDSCI(cli client.Client, platform deploy.Platform, appNamespace, monNamespace string) error { + defaultDsciSpec := &dsci.DSCInitializationSpec{ + ApplicationsNamespace: appNamespace, + Monitoring: dsci.Monitoring{ + ManagementState: operatorv1.Managed, + Namespace: monNamespace, + }, + } + + defaultDsci := &dsci.DSCInitialization{ + TypeMeta: metav1.TypeMeta{ + Kind: "DSCInitialization", + APIVersion: "dscinitialization.opendatahub.io/v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "default-dsci", + }, + Spec: *defaultDsciSpec, + } + + instances := &dsci.DSCInitializationList{} + if err := cli.List(context.TODO(), instances); err != nil { + return err + } + + switch { + case len(instances.Items) > 1: + return fmt.Errorf("only one instance of DSCInitialization object is allowed. Please delete other instances ") + case len(instances.Items) == 1: + if platform == deploy.ManagedRhods || platform == deploy.SelfManagedRhods { + data, err := json.Marshal(defaultDsciSpec) if err != nil { - return fmt.Errorf("failed to get DataScienceCluster custom resource data: %v", err) + return err } - err = cli.Patch(context.TODO(), releaseDataScienceCluster, client.RawPatch(types.ApplyPatchType, data), + err = cli.Patch(context.TODO(), defaultDsci, client.RawPatch(types.ApplyPatchType, data), client.ForceOwnership, client.FieldOwner("opendatahub-operator")) if err != nil { - return fmt.Errorf("failed to update DataScienceCluster custom resource:%v", err) + return err } } else { - fmt.Printf("DataScienceCluster resource already exists. It will not be updated with default DSC.") - return nil } - default: - - return fmt.Errorf("failed to create DataScienceCluster custom resource: %v", err) + case len(instances.Items) == 0: + err := cli.Create(context.TODO(), defaultDsci) + if err != nil { + return err + } } - return nil } diff --git a/tests/e2e/controller_setup_test.go b/tests/e2e/controller_setup_test.go index 0b6285bc11d..c2131cb6874 100644 --- a/tests/e2e/controller_setup_test.go +++ b/tests/e2e/controller_setup_test.go @@ -79,9 +79,9 @@ func NewTestContext() (*testContext, error) { // Get Applications namespace from DSCInitialization instance dscInit := &dsci.DSCInitialization{} - err = custClient.Get(context.TODO(), types.NamespacedName{Name: "default"}, dscInit) + err = custClient.Get(context.TODO(), types.NamespacedName{Name: "default-dsci"}, dscInit) if err != nil { - return nil, errors.Wrap(err, "error getting DSCInitialization instance 'default'") + return nil, errors.Wrap(err, "error getting DSCInitialization instance") } return &testContext{