@@ -18,12 +18,16 @@ func (r policyResult) Extract() (*Policy, error) {
18
18
}
19
19
20
20
var response struct {
21
- Policy Policy `mapstructure:"policy"`
21
+ Policy policy `mapstructure:"policy"`
22
22
}
23
23
24
- err := mapstructure .Decode (r .Body , & response )
24
+ if err := mapstructure .Decode (r .Body , & response ); err != nil {
25
+ return nil , err
26
+ }
27
+
28
+ policy := response .Policy .toExported ()
25
29
26
- return & response . Policy , err
30
+ return & policy , nil
27
31
}
28
32
29
33
// CreateResult represents the result of a create operation.
@@ -62,43 +66,93 @@ type ExecuteResult struct {
62
66
gophercloud.ErrResult
63
67
}
64
68
69
+ // Type represents a type of scaling policy.
70
+ type Type string
71
+
72
+ const (
73
+ // Schedule policies run at given times.
74
+ Schedule Type = "schedule"
75
+
76
+ // Webhook policies are triggered by HTTP requests.
77
+ Webhook Type = "webhook"
78
+ )
79
+
80
+ // AdjustmentType represents the way in which a policy will change a group.
81
+ type AdjustmentType string
82
+
83
+ // Valid types of adjustments for a policy.
84
+ const (
85
+ Change AdjustmentType = "change"
86
+ ChangePercent AdjustmentType = "changePercent"
87
+ DesiredCapacity AdjustmentType = "desiredCapacity"
88
+ )
89
+
65
90
// Policy represents a scaling policy.
66
91
type Policy struct {
67
92
// UUID for the policy.
68
- ID string `mapstructure:"id" json:"id"`
93
+ ID string
69
94
70
95
// Name of the policy.
71
- Name string `mapstructure:"name" json:"name"`
96
+ Name string
72
97
73
98
// Type of scaling policy.
74
- Type Type `mapstructure:"type" json:"type"`
99
+ Type Type
75
100
76
101
// Cooldown period, in seconds.
77
- Cooldown int `mapstructure:"cooldown" json:"cooldown"`
78
-
79
- // Number of servers added or, if negative, removed.
80
- Change interface {} `mapstructure:"change" json:"change"`
102
+ Cooldown int
81
103
82
- // Percent change to make in the number of servers .
83
- ChangePercent interface {} `mapstructure:"changePercent" json:"changePercent"`
104
+ // The type of adjustment in capacity to be made .
105
+ AdjustmentType AdjustmentType
84
106
85
- // Desired capacity of the of the associated group .
86
- DesiredCapacity interface {} `mapstructure:"desiredCapacity" json:"desiredCapacity"`
107
+ // The numeric value of the adjustment in capacity .
108
+ AdjustmentValue float64
87
109
88
110
// Additional configuration options for some types of policy.
89
- Args map [string ]interface {} `mapstructure:"args" json:"args"`
111
+ Args map [string ]interface {}
90
112
}
91
113
92
- // Type represents a type of scaling policy.
93
- type Type string
114
+ // This is an intermediate representation of the exported Policy type. The
115
+ // fields in API responses vary by policy type and configuration. This lets us
116
+ // decode responses then normalize them into a Policy.
117
+ type policy struct {
118
+ ID string `mapstructure:"id"`
119
+ Name string `mapstructure:"name"`
120
+ Type Type `mapstructure:"type"`
121
+ Cooldown int `mapstructure:"cooldown"`
122
+
123
+ // The API will respond with exactly one of these omitting the others.
124
+ Change interface {} `mapstructure:"change"`
125
+ ChangePercent interface {} `mapstructure:"changePercent"`
126
+ DesiredCapacity interface {} `mapstructure:"desiredCapacity"`
127
+
128
+ // Additional configuration options for schedule policies.
129
+ Args map [string ]interface {} `mapstructure:"args"`
130
+ }
94
131
95
- const (
96
- // Schedule policies run at given times.
97
- Schedule Type = "schedule"
132
+ // Assemble a Policy from the intermediate policy struct.
133
+ func (p policy ) toExported () Policy {
134
+ policy := Policy {}
135
+
136
+ policy .ID = p .ID
137
+ policy .Name = p .Name
138
+ policy .Type = p .Type
139
+ policy .Cooldown = p .Cooldown
140
+
141
+ policy .Args = p .Args
142
+
143
+ if v , ok := p .Change .(float64 ); ok {
144
+ policy .AdjustmentType = Change
145
+ policy .AdjustmentValue = v
146
+ } else if v , ok := p .ChangePercent .(float64 ); ok {
147
+ policy .AdjustmentType = ChangePercent
148
+ policy .AdjustmentValue = v
149
+ } else if v , ok := p .DesiredCapacity .(float64 ); ok {
150
+ policy .AdjustmentType = DesiredCapacity
151
+ policy .AdjustmentValue = v
152
+ }
98
153
99
- // Webhook policies are triggered by HTTP requests.
100
- Webhook Type = "webhook"
101
- )
154
+ return policy
155
+ }
102
156
103
157
// PolicyPage is the page returned by a pager when traversing over a collection
104
158
// of scaling policies.
@@ -125,7 +179,7 @@ func ExtractPolicies(page pagination.Page) ([]Policy, error) {
125
179
126
180
func commonExtractPolicies (body interface {}) ([]Policy , error ) {
127
181
var response struct {
128
- Policies []Policy `mapstructure:"policies"`
182
+ Policies []policy `mapstructure:"policies"`
129
183
}
130
184
131
185
err := mapstructure .Decode (body , & response )
@@ -134,5 +188,11 @@ func commonExtractPolicies(body interface{}) ([]Policy, error) {
134
188
return nil , err
135
189
}
136
190
137
- return response .Policies , err
191
+ policies := make ([]Policy , len (response .Policies ))
192
+
193
+ for i , p := range response .Policies {
194
+ policies [i ] = p .toExported ()
195
+ }
196
+
197
+ return policies , nil
138
198
}
0 commit comments