forked from kubernetes/kubernetes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
results.go
213 lines (173 loc) · 5.97 KB
/
results.go
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
}