Add intermediate type for autoscale policies
diff --git a/rackspace/autoscale/v1/policies/fixtures.go b/rackspace/autoscale/v1/policies/fixtures.go
index ac54268..67967b0 100644
--- a/rackspace/autoscale/v1/policies/fixtures.go
+++ b/rackspace/autoscale/v1/policies/fixtures.go
@@ -130,19 +130,21 @@
var (
// WebhookPolicy is a Policy corresponding to the first result in PolicyListBody.
WebhookPolicy = Policy{
- ID: "2b48d247-0282-4b9d-8775-5c4b67e8e649",
- Name: "webhook policy",
- Type: Webhook,
- Cooldown: 300,
- ChangePercent: 3.3,
+ ID: "2b48d247-0282-4b9d-8775-5c4b67e8e649",
+ Name: "webhook policy",
+ Type: Webhook,
+ Cooldown: 300,
+ AdjustmentType: ChangePercent,
+ AdjustmentValue: 3.3,
}
// OneTimePolicy is a Policy corresponding to the second result in PolicyListBody.
OneTimePolicy = Policy{
- ID: "c175c31e-65f9-41de-8b15-918420d3253e",
- Name: "one time",
- Type: Schedule,
- Change: float64(-1),
+ ID: "c175c31e-65f9-41de-8b15-918420d3253e",
+ Name: "one time",
+ Type: Schedule,
+ AdjustmentType: Change,
+ AdjustmentValue: float64(-1),
Args: map[string]interface{}{
"at": "2020-04-01T23:00:00.000Z",
},
@@ -153,7 +155,8 @@
ID: "e785e3e7-af9e-4f3c-99ae-b80a532e1663",
Name: "sunday afternoon",
Type: Schedule,
- DesiredCapacity: float64(2),
+ AdjustmentType: DesiredCapacity,
+ AdjustmentValue: float64(2),
Args: map[string]interface{}{
"cron": "59 15 * * 0",
},
diff --git a/rackspace/autoscale/v1/policies/requests.go b/rackspace/autoscale/v1/policies/requests.go
index 25747b8..bc7a8fe 100644
--- a/rackspace/autoscale/v1/policies/requests.go
+++ b/rackspace/autoscale/v1/policies/requests.go
@@ -31,16 +31,6 @@
ToPolicyCreateMap() ([]map[string]interface{}, error)
}
-// AdjustmentType represents the way in which a policy will change a group.
-type AdjustmentType string
-
-// Valid types of adjustments for a policy.
-const (
- Change AdjustmentType = "change"
- ChangePercent AdjustmentType = "changePercent"
- DesiredCapacity AdjustmentType = "desiredCapacity"
-)
-
// CreateOpts is a slice of CreateOpt structs that allow the user to create
// multiple policies in a single operation.
type CreateOpts []CreateOpt
diff --git a/rackspace/autoscale/v1/policies/results.go b/rackspace/autoscale/v1/policies/results.go
index b304e9d..95d03ca 100644
--- a/rackspace/autoscale/v1/policies/results.go
+++ b/rackspace/autoscale/v1/policies/results.go
@@ -18,12 +18,16 @@
}
var response struct {
- Policy Policy `mapstructure:"policy"`
+ Policy policy `mapstructure:"policy"`
}
- err := mapstructure.Decode(r.Body, &response)
+ if err := mapstructure.Decode(r.Body, &response); err != nil {
+ return nil, err
+ }
- return &response.Policy, err
+ policy := response.Policy.toExported()
+
+ return &policy, nil
}
// CreateResult represents the result of a create operation.
@@ -62,33 +66,6 @@
gophercloud.ErrResult
}
-// Policy represents a scaling policy.
-type Policy struct {
- // UUID for the policy.
- ID string `mapstructure:"id" json:"id"`
-
- // Name of the policy.
- Name string `mapstructure:"name" json:"name"`
-
- // Type of scaling policy.
- Type Type `mapstructure:"type" json:"type"`
-
- // Cooldown period, in seconds.
- Cooldown int `mapstructure:"cooldown" json:"cooldown"`
-
- // Number of servers added or, if negative, removed.
- Change interface{} `mapstructure:"change" json:"change"`
-
- // Percent change to make in the number of servers.
- ChangePercent interface{} `mapstructure:"changePercent" json:"changePercent"`
-
- // Desired capacity of the of the associated group.
- DesiredCapacity interface{} `mapstructure:"desiredCapacity" json:"desiredCapacity"`
-
- // Additional configuration options for some types of policy.
- Args map[string]interface{} `mapstructure:"args" json:"args"`
-}
-
// Type represents a type of scaling policy.
type Type string
@@ -100,6 +77,83 @@
Webhook Type = "webhook"
)
+// AdjustmentType represents the way in which a policy will change a group.
+type AdjustmentType string
+
+// Valid types of adjustments for a policy.
+const (
+ Change AdjustmentType = "change"
+ ChangePercent AdjustmentType = "changePercent"
+ DesiredCapacity AdjustmentType = "desiredCapacity"
+)
+
+// Policy represents a scaling policy.
+type Policy struct {
+ // UUID for the policy.
+ ID string
+
+ // Name of the policy.
+ Name string
+
+ // Type of scaling policy.
+ Type Type
+
+ // Cooldown period, in seconds.
+ Cooldown int
+
+ // The type of adjustment in capacity to be made.
+ AdjustmentType AdjustmentType
+
+ // The numeric value of the adjustment in capacity.
+ AdjustmentValue float64
+
+ // Additional configuration options for some types of policy.
+ Args map[string]interface{}
+}
+
+// This is an intermediate representation of the exported Policy type. The
+// fields in API responses vary by policy type and configuration. This lets us
+// decode responses then normalize them into a Policy.
+type policy struct {
+ ID string `mapstructure:"id"`
+ Name string `mapstructure:"name"`
+ Type Type `mapstructure:"type"`
+ Cooldown int `mapstructure:"cooldown"`
+
+ // The API will respond with exactly one of these omitting the others.
+ Change interface{} `mapstructure:"change"`
+ ChangePercent interface{} `mapstructure:"changePercent"`
+ DesiredCapacity interface{} `mapstructure:"desiredCapacity"`
+
+ // Additional configuration options for schedule policies.
+ Args map[string]interface{} `mapstructure:"args"`
+}
+
+// Assemble a Policy from the intermediate policy struct.
+func (p policy) toExported() Policy {
+ policy := Policy{}
+
+ policy.ID = p.ID
+ policy.Name = p.Name
+ policy.Type = p.Type
+ policy.Cooldown = p.Cooldown
+
+ policy.Args = p.Args
+
+ if v, ok := p.Change.(float64); ok {
+ policy.AdjustmentType = Change
+ policy.AdjustmentValue = v
+ } else if v, ok := p.ChangePercent.(float64); ok {
+ policy.AdjustmentType = ChangePercent
+ policy.AdjustmentValue = v
+ } else if v, ok := p.DesiredCapacity.(float64); ok {
+ policy.AdjustmentType = DesiredCapacity
+ policy.AdjustmentValue = v
+ }
+
+ return policy
+}
+
// PolicyPage is the page returned by a pager when traversing over a collection
// of scaling policies.
type PolicyPage struct {
@@ -125,7 +179,7 @@
func commonExtractPolicies(body interface{}) ([]Policy, error) {
var response struct {
- Policies []Policy `mapstructure:"policies"`
+ Policies []policy `mapstructure:"policies"`
}
err := mapstructure.Decode(body, &response)
@@ -134,5 +188,11 @@
return nil, err
}
- return response.Policies, err
+ policies := make([]Policy, len(response.Policies))
+
+ for i, p := range response.Policies {
+ policies[i] = p.toExported()
+ }
+
+ return policies, nil
}