-
Notifications
You must be signed in to change notification settings - Fork 180
[RFR] Rackspace Auto Scale: policies #554
Conversation
Cooldown int `mapstructure:"cooldown" json:"cooldown"` | ||
|
||
// Number of servers added or, if negative, removed. | ||
Change interface{} `mapstructure:"change" json:"change"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change
, ChangePercent
, and DesiredCapacity
are empty interfaces here because a policy can only have one of the three. The API will return whichever field is appropriate and omit the others. In reality, ChangePercent
is a float and the other two are integers.
So, this lets you test if each is nil
, though everything comes back as a float64. I could add an UnmarshalJSON
method that converts to integers as needed. Is that necessary? Or is this off base altogether?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're on the right track here. I'd add an additional unmarshaling step: Define the Policy
you have here as an unexported type (maybe in the commonExtractPolicies
function as policy
), decode the raw response data into that structure, and then add logic to massage it into a more user-friendly, exported Policy
object like:
type Policy struct {
//...
AdjustmentType AdjustmentType
AdjustmentValue float64
//...
}
``
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about this more. Not sure this is doable with mapstructure. It's easy enough adding an UnmarshalJSON
method to Policy
, but I think that means doing one of the following:
- Keep the raw HTTP response in the
Body
field on thegophercloud.Result
structs and do the decoding in the extract methods. - Do the decoding in the request methods, and store a
Policy
ingophercloud.Result.Body
. The extract methods don't do much then. - Add a
Policy
to thepolicyResult
struct and store the decoded policies there.
The first option seems most reasonable to me. Anyway, my hangup is that all of those break from the norm of decoding into a generic map on gophercloud.Result.Body
and then using mapstructure. I can't find anywhere else in the code that does something like this.
Thoughts? Also, if it's easier, I can push something I have along the lines of the first option above and we can talk about it more concretely maybe.
EDIT: Maybe I misunderstood what you said. I guess you mean use mapstructure to decode into the unexported type then just define a helper to build a Policy
from that. Is that right? If so, I'm guessing that's preferable to what I described?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you mean use mapstructure to decode into the unexported type then just define a helper to build a Policy from that. Is that right?
Exactly. Doesn't have to be a separate function; could be defined in commonExtractPolicies
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense. Done.
policy.AdjustmentValue = v | ||
} | ||
|
||
if v, ok := p.ChangePercent.(float64); ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since only one of these can be set, we can else if
here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Done.
Looks great. Let me know when you're done making changes and I'll merge it. |
Pushed 0310e5c with the policy, err := policies.Get(client, group, policyID).Extract()
switch s := policy.Schedule.(type) {
case policies.At:
t := time.Time(s)
fmt.Println("EXECUTE AT:", t.Format(time.RFC850))
case policies.Cron:
fmt.Println("CRON:", s)
default:
fmt.Println("Webhook.")
} Creating policies with an |
Added the I think this is finished assuming you're good with the |
Maybe we can compromise and just have |
We can do that. My only worry is the zero values. I really think We could make those fields |
Or did you mean keep the |
I'm very much a fan of the |
We could keep the That doesn't seem ideal, and you still have to do some looking into the map, but maybe it's more straight forward than the type switch. I'm not really sure. |
No, let's go with what you have now. I think it's the best of the options I can think of right now. |
Is it ready to merge? |
Yeah, I think it's good. |
+2 |
Adds a package for Rackspace Auto Scale policies.