diff --git a/controllers/storagecluster/storageclient.go b/controllers/storagecluster/storageclient.go index 19254da491..e398b58197 100644 --- a/controllers/storagecluster/storageclient.go +++ b/controllers/storagecluster/storageclient.go @@ -40,6 +40,7 @@ func (s *storageClient) ensureCreated(r *StorageClusterReconciler, storagecluste // the controller of storageclient is running in same namespace and should be able to resolve the endpoint // via servicename:serviceport irrespective of clusterip/nodeport/lb storageClient.Spec.StorageProviderEndpoint = fmt.Sprintf("%s:%d", ocsProviderServerName, ocsProviderServicePort) + util.AddAnnotation(storageClient, "is-local-client", "true") return nil }) if err != nil { diff --git a/rbac/provider-role.yaml b/rbac/provider-role.yaml index bd708fc6fe..ff2dc20ee6 100644 --- a/rbac/provider-role.yaml +++ b/rbac/provider-role.yaml @@ -61,3 +61,12 @@ rules: verbs: - get - list +- apiGroups: + - noobaa.io + resources: + - noobaaaccounts + verbs: + - get + - list + - create + - delete diff --git a/services/provider/server/consumer.go b/services/provider/server/consumer.go index 6e050257fd..33e3baa7f4 100644 --- a/services/provider/server/consumer.go +++ b/services/provider/server/consumer.go @@ -6,6 +6,7 @@ import ( "fmt" "sync" + nbv1 "github.com/noobaa/noobaa-operator/v5/pkg/apis/noobaa/v1alpha1" ocsv1alpha1 "github.com/red-hat-storage/ocs-operator/api/v4/v1alpha1" ifaces "github.com/red-hat-storage/ocs-operator/v4/services/provider/interfaces" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -226,3 +227,35 @@ func (c *ocsConsumerManager) UpdateConsumerStatus(ctx context.Context, id string klog.Infof("successfully updated Status for StorageConsumer %v", consumerObj.Name) return nil } + +func (c *ocsConsumerManager) CreateNoobaaAccount(ctx context.Context, id string) error { + + consumerObj, err := c.Get(ctx, id) + if err != nil { + return err + } + nbAccountObj := &nbv1.NooBaaAccount{} + nbAccountObj.Name = consumerObj.Name + nbAccountObj.Namespace = consumerObj.Namespace + nbAccountObj.Spec.Role = "remote-operator" + + err = c.client.Create(ctx, nbAccountObj) + if err != nil { + return fmt.Errorf("failed to create noobaa account for storageConsumer %v: %v", consumerObj.Name, err) + } + return nil +} + +func (c *ocsConsumerManager) DeleteNoobaaAccount(ctx context.Context, id string) error { + consumerObj, err := c.Get(ctx, id) + if err != nil { + return err + } + nbAccountObj := &nbv1.NooBaaAccount{} + nbAccountObj.Name = consumerObj.Name + nbAccountObj.Namespace = consumerObj.Namespace + if err := c.client.Delete(ctx, nbAccountObj); err != nil { + return fmt.Errorf("failed to delete Noobaa account %q. %v", nbAccountObj.Name, err) + } + return nil +} diff --git a/services/provider/server/server.go b/services/provider/server/server.go index b019b2c236..b7b9ee28c8 100644 --- a/services/provider/server/server.go +++ b/services/provider/server/server.go @@ -19,18 +19,16 @@ import ( "github.com/blang/semver/v4" quotav1 "github.com/openshift/api/quota/v1" + routev1 "github.com/openshift/api/route/v1" + opv1a1 "github.com/operator-framework/api/pkg/operators/v1alpha1" "github.com/red-hat-storage/ocs-operator/api/v4/v1alpha1" ocsv1alpha1 "github.com/red-hat-storage/ocs-operator/api/v4/v1alpha1" controllers "github.com/red-hat-storage/ocs-operator/v4/controllers/storageconsumer" "github.com/red-hat-storage/ocs-operator/v4/controllers/util" + "github.com/red-hat-storage/ocs-operator/v4/services" pb "github.com/red-hat-storage/ocs-operator/v4/services/provider/pb" ocsVersion "github.com/red-hat-storage/ocs-operator/v4/version" rookCephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - opv1a1 "github.com/operator-framework/api/pkg/operators/v1alpha1" - "github.com/red-hat-storage/ocs-operator/v4/services" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -39,6 +37,8 @@ import ( corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" klog "k8s.io/klog/v2" @@ -146,7 +146,10 @@ func (s *OCSProviderServer) AcknowledgeOnboarding(ctx context.Context, req *pb.A } return nil, status.Errorf(codes.Internal, "Failed to update the storageConsumer. %v", err) } - + // create noobaa account CR + if err := s.consumerManager.CreateNoobaaAccount(ctx, req.StorageConsumerUUID); err != nil { + return nil, status.Errorf(codes.Internal, "Failed to create noobaa account for storageconsumer. %v", err) + } return &pb.AcknowledgeOnboardingResponse{}, nil } @@ -191,7 +194,11 @@ func (s *OCSProviderServer) OffboardConsumer(ctx context.Context, req *pb.Offboa if err != nil { return nil, status.Errorf(codes.Internal, "failed to delete storageConsumer resource with the provided UUID. %v", err) } - + // remove noobaa account + err = s.consumerManager.DeleteNoobaaAccount(ctx, req.StorageConsumerUUID) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to delete noobaaAccount resource with the provided UUID. %v", err) + } return &pb.OffboardConsumerResponse{}, nil } @@ -238,6 +245,10 @@ func newClient() (client.Client, error) { if err != nil { return nil, fmt.Errorf("failed to add operatorsv1alpha1 to scheme. %v", err) } + err = routev1.AddToScheme(scheme) + if err != nil { + return nil, fmt.Errorf("failed to add routev1 to scheme. %v", err) + } config, err := config.GetConfig() if err != nil { @@ -400,6 +411,44 @@ func (s *OCSProviderServer) getExternalResources(ctx context.Context, consumerRe } + // Fetch noobaa remote secret and management address and append to extResources + noobaaOperatorSecret := &v1.Secret{} + consumerID := strings.TrimPrefix(consumerResource.Name, "storageconsumer-") + if consumerID != "" && len(consumerID) == 0 || consumerID == consumerResource.Name { + return nil, fmt.Errorf("failed to get consumerID from consumerResource Name%s %v", consumerResource.Name, err) + } + noobaaOperatorSecretName := consumerID + err = s.client.Get(ctx, types.NamespacedName{Name: noobaaOperatorSecretName, Namespace: s.namespace}, noobaaOperatorSecret) + if err != nil { + return nil, fmt.Errorf("failed to get %s secret. %v", noobaaOperatorSecretName, err) + } + + authToken, ok := noobaaOperatorSecret.Data["auth_token"] + if !ok || len(authToken) == 0 { + return nil, fmt.Errorf("auth_token not found in %s secret", noobaaOperatorSecretName) + } + + noobaMgmtRoute := &routev1.Route{} + err = s.client.Get(ctx, types.NamespacedName{Name: "noobaa-mgmt", Namespace: s.namespace}, noobaMgmtRoute) + if err != nil { + return nil, fmt.Errorf("failed to get noobaa-mgmt route. %v", err) + } + if noobaMgmtRoute.Status.Ingress == nil || len(noobaMgmtRoute.Status.Ingress) == 0 { + return nil, fmt.Errorf("no Ingress available in noobaa-mgmt route") + } + + noobaaMgmtAddress := noobaMgmtRoute.Status.Ingress[0].Host + if noobaaMgmtAddress == "" { + return nil, fmt.Errorf("no Host found in noobaa-mgmt route Ingress") + } + extR = append(extR, &pb.ExternalResource{ + Name: consumerResource.Name, + Kind: "Secret", + Data: mustMarshal((map[string]string{ + "auth_token": string(authToken), + "mgmt_addr": noobaaMgmtAddress, + })), + }) return extR, nil } diff --git a/vendor/github.com/noobaa/noobaa-operator/v5/pkg/apis/noobaa/v1alpha1/noobaaaccount_types.go b/vendor/github.com/noobaa/noobaa-operator/v5/pkg/apis/noobaa/v1alpha1/noobaaaccount_types.go index 8e395bf008..b255c95658 100644 --- a/vendor/github.com/noobaa/noobaa-operator/v5/pkg/apis/noobaa/v1alpha1/noobaaaccount_types.go +++ b/vendor/github.com/noobaa/noobaa-operator/v5/pkg/apis/noobaa/v1alpha1/noobaaaccount_types.go @@ -70,6 +70,10 @@ type NooBaaAccountSpec struct { // ForceMd5Etag specifies whether MD5 Etags should be calculated for the account or not // +optional ForceMd5Etag *bool `json:"force_md5_etag,omitempty"` + + // Role specifies the permssions role for the account + // +optional + Role string `json:"role,omitempty"` } // AccountNsfsConfig is the configuration of NSFS of CreateAccountParams