github.com/ThomasObenaus/nomad@v0.11.1/command/node_eligibility.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/hashicorp/nomad/api/contexts" 8 "github.com/posener/complete" 9 ) 10 11 type NodeEligibilityCommand struct { 12 Meta 13 } 14 15 func (c *NodeEligibilityCommand) Help() string { 16 helpText := ` 17 Usage: nomad node eligibility [options] <node> 18 19 Toggles the nodes scheduling eligibility. When a node is marked as ineligible, 20 no new allocations will be placed on it but existing allocations will remain. 21 To remove existing allocations, use the node drain command. 22 23 It is required that either -enable or -disable is specified, but not both. 24 The -self flag is useful to set the scheduling eligibility of the local node. 25 26 General Options: 27 28 ` + generalOptionsUsage() + ` 29 30 Node Eligibility Options: 31 32 -disable 33 Mark the specified node as ineligible for new allocations. 34 35 -enable 36 Mark the specified node as eligible for new allocations. 37 38 -self 39 Set the eligibility of the local node. 40 ` 41 return strings.TrimSpace(helpText) 42 } 43 44 func (c *NodeEligibilityCommand) Synopsis() string { 45 return "Toggle scheduling eligibility for a given node" 46 } 47 48 func (c *NodeEligibilityCommand) AutocompleteFlags() complete.Flags { 49 return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), 50 complete.Flags{ 51 "-disable": complete.PredictNothing, 52 "-enable": complete.PredictNothing, 53 "-self": complete.PredictNothing, 54 }) 55 } 56 57 func (c *NodeEligibilityCommand) AutocompleteArgs() complete.Predictor { 58 return complete.PredictFunc(func(a complete.Args) []string { 59 client, err := c.Meta.Client() 60 if err != nil { 61 return nil 62 } 63 64 resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Nodes, nil) 65 if err != nil { 66 return []string{} 67 } 68 return resp.Matches[contexts.Nodes] 69 }) 70 } 71 72 func (c *NodeEligibilityCommand) Name() string { return "node-eligibility" } 73 74 func (c *NodeEligibilityCommand) Run(args []string) int { 75 var enable, disable, self bool 76 77 flags := c.Meta.FlagSet(c.Name(), FlagSetClient) 78 flags.Usage = func() { c.Ui.Output(c.Help()) } 79 flags.BoolVar(&enable, "enable", false, "Mark node as eligibile for scheduling") 80 flags.BoolVar(&disable, "disable", false, "Mark node as ineligibile for scheduling") 81 flags.BoolVar(&self, "self", false, "") 82 83 if err := flags.Parse(args); err != nil { 84 return 1 85 } 86 87 // Check that we got either enable or disable, but not both. 88 if (enable && disable) || (!enable && !disable) { 89 c.Ui.Error("Either the '-enable' or '-disable' flag must be set") 90 c.Ui.Error(commandErrorText(c)) 91 return 1 92 } 93 94 // Check that we got a node ID 95 args = flags.Args() 96 if l := len(args); self && l != 0 || !self && l != 1 { 97 c.Ui.Error("Node ID must be specified if -self isn't being used") 98 c.Ui.Error(commandErrorText(c)) 99 return 1 100 } 101 102 // Get the HTTP client 103 client, err := c.Meta.Client() 104 if err != nil { 105 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 106 return 1 107 } 108 109 // If -self flag is set then determine the current node. 110 var nodeID string 111 if !self { 112 nodeID = args[0] 113 } else { 114 var err error 115 if nodeID, err = getLocalNodeID(client); err != nil { 116 c.Ui.Error(err.Error()) 117 return 1 118 } 119 } 120 121 // Check if node exists 122 if len(nodeID) == 1 { 123 c.Ui.Error(fmt.Sprintf("Identifier must contain at least two characters.")) 124 return 1 125 } 126 127 nodeID = sanitizeUUIDPrefix(nodeID) 128 nodes, _, err := client.Nodes().PrefixList(nodeID) 129 if err != nil { 130 c.Ui.Error(fmt.Sprintf("Error updating scheduling eligibility: %s", err)) 131 return 1 132 } 133 // Return error if no nodes are found 134 if len(nodes) == 0 { 135 c.Ui.Error(fmt.Sprintf("No node(s) with prefix or id %q found", nodeID)) 136 return 1 137 } 138 if len(nodes) > 1 { 139 c.Ui.Error(fmt.Sprintf("Prefix matched multiple nodes\n\n%s", 140 formatNodeStubList(nodes, true))) 141 return 1 142 } 143 144 // Prefix lookup matched a single node 145 node, _, err := client.Nodes().Info(nodes[0].ID, nil) 146 if err != nil { 147 c.Ui.Error(fmt.Sprintf("Error updating scheduling eligibility: %s", err)) 148 return 1 149 } 150 151 // Toggle node eligibility 152 if _, err := client.Nodes().ToggleEligibility(node.ID, enable, nil); err != nil { 153 c.Ui.Error(fmt.Sprintf("Error updating scheduling eligibility: %s", err)) 154 return 1 155 } 156 157 if enable { 158 c.Ui.Output(fmt.Sprintf("Node %q scheduling eligibility set: eligible for scheduling", node.ID)) 159 } else { 160 c.Ui.Output(fmt.Sprintf("Node %q scheduling eligibility set: ineligible for scheduling", node.ID)) 161 } 162 return 0 163 }