blob: 8b56c2e2d87fcc533beffcb00efdb0b9e92c5506 [file] [log] [blame]
Brad Ison53e997c2016-03-26 18:02:05 -04001package policies
2
3import (
Brad Isone7d6dfc2016-04-06 14:55:07 -04004 "errors"
5
Brad Ison53e997c2016-03-26 18:02:05 -04006 "github.com/rackspace/gophercloud"
7 "github.com/rackspace/gophercloud/pagination"
8)
9
Brad Isone7d6dfc2016-04-06 14:55:07 -040010// Validation errors returned by create or update operations.
11var (
12 ErrNoName = errors.New("Policy name cannot by empty.")
13 ErrNoArgs = errors.New("Args cannot be nil for schedule policies.")
14)
15
Brad Ison53e997c2016-03-26 18:02:05 -040016// List returns all scaling policies for a group.
17func List(client *gophercloud.ServiceClient, groupID string) pagination.Pager {
18 url := listURL(client, groupID)
19
20 createPageFn := func(r pagination.PageResult) pagination.Page {
21 return PolicyPage{pagination.SinglePageBase(r)}
22 }
23
24 return pagination.NewPager(client, url, createPageFn)
25}
Brad Isone7d6dfc2016-04-06 14:55:07 -040026
27// CreateOptsBuilder is the interface responsible for generating the map that
28// will be marshalled to JSON for a Create operation.
29type CreateOptsBuilder interface {
30 ToPolicyCreateMap() ([]map[string]interface{}, error)
31}
32
33// Adjustment represents the change in capacity associated with a policy.
34type Adjustment struct {
35 // The type for this adjustment.
36 Type AdjustmentType
37
38 // The value of the adjustment. For adjustments of type Change or
39 // DesiredCapacity, this will be converted to an integer.
40 Value float64
41}
42
43// AdjustmentType represents the way in which a policy will change a group.
44type AdjustmentType string
45
46// Valid types of adjustments for a policy.
47const (
48 Change AdjustmentType = "change"
49 ChangePercent AdjustmentType = "changePercent"
50 DesiredCapacity AdjustmentType = "desiredCapacity"
51)
52
53// CreateOpts is a slice of CreateOpt structs that allow the user to create
54// multiple policies in a single operation.
55type CreateOpts []CreateOpt
56
57// CreateOpt represents the options to create a policy.
58type CreateOpt struct {
59 // Name [required] is a name for the policy.
60 Name string
61
62 // Type [required] of policy, i.e. either "webhook" or "schedule".
63 Type Type
64
65 // Cooldown [required] period in seconds.
66 Cooldown int
67
68 // Adjustment [requried] type and value for the policy.
69 Adjustment Adjustment
70
71 // Additional configuration options for some types of policy.
72 Args map[string]interface{}
73}
74
75// ToPolicyCreateMap converts a slice of CreateOpt structs into a map for use
76// in the request body of a Create operation.
77func (opts CreateOpts) ToPolicyCreateMap() ([]map[string]interface{}, error) {
78 var policies []map[string]interface{}
79
80 for _, o := range opts {
81 if o.Name == "" {
82 return nil, ErrNoName
83 }
84
85 if o.Type == Schedule && o.Args == nil {
86 return nil, ErrNoArgs
87 }
88
89 policy := make(map[string]interface{})
90
91 policy["name"] = o.Name
92 policy["type"] = o.Type
93 policy["cooldown"] = o.Cooldown
94
95 // TODO: Function to validate and cast key + value?
96 policy[string(o.Adjustment.Type)] = o.Adjustment.Value
97
98 if o.Args != nil {
99 policy["args"] = o.Args
100 }
101
102 policies = append(policies, policy)
103 }
104
105 return policies, nil
106}
107
108// Create requests a new policy be created and associated with the given group.
109func Create(client *gophercloud.ServiceClient, groupID string, opts CreateOptsBuilder) CreateResult {
110 var res CreateResult
111
112 reqBody, err := opts.ToPolicyCreateMap()
113
114 if err != nil {
115 res.Err = err
116 return res
117 }
118
119 _, res.Err = client.Post(createURL(client, groupID), reqBody, &res.Body, nil)
120
121 return res
122}
Brad Ison55523e52016-04-06 19:25:20 -0400123
124// Get requests the details of a single policy with the given ID.
125func Get(client *gophercloud.ServiceClient, groupID, policyID string) GetResult {
126 var result GetResult
127
128 _, result.Err = client.Get(getURL(client, groupID, policyID), &result.Body, nil)
129
130 return result
131}
Brad Isonac037d52016-04-07 19:41:29 -0400132
133// UpdateOptsBuilder is the interface responsible for generating the map
134// structure for producing JSON for an Update operation.
135type UpdateOptsBuilder interface {
136 ToPolicyUpdateMap() (map[string]interface{}, error)
137}
138
139// UpdateOpts represents the options for updating an existing policy.
140//
141// Update operations completely replace the configuration being updated. Empty
142// values in the update are accepted and overwrite previously specified
143// parameters.
144type UpdateOpts struct {
145 // Name [required] is a name for the policy.
146 Name string
147
148 // Type [required] of policy, i.e. either "webhook" or "schedule".
149 Type Type
150
151 // Cooldown [required] period in seconds. If you don't specify a cooldown,
152 // it will default to zero, and the policy will be configured as such.
153 Cooldown int
154
155 // Adjustment [requried] type and value for the policy.
156 Adjustment Adjustment
157
158 // Additional configuration options for some types of policy.
159 Args map[string]interface{}
160}
161
162// ToPolicyUpdateMap converts an UpdateOpts struct into a map for use as the
163// request body in an Update request.
164func (opts UpdateOpts) ToPolicyUpdateMap() (map[string]interface{}, error) {
165 if opts.Name == "" {
166 return nil, ErrNoName
167 }
168
169 if opts.Type == Schedule && opts.Args == nil {
170 return nil, ErrNoArgs
171 }
172
173 policy := make(map[string]interface{})
174
175 policy["name"] = opts.Name
176 policy["type"] = opts.Type
177 policy["cooldown"] = opts.Cooldown
178
179 // TODO: Function to validate and cast key + value?
180 policy[string(opts.Adjustment.Type)] = opts.Adjustment.Value
181
182 if opts.Args != nil {
183 policy["args"] = opts.Args
184 }
185
186 return policy, nil
187}
188
189// Update requests the configuration of the given policy be updated.
190func Update(client *gophercloud.ServiceClient, groupID, policyID string, opts UpdateOptsBuilder) UpdateResult {
191 var result UpdateResult
192
193 url := updateURL(client, groupID, policyID)
194 reqBody, err := opts.ToPolicyUpdateMap()
195
196 if err != nil {
197 result.Err = err
198 return result
199 }
200
201 _, result.Err = client.Put(url, reqBody, nil, &gophercloud.RequestOpts{
202 OkCodes: []int{204},
203 })
204
205 return result
206}
Brad Ison124df8e2016-04-07 19:51:51 -0400207
208// Delete requests the given policy be permanently deleted.
209func Delete(client *gophercloud.ServiceClient, groupID, policyID string) DeleteResult {
210 var result DeleteResult
211
212 url := deleteURL(client, groupID, policyID)
213 _, result.Err = client.Delete(url, &gophercloud.RequestOpts{
214 OkCodes: []int{204},
215 })
216
217 return result
218}
Brad Ison42f8dfb2016-04-07 20:26:06 -0400219
220// Execute requests the given policy be executed immediately.
221func Execute(client *gophercloud.ServiceClient, groupID, policyID string) ExecuteResult {
222 var result ExecuteResult
223
224 url := executeURL(client, groupID, policyID)
225 _, result.Err = client.Post(url, nil, &result.Body, &gophercloud.RequestOpts{
226 OkCodes: []int{202},
227 })
228
229 return result
230}