diff --git a/controllers/components/dashboard/dashboard.go b/controllers/components/dashboard/dashboard.go index 6293e7d3908..4311e07f5c8 100644 --- a/controllers/components/dashboard/dashboard.go +++ b/controllers/components/dashboard/dashboard.go @@ -5,15 +5,31 @@ import ( operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" componentsv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/components/v1" dscv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/datasciencecluster/v1" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" + cr "github.com/opendatahub-io/opendatahub-operator/v2/pkg/componentsregistry" odhdeploy "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/annotations" ) -func Init(platform cluster.Platform) error { +type componentHandler struct{} + +func Init() { + cr.Add(&componentHandler{}) +} + +func (s *componentHandler) GetName() string { + return componentsv1.DashboardComponentName +} + +func (s *componentHandler) GetManagementState(dsc *dscv1.DataScienceCluster) operatorv1.ManagementState { + return dsc.Spec.Components.Dashboard.ManagementState +} + +func (s *componentHandler) Init(platform cluster.Platform) error { mi := defaultManifestInfo(platform) if err := odhdeploy.ApplyParams(mi.String(), imagesMap); err != nil { @@ -23,7 +39,7 @@ func Init(platform cluster.Platform) error { return nil } -func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.Dashboard { +func (s *componentHandler) NewCRObject(dsc *dscv1.DataScienceCluster) client.Object { //nolint:ireturn dashboardAnnotations := make(map[string]string) switch dsc.Spec.Components.Dashboard.ManagementState { @@ -33,7 +49,7 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.Dashboard { dashboardAnnotations[annotations.ManagementStateAnnotation] = "Unknown" } - return &componentsv1.Dashboard{ + return client.Object(&componentsv1.Dashboard{ TypeMeta: metav1.TypeMeta{ Kind: componentsv1.DashboardKind, APIVersion: componentsv1.GroupVersion.String(), @@ -45,5 +61,5 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.Dashboard { Spec: componentsv1.DashboardSpec{ DashboardCommonSpec: dsc.Spec.Components.Dashboard.DashboardCommonSpec, }, - } + }) } diff --git a/controllers/components/dashboard/dashboard_controller.go b/controllers/components/dashboard/dashboard_controller.go index 0600f689577..b2d1841357a 100644 --- a/controllers/components/dashboard/dashboard_controller.go +++ b/controllers/components/dashboard/dashboard_controller.go @@ -41,7 +41,7 @@ import ( ) // NewComponentReconciler creates a ComponentReconciler for the Dashboard API. -func NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { +func (s *componentHandler) NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { componentName := computeComponentName() _, err := reconciler.ComponentReconcilerFor(mgr, componentsv1.DashboardInstanceName, &componentsv1.Dashboard{}). diff --git a/controllers/components/datasciencepipelines/datasciencepipelines.go b/controllers/components/datasciencepipelines/datasciencepipelines.go index 3fef4322abe..0e0981f746d 100644 --- a/controllers/components/datasciencepipelines/datasciencepipelines.go +++ b/controllers/components/datasciencepipelines/datasciencepipelines.go @@ -5,10 +5,12 @@ import ( operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" componentsv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/components/v1" dscv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/datasciencecluster/v1" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" + cr "github.com/opendatahub-io/opendatahub-operator/v2/pkg/componentsregistry" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/annotations" ) @@ -17,7 +19,21 @@ const ( ArgoWorkflowCRD = "workflows.argoproj.io" ) -func Init(platform cluster.Platform) error { +type componentHandler struct{} + +func Init() { + cr.Add(&componentHandler{}) +} + +func (s *componentHandler) GetName() string { + return componentsv1.DashboardComponentName +} + +func (s *componentHandler) GetManagementState(dsc *dscv1.DataScienceCluster) operatorv1.ManagementState { + return dsc.Spec.Components.Dashboard.ManagementState +} + +func (s *componentHandler) Init(platform cluster.Platform) error { var imageParamMap = map[string]string{ // v1 "IMAGES_APISERVER": "RELATED_IMAGE_ODH_ML_PIPELINES_API_SERVER_IMAGE", @@ -44,7 +60,7 @@ func Init(platform cluster.Platform) error { return nil } -func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.DataSciencePipelines { +func (s *componentHandler) NewCRObject(dsc *dscv1.DataScienceCluster) client.Object { //nolint:ireturn dataSciencePipelinesAnnotations := make(map[string]string) switch dsc.Spec.Components.DataSciencePipelines.ManagementState { @@ -54,7 +70,7 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.DataSciencePipe dataSciencePipelinesAnnotations[annotations.ManagementStateAnnotation] = "Unknown" } - return &componentsv1.DataSciencePipelines{ + return client.Object(&componentsv1.DataSciencePipelines{ TypeMeta: metav1.TypeMeta{ Kind: componentsv1.DataSciencePipelinesKind, APIVersion: componentsv1.GroupVersion.String(), @@ -66,5 +82,5 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.DataSciencePipe Spec: componentsv1.DataSciencePipelinesSpec{ DataSciencePipelinesCommonSpec: dsc.Spec.Components.DataSciencePipelines.DataSciencePipelinesCommonSpec, }, - } + }) } diff --git a/controllers/components/datasciencepipelines/datasciencepipelines_controller.go b/controllers/components/datasciencepipelines/datasciencepipelines_controller.go index e9b085963ea..f35e40d7514 100644 --- a/controllers/components/datasciencepipelines/datasciencepipelines_controller.go +++ b/controllers/components/datasciencepipelines/datasciencepipelines_controller.go @@ -48,7 +48,7 @@ var ( } ) -func NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { +func (s *componentHandler) NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { _, err := reconciler.ComponentReconcilerFor( mgr, componentsv1.DataSciencePipelinesInstanceName, diff --git a/controllers/components/kueue/kueue.go b/controllers/components/kueue/kueue.go index bf0da0a024a..c8c333fc9b7 100644 --- a/controllers/components/kueue/kueue.go +++ b/controllers/components/kueue/kueue.go @@ -5,10 +5,12 @@ import ( operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" componentsv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/components/v1" dscv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/datasciencecluster/v1" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" + cr "github.com/opendatahub-io/opendatahub-operator/v2/pkg/componentsregistry" odhdeploy "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/annotations" ) @@ -21,8 +23,21 @@ var ( DefaultPath = odhdeploy.DefaultManifestPath + "/" + ComponentName + "/rhoai" // same path for both odh and rhoai ) -// for DSC to get compoment Kueue's CR. -func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.Kueue { +type componentHandler struct{} + +func Init() { + cr.Add(&componentHandler{}) +} + +func (s *componentHandler) GetName() string { + return componentsv1.KueueComponentName +} + +func (s *componentHandler) GetManagementState(dsc *dscv1.DataScienceCluster) operatorv1.ManagementState { + return dsc.Spec.Components.Kueue.ManagementState +} + +func (s *componentHandler) NewCRObject(dsc *dscv1.DataScienceCluster) client.Object { //nolint:ireturn kueueAnnotations := make(map[string]string) switch dsc.Spec.Components.Kueue.ManagementState { case operatorv1.Managed, operatorv1.Removed: @@ -31,7 +46,7 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.Kueue { kueueAnnotations[annotations.ManagementStateAnnotation] = "Unknown" } - return &componentsv1.Kueue{ + return client.Object(&componentsv1.Kueue{ TypeMeta: metav1.TypeMeta{ Kind: componentsv1.KueueKind, APIVersion: componentsv1.GroupVersion.String(), @@ -43,11 +58,10 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.Kueue { Spec: componentsv1.KueueSpec{ KueueCommonSpec: dsc.Spec.Components.Kueue.KueueCommonSpec, }, - } + }) } -// Init for set images. -func Init(platform cluster.Platform) error { +func (s *componentHandler) Init(platform cluster.Platform) error { imageParamMap := map[string]string{ "odh-kueue-controller-image": "RELATED_IMAGE_ODH_KUEUE_CONTROLLER_IMAGE", } diff --git a/controllers/components/kueue/kueue_controller.go b/controllers/components/kueue/kueue_controller.go index 1355f641a1f..32b0356381d 100644 --- a/controllers/components/kueue/kueue_controller.go +++ b/controllers/components/kueue/kueue_controller.go @@ -39,7 +39,7 @@ import ( "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/labels" ) -func NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { +func (s *componentHandler) NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { _, err := reconciler.ComponentReconcilerFor( mgr, componentsv1.KueueInstanceName, diff --git a/controllers/components/modelregistry/modelregistry.go b/controllers/components/modelregistry/modelregistry.go index cc9786a896f..ee6e714d0e1 100644 --- a/controllers/components/modelregistry/modelregistry.go +++ b/controllers/components/modelregistry/modelregistry.go @@ -5,15 +5,31 @@ import ( operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" componentsv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/components/v1" dscv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/datasciencecluster/v1" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" + cr "github.com/opendatahub-io/opendatahub-operator/v2/pkg/componentsregistry" odhdeploy "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/annotations" ) -func Init(_ cluster.Platform) error { +type componentHandler struct{} + +func Init() { + cr.Add(&componentHandler{}) +} + +func (s *componentHandler) GetName() string { + return componentsv1.ModelRegistryComponentName +} + +func (s *componentHandler) GetManagementState(dsc *dscv1.DataScienceCluster) operatorv1.ManagementState { + return dsc.Spec.Components.ModelRegistry.ManagementState +} + +func (s *componentHandler) Init(_ cluster.Platform) error { mi := baseManifestInfo(BaseManifestsSourcePath) params := make(map[string]string) @@ -31,7 +47,7 @@ func Init(_ cluster.Platform) error { return nil } -func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.ModelRegistry { +func (s *componentHandler) NewCRObject(dsc *dscv1.DataScienceCluster) client.Object { //nolint:ireturn componentAnnotations := make(map[string]string) switch dsc.Spec.Components.ModelRegistry.ManagementState { @@ -42,7 +58,7 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.ModelRegistry { componentAnnotations[annotations.ManagementStateAnnotation] = "Unknown" } - return &componentsv1.ModelRegistry{ + return client.Object(&componentsv1.ModelRegistry{ TypeMeta: metav1.TypeMeta{ Kind: componentsv1.ModelRegistryKind, APIVersion: componentsv1.GroupVersion.String(), @@ -54,5 +70,5 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.ModelRegistry { Spec: componentsv1.ModelRegistrySpec{ ModelRegistryCommonSpec: dsc.Spec.Components.ModelRegistry.ModelRegistryCommonSpec, }, - } + }) } diff --git a/controllers/components/modelregistry/modelregistry_controller.go b/controllers/components/modelregistry/modelregistry_controller.go index fe8ba797bf9..3b9fb9dcfec 100644 --- a/controllers/components/modelregistry/modelregistry_controller.go +++ b/controllers/components/modelregistry/modelregistry_controller.go @@ -39,8 +39,7 @@ import ( "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/labels" ) -// NewComponentReconciler creates a ComponentReconciler for the Dashboard API. -func NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { +func (s *componentHandler) NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { _, err := reconciler.ComponentReconcilerFor( mgr, componentsv1.ModelRegistryInstanceName, diff --git a/controllers/components/ray/ray.go b/controllers/components/ray/ray.go index 5b7bfb03fed..2f7ba48951c 100644 --- a/controllers/components/ray/ray.go +++ b/controllers/components/ray/ray.go @@ -5,10 +5,12 @@ import ( operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" componentsv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/components/v1" dscv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/datasciencecluster/v1" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" + cr "github.com/opendatahub-io/opendatahub-operator/v2/pkg/componentsregistry" odhdeploy "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/annotations" ) @@ -21,8 +23,21 @@ var ( DefaultPath = odhdeploy.DefaultManifestPath + "/" + ComponentName + "/openshift" ) -// for DSC to get compoment Ray's CR. -func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.Ray { +type componentHandler struct{} + +func Init() { + cr.Add(&componentHandler{}) +} + +func (s *componentHandler) GetName() string { + return componentsv1.RayComponentName +} + +func (s *componentHandler) GetManagementState(dsc *dscv1.DataScienceCluster) operatorv1.ManagementState { + return dsc.Spec.Components.Ray.ManagementState +} + +func (s *componentHandler) NewCRObject(dsc *dscv1.DataScienceCluster) client.Object { //nolint:ireturn rayAnnotations := make(map[string]string) switch dsc.Spec.Components.Ray.ManagementState { case operatorv1.Managed, operatorv1.Removed: @@ -31,7 +46,7 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.Ray { rayAnnotations[annotations.ManagementStateAnnotation] = "Unknown" } - return &componentsv1.Ray{ + return client.Object(&componentsv1.Ray{ TypeMeta: metav1.TypeMeta{ Kind: componentsv1.RayKind, APIVersion: componentsv1.GroupVersion.String(), @@ -43,11 +58,10 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.Ray { Spec: componentsv1.RaySpec{ RayCommonSpec: dsc.Spec.Components.Ray.RayCommonSpec, }, - } + }) } -// Init for set images. -func Init(platform cluster.Platform) error { +func (s *componentHandler) Init(platform cluster.Platform) error { imageParamMap := map[string]string{ "odh-kuberay-operator-controller-image": "RELATED_IMAGE_ODH_KUBERAY_OPERATOR_CONTROLLER_IMAGE", } diff --git a/controllers/components/ray/ray_controller.go b/controllers/components/ray/ray_controller.go index 83781ace84c..bc6efc23115 100644 --- a/controllers/components/ray/ray_controller.go +++ b/controllers/components/ray/ray_controller.go @@ -37,7 +37,7 @@ import ( "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/labels" ) -func NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { +func (s *componentHandler) NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { _, err := reconciler.ComponentReconcilerFor( mgr, componentsv1.RayInstanceName, diff --git a/controllers/components/trainingoperator/trainingoperator.go b/controllers/components/trainingoperator/trainingoperator.go index 3c51fe8e525..5417c39743e 100644 --- a/controllers/components/trainingoperator/trainingoperator.go +++ b/controllers/components/trainingoperator/trainingoperator.go @@ -5,10 +5,12 @@ import ( operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sclient "sigs.k8s.io/controller-runtime/pkg/client" componentsv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/components/v1" dscv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/datasciencecluster/v1" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" + cr "github.com/opendatahub-io/opendatahub-operator/v2/pkg/componentsregistry" odhdeploy "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/annotations" ) @@ -21,8 +23,21 @@ var ( DefaultPath = odhdeploy.DefaultManifestPath + "/" + ComponentName + "/rhoai" ) -// for DSC to get compoment TrainingOperator's CR. -func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.TrainingOperator { +type componentHandler struct{} + +func Init() { + cr.Add(&componentHandler{}) +} + +func (s *componentHandler) GetName() string { + return componentsv1.TrainingOperatorComponentName +} + +func (s *componentHandler) GetManagementState(dsc *dscv1.DataScienceCluster) operatorv1.ManagementState { + return dsc.Spec.Components.TrainingOperator.ManagementState +} + +func (s *componentHandler) NewCRObject(dsc *dscv1.DataScienceCluster) k8sclient.Object { //nolint:ireturn trainingoperatorAnnotations := make(map[string]string) switch dsc.Spec.Components.TrainingOperator.ManagementState { case operatorv1.Managed, operatorv1.Removed: @@ -31,7 +46,7 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.TrainingOperato trainingoperatorAnnotations[annotations.ManagementStateAnnotation] = "Unknown" } - return &componentsv1.TrainingOperator{ + return k8sclient.Object(&componentsv1.TrainingOperator{ TypeMeta: metav1.TypeMeta{ Kind: componentsv1.TrainingOperatorKind, APIVersion: componentsv1.GroupVersion.String(), @@ -43,11 +58,10 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.TrainingOperato Spec: componentsv1.TrainingOperatorSpec{ TrainingOperatorCommonSpec: dsc.Spec.Components.TrainingOperator.TrainingOperatorCommonSpec, }, - } + }) } -// Init for set images. -func Init(platform cluster.Platform) error { +func (s *componentHandler) Init(platform cluster.Platform) error { imageParamMap := map[string]string{ "odh-training-operator-controller-image": "RELATED_IMAGE_ODH_TRAINING_OPERATOR_IMAGE", } diff --git a/controllers/components/trainingoperator/trainingoperator_controller.go b/controllers/components/trainingoperator/trainingoperator_controller.go index ba65e7e71ee..610c3bf0a4d 100644 --- a/controllers/components/trainingoperator/trainingoperator_controller.go +++ b/controllers/components/trainingoperator/trainingoperator_controller.go @@ -37,7 +37,7 @@ import ( "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/labels" ) -func NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { +func (s *componentHandler) NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { _, err := reconciler.ComponentReconcilerFor( mgr, componentsv1.TrainingOperatorInstanceName, diff --git a/controllers/components/trustyai/trustyai.go b/controllers/components/trustyai/trustyai.go index a166863e3e3..a683bfdb02f 100644 --- a/controllers/components/trustyai/trustyai.go +++ b/controllers/components/trustyai/trustyai.go @@ -5,10 +5,12 @@ import ( operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" componentsv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/components/v1" dscv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/datasciencecluster/v1" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" + cr "github.com/opendatahub-io/opendatahub-operator/v2/pkg/componentsregistry" odhdeploy "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/annotations" ) @@ -27,8 +29,21 @@ var ( } ) -// for DSC to get compoment TrustyAI's CR. -func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.TrustyAI { +type componentHandler struct{} + +func Init() { + cr.Add(&componentHandler{}) +} + +func (s *componentHandler) GetName() string { + return componentsv1.TrustyAIComponentName +} + +func (s *componentHandler) GetManagementState(dsc *dscv1.DataScienceCluster) operatorv1.ManagementState { + return dsc.Spec.Components.TrustyAI.ManagementState +} + +func (s *componentHandler) NewCRObject(dsc *dscv1.DataScienceCluster) client.Object { //nolint:ireturn trustyaiAnnotations := make(map[string]string) switch dsc.Spec.Components.TrustyAI.ManagementState { case operatorv1.Managed, operatorv1.Removed: @@ -37,7 +52,7 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.TrustyAI { trustyaiAnnotations[annotations.ManagementStateAnnotation] = "Unknown" } - return &componentsv1.TrustyAI{ + return client.Object(&componentsv1.TrustyAI{ TypeMeta: metav1.TypeMeta{ Kind: componentsv1.TrustyAIKind, APIVersion: componentsv1.GroupVersion.String(), @@ -49,11 +64,10 @@ func GetComponentCR(dsc *dscv1.DataScienceCluster) *componentsv1.TrustyAI { Spec: componentsv1.TrustyAISpec{ TrustyAICommonSpec: dsc.Spec.Components.TrustyAI.TrustyAICommonSpec, }, - } + }) } -// Init for set images. -func Init(platform cluster.Platform) error { +func (s *componentHandler) Init(platform cluster.Platform) error { imageParamMap := map[string]string{ "trustyaiServiceImage": "RELATED_IMAGE_ODH_TRUSTYAI_SERVICE_IMAGE", "trustyaiOperatorImage": "RELATED_IMAGE_ODH_TRUSTYAI_SERVICE_OPERATOR_IMAGE", diff --git a/controllers/components/trustyai/trustyai_controller.go b/controllers/components/trustyai/trustyai_controller.go index 82ebfd6461d..85e602d6d85 100644 --- a/controllers/components/trustyai/trustyai_controller.go +++ b/controllers/components/trustyai/trustyai_controller.go @@ -36,7 +36,7 @@ import ( "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/labels" ) -func NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { +func (s *componentHandler) NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error { _, err := reconciler.ComponentReconcilerFor( mgr, componentsv1.TrustyAIInstanceName, diff --git a/controllers/datasciencecluster/datasciencecluster_controller.go b/controllers/datasciencecluster/datasciencecluster_controller.go index 494a69c8fda..649ac52bd8a 100644 --- a/controllers/datasciencecluster/datasciencecluster_controller.go +++ b/controllers/datasciencecluster/datasciencecluster_controller.go @@ -25,7 +25,6 @@ import ( "time" "github.com/go-logr/logr" - "github.com/hashicorp/go-multierror" buildv1 "github.com/openshift/api/build/v1" imagev1 "github.com/openshift/api/image/v1" operatorv1 "github.com/openshift/api/operator/v1" @@ -52,15 +51,10 @@ import ( componentsv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/components/v1" dscv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/datasciencecluster/v1" dsciv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/v1" - dashboardctrl "github.com/opendatahub-io/opendatahub-operator/v2/controllers/components/dashboard" datasciencepipelinesctrl "github.com/opendatahub-io/opendatahub-operator/v2/controllers/components/datasciencepipelines" - kueuectrl "github.com/opendatahub-io/opendatahub-operator/v2/controllers/components/kueue" - modelregistryctrl "github.com/opendatahub-io/opendatahub-operator/v2/controllers/components/modelregistry" - rayctrl "github.com/opendatahub-io/opendatahub-operator/v2/controllers/components/ray" - trainingoperatorctrl "github.com/opendatahub-io/opendatahub-operator/v2/controllers/components/trainingoperator" - trustyaictrl "github.com/opendatahub-io/opendatahub-operator/v2/controllers/components/trustyai" "github.com/opendatahub-io/opendatahub-operator/v2/controllers/status" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" + cr "github.com/opendatahub-io/opendatahub-operator/v2/pkg/componentsregistry" odhClient "github.com/opendatahub-io/opendatahub-operator/v2/pkg/controller/client" annotations "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/annotations" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/labels" @@ -88,7 +82,7 @@ const ( // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. -func (r *DataScienceClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { //nolint:maintidx,gocyclo +func (r *DataScienceClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { //nolint:maintidx log := r.Log log.Info("Reconciling DataScienceCluster resources", "Request.Name", req.Name) @@ -228,66 +222,11 @@ func (r *DataScienceClusterReconciler) Reconcile(ctx context.Context, req ctrl.R } } - // Initialize error list, instead of returning errors after every component is deployed - var componentErrors *multierror.Error - - // Deploy Dashboard - if instance, err = r.ReconcileComponent(ctx, instance, componentsv1.DashboardComponentName, func() (error, bool) { - // Get the Dashboard instance - dashboard := dashboardctrl.GetComponentCR(instance) - // Reconcile component either create CR with setting owner or delete it - return r.apply(ctx, instance, dashboard), instance.Spec.Components.Dashboard.ManagementState == operatorv1.Managed - }); err != nil { - componentErrors = multierror.Append(componentErrors, err) - } - - // Deploy Ray - if instance, err = r.ReconcileComponent(ctx, instance, componentsv1.RayComponentName, func() (error, bool) { - ray := rayctrl.GetComponentCR(instance) - return r.apply(ctx, instance, ray), instance.Spec.Components.Ray.ManagementState == operatorv1.Managed - }); err != nil { - componentErrors = multierror.Append(componentErrors, err) - } - - // Deploy Model Registry - if instance, err = r.ReconcileComponent(ctx, instance, componentsv1.ModelRegistryComponentName, func() (error, bool) { - modelregistry := modelregistryctrl.GetComponentCR(instance) - return r.apply(ctx, instance, modelregistry), instance.Spec.Components.ModelRegistry.ManagementState == operatorv1.Managed - }); err != nil { - componentErrors = multierror.Append(componentErrors, err) - } - - // Deploy TrustyAI - if instance, err = r.ReconcileComponent(ctx, instance, componentsv1.TrustyAIComponentName, func() (error, bool) { - trustyai := trustyaictrl.GetComponentCR(instance) - return r.apply(ctx, instance, trustyai), instance.Spec.Components.TrustyAI.ManagementState == operatorv1.Managed - }); err != nil { - componentErrors = multierror.Append(componentErrors, err) - } - - // Deploy Kueue - if instance, err = r.ReconcileComponent(ctx, instance, componentsv1.KueueComponentName, func() (error, bool) { - kueue := kueuectrl.GetComponentCR(instance) - return r.apply(ctx, instance, kueue), instance.Spec.Components.Kueue.ManagementState == operatorv1.Managed - }); err != nil { - componentErrors = multierror.Append(componentErrors, err) - } - - // Deploy TrainingOperator - if instance, err = r.ReconcileComponent(ctx, instance, componentsv1.TrainingOperatorComponentName, func() (error, bool) { - trainingoperator := trainingoperatorctrl.GetComponentCR(instance) - return r.apply(ctx, instance, trainingoperator), instance.Spec.Components.TrainingOperator.ManagementState == operatorv1.Managed - }); err != nil { - componentErrors = multierror.Append(componentErrors, err) - } - - // Deploy DataSciencePipelines - if instance, err = r.ReconcileComponent(ctx, instance, componentsv1.DataSciencePipelinesComponentName, func() (error, bool) { - dsp := datasciencepipelinesctrl.GetComponentCR(instance) - return r.apply(ctx, instance, dsp), instance.Spec.Components.DataSciencePipelines.ManagementState == operatorv1.Managed - }); err != nil { - componentErrors = multierror.Append(componentErrors, err) - } + componentErrors := cr.ForEach(func(component cr.ComponentHandler) error { + var err error + instance, err = r.ReconcileComponent(ctx, instance, component) + return err + }) // Process errors for components if componentErrors != nil { @@ -329,20 +268,23 @@ func (r *DataScienceClusterReconciler) Reconcile(ctx context.Context, req ctrl.R return ctrl.Result{}, nil } -type ComponentHandler func() (error, bool) - -// TODO: make it generic for all components. func (r *DataScienceClusterReconciler) ReconcileComponent( ctx context.Context, instance *dscv1.DataScienceCluster, - componentName string, - componentRec ComponentHandler, + component cr.ComponentHandler, ) (*dscv1.DataScienceCluster, error) { + componentName := component.GetName() + r.Log.Info("Starting reconciliation of component: " + componentName) - err, enabled := componentRec() - _, isExistStatus := instance.Status.InstalledComponents[componentName] + enabled := component.GetManagementState(instance) == operatorv1.Managed + componentCR := component.NewCRObject(instance) + err := r.apply(ctx, instance, componentCR) + if err != nil { + return instance, err + } + _, isExistStatus := instance.Status.InstalledComponents[componentName] if !isExistStatus { message := "Component is disabled" if enabled { diff --git a/main.go b/main.go index 16e61f416c2..cd73bccd24e 100644 --- a/main.go +++ b/main.go @@ -21,7 +21,6 @@ import ( "flag" "os" - "github.com/hashicorp/go-multierror" addonv1alpha1 "github.com/openshift/addon-operator/apis/addons/v1alpha1" ocappsv1 "github.com/openshift/api/apps/v1" //nolint:importas //reason: conflicts with appsv1 "k8s.io/api/apps/v1" buildv1 "github.com/openshift/api/build/v1" @@ -76,6 +75,7 @@ import ( "github.com/opendatahub-io/opendatahub-operator/v2/controllers/webhook" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster/gvk" + cr "github.com/opendatahub-io/opendatahub-operator/v2/pkg/componentsregistry" odhClient "github.com/opendatahub-io/opendatahub-operator/v2/pkg/controller/client" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/logger" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/resources" @@ -119,31 +119,17 @@ func init() { //nolint:gochecknoinits } func initComponents(_ context.Context, p cluster.Platform) error { - var multiErr *multierror.Error - - if err := dashboardctrl.Init(p); err != nil { - multiErr = multierror.Append(multiErr, err) - } - if err := rayctrl.Init(p); err != nil { - multiErr = multierror.Append(multiErr, err) - } - if err := modelregistryctrl.Init(p); err != nil { - return err - } - if err := trainingoperatorctrl.Init(p); err != nil { - return err - } - if err := trustyaictrl.Init(p); err != nil { - return err - } - if err := datasciencepipelinesctrl.Init(p); err != nil { - multiErr = multierror.Append(multiErr, err) - } - - if err := kueuectrl.Init(p); err != nil { - multiErr = multierror.Append(multiErr, err) - } - return multiErr.ErrorOrNil() + dashboardctrl.Init() + rayctrl.Init() + modelregistryctrl.Init() + trainingoperatorctrl.Init() + trustyaictrl.Init() + kueuectrl.Init() + datasciencepipelinesctrl.Init() + + return cr.ForEach(func(ch cr.ComponentHandler) error { + return ch.Init(p) + }) } func main() { //nolint:funlen,maintidx @@ -436,36 +422,8 @@ func createDeploymentCacheConfig(platform cluster.Platform) map[string]cache.Con } func CreateComponentReconcilers(ctx context.Context, mgr manager.Manager) error { - // TODO: add more here or make it go routine - if err := dashboardctrl.NewComponentReconciler(ctx, mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "DashboardReconciler") - return err - } - - if err := rayctrl.NewComponentReconciler(ctx, mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "RayReconciler") - return err - } - if err := modelregistryctrl.NewComponentReconciler(ctx, mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "ModelRegistryReconciler") - return err - } - if err := trustyaictrl.NewComponentReconciler(ctx, mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "TrustyAIReconciler") - return err - } - if err := kueuectrl.NewComponentReconciler(ctx, mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "KueueReconciler") - return err - } - if err := trainingoperatorctrl.NewComponentReconciler(ctx, mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "TrainingOperatorReconciler") - return err - } - if err := datasciencepipelinesctrl.NewComponentReconciler(ctx, mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "DataSciencePipelinesReconciler") - return err - } - - return nil + // TODO: can it be moved to initComponents? + return cr.ForEach(func(ch cr.ComponentHandler) error { + return ch.NewComponentReconciler(ctx, mgr) + }) } diff --git a/pkg/componentsregistry/componentsregistry.go b/pkg/componentsregistry/componentsregistry.go new file mode 100644 index 00000000000..c6591d1a218 --- /dev/null +++ b/pkg/componentsregistry/componentsregistry.go @@ -0,0 +1,49 @@ +// componentsregistry package is a registry of all components that can be managed by the operator +// TODO: it may make sense to put it under components/ when it's clear from the old stuff +package componentsregistry + +import ( + "context" + + "github.com/hashicorp/go-multierror" + operatorv1 "github.com/openshift/api/operator/v1" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + dscv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/datasciencecluster/v1" + "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" +) + +// ComponentHandler is an interface to manage a component +// Every method should accept ctx since it contains the logger. +type ComponentHandler interface { + Init(platform cluster.Platform) error + // GetName and GetManagementState sound like pretty much the same across + // all components, but I could not find a way to avoid it + GetName() string + GetManagementState(dsc *dscv1.DataScienceCluster) operatorv1.ManagementState + // NewCRObject constructs components specific Custom Resource + // e.g. Dashboard in datasciencecluster.opendatahub.io group + // It returns interface, but it simplifies DSC reconciler code a lot + NewCRObject(dsc *dscv1.DataScienceCluster) client.Object + NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error +} + +var registry = []ComponentHandler{} + +// Add registers a new component handler +// not thread safe, supposed to be called during init. +// TODO: check if init() can be called in parallel. +func Add(ch ComponentHandler) { + registry = append(registry, ch) +} + +// ForEach iterates over all registered component handlers +// With go1.23 probably https://go.dev/blog/range-functions can be used. +func ForEach(f func(ch ComponentHandler) error) error { + var errs *multierror.Error + for _, ch := range registry { + errs = multierror.Append(errs, f(ch)) + } + return errs.ErrorOrNil() +}