Skip to content

Commit 68c5162

Browse files
committed
feat(dashboard): supplement some features that ob-operator supports
1 parent ba32a91 commit 68c5162

File tree

13 files changed

+410
-26
lines changed

13 files changed

+410
-26
lines changed

internal/cli/utils/parser.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ func MapZonesToTopology(zones map[string]string) ([]param.ZoneTopology, error) {
4343
Zone: zoneName,
4444
Replicas: replica,
4545
NodeSelector: make([]common.KVPair, 0),
46-
Tolerations: make([]common.KVPair, 0),
4746
Affinities: make([]common.AffinitySpec, 0),
4847
})
4948
}

internal/dashboard/business/oceanbase/obcluster.go

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
}

internal/dashboard/business/oceanbase/obcluster_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@ func getMockedCreateClusterParam() *param.CreateOBClusterParam {
4141
Key: "test-node-selector",
4242
Value: "test-node-selector-value",
4343
}},
44-
Tolerations: []common.KVPair{{
45-
Key: "test-toleration",
46-
Value: "test-toleration-value",
44+
Tolerations: []common.TolerationSpec{{
45+
KVPair: common.KVPair{
46+
Key: "test-toleration",
47+
Value: "test-toleration-value",
48+
},
4749
}},
4850
Affinities: []common.AffinitySpec{{
4951
SelectorExpression: common.SelectorExpression{

internal/dashboard/business/oceanbase/obtenant.go

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/oceanbase/ob-operator/api/v1alpha1"
3232
"github.com/oceanbase/ob-operator/internal/clients"
3333
"github.com/oceanbase/ob-operator/internal/clients/schema"
34+
oceanbaseconst "github.com/oceanbase/ob-operator/internal/const/oceanbase"
3435
"github.com/oceanbase/ob-operator/internal/const/status/tenantstatus"
3536
"github.com/oceanbase/ob-operator/internal/dashboard/model/param"
3637
"github.com/oceanbase/ob-operator/internal/dashboard/model/response"
@@ -41,8 +42,10 @@ import (
4142
func buildOBTenantApiType(nn types.NamespacedName, p *param.CreateOBTenantParam) (*v1alpha1.OBTenant, error) {
4243
t := &v1alpha1.OBTenant{
4344
ObjectMeta: v1.ObjectMeta{
44-
Name: nn.Name,
45-
Namespace: nn.Namespace,
45+
Name: nn.Name,
46+
Namespace: nn.Namespace,
47+
Annotations: make(map[string]string),
48+
Labels: make(map[string]string),
4649
},
4750
TypeMeta: v1.TypeMeta{
4851
Kind: schema.OBTenantKind,
@@ -58,6 +61,8 @@ func buildOBTenantApiType(nn types.NamespacedName, p *param.CreateOBTenantParam)
5861

5962
// guard non-nil
6063
Pools: []v1alpha1.ResourcePoolSpec{},
64+
65+
Scenario: p.Scenario,
6166
},
6267
}
6368

@@ -141,6 +146,27 @@ func buildOBTenantApiType(nn types.NamespacedName, p *param.CreateOBTenantParam)
141146
}
142147
}
143148
}
149+
if len(p.Variables) > 0 {
150+
t.Spec.Variables = make([]apitypes.Variable, 0, len(p.Variables))
151+
for i := range p.Variables {
152+
t.Spec.Variables = append(t.Spec.Variables, apitypes.Variable{
153+
Name: p.Variables[i].Key,
154+
Value: p.Variables[i].Value,
155+
})
156+
}
157+
}
158+
if len(p.Parameters) > 0 {
159+
t.Spec.Parameters = make([]apitypes.Parameter, 0, len(p.Parameters))
160+
for i := range p.Parameters {
161+
t.Spec.Parameters = append(t.Spec.Parameters, apitypes.Parameter{
162+
Name: p.Parameters[i].Key,
163+
Value: p.Parameters[i].Value,
164+
})
165+
}
166+
}
167+
if p.DeletionProtection {
168+
t.Annotations[oceanbaseconst.AnnotationsIgnoreDeletion] = "true"
169+
}
144170
return t, nil
145171
}
146172

@@ -351,7 +377,7 @@ func CreateOBTenant(ctx context.Context, nn types.NamespacedName, p *param.Creat
351377
}
352378

353379
if p.Source.Restore.OSSAccessID != "" && p.Source.Restore.OSSAccessKey != "" {
354-
ossSecretName := p.Name + "-oss-access-" + rand.String(6)
380+
ossSecretName := nn.Name + "-backup-" + strings.ToLower(strings.ReplaceAll(string(p.Source.Restore.Type), "_", "-")) + "-secret-" + rand.String(6)
355381
t.Spec.Source.Restore.ArchiveSource.OSSAccessSecret = ossSecretName
356382
t.Spec.Source.Restore.BakDataSource.OSSAccessSecret = ossSecretName
357383
_, err = k8sclient.ClientSet.CoreV1().Secrets(nn.Namespace).Create(ctx, &corev1.Secret{
@@ -362,6 +388,8 @@ func CreateOBTenant(ctx context.Context, nn types.NamespacedName, p *param.Creat
362388
StringData: map[string]string{
363389
"accessId": p.Source.Restore.OSSAccessID,
364390
"accessKey": p.Source.Restore.OSSAccessKey,
391+
"appId": p.Source.Restore.AppID,
392+
"s3Region": p.Source.Restore.Region,
365393
},
366394
}, v1.CreateOptions{})
367395
if err != nil {
@@ -548,6 +576,7 @@ func PatchTenant(ctx context.Context, nn types.NamespacedName, p *param.PatchTen
548576
if err != nil {
549577
return nil, err
550578
}
579+
alreadyIgnoreDeletion := tenant.Annotations[oceanbaseconst.AnnotationsIgnoreDeletion] == "true"
551580
if p.UnitNumber != nil {
552581
tenant.Spec.UnitNumber = *p.UnitNumber
553582
}
@@ -595,6 +624,31 @@ func PatchTenant(ctx context.Context, nn types.NamespacedName, p *param.PatchTen
595624
}
596625
}
597626
}
627+
if alreadyIgnoreDeletion && p.RemoveDeletionProtection {
628+
delete(tenant.Annotations, oceanbaseconst.AnnotationsIgnoreDeletion)
629+
} else if !alreadyIgnoreDeletion && p.AddDeletionProtection {
630+
tenant.Annotations[oceanbaseconst.AnnotationsIgnoreDeletion] = "true"
631+
}
632+
if len(p.Variables) > 0 {
633+
newVars := make([]apitypes.Variable, 0, len(p.Variables))
634+
for i := range p.Variables {
635+
newVars = append(newVars, apitypes.Variable{
636+
Name: p.Variables[i].Key,
637+
Value: p.Variables[i].Value,
638+
})
639+
}
640+
tenant.Spec.Variables = newVars
641+
}
642+
if len(p.Parameters) > 0 {
643+
newParameters := make([]apitypes.Parameter, 0, len(p.Parameters))
644+
for i := range p.Parameters {
645+
newParameters = append(newParameters, apitypes.Parameter{
646+
Name: p.Parameters[i].Key,
647+
Value: p.Parameters[i].Value,
648+
})
649+
}
650+
tenant.Spec.Parameters = newParameters
651+
}
598652
tenant, err = clients.UpdateOBTenant(ctx, tenant)
599653
if err != nil {
600654
return nil, err

internal/dashboard/business/oceanbase/obtenantbackup.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,8 @@ func CreateTenantBackupPolicy(ctx context.Context, nn types.NamespacedName, p *p
354354
return nil, err
355355
}
356356

357-
if p.DestType == "OSS" && p.OSSAccessID != "" && p.OSSAccessKey != "" {
358-
ossSecretName := nn.Name + "-backup-oss-secret-" + rand.String(6)
357+
if p.DestType != param.BackupDestNFS && p.OSSAccessID != "" && p.OSSAccessKey != "" {
358+
ossSecretName := nn.Name + "-backup-" + strings.ToLower(strings.ReplaceAll(string(p.DestType), "_", "-")) + "-secret-" + rand.String(6)
359359
backupPolicy.Spec.LogArchive.Destination.OSSAccessSecret = ossSecretName
360360
backupPolicy.Spec.DataBackup.Destination.OSSAccessSecret = ossSecretName
361361
secret := &corev1.Secret{
@@ -366,6 +366,8 @@ func CreateTenantBackupPolicy(ctx context.Context, nn types.NamespacedName, p *p
366366
StringData: map[string]string{
367367
"accessId": p.OSSAccessID,
368368
"accessKey": p.OSSAccessKey,
369+
"s3Region": p.Region,
370+
"appId": p.AppID,
369371
},
370372
}
371373
_, err := client.GetClient().ClientSet.CoreV1().Secrets(nn.Namespace).Create(ctx, secret, metav1.CreateOptions{})

0 commit comments

Comments
 (0)