1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
|
package nodes
import (
"github.com/mitchellh/mapstructure"
"github.com/rackspace/gophercloud"
"github.com/rackspace/gophercloud/pagination"
)
// Node represents a back-end device, usually a virtual machine, that can
// handle traffic. It is assigned traffic based on its parent load balancer.
type Node struct {
// The IP address or CIDR for this back-end node.
Address string
// The unique ID for this node.
ID int
// The port on which traffic is sent and received.
Port int
// The node's status.
Status Status
// The node's condition.
Condition Condition
// The priority at which this node will receive traffic if a weighted
// algorithm is used by its parent load balancer. Ranges from 1 to 100.
Weight int
// Type of node.
Type Type
}
// Type indicates whether the node is of a PRIMARY or SECONDARY nature.
type Type string
const (
// PRIMARY nodes are in the normal rotation to receive traffic from the load
// balancer.
PRIMARY Type = "PRIMARY"
// SECONDARY nodes are only in the rotation to receive traffic from the load
// balancer when all the primary nodes fail. This provides a failover feature
// that automatically routes traffic to the secondary node in the event that
// the primary node is disabled or in a failing state. Note that active
// health monitoring must be enabled on the load balancer to enable the
// failover feature to the secondary node.
SECONDARY Type = "SECONDARY"
)
// Condition represents the condition of a node.
type Condition string
const (
// ENABLED indicates that the node is permitted to accept new connections.
ENABLED Condition = "ENABLED"
// DISABLED indicates that the node is not permitted to accept any new
// connections regardless of session persistence configuration. Existing
// connections are forcibly terminated.
DISABLED Condition = "DISABLED"
// DRAINING indicates that the node is allowed to service existing
// established connections and connections that are being directed to it as a
// result of the session persistence configuration.
DRAINING Condition = "DRAINING"
)
// Status indicates whether the node can accept service traffic. If a node is
// not listening on its port or does not meet the conditions of the defined
// active health check for the load balancer, then the load balancer does not
// forward connections, and its status is listed as OFFLINE.
type Status string
const (
// ONLINE indicates that the node is healthy and capable of receiving traffic
// from the load balancer.
ONLINE Status = "ONLINE"
// OFFLINE indicates that the node is not in a position to receive service
// traffic. It is usually switched into this state when a health check is not
// satisfied with the node's response time.
OFFLINE Status = "OFFLINE"
)
// NodePage is the page returned by a pager when traversing over a collection
// of nodes.
type NodePage struct {
pagination.SinglePageBase
}
// IsEmpty checks whether a NodePage struct is empty.
func (p NodePage) IsEmpty() (bool, error) {
is, err := ExtractNodes(p)
if err != nil {
return true, nil
}
return len(is) == 0, nil
}
func commonExtractNodes(body interface{}) ([]Node, error) {
var resp struct {
Nodes []Node `mapstructure:"nodes" json:"nodes"`
}
err := mapstructure.Decode(body, &resp)
return resp.Nodes, err
}
// ExtractNodes accepts a Page struct, specifically a NodePage struct, and
// extracts the elements into a slice of Node structs. In other words, a
// generic collection is mapped into a relevant slice.
func ExtractNodes(page pagination.Page) ([]Node, error) {
return commonExtractNodes(page.(NodePage).Body)
}
// CreateResult represents the result of a create operation. Since multiple
// nodes can be added in one operation, this result represents multiple nodes
// and should be treated as a typical pagination Page. Use its ExtractNodes
// method to get out a slice of Node structs.
type CreateResult struct {
pagination.SinglePageBase
}
// ExtractNodes extracts a slice of Node structs from a CreateResult.
func (res CreateResult) ExtractNodes() ([]Node, error) {
if res.Err != nil {
return nil, res.Err
}
return commonExtractNodes(res.Body)
}
// DeleteResult represents the result of a delete operation.
type DeleteResult struct {
gophercloud.ErrResult
}
type commonResult struct {
gophercloud.Result
}
// GetResult represents the result of a get operation.
type GetResult struct {
commonResult
}
// UpdateResult represents the result of an update operation.
type UpdateResult struct {
gophercloud.ErrResult
}
func (r commonResult) Extract() (*Node, error) {
if r.Err != nil {
return nil, r.Err
}
var response struct {
Node Node `mapstructure:"node"`
}
err := mapstructure.Decode(r.Body, &response)
return &response.Node, err
}
// NodeEvent represents a service event that occurred between a node and a
// load balancer.
type NodeEvent struct {
ID int
DetailedMessage string
NodeID int
Type string
Description string
Category string
Severity string
RelativeURI string
AccountID int
LoadBalancerID int
Title string
Author string
Created string
}
// NodeEventPage is a concrete type which embeds the common SinglePageBase
// struct, and is used when traversing node event collections.
type NodeEventPage struct {
pagination.SinglePageBase
}
// IsEmpty is a concrete function which indicates whether an NodeEventPage is
// empty or not.
func (r NodeEventPage) IsEmpty() (bool, error) {
is, err := ExtractNodeEvents(r)
if err != nil {
return true, err
}
return len(is) == 0, nil
}
// ExtractNodeEvents accepts a Page struct, specifically a NodeEventPage
// struct, and extracts the elements into a slice of NodeEvent structs. In
// other words, the collection is mapped into a relevant slice.
func ExtractNodeEvents(page pagination.Page) ([]NodeEvent, error) {
var resp struct {
Events []NodeEvent `mapstructure:"nodeServiceEvents" json:"nodeServiceEvents"`
}
err := mapstructure.Decode(page.(NodeEventPage).Body, &resp)
return resp.Events, err
}
|