Ditto for Images.
I'm guessing that the images service also uses marker-and-limit pagination. I'll have to
check when I'm less :airplane:.
diff --git a/openstack/compute/v2/images/client.go b/openstack/compute/v2/images/client.go
deleted file mode 100644
index 6322b9c..0000000
--- a/openstack/compute/v2/images/client.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package images
-
-import (
- "github.com/rackspace/gophercloud"
- identity "github.com/rackspace/gophercloud/openstack/identity/v2"
-)
-
-type Client struct {
- endpoint string
- authority identity.AuthResults
- options gophercloud.AuthOptions
-}
-
-func NewClient(e string, a identity.AuthResults, ao gophercloud.AuthOptions) *Client {
- return &Client{
- endpoint: e,
- authority: a,
- options: ao,
- }
-}
-
-func (c *Client) getListUrl() string {
- return c.endpoint + "/images/detail"
-}
-
-func (c *Client) getListHeaders() (map[string]string, error) {
- t, err := identity.GetToken(c.authority)
- if err != nil {
- return map[string]string{}, err
- }
-
- return map[string]string{
- "X-Auth-Token": t.ID,
- }, nil
-}
diff --git a/openstack/compute/v2/images/images.go b/openstack/compute/v2/images/images.go
index c881092..c4e838e 100644
--- a/openstack/compute/v2/images/images.go
+++ b/openstack/compute/v2/images/images.go
@@ -1,52 +1,38 @@
package images
-import "github.com/mitchellh/mapstructure"
+import (
+ "github.com/mitchellh/mapstructure"
+ "github.com/rackspace/gophercloud/pagination"
+)
// Image is used for JSON (un)marshalling.
// It provides a description of an OS image.
-//
-// The Id field contains the image's unique identifier.
-// For example, this identifier will be useful for specifying which operating system to install on a new server instance.
-//
-// The MinDisk and MinRam fields specify the minimum resources a server must provide to be able to install the image.
-//
-// The Name field provides a human-readable moniker for the OS image.
-//
-// The Progress and Status fields indicate image-creation status.
-// Any usable image will have 100% progress.
-//
-// The Updated field indicates the last time this image was changed.
type Image struct {
- Created string
- Id string
- MinDisk int
- MinRam int
- Name string
+ // ID contains the image's unique identifier.
+ ID string
+
+ Created string
+
+ // MinDisk and MinRAM specify the minimum resources a server must provide to be able to install the image.
+ MinDisk int
+ MinRAM int
+
+ // Name provides a human-readable moniker for the OS image.
+ Name string
+
+ // The Progress and Status fields indicate image-creation status.
+ // Any usable image will have 100% progress.
Progress int
Status string
- Updated string
+
+ Updated string
}
-func GetImages(lr ListResults) ([]Image, error) {
- ia, ok := lr["images"]
- if !ok {
- return nil, ErrNotImplemented
- }
- ims := ia.([]interface{})
+// ExtractImages converts a page of List results into a slice of usable Image structs.
+func ExtractImages(page pagination.Page) ([]Image, error) {
+ casted := page.(ListResults).Body
+ var results []Image
- images := make([]Image, len(ims))
- for i, im := range ims {
- imageObj := im.(map[string]interface{})
- err := mapstructure.Decode(imageObj, &images[i])
- if err != nil {
- return images, err
- }
- }
- return images, nil
-}
-
-func GetImage(ir ImageResults) (Image, error) {
- image := Image{}
- err := mapstructure.Decode(ir, &image)
- return image, err
+ err := mapstructure.Decode(results, casted)
+ return results, err
}
diff --git a/openstack/compute/v2/images/requests.go b/openstack/compute/v2/images/requests.go
index 79783c4..22c6e9b 100644
--- a/openstack/compute/v2/images/requests.go
+++ b/openstack/compute/v2/images/requests.go
@@ -1,26 +1,44 @@
package images
import (
- "fmt"
- "github.com/racker/perigee"
+ "github.com/rackspace/gophercloud"
+ "github.com/rackspace/gophercloud/pagination"
)
-var ErrNotImplemented = fmt.Errorf("Images functionality not implemented.")
+// ListResults contains a single page of results from a List operation.
+// Use ExtractImages to convert it into a slice of usable structs.
+type ListResults struct {
+ pagination.MarkerPageBase
+}
-type ListResults map[string]interface{}
-type ImageResults map[string]interface{}
-
-func List(c *Client) (ListResults, error) {
- var lr ListResults
-
- h, err := c.getListHeaders()
+// IsEmpty returns true if a page contains no Image results.
+func (page ListResults) IsEmpty() (bool, error) {
+ images, err := ExtractImages(page)
if err != nil {
- return nil, err
+ return true, err
+ }
+ return len(images) == 0, nil
+}
+
+// LastMarker returns the ID of the final Image on the current page of ListResults.
+func (page ListResults) LastMarker() (string, error) {
+ images, err := ExtractImages(page)
+ if err != nil {
+ return "", err
+ }
+ if len(images) == 0 {
+ return "", nil
+ }
+ return images[len(images)-1].ID, nil
+}
+
+// List enumerates the available images.
+func List(client *gophercloud.ServiceClient) pagination.Pager {
+ createPage := func(r pagination.LastHTTPResponse) pagination.Page {
+ p := ListResults{pagination.MarkerPageBase{LastHTTPResponse: r}}
+ p.MarkerPageBase.Owner = p
+ return p
}
- err = perigee.Get(c.getListUrl(), perigee.Options{
- Results: &lr,
- MoreHeaders: h,
- })
- return lr, err
+ return pagination.NewPager(client, getListURL(client), createPage)
}
diff --git a/openstack/compute/v2/images/urls.go b/openstack/compute/v2/images/urls.go
new file mode 100644
index 0000000..0e40a4e
--- /dev/null
+++ b/openstack/compute/v2/images/urls.go
@@ -0,0 +1,7 @@
+package images
+
+import "github.com/rackspace/gophercloud"
+
+func getListURL(client *gophercloud.ServiceClient) string {
+ return client.ServiceURL("images", "detail")
+}