Merge pull request #12 from jrperritt/7
Implement json.Unmarshaler for Flavor
diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md
index 4cc84f6..18f6dc4 100644
--- a/STYLEGUIDE.md
+++ b/STYLEGUIDE.md
@@ -11,7 +11,9 @@
are not good enough. The link(s) should be to a non-`master` branch. For example,
a pull request implementing the creation of a Neutron v2 subnet might put the
following link in the description:
+
https://github.com/openstack/neutron/blob/stable/mitaka/neutron/api/v2/attributes.py#L749
+
From that link, a reviewer (or user) can verify the fields in the request/response
objects in the PR.
@@ -37,3 +39,30 @@
own infrastructure and see an example of usage.
- If in doubt, ask in-line on the PR.
+
+### File Structure
+
+- The following should be used in most cases:
+
+ - `requests.go`: contains all the functions that make HTTP requests and the
+ types associated with the HTTP request (parameters for URL, body, etc)
+ - `results.go`: contains all the response objects and their methods
+ - `urls.go`: contains the endpoints to which the requests are made
+
+### Naming
+
+- For methods on a type in `response.go`, the receiver should be named `r` and the
+ variable into which it will be unmarshalled `s`.
+
+- Functions in `requests.go`, with the exception of functions that return a
+ `pagination.Pager`, should be named returns of the name `r`.
+
+- Functions in `requests.go` that accept request bodies should accept as their
+ last parameter an `interface` named `<Action>OptsBuilder` (eg `CreateOptsBuilder`).
+ This `interface` should have at the least a method named `To<Resource><Action>Map`
+ (eg `ToPortCreateMap`).
+
+- Functions in `requests.go` that accept query strings should accept as their
+ last parameter an `interface` named `<Action>OptsBuilder` (eg `ListOptsBuilder`).
+ This `interface` should have at the least a method named `To<Resource><Action>Query`
+ (eg `ToServerListQuery`).
diff --git a/openstack/compute/v2/flavors/results.go b/openstack/compute/v2/flavors/results.go
index 0edc7d2..a49de0d 100644
--- a/openstack/compute/v2/flavors/results.go
+++ b/openstack/compute/v2/flavors/results.go
@@ -1,15 +1,13 @@
package flavors
import (
- "errors"
+ "encoding/json"
+ "strconv"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
-// ErrCannotInterpret is returned by an Extract call if the response body doesn't have the expected structure.
-var ErrCannotInterpet = errors.New("Unable to interpret a response body.")
-
// GetResult temporarily holds the response from a Get call.
type GetResult struct {
gophercloud.Result
@@ -29,24 +27,60 @@
// The Id field contains the flavor's unique identifier.
// For example, this identifier will be useful when specifying which hardware configuration to use for a new server instance.
ID string `json:"id"`
-
// The Disk and RA< fields provide a measure of storage space offered by the flavor, in GB and MB, respectively.
Disk int `json:"disk"`
RAM int `json:"ram"`
-
// The Name field provides a human-readable moniker for the flavor.
- Name string `json:"name"`
-
+ Name string `json:"name"`
RxTxFactor float64 `json:"rxtx_factor"`
-
// Swap indicates how much space is reserved for swap.
// If not provided, this field will be set to 0.
Swap int `json:"swap"`
-
// VCPUs indicates how many (virtual) CPUs are available for this flavor.
VCPUs int `json:"vcpus"`
}
+func (f *Flavor) UnmarshalJSON(b []byte) error {
+ var flavor struct {
+ ID string `json:"id"`
+ Disk int `json:"disk"`
+ RAM int `json:"ram"`
+ Name string `json:"name"`
+ RxTxFactor float64 `json:"rxtx_factor"`
+ Swap interface{} `json:"swap"`
+ VCPUs int `json:"vcpus"`
+ }
+ err := json.Unmarshal(b, &flavor)
+ if err != nil {
+ return err
+ }
+
+ f.ID = flavor.ID
+ f.Disk = flavor.Disk
+ f.RAM = flavor.RAM
+ f.Name = flavor.Name
+ f.RxTxFactor = flavor.RxTxFactor
+ f.VCPUs = flavor.VCPUs
+
+ switch t := flavor.Swap.(type) {
+ case float64:
+ f.Swap = int(t)
+ case string:
+ switch t {
+ case "":
+ f.Swap = 0
+ default:
+ swap, err := strconv.ParseFloat(t, 64)
+ if err != nil {
+ return err
+ }
+ f.Swap = int(swap)
+ }
+ }
+
+ return nil
+}
+
// FlavorPage contains a single page of the response from a List call.
type FlavorPage struct {
pagination.LinkedPageBase
diff --git a/openstack/compute/v2/flavors/testing/requests_test.go b/openstack/compute/v2/flavors/testing/requests_test.go
index e86512a..1b96933 100644
--- a/openstack/compute/v2/flavors/testing/requests_test.go
+++ b/openstack/compute/v2/flavors/testing/requests_test.go
@@ -35,14 +35,16 @@
"name": "m1.tiny",
"disk": 1,
"ram": 512,
- "vcpus": 1
+ "vcpus": 1,
+ "swap":""
},
{
"id": "2",
"name": "m2.small",
"disk": 10,
"ram": 1024,
- "vcpus": 2
+ "vcpus": 2,
+ "swap": 1000
}
],
"flavors_links": [
@@ -70,8 +72,8 @@
}
expected := []flavors.Flavor{
- {ID: "1", Name: "m1.tiny", Disk: 1, RAM: 512, VCPUs: 1},
- {ID: "2", Name: "m2.small", Disk: 10, RAM: 1024, VCPUs: 2},
+ {ID: "1", Name: "m1.tiny", Disk: 1, RAM: 512, VCPUs: 1, Swap: 0},
+ {ID: "2", Name: "m2.small", Disk: 10, RAM: 1024, VCPUs: 2, Swap: 1000},
}
if !reflect.DeepEqual(expected, actual) {
@@ -105,7 +107,8 @@
"disk": 1,
"ram": 512,
"vcpus": 1,
- "rxtx_factor": 1
+ "rxtx_factor": 1,
+ "swap": ""
}
}
`)
@@ -123,6 +126,7 @@
RAM: 512,
VCPUs: 1,
RxTxFactor: 1,
+ Swap: 0,
}
if !reflect.DeepEqual(expected, actual) {
t.Errorf("Expected %#v, but was %#v", expected, actual)