diff --git a/api/v1alpha1/storageclaim_types.go b/api/v1alpha1/storageclaim_types.go index 2d52d4d4..5d5da6fc 100644 --- a/api/v1alpha1/storageclaim_types.go +++ b/api/v1alpha1/storageclaim_types.go @@ -44,6 +44,8 @@ type StorageClaimStatus struct { Phase storageClaimState `json:"phase,omitempty"` } +// TODO: remove after storageclassclaim migration controller and storageclassclaim is deleted + type StorageClientNamespacedName struct { Name string `json:"name"` Namespace string `json:"namespace"` @@ -52,10 +54,10 @@ type StorageClientNamespacedName struct { // StorageClaimSpec defines the desired state of StorageClaim type StorageClaimSpec struct { //+kubebuilder:validation:Enum=block;sharedfile - Type string `json:"type"` - EncryptionMethod string `json:"encryptionMethod,omitempty"` - StorageProfile string `json:"storageProfile,omitempty"` - StorageClient *StorageClientNamespacedName `json:"storageClient"` + Type string `json:"type"` + EncryptionMethod string `json:"encryptionMethod,omitempty"` + StorageProfile string `json:"storageProfile,omitempty"` + StorageClient string `json:"storageClient"` } //+kubebuilder:object:root=true diff --git a/api/v1alpha1/storageclient_types.go b/api/v1alpha1/storageclient_types.go index 28147c76..6ca4d7c8 100644 --- a/api/v1alpha1/storageclient_types.go +++ b/api/v1alpha1/storageclient_types.go @@ -56,6 +56,7 @@ type StorageClientStatus struct { //+kubebuilder:object:root=true //+kubebuilder:subresource:status +//+kubebuilder:resource:scope=Cluster //+kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase" //+kubebuilder:printcolumn:name="consumer",type="string",JSONPath=".status.id" diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index c5b6e024..2827ce82 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -30,7 +30,7 @@ func (in *StorageClaim) DeepCopyInto(out *StorageClaim) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) + out.Spec = in.Spec out.Status = in.Status } @@ -87,11 +87,6 @@ func (in *StorageClaimList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StorageClaimSpec) DeepCopyInto(out *StorageClaimSpec) { *out = *in - if in.StorageClient != nil { - in, out := &in.StorageClient, &out.StorageClient - *out = new(StorageClientNamespacedName) - **out = **in - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageClaimSpec. diff --git a/bundle/manifests/ocs.openshift.io_storageclaims.yaml b/bundle/manifests/ocs.openshift.io_storageclaims.yaml index 4af41198..e1f0db46 100644 --- a/bundle/manifests/ocs.openshift.io_storageclaims.yaml +++ b/bundle/manifests/ocs.openshift.io_storageclaims.yaml @@ -53,15 +53,7 @@ spec: encryptionMethod: type: string storageClient: - properties: - name: - type: string - namespace: - type: string - required: - - name - - namespace - type: object + type: string storageProfile: type: string type: diff --git a/bundle/manifests/ocs.openshift.io_storageclients.yaml b/bundle/manifests/ocs.openshift.io_storageclients.yaml index 01c2192d..95e22b1d 100644 --- a/bundle/manifests/ocs.openshift.io_storageclients.yaml +++ b/bundle/manifests/ocs.openshift.io_storageclients.yaml @@ -12,7 +12,7 @@ spec: listKind: StorageClientList plural: storageclients singular: storageclient - scope: Namespaced + scope: Cluster versions: - additionalPrinterColumns: - jsonPath: .status.phase diff --git a/config/crd/bases/ocs.openshift.io_storageclaims.yaml b/config/crd/bases/ocs.openshift.io_storageclaims.yaml index a10dc976..a5129a13 100644 --- a/config/crd/bases/ocs.openshift.io_storageclaims.yaml +++ b/config/crd/bases/ocs.openshift.io_storageclaims.yaml @@ -54,15 +54,7 @@ spec: encryptionMethod: type: string storageClient: - properties: - name: - type: string - namespace: - type: string - required: - - name - - namespace - type: object + type: string storageProfile: type: string type: diff --git a/config/crd/bases/ocs.openshift.io_storageclients.yaml b/config/crd/bases/ocs.openshift.io_storageclients.yaml index 766ae368..afcbcd44 100644 --- a/config/crd/bases/ocs.openshift.io_storageclients.yaml +++ b/config/crd/bases/ocs.openshift.io_storageclients.yaml @@ -13,7 +13,7 @@ spec: listKind: StorageClientList plural: storageclients singular: storageclient - scope: Namespaced + scope: Cluster versions: - additionalPrinterColumns: - jsonPath: .status.phase diff --git a/controllers/storageclaim_controller.go b/controllers/storageclaim_controller.go index e8460101..2320da50 100644 --- a/controllers/storageclaim_controller.go +++ b/controllers/storageclaim_controller.go @@ -152,7 +152,7 @@ func (r *StorageClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request r.storageClaimHash = getMD5Hash(r.storageClaim.Name) r.storageClaim.Status.Phase = v1alpha1.StorageClaimInitializing - if r.storageClaim.Spec.StorageClient == nil { + if r.storageClaim.Spec.StorageClient == "" { storageClientList := &v1alpha1.StorageClientList{} if err := r.list(storageClientList); err != nil { return reconcile.Result{}, err @@ -170,8 +170,7 @@ func (r *StorageClaimReconciler) Reconcile(ctx context.Context, req ctrl.Request } else { // Fetch the StorageClient instance r.storageClient = &v1alpha1.StorageClient{} - r.storageClient.Name = r.storageClaim.Spec.StorageClient.Name - r.storageClient.Namespace = r.storageClaim.Spec.StorageClient.Namespace + r.storageClient.Name = r.storageClaim.Spec.StorageClient if err := r.get(r.storageClient); err != nil { r.log.Error(err, "Failed to get StorageClient.") return reconcile.Result{}, err @@ -265,18 +264,8 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) { // Configuration phase. r.storageClaim.Status.Phase = v1alpha1.StorageClaimConfiguring - updateStorageClaim := false // Check if finalizers are present, if not, add them. - if !contains(r.storageClaim.GetFinalizers(), storageClaimFinalizer) { - r.log.Info("Finalizer not found for StorageClaim. Adding finalizer.", "StorageClaim", r.storageClaim.Name) - r.storageClaim.SetFinalizers(append(r.storageClaim.GetFinalizers(), storageClaimFinalizer)) - updateStorageClaim = true - } - if utils.AddAnnotation(r.storageClaim, storageClientAnnotationKey, client.ObjectKeyFromObject(r.storageClient).String()) { - updateStorageClaim = true - } - - if updateStorageClaim { + if controllerutil.AddFinalizer(r.storageClaim, storageClaimFinalizer) { if err := r.update(r.storageClaim); err != nil { return reconcile.Result{}, fmt.Errorf("failed to update StorageClaim %q: %v", r.storageClaim.Name, err) } @@ -347,7 +336,7 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) { case "Secret": secret := &corev1.Secret{} secret.Name = resource.Name - secret.Namespace = r.storageClient.Namespace + secret.Namespace = r.OperatorNamespace _, err = controllerutil.CreateOrUpdate(r.ctx, r.Client, secret, func() error { // cluster scoped resource owning namespace scoped resource which allows garbage collection if err := r.own(secret); err != nil { @@ -382,9 +371,9 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) { // same name. csiClusterConfigEntry.ClusterID = r.storageClaimHash var storageClass *storagev1.StorageClass - data["csi.storage.k8s.io/provisioner-secret-namespace"] = r.storageClient.Namespace - data["csi.storage.k8s.io/node-stage-secret-namespace"] = r.storageClient.Namespace - data["csi.storage.k8s.io/controller-expand-secret-namespace"] = r.storageClient.Namespace + data["csi.storage.k8s.io/provisioner-secret-namespace"] = r.OperatorNamespace + data["csi.storage.k8s.io/node-stage-secret-namespace"] = r.OperatorNamespace + data["csi.storage.k8s.io/controller-expand-secret-namespace"] = r.OperatorNamespace data["clusterID"] = r.storageClaimHash if resource.Name == "cephfs" { @@ -403,7 +392,7 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) { } case "VolumeSnapshotClass": var volumeSnapshotClass *snapapi.VolumeSnapshotClass - data["csi.storage.k8s.io/snapshotter-secret-namespace"] = r.storageClient.Namespace + data["csi.storage.k8s.io/snapshotter-secret-namespace"] = r.OperatorNamespace // generate a new clusterID for cephfs subvolumegroup, as // storageclaim is clusterscoped resources using its // hash as the clusterID @@ -465,8 +454,7 @@ func (r *StorageClaimReconciler) reconcilePhases() (reconcile.Result, error) { return reconcile.Result{}, fmt.Errorf("failed to revoke StorageClassClaim: %s", err) } - if contains(r.storageClaim.GetFinalizers(), storageClaimFinalizer) { - r.storageClaim.Finalizers = remove(r.storageClaim.Finalizers, storageClaimFinalizer) + if controllerutil.RemoveFinalizer(r.storageClaim, storageClaimFinalizer) { if err := r.update(r.storageClaim); err != nil { return ctrl.Result{}, fmt.Errorf("failed to remove finalizer from storageClaim: %s", err) } @@ -595,8 +583,7 @@ func (r *StorageClaimReconciler) delete(obj client.Object) error { } func (r *StorageClaimReconciler) own(resource metav1.Object) error { - // Ensure StorageClaim ownership on a resource - return controllerutil.SetOwnerReference(r.storageClaim, resource, r.Scheme) + return controllerutil.SetControllerReference(r.storageClaim, resource, r.Scheme) } func (r *StorageClaimReconciler) createOrReplaceVolumeSnapshotClass(volumeSnapshotClass *snapapi.VolumeSnapshotClass) error { diff --git a/controllers/storageclassclaim_migration_controller.go b/controllers/storageclassclaim_migration_controller.go index 35a02c33..552d2085 100644 --- a/controllers/storageclassclaim_migration_controller.go +++ b/controllers/storageclassclaim_migration_controller.go @@ -82,7 +82,9 @@ func (r *StorageClassClaimMigrationReconciler) Reconcile(ctx context.Context, re storageClaim.Spec.EncryptionMethod = storageClassClaim.Spec.EncryptionMethod storageClaim.Spec.StorageProfile = storageClassClaim.Spec.StorageProfile - storageClaim.Spec.StorageClient = storageClassClaim.Spec.StorageClient.DeepCopy() + if storageClassClaim.Spec.StorageClient != nil { + storageClaim.Spec.StorageClient = storageClassClaim.Spec.StorageClient.Name + } r.log.Info(fmt.Sprintf("Migrating storageclassclaim %q", storageClassClaim.Name)) if err := r.create(storageClaim); err != nil && !kerrors.IsAlreadyExists(err) { diff --git a/controllers/storageclient_controller.go b/controllers/storageclient_controller.go index a36c8fbb..f46cd57b 100644 --- a/controllers/storageclient_controller.go +++ b/controllers/storageclient_controller.go @@ -18,9 +18,6 @@ package controllers import ( "context" - "crypto/md5" - "encoding/hex" - "encoding/json" "fmt" "os" "strings" @@ -37,13 +34,12 @@ import ( batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" "k8s.io/klog/v2" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -55,19 +51,13 @@ const ( GetStorageConfig = "GetStorageConfig" AcknowledgeOnboarding = "AcknowledgeOnboarding" - storageClientAnnotationKey = "ocs.openshift.io/storageclient" - storageClientNameLabel = "ocs.openshift.io/storageclient.name" - storageClientNamespaceLabel = "ocs.openshift.io/storageclient.namespace" - storageClientFinalizer = "storageclient.ocs.openshift.io" - defaultClaimsOwnerAnnotationKey = "ocs.openshift.io/storageclaim.owner" - defaultClaimsProcessedAnnotationKey = "ocs.openshift.io/storageclaim.processed" - defaultBlockStorageClaim = "ocs-storagecluster-ceph-rbd" - defaultSharedfileStorageClaim = "ocs-storagecluster-cephfs" + storageClientNameLabel = "ocs.openshift.io/storageclient.name" + storageClientFinalizer = "storageclient.ocs.openshift.io" + storageClaimProcessedAnnotationKey = "ocs.openshift.io/storageclaim.processed" + storageClientDefaultAnnotationKey = "ocs.openshift.io/storageclient.default" // indexes for caching - storageProviderEndpointIndexName = "index:storageProviderEndpoint" - storageClientAnnotationIndexName = "index:storageClientAnnotation" - defaultClaimsOwnerIndexName = "index:defaultClaimsOwner" + ownerIndexName = "index:ownerUID" csvPrefix = "ocs-client-operator" ) @@ -76,58 +66,34 @@ const ( type StorageClientReconciler struct { ctx context.Context client.Client - Log klog.Logger - Scheme *runtime.Scheme - recorder *utils.EventReporter + Log klog.Logger + Scheme *runtime.Scheme + recorder *utils.EventReporter + storageClient *v1alpha1.StorageClient OperatorNamespace string } // SetupWithManager sets up the controller with the Manager. -func (s *StorageClientReconciler) SetupWithManager(mgr ctrl.Manager) error { +func (r *StorageClientReconciler) SetupWithManager(mgr ctrl.Manager) error { ctx := context.Background() - // Index should be registered before cache start. - // IndexField is used to filter out the objects that already exists with - // status.phase != failed This will help in blocking - // the new storageclient creation if there is already with one with same - // provider endpoint with status.phase != failed - _ = mgr.GetCache().IndexField(ctx, &v1alpha1.StorageClient{}, storageProviderEndpointIndexName, func(o client.Object) []string { - res := []string{} - if o.(*v1alpha1.StorageClient).Status.Phase != v1alpha1.StorageClientFailed { - res = append(res, o.(*v1alpha1.StorageClient).Spec.StorageProviderEndpoint) + if err := mgr.GetCache().IndexField(ctx, &v1alpha1.StorageClaim{}, ownerIndexName, func(obj client.Object) []string { + refs := obj.GetOwnerReferences() + var owners []string + for i := range refs { + owners = append(owners, string(refs[i].UID)) } - return res - }) - - if err := mgr.GetCache().IndexField(ctx, &v1alpha1.StorageClaim{}, storageClientAnnotationIndexName, func(obj client.Object) []string { - return []string{obj.GetAnnotations()[storageClientAnnotationKey]} - }); err != nil { - return fmt.Errorf("unable to set up FieldIndexer for storageclient annotation: %v", err) - } - - if err := mgr.GetCache().IndexField(ctx, &v1alpha1.StorageClient{}, defaultClaimsOwnerIndexName, func(obj client.Object) []string { - return []string{obj.GetAnnotations()[defaultClaimsOwnerAnnotationKey]} + return owners }); err != nil { - return fmt.Errorf("unable to set up FieldIndexer for storageclient owner annotation: %v", err) + return fmt.Errorf("unable to set up FieldIndexer for StorageClaim's owner uid: %v", err) } - enqueueStorageClientRequest := handler.EnqueueRequestsFromMapFunc( - func(_ context.Context, obj client.Object) []reconcile.Request { - annotations := obj.GetAnnotations() - if _, found := annotations[storageClaimAnnotation]; found { - return []reconcile.Request{{ - NamespacedName: types.NamespacedName{ - Name: obj.GetName(), - }, - }} - } - return []reconcile.Request{} - }) - s.recorder = utils.NewEventReporter(mgr.GetEventRecorderFor("controller_storageclient")) + r.recorder = utils.NewEventReporter(mgr.GetEventRecorderFor("controller_storageclient")) return ctrl.NewControllerManagedBy(mgr). For(&v1alpha1.StorageClient{}). - Watches(&v1alpha1.StorageClaim{}, enqueueStorageClientRequest). - Complete(s) + Owns(&v1alpha1.StorageClaim{}). + Owns(&batchv1.CronJob{}). + Complete(r) } //+kubebuilder:rbac:groups=ocs.openshift.io,resources=storageclients,verbs=get;list;watch;create;update;patch;delete @@ -137,37 +103,34 @@ func (s *StorageClientReconciler) SetupWithManager(mgr ctrl.Manager) error { //+kubebuilder:rbac:groups=batch,resources=cronjobs,verbs=get;list;create;update;watch;delete //+kubebuilder:rbac:groups=operators.coreos.com,resources=clusterserviceversions,verbs=get;list;watch -func (s *StorageClientReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { +func (r *StorageClientReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { var err error - s.ctx = ctx - s.Log = log.FromContext(ctx, "StorageClient", req) - s.Log.Info("Reconciling StorageClient") + r.ctx = ctx + r.Log = log.FromContext(ctx, "StorageClient", req) + r.Log.Info("Reconciling StorageClient") - // Fetch the StorageClient instance - instance := &v1alpha1.StorageClient{} - instance.Name = req.Name - instance.Namespace = req.Namespace - - if err = s.Client.Get(ctx, types.NamespacedName{Name: instance.Name, Namespace: instance.Namespace}, instance); err != nil { + r.storageClient = &v1alpha1.StorageClient{} + r.storageClient.Name = req.Name + if err = r.get(r.storageClient); err != nil { if kerrors.IsNotFound(err) { - s.Log.Info("StorageClient resource not found. Ignoring since object must be deleted.") + r.Log.Info("StorageClient resource not found. Ignoring since object must be deleted.") return reconcile.Result{}, nil } - s.Log.Error(err, "Failed to get StorageClient.") + r.Log.Error(err, "Failed to get StorageClient.") return reconcile.Result{}, fmt.Errorf("failed to get StorageClient: %v", err) } // Dont Reconcile the StorageClient if it is in failed state - if instance.Status.Phase == v1alpha1.StorageClientFailed { + if r.storageClient.Status.Phase == v1alpha1.StorageClientFailed { return reconcile.Result{}, nil } - result, reconcileErr := s.reconcilePhases(instance) + result, reconcileErr := r.reconcilePhases() // Apply status changes to the StorageClient - statusErr := s.Client.Status().Update(ctx, instance) + statusErr := r.Client.Status().Update(ctx, r.storageClient) if statusErr != nil { - s.Log.Error(statusErr, "Failed to update StorageClient status.") + r.Log.Error(statusErr, "Failed to update StorageClient status.") } if reconcileErr != nil { err = reconcileErr @@ -177,110 +140,107 @@ func (s *StorageClientReconciler) Reconcile(ctx context.Context, req ctrl.Reques return result, err } -func (s *StorageClientReconciler) reconcilePhases(instance *v1alpha1.StorageClient) (ctrl.Result, error) { - storageClientListOption := []client.ListOption{ - client.MatchingFields{storageProviderEndpointIndexName: instance.Spec.StorageProviderEndpoint}, - } - - storageClientList := &v1alpha1.StorageClientList{} - if err := s.Client.List(s.ctx, storageClientList, storageClientListOption...); err != nil { - s.Log.Error(err, "unable to list storage clients") - return ctrl.Result{}, err - } +func (r *StorageClientReconciler) reconcilePhases() (ctrl.Result, error) { - if len(storageClientList.Items) > 1 { - s.Log.Info("one StorageClient is allowed per namespace but found more than one. Rejecting new request.") - instance.Status.Phase = v1alpha1.StorageClientFailed - // Dont Reconcile again as there is already a StorageClient with same provider endpoint - return reconcile.Result{}, nil - } - - externalClusterClient, err := s.newExternalClusterClient(instance) + externalClusterClient, err := r.newExternalClusterClient() if err != nil { return reconcile.Result{}, err } defer externalClusterClient.Close() // deletion phase - if !instance.GetDeletionTimestamp().IsZero() { - return s.deletionPhase(instance, externalClusterClient) + if !r.storageClient.GetDeletionTimestamp().IsZero() { + return r.deletionPhase(externalClusterClient) + } + + updateStorageClient := false + storageClients := &v1alpha1.StorageClientList{} + if err := r.list(storageClients); err != nil { + r.Log.Error(err, "unable to list storage clients") + return ctrl.Result{}, err + } + if len(storageClients.Items) == 1 && storageClients.Items[0].Name == r.storageClient.Name { + if utils.AddAnnotation(r.storageClient, storageClientDefaultAnnotationKey, "true") { + updateStorageClient = true + } } // ensure finalizer - if !contains(instance.GetFinalizers(), storageClientFinalizer) { - instance.Status.Phase = v1alpha1.StorageClientInitializing - s.Log.Info("Finalizer not found for StorageClient. Adding finalizer.", "StorageClient", klog.KRef(instance.Namespace, instance.Name)) - instance.ObjectMeta.Finalizers = append(instance.ObjectMeta.Finalizers, storageClientFinalizer) - if err := s.Client.Update(s.ctx, instance); err != nil { - s.Log.Info("Failed to update StorageClient with finalizer.", "StorageClient", klog.KRef(instance.Namespace, instance.Name)) - return reconcile.Result{}, fmt.Errorf("failed to update StorageClient with finalizer: %v", err) + if controllerutil.AddFinalizer(r.storageClient, storageClientFinalizer) { + r.storageClient.Status.Phase = v1alpha1.StorageClientInitializing + r.Log.Info("Finalizer not found for StorageClient. Adding finalizer.", "StorageClient", r.storageClient.Name) + updateStorageClient = true + } + + if updateStorageClient { + if err := r.update(r.storageClient); err != nil { + return reconcile.Result{}, fmt.Errorf("failed to update StorageClient: %v", err) } } - if instance.Status.ConsumerID == "" { - return s.onboardConsumer(instance, externalClusterClient) - } else if instance.Status.Phase == v1alpha1.StorageClientOnboarding { - return s.acknowledgeOnboarding(instance, externalClusterClient) + if r.storageClient.Status.ConsumerID == "" { + return r.onboardConsumer(externalClusterClient) + } else if r.storageClient.Status.Phase == v1alpha1.StorageClientOnboarding { + return r.acknowledgeOnboarding(externalClusterClient) } - if res, err := s.reconcileClientStatusReporterJob(instance); err != nil { + if res, err := r.reconcileClientStatusReporterJob(); err != nil { return res, err } - if err := s.reconcileDefaultStorageClaims(instance); err != nil { - return reconcile.Result{}, err + if r.storageClient.GetAnnotations()[storageClaimProcessedAnnotationKey] != "true" { + if err := r.reconcileBlockStorageClaim(); err != nil { + return reconcile.Result{}, err + } + + if err := r.reconcileSharedfileStorageClaim(); err != nil { + return reconcile.Result{}, err + } + + utils.AddAnnotation(r.storageClient, storageClaimProcessedAnnotationKey, "true") + if err := r.update(r.storageClient); err != nil { + return reconcile.Result{}, fmt.Errorf("failed to update StorageClient with claim processed annotation: %v", err) + } } return reconcile.Result{}, nil } -func (s *StorageClientReconciler) deletionPhase(instance *v1alpha1.StorageClient, externalClusterClient *providerClient.OCSProviderClient) (ctrl.Result, error) { +func (r *StorageClientReconciler) deletionPhase(externalClusterClient *providerClient.OCSProviderClient) (ctrl.Result, error) { // TODO Need to take care of deleting the SCC created for this // storageClient and also the default SCC created for this storageClient - if contains(instance.GetFinalizers(), storageClientFinalizer) { - instance.Status.Phase = v1alpha1.StorageClientOffboarding - err := s.verifyNoStorageClaimsExist(instance) - if err != nil { - s.Log.Error(err, "still storageclaims exist for this storageclient") - return reconcile.Result{}, fmt.Errorf("still storageclaims exist for this storageclient: %v", err) - } - if res, err := s.offboardConsumer(instance, externalClusterClient); err != nil { - s.Log.Error(err, "Offboarding in progress.") - } else if !res.IsZero() { - // result is not empty - return res, nil - } + r.storageClient.Status.Phase = v1alpha1.StorageClientOffboarding - cronJob := &batchv1.CronJob{} - cronJob.Name = getStatusReporterName(instance.Namespace, instance.Name) - cronJob.Namespace = s.OperatorNamespace - - if err := s.delete(cronJob); err != nil { - s.Log.Error(err, "Failed to delete the status reporter job") - return reconcile.Result{}, fmt.Errorf("failed to delete the status reporter job: %v", err) - } - - if err := s.deleteDefaultStorageClaims(instance); err != nil { - return reconcile.Result{}, fmt.Errorf("failed to delete default storageclaims: %v", err) - } + if err := r.deleteOwnedStorageClaims(); err != nil { + return reconcile.Result{}, fmt.Errorf("failed to delete storageclaims owned by storageclient %v: %v", r.storageClient.Name, err) + } + if err := r.verifyNoStorageClaimsExist(); err != nil { + r.Log.Error(err, "still storageclaims exist for this storageclient") + return reconcile.Result{}, fmt.Errorf("still storageclaims exist for this storageclient: %v", err) + } + if res, err := r.offboardConsumer(externalClusterClient); err != nil { + r.Log.Error(err, "Offboarding in progress.") + } else if !res.IsZero() { + // result is not empty + return res, nil + } - s.Log.Info("removing finalizer from StorageClient.", "StorageClient", klog.KRef(instance.Namespace, instance.Name)) - // Once all finalizers have been removed, the object will be deleted - instance.ObjectMeta.Finalizers = remove(instance.ObjectMeta.Finalizers, storageClientFinalizer) - if err := s.Client.Update(s.ctx, instance); err != nil { - s.Log.Info("Failed to remove finalizer from StorageClient", "StorageClient", klog.KRef(instance.Namespace, instance.Name)) + if controllerutil.RemoveFinalizer(r.storageClient, storageClientFinalizer) { + r.Log.Info("removing finalizer from StorageClient.", "StorageClient", r.storageClient.Name) + if err := r.update(r.storageClient); err != nil { + r.Log.Info("Failed to remove finalizer from StorageClient", "StorageClient", r.storageClient.Name) return reconcile.Result{}, fmt.Errorf("failed to remove finalizer from StorageClient: %v", err) } } - s.Log.Info("StorageClient is offboarded", "StorageClient", klog.KRef(instance.Namespace, instance.Name)) + r.Log.Info("StorageClient is offboarded", "StorageClient", r.storageClient.Name) return reconcile.Result{}, nil } // newExternalClusterClient returns the *providerClient.OCSProviderClient -func (s *StorageClientReconciler) newExternalClusterClient(instance *v1alpha1.StorageClient) (*providerClient.OCSProviderClient, error) { +func (r *StorageClientReconciler) newExternalClusterClient() (*providerClient.OCSProviderClient, error) { ocsProviderClient, err := providerClient.NewProviderClient( - s.ctx, instance.Spec.StorageProviderEndpoint, time.Second*10) + r.ctx, r.storageClient.Spec.StorageProviderEndpoint, time.Second*10) if err != nil { return nil, fmt.Errorf("failed to create a new provider client: %v", err) } @@ -289,21 +249,21 @@ func (s *StorageClientReconciler) newExternalClusterClient(instance *v1alpha1.St } // onboardConsumer makes an API call to the external storage provider cluster for onboarding -func (s *StorageClientReconciler) onboardConsumer(instance *v1alpha1.StorageClient, externalClusterClient *providerClient.OCSProviderClient) (reconcile.Result, error) { +func (r *StorageClientReconciler) onboardConsumer(externalClusterClient *providerClient.OCSProviderClient) (reconcile.Result, error) { // TODO Need to find a way to get rid of ClusterVersion here as it is OCP // specific one. clusterVersion := &configv1.ClusterVersion{} - err := s.Client.Get(s.ctx, types.NamespacedName{Name: "version"}, clusterVersion) - if err != nil { - s.Log.Error(err, "failed to get the clusterVersion version of the OCP cluster") + clusterVersion.Name = "version" + if err := r.get(clusterVersion); err != nil { + r.Log.Error(err, "failed to get the clusterVersion version of the OCP cluster") return reconcile.Result{}, fmt.Errorf("failed to get the clusterVersion version of the OCP cluster: %v", err) } // TODO Have a version file corresponding to the release csvList := opv1a1.ClusterServiceVersionList{} - if err = s.list(&csvList, client.InNamespace(s.OperatorNamespace)); err != nil { - return reconcile.Result{}, fmt.Errorf("failed to list csv resources in ns: %v, err: %v", s.OperatorNamespace, err) + if err := r.list(&csvList, client.InNamespace(r.OperatorNamespace)); err != nil { + return reconcile.Result{}, fmt.Errorf("failed to list csv resources in ns: %v, err: %v", r.OperatorNamespace, err) } csv := utils.Find(csvList.Items, func(csv *opv1a1.ClusterServiceVersion) bool { return strings.HasPrefix(csv.Name, csvPrefix) @@ -314,52 +274,52 @@ func (s *StorageClientReconciler) onboardConsumer(instance *v1alpha1.StorageClie name := fmt.Sprintf("storageconsumer-%s", clusterVersion.Spec.ClusterID) onboardRequest := providerClient.NewOnboardConsumerRequest(). SetConsumerName(name). - SetOnboardingTicket(instance.Spec.OnboardingTicket). + SetOnboardingTicket(r.storageClient.Spec.OnboardingTicket). SetClientOperatorVersion(csv.Spec.Version.String()) - response, err := externalClusterClient.OnboardConsumer(s.ctx, onboardRequest) + response, err := externalClusterClient.OnboardConsumer(r.ctx, onboardRequest) if err != nil { if st, ok := status.FromError(err); ok { - s.logGrpcErrorAndReportEvent(instance, OnboardConsumer, err, st.Code()) + r.logGrpcErrorAndReportEvent(OnboardConsumer, err, st.Code()) } return reconcile.Result{}, fmt.Errorf("failed to onboard consumer: %v", err) } if response.StorageConsumerUUID == "" { err = fmt.Errorf("storage provider response is empty") - s.Log.Error(err, "empty response") + r.Log.Error(err, "empty response") return reconcile.Result{}, err } - instance.Status.ConsumerID = response.StorageConsumerUUID - instance.Status.Phase = v1alpha1.StorageClientOnboarding + r.storageClient.Status.ConsumerID = response.StorageConsumerUUID + r.storageClient.Status.Phase = v1alpha1.StorageClientOnboarding - s.Log.Info("onboarding started") + r.Log.Info("onboarding started") return reconcile.Result{Requeue: true}, nil } -func (s *StorageClientReconciler) acknowledgeOnboarding(instance *v1alpha1.StorageClient, externalClusterClient *providerClient.OCSProviderClient) (reconcile.Result, error) { +func (r *StorageClientReconciler) acknowledgeOnboarding(externalClusterClient *providerClient.OCSProviderClient) (reconcile.Result, error) { - _, err := externalClusterClient.AcknowledgeOnboarding(s.ctx, instance.Status.ConsumerID) + _, err := externalClusterClient.AcknowledgeOnboarding(r.ctx, r.storageClient.Status.ConsumerID) if err != nil { if st, ok := status.FromError(err); ok { - s.logGrpcErrorAndReportEvent(instance, AcknowledgeOnboarding, err, st.Code()) + r.logGrpcErrorAndReportEvent(AcknowledgeOnboarding, err, st.Code()) } - s.Log.Error(err, "Failed to acknowledge onboarding.") + r.Log.Error(err, "Failed to acknowledge onboarding.") return reconcile.Result{}, fmt.Errorf("failed to acknowledge onboarding: %v", err) } - instance.Status.Phase = v1alpha1.StorageClientConnected + r.storageClient.Status.Phase = v1alpha1.StorageClientConnected - s.Log.Info("Onboarding is acknowledged successfully.") + r.Log.Info("Onboarding is acknowledged successfully.") return reconcile.Result{Requeue: true}, nil } // offboardConsumer makes an API call to the external storage provider cluster for offboarding -func (s *StorageClientReconciler) offboardConsumer(instance *v1alpha1.StorageClient, externalClusterClient *providerClient.OCSProviderClient) (reconcile.Result, error) { +func (r *StorageClientReconciler) offboardConsumer(externalClusterClient *providerClient.OCSProviderClient) (reconcile.Result, error) { - _, err := externalClusterClient.OffboardConsumer(s.ctx, instance.Status.ConsumerID) + _, err := externalClusterClient.OffboardConsumer(r.ctx, r.storageClient.Status.ConsumerID) if err != nil { if st, ok := status.FromError(err); ok { - s.logGrpcErrorAndReportEvent(instance, OffboardConsumer, err, st.Code()) + r.logGrpcErrorAndReportEvent(OffboardConsumer, err, st.Code()) } return reconcile.Result{}, fmt.Errorf("failed to offboard consumer: %v", err) } @@ -367,29 +327,43 @@ func (s *StorageClientReconciler) offboardConsumer(instance *v1alpha1.StorageCli return reconcile.Result{}, nil } -func (s *StorageClientReconciler) verifyNoStorageClaimsExist(instance *v1alpha1.StorageClient) error { +func (r *StorageClientReconciler) deleteOwnedStorageClaims() error { + storageClaims := &v1alpha1.StorageClaimList{} + if err := r.list(storageClaims, client.MatchingFields{ownerIndexName: string(r.storageClient.UID)}); err != nil { + return fmt.Errorf("failed to list storageClaims via owner reference: %v", err) + } + + for idx := range storageClaims.Items { + storageClaim := &storageClaims.Items[idx] + if err := r.delete(storageClaim); err != nil { + return fmt.Errorf("failed to delete storageClaim %v: %v", storageClaim.Name, err) + } + } + return nil +} + +func (r *StorageClientReconciler) verifyNoStorageClaimsExist() error { storageClaims := &v1alpha1.StorageClaimList{} - err := s.Client.List(s.ctx, - storageClaims, - client.MatchingFields{storageClientAnnotationIndexName: client.ObjectKeyFromObject(instance).String()}, - client.Limit(1), - ) - if err != nil { + if err := r.list(storageClaims); err != nil { return fmt.Errorf("failed to list storageClaims: %v", err) } - if len(storageClaims.Items) != 0 { - err = fmt.Errorf("Failed to cleanup resources. storageClaims are present."+ - "Delete all storageClaims corresponding to storageclient %q for the cleanup to proceed", client.ObjectKeyFromObject(instance)) - s.recorder.ReportIfNotPresent(instance, corev1.EventTypeWarning, "Cleanup", err.Error()) - s.Log.Error(err, "Waiting for all storageClaims to be deleted.") - return err + for idx := range storageClaims.Items { + storageClaim := &storageClaims.Items[idx] + if (storageClaim.Spec.StorageClient == "" && r.storageClient.Annotations[storageClientDefaultAnnotationKey] == "true") || + storageClaim.Spec.StorageClient == r.storageClient.Name { + err := fmt.Errorf("failed to cleanup resources. storageClaims are present on the cluster") + r.recorder.ReportIfNotPresent(r.storageClient, corev1.EventTypeWarning, "Cleanup", err.Error()) + r.Log.Error(err, "Waiting for all storageClaims to be deleted.") + return err + } } return nil } -func (s *StorageClientReconciler) logGrpcErrorAndReportEvent(instance *v1alpha1.StorageClient, grpcCallName string, err error, errCode codes.Code) { + +func (r *StorageClientReconciler) logGrpcErrorAndReportEvent(grpcCallName string, err error, errCode codes.Code) { var msg, eventReason, eventType string @@ -432,51 +406,28 @@ func (s *StorageClientReconciler) logGrpcErrorAndReportEvent(instance *v1alpha1. } if msg != "" { - s.Log.Error(err, "StorageProvider:"+grpcCallName+":"+msg) - s.recorder.ReportIfNotPresent(instance, eventType, eventReason, msg) - } -} - -func getStatusReporterName(namespace, name string) string { - // getStatusReporterName generates a name for a StatusReporter CronJob. - var s struct { - StorageClientName string `json:"storageClientName"` - StorageClientNamespace string `json:"storageClientNamespace"` - } - s.StorageClientName = name - s.StorageClientNamespace = namespace - - statusReporterName, err := json.Marshal(s) - if err != nil { - klog.Errorf("failed to marshal a name for a storage client based on %v. %v", s, err) - panic("failed to marshal storage client name") - } - reporterName := md5.Sum([]byte(statusReporterName)) - // The name of the StorageClient is the MD5 hash of the JSON - // representation of the StorageClient name and namespace. - return fmt.Sprintf("storageclient-%s-status-reporter", hex.EncodeToString(reporterName[:8])) -} - -func (s *StorageClientReconciler) delete(obj client.Object) error { - if err := s.Client.Delete(s.ctx, obj); err != nil && !kerrors.IsNotFound(err) { - return err + r.Log.Error(err, "StorageProvider:"+grpcCallName+":"+msg) + r.recorder.ReportIfNotPresent(r.storageClient, eventType, eventReason, msg) } - return nil } -func (s *StorageClientReconciler) reconcileClientStatusReporterJob(instance *v1alpha1.StorageClient) (reconcile.Result, error) { - // start the cronJob to ping the provider api server +func (r *StorageClientReconciler) reconcileClientStatusReporterJob() (reconcile.Result, error) { cronJob := &batchv1.CronJob{} - cronJob.Name = getStatusReporterName(instance.Namespace, instance.Name) - cronJob.Namespace = s.OperatorNamespace - utils.AddLabel(cronJob, storageClientNameLabel, instance.Name) - utils.AddLabel(cronJob, storageClientNamespaceLabel, instance.Namespace) + // maximum characters allowed for cronjob name is 52 and below interpolation creates 47 characters + cronJob.Name = fmt.Sprintf("storageclient-%s-status-reporter", getMD5Hash(r.storageClient.Name)) + cronJob.Namespace = r.OperatorNamespace + var podDeadLineSeconds int64 = 120 jobDeadLineSeconds := podDeadLineSeconds + 35 var keepJobResourceSeconds int32 = 600 var reducedKeptSuccecsful int32 = 1 - _, err := controllerutil.CreateOrUpdate(s.ctx, s.Client, cronJob, func() error { + _, err := controllerutil.CreateOrUpdate(r.ctx, r.Client, cronJob, func() error { + if err := r.own(cronJob); err != nil { + return fmt.Errorf("failed to own cronjob: %v", err) + } + // this helps during listing of cronjob by labels corresponding to the storageclient + utils.AddLabel(cronJob, storageClientNameLabel, r.storageClient.Name) cronJob.Spec = batchv1.CronJobSpec{ Schedule: "* * * * *", ConcurrencyPolicy: batchv1.ForbidConcurrent, @@ -496,17 +447,13 @@ func (s *StorageClientReconciler) reconcileClientStatusReporterJob(instance *v1a "/status-reporter", }, Env: []corev1.EnvVar{ - { - Name: utils.StorageClientNamespaceEnvVar, - Value: instance.Namespace, - }, { Name: utils.StorageClientNameEnvVar, - Value: instance.Name, + Value: r.storageClient.Name, }, { Name: utils.OperatorNamespaceEnvVar, - Value: s.OperatorNamespace, + Value: r.OperatorNamespace, }, }, }, @@ -526,98 +473,58 @@ func (s *StorageClientReconciler) reconcileClientStatusReporterJob(instance *v1a return reconcile.Result{}, nil } -func (s *StorageClientReconciler) list(obj client.ObjectList, listOptions ...client.ListOption) error { - return s.Client.List(s.ctx, obj, listOptions...) +func (r *StorageClientReconciler) list(obj client.ObjectList, listOptions ...client.ListOption) error { + return r.Client.List(r.ctx, obj, listOptions...) } -func (s *StorageClientReconciler) reconcileDefaultStorageClaims(instance *v1alpha1.StorageClient) error { - - if instance.GetAnnotations()[defaultClaimsProcessedAnnotationKey] == "true" { - // we already processed default claims for this client - return nil - } - - // try to list the default client who is the default storage claims owner - claimOwners := &v1alpha1.StorageClientList{} - if err := s.list(claimOwners, client.MatchingFields{defaultClaimsOwnerIndexName: "true"}); err != nil { - return fmt.Errorf("failed to list default storage claims owner: %v", err) +func (r *StorageClientReconciler) reconcileBlockStorageClaim() error { + blockClaim := &v1alpha1.StorageClaim{} + blockClaim.Name = fmt.Sprintf("%s-ceph-rbd", r.storageClient.Name) + blockClaim.Spec.Type = "block" + blockClaim.Spec.StorageClient = r.storageClient.Name + if err := r.own(blockClaim); err != nil { + return fmt.Errorf("failed to own storageclaim of type block: %v", err) } - - if len(claimOwners.Items) == 0 { - // no other storageclient claims as an owner and take responsibility of creating the default claims by becoming owner - if utils.AddAnnotation(instance, defaultClaimsOwnerAnnotationKey, "true") { - if err := s.update(instance); err != nil { - return fmt.Errorf("not able to claim ownership of creating default storageclaims: %v", err) - } - } + if err := r.create(blockClaim); err != nil && !kerrors.IsAlreadyExists(err) { + return fmt.Errorf("failed to create block storageclaim: %v", err) } + return nil +} - // we successfully took the ownership to create a default claim from this storageclient, so create default claims if not created - // after claiming as an owner no other storageclient will try to take ownership for creating default storageclaims - annotations := instance.GetAnnotations() - if annotations[defaultClaimsOwnerAnnotationKey] == "true" && annotations[defaultClaimsProcessedAnnotationKey] != "true" { - if err := s.createDefaultBlockStorageClaim(instance); err != nil && !kerrors.IsAlreadyExists(err) { - return fmt.Errorf("failed to create %q storageclaim: %v", defaultBlockStorageClaim, err) - } - if err := s.createDefaultSharedfileStorageClaim(instance); err != nil && !kerrors.IsAlreadyExists(err) { - return fmt.Errorf("failed to create %q storageclaim: %v", defaultSharedfileStorageClaim, err) - } +func (r *StorageClientReconciler) reconcileSharedfileStorageClaim() error { + sharedfileClaim := &v1alpha1.StorageClaim{} + sharedfileClaim.Name = fmt.Sprintf("%s-cephfs", r.storageClient.Name) + sharedfileClaim.Spec.Type = "sharedfile" + sharedfileClaim.Spec.StorageClient = r.storageClient.Name + if err := r.own(sharedfileClaim); err != nil { + return fmt.Errorf("failed to own storageclaim of type sharedfile: %v", err) } - - // annotate that we created default storageclaims successfully and will not retry - if utils.AddAnnotation(instance, defaultClaimsProcessedAnnotationKey, "true") { - if err := s.update(instance); err != nil { - return fmt.Errorf("not able to update annotation for creation of default storageclaims: %v", err) - } + if err := r.create(sharedfileClaim); err != nil && !kerrors.IsAlreadyExists(err) { + return fmt.Errorf("failed to create sharedfile storageclaim: %v", err) } - return nil } -func (s *StorageClientReconciler) createDefaultBlockStorageClaim(instance *v1alpha1.StorageClient) error { - storageclaim := &v1alpha1.StorageClaim{} - storageclaim.Name = defaultBlockStorageClaim - storageclaim.Spec.Type = "block" - storageclaim.Spec.StorageClient = &v1alpha1.StorageClientNamespacedName{ - Name: instance.Name, - Namespace: instance.Namespace, - } - return s.create(storageclaim) +func (r *StorageClientReconciler) get(obj client.Object, opts ...client.GetOption) error { + key := client.ObjectKeyFromObject(obj) + return r.Get(r.ctx, key, obj, opts...) } -func (s *StorageClientReconciler) createDefaultSharedfileStorageClaim(instance *v1alpha1.StorageClient) error { - sharedfileClaim := &v1alpha1.StorageClaim{} - sharedfileClaim.Name = defaultSharedfileStorageClaim - sharedfileClaim.Spec.Type = "sharedfile" - sharedfileClaim.Spec.StorageClient = &v1alpha1.StorageClientNamespacedName{ - Name: instance.Name, - Namespace: instance.Namespace, - } - return s.create(sharedfileClaim) +func (r *StorageClientReconciler) update(obj client.Object, opts ...client.UpdateOption) error { + return r.Update(r.ctx, obj, opts...) } -func (s *StorageClientReconciler) deleteDefaultStorageClaims(instance *v1alpha1.StorageClient) error { - if instance.GetAnnotations()[defaultClaimsOwnerAnnotationKey] == "true" { - blockClaim := &v1alpha1.StorageClaim{} - blockClaim.Name = defaultBlockStorageClaim - if err := s.delete(blockClaim); err != nil { - return fmt.Errorf("failed to remove default storageclaim %q: %v", blockClaim.Name, err) - } +func (r *StorageClientReconciler) create(obj client.Object, opts ...client.CreateOption) error { + return r.Create(r.ctx, obj, opts...) +} - sharedfsClaim := &v1alpha1.StorageClaim{} - sharedfsClaim.Name = defaultSharedfileStorageClaim - if err := s.delete(sharedfsClaim); err != nil { - return fmt.Errorf("failed to remove default storageclaim %q: %v", blockClaim.Name, err) - } - s.Log.Info("Successfully deleted default storageclaims") +func (r *StorageClientReconciler) delete(obj client.Object, opts ...client.DeleteOption) error { + if err := r.Delete(r.ctx, obj, opts...); err != nil && !kerrors.IsNotFound(err) { + return err } return nil } -func (s *StorageClientReconciler) update(obj client.Object, opts ...client.UpdateOption) error { - return s.Update(s.ctx, obj, opts...) -} - -func (s *StorageClientReconciler) create(obj client.Object, opts ...client.CreateOption) error { - return s.Create(s.ctx, obj, opts...) +func (r *StorageClientReconciler) own(dependent metav1.Object) error { + return controllerutil.SetOwnerReference(r.storageClient, dependent, r.Scheme) } diff --git a/pkg/utils/k8sutils.go b/pkg/utils/k8sutils.go index 5d47b2c2..11dce7a8 100644 --- a/pkg/utils/k8sutils.go +++ b/pkg/utils/k8sutils.go @@ -34,9 +34,6 @@ const OperatorPodNameEnvVar = "OPERATOR_POD_NAME" // StorageClientNameEnvVar is the constant for env variable STORAGE_CLIENT_NAME const StorageClientNameEnvVar = "STORAGE_CLIENT_NAME" -// StorageClientNamespaceEnvVar is the constant for env variable STORAGE_CLIENT_NAMESPACE -const StorageClientNamespaceEnvVar = "STORAGE_CLIENT_NAMESPACE" - const StatusReporterImageEnvVar = "STATUS_REPORTER_IMAGE" // Value corresponding to annotation key has subscription channel diff --git a/service/status-report/main.go b/service/status-report/main.go index 0f758e5a..9cacd293 100644 --- a/service/status-report/main.go +++ b/service/status-report/main.go @@ -74,11 +74,6 @@ func main() { ctx := context.Background() - storageClientNamespace, isSet := os.LookupEnv(utils.StorageClientNamespaceEnvVar) - if !isSet { - klog.Exitf("%s env var not set", utils.StorageClientNamespaceEnvVar) - } - storageClientName, isSet := os.LookupEnv(utils.StorageClientNameEnvVar) if !isSet { klog.Exitf("%s env var not set", utils.StorageClientNameEnvVar) @@ -90,15 +85,14 @@ func main() { } storageClient := &v1alpha1.StorageClient{} storageClient.Name = storageClientName - storageClient.Namespace = storageClientNamespace - if err = cl.Get(ctx, types.NamespacedName{Name: storageClient.Name, Namespace: storageClient.Namespace}, storageClient); err != nil { + if err = cl.Get(ctx, client.ObjectKeyFromObject(storageClient), storageClient); err != nil { klog.Exitf("Failed to get storageClient %q/%q: %v", storageClient.Namespace, storageClient.Name, err) } var oprVersion string csvList := opv1a1.ClusterServiceVersionList{} - if err = cl.List(ctx, &csvList, client.InNamespace(storageClientNamespace)); err != nil { + if err = cl.List(ctx, &csvList, client.InNamespace(operatorNamespace)); err != nil { klog.Warningf("Failed to list csv resources: %v", err) } else { item := utils.Find(csvList.Items, func(csv *opv1a1.ClusterServiceVersion) bool { @@ -131,11 +125,6 @@ func main() { klog.Warningf("Unable to find ocp version with completed update") } - namespacedName := types.NamespacedName{ - Namespace: storageClient.Namespace, - Name: storageClient.Name, - } - clusterConfig := &corev1.ConfigMap{} clusterConfig.Name = clusterConfigName clusterConfig.Namespace = clusterConfigNamespace @@ -174,7 +163,7 @@ func main() { SetOperatorVersion(oprVersion). SetClusterID(string(clusterID)). SetClusterName(clusterName). - SetNamespacedName(namespacedName.String()) + SetNamespacedName(storageClientName) statusResponse, err := providerClient.ReportStatus(ctx, storageClient.Status.ConsumerID, status) if err != nil { klog.Exitf("Failed to report status of storageClient %v: %v", storageClient.Status.ConsumerID, err)