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