package hosts import ( "encoding/json" "fmt" "strings" "xcecli/common/request" "xcecli/config" "xcecli/models" "github.com/spf13/cobra" ) const ( HOST_OPEN = 1 HOST_CLOSE = 2 ) // HostController host control controller type HostController struct { configManager *config.ConfigManager action string hostnames []string comment string allHosts bool } // NewHostController create host control controller func NewHostController(configManager *config.ConfigManager, action string) *HostController { return &HostController{ configManager: configManager, action: action, hostnames: []string{}, } } // Run execute host control func (c *HostController) RunHostsControl() error { // get server info and verify authentication serverInfo, _ := c.configManager.GetServerInfo() // create API client apiClient := request.NewAPIClient(serverInfo.URL) // handle all hosts case if c.allHosts { c.hostnames = []string{"all"} } // if no hostnames specified, return error if len(c.hostnames) == 0 { return fmt.Errorf("must specify hostnames or use --all option") } // create request req := models.HostControlRequest{ ControlAction: c.action, Hostname: c.hostnames, Comment: c.comment, } // encode request to JSON bytes reqData, err := json.Marshal(req) if err != nil { errMsg := request.ExtractErrorMessage(err) return fmt.Errorf("failed to encode request data: [%s]", errMsg) } var resp models.HostControlResponse err = apiClient.PostRequestToAPIServer( serverInfo.Token, "/xce/v1/hosts/control", reqData, &resp, ) if err != nil { return err } if len(c.hostnames) == 1 && c.hostnames[0] == "all" { for _, data := range resp.Data.Accepted { fmt.Printf("host <%s> is being <%s>\n", data.HostName, c.action) } for _, host := range resp.Data.Failed { fmt.Printf("host <%s> cannot be <%s> for reason <%s>\n", host.HostName, c.action, host.Msg) } } else { for _, data := range resp.Data.Accepted { fmt.Printf("host <%s> is being <%s>\n", data.HostName, c.action) } for _, host := range resp.Data.Failed { fmt.Printf("host <%s> cannot be <%s> for reason <%s>\n", host.HostName, c.action, host.Msg) } } return nil } // Parse parse command line arguments func (c *HostController) ParseCmdArgs(cmd *cobra.Command, args []string) error { // handle hostnames if len(args) > 0 { c.hostnames = append(c.hostnames, args...) } return nil } // NewOpenHostsCmd create open hosts command func NewOpenHostsCmd(configManager *config.ConfigManager) *cobra.Command { controller := NewHostController(configManager, "open") cmd := &cobra.Command{ Use: "open [hostname1 hostname2...]", Short: "Open hosts", Long: `Open hosts by hostname. Open hosts changes hosts from DOWN, UNREACH, or UNAVAIL status to OK status. Examples: xce hosts open host1,host2,... # open specific hosts xce hosts open --all # open all hosts`, RunE: func(cmd *cobra.Command, args []string) error { if err := controller.ParseCmdArgs(cmd, args); err != nil { fmt.Println(strings.ToLower(err.Error())) return nil } if err := controller.RunHostsControl(); err != nil { fmt.Println(strings.ToLower(err.Error())) return nil } return nil }, } // add control options flags := cmd.Flags() flags.BoolVarP(&controller.allHosts, "all", "a", false, "apply to all hosts") flags.StringVarP(&controller.comment, "comment", "c", "", "add comment for this operation") return cmd } // NewCloseHostsCmd create close hosts command func NewCloseHostsCmd(configManager *config.ConfigManager) *cobra.Command { controller := NewHostController(configManager, "close") cmd := &cobra.Command{ Use: "close [hostname1 hostname2...]", Short: "Close hosts", Long: `Close hosts by hostname. Close hosts changes hosts from OK, BUSY, or IDLE status to UNAVAIL status. Examples: xce hosts close host1 host2 # close specific hosts xce hosts close --all # close all hosts`, RunE: func(cmd *cobra.Command, args []string) error { if err := controller.ParseCmdArgs(cmd, args); err != nil { fmt.Println(strings.ToLower(err.Error())) return nil } if err := controller.RunHostsControl(); err != nil { fmt.Println(strings.ToLower(err.Error())) return nil } return nil }, } // add control options flags := cmd.Flags() flags.BoolVarP(&controller.allHosts, "all", "a", false, "apply to all hosts") flags.StringVarP(&controller.comment, "comment", "c", "", "add comment for this operation") return cmd }