diff --git a/go.mod b/go.mod index 75e5b3ed09..aa52438b2b 100644 --- a/go.mod +++ b/go.mod @@ -31,6 +31,7 @@ require ( github.com/operator-framework/operator-lifecycle-manager v0.28.1-0.20240827180342-c730fbc779a8 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.76.0 github.com/prometheus-operator/prometheus-operator/pkg/client v0.76.0 + github.com/ramendr/ramen/api v0.0.0-20241014164256-3929be6ce297 github.com/red-hat-storage/ocs-client-operator v0.0.0-20240731100835-31192d2c370e github.com/red-hat-storage/ocs-operator/api/v4 v4.0.0-20240731064750-930a78b89d84 github.com/red-hat-storage/ocs-operator/services/provider/api/v4 v4.0.0-00010101000000-000000000000 @@ -114,7 +115,6 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.57.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/ramendr/ramen/api v0.0.0-20241014164256-3929be6ce297 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect diff --git a/services/provider/server/maintenancemode.go b/services/provider/server/maintenancemode.go new file mode 100644 index 0000000000..4bd8da8e5a --- /dev/null +++ b/services/provider/server/maintenancemode.go @@ -0,0 +1,50 @@ +package server + +import ( + "context" + ramenv1alpha1 "github.com/ramendr/ramen/api/v1alpha1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +type maintenanceModeManager struct { + client client.Client + namespace string +} + +func newMaintenanceModeManager(cl client.Client, namespace string) (*maintenanceModeManager, error) { + return &maintenanceModeManager{ + client: cl, + namespace: namespace, + }, nil +} + +func (m maintenanceModeManager) Create(ctx context.Context, name string, spec *ramenv1alpha1.MaintenanceModeSpec) error { + mModeObj := &ramenv1alpha1.MaintenanceMode{} + mModeObj.Name = name + _, err := controllerutil.CreateOrUpdate(ctx, m.client, mModeObj, func() error { + mModeObj.Spec = *spec + return nil + }) + return err +} + +func (m maintenanceModeManager) Get(ctx context.Context, name string) (*ramenv1alpha1.MaintenanceMode, error) { + mModeObj := &ramenv1alpha1.MaintenanceMode{} + mModeObj.Name = name + err := m.client.Get(ctx, client.ObjectKey{Name: name}, mModeObj) + if err != nil { + return nil, err + } + return mModeObj, nil +} + +func (m maintenanceModeManager) Delete(ctx context.Context, name string) error { + mModeObj := &ramenv1alpha1.MaintenanceMode{} + mModeObj.Name = name + err := m.client.Delete(ctx, mModeObj) + if err != nil { + return err + } + return nil +} diff --git a/services/provider/server/server.go b/services/provider/server/server.go index f12e7e021f..62196ed17b 100644 --- a/services/provider/server/server.go +++ b/services/provider/server/server.go @@ -37,6 +37,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" csiopv1a1 "github.com/ceph/ceph-csi-operator/api/v1alpha1" + ramenv1alpha1 "github.com/ramendr/ramen/api/v1alpha1" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -67,10 +68,11 @@ const ( type OCSProviderServer struct { pb.UnimplementedOCSProviderServer - client client.Client - consumerManager *ocsConsumerManager - storageRequestManager *storageRequestManager - namespace string + client client.Client + consumerManager *ocsConsumerManager + storageRequestManager *storageRequestManager + maintenanceModeManager *maintenanceModeManager + namespace string } func NewOCSProviderServer(ctx context.Context, namespace string) (*OCSProviderServer, error) { @@ -89,11 +91,17 @@ func NewOCSProviderServer(ctx context.Context, namespace string) (*OCSProviderSe return nil, fmt.Errorf("failed to create new StorageRequest instance. %v", err) } + maintenanceModeManager, err := newMaintenanceModeManager(client, namespace) + if err != nil { + return nil, fmt.Errorf("failed to create new MaintenanceMode instance. %v", err) + } + return &OCSProviderServer{ - client: client, - consumerManager: consumerManager, - storageRequestManager: storageRequestManager, - namespace: namespace, + client: client, + consumerManager: consumerManager, + storageRequestManager: storageRequestManager, + maintenanceModeManager: maintenanceModeManager, + namespace: namespace, }, nil } @@ -949,3 +957,53 @@ func extractMonitorIps(data string) ([]string, error) { func (s *OCSProviderServer) PeerStorageCluster(_ context.Context, _ *pb.PeerStorageClusterRequest) (*pb.PeerStorageClusterResponse, error) { return &pb.PeerStorageClusterResponse{}, nil } + +func (s *OCSProviderServer) StartMaintenanceMode(ctx context.Context, req *pb.StartMaintenanceModeRequest) (*pb.StartMaintenanceModeResponse, error) { + // Get storage consumer resource using UUID + _, err := s.consumerManager.Get(ctx, req.StorageConsumerUUID) + if err != nil { + return nil, status.Errorf(codes.Internal, err.Error()) + } + + obj := req.ExternalResource + + mmModeSpec := &ramenv1alpha1.MaintenanceModeSpec{} + err = json.Unmarshal(req.ExternalResource.Data, mmModeSpec) + if err != nil { + return nil, status.Errorf(codes.Internal, err.Error()) + } + + if err = s.maintenanceModeManager.Create(ctx, obj.Name, mmModeSpec); err != nil { + return nil, status.Errorf(codes.Internal, err.Error()) + } + return &pb.StartMaintenanceModeResponse{}, nil +} + +func (s *OCSProviderServer) StopMaintenanceMode(ctx context.Context, req *pb.StopMaintenanceModeRequest) (*pb.StopMaintenanceModeResponse, error) { + // Get storage consumer resource using UUID + _, err := s.consumerManager.Get(ctx, req.StorageConsumerUUID) + if err != nil { + return nil, status.Errorf(codes.Internal, err.Error()) + } + + if err := s.maintenanceModeManager.Delete(ctx, req.MaintenanceModeName); err != nil { + return nil, status.Errorf(codes.Internal, err.Error()) + } + + return &pb.StopMaintenanceModeResponse{}, nil +} + +func (s *OCSProviderServer) GetMaintenanceModeStatus(ctx context.Context, req *pb.GetMaintenanceModeStatusRequest) (*pb.GetMaintenanceModeStatusResponse, error) { + // Get storage consumer resource using UUID + _, err := s.consumerManager.Get(ctx, req.StorageConsumerUUID) + if err != nil { + return nil, status.Errorf(codes.Internal, err.Error()) + } + + maintenanceMode, err := s.maintenanceModeManager.Get(ctx, req.MaintenanceModeName) + if err != nil { + return nil, status.Errorf(codes.Internal, err.Error()) + } + + return &pb.GetMaintenanceModeStatusResponse{MaintenanceModeStatus: mustMarshal(maintenanceMode.Status)}, nil +}