blob: 7367f3aee9cc08097e4ec3eb6f3bef24bb380045 [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{})
210 ts, err := time.Parse(time.RFC3339, val["time"].(string))
211
212 return ts, err
213}
214
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100215type commonResult struct {
216 gophercloud.Result
217}
218
219// Extract interprets any commonResult as a LB, if possible.
220func (r commonResult) Extract() (*LoadBalancer, error) {
221 if r.Err != nil {
222 return nil, r.Err
223 }
224
225 var response struct {
226 LB LoadBalancer `mapstructure:"loadBalancer"`
227 }
228
229 err := mapstructure.Decode(r.Body, &response)
230
Jamie Hannaford4d398ff2014-11-14 11:03:00 +0100231 json := r.Body.(map[string]interface{})
232 lb := json["loadBalancer"].(map[string]interface{})
233
234 ts, err := extractTS(lb, "created")
235 if err != nil {
236 return nil, err
237 }
238 response.LB.Created.Time = ts
239
240 ts, err = extractTS(lb, "updated")
241 if err != nil {
242 return nil, err
243 }
244 response.LB.Updated.Time = ts
245
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100246 return &response.LB, err
247}
248
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100249// CreateResult represents the result of a create operation.
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100250type CreateResult struct {
251 commonResult
252}
Jamie Hannaford1c260332014-10-31 15:57:22 +0100253
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100254// DeleteResult represents the result of a delete operation.
Jamie Hannaford1c260332014-10-31 15:57:22 +0100255type DeleteResult struct {
256 gophercloud.ErrResult
257}
Jamie Hannaford07c06962014-10-31 16:42:03 +0100258
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100259// UpdateResult represents the result of an update operation.
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100260type UpdateResult struct {
261 gophercloud.ErrResult
262}
263
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100264// GetResult represents the result of a get operation.
Jamie Hannaford07c06962014-10-31 16:42:03 +0100265type GetResult struct {
266 commonResult
267}
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +0100268
269// ProtocolPage is the page returned by a pager when traversing over a
270// collection of LB protocols.
271type ProtocolPage struct {
272 pagination.SinglePageBase
273}
274
275// IsEmpty checks whether a ProtocolPage struct is empty.
276func (p ProtocolPage) IsEmpty() (bool, error) {
277 is, err := ExtractProtocols(p)
278 if err != nil {
279 return true, nil
280 }
281 return len(is) == 0, nil
282}
283
284// ExtractProtocols accepts a Page struct, specifically a ProtocolPage struct,
Jamie Hannaford227d9592014-11-13 10:32:07 +0100285// and extracts the elements into a slice of Protocol structs. In other
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +0100286// words, a generic collection is mapped into a relevant slice.
287func ExtractProtocols(page pagination.Page) ([]Protocol, error) {
288 var resp struct {
289 Protocols []Protocol `mapstructure:"protocols" json:"protocols"`
290 }
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +0100291 err := mapstructure.Decode(page.(ProtocolPage).Body, &resp)
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +0100292 return resp.Protocols, err
293}
Jamie Hannaford46336282014-11-04 14:48:20 +0100294
295// AlgorithmPage is the page returned by a pager when traversing over a
296// collection of LB algorithms.
297type AlgorithmPage struct {
298 pagination.SinglePageBase
299}
300
Jamie Hannaford227d9592014-11-13 10:32:07 +0100301// IsEmpty checks whether an AlgorithmPage struct is empty.
Jamie Hannaford46336282014-11-04 14:48:20 +0100302func (p AlgorithmPage) IsEmpty() (bool, error) {
303 is, err := ExtractAlgorithms(p)
304 if err != nil {
305 return true, nil
306 }
307 return len(is) == 0, nil
308}
309
310// ExtractAlgorithms accepts a Page struct, specifically a AlgorithmPage struct,
311// and extracts the elements into a slice of Algorithm structs. In other
312// words, a generic collection is mapped into a relevant slice.
313func ExtractAlgorithms(page pagination.Page) ([]Algorithm, error) {
314 var resp struct {
315 Algorithms []Algorithm `mapstructure:"algorithms" json:"algorithms"`
316 }
317 err := mapstructure.Decode(page.(AlgorithmPage).Body, &resp)
318 return resp.Algorithms, err
319}
Jamie Hannafordda45b422014-11-10 11:00:38 +0100320
321// ErrorPage represents the HTML file that is shown to an end user who is
322// attempting to access a load balancer node that is offline/unavailable.
323//
324// During provisioning, every load balancer is configured with a default error
325// page that gets displayed when traffic is requested for an offline node.
326//
327// You can add a single custom error page with an HTTP-based protocol to a load
328// balancer. Page updates override existing content. If a custom error page is
329// deleted, or the load balancer is changed to a non-HTTP protocol, the default
330// error page is restored.
331type ErrorPage struct {
332 Content string
333}
334
335// ErrorPageResult represents the result of an error page operation -
336// specifically getting or creating one.
337type ErrorPageResult struct {
338 gophercloud.Result
339}
340
341// Extract interprets any commonResult as an ErrorPage, if possible.
342func (r ErrorPageResult) Extract() (*ErrorPage, error) {
343 if r.Err != nil {
344 return nil, r.Err
345 }
346
347 var response struct {
348 ErrorPage ErrorPage `mapstructure:"errorpage"`
349 }
350
351 err := mapstructure.Decode(r.Body, &response)
352
353 return &response.ErrorPage, err
354}
Jamie Hannaford3da65282014-11-10 11:36:16 +0100355
356// Stats represents all the key information about a load balancer's usage.
357type Stats struct {
358 // The number of connections closed by this load balancer because its
359 // ConnectTimeout interval was exceeded.
360 ConnectTimeout int `mapstructure:"connectTimeOut"`
361
362 // The number of transaction or protocol errors for this load balancer.
363 ConnectError int
364
365 // Number of connection failures for this load balancer.
366 ConnectFailure int
367
368 // Number of connections closed by this load balancer because its Timeout
369 // interval was exceeded.
370 DataTimedOut int
371
372 // Number of connections closed by this load balancer because the
373 // 'keepalive_timeout' interval was exceeded.
374 KeepAliveTimedOut int
375
376 // The maximum number of simultaneous TCP connections this load balancer has
377 // processed at any one time.
378 MaxConnections int `mapstructure:"maxConn"`
379
380 // Number of simultaneous connections active at the time of the request.
381 CurrentConnections int `mapstructure:"currentConn"`
382
383 // Number of SSL connections closed by this load balancer because the
384 // ConnectTimeout interval was exceeded.
385 SSLConnectTimeout int `mapstructure:"connectTimeOutSsl"`
386
387 // Number of SSL transaction or protocol erros in this load balancer.
388 SSLConnectError int `mapstructure:"connectErrorSsl"`
389
390 // Number of SSL connection failures in this load balancer.
391 SSLConnectFailure int `mapstructure:"connectFailureSsl"`
392
393 // Number of SSL connections closed by this load balancer because the
394 // Timeout interval was exceeded.
395 SSLDataTimedOut int `mapstructure:"dataTimedOutSsl"`
396
397 // Number of SSL connections closed by this load balancer because the
398 // 'keepalive_timeout' interval was exceeded.
399 SSLKeepAliveTimedOut int `mapstructure:"keepAliveTimedOutSsl"`
400
401 // Maximum number of simultaneous SSL connections this load balancer has
402 // processed a any one time.
403 SSLMaxConnections int `mapstructure:"maxConnSsl"`
404
405 // Number of simultaneous SSL connections active at the time of the request.
406 SSLCurrentConnections int `mapstructure:"currentConnSsl"`
407}
408
Jamie Hannaford227d9592014-11-13 10:32:07 +0100409// StatsResult represents the result of a Stats operation.
Jamie Hannaford3da65282014-11-10 11:36:16 +0100410type StatsResult struct {
411 gophercloud.Result
412}
413
414// Extract interprets any commonResult as a Stats struct, if possible.
415func (r StatsResult) Extract() (*Stats, error) {
416 if r.Err != nil {
417 return nil, r.Err
418 }
419 res := &Stats{}
420 err := mapstructure.Decode(r.Body, res)
421 return res, err
422}