Complete Flavors sub-API.
diff --git a/acceptance/openstack/compute_test.go b/acceptance/openstack/compute_test.go
index 0a99d05..f396fe2 100644
--- a/acceptance/openstack/compute_test.go
+++ b/acceptance/openstack/compute_test.go
@@ -109,7 +109,7 @@
client := flavors.NewClient(ep.PublicURL, ts.a, ts.o)
- listResults, err := flavors.List(client)
+ listResults, err := flavors.List(client, flavors.ListFilterOptions{})
if err != nil {
t.Error(err)
return
@@ -128,7 +128,32 @@
}
}
ts.w.Flush()
- fmt.Printf("--------\n%d images listed.\n", n)
+ fmt.Printf("--------\n%d flavors listed.\n", n)
+}
+
+func TestGetFlavor(t *testing.T) {
+ ts, err := setupForCRUD()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ region := os.Getenv("OS_REGION_NAME")
+ for _, ep := range ts.eps {
+ if (region != "") && (region != ep.Region) {
+ continue
+ }
+ client := flavors.NewClient(ep.PublicURL, ts.a, ts.o)
+
+ getResults, err := flavors.Get(client, ts.flavorId)
+ if err != nil {
+ t.Fatal(err)
+ }
+ flav, err := flavors.GetFlavor(getResults)
+ if err != nil {
+ t.Fatal(err)
+ }
+ fmt.Printf("%#v\n", flav)
+ }
}
func TestCreateDestroyServer(t *testing.T) {
diff --git a/openstack/compute/flavors/client.go b/openstack/compute/flavors/client.go
index 60c7cd1..2c64908 100644
--- a/openstack/compute/flavors/client.go
+++ b/openstack/compute/flavors/client.go
@@ -1,7 +1,10 @@
package flavors
import (
+ "fmt"
+ "net/url"
"github.com/rackspace/gophercloud/openstack/identity"
+ "strconv"
)
type Client struct {
@@ -18,8 +21,32 @@
}
}
-func (c *Client) getListUrl() string {
- return c.endpoint + "/flavors/detail"
+func (c *Client) getListUrl(lfo ListFilterOptions) string {
+ v := url.Values{}
+ if lfo.ChangesSince != "" {
+ v.Set("changes-since", lfo.ChangesSince)
+ }
+ if lfo.MinDisk != 0 {
+ v.Set("minDisk", strconv.Itoa(lfo.MinDisk))
+ }
+ if lfo.MinRam != 0 {
+ v.Set("minRam", strconv.Itoa(lfo.MinRam))
+ }
+ if lfo.Marker != "" {
+ v.Set("marker", lfo.Marker)
+ }
+ if lfo.Limit != 0 {
+ v.Set("limit", strconv.Itoa(lfo.Limit))
+ }
+ tail := ""
+ if len(v) > 0 {
+ tail = fmt.Sprintf("?%s", v.Encode())
+ }
+ return fmt.Sprintf("%s/flavors/detail%s", c.endpoint, tail)
+}
+
+func (c *Client) getGetUrl(id string) string {
+ return fmt.Sprintf("%s/flavors/%s", c.endpoint, id)
}
func (c *Client) getListHeaders() (map[string]string, error) {
diff --git a/openstack/compute/flavors/flavors.go b/openstack/compute/flavors/flavors.go
index 81996a5..146bcc4 100644
--- a/openstack/compute/flavors/flavors.go
+++ b/openstack/compute/flavors/flavors.go
@@ -35,6 +35,7 @@
return v, nil
}
+// GetFlavors provides access to the list of flavors returned by the List function.
func GetFlavors(lr ListResults) ([]Flavor, error) {
fa, ok := lr["flavors"]
if !ok {
@@ -60,3 +61,23 @@
}
return flavors, nil
}
+
+// GetFlavor provides access to the individual flavor returned by the Get function.
+func GetFlavor(gr GetResults) (*Flavor, error) {
+ f, ok := gr["flavor"]
+ if !ok {
+ return nil, ErrNotImplemented
+ }
+
+ flav := new(Flavor)
+ cfg := &mapstructure.DecoderConfig{
+ DecodeHook: defaulter,
+ Result: flav,
+ }
+ decoder, err := mapstructure.NewDecoder(cfg)
+ if err != nil {
+ return flav, err
+ }
+ err = decoder.Decode(f)
+ return flav, err
+}
diff --git a/openstack/compute/flavors/requests.go b/openstack/compute/flavors/requests.go
index f4dd072..3758206 100644
--- a/openstack/compute/flavors/requests.go
+++ b/openstack/compute/flavors/requests.go
@@ -8,8 +8,27 @@
var ErrNotImplemented = fmt.Errorf("Flavors functionality not implemented.")
type ListResults map[string]interface{}
+type GetResults map[string]interface{}
-func List(c *Client) (ListResults, error) {
+// ListFilterOptions helps control the results returned by the List() function.
+// ChangesSince, if provided, instructs List to return only those things which have changed since the timestamp provided.
+// MinDisk and MinRam, if provided, elides flavors which do not meet your criteria.
+// For example, a flavor with a minDisk field of 10 will not be returned if you specify MinDisk set to 20.
+// Marker and Limit control paging.
+// Limit instructs List to refrain from sending excessively large lists of flavors.
+// Marker instructs List where to start listing from.
+// Typically, software will use the last ID of the previous call to List to set the Marker for the current call.
+type ListFilterOptions struct {
+ ChangesSince string
+ MinDisk, MinRam int
+ Marker string
+ Limit int
+}
+
+// List instructs OpenStack to provide a list of flavors.
+// You may provide criteria by which List curtails its results for easier processing.
+// See ListFilterOptions for more details.
+func List(c *Client, lfo ListFilterOptions) (ListResults, error) {
var lr ListResults
h, err := c.getListHeaders()
@@ -17,9 +36,23 @@
return nil, err
}
- err = perigee.Get(c.getListUrl(), perigee.Options{
+ err = perigee.Get(c.getListUrl(lfo), perigee.Options{
Results: &lr,
MoreHeaders: h,
})
return lr, err
}
+
+// Get instructs OpenStack to provide details on a single flavor, identified by its ID.
+func Get(c *Client, id string) (GetResults, error) {
+ var gr GetResults
+ h, err := c.getListHeaders() // same for Get Flavor API
+ if err != nil {
+ return gr, err
+ }
+ err = perigee.Get(c.getGetUrl(id), perigee.Options{
+ Results: &gr,
+ MoreHeaders: h,
+ })
+ return gr, err
+}