List instances
diff --git a/openstack/db/v1/instances/fixtures.go b/openstack/db/v1/instances/fixtures.go
index 8f7d1b7..f990165 100644
--- a/openstack/db/v1/instances/fixtures.go
+++ b/openstack/db/v1/instances/fixtures.go
@@ -90,3 +90,50 @@
`)
})
}
+
+func HandleListInstanceSuccessfully(t *testing.T) {
+ th.Mux.HandleFunc("/instances", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "GET")
+ th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+
+ w.Header().Add("Content-Type", "application/json")
+
+ fmt.Fprintf(w, `
+{
+ "instances": [
+ {
+ "name": "xml_rack_instance",
+ "status": "ACTIVE",
+ "volume": {
+ "size": 2
+ },
+ "flavor": {
+ "id": "1",
+ "links": [
+ {
+ "href": "https://openstack.example.com/v1.0/1234/flavors/1",
+ "rel": "self"
+ },
+ {
+ "href": "https://openstack.example.com/flavors/1",
+ "rel": "bookmark"
+ }
+ ]
+ },
+ "id": "8fb081af-f237-44f5-80cc-b46be1840ca9",
+ "links": [
+ {
+ "href": "https://openstack.example.com/v1.0/1234/instances/8fb081af-f237-44f5-80cc-b46be1840ca9",
+ "rel": "self"
+ },
+ {
+ "href": "https://openstack.example.com/instances/8fb081af-f237-44f5-80cc-b46be1840ca9",
+ "rel": "bookmark"
+ }
+ ]
+ }
+ ]
+}
+`)
+ })
+}
diff --git a/openstack/db/v1/instances/requests.go b/openstack/db/v1/instances/requests.go
index 914c593..eb60342 100644
--- a/openstack/db/v1/instances/requests.go
+++ b/openstack/db/v1/instances/requests.go
@@ -5,6 +5,7 @@
"github.com/racker/perigee"
"github.com/rackspace/gophercloud"
+ "github.com/rackspace/gophercloud/pagination"
)
// CreateOptsBuilder is the top-level interface for create options.
@@ -176,7 +177,7 @@
return res
}
- resp, err := perigee.Request("POST", createURL(client), perigee.Options{
+ resp, err := perigee.Request("POST", baseURL(client), perigee.Options{
MoreHeaders: client.AuthenticatedHeaders(),
ReqBody: &reqBody,
Results: &res.Body,
@@ -188,3 +189,11 @@
return res
}
+
+func List(client *gophercloud.ServiceClient) pagination.Pager {
+ createPageFn := func(r pagination.PageResult) pagination.Page {
+ return InstancePage{pagination.LinkedPageBase{PageResult: r}}
+ }
+
+ return pagination.NewPager(client, baseURL(client), createPageFn)
+}
diff --git a/openstack/db/v1/instances/requests_test.go b/openstack/db/v1/instances/requests_test.go
index 18ba928..236deae 100644
--- a/openstack/db/v1/instances/requests_test.go
+++ b/openstack/db/v1/instances/requests_test.go
@@ -4,6 +4,7 @@
"testing"
"github.com/rackspace/gophercloud"
+ "github.com/rackspace/gophercloud/pagination"
th "github.com/rackspace/gophercloud/testhelper"
fake "github.com/rackspace/gophercloud/testhelper/client"
)
@@ -58,3 +59,50 @@
th.AssertNoErr(t, err)
th.AssertDeepEquals(t, expected, instance)
}
+
+func TestInstanceList(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ HandleListInstanceSuccessfully(t)
+
+ expectedInstance := Instance{
+ Flavor: Flavor{
+ ID: "1",
+ Links: []gophercloud.Link{
+ gophercloud.Link{Href: "https://openstack.example.com/v1.0/1234/flavors/1", Rel: "self"},
+ gophercloud.Link{Href: "https://openstack.example.com/flavors/1", Rel: "bookmark"},
+ },
+ },
+ ID: "8fb081af-f237-44f5-80cc-b46be1840ca9",
+ Links: []gophercloud.Link{
+ gophercloud.Link{Href: "https://openstack.example.com/v1.0/1234/instances/8fb081af-f237-44f5-80cc-b46be1840ca9", Rel: "self"},
+ },
+ Name: "xml_rack_instance",
+ Status: "ACTIVE",
+ Volume: Volume{Size: 2},
+ }
+
+ pages := 0
+ err := List(fake.ServiceClient()).EachPage(func(page pagination.Page) (bool, error) {
+ pages++
+
+ actual, err := ExtractInstances(page)
+ if err != nil {
+ return false, err
+ }
+
+ if len(actual) != 1 {
+ t.Fatalf("Expected 1 DB instance, got %d", len(actual))
+ }
+ th.CheckDeepEquals(t, expectedInstance, actual[0])
+
+ return true, nil
+ })
+
+ th.AssertNoErr(t, err)
+
+ if pages != 1 {
+ t.Errorf("Expected 1 page, saw %d", pages)
+ }
+}
diff --git a/openstack/db/v1/instances/results.go b/openstack/db/v1/instances/results.go
index c3319e0..0207329 100644
--- a/openstack/db/v1/instances/results.go
+++ b/openstack/db/v1/instances/results.go
@@ -3,6 +3,7 @@
import (
"github.com/mitchellh/mapstructure"
"github.com/rackspace/gophercloud"
+ "github.com/rackspace/gophercloud/pagination"
)
type Flavor struct {
@@ -44,3 +45,41 @@
return &response.Instance, err
}
+
+type InstancePage struct {
+ pagination.LinkedPageBase
+}
+
+func (page InstancePage) IsEmpty() (bool, error) {
+ instances, err := ExtractInstances(page)
+ if err != nil {
+ return true, err
+ }
+ return len(instances) == 0, nil
+}
+
+func (page InstancePage) NextPageURL() (string, error) {
+ type resp struct {
+ Links []gophercloud.Link `mapstructure:"instances_links"`
+ }
+
+ var r resp
+ err := mapstructure.Decode(page.Body, &r)
+ if err != nil {
+ return "", err
+ }
+
+ return gophercloud.ExtractNextURL(r.Links)
+}
+
+func ExtractInstances(page pagination.Page) ([]Instance, error) {
+ casted := page.(InstancePage).Body
+
+ var response struct {
+ Instances []Instance `mapstructure:"instances"`
+ }
+
+ err := mapstructure.Decode(casted, &response)
+
+ return response.Instances, err
+}
diff --git a/openstack/db/v1/instances/urls.go b/openstack/db/v1/instances/urls.go
index bb6edf2..e049b6c 100644
--- a/openstack/db/v1/instances/urls.go
+++ b/openstack/db/v1/instances/urls.go
@@ -5,7 +5,3 @@
func baseURL(c *gophercloud.ServiceClient) string {
return c.ServiceURL("instances")
}
-
-func createURL(c *gophercloud.ServiceClient) string {
- return baseURL(c)
-}