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