blob: 2d57520b3561ef3ab44ba33c6750c485634a6769 [file] [log] [blame]
Jamie Hannafordfba65af2014-11-03 10:32:37 +01001package lbs
Jamie Hannaford186d4e22014-10-31 12:26:11 +01002
3import (
Jamie Hannaforde09b6822014-10-31 15:33:57 +01004 "errors"
5
Jamie Hannafordd78bb352014-11-07 16:36:09 +01006 "github.com/mitchellh/mapstructure"
Jamie Hannaforde09b6822014-10-31 15:33:57 +01007 "github.com/racker/perigee"
8
Jamie Hannaford186d4e22014-10-31 12:26:11 +01009 "github.com/rackspace/gophercloud"
10 "github.com/rackspace/gophercloud/pagination"
Jamie Hannaford940159d2014-11-03 13:04:08 +010011 "github.com/rackspace/gophercloud/rackspace/lb/v1"
Jamie Hannafordcfe2f282014-11-07 15:11:21 +010012 "github.com/rackspace/gophercloud/rackspace/lb/v1/acl"
13 "github.com/rackspace/gophercloud/rackspace/lb/v1/monitors"
Jamie Hannaford0a9a6be2014-11-03 12:55:38 +010014 "github.com/rackspace/gophercloud/rackspace/lb/v1/nodes"
Jamie Hannaford6bc93aa2014-11-06 12:37:52 +010015 "github.com/rackspace/gophercloud/rackspace/lb/v1/sessions"
Jamie Hannafordcfe2f282014-11-07 15:11:21 +010016 "github.com/rackspace/gophercloud/rackspace/lb/v1/throttle"
Jamie Hannaford1c817312014-11-04 10:56:58 +010017 "github.com/rackspace/gophercloud/rackspace/lb/v1/vips"
Jamie Hannaford186d4e22014-10-31 12:26:11 +010018)
19
Jamie Hannafordcfe2f282014-11-07 15:11:21 +010020var (
21 errNameRequired = errors.New("Name is a required attribute")
22 errTimeoutExceeded = errors.New("Timeout must be less than 120")
23)
24
Jamie Hannaford186d4e22014-10-31 12:26:11 +010025// ListOptsBuilder allows extensions to add additional parameters to the
26// List request.
27type ListOptsBuilder interface {
28 ToLBListQuery() (string, error)
29}
30
31// ListOpts allows the filtering and sorting of paginated collections through
32// the API.
33type ListOpts struct {
34 ChangesSince string `q:"changes-since"`
35 Status Status `q:"status"`
36 NodeAddr string `q:"nodeaddress"`
37 Marker string `q:"marker"`
38 Limit int `q:"limit"`
39}
40
41// ToLBListQuery formats a ListOpts into a query string.
42func (opts ListOpts) ToLBListQuery() (string, error) {
43 q, err := gophercloud.BuildQueryString(opts)
44 if err != nil {
45 return "", err
46 }
47 return q.String(), nil
48}
49
Jamie Hannafordb2007ee2014-11-03 16:24:43 +010050// List is the operation responsible for returning a paginated collection of
51// load balancers. You may pass in a ListOpts struct to filter results.
Jamie Hannaford186d4e22014-10-31 12:26:11 +010052func List(client *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager {
53 url := rootURL(client)
54 if opts != nil {
55 query, err := opts.ToLBListQuery()
56 if err != nil {
57 return pagination.Pager{Err: err}
58 }
59 url += query
60 }
61
62 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
63 return LBPage{pagination.LinkedPageBase{PageResult: r}}
64 })
65}
Jamie Hannaforde09b6822014-10-31 15:33:57 +010066
Jamie Hannaforde09b6822014-10-31 15:33:57 +010067// CreateOptsBuilder is the interface options structs have to satisfy in order
68// to be used in the main Create operation in this package. Since many
69// extensions decorate or modify the common logic, it is useful for them to
70// satisfy a basic interface in order for them to be used.
71type CreateOptsBuilder interface {
72 ToLBCreateMap() (map[string]interface{}, error)
73}
74
75// CreateOpts is the common options struct used in this package's Create
76// operation.
77type CreateOpts struct {
78 // Required - name of the load balancer to create. The name must be 128
79 // characters or fewer in length, and all UTF-8 characters are valid.
80 Name string
81
82 // Optional - nodes to be added.
Jamie Hannaford0a9a6be2014-11-03 12:55:38 +010083 Nodes []nodes.Node
Jamie Hannaforde09b6822014-10-31 15:33:57 +010084
85 // Required - protocol of the service that is being load balanced.
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +010086 // See http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/protocols.html
87 // for a full list of supported protocols.
88 Protocol string
Jamie Hannaforde09b6822014-10-31 15:33:57 +010089
90 // Optional - enables or disables Half-Closed support for the load balancer.
91 // Half-Closed support provides the ability for one end of the connection to
92 // terminate its output, while still receiving data from the other end. Only
93 // available for TCP/TCP_CLIENT_FIRST protocols.
Jamie Hannafordcfe2f282014-11-07 15:11:21 +010094 HalfClosed gophercloud.EnabledState
Jamie Hannaforde09b6822014-10-31 15:33:57 +010095
96 // Optional - the type of virtual IPs you want associated with the load
97 // balancer.
Jamie Hannaford1c817312014-11-04 10:56:58 +010098 VIPs []vips.VIP
Jamie Hannaforde09b6822014-10-31 15:33:57 +010099
100 // Optional - the access list management feature allows fine-grained network
101 // access controls to be applied to the load balancer virtual IP address.
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100102 AccessList *acl.AccessList
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100103
104 // Optional - algorithm that defines how traffic should be directed between
105 // back-end nodes.
Jamie Hannaford46336282014-11-04 14:48:20 +0100106 Algorithm string
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100107
108 // Optional - current connection logging configuration.
109 ConnectionLogging *ConnectionLogging
110
111 // Optional - specifies a limit on the number of connections per IP address
112 // to help mitigate malicious or abusive traffic to your applications.
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100113 ConnThrottle *throttle.ConnectionThrottle
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100114
Jamie Hannaforddfdf0a22014-11-12 11:06:45 +0100115 // Optional - the type of health monitor check to perform to ensure that the
116 // service is performing properly.
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100117 HealthMonitor *monitors.Monitor
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100118
119 // Optional - arbitrary information that can be associated with each LB.
120 Metadata map[string]interface{}
121
122 // Optional - port number for the service you are load balancing.
123 Port int
124
125 // Optional - the timeout value for the load balancer and communications with
126 // its nodes. Defaults to 30 seconds with a maximum of 120 seconds.
127 Timeout int
128
129 // Optional - specifies whether multiple requests from clients are directed
130 // to the same node.
Jamie Hannaford6bc93aa2014-11-06 12:37:52 +0100131 SessionPersistence *sessions.SessionPersistence
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100132
133 // Optional - enables or disables HTTP to HTTPS redirection for the load
134 // balancer. When enabled, any HTTP request returns status code 301 (Moved
135 // Permanently), and the requester is redirected to the requested URL via the
136 // HTTPS protocol on port 443. For example, http://example.com/page.html
137 // would be redirected to https://example.com/page.html. Only available for
138 // HTTPS protocol (port=443), or HTTP protocol with a properly configured SSL
139 // termination (secureTrafficOnly=true, securePort=443).
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100140 HTTPSRedirect gophercloud.EnabledState
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100141}
142
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100143// ToLBCreateMap casts a CreateOpts struct to a map.
144func (opts CreateOpts) ToLBCreateMap() (map[string]interface{}, error) {
145 lb := make(map[string]interface{})
146
147 if opts.Name == "" {
148 return lb, errNameRequired
149 }
150 if opts.Timeout > 120 {
151 return lb, errTimeoutExceeded
152 }
153
154 lb["name"] = opts.Name
155
156 if len(opts.Nodes) > 0 {
157 nodes := []map[string]interface{}{}
158 for _, n := range opts.Nodes {
159 nodes = append(nodes, map[string]interface{}{
160 "address": n.Address,
161 "port": n.Port,
162 "condition": n.Condition,
163 })
164 }
165 lb["nodes"] = nodes
166 }
167
168 if opts.Protocol != "" {
169 lb["protocol"] = opts.Protocol
170 }
171 if opts.HalfClosed != nil {
172 lb["halfClosed"] = opts.HalfClosed
173 }
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100174 if len(opts.VIPs) > 0 {
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100175 lb["virtualIps"] = opts.VIPs
176 }
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100177 if opts.AccessList != nil {
178 lb["accessList"] = &opts.AccessList
179 }
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100180 if opts.Algorithm != "" {
181 lb["algorithm"] = opts.Algorithm
182 }
183 if opts.ConnectionLogging != nil {
184 lb["connectionLogging"] = &opts.ConnectionLogging
185 }
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100186 if opts.ConnThrottle != nil {
187 lb["connectionThrottle"] = &opts.ConnThrottle
188 }
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100189 if opts.HealthMonitor != nil {
190 lb["healthMonitor"] = &opts.HealthMonitor
191 }
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100192 if len(opts.Metadata) != 0 {
193 lb["metadata"] = opts.Metadata
194 }
195 if opts.Port > 0 {
196 lb["port"] = opts.Port
197 }
198 if opts.Timeout > 0 {
199 lb["timeout"] = opts.Timeout
200 }
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100201 if opts.SessionPersistence != nil {
202 lb["sessionPersistence"] = &opts.SessionPersistence
203 }
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100204 if opts.HTTPSRedirect != nil {
205 lb["httpsRedirect"] = &opts.HTTPSRedirect
206 }
207
208 return map[string]interface{}{"loadBalancer": lb}, nil
209}
210
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100211// Create is the operation responsible for asynchronously provisioning a new
212// load balancer based on the configuration defined in CreateOpts. Once the
213// request is validated and progress has started on the provisioning process, a
214// response struct is returned. When extracted (with Extract()), you have
215// to the load balancer's unique ID and status.
216//
217// Once an ID is attained, you can check on the progress of the operation by
218// calling Get and passing in the ID. If the corresponding request cannot be
Jamie Hannaforddfdf0a22014-11-12 11:06:45 +0100219// fulfilled due to insufficient or invalid data, an HTTP 400 (Bad Request)
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100220// error response is returned with information regarding the nature of the
221// failure in the body of the response. Failures in the validation process are
222// non-recoverable and require the caller to correct the cause of the failure.
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100223func Create(c *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
224 var res CreateResult
225
226 reqBody, err := opts.ToLBCreateMap()
227 if err != nil {
228 res.Err = err
229 return res
230 }
231
232 _, res.Err = perigee.Request("POST", rootURL(c), perigee.Options{
233 MoreHeaders: c.AuthenticatedHeaders(),
234 ReqBody: &reqBody,
235 Results: &res.Body,
Jamie Hannafordd56375d2014-11-05 12:38:04 +0100236 OkCodes: []int{202},
Jamie Hannaforde09b6822014-10-31 15:33:57 +0100237 })
238
239 return res
240}
Jamie Hannaford1c260332014-10-31 15:57:22 +0100241
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100242// Get is the operation responsible for providing detailed information
243// regarding a specific load balancer which is configured and associated with
244// your account. This operation is not capable of returning details for a load
245// balancer which has been deleted.
Jamie Hannaford07c06962014-10-31 16:42:03 +0100246func Get(c *gophercloud.ServiceClient, id int) GetResult {
247 var res GetResult
248
249 _, res.Err = perigee.Request("GET", resourceURL(c, id), perigee.Options{
250 MoreHeaders: c.AuthenticatedHeaders(),
251 Results: &res.Body,
252 OkCodes: []int{200},
253 })
254
255 return res
256}
257
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100258// BulkDelete removes all the load balancers referenced in the slice of IDs.
Jamie Hannaforddfdf0a22014-11-12 11:06:45 +0100259// Any and all configuration data associated with these load balancers is
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100260// immediately purged and is not recoverable.
261//
262// If one of the items in the list cannot be removed due to its current status,
263// a 400 Bad Request error is returned along with the IDs of the ones the
264// system identified as potential failures for this request.
Jamie Hannaford1c260332014-10-31 15:57:22 +0100265func BulkDelete(c *gophercloud.ServiceClient, ids []int) DeleteResult {
266 var res DeleteResult
267
Jamie Hannaford0a9a6be2014-11-03 12:55:38 +0100268 if len(ids) > 10 || len(ids) == 0 {
269 res.Err = errors.New("You must provide a minimum of 1 and a maximum of 10 LB IDs")
270 return res
271 }
272
Jamie Hannaford1c260332014-10-31 15:57:22 +0100273 url := rootURL(c)
Jamie Hannaford940159d2014-11-03 13:04:08 +0100274 url += v1.IDSliceToQueryString("id", ids)
Jamie Hannaford1c260332014-10-31 15:57:22 +0100275
276 _, res.Err = perigee.Request("DELETE", url, perigee.Options{
277 MoreHeaders: c.AuthenticatedHeaders(),
278 OkCodes: []int{202},
279 })
280
281 return res
282}
Jamie Hannaford5f95e6a2014-10-31 16:13:44 +0100283
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100284// Delete removes a single load balancer.
Jamie Hannaford5f95e6a2014-10-31 16:13:44 +0100285func Delete(c *gophercloud.ServiceClient, id int) DeleteResult {
286 var res DeleteResult
287
288 _, res.Err = perigee.Request("DELETE", resourceURL(c, id), perigee.Options{
289 MoreHeaders: c.AuthenticatedHeaders(),
290 OkCodes: []int{202},
291 })
292
293 return res
294}
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100295
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100296// UpdateOptsBuilder represents a type that can be converted into a JSON-like
297// map structure.
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100298type UpdateOptsBuilder interface {
299 ToLBUpdateMap() (map[string]interface{}, error)
300}
301
Jamie Hannaforddfdf0a22014-11-12 11:06:45 +0100302// UpdateOpts represents the options for updating an existing load balancer.
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100303type UpdateOpts struct {
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100304 // Optional - new name of the load balancer.
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100305 Name string
306
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100307 // Optional - the new protocol you want your load balancer to have.
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +0100308 // See http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/protocols.html
309 // for a full list of supported protocols.
310 Protocol string
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100311
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100312 // Optional - see the HalfClosed field in CreateOpts for more information.
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100313 HalfClosed gophercloud.EnabledState
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100314
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100315 // Optional - see the Algorithm field in CreateOpts for more information.
Jamie Hannaford46336282014-11-04 14:48:20 +0100316 Algorithm string
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100317
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100318 // Optional - see the Port field in CreateOpts for more information.
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100319 Port int
320
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100321 // Optional - see the Timeout field in CreateOpts for more information.
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100322 Timeout int
323
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100324 // Optional - see the HTTPSRedirect field in CreateOpts for more information.
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100325 HTTPSRedirect gophercloud.EnabledState
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100326}
327
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100328// ToLBUpdateMap casts an UpdateOpts struct to a map.
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100329func (opts UpdateOpts) ToLBUpdateMap() (map[string]interface{}, error) {
330 lb := make(map[string]interface{})
331
332 if opts.Name != "" {
333 lb["name"] = opts.Name
334 }
335 if opts.Protocol != "" {
336 lb["protocol"] = opts.Protocol
337 }
338 if opts.HalfClosed != nil {
339 lb["halfClosed"] = opts.HalfClosed
340 }
341 if opts.Algorithm != "" {
342 lb["algorithm"] = opts.Algorithm
343 }
344 if opts.Port > 0 {
345 lb["port"] = opts.Port
346 }
347 if opts.Timeout > 0 {
348 lb["timeout"] = opts.Timeout
349 }
350 if opts.HTTPSRedirect != nil {
351 lb["httpsRedirect"] = &opts.HTTPSRedirect
352 }
353
354 return map[string]interface{}{"loadBalancer": lb}, nil
355}
356
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100357// Update is the operation responsible for asynchronously updating the
358// attributes of a specific load balancer. Upon successful validation of the
Jamie Hannaforddfdf0a22014-11-12 11:06:45 +0100359// request, the service returns a 202 Accepted response, and the load balancer
Jamie Hannafordb2007ee2014-11-03 16:24:43 +0100360// enters a PENDING_UPDATE state. A user can poll the load balancer with Get to
361// wait for the changes to be applied. When this happens, the load balancer will
362// return to an ACTIVE state.
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100363func Update(c *gophercloud.ServiceClient, id int, opts UpdateOptsBuilder) UpdateResult {
364 var res UpdateResult
365
366 reqBody, err := opts.ToLBUpdateMap()
367 if err != nil {
368 res.Err = err
369 return res
370 }
371
372 _, res.Err = perigee.Request("PUT", resourceURL(c, id), perigee.Options{
373 MoreHeaders: c.AuthenticatedHeaders(),
374 ReqBody: &reqBody,
Jamie Hannafordd56375d2014-11-05 12:38:04 +0100375 OkCodes: []int{202},
Jamie Hannaford76fcc832014-10-31 16:56:50 +0100376 })
377
378 return res
379}
Jamie Hannaford4ab9aea2014-11-04 14:38:06 +0100380
381// ListProtocols is the operation responsible for returning a paginated
382// collection of load balancer protocols.
383func ListProtocols(client *gophercloud.ServiceClient) pagination.Pager {
384 url := protocolsURL(client)
385 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
386 return ProtocolPage{pagination.SinglePageBase(r)}
387 })
388}
Jamie Hannaford46336282014-11-04 14:48:20 +0100389
390// ListAlgorithms is the operation responsible for returning a paginated
391// collection of load balancer algorithms.
392func ListAlgorithms(client *gophercloud.ServiceClient) pagination.Pager {
393 url := algorithmsURL(client)
394 return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
395 return AlgorithmPage{pagination.SinglePageBase(r)}
396 })
397}
Jamie Hannafordd78bb352014-11-07 16:36:09 +0100398
399// IsLoggingEnabled returns true if the load balancer has connection logging
400// enabled and false if not.
401func IsLoggingEnabled(client *gophercloud.ServiceClient, id int) (bool, error) {
402 var body interface{}
403
404 _, err := perigee.Request("GET", loggingURL(client, id), perigee.Options{
405 MoreHeaders: client.AuthenticatedHeaders(),
406 Results: &body,
407 OkCodes: []int{200},
408 })
409 if err != nil {
410 return false, err
411 }
412
413 var resp struct {
414 CL struct {
415 Enabled bool `mapstructure:"enabled"`
416 } `mapstructure:"connectionLogging"`
417 }
418
419 err = mapstructure.Decode(body, &resp)
420 return resp.CL.Enabled, err
421}
422
423func toConnLoggingMap(state bool) map[string]map[string]bool {
424 return map[string]map[string]bool{
Jamie Hannaford20b75882014-11-10 13:39:51 +0100425 "connectionLogging": map[string]bool{"enabled": state},
Jamie Hannafordd78bb352014-11-07 16:36:09 +0100426 }
427}
428
429// EnableLogging will enable connection logging for a specified load balancer.
430func EnableLogging(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult {
431 reqBody := toConnLoggingMap(true)
432 var res gophercloud.ErrResult
433
Jamie Hannaford20b75882014-11-10 13:39:51 +0100434 _, res.Err = perigee.Request("PUT", loggingURL(client, id), perigee.Options{
Jamie Hannafordd78bb352014-11-07 16:36:09 +0100435 MoreHeaders: client.AuthenticatedHeaders(),
436 ReqBody: &reqBody,
Jamie Hannafordb514bfd2014-11-10 15:39:15 +0100437 OkCodes: []int{202},
Jamie Hannafordd78bb352014-11-07 16:36:09 +0100438 })
439
440 return res
441}
442
443// DisableLogging will disable connection logging for a specified load balancer.
444func DisableLogging(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult {
445 reqBody := toConnLoggingMap(false)
446 var res gophercloud.ErrResult
447
Jamie Hannaford20b75882014-11-10 13:39:51 +0100448 _, res.Err = perigee.Request("PUT", loggingURL(client, id), perigee.Options{
Jamie Hannafordd78bb352014-11-07 16:36:09 +0100449 MoreHeaders: client.AuthenticatedHeaders(),
450 ReqBody: &reqBody,
Jamie Hannafordb514bfd2014-11-10 15:39:15 +0100451 OkCodes: []int{202},
Jamie Hannafordd78bb352014-11-07 16:36:09 +0100452 })
453
454 return res
455}
Jamie Hannafordda45b422014-11-10 11:00:38 +0100456
Jamie Hannaford3da65282014-11-10 11:36:16 +0100457// GetErrorPage will retrieve the current error page for the load balancer.
Jamie Hannafordda45b422014-11-10 11:00:38 +0100458func GetErrorPage(client *gophercloud.ServiceClient, id int) ErrorPageResult {
459 var res ErrorPageResult
460
461 _, res.Err = perigee.Request("GET", errorPageURL(client, id), perigee.Options{
462 MoreHeaders: client.AuthenticatedHeaders(),
463 Results: &res.Body,
464 OkCodes: []int{200},
465 })
466
467 return res
468}
469
Jamie Hannaford3da65282014-11-10 11:36:16 +0100470// SetErrorPage will set the HTML of the load balancer's error page to a
471// specific value.
Jamie Hannafordda45b422014-11-10 11:00:38 +0100472func SetErrorPage(client *gophercloud.ServiceClient, id int, html string) ErrorPageResult {
473 var res ErrorPageResult
474
475 type stringMap map[string]string
476 reqBody := map[string]stringMap{"errorpage": stringMap{"content": html}}
477
478 _, res.Err = perigee.Request("PUT", errorPageURL(client, id), perigee.Options{
479 MoreHeaders: client.AuthenticatedHeaders(),
480 Results: &res.Body,
481 ReqBody: &reqBody,
482 OkCodes: []int{200},
483 })
484
485 return res
486}
487
Jamie Hannaford3da65282014-11-10 11:36:16 +0100488// DeleteErrorPage will delete the current error page for the load balancer.
Jamie Hannafordda45b422014-11-10 11:00:38 +0100489func DeleteErrorPage(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult {
490 var res gophercloud.ErrResult
491
492 _, res.Err = perigee.Request("DELETE", errorPageURL(client, id), perigee.Options{
493 MoreHeaders: client.AuthenticatedHeaders(),
494 OkCodes: []int{200},
495 })
496
497 return res
498}
Jamie Hannaford3da65282014-11-10 11:36:16 +0100499
500// GetStats will retrieve detailed stats related to the load balancer's usage.
501func GetStats(client *gophercloud.ServiceClient, id int) StatsResult {
502 var res StatsResult
503
504 _, res.Err = perigee.Request("GET", statsURL(client, id), perigee.Options{
505 MoreHeaders: client.AuthenticatedHeaders(),
506 Results: &res.Body,
507 OkCodes: []int{200},
508 })
509
510 return res
511}
Jamie Hannaford20b75882014-11-10 13:39:51 +0100512
Jamie Hannafordb514bfd2014-11-10 15:39:15 +0100513// IsContentCached will check to see whether the specified load balancer caches
514// content. When content caching is enabled, recently-accessed files are stored
515// on the load balancer for easy retrieval by web clients. Content caching
516// improves the performance of high traffic web sites by temporarily storing
517// data that was recently accessed. While it's cached, requests for that data
518// are served by the load balancer, which in turn reduces load off the back end
519// nodes. The result is improved response times for those requests and less
520// load on the web server.
Jamie Hannaford20b75882014-11-10 13:39:51 +0100521func IsContentCached(client *gophercloud.ServiceClient, id int) (bool, error) {
522 var body interface{}
523
524 _, err := perigee.Request("GET", cacheURL(client, id), perigee.Options{
525 MoreHeaders: client.AuthenticatedHeaders(),
526 Results: &body,
527 OkCodes: []int{200},
528 })
529 if err != nil {
530 return false, err
531 }
532
533 var resp struct {
534 CC struct {
535 Enabled bool `mapstructure:"enabled"`
536 } `mapstructure:"contentCaching"`
537 }
538
539 err = mapstructure.Decode(body, &resp)
540 return resp.CC.Enabled, err
541}
542
543func toCachingMap(state bool) map[string]map[string]bool {
544 return map[string]map[string]bool{
545 "contentCaching": map[string]bool{"enabled": state},
546 }
547}
548
Jamie Hannafordb514bfd2014-11-10 15:39:15 +0100549// EnableCaching will enable content-caching for the specified load balancer.
Jamie Hannaford20b75882014-11-10 13:39:51 +0100550func EnableCaching(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult {
551 reqBody := toCachingMap(true)
552 var res gophercloud.ErrResult
553
554 _, res.Err = perigee.Request("PUT", cacheURL(client, id), perigee.Options{
555 MoreHeaders: client.AuthenticatedHeaders(),
556 ReqBody: &reqBody,
Jamie Hannafordb514bfd2014-11-10 15:39:15 +0100557 OkCodes: []int{202},
Jamie Hannaford20b75882014-11-10 13:39:51 +0100558 })
559
560 return res
561}
562
Jamie Hannafordb514bfd2014-11-10 15:39:15 +0100563// DisableCaching will disable content-caching for the specified load balancer.
Jamie Hannaford20b75882014-11-10 13:39:51 +0100564func DisableCaching(client *gophercloud.ServiceClient, id int) gophercloud.ErrResult {
565 reqBody := toCachingMap(false)
566 var res gophercloud.ErrResult
567
568 _, res.Err = perigee.Request("PUT", cacheURL(client, id), perigee.Options{
569 MoreHeaders: client.AuthenticatedHeaders(),
570 ReqBody: &reqBody,
Jamie Hannafordb514bfd2014-11-10 15:39:15 +0100571 OkCodes: []int{202},
Jamie Hannaford20b75882014-11-10 13:39:51 +0100572 })
573
574 return res
575}