diff --git a/.gitignore b/.gitignore index a804171..763bd2b 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,7 @@ dist/ *.bazelrc.user +.opencode +opencode/ +opencode.json mimir-key \ No newline at end of file diff --git a/src/cmd/agent.go b/src/cmd/agent.go index c6c10a5..ba4fa88 100644 --- a/src/cmd/agent.go +++ b/src/cmd/agent.go @@ -3,7 +3,6 @@ package cmd import ( "fmt" - "os" "github.com/cubbit/composer-cli/src/action" "github.com/cubbit/composer-cli/utils" @@ -16,39 +15,25 @@ var agentCmd = &cobra.Command{ } var createAgentSubCmd = &cobra.Command{ - Use: "create", - Short: "create a new agent", + Use: "create", + Short: "create a new agent or multiple agents from a batch file", + Example: "cubbit agent create --swarm-id --nexus-id --node-id --batch --file ./batch.json\ncubbit agent create --swarm-id --nexus-id --node-id --agent-port 8080 --agent-disk /dev/sdb --agent-mount-point /mnt/agent", PreRun: func(cmd *cobra.Command, args []string) { + cmd.MarkFlagRequired("swarm-id") cmd.MarkFlagRequired("nexus-id") cmd.MarkFlagRequired("node-id") - batch, _ := cmd.Flags().GetBool("batch") - if batch { - file, _ := cmd.Flags().GetString("file") - if file == "" { - fmt.Println("Error: --file flag is required when using --batch mode.") - cmd.Usage() - os.Exit(1) - } - - if _, err := os.Stat(file); os.IsNotExist(err) { - fmt.Println("Error: file does not exist:", file) - os.Exit(1) - } - return - } - - cmd.MarkFlagRequired("agent-port") - cmd.MarkFlagRequired("agent-disk") - cmd.MarkFlagRequired("agent-mount-point") + cmd.MarkFlagsOneRequired("batch", "agent-port") + cmd.MarkFlagsRequiredTogether("batch", "file") + cmd.MarkFlagsRequiredTogether("agent-port", "agent-disk", "agent-mount-point") - agentPort := cmd.Flags().Lookup("agent-port") - if agentPort != nil && !agentPort.Changed { - fmt.Println("Error: --agent-port must be explicitly provided.") - cmd.Usage() - os.Exit(1) - } + cmd.MarkFlagsMutuallyExclusive("batch", "agent-port") + cmd.MarkFlagsMutuallyExclusive("batch", "agent-disk") + cmd.MarkFlagsMutuallyExclusive("batch", "agent-mount-point") + cmd.MarkFlagsMutuallyExclusive("file", "agent-port") + cmd.MarkFlagsMutuallyExclusive("file", "agent-disk") + cmd.MarkFlagsMutuallyExclusive("file", "agent-mount-point") }, Run: func(cmd *cobra.Command, args []string) { batch, _ := cmd.Flags().GetBool("batch") @@ -69,6 +54,7 @@ var editAgentSubCmd = &cobra.Command{ Use: "edit", Short: "edit an agent", PreRun: func(cmd *cobra.Command, args []string) { + cmd.MarkFlagRequired("swarm-id") cmd.MarkFlagRequired("nexus-id") cmd.MarkFlagRequired("node-id") cmd.MarkFlagRequired("agent-id") @@ -84,6 +70,7 @@ var describeAgentSubCmd = &cobra.Command{ Use: "describe", Short: "describe an agent", PreRun: func(cmd *cobra.Command, args []string) { + cmd.MarkFlagRequired("swarm-id") cmd.MarkFlagRequired("nexus-id") cmd.MarkFlagRequired("node-id") cmd.MarkFlagRequired("agent-id") @@ -96,34 +83,37 @@ var describeAgentSubCmd = &cobra.Command{ } var listAgentsSubCmd = &cobra.Command{ - Use: "list", - Short: "list agents", + Use: "list", + Short: "list agents in a node or redundancy class", + Example: "cubbit agent list --swarm-id --nexus-id --node-id \ncubbit agent list --swarm-id --redundancy-class-id ", PreRun: func(cmd *cobra.Command, args []string) { + cmd.MarkFlagRequired("swarm-id") + cmd.MarkFlagsOneRequired("redundancy-class-id", "node-id") + + cmd.MarkFlagsRequiredTogether("nexus-id", "node-id") cmd.MarkFlagsMutuallyExclusive("nexus-id", "redundancy-class-id") cmd.MarkFlagsMutuallyExclusive("node-id", "redundancy-class-id") - + }, + RunE: func(cmd *cobra.Command, args []string) error { allowedSortingKeys := []string{"id", "node_id", "port", "created_at"} sort, _ := cmd.Flags().GetString("sort") - if sort != "" && !utils.Contains(allowedSortingKeys, sort) { - fmt.Println("Error: invalid sort key provided, allowed keys are: id, node_id", "port", "created_at") - cmd.Usage() - os.Exit(1) + msg := "Error: invalid sort key provided, allowed keys are: id, node_id, port, created_at" + return fmt.Errorf(msg) } filter, _ := cmd.Flags().GetString("filter") - if filter != "" { - if !utils.IsValidFilter(filter) { - fmt.Println("Error: invalid filter provided, allowed format is: key:value key:value ...") - cmd.Usage() - os.Exit(1) - } + if filter != "" && !utils.IsValidFilter(filter) { + msg := "Error: invalid filter provided, allowed format is: key:value key:value ..." + return fmt.Errorf(msg) } - }, - Run: func(cmd *cobra.Command, args []string) { + if err := action.ListAgents(cmd, args); err != nil { utils.PrintError(err) + return err } + + return nil }, } @@ -131,6 +121,7 @@ var removeAgentSubCmd = &cobra.Command{ Use: "remove", Short: "remove an agent", PreRun: func(cmd *cobra.Command, args []string) { + cmd.MarkFlagRequired("swarm-id") cmd.MarkFlagRequired("nexus-id") cmd.MarkFlagRequired("node-id") cmd.MarkFlagRequired("agent-id") @@ -146,6 +137,7 @@ var checkAgentStatusSubCmd = &cobra.Command{ Use: "status", Short: "check the status of an agent", PreRun: func(cmd *cobra.Command, args []string) { + cmd.MarkFlagRequired("swarm-id") cmd.MarkFlagRequired("nexus-id") cmd.MarkFlagRequired("node-id") cmd.MarkFlagRequired("agent-id") @@ -194,8 +186,6 @@ func init() { rootCmd.AddCommand(agentCmd) agentCmd.PersistentFlags().String("swarm-id", "", "ID of the swarm") - agentCmd.MarkPersistentFlagRequired("swarm-id") agentCmd.PersistentFlags().String("nexus-id", "", "ID of the nexus") agentCmd.PersistentFlags().String("node-id", "", "ID of the node") - } diff --git a/src/cmd/gateway.go b/src/cmd/gateway.go index 5ac3e98..43a3b42 100644 --- a/src/cmd/gateway.go +++ b/src/cmd/gateway.go @@ -3,7 +3,6 @@ package cmd import ( "fmt" - "os" "github.com/cubbit/composer-cli/src/action" "github.com/cubbit/composer-cli/utils" @@ -21,6 +20,7 @@ var createGatewaySubCmd = &cobra.Command{ PreRun: func(cmd *cobra.Command, args []string) { cmd.MarkFlagRequired("name") cmd.MarkFlagRequired("location") + cmd.MarkFlagRequired("tenant-id") }, Run: func(cmd *cobra.Command, args []string) { if err := action.CreateGateway(cmd, args); err != nil { @@ -34,6 +34,7 @@ var describeGatewaySubCmd = &cobra.Command{ Short: "describes tenant gateways", PreRun: func(cmd *cobra.Command, args []string) { cmd.MarkFlagRequired("gateway-id") + cmd.MarkFlagRequired("tenant-id") }, Run: func(cmd *cobra.Command, args []string) { if err := action.DescribeGateway(cmd, args); err != nil { @@ -47,6 +48,7 @@ var updateGatewaySubCmd = &cobra.Command{ Short: "updates a gateway in a tenant", PreRun: func(cmd *cobra.Command, args []string) { cmd.MarkFlagRequired("gateway-id") + cmd.MarkFlagRequired("tenant-id") }, Run: func(cmd *cobra.Command, args []string) { if err := action.UpdateGateway(cmd, args); err != nil { @@ -59,19 +61,22 @@ var listGatewaysSubCmd = &cobra.Command{ Use: "list", Short: "lists tenant gateways", PreRun: func(cmd *cobra.Command, args []string) { - allowedSortingKeys := []string{"id, name"} + cmd.MarkFlagRequired("tenant-id") + }, + RunE: func(cmd *cobra.Command, args []string) error { + allowedSortingKeys := []string{"id", "name"} sort, _ := cmd.Flags().GetString("sort") - if sort != "" && !utils.Contains(allowedSortingKeys, sort) { - fmt.Println("Error: invalid sort key provided, allowed keys are: id, name") - cmd.Usage() - os.Exit(1) + err := fmt.Errorf("invalid sort key provided, allowed keys are: id, name") + return err } - }, - Run: func(cmd *cobra.Command, args []string) { + if err := action.ListGateways(cmd, args); err != nil { utils.PrintError(err) + return err } + + return nil }, } @@ -80,6 +85,7 @@ var removeGatewaySubCmd = &cobra.Command{ Short: "removes a tenant gateway", PreRun: func(cmd *cobra.Command, args []string) { cmd.MarkFlagRequired("gateway-id") + cmd.MarkFlagRequired("tenant-id") }, Run: func(cmd *cobra.Command, args []string) { if err := action.RemoveGateway(cmd, args); err != nil { @@ -89,12 +95,18 @@ var removeGatewaySubCmd = &cobra.Command{ } var installGatewaySubCmd = &cobra.Command{ - Use: "install", - Short: "installs a gateway for a tenant", + Use: "install", + Short: "installs a gateway for a tenant", + Example: "cubbit gateway install --interactive\ncubbit gateway install --tenant-id --gateway-id ", PreRun: func(cmd *cobra.Command, args []string) { - cmd.MarkFlagRequired("gateway-id") + cmd.MarkFlagsOneRequired("interactive", "gateway-id") + + cmd.MarkFlagsRequiredTogether("tenant-id", "gateway-id") + cmd.MarkFlagsMutuallyExclusive("interactive", "gateway-id") + cmd.MarkFlagsMutuallyExclusive("interactive", "tenant-id") }, Run: func(cmd *cobra.Command, args []string) { + interactive, _ := cmd.Flags().GetBool("interactive") if !interactive { if err := action.InstallGateway(cmd, args); err != nil { utils.PrintError(err) @@ -142,8 +154,8 @@ func init() { installGatewaySubCmd.Flags().Bool("no-offloader", false, "Skip offloader setup") installGatewaySubCmd.Flags().Bool("no-s3", false, "Skip S3 setup") installGatewaySubCmd.Flags().Bool("ingress", false, "Install only ingress") + installGatewaySubCmd.Flags().BoolP("interactive", "i", false, "Run in interactive mode") rootCmd.AddCommand(gatewayCmd) gatewayCmd.PersistentFlags().String("tenant-id", "", "ID of the tenant") - gatewayCmd.MarkPersistentFlagRequired("tenant-id") } diff --git a/src/cmd/nexus.go b/src/cmd/nexus.go index 793f4de..fc5ad97 100644 --- a/src/cmd/nexus.go +++ b/src/cmd/nexus.go @@ -16,6 +16,7 @@ var createNexusSubCmd = &cobra.Command{ Use: "create", Short: "create a new nexus", PreRun: func(cmd *cobra.Command, args []string) { + cmd.MarkFlagRequired("swarm-id") cmd.MarkFlagRequired("name") cmd.MarkFlagRequired("location") cmd.MarkFlagRequired("provider-id") @@ -32,6 +33,7 @@ var editNexusSubCmd = &cobra.Command{ Short: "edit a nexus", PreRun: func(cmd *cobra.Command, args []string) { cmd.MarkFlagRequired("nexus-id") + cmd.MarkFlagRequired("swarm-id") }, Run: func(cmd *cobra.Command, args []string) { if err := action.EditNexus(cmd, args); err != nil { @@ -45,6 +47,7 @@ var removeNexusSubCmd = &cobra.Command{ Short: "remove a nexus", PreRun: func(cmd *cobra.Command, args []string) { cmd.MarkFlagRequired("nexus-id") + cmd.MarkFlagRequired("swarm-id") }, Run: func(cmd *cobra.Command, args []string) { if err := action.RemoveNexus(cmd, args); err != nil { @@ -57,6 +60,7 @@ var listNexusesSubCmd = &cobra.Command{ Use: "list", Short: "list nexuses", PreRun: func(cmd *cobra.Command, args []string) { + cmd.MarkFlagRequired("swarm-id") }, Run: func(cmd *cobra.Command, args []string) { if err := action.ListNexuses(cmd, args); err != nil { @@ -70,6 +74,7 @@ var describeNexusSubCmd = &cobra.Command{ Short: "describe a nexus", PreRun: func(cmd *cobra.Command, args []string) { cmd.MarkFlagRequired("nexus-id") + cmd.MarkFlagRequired("swarm-id") }, Run: func(cmd *cobra.Command, args []string) { if err := action.DescribeNexus(cmd, args); err != nil { @@ -121,5 +126,4 @@ func init() { rootCmd.AddCommand(nexusCmd) nexusCmd.PersistentFlags().String("swarm-id", "", "ID of the swarm") - nexusCmd.MarkPersistentFlagRequired("swarm-id") } diff --git a/src/cmd/node.go b/src/cmd/node.go index 9db454b..8af0220 100644 --- a/src/cmd/node.go +++ b/src/cmd/node.go @@ -3,7 +3,6 @@ package cmd import ( "fmt" - "os" "github.com/cubbit/composer-cli/src/action" "github.com/cubbit/composer-cli/utils" @@ -16,64 +15,61 @@ var nodeCmd = &cobra.Command{ } var createNodeSubCmd = &cobra.Command{ - Use: "create", - Short: "create a new node", + Use: "create", + Short: "create a new node or a batch of nodes", + Example: "cubbit node create --swarm-id --nexus-id --batch --file ./batch.json\n cubbit node create --swarm-id --nexus-id --name --private-ip --public-ip --label