@@ -20,11 +20,13 @@ import (
2020
2121 "github.com/google/uuid"
2222 "github.com/pkg/errors"
23+ "github.com/sirupsen/logrus"
2324 logger "github.com/sirupsen/logrus"
2425 corev1 "k8s.io/api/core/v1"
2526 apiresource "k8s.io/apimachinery/pkg/api/resource"
2627 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2728
29+ "github.com/oceanbase/ob-operator/api/constants"
2830 apitypes "github.com/oceanbase/ob-operator/api/types"
2931 "github.com/oceanbase/ob-operator/api/v1alpha1"
3032 "github.com/oceanbase/ob-operator/internal/clients"
@@ -35,7 +37,9 @@ import (
3537 modelcommon "github.com/oceanbase/ob-operator/internal/dashboard/model/common"
3638 "github.com/oceanbase/ob-operator/internal/dashboard/model/param"
3739 "github.com/oceanbase/ob-operator/internal/dashboard/model/response"
40+ "github.com/oceanbase/ob-operator/internal/dashboard/utils"
3841 oberr "github.com/oceanbase/ob-operator/pkg/errors"
42+ models "github.com/oceanbase/ob-operator/pkg/oceanbase-sdk/model"
3943)
4044
4145const (
@@ -115,11 +119,16 @@ func buildOBClusterResponse(ctx context.Context, obcluster *v1alpha1.OBCluster)
115119 // TODO: add metrics
116120 Metrics : nil ,
117121 }
118- var parameters []modelcommon.KVPair
122+ var parameters []response.ParameterSpec
123+ statusParameterMap := make (map [string ]string , 0 )
124+ for _ , param := range obcluster .Status .Parameters {
125+ statusParameterMap [param .Name ] = param .Value
126+ }
119127 for _ , param := range obcluster .Spec .Parameters {
120- parameters = append (parameters , modelcommon.KVPair {
121- Key : param .Name ,
122- Value : param .Value ,
128+ parameters = append (parameters , response.ParameterSpec {
129+ Name : param .Name ,
130+ SpecValue : param .Value ,
131+ Value : statusParameterMap [param .Name ],
123132 })
124133 }
125134 respCluster .Parameters = parameters
@@ -537,6 +546,7 @@ func generateOBClusterInstance(param *param.CreateOBClusterParam) *v1alpha1.OBCl
537546 Parameters : parameters ,
538547 Topology : topology ,
539548 UserSecrets : generateUserSecrets (param .Name , param .ClusterId ),
549+ Scenario : param .Scenario ,
540550 },
541551 }
542552 switch param .Mode {
@@ -546,6 +556,12 @@ func generateOBClusterInstance(param *param.CreateOBClusterParam) *v1alpha1.OBCl
546556 obcluster .Annotations [oceanbaseconst .AnnotationsMode ] = oceanbaseconst .ModeService
547557 default :
548558 }
559+ if param .DeletionProtection {
560+ obcluster .Annotations [oceanbaseconst .AnnotationsIgnoreDeletion ] = "true"
561+ }
562+ if param .PvcIndependent {
563+ obcluster .Annotations [oceanbaseconst .AnnotationsIndependentPVCLifecycle ] = "true"
564+ }
549565 return obcluster
550566}
551567
@@ -723,3 +739,175 @@ func GetOBClusterStatistic(ctx context.Context) ([]response.OBClusterStatistic,
723739 })
724740 return statisticResult , nil
725741}
742+
743+ func PatchOBCluster (ctx context.Context , nn * param.K8sObjectIdentity , param * param.PatchOBClusterParam ) (* response.OBCluster , error ) {
744+ obcluster , err := clients .GetOBCluster (ctx , nn .Namespace , nn .Name )
745+ if err != nil {
746+ return nil , errors .Wrapf (err , "Get obcluster %s %s" , nn .Namespace , nn .Name )
747+ }
748+ if obcluster .Status .Status != clusterstatus .Running {
749+ return nil , errors .Errorf ("OBCluster status is invalid %s" , obcluster .Status .Status )
750+ }
751+ alreadyIgnoredDeletion := obcluster .Annotations [oceanbaseconst .AnnotationsIgnoreDeletion ] == "true"
752+
753+ if obcluster .Spec .OBServerTemplate != nil {
754+ // Update resource if specified
755+ obcluster .Spec .OBServerTemplate .Resource = & apitypes.ResourceSpec {
756+ Cpu : * apiresource .NewQuantity (param .Resource .Cpu , apiresource .DecimalSI ),
757+ Memory : * apiresource .NewQuantity (param .Resource .MemoryGB * constant .GB , apiresource .BinarySI ),
758+ }
759+ } else if param .Storage != nil && obcluster .Spec .OBServerTemplate != nil {
760+ // Update storage if specified
761+ obcluster .Spec .OBServerTemplate .Storage = & apitypes.OceanbaseStorageSpec {
762+ DataStorage : & apitypes.StorageSpec {
763+ StorageClass : param .Storage .Data .StorageClass ,
764+ Size : * apiresource .NewQuantity (param .Storage .Data .SizeGB * constant .GB , apiresource .BinarySI ),
765+ },
766+ RedoLogStorage : & apitypes.StorageSpec {
767+ StorageClass : param .Storage .RedoLog .StorageClass ,
768+ Size : * apiresource .NewQuantity (param .Storage .RedoLog .SizeGB * constant .GB , apiresource .BinarySI ),
769+ },
770+ LogStorage : & apitypes.StorageSpec {
771+ StorageClass : param .Storage .Log .StorageClass ,
772+ Size : * apiresource .NewQuantity (param .Storage .Log .SizeGB * constant .GB , apiresource .BinarySI ),
773+ },
774+ }
775+ } else if param .Monitor != nil && obcluster .Spec .MonitorTemplate == nil {
776+ // Update monitor if specified
777+ obcluster .Spec .MonitorTemplate = & apitypes.MonitorTemplate {
778+ Image : param .Monitor .Image ,
779+ Resource : & apitypes.ResourceSpec {
780+ Cpu : * apiresource .NewQuantity (param .Monitor .Resource .Cpu , apiresource .DecimalSI ),
781+ Memory : * apiresource .NewQuantity (param .Monitor .Resource .MemoryGB * constant .GB , apiresource .BinarySI ),
782+ },
783+ }
784+ } else if param .RemoveMonitor {
785+ // Remove monitor if specified
786+ obcluster .Spec .MonitorTemplate = nil
787+ } else if param .BackupVolume != nil && obcluster .Spec .BackupVolume == nil {
788+ // Update backup volume if specified
789+ obcluster .Spec .BackupVolume = & apitypes.BackupVolumeSpec {
790+ Volume : & corev1.Volume {
791+ Name : "ob-backup" ,
792+ VolumeSource : corev1.VolumeSource {
793+ NFS : & corev1.NFSVolumeSource {
794+ Server : param .BackupVolume .Address ,
795+ Path : param .BackupVolume .Path ,
796+ ReadOnly : false ,
797+ },
798+ },
799+ },
800+ }
801+ } else if param .RemoveBackupVolume {
802+ // Remove backup volume if specified
803+ obcluster .Spec .BackupVolume = nil
804+ } else if len (param .Parameters ) > 0 {
805+ // Update parameters if specified
806+ obcluster .Spec .Parameters = buildOBClusterParameters (param .Parameters )
807+ }
808+
809+ if param .AddDeletionProtection && ! alreadyIgnoredDeletion {
810+ // Update deletion protection if specified
811+ obcluster .Annotations [oceanbaseconst .AnnotationsIgnoreDeletion ] = "true"
812+ } else if param .RemoveDeletionProtection && alreadyIgnoredDeletion {
813+ delete (obcluster .Annotations , oceanbaseconst .AnnotationsIgnoreDeletion )
814+ }
815+
816+ cluster , err := clients .UpdateOBCluster (ctx , obcluster )
817+ if err != nil {
818+ return nil , oberr .NewInternal (err .Error ())
819+ }
820+ return buildOBClusterResponse (ctx , cluster )
821+ }
822+
823+ func RestartOBServers (ctx context.Context , nn * param.K8sObjectIdentity , param * param.RestartOBServersParam ) (* response.OBCluster , error ) {
824+ obcluster , err := clients .GetOBCluster (ctx , nn .Namespace , nn .Name )
825+ if err != nil {
826+ return nil , errors .Wrapf (err , "Get obcluster %s %s" , nn .Namespace , nn .Name )
827+ }
828+ if obcluster .Status .Status != clusterstatus .Running {
829+ return nil , errors .Errorf ("OBCluster status is invalid %s" , obcluster .Status .Status )
830+ }
831+
832+ // Create OBClusterOperation for restarting observers
833+ operation := & v1alpha1.OBClusterOperation {
834+ ObjectMeta : metav1.ObjectMeta {
835+ GenerateName : "restart-observers-" ,
836+ Namespace : nn .Namespace ,
837+ },
838+ Spec : v1alpha1.OBClusterOperationSpec {
839+ Type : constants .ClusterOpTypeRestartOBServers ,
840+ OBCluster : nn .Name ,
841+ RestartOBServers : & v1alpha1.RestartOBServersConfig {
842+ OBServers : param .OBServers ,
843+ OBZones : param .OBZones ,
844+ All : param .All ,
845+ },
846+ },
847+ }
848+
849+ _ , err = clients .CreateOBClusterOperation (ctx , operation )
850+ if err != nil {
851+ return nil , oberr .NewInternal (err .Error ())
852+ }
853+
854+ return buildOBClusterResponse (ctx , obcluster )
855+ }
856+
857+ func DeleteOBServers (ctx context.Context , nn * param.K8sObjectIdentity , param * param.DeleteOBServersParam ) (* response.OBCluster , error ) {
858+ obcluster , err := clients .GetOBCluster (ctx , nn .Namespace , nn .Name )
859+ if err != nil {
860+ return nil , errors .Wrapf (err , "Get obcluster %s %s" , nn .Namespace , nn .Name )
861+ }
862+ if obcluster .Status .Status != clusterstatus .Running {
863+ return nil , errors .Errorf ("OBCluster status is invalid %s" , obcluster .Status .Status )
864+ }
865+
866+ // Create OBClusterOperation for deleting observers
867+ operation := & v1alpha1.OBClusterOperation {
868+ ObjectMeta : metav1.ObjectMeta {
869+ GenerateName : "delete-observers-" ,
870+ Namespace : nn .Namespace ,
871+ },
872+ Spec : v1alpha1.OBClusterOperationSpec {
873+ Type : constants .ClusterOpTypeDeleteOBServers ,
874+ OBCluster : nn .Name ,
875+ DeleteOBServers : & v1alpha1.DeleteOBServersConfig {
876+ OBServers : param .OBServers ,
877+ },
878+ },
879+ }
880+
881+ _ , err = clients .CreateOBClusterOperation (ctx , operation )
882+ if err != nil {
883+ return nil , oberr .NewInternal (err .Error ())
884+ }
885+
886+ return buildOBClusterResponse (ctx , obcluster )
887+ }
888+
889+ func ListOBClusterParameters (ctx context.Context , nn * param.K8sObjectIdentity ) ([]* models.Parameter , error ) {
890+ obcluster , err := clients .GetOBCluster (ctx , nn .Namespace , nn .Name )
891+ if err != nil {
892+ return nil , errors .Wrapf (err , "Get obcluster %s %s" , nn .Namespace , nn .Name )
893+ }
894+ observerList := v1alpha1.OBServerList {}
895+ err = clients .ServerClient .List (ctx , nn .Namespace , & observerList , metav1.ListOptions {
896+ LabelSelector : fmt .Sprintf ("%s=%s" , oceanbaseconst .LabelRefOBCluster , nn .Name ),
897+ })
898+ if err != nil {
899+ logrus .WithError (err ).Error ("Failed to list observers" )
900+ return nil , errors .Wrap (err , "List observers" )
901+ }
902+ conn , err := utils .GetOBConnection (ctx , obcluster , "root" , "sys" , obcluster .Spec .UserSecrets .Root )
903+ if err != nil {
904+ logrus .Info ("Failed to get OceanBase database connection" )
905+ return nil , errors .Wrap (err , "Get OceanBase database connection" )
906+ }
907+ parameters , err := conn .ListParametersWithTenantID (ctx , 1 )
908+ if err != nil {
909+ logrus .WithError (err ).Error ("Failed to query parameters" )
910+ return nil , errors .Wrap (err , "Query parameters" )
911+ }
912+ return parameters , nil
913+ }
0 commit comments