diff --git a/internal/servers/delete.go b/internal/servers/delete.go index e8204c1..02b5f43 100644 --- a/internal/servers/delete.go +++ b/internal/servers/delete.go @@ -2,6 +2,7 @@ package servers import ( "fmt" + "strconv" "github.com/manifoldco/promptui" "github.com/pkg/errors" @@ -9,25 +10,25 @@ import ( ) func (c *Client) Delete() *cobra.Command { - var serverID int var force bool deleteServerCmd := &cobra.Command{ - Use: `delete -i `, + Use: `delete ID [-f]`, + Args: cobra.ExactArgs(1), Short: "Delete a server.", Long: "Deletes the specified server with a confirmation prompt. To skip the confirmation use --force.", Example: ` # Deletes the specified server: - cherryctl server delete -i 12345 + cherryctl server delete 12345 > ✔ Are you sure you want to delete server 12345: y # Deletes a server, skipping confirmation: - cherryctl server delete -f -i 12345`, + cherryctl server delete 12345 -f`, RunE: func(cmd *cobra.Command, args []string) error { cmd.SilenceUsage = true if !force { prompt := promptui.Prompt{ - Label: fmt.Sprintf("Are you sure you want to delete server %d: ", serverID), + Label: fmt.Sprintf("Are you sure you want to delete server %s: ", args[0]), IsConfirm: true, } @@ -36,20 +37,23 @@ func (c *Client) Delete() *cobra.Command { return nil } } - _, _, err := c.Service.Delete(serverID) - if err != nil { - return errors.Wrap(err, "Could not delete Server") + + if serverID, err := strconv.Atoi(args[0]); err == nil { + _, _, err := c.Service.Delete(serverID) + if err != nil { + return errors.Wrap(err, "Could not delete Server") + } + + fmt.Println("Server", serverID, "successfully deleted.") + return nil } - fmt.Println("Server", serverID, "successfully deleted.") + fmt.Println("Server with ID %s was not found", args[0]) return nil }, } - deleteServerCmd.Flags().IntVarP(&serverID, "server-id", "i", 0, "The ID of a server.") deleteServerCmd.Flags().BoolVarP(&force, "force", "f", false, "Skips confirmation for the server deletion.") - _ = deleteServerCmd.MarkFlagRequired("server-id") - return deleteServerCmd } diff --git a/internal/servers/get.go b/internal/servers/get.go index 35fa859..0586605 100644 --- a/internal/servers/get.go +++ b/internal/servers/get.go @@ -11,32 +11,36 @@ import ( func (c *Client) Get() *cobra.Command { var serverID int - var hostname string var projectID int serverGetCmd := &cobra.Command{ - Use: `get {-i | --hostname} [-p ]`, + Args: func(cmd *cobra.Command, args []string) error { + if len(args) < 1 { + return errors.New("Server ID or Hostname must be given as positional argument") + } + return nil + }, + Use: `get {ID | HOSTNAME} [-p ]`, Short: "Retrieves server details.", Long: "Retrieves the details of the specified server.", Example: ` # Gets the details of the specified server: - cherryctl server get -i 12345`, + cherryctl server get 12345`, RunE: func(cmd *cobra.Command, args []string) error { cmd.SilenceUsage = true - if hostname == "" && serverID == 0 { - return fmt.Errorf("either server-id or hostname should be set") - } - if hostname != "" { - srvID, err := utils.ServerHostnameToID(hostname, projectID, c.Service) + if srvID, err := strconv.Atoi(args[0]); err == nil { + serverID = srvID + } else { + srvID, err := utils.ServerHostnameToID(args[0], projectID, c.Service) if err != nil { - return errors.Wrap(err, "Could not get a Server") + return errors.Wrap(err, "Server with hostname %s was not found") } serverID = srvID } s, _, err := c.Service.Get(serverID, c.Servicer.GetOptions()) if err != nil { - return errors.Wrap(err, "Could not get Server") + return errors.Wrap(err, "Could not get a Server") } header := []string{"ID", "Plan", "Hostname", "Image", "State", "Public IP", "Private IP", "Region", "Tags", "Spot"} data := make([][]string, 1) @@ -46,11 +50,7 @@ func (c *Client) Get() *cobra.Command { }, } - serverGetCmd.Flags().IntVarP(&serverID, "server-id", "i", 0, "The ID of a server.") - serverGetCmd.Flags().StringVarP(&hostname, "hostname", "", "", "The Hostname of a server.") serverGetCmd.Flags().IntVarP(&projectID, "project-id", "p", 0, "The project's ID.") - serverGetCmd.MarkFlagsMutuallyExclusive("server-id", "hostname") - return serverGetCmd } diff --git a/internal/servers/reboot.go b/internal/servers/reboot.go index 56516e8..3424bf2 100644 --- a/internal/servers/reboot.go +++ b/internal/servers/reboot.go @@ -2,34 +2,37 @@ package servers import ( "fmt" + "strconv" "github.com/pkg/errors" "github.com/spf13/cobra" ) func (c *Client) Reboot() *cobra.Command { - var serverID int rebootServerCmd := &cobra.Command{ - Use: `reboot -i `, + Use: `reboot ID`, + Args: cobra.ExactArgs(1), Short: "Reboot a server.", Long: "Reboot the specified server.", Example: ` # Reboot the specified server: - cherryctl server reboot -i 12345`, + cherryctl server reboot 12345`, RunE: func(cmd *cobra.Command, args []string) error { cmd.SilenceUsage = true - _, _, err := c.Service.Reboot(serverID) - if err != nil { - return errors.Wrap(err, "Could not reboot a Server") + if serverID, err := strconv.Atoi(args[0]); err == nil { + _, _, err := c.Service.Reboot(serverID) + if err != nil { + return errors.Wrap(err, "Could not reboot a Server") + } + + fmt.Println("Server", serverID, "successfully rebooted.") + return nil } - fmt.Println("Server", serverID, "successfully rebooted.") + fmt.Println("Server with ID %s was not found", args[0]) return nil }, } - rebootServerCmd.Flags().IntVarP(&serverID, "server-id", "i", 0, "The ID of a server.") - _ = rebootServerCmd.MarkFlagRequired("server-id") - return rebootServerCmd } diff --git a/internal/servers/reinstall.go b/internal/servers/reinstall.go index 10cc173..fe44022 100644 --- a/internal/servers/reinstall.go +++ b/internal/servers/reinstall.go @@ -2,6 +2,7 @@ package servers import ( "fmt" + "strconv" "github.com/cherryservers/cherrygo/v3" "github.com/pkg/errors" @@ -10,7 +11,6 @@ import ( func (c *Client) Reinstall() *cobra.Command { var ( - serverID int hostname string image string password string @@ -19,11 +19,12 @@ func (c *Client) Reinstall() *cobra.Command { ) reinstallServerCmd := &cobra.Command{ - Use: `reinstall -i --hostname --image --password [--ssh-keys ] [--os-partition-size ]`, + Use: `reinstall ID --hostname --image --password [--ssh-keys ] [--os-partition-size ]`, + Args: cobra.ExactArgs(1), Short: "Reinstall a server.", Long: "Reinstall the specified server.", Example: ` # Reinstall the specified server: - cherryctl server reinstall -i 12345 -h staging-server-1 --image ubuntu_20_04 --password G1h2e_39Q9oT`, + cherryctl server reinstall 12345 -hostname staging-server-1 --image ubuntu_20_04 --password G1h2e_39Q9oT`, RunE: func(cmd *cobra.Command, args []string) error { cmd.SilenceUsage = true @@ -36,24 +37,27 @@ func (c *Client) Reinstall() *cobra.Command { OSPartitionSize: osPartitionSize, } - _, _, err := c.Service.Reinstall(serverID, request) - if err != nil { - return errors.Wrap(err, "Could not reinstall Server") + if serverID, err := strconv.Atoi(args[0]); err == nil { + _, _, err := c.Service.Reinstall(serverID, request) + if err != nil { + return errors.Wrap(err, "Could not reinstall a Server.") + } + + fmt.Println("Server", serverID, "reinstall has been started.") + return nil } - fmt.Println("Server", serverID, "reinstall has been started.") + fmt.Println("Server with ID %s was not found.", args[0]) return nil }, } - reinstallServerCmd.Flags().IntVarP(&serverID, "server-id", "i", 0, "The ID of a server.") reinstallServerCmd.Flags().StringVarP(&hostname, "hostname", "", "", "Hostname.") reinstallServerCmd.Flags().StringVarP(&image, "image", "", "", "Operating system slug for the server.") reinstallServerCmd.Flags().StringVarP(&password, "password", "", "", "Server password.") reinstallServerCmd.Flags().StringSliceVarP(&sshKeys, "ssh-keys", "", []string{}, "Comma separated list of SSH key IDs to be embed in the Server.") reinstallServerCmd.Flags().IntVarP(&osPartitionSize, "os-partition-size", "", 0, "OS partition size in GB.") - _ = reinstallServerCmd.MarkFlagRequired("server-id") _ = reinstallServerCmd.MarkFlagRequired("hostname") _ = reinstallServerCmd.MarkFlagRequired("image") _ = reinstallServerCmd.MarkFlagRequired("password") diff --git a/internal/servers/server.go b/internal/servers/server.go index 1b1d165..199977c 100644 --- a/internal/servers/server.go +++ b/internal/servers/server.go @@ -35,6 +35,7 @@ func (c *Client) NewCommand() *cobra.Command { c.Get(), c.List(), c.Create(), + c.Update(), c.Start(), c.Stop(), c.Reboot(), diff --git a/internal/servers/start.go b/internal/servers/start.go index 4ae11c1..ed52826 100644 --- a/internal/servers/start.go +++ b/internal/servers/start.go @@ -2,34 +2,38 @@ package servers import ( "fmt" + "strconv" "github.com/pkg/errors" "github.com/spf13/cobra" ) func (c *Client) Start() *cobra.Command { - var serverID int startServerCmd := &cobra.Command{ - Use: `start -i `, + Use: `start ID`, + Args: cobra.ExactArgs(1), Short: "Starts a server.", Long: "Starts or powers on a server that is currently stopped or powered off.", Example: ` # Starts the specified server: - cherryctl server start -i 12345`, + cherryctl server start 12345`, RunE: func(cmd *cobra.Command, args []string) error { cmd.SilenceUsage = true - _, _, err := c.Service.PowerOn(serverID) - if err != nil { - return errors.Wrap(err, "Could not start a Server") + + if serverID, err := strconv.Atoi(args[0]); err == nil { + _, _, err := c.Service.PowerOn(serverID) + if err != nil { + return errors.Wrap(err, "Could not start a Server") + } + + fmt.Println("Server", serverID, "successfully started.") + return nil } - fmt.Println("Server", serverID, "successfully started.") + fmt.Println("Server with ID %s was not found.", args[0]) return nil }, } - startServerCmd.Flags().IntVarP(&serverID, "server-id", "i", 0, "The ID of a server.") - _ = startServerCmd.MarkFlagRequired("server-id") - return startServerCmd } diff --git a/internal/servers/stop.go b/internal/servers/stop.go index 8b9ccac..944c7f6 100644 --- a/internal/servers/stop.go +++ b/internal/servers/stop.go @@ -2,34 +2,37 @@ package servers import ( "fmt" + "strconv" "github.com/pkg/errors" "github.com/spf13/cobra" ) func (c *Client) Stop() *cobra.Command { - var serverID int stopServerCmd := &cobra.Command{ - Use: `stop -i `, + Use: `stop ID`, + Args: cobra.ExactArgs(1), Short: "Stop a server.", Long: "Stops or powers off a server that is currently powered on.", Example: ` # Stops the specified server: - cherryctl server stop -i 12345`, + cherryctl server stop 12345`, RunE: func(cmd *cobra.Command, args []string) error { cmd.SilenceUsage = true - _, _, err := c.Service.PowerOff(serverID) - if err != nil { - return errors.Wrap(err, "Could not stop a Server") + if serverID, err := strconv.Atoi(args[0]); err == nil { + _, _, err := c.Service.PowerOff(serverID) + if err != nil { + return errors.Wrap(err, "Could not stop a Server") + } + + fmt.Println("Server", serverID, "successfully stopped.") + return nil } - fmt.Println("Server", serverID, "successfully stopped.") + fmt.Println("Server with ID %s was not found.", args[0]) return nil }, } - stopServerCmd.Flags().IntVarP(&serverID, "server-id", "i", 0, "The ID of a server.") - _ = stopServerCmd.MarkFlagRequired("server-id") - return stopServerCmd } diff --git a/internal/servers/update.go b/internal/servers/update.go index ebedfb5..f82f21b 100644 --- a/internal/servers/update.go +++ b/internal/servers/update.go @@ -1,6 +1,7 @@ package servers import ( + "fmt" "strconv" "strings" @@ -18,14 +19,23 @@ func (c *Client) Update() *cobra.Command { bgp bool ) serverUpdateCmd := &cobra.Command{ - Use: `update -i [--name ] [--hostname] [--tags] [--bgp]`, + Use: `update ID [--name ] [--hostname ] [--tags ] [--bgp]`, + Args: cobra.ExactArgs(1), Short: "Update server.", Long: "Update server.", Example: ` # Update server to change tags: - cherryctl server update -i 12345 --tags="env=stage"`, + cherryctl server update 12345 --tags="env=stage"`, RunE: func(cmd *cobra.Command, args []string) error { cmd.SilenceUsage = true + + if srvID, err := strconv.Atoi(args[0]); err == nil { + serverID = srvID + } else { + fmt.Println("Server with ID %s was not found.", args[0]) + return nil + } + tagsArr := make(map[string]string) for _, kv := range tags { @@ -59,12 +69,9 @@ func (c *Client) Update() *cobra.Command { }, } - serverUpdateCmd.Flags().IntVarP(&serverID, "server-id", "i", 0, "The ID of a server.") serverUpdateCmd.Flags().StringVarP(&hostname, "hostname", "", "", "Server hostname.") serverUpdateCmd.Flags().BoolVarP(&bgp, "bgp", "b", false, "True to enable BGP in a server.") serverUpdateCmd.Flags().StringSliceVarP(&tags, "tags", "", []string{}, `Tag or list of tags for the server: --tags="key=value,env=prod".`) - serverUpdateCmd.MarkFlagRequired("server-id") - return serverUpdateCmd } diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 9e89e31..c29edfc 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -17,6 +17,10 @@ func BoolToYesNo(b bool) string { } func ServerHostnameToID(hostname string, projectID int, ServerService cherrygo.ServersService) (int, error) { + if projectID == 0 { + return 0, fmt.Errorf("Project ID must be set") + } + serversList, err := serverList(projectID, ServerService) for _, s := range serversList { if strings.EqualFold(hostname, s.Hostname) {