blob: 98f3962d77ecb0e9890841eb565db123d9b734fd [file] [log] [blame]
Jamie Hannafordfba65af2014-11-03 10:32:37 +01001package lbs
Jamie Hannaford186d4e22014-10-31 12:26:11 +01002
3import (
Jamie Hannaford4d398ff2014-11-14 11:03:00 +01004 "reflect"
5 "time"
6
Jamie Hannaford186d4e22014-10-31 12:26:11 +01007 "github.com/mitchellh/mapstructure"
Jamie Hannaforde09b6822014-10-31 15:33:57 +01008
9 "github.com/rackspace/gophercloud"
Jamie Hannaford186d4e22014-10-31 12:26:11 +010010 "github.com/rackspace/gophercloud/pagination"
Jamie Hannafordcfe2f282014-11-07 15:11:21 +010011 "github.com/rackspace/gophercloud/rackspace/lb/v1/acl"
Jamie Hannaford21a3eb12014-11-03 10:34:29 +010012 "github.com/rackspace/gophercloud/rackspace/lb/v1/nodes"
Jamie Hannaford6bc93aa2014-11-06 12:37:52 +010013 "github.com/rackspace/gophercloud/rackspace/lb/v1/sessions"
Jamie Hannafordcfe2f282014-11-07 15:11:21 +010014 "github.com/rackspace/gophercloud/rackspace/lb/v1/throttle"
Jamie Hannaford1c817312014-11-04 10:56:58 +010015 "github.com/rackspace/gophercloud/rackspace/lb/v1/vips"
Jamie Hannaford186d4e22014-10-31 12:26:11 +010016)
17
Jamie Hannafordb2007ee2014-11-03 16:24:43 +010018// Protocol represents the network protocol which the load balancer accepts.
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +010019type Protocol struct {
20 // The name of the protocol, e.g. HTTP, LDAP, FTP, etc.
21 Name string
Jamie Hannaford186d4e22014-10-31 12:26:11 +010022
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +010023 // The port number for the protocol.
24 Port int
25}
Jamie Hannaford186d4e22014-10-31 12:26:11 +010026
27// Algorithm defines how traffic should be directed between back-end nodes.
Jamie Hannaford46336282014-11-04 14:48:20 +010028type Algorithm struct {
29 // The name of the algorithm, e.g RANDOM, ROUND_ROBIN, etc.
30 Name string
31}
Jamie Hannaford186d4e22014-10-31 12:26:11 +010032
Jamie Hannafordb2007ee2014-11-03 16:24:43 +010033// Status represents the potential state of a load balancer resource.
Jamie Hannaford186d4e22014-10-31 12:26:11 +010034type Status string
35
36const (
37 // ACTIVE indicates that the LB is configured properly and ready to serve
38 // traffic to incoming requests via the configured virtual IPs.
Jamie Hannaford227d9592014-11-13 10:32:07 +010039 ACTIVE Status = "ACTIVE"
Jamie Hannaford186d4e22014-10-31 12:26:11 +010040
41 // BUILD indicates that the LB is being provisioned for the first time and
42 // configuration is being applied to bring the service online. The service
43 // cannot yet serve incoming requests.
Jamie Hannaford227d9592014-11-13 10:32:07 +010044 BUILD Status = "BUILD"
Jamie Hannaford186d4e22014-10-31 12:26:11 +010045
46 // PENDINGUPDATE indicates that the LB is online but configuration changes
47 // are being applied to update the service based on a previous request.
Jamie Hannaford227d9592014-11-13 10:32:07 +010048 PENDINGUPDATE Status = "PENDING_UPDATE"
Jamie Hannaford186d4e22014-10-31 12:26:11 +010049
50 // PENDINGDELETE indicates that the LB is online but configuration changes
51 // are being applied to begin deletion of the service based on a previous
52 // request.
Jamie Hannaford227d9592014-11-13 10:32:07 +010053 PENDINGDELETE Status = "PENDING_DELETE"
Jamie Hannaford186d4e22014-10-31 12:26:11 +010054
55 // SUSPENDED indicates that the LB has been taken offline and disabled.
Jamie Hannaford227d9592014-11-13 10:32:07 +010056 SUSPENDED Status = "SUSPENDED"
Jamie Hannaford186d4e22014-10-31 12:26:11 +010057
58 // ERROR indicates that the system encountered an error when attempting to
59 // configure the load balancer.
Jamie Hannaford227d9592014-11-13 10:32:07 +010060 ERROR Status = "ERROR"
Jamie Hannaford186d4e22014-10-31 12:26:11 +010061
62 // DELETED indicates that the LB has been deleted.
Jamie Hannaford227d9592014-11-13 10:32:07 +010063 DELETED Status = "DELETED"
Jamie Hannaford186d4e22014-10-31 12:26:11 +010064)
65
Jamie Hannafordb2007ee2014-11-03 16:24:43 +010066// Datetime represents the structure of a Created or Updated field.
Jamie Hannaford186d4e22014-10-31 12:26:11 +010067type Datetime struct {
Jamie Hannaford4d398ff2014-11-14 11:03:00 +010068 Time time.Time `mapstructure:"-"`
Jamie Hannaford186d4e22014-10-31 12:26:11 +010069}
70
Jamie Hannafordb2007ee2014-11-03 16:24:43 +010071// LoadBalancer represents a load balancer API resource.
Jamie Hannaford186d4e22014-10-31 12:26:11 +010072type LoadBalancer struct {
73 // Human-readable name for the load balancer.
74 Name string
75
76 // The unique ID for the load balancer.
77 ID int
78
Jamie Hannafordb2007ee2014-11-03 16:24:43 +010079 // Represents the service protocol being load balanced. See Protocol type for
80 // a list of accepted values.
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +010081 // See http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/protocols.html
82 // for a full list of supported protocols.
83 Protocol string
Jamie Hannaford186d4e22014-10-31 12:26:11 +010084
85 // Defines how traffic should be directed between back-end nodes. The default
Jamie Hannafordb2007ee2014-11-03 16:24:43 +010086 // algorithm is RANDOM. See Algorithm type for a list of accepted values.
Jamie Hannaford46336282014-11-04 14:48:20 +010087 Algorithm string
Jamie Hannaford186d4e22014-10-31 12:26:11 +010088
89 // The current status of the load balancer.
90 Status Status
91
92 // The number of load balancer nodes.
93 NodeCount int `mapstructure:"nodeCount"`
94
95 // Slice of virtual IPs associated with this load balancer.
Jamie Hannaford1c817312014-11-04 10:56:58 +010096 VIPs []vips.VIP `mapstructure:"virtualIps"`
Jamie Hannaford186d4e22014-10-31 12:26:11 +010097
98 // Datetime when the LB was created.
99 Created Datetime
100
101 // Datetime when the LB was created.
102 Updated Datetime
103
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100104 // Port number for the service you are load balancing.
Jamie Hannaford186d4e22014-10-31 12:26:11 +0100105 Port int
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100106
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100107 // HalfClosed provides the ability for one end of the connection to
108 // terminate its output while still receiving data from the other end. This
109 // is only available on TCP/TCP_CLIENT_FIRST protocols.
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100110 HalfClosed bool
111
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100112 // Timeout represents the timeout value between a load balancer and its
113 // nodes. Defaults to 30 seconds with a maximum of 120 seconds.
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100114 Timeout int
115
Jamie Hannaford227d9592014-11-13 10:32:07 +0100116 // The cluster name.
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100117 Cluster Cluster
118
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100119 // Nodes shows all the back-end nodes which are associated with the load
120 // balancer. These are the devices which are delivered traffic.
Jamie Hannaford21a3eb12014-11-03 10:34:29 +0100121 Nodes []nodes.Node
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100122
Jamie Hannaford227d9592014-11-13 10:32:07 +0100123 // Current connection logging configuration.
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100124 ConnectionLogging ConnectionLogging
Jamie Hannaford07c06962014-10-31 16:42:03 +0100125
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100126 // SessionPersistence specifies whether multiple requests from clients are
127 // directed to the same node.
Jamie Hannaford6bc93aa2014-11-06 12:37:52 +0100128 SessionPersistence sessions.SessionPersistence
Jamie Hannaford07c06962014-10-31 16:42:03 +0100129
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100130 // ConnectionThrottle specifies a limit on the number of connections per IP
131 // address to help mitigate malicious or abusive traffic to your applications.
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100132 ConnectionThrottle throttle.ConnectionThrottle
Jamie Hannaford07c06962014-10-31 16:42:03 +0100133
Jamie Hannaford227d9592014-11-13 10:32:07 +0100134 // The source public and private IP addresses.
Jamie Hannaford07c06962014-10-31 16:42:03 +0100135 SourceAddrs SourceAddrs `mapstructure:"sourceAddresses"`
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100136
137 // Represents the access rules for this particular load balancer. IP addresses
138 // or subnet ranges, depending on their type (ALLOW or DENY), can be permitted
139 // or blocked.
140 AccessList acl.AccessList
Jamie Hannaford07c06962014-10-31 16:42:03 +0100141}
142
Jamie Hannaford227d9592014-11-13 10:32:07 +0100143// SourceAddrs represents the source public and private IP addresses.
Jamie Hannaford07c06962014-10-31 16:42:03 +0100144type SourceAddrs struct {
145 IPv4Public string `json:"ipv4Public" mapstructure:"ipv4Public"`
146 IPv4Private string `json:"ipv4Servicenet" mapstructure:"ipv4Servicenet"`
147 IPv6Public string `json:"ipv6Public" mapstructure:"ipv6Public"`
148 IPv6Private string `json:"ipv6Servicenet" mapstructure:"ipv6Servicenet"`
149}
150
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100151// ConnectionLogging - temp
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100152type ConnectionLogging struct {
153 Enabled bool
154}
155
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100156// Cluster - temp
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100157type Cluster struct {
158 Name string
159}
160
Jamie Hannaford186d4e22014-10-31 12:26:11 +0100161// LBPage is the page returned by a pager when traversing over a collection of
162// LBs.
163type LBPage struct {
164 pagination.LinkedPageBase
165}
166
167// IsEmpty checks whether a NetworkPage struct is empty.
168func (p LBPage) IsEmpty() (bool, error) {
169 is, err := ExtractLBs(p)
170 if err != nil {
171 return true, nil
172 }
173 return len(is) == 0, nil
174}
175
176// ExtractLBs accepts a Page struct, specifically a LBPage struct, and extracts
177// the elements into a slice of LoadBalancer structs. In other words, a generic
178// collection is mapped into a relevant slice.
179func ExtractLBs(page pagination.Page) ([]LoadBalancer, error) {
180 var resp struct {
181 LBs []LoadBalancer `mapstructure:"loadBalancers" json:"loadBalancers"`
182 }
183
Jamie Hannaford4d398ff2014-11-14 11:03:00 +0100184 coll := page.(LBPage).Body
185 err := mapstructure.Decode(coll, &resp)
186
187 s := reflect.ValueOf(coll.(map[string]interface{})["loadBalancers"])
188
189 for i := 0; i < s.Len(); i++ {
190 val := (s.Index(i).Interface()).(map[string]interface{})
191
192 ts, err := extractTS(val, "created")
193 if err != nil {
194 return resp.LBs, err
195 }
196 resp.LBs[i].Created.Time = ts
197
198 ts, err = extractTS(val, "updated")
199 if err != nil {
200 return resp.LBs, err
201 }
202 resp.LBs[i].Updated.Time = ts
203 }
Jamie Hannaford186d4e22014-10-31 12:26:11 +0100204
205 return resp.LBs, err
206}
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100207
Jamie Hannaford4d398ff2014-11-14 11:03:00 +0100208func extractTS(body map[string]interface{}, key string) (time.Time, error) {
209 val := body[key].(map[string]interface{})
Jamie Hannaforda587fb02014-11-14 11:09:23 +0100210 return time.Parse(time.RFC3339, val["time"].(string))
Jamie Hannaford4d398ff2014-11-14 11:03:00 +0100211}
212
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100213type commonResult struct {
214 gophercloud.Result
215}
216
217// Extract interprets any commonResult as a LB, if possible.
218func (r commonResult) Extract() (*LoadBalancer, error) {
219 if r.Err != nil {
220 return nil, r.Err
221 }
222
223 var response struct {
224 LB LoadBalancer `mapstructure:"loadBalancer"`
225 }
226
227 err := mapstructure.Decode(r.Body, &response)
228
Jamie Hannaford4d398ff2014-11-14 11:03:00 +0100229 json := r.Body.(map[string]interface{})
230 lb := json["loadBalancer"].(map[string]interface{})
231
232 ts, err := extractTS(lb, "created")
233 if err != nil {
234 return nil, err
235 }
236 response.LB.Created.Time = ts
237
238 ts, err = extractTS(lb, "updated")
239 if err != nil {
240 return nil, err
241 }
242 response.LB.Updated.Time = ts
243
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100244 return &response.LB, err
245}
246
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100247// CreateResult represents the result of a create operation.
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100248type CreateResult struct {
249 commonResult
250}
Jamie Hannaford1c260332014-10-31 15:57:22 +0100251
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100252// DeleteResult represents the result of a delete operation.
Jamie Hannaford1c260332014-10-31 15:57:22 +0100253type DeleteResult struct {
254 gophercloud.ErrResult
255}
Jamie Hannaford07c06962014-10-31 16:42:03 +0100256
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100257// UpdateResult represents the result of an update operation.
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100258type UpdateResult struct {
259 gophercloud.ErrResult
260}
261
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100262// GetResult represents the result of a get operation.
Jamie Hannaford07c06962014-10-31 16:42:03 +0100263type GetResult struct {
264 commonResult
265}
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +0100266
267// ProtocolPage is the page returned by a pager when traversing over a
268// collection of LB protocols.
269type ProtocolPage struct {
270 pagination.SinglePageBase
271}
272
273// IsEmpty checks whether a ProtocolPage struct is empty.
274func (p ProtocolPage) IsEmpty() (bool, error) {
275 is, err := ExtractProtocols(p)
276 if err != nil {
277 return true, nil
278 }
279 return len(is) == 0, nil
280}
281
282// ExtractProtocols accepts a Page struct, specifically a ProtocolPage struct,
Jamie Hannaford227d9592014-11-13 10:32:07 +0100283// and extracts the elements into a slice of Protocol structs. In other
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +0100284// words, a generic collection is mapped into a relevant slice.
285func ExtractProtocols(page pagination.Page) ([]Protocol, error) {
286 var resp struct {
287 Protocols []Protocol `mapstructure:"protocols" json:"protocols"`
288 }
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +0100289 err := mapstructure.Decode(page.(ProtocolPage).Body, &resp)
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +0100290 return resp.Protocols, err
291}
Jamie Hannaford46336282014-11-04 14:48:20 +0100292
293// AlgorithmPage is the page returned by a pager when traversing over a
294// collection of LB algorithms.
295type AlgorithmPage struct {
296 pagination.SinglePageBase
297}
298
Jamie Hannaford227d9592014-11-13 10:32:07 +0100299// IsEmpty checks whether an AlgorithmPage struct is empty.
Jamie Hannaford46336282014-11-04 14:48:20 +0100300func (p AlgorithmPage) IsEmpty() (bool, error) {
301 is, err := ExtractAlgorithms(p)
302 if err != nil {
303 return true, nil
304 }
305 return len(is) == 0, nil
306}
307
Alex Gaynorba186082014-11-18 07:51:18 -0800308// ExtractAlgorithms accepts a Page struct, specifically an AlgorithmPage struct,
Jamie Hannaford46336282014-11-04 14:48:20 +0100309// and extracts the elements into a slice of Algorithm structs. In other
310// words, a generic collection is mapped into a relevant slice.
311func ExtractAlgorithms(page pagination.Page) ([]Algorithm, error) {
312 var resp struct {
313 Algorithms []Algorithm `mapstructure:"algorithms" json:"algorithms"`
314 }
315 err := mapstructure.Decode(page.(AlgorithmPage).Body, &resp)
316 return resp.Algorithms, err
317}
Jamie Hannafordda45b422014-11-10 11:00:38 +0100318
319// ErrorPage represents the HTML file that is shown to an end user who is
320// attempting to access a load balancer node that is offline/unavailable.
321//
322// During provisioning, every load balancer is configured with a default error
323// page that gets displayed when traffic is requested for an offline node.
324//
325// You can add a single custom error page with an HTTP-based protocol to a load
326// balancer. Page updates override existing content. If a custom error page is
327// deleted, or the load balancer is changed to a non-HTTP protocol, the default
328// error page is restored.
329type ErrorPage struct {
330 Content string
331}
332
333// ErrorPageResult represents the result of an error page operation -
334// specifically getting or creating one.
335type ErrorPageResult struct {
336 gophercloud.Result
337}
338
339// Extract interprets any commonResult as an ErrorPage, if possible.
340func (r ErrorPageResult) Extract() (*ErrorPage, error) {
341 if r.Err != nil {
342 return nil, r.Err
343 }
344
345 var response struct {
346 ErrorPage ErrorPage `mapstructure:"errorpage"`
347 }
348
349 err := mapstructure.Decode(r.Body, &response)
350
351 return &response.ErrorPage, err
352}
Jamie Hannaford3da65282014-11-10 11:36:16 +0100353
354// Stats represents all the key information about a load balancer's usage.
355type Stats struct {
356 // The number of connections closed by this load balancer because its
357 // ConnectTimeout interval was exceeded.
358 ConnectTimeout int `mapstructure:"connectTimeOut"`
359
360 // The number of transaction or protocol errors for this load balancer.
361 ConnectError int
362
363 // Number of connection failures for this load balancer.
364 ConnectFailure int
365
366 // Number of connections closed by this load balancer because its Timeout
367 // interval was exceeded.
368 DataTimedOut int
369
370 // Number of connections closed by this load balancer because the
371 // 'keepalive_timeout' interval was exceeded.
372 KeepAliveTimedOut int
373
374 // The maximum number of simultaneous TCP connections this load balancer has
375 // processed at any one time.
376 MaxConnections int `mapstructure:"maxConn"`
377
378 // Number of simultaneous connections active at the time of the request.
379 CurrentConnections int `mapstructure:"currentConn"`
380
381 // Number of SSL connections closed by this load balancer because the
382 // ConnectTimeout interval was exceeded.
383 SSLConnectTimeout int `mapstructure:"connectTimeOutSsl"`
384
385 // Number of SSL transaction or protocol erros in this load balancer.
386 SSLConnectError int `mapstructure:"connectErrorSsl"`
387
388 // Number of SSL connection failures in this load balancer.
389 SSLConnectFailure int `mapstructure:"connectFailureSsl"`
390
391 // Number of SSL connections closed by this load balancer because the
392 // Timeout interval was exceeded.
393 SSLDataTimedOut int `mapstructure:"dataTimedOutSsl"`
394
395 // Number of SSL connections closed by this load balancer because the
396 // 'keepalive_timeout' interval was exceeded.
397 SSLKeepAliveTimedOut int `mapstructure:"keepAliveTimedOutSsl"`
398
399 // Maximum number of simultaneous SSL connections this load balancer has
Alex Gaynorba186082014-11-18 07:51:18 -0800400 // processed at any one time.
Jamie Hannaford3da65282014-11-10 11:36:16 +0100401 SSLMaxConnections int `mapstructure:"maxConnSsl"`
402
403 // Number of simultaneous SSL connections active at the time of the request.
404 SSLCurrentConnections int `mapstructure:"currentConnSsl"`
405}
406
Jamie Hannaford227d9592014-11-13 10:32:07 +0100407// StatsResult represents the result of a Stats operation.
Jamie Hannaford3da65282014-11-10 11:36:16 +0100408type StatsResult struct {
409 gophercloud.Result
410}
411
412// Extract interprets any commonResult as a Stats struct, if possible.
413func (r StatsResult) Extract() (*Stats, error) {
414 if r.Err != nil {
415 return nil, r.Err
416 }
417 res := &Stats{}
418 err := mapstructure.Decode(r.Body, res)
419 return res, err
420}