Skip to content

Commit

Permalink
Adding scafolding for status reporting. opendatahub-io#158
Browse files Browse the repository at this point in the history
  • Loading branch information
etirelli committed Jun 11, 2023
1 parent f20aee4 commit a56eca8
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 25 deletions.
20 changes: 14 additions & 6 deletions api/v1alpha1/dscinitialization_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// List of constants to show different different reconciliation messages and statuses.
const (
ReconcileFailed = "ReconcileFailed"
ReconcileInit = "ReconcileInit"
ReconcileCompleted = "ReconcileCompleted"
ReconcileCompletedMessage = "Reconcile completed successfully"
)

// DSCInitializationSpec defines the desired state of DSCInitiatlization
type DSCInitializationSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
Expand Down Expand Up @@ -57,8 +65,8 @@ type DSCInitiatlizationStatus struct {
//+kubebuilder:printcolumn:name="Created At",type=string,JSONPath=.metadata.creationTimestamp
//+operator-sdk:csv:customresourcedefinitions:displayName="DSC Initialization"

// DSCInitiatlization is the Schema for the dscinitiatlizations API
type DSCInitiatlization struct {
// DSCInitialization is the Schema for the dscinitiatlizations API
type DSCInitialization struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Expand All @@ -68,13 +76,13 @@ type DSCInitiatlization struct {

//+kubebuilder:object:root=true

// DSCInitiatlizationList contains a list of DSCInitiatlization
type DSCInitiatlizationList struct {
// DSCInitializationList contains a list of DSCInitiatlization
type DSCInitializationList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []DSCInitiatlization `json:"items"`
Items []DSCInitialization `json:"items"`
}

func init() {
SchemeBuilder.Register(&DSCInitiatlization{}, &DSCInitiatlizationList{})
SchemeBuilder.Register(&DSCInitialization{}, &DSCInitializationList{})
}
18 changes: 9 additions & 9 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 45 additions & 9 deletions controllers/dscinitiatlization_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,21 @@ import (
"context"

"k8s.io/apimachinery/pkg/runtime"
"k8s.io/klog/v2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

dscinitializationv1alpha1 "github.com/opendatahub-io/opendatahub-operator/api/v1alpha1"
"github.com/go-logr/logr"
dsci "github.com/opendatahub-io/opendatahub-operator/api/v1alpha1"
)

// DSCInitiatlizationReconciler reconciles a DSCInitiatlization object
type DSCInitiatlizationReconciler struct {
// DSCInitializationReconciler reconciles a DSCInitiatlization object
type DSCInitializationReconciler struct {
client.Client
Scheme *runtime.Scheme
ctx context.Context
Log logr.Logger
}

//+kubebuilder:rbac:groups=dscinitialization.opendatahub.io,resources=dscinitiatlizations,verbs=get;list;watch;create;update;patch;delete
Expand All @@ -46,17 +50,49 @@ type DSCInitiatlizationReconciler struct {
//
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.14.1/pkg/reconcile
func (r *DSCInitiatlizationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
_ = log.FromContext(ctx)
func (r *DSCInitializationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {

// TODO(user): your logic here
//_ = log.FromContext(ctx)
prevLogger := r.Log
defer func() { r.Log = prevLogger }()
r.Log = r.Log.WithValues("Request.Namespace", req.Namespace, "Request.Name", req.Name)
r.ctx = ctx

r.Log.Info("Reconciling OCSInitialization.", "OCSInitialization", klog.KRef(req.Namespace, req.Name))

instance := &dsci.DSCInitialization{}
err := r.Client.Get(ctx, req.NamespacedName, instance)

// Start reconciling
if instance.Status.Conditions == nil {
reason := dsci.ReconcileInit
message := "Initializing DSCInitialization resource"
SetProgressingCondition(&instance.Status.Conditions, reason, message)

instance.Status.Phase = PhaseProgressing
err = r.Client.Status().Update(ctx, instance)
if err != nil {
r.Log.Error(err, "Failed to add conditions to status of OCSInitialization resource.", "OCSInitialization", klog.KRef(instance.Namespace, instance.Name))
return reconcile.Result{}, err
}
}

// ADD RECONCILIATION LOGIC HERE

// Finish reconciling
reason := dsci.ReconcileCompleted
message := dsci.ReconcileCompletedMessage
SetCompleteCondition(&instance.Status.Conditions, reason, message)

instance.Status.Phase = PhaseReady
err = r.Client.Status().Update(ctx, instance)

return ctrl.Result{}, nil
}

// SetupWithManager sets up the controller with the Manager.
func (r *DSCInitiatlizationReconciler) SetupWithManager(mgr ctrl.Manager) error {
func (r *DSCInitializationReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&dscinitializationv1alpha1.DSCInitiatlization{}).
For(&dsci.DSCInitialization{}).
Complete(r)
}
148 changes: 148 additions & 0 deletions controllers/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
Copyright 2023.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package controllers

import (
conditionsv1 "github.com/openshift/custom-resource-status/conditions/v1"
corev1 "k8s.io/api/core/v1"
)

// These constants represent the overall Phase as used by .Status.Phase
var (
// PhaseIgnored is used when a resource is ignored
PhaseIgnored = "Ignored"
// PhaseProgressing is used when SetProgressingCondition is called
PhaseProgressing = "Progressing"
// PhaseError is used when SetErrorCondition is called
PhaseError = "Error"
// PhaseReady is used when SetCompleteCondition is called
PhaseReady = "Ready"
// PhaseNotReady is used when waiting for system to be ready
// after reconcile is successful
PhaseNotReady = "Not Ready"
// PhaseClusterExpanding is used when cluster is expanding capacity
PhaseClusterExpanding = "Expanding Capacity"
// PhaseDeleting is used when cluster is deleting
PhaseDeleting = "Deleting"
// PhaseConnecting is used when cluster is connecting to external cluster
PhaseConnecting = "Connecting"
// PhaseOnboarding is used when consumer is Onboarding
PhaseOnboarding = "Onboarding"
)

const (
ConditionReconcileComplete conditionsv1.ConditionType = "ReconcileComplete"
)

const (
// TODO: update this list of constants with proper reasons for conditions
AReason = "AReason"
AnotherReason = "AnotherReason"
)

// 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) {
conditionsv1.SetStatusCondition(conditions, conditionsv1.Condition{
Type: ConditionReconcileComplete,
Status: corev1.ConditionUnknown,
Reason: reason,
Message: message,
})
conditionsv1.SetStatusCondition(conditions, conditionsv1.Condition{
Type: conditionsv1.ConditionAvailable,
Status: corev1.ConditionFalse,
Reason: reason,
Message: message,
})
conditionsv1.SetStatusCondition(conditions, conditionsv1.Condition{
Type: conditionsv1.ConditionProgressing,
Status: corev1.ConditionTrue,
Reason: reason,
Message: message,
})
conditionsv1.SetStatusCondition(conditions, conditionsv1.Condition{
Type: conditionsv1.ConditionDegraded,
Status: corev1.ConditionFalse,
Reason: reason,
Message: message,
})
conditionsv1.SetStatusCondition(conditions, conditionsv1.Condition{
Type: conditionsv1.ConditionUpgradeable,
Status: corev1.ConditionUnknown,
Reason: reason,
Message: message,
})
}

// SetErrorCondition sets the ConditionReconcileComplete to False in case of any errors
// during the reconciliation process.
func SetErrorCondition(conditions *[]conditionsv1.Condition, reason string, message string) {
conditionsv1.SetStatusCondition(conditions, conditionsv1.Condition{
Type: ConditionReconcileComplete,
Status: corev1.ConditionFalse,
Reason: reason,
Message: message,
})
}

// SetCompleteCondition sets the ConditionReconcileComplete to True and other Conditions
// to indicate that the reconciliation process has completed successfully.
func SetCompleteCondition(conditions *[]conditionsv1.Condition, reason string, message string) {
conditionsv1.SetStatusCondition(conditions, conditionsv1.Condition{
Type: ConditionReconcileComplete,
Status: corev1.ConditionTrue,
Reason: reason,
Message: message,
})
conditionsv1.SetStatusCondition(conditions, conditionsv1.Condition{
Type: conditionsv1.ConditionAvailable,
Status: corev1.ConditionTrue,
Reason: reason,
Message: message,
})
conditionsv1.SetStatusCondition(conditions, conditionsv1.Condition{
Type: conditionsv1.ConditionProgressing,
Status: corev1.ConditionFalse,
Reason: reason,
Message: message,
})
conditionsv1.SetStatusCondition(conditions, conditionsv1.Condition{
Type: conditionsv1.ConditionDegraded,
Status: corev1.ConditionFalse,
Reason: reason,
Message: message,
})
conditionsv1.SetStatusCondition(conditions, conditionsv1.Condition{
Type: conditionsv1.ConditionUpgradeable,
Status: corev1.ConditionTrue,
Reason: reason,
Message: message,
})
}

// won't override a status condition of the same type and status
func setStatusConditionIfNotPresent(conditions *[]conditionsv1.Condition, condition conditionsv1.Condition) {

foundCondition := conditionsv1.FindStatusCondition(*conditions, condition.Type)
if foundCondition != nil && foundCondition.Status == condition.Status {
// already exists
return
}

conditionsv1.SetStatusCondition(conditions, condition)
}
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func main() {
os.Exit(1)
}

if err = (&controllers.DSCInitiatlizationReconciler{
if err = (&controllers.DSCInitializationReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
Expand Down

0 comments on commit a56eca8

Please sign in to comment.