Skip to content

Commit

Permalink
refactor: merge subcommand into one demo command
Browse files Browse the repository at this point in the history
  • Loading branch information
lizzy-0323 committed Oct 29, 2024
1 parent 9d2605b commit 0d4e5da
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 174 deletions.
6 changes: 3 additions & 3 deletions internal/cli/cluster/enter.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ const (
DEFAULT_MONITOR_CPU = 1
DEFAULT_MONITOR_MEMORY = 1
DEFAULT_NAME = "test"
DEFAULT_NAME = "test"

// Default values for Parameter flag
DEFAULT_MIN_FULL_RESOURCE_POOL_MEMORY = "2147483648"
Expand All @@ -86,6 +85,7 @@ const (

// Default cluster type for easier cluster creation
const (
SINGLE_NODE = "single-node"
THREE_NODE = "three-node"
CLUSTER_TYPE = "cluster-type"
SINGLE_NODE = "single-node"
THREE_NODE = "three-node"
)
2 changes: 1 addition & 1 deletion internal/cli/cmd/backup/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func NewShowCmd() *cobra.Command {
if err != nil {
logger.Fatalln(err, "failed to get backup policy")
}
if backupPolicy == nil {
if backupPolicy == nil || backupPolicy.Name == "" {
logger.Fatalln("no backup policy found")
}
backupJobList, err := backup.ListBackupJobs(cmd.Context(), backupPolicy.Name, o)
Expand Down
56 changes: 53 additions & 3 deletions internal/cli/cmd/demo/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,66 @@ See the Mulan PSL v2 for more details.
*/
package demo

import "github.com/spf13/cobra"
import (
"github.com/spf13/cobra"

"github.com/oceanbase/ob-operator/internal/cli/cluster"
cmdUtil "github.com/oceanbase/ob-operator/internal/cli/cmd/util"
"github.com/oceanbase/ob-operator/internal/clients"
)

// NewCmd create demo command for cluster creation
func NewCmd() *cobra.Command {
o := cluster.NewCreateOptions()
logger := cmdUtil.GetDefaultLoggerInstance()
pf := NewPromptFactory()
cmd := &cobra.Command{
Use: "demo <subcommand>",
Short: "deploy demo ob cluster in easier way",
Long: `deploy demo ob cluster in easier way, currently support single node and three node cluster`,
Run: func(cmd *cobra.Command, args []string) {
var err error
var clusterType string
prompt := pf.CreatePrompt(cluster.FLAG_NAME)
if o.Name, err = pf.RunPromptE(prompt); err != nil {
logger.Fatalln(err)
}
prompt = pf.CreatePrompt(cluster.FLAG_NAMESPACE)
if o.Namespace, err = pf.RunPromptE(prompt); err != nil {
logger.Fatalln(err)
}
prompt = pf.CreatePrompt(cluster.CLUSTER_TYPE)
if clusterType, err = pf.RunPromptE(prompt); err != nil {
logger.Fatalln(err)
}
prompt = pf.CreatePrompt(cluster.FLAG_ROOT_PASSWORD)
if o.RootPassword, err = pf.RunPromptE(prompt); err != nil {
logger.Fatalln(err)
}
prompt = pf.CreatePrompt(cluster.FLAG_BACKUP_ADDRESS)
if o.BackupVolume.Address, err = pf.RunPromptE(prompt); err != nil {
logger.Fatalln(err)
}
prompt = pf.CreatePrompt(cluster.FLAG_BACKUP_PATH)
if o.BackupVolume.Path, err = pf.RunPromptE(prompt); err != nil {
logger.Fatalln(err)
}
if err := o.Complete(); err != nil {
logger.Fatalln(err)
}
if err := o.SetDefaultConfig(clusterType); err != nil {
logger.Fatalln(err)
}
obcluster := cluster.CreateOBClusterInstance(o)
if err := clients.CreateSecretsForOBCluster(cmd.Context(), obcluster, o.RootPassword); err != nil {
logger.Fatalf("failed to create secrets for ob cluster: %v", err)
}
if _, err := clients.CreateOBCluster(cmd.Context(), obcluster); err != nil {
logger.Fatalln(err)
}
logger.Printf("Create OBCluster instance: %s", o.ClusterName)
logger.Printf("Run `echo $(kubectl get secret %s -o jsonpath='{.data.password}'|base64 --decode)` to get the secrets", obcluster.Spec.UserSecrets.Root)
},
}
cmd.AddCommand(NewSingleNodeCmd())
cmd.AddCommand(NewThreeNodeCmd())
return cmd
}
125 changes: 67 additions & 58 deletions internal/cli/cmd/demo/prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,97 +18,97 @@ import (
"fmt"

"github.com/manifoldco/promptui"

"github.com/oceanbase/ob-operator/internal/cli/cluster"
"github.com/oceanbase/ob-operator/internal/cli/utils"
)

var tepl *promptui.PromptTemplates = &promptui.PromptTemplates{
Prompt: "{{ . }} ",
Valid: "{{ . | green }} ",
Invalid: "{{ . | red }} ",
Success: "{{ . | bold }} ",
}
var (
promptTepl = &promptui.PromptTemplates{
Prompt: "{{ . }} ",
Valid: "{{ . | green }} ",
Invalid: "{{ . | red }} ",
Success: "{{ . | bold }} ",
}
selectTepl = &promptui.SelectTemplates{
Label: "{{ . }} ",
Active: "\U0001F336 {{ . | cyan }}",
Inactive: " {{ . | cyan }}",
Selected: "\U0001F336 {{ . | green | cyan }}",
}
)

type PromptFactory struct {
template *promptui.PromptTemplates
promptTepl *promptui.PromptTemplates
selectTepl *promptui.SelectTemplates
}

// NewPromptFactory creates a new prompt factory
func NewPromptFactory() *PromptFactory {
return &PromptFactory{
template: tepl,
promptTepl: promptTepl,
selectTepl: selectTepl,
}
}

func RunPromptsForCluster(pf *PromptFactory, o *cluster.CreateOptions) (err error) {
prompt := pf.CreatePrompt(cluster.FLAG_NAME)
if o.Name, err = pf.RunPromptE(prompt); err != nil {
return err
}
prompt = pf.CreatePrompt(cluster.FLAG_NAMESPACE)
if o.Namespace, err = pf.RunPromptE(prompt); err != nil {
return err
}
prompt = pf.CreatePrompt(cluster.FLAG_ROOT_PASSWORD)
if o.RootPassword, err = pf.RunPromptE(prompt); err != nil {
return err
}
prompt = pf.CreatePrompt(cluster.FLAG_BACKUP_ADDRESS)
if o.BackupVolume.Address, err = pf.RunPromptE(prompt); err != nil {
return err
}
prompt = pf.CreatePrompt(cluster.FLAG_BACKUP_PATH)
if o.BackupVolume.Path, err = pf.RunPromptE(prompt); err != nil {
return err
}
if err := o.Complete(); err != nil {
return err
}
if err := o.SetDefaultConfig(cluster.SINGLE_NODE); err != nil {
return err
}
return nil
}

func (pf *PromptFactory) RunPromptE(p *promptui.Prompt) (result string, err error) {
if result, err = p.Run(); err != nil {
if err == promptui.ErrInterrupt {
return "", errors.New("interrupted by user")
// RunPromptE runs the prompt and returns the result or error
func (pf *PromptFactory) RunPromptE(p any) (result string, err error) {
switch v := p.(type) {
case *promptui.Prompt:
if result, err = v.Run(); err != nil {
if err == promptui.ErrInterrupt {
return "", errors.New("interrupted by user")
}
return "", fmt.Errorf("failed to create cluster: %v", err)
}
return result, nil
case *promptui.Select:
if _, result, err = v.Run(); err != nil {
if err == promptui.ErrInterrupt {
return "", errors.New("interrupted by user")
}
return "", fmt.Errorf("failed to create cluster: %v", err)
}
return "", fmt.Errorf("failed to create cluster: %v", err)
return result, nil
default:
return "", errors.New("invalid prompt type")
}
return result, nil
}

func (pf *PromptFactory) CreatePrompt(promptType string) *promptui.Prompt {
// CreatePrompt creates a prompt by prompt factory, based on the prompt type
func (pf *PromptFactory) CreatePrompt(promptType string) any {
switch promptType {
case cluster.FLAG_NAME:
return &promptui.Prompt{
Label: "Please input the cluster name (Default `test`): ",
Templates: pf.template,
Label: "Please input the cluster name, press `enter` to use the default name `test`: ",
Templates: pf.promptTepl,
Validate: func(input string) error {
if !utils.CheckResourceName(input) {
return errors.New("invalid cluster name")
}
return nil
},
Default: cluster.DEFAULT_NAME,
AllowEdit: true,
Default: cluster.DEFAULT_NAME,
}
case cluster.FLAG_NAMESPACE:
return &promptui.Prompt{
Label: "Please input the namespace (Default `default`): ",
Templates: pf.template,
Label: "Please input the namespace, press `enter` to use default namespace: ",
Templates: pf.promptTepl,
Validate: func(input string) error {
if input == "" {
return errors.New("namespace can not be empty")
}
return nil
},
Default: cluster.DEFAULT_NAMESPACE,
AllowEdit: true,
Default: cluster.DEFAULT_NAMESPACE,
}
case cluster.FLAG_ROOT_PASSWORD:
return &promptui.Prompt{
Label: "Please input the root password (if not used, generate random password): ",
Templates: pf.template,
Label: "Please input the root password, press `enter` to generate a random password: ",
Templates: pf.promptTepl,
Mask: '*', // mask the input
Validate: func(input string) error {
if input == "" {
return nil
Expand All @@ -118,19 +118,28 @@ func (pf *PromptFactory) CreatePrompt(promptType string) *promptui.Prompt {
}
return nil
},
Default: utils.GenerateRandomPassword(8, 32),
AllowEdit: true,
}
case cluster.FLAG_BACKUP_ADDRESS:
return &promptui.Prompt{
Label: "Please input the backup address (if not set, it will be empty): ",
Templates: pf.template,
Label: "Please input the backup address, if press `enter`, cluster will not support backup: ",
Templates: pf.promptTepl,
Default: "",
AllowEdit: true,
}
case cluster.FLAG_BACKUP_PATH:
return &promptui.Prompt{
Label: "Please input the backup path (if not set, it will be empty): ",
Templates: pf.template,
Label: "Please input the backup path, if press `enter`, cluster will not support backup: ",
Templates: pf.promptTepl,
Default: "",
AllowEdit: true,
}
case cluster.CLUSTER_TYPE:
return &promptui.Select{
Label: "Please select the cluster type: ",
Items: []string{cluster.SINGLE_NODE, cluster.THREE_NODE},
Templates: pf.selectTepl,
HideSelected: true,
}
default:
return nil
Expand Down
54 changes: 0 additions & 54 deletions internal/cli/cmd/demo/single-node.go

This file was deleted.

54 changes: 0 additions & 54 deletions internal/cli/cmd/demo/three-node.go

This file was deleted.

Loading

0 comments on commit 0d4e5da

Please sign in to comment.