diff --git a/api/v1alpha1/operandrequest_types.go b/api/v1alpha1/operandrequest_types.go index e2ad35b0..d92e6bf4 100644 --- a/api/v1alpha1/operandrequest_types.go +++ b/api/v1alpha1/operandrequest_types.go @@ -29,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "k8s.io/klog" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -650,6 +651,58 @@ func (r *OperandRequest) UpdateLabels() bool { return isUpdated } +func (r *OperandRequest) CheckServiceStatus() bool { + requeue := false + monitoredServices := []string{"ibm-iam-operator", "ibm-idp-config-ui-operator", "ibm-mongodb-operator", "ibm-im-operator"} + servicesRequested := false + for _, serviceName := range monitoredServices { + if foundOperand(r.Spec.Requests, serviceName) { + servicesRequested = true + break + } + } + if servicesRequested { + if len(r.Status.Services) == 0 { + klog.Info("Waiting for status.services to be instantiated ...") + requeue = true + return requeue + } + // var IMOrIAM string + exists := false + if foundOperand(r.Spec.Requests, "ibm-iam-operator") { + // IMOrIAM = "ibm-iam-operator" + exists = true + } else if foundOperand(r.Spec.Requests, "ibm-im-operator") { + // IMOrIAM = "ibm-im-operator" + exists = true + } + + if exists { + var imIndex int + found := false + for i, s := range r.Status.Services { + if "ibm-iam-operator" == s.OperatorName { //eventually this should be changed to the variable but the operator name is still listed as iam in practice even when im is requested + found = true + imIndex = i + break + } + } + if found { + if r.Status.Services[imIndex].Status != "Ready" { + klog.Info("Waiting for IM service to be Ready ...") + requeue = true + return requeue + } + } else { + klog.Info("Waiting for IM service status ...") + requeue = true + return requeue + } + } + } + return requeue +} + // GetAllRegistryReconcileRequest gets all the Registry ReconcileRequest. func (r *OperandRequest) GetAllRegistryReconcileRequest() []reconcile.Request { rrs := []reconcile.Request{} diff --git a/controllers/operandrequest/operandrequest_controller.go b/controllers/operandrequest/operandrequest_controller.go index 7babfbd0..8e4284b2 100644 --- a/controllers/operandrequest/operandrequest_controller.go +++ b/controllers/operandrequest/operandrequest_controller.go @@ -153,6 +153,11 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ ctrl.Re return ctrl.Result{RequeueAfter: constant.DefaultRequeueDuration}, nil } + //check if status.services is present (if a relevant service was requested), requeue again is im/iam is not ready yet + if requestInstance.CheckServiceStatus() { + return ctrl.Result{RequeueAfter: constant.DefaultRequeueDuration}, nil + } + klog.V(1).Infof("Finished reconciling OperandRequest: %s", req.NamespacedName) return ctrl.Result{RequeueAfter: constant.DefaultSyncPeriod}, nil } diff --git a/controllers/operandrequest/reconcile_operand.go b/controllers/operandrequest/reconcile_operand.go index 50876ced..240ada10 100644 --- a/controllers/operandrequest/reconcile_operand.go +++ b/controllers/operandrequest/reconcile_operand.go @@ -183,7 +183,7 @@ func (r *Reconciler) reconcileOperand(ctx context.Context, requestInstance *oper klog.V(2).Infof("There is no service: %s from the OperandConfig instance: %s/%s, Skip reconciling Operands", operand.Name, registryKey.Namespace, req.Registry) continue } - err = r.reconcileCRwithConfig(ctx, opdConfig, configInstance.Namespace, csv, requestInstance, sub.Namespace, &r.Mutex) + err = r.reconcileCRwithConfig(ctx, opdConfig, configInstance.Namespace, csv, requestInstance, operand.Name, sub.Namespace, &r.Mutex) if err != nil { merr.Add(err) requestInstance.SetMemberStatus(operand.Name, "", operatorv1alpha1.ServiceFailed, &r.Mutex) @@ -215,7 +215,7 @@ func (r *Reconciler) reconcileOperand(ctx context.Context, requestInstance *oper } // reconcileCRwithConfig merge and create custom resource base on OperandConfig and CSV alm-examples -func (r *Reconciler) reconcileCRwithConfig(ctx context.Context, service *operatorv1alpha1.ConfigService, namespace string, csv *olmv1alpha1.ClusterServiceVersion, requestInstance *operatorv1alpha1.OperandRequest, operatorNamespace string, mu sync.Locker) error { +func (r *Reconciler) reconcileCRwithConfig(ctx context.Context, service *operatorv1alpha1.ConfigService, namespace string, csv *olmv1alpha1.ClusterServiceVersion, requestInstance *operatorv1alpha1.OperandRequest, operandName string, operatorNamespace string, mu sync.Locker) error { merr := &util.MultiErr{} // Create k8s resources required by service @@ -337,10 +337,6 @@ func (r *Reconciler) reconcileCRwithConfig(ctx context.Context, service *operato merr.Add(err) continue } - managedBy, err := r.getManagedBy(crFromALM) - if err != nil { - return err - } statusSpec, err := r.getOperandStatus(crFromALM) if err != nil { return err @@ -349,7 +345,7 @@ func (r *Reconciler) reconcileCRwithConfig(ctx context.Context, service *operato if serviceKind != "OperandRequest" && statusSpec.ObjectName != "" { var resources []operatorv1alpha1.OperandStatus resources = append(resources, statusSpec) - serviceSpec := newServiceStatus(managedBy, operatorNamespace, resources) + serviceSpec := newServiceStatus(operandName, operatorNamespace, resources) seterr := requestInstance.SetServiceStatus(ctx, serviceSpec, r.Client, mu) if seterr != nil { return seterr @@ -421,10 +417,6 @@ func (r *Reconciler) reconcileCRwithRequest(ctx context.Context, requestInstance if err := r.updateCustomResource(ctx, crFromRequest, requestKey.Namespace, operand.Kind, operand.Spec.Raw, map[string]interface{}{}); err != nil { return err } - managedBy, err := r.getManagedBy(crFromRequest) - if err != nil { - return err - } statusSpec, err := r.getOperandStatus(crFromRequest) if err != nil { return err @@ -432,7 +424,7 @@ func (r *Reconciler) reconcileCRwithRequest(ctx context.Context, requestInstance if operand.Kind != "OperandRequest" && statusSpec.ObjectName != "" { var resources []operatorv1alpha1.OperandStatus resources = append(resources, statusSpec) - serviceSpec := newServiceStatus(managedBy, operatorNamespace, resources) + serviceSpec := newServiceStatus(operand.Name, operatorNamespace, resources) seterr := requestInstance.SetServiceStatus(ctx, serviceSpec, r.Client, mu) if seterr != nil { return seterr @@ -449,38 +441,6 @@ func (r *Reconciler) reconcileCRwithRequest(ctx context.Context, requestInstance return nil } -func (r *Reconciler) getManagedBy(existingCR unstructured.Unstructured) (string, error) { - byteMetadata, err := json.Marshal(existingCR.Object["metadata"]) - if err != nil { - klog.Error(err) - return "", err - } - var rawMetadata map[string]interface{} - err = json.Unmarshal(byteMetadata, &rawMetadata) - if err != nil { - klog.Error(err) - return "", err - } - byteLabels, err := json.Marshal(rawMetadata["labels"]) - if err != nil { - klog.Error(err) - return "", err - } - var parsedLabels map[string]string - err = json.Unmarshal(byteLabels, &parsedLabels) - if err != nil { - klog.Error(err) - return "", err - } - var managedBy string - for key, value := range parsedLabels { - if key == "app.kubernetes.io/managed-by" { - managedBy = value - } - } - return managedBy, nil -} - func (r *Reconciler) getOperandStatus(existingCR unstructured.Unstructured) (operatorv1alpha1.OperandStatus, error) { var emptyStatus operatorv1alpha1.OperandStatus byteStatus, err := json.Marshal(existingCR.Object["status"])