Skip to content

Commit

Permalink
refactor: added pre-conditions for DSP controller
Browse files Browse the repository at this point in the history
  • Loading branch information
jackdelahunt committed Nov 11, 2024
1 parent a653d30 commit 8acd4a2
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ func NewComponentReconciler(ctx context.Context, mgr ctrl.Manager) error {
Owns(&securityv1.SecurityContextConstraints{}).
Watches(&extv1.CustomResourceDefinition{}). // call ForLabel() + new predicates
// Add datasciencepipelines-specific actions
WithAction(checkPreConditions).
WithAction(initialize).
WithAction(devFlags).
WithAction(UnmanagedArgoWorkFlowExists).
WithAction(kustomize.NewAction(
kustomize.WithCache(kustomize.DefaultCachingKeyFn),
kustomize.WithLabel(labels.ODH.Component(componentsv1.DataSciencePipelinesComponentName), "true"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,62 @@ package datasciencepipelines

import (
"context"
"errors"
"fmt"

corev1 "k8s.io/api/core/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
k8serr "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
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"
"github.com/opendatahub-io/opendatahub-operator/v2/controllers/status"
odherrors "github.com/opendatahub-io/opendatahub-operator/v2/pkg/controller/actions/errors"
odhtypes "github.com/opendatahub-io/opendatahub-operator/v2/pkg/controller/types"
odhdeploy "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/labels"
)

func checkPreConditions(ctx context.Context, rr *odhtypes.ReconciliationRequest) error {
dsp, ok := rr.Instance.(*componentsv1.DataSciencePipelines)
if !ok {
return fmt.Errorf("resource instance %v is not a componentsv1.DataSciencePipelines", rr.Instance)
}

// Check preconditions if this is an upgrade
if rr.Instance.GetStatus().Phase != status.PhaseReady {
return nil
}

workflowCRD := &apiextensionsv1.CustomResourceDefinition{}
if err := rr.Client.Get(ctx, client.ObjectKey{Name: ArgoWorkflowCRD}, workflowCRD); err != nil {
if k8serr.IsNotFound(err) {
return nil
}
return odherrors.NewStopError("failed to get existing Workflow CRD : %v", err)
}

// Verify if existing workflow is deployed by ODH with label
// if not then set Argo capability status condition to false
odhLabelValue, odhLabelExists := workflowCRD.Labels[labels.ODH.Component(componentsv1.DataSciencePipelinesComponentName)]
if !odhLabelExists || odhLabelValue != "true" {
s := dsp.GetStatus()
s.Phase = "NotReady"

meta.SetStatusCondition(&s.Conditions, metav1.Condition{
Type: status.ConditionTypeReady,
Status: metav1.ConditionFalse,
Reason: status.DataSciencePipelinesDoesntOwnArgoCRDReason,
Message: status.DataSciencePipelinesDoesntOwnArgoCRDMessage,
ObservedGeneration: s.ObservedGeneration,
})

return odherrors.NewStopError(status.DataSciencePipelinesDoesntOwnArgoCRDMessage)
}

return nil
}

func initialize(ctx context.Context, rr *odhtypes.ReconciliationRequest) error {
rr.Manifests = append(rr.Manifests, odhtypes.ManifestInfo{
Path: DefaultPath,
Expand Down Expand Up @@ -72,32 +113,3 @@ func devFlags(ctx context.Context, rr *odhtypes.ReconciliationRequest) error {

return nil
}

func UnmanagedArgoWorkFlowExists(ctx context.Context, rr *odhtypes.ReconciliationRequest) error {
// Check preconditions if this is an upgrade
if rr.Instance.GetStatus().Phase != status.PhaseReady {
return nil
}

workflowCRD := &apiextensionsv1.CustomResourceDefinition{}
if err := rr.Client.Get(ctx, client.ObjectKey{Name: ArgoWorkflowCRD}, workflowCRD); err != nil {
if k8serr.IsNotFound(err) {
return nil
}
return fmt.Errorf("failed to get existing Workflow CRD : %w", err)
}

// Verify if existing workflow is deployed by ODH with label
// if not then set Argo capability condition to false
odhLabelValue, odhLabelExists := workflowCRD.Labels[labels.ODH.Component(componentsv1.DataSciencePipelinesComponentName)]
if !odhLabelExists || odhLabelValue != "true" {
message := fmt.Sprintf("Failed upgrade: %s CRD already exists but not deployed by this operator"+
"Remove existing Argo workflows or set `spec.components.datasciencepipelines.managementState` to Removed to proceed", ArgoWorkflowCRD)

status.SetCondition(&rr.DSC.Status.Conditions, string(status.CapabilityDSPv2Argo), status.ArgoWorkflowExist, message, corev1.ConditionFalse)

return errors.New(message)
}

return nil
}
6 changes: 6 additions & 0 deletions controllers/status/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ const (
ServiceMeshNotConfiguredMessage = "ServiceMesh needs to be set to 'Managed' in DSCI CR"
)

const (
DataSciencePipelinesDoesntOwnArgoCRDReason = "DataSciencePipelinesDoesntOwnArgoCRD"
DataSciencePipelinesDoesntOwnArgoCRDMessage = "Failed upgrade: workflows.argoproj.io CRD already exists but not deployed by this operator " +
"remove existing Argo workflows or set `spec.components.datasciencepipelines.managementState` to Removed to proceed"
)

// SetProgressingCondition sets the ProgressingCondition to True and other conditions to false or
// Unknown. Used when we are just starting to reconcile, and there are no existing conditions.
func SetProgressingCondition(conditions *[]conditionsv1.Condition, reason string, message string) {
Expand Down

0 comments on commit 8acd4a2

Please sign in to comment.