github.com/maier/nomad@v0.4.1-0.20161110003312-a9e3d0b8549d/api/nodes.go (about) 1 package api 2 3 import ( 4 "fmt" 5 "sort" 6 "strconv" 7 ) 8 9 // Nodes is used to query node-related API endpoints 10 type Nodes struct { 11 client *Client 12 } 13 14 // Nodes returns a handle on the node endpoints. 15 func (c *Client) Nodes() *Nodes { 16 return &Nodes{client: c} 17 } 18 19 // List is used to list out all of the nodes 20 func (n *Nodes) List(q *QueryOptions) ([]*NodeListStub, *QueryMeta, error) { 21 var resp NodeIndexSort 22 qm, err := n.client.query("/v1/nodes", &resp, q) 23 if err != nil { 24 return nil, nil, err 25 } 26 sort.Sort(NodeIndexSort(resp)) 27 return resp, qm, nil 28 } 29 30 func (n *Nodes) PrefixList(prefix string) ([]*NodeListStub, *QueryMeta, error) { 31 return n.List(&QueryOptions{Prefix: prefix}) 32 } 33 34 // Info is used to query a specific node by its ID. 35 func (n *Nodes) Info(nodeID string, q *QueryOptions) (*Node, *QueryMeta, error) { 36 var resp Node 37 qm, err := n.client.query("/v1/node/"+nodeID, &resp, q) 38 if err != nil { 39 return nil, nil, err 40 } 41 return &resp, qm, nil 42 } 43 44 // ToggleDrain is used to toggle drain mode on/off for a given node. 45 func (n *Nodes) ToggleDrain(nodeID string, drain bool, q *WriteOptions) (*WriteMeta, error) { 46 drainArg := strconv.FormatBool(drain) 47 wm, err := n.client.write("/v1/node/"+nodeID+"/drain?enable="+drainArg, nil, nil, q) 48 if err != nil { 49 return nil, err 50 } 51 return wm, nil 52 } 53 54 // Allocations is used to return the allocations associated with a node. 55 func (n *Nodes) Allocations(nodeID string, q *QueryOptions) ([]*Allocation, *QueryMeta, error) { 56 var resp []*Allocation 57 qm, err := n.client.query("/v1/node/"+nodeID+"/allocations", &resp, q) 58 if err != nil { 59 return nil, nil, err 60 } 61 sort.Sort(AllocationSort(resp)) 62 return resp, qm, nil 63 } 64 65 // ForceEvaluate is used to force-evaluate an existing node. 66 func (n *Nodes) ForceEvaluate(nodeID string, q *WriteOptions) (string, *WriteMeta, error) { 67 var resp nodeEvalResponse 68 wm, err := n.client.write("/v1/node/"+nodeID+"/evaluate", nil, &resp, q) 69 if err != nil { 70 return "", nil, err 71 } 72 return resp.EvalID, wm, nil 73 } 74 75 func (n *Nodes) Stats(nodeID string, q *QueryOptions) (*HostStats, error) { 76 node, _, err := n.client.Nodes().Info(nodeID, q) 77 if err != nil { 78 return nil, err 79 } 80 if node.HTTPAddr == "" { 81 return nil, fmt.Errorf("http addr of the node %q is running is not advertised", nodeID) 82 } 83 client, err := NewClient(n.client.config.CopyConfig(node.HTTPAddr, node.TLSEnabled)) 84 if err != nil { 85 return nil, err 86 } 87 var resp HostStats 88 if _, err := client.query("/v1/client/stats", &resp, nil); err != nil { 89 return nil, err 90 } 91 return &resp, nil 92 } 93 94 // Node is used to deserialize a node entry. 95 type Node struct { 96 ID string 97 Datacenter string 98 Name string 99 HTTPAddr string 100 TLSEnabled bool 101 Attributes map[string]string 102 Resources *Resources 103 Reserved *Resources 104 Links map[string]string 105 Meta map[string]string 106 NodeClass string 107 Drain bool 108 Status string 109 StatusDescription string 110 StatusUpdatedAt int64 111 CreateIndex uint64 112 ModifyIndex uint64 113 } 114 115 // HostStats represents resource usage stats of the host running a Nomad client 116 type HostStats struct { 117 Memory *HostMemoryStats 118 CPU []*HostCPUStats 119 DiskStats []*HostDiskStats 120 Uptime uint64 121 CPUTicksConsumed float64 122 } 123 124 type HostMemoryStats struct { 125 Total uint64 126 Available uint64 127 Used uint64 128 Free uint64 129 } 130 131 type HostCPUStats struct { 132 CPU string 133 User float64 134 System float64 135 Idle float64 136 } 137 138 type HostDiskStats struct { 139 Device string 140 Mountpoint string 141 Size uint64 142 Used uint64 143 Available uint64 144 UsedPercent float64 145 InodesUsedPercent float64 146 } 147 148 // NodeListStub is a subset of information returned during 149 // node list operations. 150 type NodeListStub struct { 151 ID string 152 Datacenter string 153 Name string 154 NodeClass string 155 Drain bool 156 Status string 157 StatusDescription string 158 CreateIndex uint64 159 ModifyIndex uint64 160 } 161 162 // NodeIndexSort reverse sorts nodes by CreateIndex 163 type NodeIndexSort []*NodeListStub 164 165 func (n NodeIndexSort) Len() int { 166 return len(n) 167 } 168 169 func (n NodeIndexSort) Less(i, j int) bool { 170 return n[i].CreateIndex > n[j].CreateIndex 171 } 172 173 func (n NodeIndexSort) Swap(i, j int) { 174 n[i], n[j] = n[j], n[i] 175 } 176 177 // nodeEvalResponse is used to decode a force-eval. 178 type nodeEvalResponse struct { 179 EvalID string 180 } 181 182 // AllocationSort reverse sorts allocs by CreateIndex. 183 type AllocationSort []*Allocation 184 185 func (a AllocationSort) Len() int { 186 return len(a) 187 } 188 189 func (a AllocationSort) Less(i, j int) bool { 190 return a[i].CreateIndex > a[j].CreateIndex 191 } 192 193 func (a AllocationSort) Swap(i, j int) { 194 a[i], a[j] = a[j], a[i] 195 }