github.com/djenriquez/nomad-1@v0.8.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) Run(args []string) int { 73 var enable, disable, self bool 74 75 flags := c.Meta.FlagSet("node-eligibility", FlagSetClient) 76 flags.Usage = func() { c.Ui.Output(c.Help()) } 77 flags.BoolVar(&enable, "enable", false, "Mark node as eligibile for scheduling") 78 flags.BoolVar(&disable, "disable", false, "Mark node as ineligibile for scheduling") 79 flags.BoolVar(&self, "self", false, "") 80 81 if err := flags.Parse(args); err != nil { 82 return 1 83 } 84 85 // Check that we got either enable or disable, but not both. 86 if (enable && disable) || (!enable && !disable) { 87 c.Ui.Error(c.Help()) 88 return 1 89 } 90 91 // Check that we got a node ID 92 args = flags.Args() 93 if l := len(args); self && l != 0 || !self && l != 1 { 94 c.Ui.Error("Node ID must be specified if -self isn't being used") 95 return 1 96 } 97 98 // Get the HTTP client 99 client, err := c.Meta.Client() 100 if err != nil { 101 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 102 return 1 103 } 104 105 // If -self flag is set then determine the current node. 106 var nodeID string 107 if !self { 108 nodeID = args[0] 109 } else { 110 var err error 111 if nodeID, err = getLocalNodeID(client); err != nil { 112 c.Ui.Error(err.Error()) 113 return 1 114 } 115 } 116 117 // Check if node exists 118 if len(nodeID) == 1 { 119 c.Ui.Error(fmt.Sprintf("Identifier must contain at least two characters.")) 120 return 1 121 } 122 123 nodeID = sanitizeUUIDPrefix(nodeID) 124 nodes, _, err := client.Nodes().PrefixList(nodeID) 125 if err != nil { 126 c.Ui.Error(fmt.Sprintf("Error updating scheduling eligibility: %s", err)) 127 return 1 128 } 129 // Return error if no nodes are found 130 if len(nodes) == 0 { 131 c.Ui.Error(fmt.Sprintf("No node(s) with prefix or id %q found", nodeID)) 132 return 1 133 } 134 if len(nodes) > 1 { 135 c.Ui.Error(fmt.Sprintf("Prefix matched multiple nodes\n\n%s", 136 formatNodeStubList(nodes, true))) 137 return 1 138 } 139 140 // Prefix lookup matched a single node 141 node, _, err := client.Nodes().Info(nodes[0].ID, nil) 142 if err != nil { 143 c.Ui.Error(fmt.Sprintf("Error updating scheduling eligibility: %s", err)) 144 return 1 145 } 146 147 // Toggle node eligibility 148 if _, err := client.Nodes().ToggleEligibility(node.ID, enable, nil); err != nil { 149 c.Ui.Error(fmt.Sprintf("Error updating scheduling eligibility: %s", err)) 150 return 1 151 } 152 153 if enable { 154 c.Ui.Output(fmt.Sprintf("Node %q scheduling eligibility set: eligible for scheduling", node.ID)) 155 } else { 156 c.Ui.Output(fmt.Sprintf("Node %q scheduling eligibility set: ineligible for scheduling", node.ID)) 157 } 158 return 0 159 }