@@ -25,6 +25,7 @@ import (
2525 apiresource "k8s.io/apimachinery/pkg/api/resource"
2626 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2727
28+ "github.com/oceanbase/ob-operator/api/constants"
2829 apitypes "github.com/oceanbase/ob-operator/api/types"
2930 "github.com/oceanbase/ob-operator/api/v1alpha1"
3031 "github.com/oceanbase/ob-operator/internal/clients"
@@ -537,6 +538,7 @@ func generateOBClusterInstance(param *param.CreateOBClusterParam) *v1alpha1.OBCl
537538 Parameters : parameters ,
538539 Topology : topology ,
539540 UserSecrets : generateUserSecrets (param .Name , param .ClusterId ),
541+ Scenario : param .Scenario ,
540542 },
541543 }
542544 switch param .Mode {
@@ -546,6 +548,12 @@ func generateOBClusterInstance(param *param.CreateOBClusterParam) *v1alpha1.OBCl
546548 obcluster .Annotations [oceanbaseconst .AnnotationsMode ] = oceanbaseconst .ModeService
547549 default :
548550 }
551+ if param .DeletionProtection {
552+ obcluster .Annotations [oceanbaseconst .AnnotationsIgnoreDeletion ] = "true"
553+ }
554+ if param .PvcIndependent {
555+ obcluster .Annotations [oceanbaseconst .AnnotationsIndependentPVCLifecycle ] = "true"
556+ }
549557 return obcluster
550558}
551559
@@ -723,3 +731,149 @@ func GetOBClusterStatistic(ctx context.Context) ([]response.OBClusterStatistic,
723731 })
724732 return statisticResult , nil
725733}
734+
735+ func PatchOBCluster (ctx context.Context , nn * param.K8sObjectIdentity , param * param.PatchOBClusterParam ) (* response.OBCluster , error ) {
736+ obcluster , err := clients .GetOBCluster (ctx , nn .Namespace , nn .Name )
737+ if err != nil {
738+ return nil , errors .Wrapf (err , "Get obcluster %s %s" , nn .Namespace , nn .Name )
739+ }
740+ if obcluster .Status .Status != clusterstatus .Running {
741+ return nil , errors .Errorf ("OBCluster status is invalid %s" , obcluster .Status .Status )
742+ }
743+ alreadyIgnoredDeletion := obcluster .Annotations [oceanbaseconst .AnnotationsIgnoreDeletion ] == "true"
744+
745+ if obcluster .Spec .OBServerTemplate != nil {
746+ // Update resource if specified
747+ obcluster .Spec .OBServerTemplate .Resource = & apitypes.ResourceSpec {
748+ Cpu : * apiresource .NewQuantity (param .Resource .Cpu , apiresource .DecimalSI ),
749+ Memory : * apiresource .NewQuantity (param .Resource .MemoryGB * constant .GB , apiresource .BinarySI ),
750+ }
751+ } else if param .Storage != nil && obcluster .Spec .OBServerTemplate != nil {
752+ // Update storage if specified
753+ obcluster .Spec .OBServerTemplate .Storage = & apitypes.OceanbaseStorageSpec {
754+ DataStorage : & apitypes.StorageSpec {
755+ StorageClass : param .Storage .Data .StorageClass ,
756+ Size : * apiresource .NewQuantity (param .Storage .Data .SizeGB * constant .GB , apiresource .BinarySI ),
757+ },
758+ RedoLogStorage : & apitypes.StorageSpec {
759+ StorageClass : param .Storage .RedoLog .StorageClass ,
760+ Size : * apiresource .NewQuantity (param .Storage .RedoLog .SizeGB * constant .GB , apiresource .BinarySI ),
761+ },
762+ LogStorage : & apitypes.StorageSpec {
763+ StorageClass : param .Storage .Log .StorageClass ,
764+ Size : * apiresource .NewQuantity (param .Storage .Log .SizeGB * constant .GB , apiresource .BinarySI ),
765+ },
766+ }
767+ } else if param .Monitor != nil && obcluster .Spec .MonitorTemplate == nil {
768+ // Update monitor if specified
769+ obcluster .Spec .MonitorTemplate = & apitypes.MonitorTemplate {
770+ Image : param .Monitor .Image ,
771+ Resource : & apitypes.ResourceSpec {
772+ Cpu : * apiresource .NewQuantity (param .Monitor .Resource .Cpu , apiresource .DecimalSI ),
773+ Memory : * apiresource .NewQuantity (param .Monitor .Resource .MemoryGB * constant .GB , apiresource .BinarySI ),
774+ },
775+ }
776+ } else if param .RemoveMonitor {
777+ // Remove monitor if specified
778+ obcluster .Spec .MonitorTemplate = nil
779+ } else if param .BackupVolume != nil && obcluster .Spec .BackupVolume == nil {
780+ // Update backup volume if specified
781+ obcluster .Spec .BackupVolume = & apitypes.BackupVolumeSpec {
782+ Volume : & corev1.Volume {
783+ Name : "ob-backup" ,
784+ VolumeSource : corev1.VolumeSource {
785+ NFS : & corev1.NFSVolumeSource {
786+ Server : param .BackupVolume .Address ,
787+ Path : param .BackupVolume .Path ,
788+ ReadOnly : false ,
789+ },
790+ },
791+ },
792+ }
793+ } else if param .RemoveBackupVolume {
794+ // Remove backup volume if specified
795+ obcluster .Spec .BackupVolume = nil
796+ } else if len (param .Parameters ) > 0 {
797+ // Update parameters if specified
798+ obcluster .Spec .Parameters = buildOBClusterParameters (param .Parameters )
799+ }
800+
801+ if param .AddDeletionProtection && ! alreadyIgnoredDeletion {
802+ // Update deletion protection if specified
803+ obcluster .Annotations [oceanbaseconst .AnnotationsIgnoreDeletion ] = "true"
804+ } else if param .RemoveDeletionProtection && alreadyIgnoredDeletion {
805+ delete (obcluster .Annotations , oceanbaseconst .AnnotationsIgnoreDeletion )
806+ }
807+
808+ cluster , err := clients .UpdateOBCluster (ctx , obcluster )
809+ if err != nil {
810+ return nil , oberr .NewInternal (err .Error ())
811+ }
812+ return buildOBClusterResponse (ctx , cluster )
813+ }
814+
815+ func RestartOBServers (ctx context.Context , nn * param.K8sObjectIdentity , param * param.RestartOBServersParam ) (* response.OBCluster , error ) {
816+ obcluster , err := clients .GetOBCluster (ctx , nn .Namespace , nn .Name )
817+ if err != nil {
818+ return nil , errors .Wrapf (err , "Get obcluster %s %s" , nn .Namespace , nn .Name )
819+ }
820+ if obcluster .Status .Status != clusterstatus .Running {
821+ return nil , errors .Errorf ("OBCluster status is invalid %s" , obcluster .Status .Status )
822+ }
823+
824+ // Create OBClusterOperation for restarting observers
825+ operation := & v1alpha1.OBClusterOperation {
826+ ObjectMeta : metav1.ObjectMeta {
827+ GenerateName : "restart-observers-" ,
828+ Namespace : nn .Namespace ,
829+ },
830+ Spec : v1alpha1.OBClusterOperationSpec {
831+ Type : constants .ClusterOpTypeRestartOBServers ,
832+ OBCluster : nn .Name ,
833+ RestartOBServers : & v1alpha1.RestartOBServersConfig {
834+ OBServers : param .OBServers ,
835+ OBZones : param .OBZones ,
836+ All : param .All ,
837+ },
838+ },
839+ }
840+
841+ _ , err = clients .CreateOBClusterOperation (ctx , operation )
842+ if err != nil {
843+ return nil , oberr .NewInternal (err .Error ())
844+ }
845+
846+ return buildOBClusterResponse (ctx , obcluster )
847+ }
848+
849+ func DeleteOBServers (ctx context.Context , nn * param.K8sObjectIdentity , param * param.DeleteOBServersParam ) (* response.OBCluster , error ) {
850+ obcluster , err := clients .GetOBCluster (ctx , nn .Namespace , nn .Name )
851+ if err != nil {
852+ return nil , errors .Wrapf (err , "Get obcluster %s %s" , nn .Namespace , nn .Name )
853+ }
854+ if obcluster .Status .Status != clusterstatus .Running {
855+ return nil , errors .Errorf ("OBCluster status is invalid %s" , obcluster .Status .Status )
856+ }
857+
858+ // Create OBClusterOperation for deleting observers
859+ operation := & v1alpha1.OBClusterOperation {
860+ ObjectMeta : metav1.ObjectMeta {
861+ GenerateName : "delete-observers-" ,
862+ Namespace : nn .Namespace ,
863+ },
864+ Spec : v1alpha1.OBClusterOperationSpec {
865+ Type : constants .ClusterOpTypeDeleteOBServers ,
866+ OBCluster : nn .Name ,
867+ DeleteOBServers : & v1alpha1.DeleteOBServersConfig {
868+ OBServers : param .OBServers ,
869+ },
870+ },
871+ }
872+
873+ _ , err = clients .CreateOBClusterOperation (ctx , operation )
874+ if err != nil {
875+ return nil , oberr .NewInternal (err .Error ())
876+ }
877+
878+ return buildOBClusterResponse (ctx , obcluster )
879+ }
0 commit comments