diff --git a/cmd/command_test.go b/cmd/command_test.go index eac9c55..39dad85 100644 --- a/cmd/command_test.go +++ b/cmd/command_test.go @@ -33,9 +33,9 @@ func TestInstanceCommand(t *testing.T) { assert.Contains(t, commandNames, "create") assert.Contains(t, commandNames, "list") assert.Contains(t, commandNames, "get --id ") - assert.Contains(t, commandNames, "update ") - assert.Contains(t, commandNames, "delete ") - assert.Contains(t, commandNames, "resize ") + assert.Contains(t, commandNames, "update --id ") + assert.Contains(t, commandNames, "delete --id ") + assert.Contains(t, commandNames, "resize --id ") } func TestVPCCommand(t *testing.T) { @@ -54,8 +54,8 @@ func TestVPCCommand(t *testing.T) { assert.Contains(t, commandNames, "create") assert.Contains(t, commandNames, "list") assert.Contains(t, commandNames, "get --id ") - assert.Contains(t, commandNames, "update ") - assert.Contains(t, commandNames, "delete ") + assert.Contains(t, commandNames, "update --id ") + assert.Contains(t, commandNames, "delete --id ") } func TestInstanceCreateCommand_Validation(t *testing.T) { diff --git a/cmd/instance_delete.go b/cmd/instance_delete.go index c61b1c2..fd67bbd 100644 --- a/cmd/instance_delete.go +++ b/cmd/instance_delete.go @@ -11,18 +11,20 @@ import ( "github.com/spf13/cobra" ) -var forceDelete bool +var ( + deleteInstanceID string + forceDelete bool +) var instanceDeleteCmd = &cobra.Command{ - Use: "delete ", + Use: "delete --id ", Short: "Delete a CloudAMQP instance", Long: `Delete a CloudAMQP instance permanently. WARNING: This action cannot be undone. All data will be lost.`, - Example: ` cloudamqp instance delete 1234 - cloudamqp instance delete 1234 --force`, - Args: cobra.ExactArgs(1), - ValidArgsFunction: completeInstances, + Example: ` cloudamqp instance delete --id 1234 + cloudamqp instance delete --id 1234 --force`, + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { var err error apiKey, err = getAPIKey() @@ -30,7 +32,11 @@ WARNING: This action cannot be undone. All data will be lost.`, return fmt.Errorf("failed to get API key: %w", err) } - instanceID, err := strconv.Atoi(args[0]) + if deleteInstanceID == "" { + return fmt.Errorf("--id is required") + } + + instanceID, err := strconv.Atoi(deleteInstanceID) if err != nil { return fmt.Errorf("invalid instance ID: %v", err) } @@ -64,5 +70,8 @@ WARNING: This action cannot be undone. All data will be lost.`, } func init() { + instanceDeleteCmd.Flags().StringVar(&deleteInstanceID, "id", "", "Instance ID (required)") instanceDeleteCmd.Flags().BoolVar(&forceDelete, "force", false, "Skip confirmation prompt") + instanceDeleteCmd.MarkFlagRequired("id") + instanceDeleteCmd.RegisterFlagCompletionFunc("id", completeInstances) } diff --git a/cmd/instance_resize.go b/cmd/instance_resize.go index e2a63e1..abbc385 100644 --- a/cmd/instance_resize.go +++ b/cmd/instance_resize.go @@ -9,12 +9,13 @@ import ( ) var ( - diskSize int - allowDowntime bool + resizeInstanceID string + diskSize int + allowDowntime bool ) var instanceResizeCmd = &cobra.Command{ - Use: "resize ", + Use: "resize --id ", Short: "Resize instance disk", Long: `Resize the disk size of an instance. Default behavior is to expand the disk without any downtime. Currently limited to instances in Amazon Web Services (AWS) and Google Compute Engine (GCE). @@ -24,10 +25,9 @@ Note: This action is asynchronous. The request will return almost immediately. T Note: Due to restrictions from cloud providers, it's only possible to resize the disk every 8 hours unless --allow-downtime is set. Available disk sizes: 0, 25, 50, 100, 250, 500, 1000, 2000 GB`, - Example: ` cloudamqp instance resize 1234 --disk-size=100 - cloudamqp instance resize 1234 --disk-size=250 --allow-downtime`, - Args: cobra.ExactArgs(1), - ValidArgsFunction: completeInstances, + Example: ` cloudamqp instance resize --id 1234 --disk-size=100 + cloudamqp instance resize --id 1234 --disk-size=250 --allow-downtime`, + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { var err error apiKey, err = getAPIKey() @@ -35,7 +35,11 @@ Available disk sizes: 0, 25, 50, 100, 250, 500, 1000, 2000 GB`, return fmt.Errorf("failed to get API key: %w", err) } - instanceID, err := strconv.Atoi(args[0]) + if resizeInstanceID == "" { + return fmt.Errorf("--id is required") + } + + instanceID, err := strconv.Atoi(resizeInstanceID) if err != nil { return fmt.Errorf("invalid instance ID: %v", err) } @@ -75,7 +79,10 @@ Available disk sizes: 0, 25, 50, 100, 250, 500, 1000, 2000 GB`, } func init() { + instanceResizeCmd.Flags().StringVar(&resizeInstanceID, "id", "", "Instance ID (required)") instanceResizeCmd.Flags().IntVar(&diskSize, "disk-size", 0, "Disk size to add in gigabytes (0, 25, 50, 100, 250, 500, 1000, 2000)") instanceResizeCmd.Flags().BoolVar(&allowDowntime, "allow-downtime", false, "Allow cluster downtime if needed when resizing disk") + instanceResizeCmd.MarkFlagRequired("id") instanceResizeCmd.MarkFlagRequired("disk-size") + instanceResizeCmd.RegisterFlagCompletionFunc("id", completeInstances) } diff --git a/cmd/instance_update.go b/cmd/instance_update.go index 38f44ed..c9fcf7b 100644 --- a/cmd/instance_update.go +++ b/cmd/instance_update.go @@ -9,13 +9,14 @@ import ( ) var ( + updateInstanceID string updateInstanceName string updateInstancePlan string updateInstanceTags []string ) var instanceUpdateCmd = &cobra.Command{ - Use: "update ", + Use: "update --id ", Short: "Update a CloudAMQP instance", Long: `Update an existing CloudAMQP instance with new configuration. @@ -23,11 +24,10 @@ You can update the following fields: --name: Instance name --plan: Subscription plan --tags: Instance tags (replaces existing tags)`, - Example: ` cloudamqp instance update 1234 --name=new-name - cloudamqp instance update 1234 --plan=rabbit-1 - cloudamqp instance update 1234 --tags=production --tags=updated`, - Args: cobra.ExactArgs(1), - ValidArgsFunction: completeInstances, + Example: ` cloudamqp instance update --id 1234 --name=new-name + cloudamqp instance update --id 1234 --plan=rabbit-1 + cloudamqp instance update --id 1234 --tags=production --tags=updated`, + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { var err error apiKey, err = getAPIKey() @@ -35,7 +35,11 @@ You can update the following fields: return fmt.Errorf("failed to get API key: %w", err) } - instanceID, err := strconv.Atoi(args[0]) + if updateInstanceID == "" { + return fmt.Errorf("--id is required") + } + + instanceID, err := strconv.Atoi(updateInstanceID) if err != nil { return fmt.Errorf("invalid instance ID: %v", err) } @@ -64,8 +68,11 @@ You can update the following fields: } func init() { + instanceUpdateCmd.Flags().StringVar(&updateInstanceID, "id", "", "Instance ID (required)") instanceUpdateCmd.Flags().StringVar(&updateInstanceName, "name", "", "New instance name") instanceUpdateCmd.Flags().StringVar(&updateInstancePlan, "plan", "", "New subscription plan") instanceUpdateCmd.Flags().StringSliceVar(&updateInstanceTags, "tags", []string{}, "New instance tags") + instanceUpdateCmd.MarkFlagRequired("id") + instanceUpdateCmd.RegisterFlagCompletionFunc("id", completeInstances) instanceUpdateCmd.RegisterFlagCompletionFunc("plan", completePlans) } diff --git a/cmd/vpc_delete.go b/cmd/vpc_delete.go index 945dd6c..9eaca61 100644 --- a/cmd/vpc_delete.go +++ b/cmd/vpc_delete.go @@ -11,18 +11,20 @@ import ( "github.com/spf13/cobra" ) -var forceDeleteVPC bool +var ( + deleteVPCID string + forceDeleteVPC bool +) var vpcDeleteCmd = &cobra.Command{ - Use: "delete ", + Use: "delete --id ", Short: "Delete a CloudAMQP VPC", Long: `Delete a CloudAMQP VPC permanently. WARNING: This action cannot be undone. All instances in the VPC must be deleted first.`, - Example: ` cloudamqp vpc delete 5678 - cloudamqp vpc delete 5678 --force`, - Args: cobra.ExactArgs(1), - ValidArgsFunction: completeVPCArgs, + Example: ` cloudamqp vpc delete --id 5678 + cloudamqp vpc delete --id 5678 --force`, + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { var err error apiKey, err = getAPIKey() @@ -30,7 +32,11 @@ WARNING: This action cannot be undone. All instances in the VPC must be deleted return fmt.Errorf("failed to get API key: %w", err) } - vpcID, err := strconv.Atoi(args[0]) + if deleteVPCID == "" { + return fmt.Errorf("--id is required") + } + + vpcID, err := strconv.Atoi(deleteVPCID) if err != nil { return fmt.Errorf("invalid VPC ID: %v", err) } @@ -64,5 +70,8 @@ WARNING: This action cannot be undone. All instances in the VPC must be deleted } func init() { + vpcDeleteCmd.Flags().StringVar(&deleteVPCID, "id", "", "VPC ID (required)") vpcDeleteCmd.Flags().BoolVar(&forceDeleteVPC, "force", false, "Skip confirmation prompt") + vpcDeleteCmd.MarkFlagRequired("id") + vpcDeleteCmd.RegisterFlagCompletionFunc("id", completeVPCArgs) } diff --git a/cmd/vpc_update.go b/cmd/vpc_update.go index d54b6ad..694e1f5 100644 --- a/cmd/vpc_update.go +++ b/cmd/vpc_update.go @@ -9,22 +9,22 @@ import ( ) var ( + updateVPCID string updateVPCName string updateVPCTags []string ) var vpcUpdateCmd = &cobra.Command{ - Use: "update ", + Use: "update --id ", Short: "Update a CloudAMQP VPC", Long: `Update an existing CloudAMQP VPC with new configuration. You can update the following fields: --name: VPC name --tags: VPC tags (replaces existing tags)`, - Example: ` cloudamqp vpc update 5678 --name=new-vpc-name - cloudamqp vpc update 5678 --tags=production --tags=updated`, - Args: cobra.ExactArgs(1), - ValidArgsFunction: completeVPCArgs, + Example: ` cloudamqp vpc update --id 5678 --name=new-vpc-name + cloudamqp vpc update --id 5678 --tags=production --tags=updated`, + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { var err error apiKey, err = getAPIKey() @@ -32,7 +32,11 @@ You can update the following fields: return fmt.Errorf("failed to get API key: %w", err) } - vpcID, err := strconv.Atoi(args[0]) + if updateVPCID == "" { + return fmt.Errorf("--id is required") + } + + vpcID, err := strconv.Atoi(updateVPCID) if err != nil { return fmt.Errorf("invalid VPC ID: %v", err) } @@ -60,6 +64,9 @@ You can update the following fields: } func init() { + vpcUpdateCmd.Flags().StringVar(&updateVPCID, "id", "", "VPC ID (required)") vpcUpdateCmd.Flags().StringVar(&updateVPCName, "name", "", "New VPC name") vpcUpdateCmd.Flags().StringSliceVar(&updateVPCTags, "tags", []string{}, "New VPC tags") + vpcUpdateCmd.MarkFlagRequired("id") + vpcUpdateCmd.RegisterFlagCompletionFunc("id", completeVPCArgs) }