@@ -18,12 +18,16 @@ func (r policyResult) Extract() (*Policy, error) {
1818 }
1919
2020 var response struct {
21- Policy Policy `mapstructure:"policy"`
21+ Policy policy `mapstructure:"policy"`
2222 }
2323
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 ()
2529
26- return & response . Policy , err
30+ return & policy , nil
2731}
2832
2933// CreateResult represents the result of a create operation.
@@ -62,43 +66,93 @@ type ExecuteResult struct {
6266 gophercloud.ErrResult
6367}
6468
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+
6590// Policy represents a scaling policy.
6691type Policy struct {
6792 // UUID for the policy.
68- ID string `mapstructure:"id" json:"id"`
93+ ID string
6994
7095 // Name of the policy.
71- Name string `mapstructure:"name" json:"name"`
96+ Name string
7297
7398 // Type of scaling policy.
74- Type Type `mapstructure:"type" json:"type"`
99+ Type Type
75100
76101 // 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
81103
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
84106
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
87109
88110 // Additional configuration options for some types of policy.
89- Args map [string ]interface {} `mapstructure:"args" json:"args"`
111+ Args map [string ]interface {}
90112}
91113
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+ }
94131
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+ }
98153
99- // Webhook policies are triggered by HTTP requests.
100- Webhook Type = "webhook"
101- )
154+ return policy
155+ }
102156
103157// PolicyPage is the page returned by a pager when traversing over a collection
104158// of scaling policies.
@@ -125,7 +179,7 @@ func ExtractPolicies(page pagination.Page) ([]Policy, error) {
125179
126180func commonExtractPolicies (body interface {}) ([]Policy , error ) {
127181 var response struct {
128- Policies []Policy `mapstructure:"policies"`
182+ Policies []policy `mapstructure:"policies"`
129183 }
130184
131185 err := mapstructure .Decode (body , & response )
@@ -134,5 +188,11 @@ func commonExtractPolicies(body interface{}) ([]Policy, error) {
134188 return nil , err
135189 }
136190
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
138198}
0 commit comments