Confirmation on destructive commands
This commit is contained in:
parent
3320e1c3dd
commit
5d48a2bc71
|
@ -27,6 +27,9 @@ Node Drain Options:
|
|||
|
||||
-enable
|
||||
Enable draining for the specified node.
|
||||
|
||||
-yes
|
||||
Automatic yes to prompts.
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
@ -36,12 +39,13 @@ func (c *NodeDrainCommand) Synopsis() string {
|
|||
}
|
||||
|
||||
func (c *NodeDrainCommand) Run(args []string) int {
|
||||
var enable, disable bool
|
||||
var enable, disable, autoYes bool
|
||||
|
||||
flags := c.Meta.FlagSet("node-drain", FlagSetClient)
|
||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
flags.BoolVar(&enable, "enable", false, "Enable drain mode")
|
||||
flags.BoolVar(&disable, "disable", false, "Disable drain mode")
|
||||
flags.BoolVar(&autoYes, "yes", false, "Automatic yes to prompts.")
|
||||
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
|
@ -108,6 +112,7 @@ func (c *NodeDrainCommand) Run(args []string) int {
|
|||
c.Ui.Output(fmt.Sprintf("Prefix matched multiple nodes\n\n%s", formatList(out)))
|
||||
return 0
|
||||
}
|
||||
|
||||
// Prefix lookup matched a single node
|
||||
node, _, err := client.Nodes().Info(nodes[0].ID, nil)
|
||||
if err != nil {
|
||||
|
@ -115,6 +120,33 @@ func (c *NodeDrainCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
// Confirm drain if the node was a prefix match.
|
||||
if nodeID != node.ID && !autoYes {
|
||||
verb := "enable"
|
||||
if disable {
|
||||
verb = "disable"
|
||||
}
|
||||
question := fmt.Sprintf("Are you sure you want to %s drain mode for node %q? [y/N]", verb, node.ID)
|
||||
answer, err := c.Ui.Ask(question)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Failed to parse answer: %v", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
if answer == "" || strings.ToLower(answer)[0] == 'n' {
|
||||
// No case
|
||||
c.Ui.Output("Canceling drain toggle")
|
||||
return 0
|
||||
} else if strings.ToLower(answer)[0] == 'y' {
|
||||
// Non exact match yes
|
||||
c.Ui.Output("For confirmation, an exact ‘y’ is required.")
|
||||
return 0
|
||||
} else if answer != "y" {
|
||||
c.Ui.Output("No confirmation detected. For confirmation, an exact 'y' is required.")
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle node draining
|
||||
if _, err := client.Nodes().ToggleDrain(node.ID, enable, nil); err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Error toggling drain mode: %s", err))
|
||||
|
|
|
@ -31,6 +31,9 @@ Stop Options:
|
|||
to the screen, which can be used to call up a monitor later if
|
||||
needed using the eval-monitor command.
|
||||
|
||||
-yes
|
||||
Automatic yes to prompts.
|
||||
|
||||
-verbose
|
||||
Display full information.
|
||||
`
|
||||
|
@ -42,12 +45,13 @@ func (c *StopCommand) Synopsis() string {
|
|||
}
|
||||
|
||||
func (c *StopCommand) Run(args []string) int {
|
||||
var detach, verbose bool
|
||||
var detach, verbose, autoYes bool
|
||||
|
||||
flags := c.Meta.FlagSet("stop", FlagSetClient)
|
||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
flags.BoolVar(&detach, "detach", false, "")
|
||||
flags.BoolVar(&verbose, "verbose", false, "")
|
||||
flags.BoolVar(&autoYes, "yes", false, "")
|
||||
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
|
@ -104,6 +108,29 @@ func (c *StopCommand) Run(args []string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
// Confirm the stop if the job was a prefix match.
|
||||
if jobID != job.ID && !autoYes {
|
||||
question := fmt.Sprintf("Are you sure you want to stop job %q? [y/N]", job.ID)
|
||||
answer, err := c.Ui.Ask(question)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf("Failed to parse answer: %v", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
if answer == "" || strings.ToLower(answer)[0] == 'n' {
|
||||
// No case
|
||||
c.Ui.Output("Cancelling job stop")
|
||||
return 0
|
||||
} else if strings.ToLower(answer)[0] == 'y' {
|
||||
// Non exact match yes
|
||||
c.Ui.Output("For confirmation, an exact ‘y’ is required.")
|
||||
return 0
|
||||
} else if answer != "y" {
|
||||
c.Ui.Output("No confirmation detected. For confirmation, an exact 'y' is required.")
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke the stop
|
||||
evalID, _, err := client.Jobs().Deregister(job.ID, nil)
|
||||
if err != nil {
|
||||
|
|
|
@ -18,6 +18,7 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory {
|
|||
meta := *metaPtr
|
||||
if meta.Ui == nil {
|
||||
meta.Ui = &cli.BasicUi{
|
||||
Reader: os.Stdin,
|
||||
Writer: os.Stdout,
|
||||
ErrorWriter: os.Stderr,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue