diff --git a/api/v1alpha1/groupversion_info.go b/api/v1alpha1/groupversion_info.go index 38bb6d3..bd6b632 100644 --- a/api/v1alpha1/groupversion_info.go +++ b/api/v1alpha1/groupversion_info.go @@ -15,8 +15,8 @@ limitations under the License. */ // Package v1alpha1 contains API Schema definitions for the resource-management v1alpha1 API group -//+kubebuilder:object:generate=true -//+groupName=resource-management.tikalk.com +// +kubebuilder:object:generate=true +// +groupName=resource-management.tikalk.com package v1alpha1 import ( diff --git a/api/v1alpha1/resourcemanager_types.go b/api/v1alpha1/resourcemanager_types.go index e2736c3..71ce2b3 100644 --- a/api/v1alpha1/resourcemanager_types.go +++ b/api/v1alpha1/resourcemanager_types.go @@ -58,6 +58,8 @@ type ExpiryCondition struct { type ResourceManagerStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster // Important: Run "make" to regenerate code after modifying this file + // Conditions is the list of status condition updates + Conditions []metav1.Condition `json:"conditions"` } //+kubebuilder:object:root=true diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 77a1abc..e1de7a9 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -53,7 +53,7 @@ func (in *ResourceManager) DeepCopyInto(out *ResourceManager) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) - out.Status = in.Status + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceManager. @@ -134,6 +134,13 @@ func (in *ResourceManagerSpec) DeepCopy() *ResourceManagerSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ResourceManagerStatus) DeepCopyInto(out *ResourceManagerStatus) { *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceManagerStatus. diff --git a/controllers/resourcemanager_controller.go b/controllers/resourcemanager_controller.go index 22044b0..2f3bb32 100644 --- a/controllers/resourcemanager_controller.go +++ b/controllers/resourcemanager_controller.go @@ -19,15 +19,18 @@ package controllers import ( "context" "fmt" + "time" + resourcemanagmentv1alpha1 "github.com/tikalk/resource-manager/api/v1alpha1" appsv1 "k8s.io/api/apps/v1" - + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + utilerrors "k8s.io/apimachinery/pkg/util/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" - - resourcemanagmentv1alpha1 "github.com/tikalk/resource-manager/api/v1alpha1" ) // ResourceManagerReconciler reconciles a ResourceManager object @@ -54,10 +57,25 @@ func (r *ResourceManagerReconciler) Reconcile(ctx context.Context, req ctrl.Requ name := req.NamespacedName.String() // your logic here + // Get the resourcemanager Operator object. resourceManagerObj := &resourcemanagmentv1alpha1.ResourceManager{} err := r.Get(ctx, req.NamespacedName, resourceManagerObj) - if err != nil { - l.Error(err, fmt.Sprintf("Failed reconcile obj %s", name)) + // If one is not found, log a message + if err != nil && errors.IsNotFound(err) { + l.Error(err, fmt.Sprintf("Failed reconcile obj %s , Operator resource not found", name)) + + // If the Operator is unable to access its custom resource (for any reason besides a simple IsNotFound error) + // set the OperatorDegraded condition to True with the reason OperatorResourceNotAvailable. + } else if err != nil { + l.Error(err, "Error getting operator resource object") + meta.SetStatusCondition(&resourceManagerObj.Status.Conditions, metav1.Condition{ + Type: "OperatorDegraded", + Status: metav1.ConditionTrue, + Reason: "OperatorResourceNotAvailable", + LastTransitionTime: metav1.NewTime(time.Now()), + Message: fmt.Sprintf("unable to get operator custom resource: %s", err.Error()), + }) + return ctrl.Result{}, utilerrors.NewAggregate([]error{err, r.Status().Update(ctx, resourceManagerObj)}) } // pods, err := clientset.CoreV1().Pods("").List(context.TODO(), metav1.ListOptions{}) @@ -72,9 +90,17 @@ func (r *ResourceManagerReconciler) Reconcile(ctx context.Context, req ctrl.Requ err = r.Client.List(ctx, deploy, &client.ListOptions{}) fmt.Printf("There are %d deployments in the cluster\n", len(deploy.Items)) + // Finally, if the Reconcile() function has completed with no critical errors + // set the OperatorDegraded condition to False with the reason operatorv1alpha1.ReasonSucceeded, l.Info(fmt.Sprintf("Done reconcile 12-- obj %s", name)) - - return ctrl.Result{}, nil + meta.SetStatusCondition(&resourceManagerObj.Status.Conditions, metav1.Condition{ + Type: "OperatorDegraded", + Status: metav1.ConditionFalse, + Reason: "list deployments succeeded", + LastTransitionTime: metav1.NewTime(time.Now()), + Message: "operator successfully reconciling", + }) + return ctrl.Result{}, utilerrors.NewAggregate([]error{err, r.Status().Update(ctx, resourceManagerObj)}) } // SetupWithManager sets up the controller with the Manager.