Use clients and pagination for Servers, too.
Whew.
diff --git a/openstack/compute/v2/servers/servers.go b/openstack/compute/v2/servers/servers.go
index 28d66d0..865c7d1 100644
--- a/openstack/compute/v2/servers/servers.go
+++ b/openstack/compute/v2/servers/servers.go
@@ -1,89 +1,80 @@
package servers
import (
- "fmt"
+ "errors"
+
"github.com/mitchellh/mapstructure"
+ "github.com/rackspace/gophercloud/pagination"
)
-// ErrNotImplemented indicates a failure to discover a feature of the response from the API.
-// E.g., a missing server field, a missing extension, etc.
-var ErrNotImplemented = fmt.Errorf("Compute Servers feature not implemented.")
+// 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.")
// Server exposes only the standard OpenStack fields corresponding to a given server on the user's account.
-//
-// Id uniquely identifies this server amongst all other servers, including those not accessible to the current tenant.
-//
-// TenantId identifies the tenant owning this server resource.
-//
-// UserId uniquely identifies the user account owning the tenant.
-//
-// Name contains the human-readable name for the server.
-//
-// Updated and Created contain ISO-8601 timestamps of when the state of the server last changed, and when it was created.
-//
-// Status contains the current operational status of the server, such as IN_PROGRESS or ACTIVE.
-//
-// Progress ranges from 0..100. A request made against the server completes only once Progress reaches 100.
-//
-// AccessIPv4 and AccessIPv6 contain the IP addresses of the server, suitable for remote access for administration.
-//
-// Image refers to a JSON object, which itself indicates the OS image used to deploy the server.
-//
-// Flavor refers to a JSON object, which itself indicates the hardware configuration of the deployed server.
-//
-// Addresses includes a list of all IP addresses assigned to the server, keyed by pool.
-//
-// Metadata includes a list of all user-specified key-value pairs attached to the server.
-//
-// Links includes HTTP references to the itself, useful for passing along to other APIs that might want a server reference.
-//
-// AdminPass will generally be empty (""). However, it will contain the administrative password chosen when provisioning a new server without a set AdminPass setting in the first place.
-// Note that this is the ONLY time this field will be valid.
type Server struct {
- Id string
- TenantId string `mapstructure:tenant_id`
- UserId string `mapstructure:user_id`
- Name string
- Updated string
- Created string
- HostId string
- Status string
- Progress int
+ // ID uniquely identifies this server amongst all other servers, including those not accessible to the current tenant.
+ ID string
+
+ // TenantID identifies the tenant owning this server resource.
+ TenantID string `mapstructure:"tenant_id"`
+
+ // UserID uniquely identifies the user account owning the tenant.
+ UserID string `mapstructure:"user_id"`
+
+ // Name contains the human-readable name for the server.
+ Name string
+
+ // Updated and Created contain ISO-8601 timestamps of when the state of the server last changed, and when it was created.
+ Updated string
+ Created string
+
+ HostID string
+
+ // Status contains the current operational status of the server, such as IN_PROGRESS or ACTIVE.
+ Status string
+
+ // Progress ranges from 0..100.
+ // A request made against the server completes only once Progress reaches 100.
+ Progress int
+
+ // AccessIPv4 and AccessIPv6 contain the IP addresses of the server, suitable for remote access for administration.
AccessIPv4 string
AccessIPv6 string
- Image map[string]interface{}
- Flavor map[string]interface{}
- Addresses map[string]interface{}
- Metadata map[string]interface{}
- Links []interface{}
- AdminPass string `mapstructure:adminPass`
+
+ // Image refers to a JSON object, which itself indicates the OS image used to deploy the server.
+ Image map[string]interface{}
+
+ // Flavor refers to a JSON object, which itself indicates the hardware configuration of the deployed server.
+ Flavor map[string]interface{}
+
+ // Addresses includes a list of all IP addresses assigned to the server, keyed by pool.
+
+ Addresses map[string]interface{}
+
+ // Metadata includes a list of all user-specified key-value pairs attached to the server.
+ Metadata map[string]interface{}
+
+ // Links includes HTTP references to the itself, useful for passing along to other APIs that might want a server reference.
+ Links []interface{}
+
+ // AdminPass will generally be empty (""). However, it will contain the administrative password chosen when provisioning a new server without a set AdminPass setting in the first place.
+ // Note that this is the ONLY time this field will be valid.
+ AdminPass string `mapstructure:"adminPass"`
}
-// GetServers interprets the result of a List() call, producing a slice of Server entities.
-func GetServers(lr ListResult) ([]Server, error) {
- sa, ok := lr["servers"]
- if !ok {
- return nil, ErrNotImplemented
- }
- serversArray := sa.([]interface{})
-
- servers := make([]Server, len(serversArray))
- for i, so := range serversArray {
- serverObj := so.(map[string]interface{})
- err := mapstructure.Decode(serverObj, &servers[i])
- if err != nil {
- return servers, err
- }
- }
-
- return servers, nil
+// ExtractServers interprets the results of a single page from a List() call, producing a slice of Server entities.
+func ExtractServers(page pagination.Page) ([]Server, error) {
+ casted := page.(ListResult).Body
+ var servers []Server
+ err := mapstructure.Decode(servers, casted)
+ return servers, err
}
-// GetServer interprets the result of a call expected to return data on a single server.
-func GetServer(sr ServerResult) (*Server, error) {
+// ExtractServer interprets the result of a call expected to return data on a single server.
+func ExtractServer(sr ServerResult) (*Server, error) {
so, ok := sr["server"]
if !ok {
- return nil, ErrNotImplemented
+ return nil, ErrCannotInterpet
}
serverObj := so.(map[string]interface{})
s := new(Server)