blob: aa6ec5b3c816f3037418cad2a9c7eb95f4f44da6 [file] [log] [blame]
Jamie Hannaford7afb7af2014-11-04 13:32:20 +01001package monitors
2
3import (
4 "errors"
5
6 "github.com/racker/perigee"
7
8 "github.com/rackspace/gophercloud"
Jamie Hannafordcfe2f282014-11-07 15:11:21 +01009 "github.com/rackspace/gophercloud/rackspace/lb/v1"
10)
11
12var (
13 errAttemptLimit = errors.New("AttemptLimit field must be an int greater than 1 and less than 10")
14 errDelay = errors.New("Delay field must be an int greater than 1 and less than 10")
15 errTimeout = errors.New("Timeout field must be an int greater than 1 and less than 10")
Jamie Hannaford7afb7af2014-11-04 13:32:20 +010016)
17
18// UpdateOptsBuilder is the interface options structs have to satisfy in order
19// to be used in the main Update operation in this package.
20type UpdateOptsBuilder interface {
21 ToMonitorUpdateMap() (map[string]interface{}, error)
22}
23
24// UpdateConnectMonitorOpts represents the options needed to update a CONNECT
25// monitor.
26type UpdateConnectMonitorOpts struct {
27 // Required - number of permissible monitor failures before removing a node
28 // from rotation. Must be a number between 1 and 10.
29 AttemptLimit int
30
31 // Required - the minimum number of seconds to wait before executing the
32 // health monitor. Must be a number between 1 and 3600.
33 Delay int
34
35 // Required - maximum number of seconds to wait for a connection to be
36 // established before timing out. Must be a number between 1 and 300.
37 Timeout int
38}
39
Jamie Hannaford7afb7af2014-11-04 13:32:20 +010040// ToMonitorUpdateMap produces a map for updating CONNECT monitors.
41func (opts UpdateConnectMonitorOpts) ToMonitorUpdateMap() (map[string]interface{}, error) {
42 type m map[string]interface{}
43
Jamie Hannafordcfe2f282014-11-07 15:11:21 +010044 if !v1.WithinRange(opts.AttemptLimit, 1, 10) {
Jamie Hannaford7afb7af2014-11-04 13:32:20 +010045 return m{}, errAttemptLimit
46 }
Jamie Hannafordcfe2f282014-11-07 15:11:21 +010047 if !v1.WithinRange(opts.Delay, 1, 3600) {
Jamie Hannaford7afb7af2014-11-04 13:32:20 +010048 return m{}, errDelay
49 }
Jamie Hannafordcfe2f282014-11-07 15:11:21 +010050 if !v1.WithinRange(opts.Timeout, 1, 300) {
Jamie Hannaford7afb7af2014-11-04 13:32:20 +010051 return m{}, errTimeout
52 }
53
54 return m{"healthMonitor": m{
55 "attemptsBeforeDeactivation": opts.AttemptLimit,
56 "delay": opts.Delay,
57 "timeout": opts.Timeout,
58 "type": CONNECT,
59 }}, nil
60}
61
62// UpdateHTTPMonitorOpts represents the options needed to update a HTTP monitor.
63type UpdateHTTPMonitorOpts struct {
64 // Required - number of permissible monitor failures before removing a node
65 // from rotation. Must be a number between 1 and 10.
66 AttemptLimit int `mapstructure:"attemptsBeforeDeactivation"`
67
68 // Required - the minimum number of seconds to wait before executing the
69 // health monitor. Must be a number between 1 and 3600.
70 Delay int
71
72 // Required - maximum number of seconds to wait for a connection to be
73 // established before timing out. Must be a number between 1 and 300.
74 Timeout int
75
76 // Required - a regular expression that will be used to evaluate the contents
77 // of the body of the response.
78 BodyRegex string
79
80 // Required - the HTTP path that will be used in the sample request.
81 Path string
82
83 // Required - a regular expression that will be used to evaluate the HTTP
84 // status code returned in the response.
85 StatusRegex string
86
87 // Optional - the name of a host for which the health monitors will check.
88 HostHeader string
89
90 // Required - either HTTP or HTTPS
91 Type Type
92}
93
94// ToMonitorUpdateMap produces a map for updating HTTP(S) monitors.
95func (opts UpdateHTTPMonitorOpts) ToMonitorUpdateMap() (map[string]interface{}, error) {
96 type m map[string]interface{}
97
Jamie Hannafordcfe2f282014-11-07 15:11:21 +010098 if !v1.WithinRange(opts.AttemptLimit, 1, 10) {
Jamie Hannaford7afb7af2014-11-04 13:32:20 +010099 return m{}, errAttemptLimit
100 }
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100101 if !v1.WithinRange(opts.Delay, 1, 3600) {
Jamie Hannaford7afb7af2014-11-04 13:32:20 +0100102 return m{}, errDelay
103 }
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100104 if !v1.WithinRange(opts.Timeout, 1, 300) {
Jamie Hannaford7afb7af2014-11-04 13:32:20 +0100105 return m{}, errTimeout
106 }
107 if opts.Type != HTTP && opts.Type != HTTPS {
108 return m{}, errors.New("Type must either by HTTP or HTTPS")
109 }
110 if opts.BodyRegex == "" {
111 return m{}, errors.New("BodyRegex is a required field")
112 }
113 if opts.Path == "" {
114 return m{}, errors.New("Path is a required field")
115 }
116 if opts.StatusRegex == "" {
117 return m{}, errors.New("StatusRegex is a required field")
118 }
119
120 json := m{
121 "attemptsBeforeDeactivation": opts.AttemptLimit,
122 "delay": opts.Delay,
123 "timeout": opts.Timeout,
124 "type": opts.Type,
125 "bodyRegex": opts.BodyRegex,
126 "path": opts.Path,
127 "statusRegex": opts.StatusRegex,
128 }
129
130 if opts.HostHeader != "" {
131 json["hostHeader"] = opts.HostHeader
132 }
133
134 return m{"healthMonitor": json}, nil
135}
136
137// Update is the operation responsible for updating a health monitor.
138func Update(c *gophercloud.ServiceClient, id int, opts UpdateOptsBuilder) UpdateResult {
139 var res UpdateResult
140
141 reqBody, err := opts.ToMonitorUpdateMap()
142 if err != nil {
143 res.Err = err
144 return res
145 }
146
147 _, res.Err = perigee.Request("PUT", rootURL(c, id), perigee.Options{
148 MoreHeaders: c.AuthenticatedHeaders(),
149 ReqBody: &reqBody,
Jamie Hannaford872ee2b2014-11-05 17:35:55 +0100150 OkCodes: []int{202},
Jamie Hannaford7afb7af2014-11-04 13:32:20 +0100151 })
152
153 return res
154}
Jamie Hannafordc9a4d892014-11-04 14:01:56 +0100155
Jamie Hannafordd7301dd2014-11-04 14:05:39 +0100156// Get is the operation responsible for showing details of a health monitor.
Jamie Hannafordc9a4d892014-11-04 14:01:56 +0100157func Get(c *gophercloud.ServiceClient, id int) GetResult {
158 var res GetResult
159
160 _, res.Err = perigee.Request("GET", rootURL(c, id), perigee.Options{
161 MoreHeaders: c.AuthenticatedHeaders(),
162 Results: &res.Body,
163 OkCodes: []int{200},
164 })
165
166 return res
167}
Jamie Hannafordd7301dd2014-11-04 14:05:39 +0100168
169// Delete is the operation responsible for deleting a health monitor.
170func Delete(c *gophercloud.ServiceClient, id int) DeleteResult {
171 var res DeleteResult
172
173 _, res.Err = perigee.Request("DELETE", rootURL(c, id), perigee.Options{
174 MoreHeaders: c.AuthenticatedHeaders(),
Jamie Hannaford872ee2b2014-11-05 17:35:55 +0100175 OkCodes: []int{202},
Jamie Hannafordd7301dd2014-11-04 14:05:39 +0100176 })
177
178 return res
179}