Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for custom subscription config #446

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions controllers/datasciencecluster/datasciencecluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ package datasciencecluster
import (
"context"
"fmt"
dsci "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/v1alpha1"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"
"time"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -115,6 +119,36 @@ func (r *DataScienceClusterReconciler) Reconcile(ctx context.Context, req ctrl.R
}
}

// Verify a valid DSCInitialization instance is created
dsciInstances := &dsci.DSCInitializationList{}
err = r.Client.List(ctx, dsciInstances)
if err != nil {
r.Log.Error(err, "Failed to retrieve DSCInitialization resource.", "DSCInitialization", req.Namespace, "Request.Name", req.Name)
r.Recorder.Eventf(instance, corev1.EventTypeWarning, "DSCInitializationReconcileError", "Failed to retrieve DSCInitialization instance")
return ctrl.Result{}, err
}

// Update phase to error state if DataScienceCluster is created without valid DSCInitialization
if len(dsciInstances.Items) == 0 {
reason := status.ReconcileFailed
message := "Failed to get a valid DSCInitialization instance"
instance, err = r.updateStatus(instance, func(saved *dsc.DataScienceCluster) {
status.SetProgressingCondition(&saved.Status.Conditions, reason, message)
saved.Status.Phase = status.PhaseError
})
if err != nil {
r.Log.Error(err, "failed to update DataScienceCluster condition")
return ctrl.Result{}, err
} else {
return ctrl.Result{}, nil
}
} else if len(dsciInstances.Items) == 1 {
// Set Applications namespace defined in DSCInitialization
r.ApplicationsNamespace = dsciInstances.Items[0].Spec.ApplicationsNamespace
} else {
return ctrl.Result{}, fmt.Errorf(fmt.Sprintf("only one instance of DSCInitialization object is allowed."))
}

// Ensure all omitted components show up as explicitly disabled
instance, err = r.updateComponents(instance)
if err != nil {
Expand Down Expand Up @@ -282,6 +316,7 @@ func (r *DataScienceClusterReconciler) SetupWithManager(mgr ctrl.Manager) error
Owns(&appsv1.Deployment{}).
Owns(&appsv1.ReplicaSet{}).
Owns(&corev1.Pod{}).
Watches(&source.Kind{Type: &dsci.DSCInitialization{}}, handler.EnqueueRequestsFromMapFunc(r.watchDataScienceClusterResources)).
zdtsw marked this conversation as resolved.
Show resolved Hide resolved
// this predicates prevents meaningless reconciliations from being triggered
WithEventFilter(predicate.Or(predicate.GenerationChangedPredicate{}, predicate.LabelChangedPredicate{})).
Complete(r)
Expand Down Expand Up @@ -324,3 +359,17 @@ func (r *DataScienceClusterReconciler) updateComponents(original *dsc.DataScienc
})
return saved, err
}

func (r *DataScienceClusterReconciler) watchDataScienceClusterResources(a client.Object) (requests []reconcile.Request) {
instanceList := &dsc.DataScienceClusterList{}
err := r.Client.List(context.TODO(), instanceList)
if err != nil {
return nil
}
if len(instanceList.Items) == 1 {
return []reconcile.Request{{
NamespacedName: types.NamespacedName{Name: instanceList.Items[0].Name}}}
} else {
return nil
}
}
24 changes: 21 additions & 3 deletions controllers/dscinitialization/dscinitialization_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package dscinitialization
import (
"context"
"errors"
"fmt"
"github.com/opendatahub-io/opendatahub-operator/v2/pkg/common"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

Expand Down Expand Up @@ -71,18 +72,35 @@ func (r *DSCInitializationReconciler) Reconcile(ctx context.Context, req ctrl.Re
r.Log.Info("Reconciling DSCInitialization.", "DSCInitialization", req.Namespace, "Request.Name", req.Name)

instance := &dsci.DSCInitialization{}
// Only apply reconcile logic to 'default' instance of DataScienceInitialization
err := r.Client.Get(ctx, types.NamespacedName{Name: "default"}, instance)
// First check if instance is being deleted, return
if instance.GetDeletionTimestamp() != nil {
return ctrl.Result{}, nil
}

// Second check if instance exists, return
err := r.Client.Get(context.TODO(), types.NamespacedName{Name: req.Name}, instance)
if err != nil {
if apierrs.IsNotFound(err) {
// DataScienceInitialization instance not found.
// DSCInitialization instance not found
return ctrl.Result{}, nil
}
r.Log.Error(err, "Failed to retrieve DSCInitialization resource.", "DSCInitialization", req.Namespace, "Request.Name", req.Name)
r.Recorder.Eventf(instance, corev1.EventTypeWarning, "DSCInitializationReconcileError", "Failed to retrieve DSCInitialization instance")
return ctrl.Result{}, err
}

// Last check if multiple instances of DSCInitialization exist
instanceList := &dsci.DSCInitializationList{}
err = r.Client.List(context.TODO(), instanceList)
if err != nil {
return ctrl.Result{}, err
}

if len(instanceList.Items) > 1 {
message := fmt.Sprintf("only one instance of DSCInitialization object is allowed. Update existing instance on namespace %s and name %s", req.Namespace, req.Name)
return ctrl.Result{}, fmt.Errorf(message)
}

// Start reconciling
if instance.Status.Conditions == nil {
reason := status.ReconcileInit
Expand Down
73 changes: 38 additions & 35 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,45 +156,48 @@ func main() {
}

//+kubebuilder:scaffold:builder

// Create OCSInitialization CR if it's not present
client := mgr.GetClient()
releaseDscInitialization := &dsci.DSCInitialization{
TypeMeta: metav1.TypeMeta{
Kind: "DSCInitialization",
APIVersion: "dscinitialization.opendatahub.io/v1alpha1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "default",
},
Spec: dsci.DSCInitializationSpec{
ApplicationsNamespace: dscApplicationsNamespace,
Monitoring: dsci.Monitoring{
Enabled: false,
// Check if user opted for disabling DSC configuration
_, disableDSCConfig := os.LookupEnv("DISABLE_DSC_CONFIG")
if !disableDSCConfig {
// Create DSCInitialization CR if it's not present
client := mgr.GetClient()
releaseDscInitialization := &dsci.DSCInitialization{
TypeMeta: metav1.TypeMeta{
Kind: "DSCInitialization",
APIVersion: "dscinitialization.opendatahub.io/v1alpha1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "default",
},
Spec: dsci.DSCInitializationSpec{
ApplicationsNamespace: dscApplicationsNamespace,
Monitoring: dsci.Monitoring{
Enabled: false,
},
},
},
}
err = client.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 = client.Patch(context.TODO(), releaseDscInitialization, client2.RawPatch(types.ApplyPatchType, data),
client2.ForceOwnership, client2.FieldOwner("opendatahub-operator"))
if err != nil {
setupLog.Error(err, "failed to update DscInitialization custom resource")
err = client.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 = client.Patch(context.TODO(), releaseDscInitialization, client2.RawPatch(types.ApplyPatchType, data),
client2.ForceOwnership, client2.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)
}
default:
setupLog.Error(err, "failed to create DscInitialization custom resource")
os.Exit(1)
}

}
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up health check")
os.Exit(1)
Expand Down