Skip to content

Commit 9e9573e

Browse files
committed
feat: create corresponding tenant in demo cmd
1 parent 543cfad commit 9e9573e

File tree

3 files changed

+113
-16
lines changed

3 files changed

+113
-16
lines changed

internal/cli/cmd/demo/demo.go

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,21 @@ See the Mulan PSL v2 for more details.
1414
package demo
1515

1616
import (
17+
"context"
18+
"log"
19+
"time"
20+
1721
"github.com/spf13/cobra"
22+
"k8s.io/apimachinery/pkg/types"
1823

24+
"github.com/oceanbase/ob-operator/api/v1alpha1"
1925
"github.com/oceanbase/ob-operator/internal/cli/cluster"
2026
"github.com/oceanbase/ob-operator/internal/cli/demo"
2127
"github.com/oceanbase/ob-operator/internal/cli/tenant"
2228
"github.com/oceanbase/ob-operator/internal/cli/utils"
2329
"github.com/oceanbase/ob-operator/internal/clients"
30+
clusterstatus "github.com/oceanbase/ob-operator/internal/const/status/obcluster"
31+
"github.com/oceanbase/ob-operator/internal/const/status/tenantstatus"
2432
)
2533

2634
// NewCmd create demo command for cluster creation
@@ -29,14 +37,16 @@ func NewCmd() *cobra.Command {
2937
tenantOptions := tenant.NewCreateOptions()
3038
logger := utils.GetDefaultLoggerInstance()
3139
pf := demo.NewPromptFactory()
32-
wait := false
40+
var clusterType string
41+
var wait bool
42+
var err error
3343
cmd := &cobra.Command{
3444
Use: "demo <subcommand>",
3545
Short: "deploy demo ob cluster and tenant in easier way",
3646
Long: `deploy demo ob cluster and tenant in easier way, currently support single node and three node cluster, with corresponding tenant`,
37-
Run: func(cmd *cobra.Command, args []string) {
38-
var err error
39-
var clusterType string
47+
Args: cobra.NoArgs,
48+
PreRun: func(cmd *cobra.Command, args []string) {
49+
// prompt for cluster create options
4050
prompt := pf.CreatePrompt(cluster.FLAG_NAME)
4151
if clusterOptions.Name, err = pf.RunPromptE(prompt); err != nil {
4252
logger.Fatalln(err)
@@ -53,6 +63,16 @@ func NewCmd() *cobra.Command {
5363
if clusterOptions.RootPassword, err = pf.RunPromptE(prompt); err != nil {
5464
logger.Fatalln(err)
5565
}
66+
prompt = pf.CreatePrompt(tenant.FLAG_TENANT_NAME_IN_K8S)
67+
if tenantOptions.Name, err = pf.RunPromptE(prompt); err != nil {
68+
logger.Fatalln(err)
69+
}
70+
prompt = pf.CreatePrompt(tenant.FLAG_TENANT_NAME)
71+
if tenantOptions.TenantName, err = pf.RunPromptE(prompt); err != nil {
72+
logger.Fatalln(err)
73+
}
74+
},
75+
Run: func(cmd *cobra.Command, args []string) {
5676
if err := clusterOptions.Complete(); err != nil {
5777
logger.Fatalln(err)
5878
}
@@ -65,23 +85,68 @@ func NewCmd() *cobra.Command {
6585
if err := demo.SetDefaultTenantConf(clusterType, clusterOptions.Namespace, clusterOptions.Name, tenantOptions); err != nil {
6686
logger.Fatalln(err)
6787
}
68-
obcluster := cluster.CreateOBClusterInstance(clusterOptions)
69-
if err := clients.CreateSecretsForOBCluster(cmd.Context(), obcluster, clusterOptions.RootPassword); err != nil {
70-
logger.Fatalf("failed to create secrets for ob cluster: %v", err)
71-
}
72-
if _, err := clients.CreateOBCluster(cmd.Context(), obcluster); err != nil {
88+
obcluster, err := cluster.CreateOBCluster(cmd.Context(), clusterOptions)
89+
if err != nil {
7390
logger.Fatalln(err)
7491
}
75-
logger.Printf("Create OBCluster instance: %s", clusterOptions.ClusterName)
76-
logger.Printf("Run `echo $(kubectl get secret %s -clusterOptions jsonpath='{.data.password}'|base64 --decode)` to get the secrets", obcluster.Spec.UserSecrets.Root)
92+
logger.Printf("Creating OBCluster instance: %s", clusterOptions.ClusterName)
93+
waitForClusterReady(cmd.Context(), obcluster, logger, 2*time.Second)
94+
logger.Printf("Run `echo $(kubectl get secret %s -clusterOptions jsonpath='{.data.password}'|base64 --decode)` to get clsuter secrets", obcluster.Spec.UserSecrets.Root)
95+
},
96+
PostRun: func(cmd *cobra.Command, args []string) {
97+
// create tenant after cluster ready
7798
obtenant, err := tenant.CreateOBTenant(cmd.Context(), tenantOptions)
7899
if err != nil {
79100
logger.Fatalln(err)
80101
}
81-
logger.Printf("Create OBTenant instance: %s", tenantOptions.TenantName)
82-
logger.Printf("Run `echo $(kubectl get secret %s -o jsonpath='{.data.password}'|base64 --decode)` to get the secrets", obtenant.Spec.Credentials.Root)
102+
logger.Printf("Creating OBTenant instance: %s", tenantOptions.TenantName)
103+
waitForTenantReady(cmd.Context(), obtenant, logger, 1*time.Second)
104+
logger.Printf("Run `echo $(kubectl get secret %s -o jsonpath='{.data.password}'|base64 --decode)` to get tenant secrets", obtenant.Spec.Credentials.Root)
83105
},
84106
}
107+
// TODO: if w is set, wait for the cluster and tenant ready
85108
cmd.Flags().BoolVarP(&wait, cluster.FLAG_WAIT, "w", cluster.DEFAULT_WAIT, "wait for the cluster and tenant ready")
86109
return cmd
87110
}
111+
112+
// waitForTenantReady wait for tenant ready, log the task status
113+
func waitForClusterReady(ctx context.Context, obcluster *v1alpha1.OBCluster, logger *log.Logger, waitTime time.Duration) {
114+
var err error
115+
lastTask := ""
116+
lastTaskStatus := ""
117+
logger.Println("Waiting for cluster ready...")
118+
for obcluster.Status.Status != clusterstatus.Running {
119+
time.Sleep(waitTime)
120+
obcluster, err = clients.GetOBCluster(ctx, obcluster.Namespace, obcluster.Name)
121+
if err != nil {
122+
logger.Fatalln(err)
123+
}
124+
if obcluster.Status.OperationContext != nil && (lastTask != string(obcluster.Status.OperationContext.Task) || lastTaskStatus != string(obcluster.Status.OperationContext.TaskStatus)) {
125+
logger.Printf("Task: %s, Status: %s", obcluster.Status.OperationContext.Task, obcluster.Status.OperationContext.TaskStatus)
126+
lastTask = string(obcluster.Status.OperationContext.Task)
127+
lastTaskStatus = string(obcluster.Status.OperationContext.TaskStatus)
128+
}
129+
}
130+
logger.Println("Cluster create successfully")
131+
}
132+
133+
// waitForTenantReady wait for tenant ready, log the task status
134+
func waitForTenantReady(ctx context.Context, obtenant *v1alpha1.OBTenant, logger *log.Logger, waitTime time.Duration) {
135+
var err error
136+
lastTask := ""
137+
lastTaskStatus := ""
138+
logger.Println("Waiting for tenant ready...")
139+
for obtenant.Status.Status != tenantstatus.Running {
140+
time.Sleep(waitTime)
141+
obtenant, err = clients.GetOBTenant(ctx, types.NamespacedName{Namespace: obtenant.Namespace, Name: obtenant.Name})
142+
if err != nil {
143+
logger.Fatalln(err)
144+
}
145+
if obtenant.Status.OperationContext != nil && (lastTask != string(obtenant.Status.OperationContext.Task) || lastTaskStatus != string(obtenant.Status.OperationContext.TaskStatus)) {
146+
logger.Printf("Task: %s, Status: %s", obtenant.Status.OperationContext.Task, obtenant.Status.OperationContext.TaskStatus)
147+
lastTask = string(obtenant.Status.OperationContext.Task)
148+
lastTaskStatus = string(obtenant.Status.OperationContext.TaskStatus)
149+
}
150+
}
151+
logger.Println("Tenant create successfully")
152+
}

internal/cli/demo/prompt.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/manifoldco/promptui"
2121

2222
"github.com/oceanbase/ob-operator/internal/cli/cluster"
23+
"github.com/oceanbase/ob-operator/internal/cli/tenant"
2324
"github.com/oceanbase/ob-operator/internal/cli/utils"
2425
)
2526

@@ -84,7 +85,7 @@ func (pf *PromptFactory) CreatePrompt(promptType string) any {
8485
Templates: pf.promptTepl,
8586
Validate: func(input string) error {
8687
if !utils.CheckResourceName(input) {
87-
return errors.New("invalid cluster name")
88+
return errors.New("invalid resource name in k8s")
8889
}
8990
return nil
9091
},
@@ -127,6 +128,32 @@ func (pf *PromptFactory) CreatePrompt(promptType string) any {
127128
Templates: pf.selectTepl,
128129
HideSelected: true,
129130
}
131+
case tenant.FLAG_TENANT_NAME_IN_K8S:
132+
return &promptui.Prompt{
133+
Label: "Please input the tenant resource name, press `enter` to use the default name `demo-tenant`: ",
134+
Templates: pf.promptTepl,
135+
Validate: func(input string) error {
136+
if !utils.CheckResourceName(input) {
137+
return errors.New("invalid resource name in k8s")
138+
}
139+
return nil
140+
},
141+
AllowEdit: true,
142+
Default: tenant.DEFAULT_TENANT_NAME_IN_K8S,
143+
}
144+
case tenant.FLAG_TENANT_NAME:
145+
return &promptui.Prompt{
146+
Label: "Please input the tenant name, press `enter` to use the default name `demo_tenant`: ",
147+
Templates: pf.promptTepl,
148+
Validate: func(input string) error {
149+
if !utils.CheckTenantName(input) {
150+
return errors.New("invalid tenant name")
151+
}
152+
return nil
153+
},
154+
AllowEdit: true,
155+
Default: tenant.DEFAULT_TENANT_NAME,
156+
}
130157
default:
131158
return nil
132159
}

internal/cli/tenant/enter.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ const (
7878
DEFAULT_RESTORE_FLAG = false
7979

8080
// Default Tenant name for demo cmd
81-
DEFAULT_NAME = "demo-tenant"
82-
DEFAULT_TENANT_NAME = "demo_tenant"
81+
DEFAULT_TENANT_NAME_IN_K8S = "demo-tenant"
82+
DEFAULT_TENANT_NAME = "demo_tenant"
83+
)
84+
85+
// using in `demo` command, tenant resource name in k8s
86+
const (
87+
FLAG_TENANT_NAME_IN_K8S = "tenant-name-in-k8s"
8388
)

0 commit comments

Comments
 (0)