remove mapstructure from identity,networking,objectstorage,orchestration,pagination
diff --git a/openstack/identity/v2/extensions/admin/roles/results.go b/openstack/identity/v2/extensions/admin/roles/results.go
index 6cfe3ac..608f206 100644
--- a/openstack/identity/v2/extensions/admin/roles/results.go
+++ b/openstack/identity/v2/extensions/admin/roles/results.go
@@ -1,7 +1,6 @@
package roles
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -29,21 +28,17 @@
// IsEmpty determines whether or not a page of Tenants contains any results.
func (page RolePage) IsEmpty() (bool, error) {
users, err := ExtractRoles(page)
- if err != nil {
- return false, err
- }
- return len(users) == 0, nil
+ return len(users) == 0, err
}
// ExtractRoles returns a slice of roles contained in a single page of results.
func ExtractRoles(page pagination.Page) ([]Role, error) {
- casted := page.(RolePage).Body
- var response struct {
- Roles []Role `mapstructure:"roles"`
+ r := page.(RolePage)
+ var s struct {
+ Roles []Role `json:"roles"`
}
-
- err := mapstructure.Decode(casted, &response)
- return response.Roles, err
+ err := r.ExtractInto(&s)
+ return s.Roles, err
}
// UserRoleResult represents the result of either an AddUserRole or
diff --git a/openstack/identity/v2/extensions/delegate.go b/openstack/identity/v2/extensions/delegate.go
index e6af80e..4b2c6a7 100644
--- a/openstack/identity/v2/extensions/delegate.go
+++ b/openstack/identity/v2/extensions/delegate.go
@@ -1,7 +1,6 @@
package extensions
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
common "github.com/gophercloud/gophercloud/openstack/common/extensions"
"github.com/gophercloud/gophercloud/pagination"
@@ -24,16 +23,15 @@
// ExtractExtensions accepts a Page struct, specifically an ExtensionPage struct, and extracts the
// elements into a slice of Extension structs.
func ExtractExtensions(page pagination.Page) ([]common.Extension, error) {
+ r := page.(ExtensionPage)
// Identity v2 adds an intermediate "values" object.
-
- var resp struct {
+ var s struct {
Extensions struct {
- Values []common.Extension `mapstructure:"values"`
- } `mapstructure:"extensions"`
+ Values []common.Extension `json:"values"`
+ } `json:"extensions"`
}
-
- err := mapstructure.Decode(page.(ExtensionPage).Body, &resp)
- return resp.Extensions.Values, err
+ err := r.ExtractInto(&s)
+ return s.Extensions.Values, err
}
// Get retrieves information for a specific extension using its alias.
diff --git a/openstack/identity/v2/tenants/results.go b/openstack/identity/v2/tenants/results.go
index cee7568..bf52554 100644
--- a/openstack/identity/v2/tenants/results.go
+++ b/openstack/identity/v2/tenants/results.go
@@ -1,7 +1,6 @@
package tenants
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -9,16 +8,16 @@
// Tenant is a grouping of users in the identity service.
type Tenant struct {
// ID is a unique identifier for this tenant.
- ID string `mapstructure:"id"`
+ ID string `json:"id"`
// Name is a friendlier user-facing name for this tenant.
- Name string `mapstructure:"name"`
+ Name string `json:"name"`
// Description is a human-readable explanation of this Tenant's purpose.
- Description string `mapstructure:"description"`
+ Description string `json:"description"`
// Enabled indicates whether or not a tenant is active.
- Enabled bool `mapstructure:"enabled"`
+ Enabled bool `json:"enabled"`
}
// TenantPage is a single page of Tenant results.
@@ -29,34 +28,27 @@
// IsEmpty determines whether or not a page of Tenants contains any results.
func (page TenantPage) IsEmpty() (bool, error) {
tenants, err := ExtractTenants(page)
- if err != nil {
- return false, err
- }
- return len(tenants) == 0, nil
+ return len(tenants) == 0, err
}
// NextPageURL extracts the "next" link from the tenants_links section of the result.
func (page TenantPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"tenants_links"`
+ var s struct {
+ Links []gophercloud.Link `json:"tenants_links"`
}
-
- var r resp
- err := mapstructure.Decode(page.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// ExtractTenants returns a slice of Tenants contained in a single page of results.
func ExtractTenants(page pagination.Page) ([]Tenant, error) {
- casted := page.(TenantPage).Body
- var response struct {
- Tenants []Tenant `mapstructure:"tenants"`
+ r := page.(TenantPage)
+ var s struct {
+ Tenants []Tenant `json:"tenants"`
}
-
- err := mapstructure.Decode(casted, &response)
- return response.Tenants, err
+ err := r.ExtractInto(&s)
+ return s.Tenants, err
}
diff --git a/openstack/identity/v2/tokens/results.go b/openstack/identity/v2/tokens/results.go
index 9ef45b6..93c0554 100644
--- a/openstack/identity/v2/tokens/results.go
+++ b/openstack/identity/v2/tokens/results.go
@@ -3,7 +3,6 @@
import (
"time"
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/identity/v2/tenants"
)
@@ -25,15 +24,17 @@
Tenant tenants.Tenant
}
-// Authorization need user info which can get from token authentication's response
+// Role is a role for a user.
type Role struct {
- Name string `mapstructure:"name"`
+ Name string `json:"name"`
}
+
+// User is an OpenStack user.
type User struct {
- ID string `mapstructure:"id"`
- Name string `mapstructure:"name"`
- UserName string `mapstructure:"username"`
- Roles []Role `mapstructure:"roles"`
+ ID string `json:"id"`
+ Name string `json:"name"`
+ UserName string `json:"username"`
+ Roles []Role `json:"roles"`
}
// Endpoint represents a single API endpoint offered by a service.
@@ -45,14 +46,14 @@
//
// In all cases, fields which aren't supported by the provider and service combined will assume a zero-value ("").
type Endpoint struct {
- TenantID string `mapstructure:"tenantId"`
- PublicURL string `mapstructure:"publicURL"`
- InternalURL string `mapstructure:"internalURL"`
- AdminURL string `mapstructure:"adminURL"`
- Region string `mapstructure:"region"`
- VersionID string `mapstructure:"versionId"`
- VersionInfo string `mapstructure:"versionInfo"`
- VersionList string `mapstructure:"versionList"`
+ TenantID string `json:"tenantId"`
+ PublicURL string `json:"publicURL"`
+ InternalURL string `json:"internalURL"`
+ AdminURL string `json:"adminURL"`
+ Region string `json:"region"`
+ VersionID string `json:"versionId"`
+ VersionInfo string `json:"versionInfo"`
+ VersionList string `json:"versionList"`
}
// CatalogEntry provides a type-safe interface to an Identity API V2 service catalog listing.
@@ -63,15 +64,15 @@
// Otherwise, you'll tie the representation of the service to a specific provider.
type CatalogEntry struct {
// Name will contain the provider-specified name for the service.
- Name string `mapstructure:"name"`
+ Name string `json:"name"`
// Type will contain a type string if OpenStack defines a type for the service.
// Otherwise, for provider-specific services, the provider may assign their own type strings.
- Type string `mapstructure:"type"`
+ Type string `json:"type"`
// Endpoints will let the caller iterate over all the different endpoints that may exist for
// the service.
- Endpoints []Endpoint `mapstructure:"endpoints"`
+ Endpoints []Endpoint `json:"endpoints"`
}
// ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
@@ -92,56 +93,43 @@
}
// ExtractToken returns the just-created Token from a CreateResult.
-func (result CreateResult) ExtractToken() (*Token, error) {
- if result.Err != nil {
- return nil, result.Err
- }
-
- var response struct {
+func (r CreateResult) ExtractToken() (*Token, error) {
+ var s struct {
Access struct {
Token struct {
- Expires string `mapstructure:"expires"`
- ID string `mapstructure:"id"`
- Tenant tenants.Tenant `mapstructure:"tenant"`
- } `mapstructure:"token"`
- } `mapstructure:"access"`
+ Expires string `json:"expires"`
+ ID string `json:"id"`
+ Tenant tenants.Tenant `json:"tenant"`
+ } `json:"token"`
+ } `json:"access"`
}
- err := mapstructure.Decode(result.Body, &response)
+ err := r.ExtractInto(&s)
if err != nil {
return nil, err
}
- expiresTs, err := time.Parse(gophercloud.RFC3339Milli, response.Access.Token.Expires)
+ expiresTs, err := time.Parse(gophercloud.RFC3339Milli, s.Access.Token.Expires)
if err != nil {
return nil, err
}
return &Token{
- ID: response.Access.Token.ID,
+ ID: s.Access.Token.ID,
ExpiresAt: expiresTs,
- Tenant: response.Access.Token.Tenant,
+ Tenant: s.Access.Token.Tenant,
}, nil
}
// ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
-func (result CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
- if result.Err != nil {
- return nil, result.Err
- }
-
- var response struct {
+func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
+ var s struct {
Access struct {
- Entries []CatalogEntry `mapstructure:"serviceCatalog"`
- } `mapstructure:"access"`
+ Entries []CatalogEntry `json:"serviceCatalog"`
+ } `json:"access"`
}
-
- err := mapstructure.Decode(result.Body, &response)
- if err != nil {
- return nil, err
- }
-
- return &ServiceCatalog{Entries: response.Access.Entries}, nil
+ err := r.ExtractInto(&s)
+ return &ServiceCatalog{Entries: s.Access.Entries}, err
}
// createErr quickly packs an error in a CreateResult.
@@ -150,21 +138,12 @@
}
// ExtractUser returns the User from a GetResult.
-func (result GetResult) ExtractUser() (*User, error) {
- if result.Err != nil {
- return nil, result.Err
- }
-
- var response struct {
+func (r GetResult) ExtractUser() (*User, error) {
+ var s struct {
Access struct {
- User User `mapstructure:"user"`
- } `mapstructure:"access"`
+ User User `json:"user"`
+ } `json:"access"`
}
-
- err := mapstructure.Decode(result.Body, &response)
- if err != nil {
- return nil, err
- }
-
- return &response.Access.User, nil
+ err := r.ExtractInto(&s)
+ return &s.Access.User, err
}
diff --git a/openstack/identity/v2/users/results.go b/openstack/identity/v2/users/results.go
index 37ba1be..c353c61 100644
--- a/openstack/identity/v2/users/results.go
+++ b/openstack/identity/v2/users/results.go
@@ -1,8 +1,6 @@
package users
import (
- "github.com/mitchellh/mapstructure"
-
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -25,7 +23,7 @@
Email string
// The ID of the tenant to which this user belongs.
- TenantID string `mapstructure:"tenant_id"`
+ TenantID string `json:"tenant_id"`
}
// Role assigns specific responsibilities to users, allowing them to accomplish
@@ -51,41 +49,33 @@
// IsEmpty determines whether or not a page of Tenants contains any results.
func (page UserPage) IsEmpty() (bool, error) {
users, err := ExtractUsers(page)
- if err != nil {
- return false, err
- }
- return len(users) == 0, nil
+ return len(users) == 0, err
}
// ExtractUsers returns a slice of Tenants contained in a single page of results.
func ExtractUsers(page pagination.Page) ([]User, error) {
- casted := page.(UserPage).Body
- var response struct {
- Users []User `mapstructure:"users"`
+ r := page.(UserPage)
+ var s struct {
+ Users []User `json:"users"`
}
-
- err := mapstructure.Decode(casted, &response)
- return response.Users, err
+ err := r.ExtractInto(&s)
+ return s.Users, err
}
// IsEmpty determines whether or not a page of Tenants contains any results.
func (page RolePage) IsEmpty() (bool, error) {
users, err := ExtractRoles(page)
- if err != nil {
- return false, err
- }
- return len(users) == 0, nil
+ return len(users) == 0, err
}
// ExtractRoles returns a slice of Roles contained in a single page of results.
func ExtractRoles(page pagination.Page) ([]Role, error) {
- casted := page.(RolePage).Body
- var response struct {
- Roles []Role `mapstructure:"roles"`
+ r := page.(RolePage)
+ var s struct {
+ Roles []Role `json:"roles"`
}
-
- err := mapstructure.Decode(casted, &response)
- return response.Roles, err
+ err := r.ExtractInto(&s)
+ return s.Roles, err
}
type commonResult struct {
@@ -94,17 +84,11 @@
// Extract interprets any commonResult as a User, if possible.
func (r commonResult) Extract() (*User, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ User *User `json:"user"`
}
-
- var response struct {
- User User `mapstructure:"user"`
- }
-
- err := mapstructure.Decode(r.Body, &response)
-
- return &response.User, err
+ err := r.ExtractInto(&s)
+ return s.User, err
}
// CreateResult represents the result of a Create operation
diff --git a/openstack/identity/v3/endpoints/results.go b/openstack/identity/v3/endpoints/results.go
index 7c20b8c..09e58e5 100644
--- a/openstack/identity/v3/endpoints/results.go
+++ b/openstack/identity/v3/endpoints/results.go
@@ -1,7 +1,6 @@
package endpoints
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -13,17 +12,11 @@
// Extract interprets a GetResult, CreateResult or UpdateResult as a concrete Endpoint.
// An error is returned if the original call or the extraction failed.
func (r commonResult) Extract() (*Endpoint, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Endpoint *Endpoint `json:"endpoint"`
}
-
- var res struct {
- Endpoint `json:"endpoint"`
- }
-
- err := mapstructure.Decode(r.Body, &res)
-
- return &res.Endpoint, err
+ err := r.ExtractInto(&s)
+ return s.Endpoint, err
}
// CreateResult is the deferred result of a Create call.
@@ -48,12 +41,12 @@
// Endpoint describes the entry point for another service's API.
type Endpoint struct {
- ID string `mapstructure:"id" json:"id"`
- Availability gophercloud.Availability `mapstructure:"interface" json:"interface"`
- Name string `mapstructure:"name" json:"name"`
- Region string `mapstructure:"region" json:"region"`
- ServiceID string `mapstructure:"service_id" json:"service_id"`
- URL string `mapstructure:"url" json:"url"`
+ ID string `json:"id"`
+ Availability gophercloud.Availability `json:"interface"`
+ Name string `json:"name"`
+ Region string `json:"region"`
+ ServiceID string `json:"service_id"`
+ URL string `json:"url"`
}
// EndpointPage is a single page of Endpoint results.
@@ -64,19 +57,15 @@
// IsEmpty returns true if no Endpoints were returned.
func (p EndpointPage) IsEmpty() (bool, error) {
es, err := ExtractEndpoints(p)
- if err != nil {
- return true, err
- }
- return len(es) == 0, nil
+ return len(es) == 0, err
}
// ExtractEndpoints extracts an Endpoint slice from a Page.
func ExtractEndpoints(page pagination.Page) ([]Endpoint, error) {
- var response struct {
- Endpoints []Endpoint `mapstructure:"endpoints"`
+ r := page.(EndpointPage)
+ var s struct {
+ Endpoints []Endpoint `json:"endpoints"`
}
-
- err := mapstructure.Decode(page.(EndpointPage).Body, &response)
-
- return response.Endpoints, err
+ err := r.ExtractInto(&s)
+ return s.Endpoints, err
}
diff --git a/openstack/identity/v3/roles/results.go b/openstack/identity/v3/roles/results.go
index 75549d3..86f21a0 100644
--- a/openstack/identity/v3/roles/results.go
+++ b/openstack/identity/v3/roles/results.go
@@ -1,10 +1,6 @@
package roles
-import (
- "github.com/gophercloud/gophercloud/pagination"
-
- "github.com/mitchellh/mapstructure"
-)
+import "github.com/gophercloud/gophercloud/pagination"
// RoleAssignment is the result of a role assignments query.
type RoleAssignment struct {
@@ -20,7 +16,7 @@
type Scope struct {
Domain Domain `json:"domain,omitempty"`
- Project Project `json:"domain,omitempty"`
+ Project Project `json:"project,omitempty"`
}
type Domain struct {
@@ -47,35 +43,26 @@
// IsEmpty returns true if the page contains no results.
func (p RoleAssignmentsPage) IsEmpty() (bool, error) {
roleAssignments, err := ExtractRoleAssignments(p)
- if err != nil {
- return true, err
- }
- return len(roleAssignments) == 0, nil
+ return len(roleAssignments) == 0, err
}
// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
func (page RoleAssignmentsPage) NextPageURL() (string, error) {
- type resp struct {
+ var s struct {
Links struct {
- Next string `mapstructure:"next"`
- } `mapstructure:"links"`
+ Next string `json:"next"`
+ } `json:"links"`
}
-
- var r resp
- err := mapstructure.Decode(page.Body, &r)
- if err != nil {
- return "", err
- }
-
- return r.Links.Next, nil
+ err := page.ExtractInto(&s)
+ return s.Links.Next, err
}
// ExtractRoleAssignments extracts a slice of RoleAssignments from a Collection acquired from List.
func ExtractRoleAssignments(page pagination.Page) ([]RoleAssignment, error) {
- var response struct {
- RoleAssignments []RoleAssignment `mapstructure:"role_assignments"`
+ r := page.(RoleAssignmentsPage)
+ var s struct {
+ RoleAssignments []RoleAssignment `json:"role_assignments"`
}
-
- err := mapstructure.Decode(page.(RoleAssignmentsPage).Body, &response)
- return response.RoleAssignments, err
+ err := r.ExtractInto(&s)
+ return s.RoleAssignments, err
}
diff --git a/openstack/identity/v3/services/results.go b/openstack/identity/v3/services/results.go
index c55ee62..45040c6 100644
--- a/openstack/identity/v3/services/results.go
+++ b/openstack/identity/v3/services/results.go
@@ -3,8 +3,6 @@
import (
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
-
- "github.com/mitchellh/mapstructure"
)
type commonResult struct {
@@ -14,17 +12,11 @@
// Extract interprets a GetResult, CreateResult or UpdateResult as a concrete Service.
// An error is returned if the original call or the extraction failed.
func (r commonResult) Extract() (*Service, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Service *Service `json:"service"`
}
-
- var res struct {
- Service `json:"service"`
- }
-
- err := mapstructure.Decode(r.Body, &res)
-
- return &res.Service, err
+ err := r.ExtractInto(&s)
+ return s.Service, err
}
// CreateResult is the deferred result of a Create call.
@@ -63,18 +55,15 @@
// IsEmpty returns true if the page contains no results.
func (p ServicePage) IsEmpty() (bool, error) {
services, err := ExtractServices(p)
- if err != nil {
- return true, err
- }
- return len(services) == 0, nil
+ return len(services) == 0, err
}
// ExtractServices extracts a slice of Services from a Collection acquired from List.
func ExtractServices(page pagination.Page) ([]Service, error) {
- var response struct {
- Services []Service `mapstructure:"services"`
+ r := page.(ServicePage)
+ var s struct {
+ Services []Service `json:"services"`
}
-
- err := mapstructure.Decode(page.(ServicePage).Body, &response)
- return response.Services, err
+ err := r.ExtractInto(&s)
+ return s.Services, err
}
diff --git a/openstack/identity/v3/tokens/results.go b/openstack/identity/v3/tokens/results.go
index ec98c1c..7dd2c0b 100644
--- a/openstack/identity/v3/tokens/results.go
+++ b/openstack/identity/v3/tokens/results.go
@@ -3,7 +3,6 @@
import (
"time"
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
)
@@ -12,10 +11,10 @@
// If supported, it contains a region specifier, again if provided.
// The significance of the Region field will depend upon your provider.
type Endpoint struct {
- ID string `mapstructure:"id"`
- Region string `mapstructure:"region"`
- Interface string `mapstructure:"interface"`
- URL string `mapstructure:"url"`
+ ID string `json:"id"`
+ Region string `json:"region"`
+ Interface string `json:"interface"`
+ URL string `json:"url"`
}
// CatalogEntry provides a type-safe interface to an Identity API V3 service catalog listing.
@@ -27,18 +26,18 @@
type CatalogEntry struct {
// Service ID
- ID string `mapstructure:"id"`
+ ID string `json:"id"`
// Name will contain the provider-specified name for the service.
- Name string `mapstructure:"name"`
+ Name string `json:"name"`
// Type will contain a type string if OpenStack defines a type for the service.
// Otherwise, for provider-specific services, the provider may assign their own type strings.
- Type string `mapstructure:"type"`
+ Type string `json:"type"`
// Endpoints will let the caller iterate over all the different endpoints that may exist for
// the service.
- Endpoints []Endpoint `mapstructure:"endpoints"`
+ Endpoints []Endpoint `json:"endpoints"`
}
// ServiceCatalog provides a view into the service catalog from a previous, successful authentication.
@@ -59,14 +58,10 @@
// ExtractToken interprets a commonResult as a Token.
func (r commonResult) ExtractToken() (*Token, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var response struct {
+ var s struct {
Token struct {
- ExpiresAt string `mapstructure:"expires_at"`
- } `mapstructure:"token"`
+ ExpiresAt string `json:"expires_at"`
+ } `json:"token"`
}
var token Token
@@ -74,35 +69,26 @@
// Parse the token itself from the stored headers.
token.ID = r.Header.Get("X-Subject-Token")
- err := mapstructure.Decode(r.Body, &response)
+ err := r.ExtractInto(&s)
if err != nil {
return nil, err
}
// Attempt to parse the timestamp.
- token.ExpiresAt, err = time.Parse(gophercloud.RFC3339Milli, response.Token.ExpiresAt)
+ token.ExpiresAt, err = time.Parse(gophercloud.RFC3339Milli, s.Token.ExpiresAt)
return &token, err
}
// ExtractServiceCatalog returns the ServiceCatalog that was generated along with the user's Token.
-func (result CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
- if result.Err != nil {
- return nil, result.Err
- }
-
- var response struct {
+func (r CreateResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
+ var s struct {
Token struct {
- Entries []CatalogEntry `mapstructure:"catalog"`
- } `mapstructure:"token"`
+ Entries []CatalogEntry `json:"catalog"`
+ } `json:"token"`
}
-
- err := mapstructure.Decode(result.Body, &response)
- if err != nil {
- return nil, err
- }
-
- return &ServiceCatalog{Entries: response.Token.Entries}, nil
+ err := r.ExtractInto(&s)
+ return &ServiceCatalog{Entries: s.Token.Entries}, err
}
// CreateResult defers the interpretation of a created token.
diff --git a/openstack/networking/v2/apiversions/results.go b/openstack/networking/v2/apiversions/results.go
index 556b9aa..eff4485 100644
--- a/openstack/networking/v2/apiversions/results.go
+++ b/openstack/networking/v2/apiversions/results.go
@@ -1,15 +1,14 @@
package apiversions
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud/pagination"
)
// APIVersion represents an API version for Neutron. It contains the status of
// the API, and its unique ID.
type APIVersion struct {
- Status string `mapstructure:"status" json:"status"`
- ID string `mapstructure:"id" json:"id"`
+ Status string `son:"status"`
+ ID string `json:"id"`
}
// APIVersionPage is the page returned by a pager when traversing over a
@@ -21,29 +20,24 @@
// IsEmpty checks whether an APIVersionPage struct is empty.
func (r APIVersionPage) IsEmpty() (bool, error) {
is, err := ExtractAPIVersions(r)
- if err != nil {
- return true, err
- }
- return len(is) == 0, nil
+ return len(is) == 0, err
}
// ExtractAPIVersions takes a collection page, extracts all of the elements,
// and returns them a slice of APIVersion structs. It is effectively a cast.
-func ExtractAPIVersions(page pagination.Page) ([]APIVersion, error) {
- var resp struct {
- Versions []APIVersion `mapstructure:"versions"`
+func ExtractAPIVersions(r pagination.Page) ([]APIVersion, error) {
+ var s struct {
+ Versions []APIVersion `json:"versions"`
}
-
- err := mapstructure.Decode(page.(APIVersionPage).Body, &resp)
-
- return resp.Versions, err
+ err := (r.(APIVersionPage)).ExtractInto(&s)
+ return s.Versions, err
}
// APIVersionResource represents a generic API resource. It contains the name
// of the resource and its plural collection name.
type APIVersionResource struct {
- Name string `mapstructure:"name" json:"name"`
- Collection string `mapstructure:"collection" json:"collection"`
+ Name string `json:"name"`
+ Collection string `json:"collection"`
}
// APIVersionResourcePage is a concrete type which embeds the common
@@ -56,22 +50,17 @@
// APIVersionResourcePage is empty or not.
func (r APIVersionResourcePage) IsEmpty() (bool, error) {
is, err := ExtractVersionResources(r)
- if err != nil {
- return true, err
- }
- return len(is) == 0, nil
+ return len(is) == 0, err
}
// ExtractVersionResources accepts a Page struct, specifically a
// APIVersionResourcePage struct, and extracts the elements into a slice of
// APIVersionResource structs. In other words, the collection is mapped into
// a relevant slice.
-func ExtractVersionResources(page pagination.Page) ([]APIVersionResource, error) {
- var resp struct {
- APIVersionResources []APIVersionResource `mapstructure:"resources"`
+func ExtractVersionResources(r pagination.Page) ([]APIVersionResource, error) {
+ var s struct {
+ APIVersionResources []APIVersionResource `json:"resources"`
}
-
- err := mapstructure.Decode(page.(APIVersionResourcePage).Body, &resp)
-
- return resp.APIVersionResources, err
+ err := (r.(APIVersionResourcePage)).ExtractInto(&s)
+ return s.APIVersionResources, err
}
diff --git a/openstack/networking/v2/extensions/external/results.go b/openstack/networking/v2/extensions/external/results.go
index c5d5f14..2c5173a 100644
--- a/openstack/networking/v2/extensions/external/results.go
+++ b/openstack/networking/v2/extensions/external/results.go
@@ -1,7 +1,6 @@
package external
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -10,72 +9,69 @@
// "external-net" extension.
type NetworkExternal struct {
// UUID for the network
- ID string `mapstructure:"id" json:"id"`
+ ID string `json:"id"`
// Human-readable name for the network. Might not be unique.
- Name string `mapstructure:"name" json:"name"`
+ Name string `json:"name"`
// The administrative state of network. If false (down), the network does not forward packets.
- AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"`
+ AdminStateUp bool `json:"admin_state_up"`
// Indicates whether network is currently operational. Possible values include
// `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional values.
- Status string `mapstructure:"status" json:"status"`
+ Status string `json:"status"`
// Subnets associated with this network.
- Subnets []string `mapstructure:"subnets" json:"subnets"`
+ Subnets []string `json:"subnets"`
// Owner of network. Only admin users can specify a tenant_id other than its own.
- TenantID string `mapstructure:"tenant_id" json:"tenant_id"`
+ TenantID string `json:"tenant_id"`
// Specifies whether the network resource can be accessed by any tenant or not.
- Shared bool `mapstructure:"shared" json:"shared"`
+ Shared bool `json:"shared"`
// Specifies whether the network is an external network or not.
- External bool `mapstructure:"router:external" json:"router:external"`
-}
-
-func commonExtract(e error, response interface{}) (*NetworkExternal, error) {
- if e != nil {
- return nil, e
- }
-
- var res struct {
- Network *NetworkExternal `json:"network"`
- }
-
- err := mapstructure.Decode(response, &res)
-
- return res.Network, err
+ External bool `json:"router:external"`
}
// ExtractGet decorates a GetResult struct returned from a networks.Get()
// function with extended attributes.
func ExtractGet(r networks.GetResult) (*NetworkExternal, error) {
- return commonExtract(r.Err, r.Body)
+ var s struct {
+ Network *NetworkExternal `json:"network"`
+ }
+ err := r.ExtractInto(&s)
+ return s.Network, err
}
// ExtractCreate decorates a CreateResult struct returned from a networks.Create()
// function with extended attributes.
func ExtractCreate(r networks.CreateResult) (*NetworkExternal, error) {
- return commonExtract(r.Err, r.Body)
+ var s struct {
+ Network *NetworkExternal `json:"network"`
+ }
+ err := r.ExtractInto(&s)
+ return s.Network, err
}
// ExtractUpdate decorates a UpdateResult struct returned from a
// networks.Update() function with extended attributes.
func ExtractUpdate(r networks.UpdateResult) (*NetworkExternal, error) {
- return commonExtract(r.Err, r.Body)
+ var s struct {
+ Network *NetworkExternal `json:"network"`
+ }
+ err := r.ExtractInto(&s)
+ return s.Network, err
}
// ExtractList accepts a Page struct, specifically a NetworkPage struct, and
// extracts the elements into a slice of NetworkExternal structs. In other
// words, a generic collection is mapped into a relevant slice.
func ExtractList(page pagination.Page) ([]NetworkExternal, error) {
- var resp struct {
- Networks []NetworkExternal `mapstructure:"networks" json:"networks"`
+ r := page.(networks.NetworkPage)
+ var s struct {
+ Networks []NetworkExternal `json:"networks" json:"networks"`
}
-
- err := mapstructure.Decode(page.(networks.NetworkPage).Body, &resp)
-
- return resp.Networks, err
+ err := r.ExtractInto(&s)
+ return s.Networks, err
}
diff --git a/openstack/networking/v2/extensions/fwaas/firewalls/results.go b/openstack/networking/v2/extensions/fwaas/firewalls/results.go
index 5af4b88..2b4338c 100644
--- a/openstack/networking/v2/extensions/fwaas/firewalls/results.go
+++ b/openstack/networking/v2/extensions/fwaas/firewalls/results.go
@@ -1,19 +1,19 @@
package firewalls
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
+// Firewall is an OpenStack firewall.
type Firewall struct {
- ID string `json:"id" mapstructure:"id"`
- Name string `json:"name" mapstructure:"name"`
- Description string `json:"description" mapstructure:"description"`
- AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"`
- Status string `json:"status" mapstructure:"status"`
- PolicyID string `json:"firewall_policy_id" mapstructure:"firewall_policy_id"`
- TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
+ ID string `json:"id"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ AdminStateUp bool `json:"admin_state_up"`
+ Status string `json:"status"`
+ PolicyID string `json:"firewall_policy_id"`
+ TenantID string `json:"tenant_id"`
}
type commonResult struct {
@@ -22,17 +22,11 @@
// Extract is a function that accepts a result and extracts a firewall.
func (r commonResult) Extract() (*Firewall, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res struct {
+ var s struct {
Firewall *Firewall `json:"firewall"`
}
-
- err := mapstructure.Decode(r.Body, &res)
-
- return res.Firewall, err
+ err := r.ExtractInto(&s)
+ return s.Firewall, err
}
// FirewallPage is the page returned by a pager when traversing over a
@@ -44,40 +38,32 @@
// NextPageURL is invoked when a paginated collection of firewalls has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
-func (p FirewallPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"firewalls_links"`
+func (page FirewallPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"firewalls_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a FirewallPage struct is empty.
-func (p FirewallPage) IsEmpty() (bool, error) {
- is, err := ExtractFirewalls(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+func (page FirewallPage) IsEmpty() (bool, error) {
+ is, err := ExtractFirewalls(page)
+ return len(is) == 0, err
}
// ExtractFirewalls accepts a Page struct, specifically a RouterPage struct,
// and extracts the elements into a slice of Router structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractFirewalls(page pagination.Page) ([]Firewall, error) {
- var resp struct {
- Firewalls []Firewall `mapstructure:"firewalls" json:"firewalls"`
+ var s struct {
+ Firewalls []Firewall `json:"firewalls" json:"firewalls"`
}
-
- err := mapstructure.Decode(page.(FirewallPage).Body, &resp)
-
- return resp.Firewalls, err
+ err := (page.(FirewallPage)).ExtractInto(&s)
+ return s.Firewalls, err
}
// GetResult represents the result of a get operation.
diff --git a/openstack/networking/v2/extensions/fwaas/policies/results.go b/openstack/networking/v2/extensions/fwaas/policies/results.go
index 9a6d563..d23c81d 100644
--- a/openstack/networking/v2/extensions/fwaas/policies/results.go
+++ b/openstack/networking/v2/extensions/fwaas/policies/results.go
@@ -1,19 +1,19 @@
package policies
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
+// Policy is a firewall policy.
type Policy struct {
- ID string `json:"id" mapstructure:"id"`
- Name string `json:"name" mapstructure:"name"`
- Description string `json:"description" mapstructure:"description"`
- TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
- Audited bool `json:"audited" mapstructure:"audited"`
- Shared bool `json:"shared" mapstructure:"shared"`
- Rules []string `json:"firewall_rules,omitempty" mapstructure:"firewall_rules"`
+ ID string `json:"id"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ TenantID string `json:"tenant_id"`
+ Audited bool `json:"audited"`
+ Shared bool `json:"shared"`
+ Rules []string `json:"firewall_rules,omitempty"`
}
type commonResult struct {
@@ -22,17 +22,11 @@
// Extract is a function that accepts a result and extracts a firewall policy.
func (r commonResult) Extract() (*Policy, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Policy *Policy `json:"firewall_policy"`
}
-
- var res struct {
- Policy *Policy `json:"firewall_policy" mapstructure:"firewall_policy"`
- }
-
- err := mapstructure.Decode(r.Body, &res)
-
- return res.Policy, err
+ err := r.ExtractInto(&s)
+ return s.Policy, err
}
// PolicyPage is the page returned by a pager when traversing over a
@@ -44,40 +38,32 @@
// NextPageURL is invoked when a paginated collection of firewall policies has
// reached the end of a page and the pager seeks to traverse over a new one.
// In order to do this, it needs to construct the next page's URL.
-func (p PolicyPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"firewall_policies_links"`
+func (page PolicyPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"firewall_policies_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a PolicyPage struct is empty.
-func (p PolicyPage) IsEmpty() (bool, error) {
- is, err := ExtractPolicies(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+func (page PolicyPage) IsEmpty() (bool, error) {
+ is, err := ExtractPolicies(page)
+ return len(is) == 0, err
}
// ExtractPolicies accepts a Page struct, specifically a RouterPage struct,
// and extracts the elements into a slice of Router structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractPolicies(page pagination.Page) ([]Policy, error) {
- var resp struct {
- Policies []Policy `mapstructure:"firewall_policies" json:"firewall_policies"`
+ var s struct {
+ Policies []Policy `json:"firewall_policies"`
}
-
- err := mapstructure.Decode(page.(PolicyPage).Body, &resp)
-
- return resp.Policies, err
+ err := (page.(PolicyPage)).ExtractInto(&s)
+ return s.Policies, err
}
// GetResult represents the result of a get operation.
diff --git a/openstack/networking/v2/extensions/fwaas/rules/results.go b/openstack/networking/v2/extensions/fwaas/rules/results.go
index 42604f4..4afdf22 100644
--- a/openstack/networking/v2/extensions/fwaas/rules/results.go
+++ b/openstack/networking/v2/extensions/fwaas/rules/results.go
@@ -1,28 +1,27 @@
package rules
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
// Rule represents a firewall rule
type Rule struct {
- ID string `json:"id" mapstructure:"id"`
- Name string `json:"name,omitempty" mapstructure:"name"`
- Description string `json:"description,omitempty" mapstructure:"description"`
- Protocol string `json:"protocol" mapstructure:"protocol"`
- Action string `json:"action" mapstructure:"action"`
- IPVersion int `json:"ip_version,omitempty" mapstructure:"ip_version"`
- SourceIPAddress string `json:"source_ip_address,omitempty" mapstructure:"source_ip_address"`
- DestinationIPAddress string `json:"destination_ip_address,omitempty" mapstructure:"destination_ip_address"`
- SourcePort string `json:"source_port,omitempty" mapstructure:"source_port"`
- DestinationPort string `json:"destination_port,omitempty" mapstructure:"destination_port"`
- Shared bool `json:"shared,omitempty" mapstructure:"shared"`
- Enabled bool `json:"enabled,omitempty" mapstructure:"enabled"`
- PolicyID string `json:"firewall_policy_id" mapstructure:"firewall_policy_id"`
- Position int `json:"position" mapstructure:"position"`
- TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
+ ID string `json:"id"`
+ Name string `json:"name,omitempty"`
+ Description string `json:"description,omitempty"`
+ Protocol string `json:"protocol"`
+ Action string `json:"action"`
+ IPVersion int `json:"ip_version,omitempty"`
+ SourceIPAddress string `json:"source_ip_address,omitempty"`
+ DestinationIPAddress string `json:"destination_ip_address,omitempty"`
+ SourcePort string `json:"source_port,omitempty"`
+ DestinationPort string `json:"destination_port,omitempty"`
+ Shared bool `json:"shared,omitempty"`
+ Enabled bool `json:"enabled,omitempty"`
+ PolicyID string `json:"firewall_policy_id"`
+ Position int `json:"position"`
+ TenantID string `json:"tenant_id"`
}
// RulePage is the page returned by a pager when traversing over a
@@ -34,40 +33,33 @@
// NextPageURL is invoked when a paginated collection of firewall rules has
// reached the end of a page and the pager seeks to traverse over a new one.
// In order to do this, it needs to construct the next page's URL.
-func (p RulePage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"firewall_rules_links"`
+func (page RulePage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"firewall_rules_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a RulePage struct is empty.
func (p RulePage) IsEmpty() (bool, error) {
is, err := ExtractRules(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+ return len(is) == 0, err
}
// ExtractRules accepts a Page struct, specifically a RouterPage struct,
// and extracts the elements into a slice of Router structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractRules(page pagination.Page) ([]Rule, error) {
- var resp struct {
- Rules []Rule `mapstructure:"firewall_rules" json:"firewall_rules"`
+ r := page.(RulePage)
+ var s struct {
+ Rules []Rule `json:"firewall_rules"`
}
-
- err := mapstructure.Decode(page.(RulePage).Body, &resp)
-
- return resp.Rules, err
+ err := r.ExtractInto(&s)
+ return s.Rules, err
}
type commonResult struct {
@@ -76,17 +68,11 @@
// Extract is a function that accepts a result and extracts a firewall rule.
func (r commonResult) Extract() (*Rule, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Rule *Rule `json:"firewall_rule"`
}
-
- var res struct {
- Rule *Rule `json:"firewall_rule" mapstructure:"firewall_rule"`
- }
-
- err := mapstructure.Decode(r.Body, &res)
-
- return res.Rule, err
+ err := r.ExtractInto(&s)
+ return s.Rule, err
}
// GetResult represents the result of a get operation.
diff --git a/openstack/networking/v2/extensions/layer3/floatingips/results.go b/openstack/networking/v2/extensions/layer3/floatingips/results.go
index 264b7a8..c33b139 100644
--- a/openstack/networking/v2/extensions/layer3/floatingips/results.go
+++ b/openstack/networking/v2/extensions/layer3/floatingips/results.go
@@ -1,9 +1,6 @@
package floatingips
import (
- "fmt"
-
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -16,27 +13,27 @@
// attribute (provided by the external network extension) is set to True.
type FloatingIP struct {
// Unique identifier for the floating IP instance.
- ID string `json:"id" mapstructure:"id"`
+ ID string `json:"id"`
// UUID of the external network where the floating IP is to be created.
- FloatingNetworkID string `json:"floating_network_id" mapstructure:"floating_network_id"`
+ FloatingNetworkID string `json:"floating_network_id"`
// Address of the floating IP on the external network.
- FloatingIP string `json:"floating_ip_address" mapstructure:"floating_ip_address"`
+ FloatingIP string `json:"floating_ip_address"`
// UUID of the port on an internal network that is associated with the floating IP.
- PortID string `json:"port_id" mapstructure:"port_id"`
+ PortID string `json:"port_id"`
// The specific IP address of the internal port which should be associated
// with the floating IP.
- FixedIP string `json:"fixed_ip_address" mapstructure:"fixed_ip_address"`
+ FixedIP string `json:"fixed_ip_address"`
// Owner of the floating IP. Only admin users can specify a tenant identifier
// other than its own.
- TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
+ TenantID string `json:"tenant_id"`
// The condition of the API resource.
- Status string `json:"status" mapstructure:"status"`
+ Status string `json:"status"`
}
type commonResult struct {
@@ -45,20 +42,11 @@
// Extract a result and extracts a FloatingIP resource.
func (r commonResult) Extract() (*FloatingIP, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res struct {
+ var s struct {
FloatingIP *FloatingIP `json:"floatingip"`
}
-
- err := mapstructure.Decode(r.Body, &res)
- if err != nil {
- return nil, fmt.Errorf("Error decoding Neutron floating IP: %v", err)
- }
-
- return res.FloatingIP, nil
+ err := r.ExtractInto(&s)
+ return s.FloatingIP, err
}
// CreateResult represents the result of a create operation.
@@ -90,38 +78,31 @@
// NextPageURL is invoked when a paginated collection of floating IPs has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
-func (p FloatingIPPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"floatingips_links"`
+func (page FloatingIPPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"floatingips_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a NetworkPage struct is empty.
-func (p FloatingIPPage) IsEmpty() (bool, error) {
- is, err := ExtractFloatingIPs(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+func (page FloatingIPPage) IsEmpty() (bool, error) {
+ is, err := ExtractFloatingIPs(page)
+ return len(is) == 0, err
}
// ExtractFloatingIPs accepts a Page struct, specifically a FloatingIPPage struct,
// and extracts the elements into a slice of FloatingIP structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractFloatingIPs(page pagination.Page) ([]FloatingIP, error) {
- var resp struct {
- FloatingIPs []FloatingIP `mapstructure:"floatingips" json:"floatingips"`
+ r := page.(FloatingIPPage)
+ var s struct {
+ FloatingIPs []FloatingIP `json:"floatingips"`
}
-
- err := mapstructure.Decode(page.(FloatingIPPage).Body, &resp)
-
- return resp.FloatingIPs, err
+ err := r.ExtractInto(&s)
+ return s.FloatingIPs, err
}
diff --git a/openstack/networking/v2/extensions/layer3/routers/results.go b/openstack/networking/v2/extensions/layer3/routers/results.go
index 2360501..e26f243 100644
--- a/openstack/networking/v2/extensions/layer3/routers/results.go
+++ b/openstack/networking/v2/extensions/layer3/routers/results.go
@@ -1,7 +1,6 @@
package routers
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -9,12 +8,13 @@
// GatewayInfo represents the information of an external gateway for any
// particular network router.
type GatewayInfo struct {
- NetworkID string `json:"network_id" mapstructure:"network_id"`
+ NetworkID string `json:"network_id"`
}
+// Route is a possible route in a router.
type Route struct {
- NextHop string `mapstructure:"nexthop" json:"nexthop"`
- DestinationCIDR string `mapstructure:"destination" json:"destination"`
+ NextHop string `json:"nexthop"`
+ DestinationCIDR string `json:"destination"`
}
// Router represents a Neutron router. A router is a logical entity that
@@ -27,28 +27,28 @@
// interface is added to the subnet's network.
type Router struct {
// Indicates whether or not a router is currently operational.
- Status string `json:"status" mapstructure:"status"`
+ Status string `json:"status"`
// Information on external gateway for the router.
- GatewayInfo GatewayInfo `json:"external_gateway_info" mapstructure:"external_gateway_info"`
+ GatewayInfo GatewayInfo `json:"external_gateway_info"`
// Administrative state of the router.
- AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"`
+ AdminStateUp bool `json:"admin_state_up"`
// Whether router is disitrubted or not..
- Distributed bool `json:"distributed" mapstructure:"distributed"`
+ Distributed bool `json:"distributed"`
// Human readable name for the router. Does not have to be unique.
- Name string `json:"name" mapstructure:"name"`
+ Name string `json:"name"`
// Unique identifier for the router.
- ID string `json:"id" mapstructure:"id"`
+ ID string `json:"id"`
// Owner of the router. Only admin users can specify a tenant identifier
// other than its own.
- TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
+ TenantID string `json:"tenant_id"`
- Routes []Route `json:"routes" mapstructure:"routes"`
+ Routes []Route `json:"routes"`
}
// RouterPage is the page returned by a pager when traversing over a
@@ -60,40 +60,33 @@
// NextPageURL is invoked when a paginated collection of routers has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
-func (p RouterPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"routers_links"`
+func (page RouterPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"routers_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a RouterPage struct is empty.
-func (p RouterPage) IsEmpty() (bool, error) {
- is, err := ExtractRouters(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+func (page RouterPage) IsEmpty() (bool, error) {
+ is, err := ExtractRouters(page)
+ return len(is) == 0, err
}
// ExtractRouters accepts a Page struct, specifically a RouterPage struct,
// and extracts the elements into a slice of Router structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractRouters(page pagination.Page) ([]Router, error) {
- var resp struct {
- Routers []Router `mapstructure:"routers" json:"routers"`
+ r := page.(RouterPage)
+ var s struct {
+ Routers []Router `json:"routers"`
}
-
- err := mapstructure.Decode(page.(RouterPage).Body, &resp)
-
- return resp.Routers, err
+ err := r.ExtractInto(&s)
+ return s.Routers, err
}
type commonResult struct {
@@ -102,17 +95,11 @@
// Extract is a function that accepts a result and extracts a router.
func (r commonResult) Extract() (*Router, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res struct {
+ var s struct {
Router *Router `json:"router"`
}
-
- err := mapstructure.Decode(r.Body, &res)
-
- return res.Router, err
+ err := r.ExtractInto(&s)
+ return s.Router, err
}
// CreateResult represents the result of a create operation.
@@ -140,16 +127,16 @@
// interface.
type InterfaceInfo struct {
// The ID of the subnet which this interface is associated with.
- SubnetID string `json:"subnet_id" mapstructure:"subnet_id"`
+ SubnetID string `json:"subnet_id"`
// The ID of the port that is a part of the subnet.
- PortID string `json:"port_id" mapstructure:"port_id"`
+ PortID string `json:"port_id"`
// The UUID of the interface.
- ID string `json:"id" mapstructure:"id"`
+ ID string `json:"id"`
// Owner of the interface.
- TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
+ TenantID string `json:"tenant_id"`
}
// InterfaceResult represents the result of interface operations, such as
@@ -160,12 +147,7 @@
// Extract is a function that accepts a result and extracts an information struct.
func (r InterfaceResult) Extract() (*InterfaceInfo, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res *InterfaceInfo
- err := mapstructure.Decode(r.Body, &res)
-
- return res, err
+ var s InterfaceInfo
+ err := r.ExtractInto(&s)
+ return &s, err
}
diff --git a/openstack/networking/v2/extensions/lbaas/members/results.go b/openstack/networking/v2/extensions/lbaas/members/results.go
index b948706..ae9f341 100644
--- a/openstack/networking/v2/extensions/lbaas/members/results.go
+++ b/openstack/networking/v2/extensions/lbaas/members/results.go
@@ -1,7 +1,6 @@
package members
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -15,20 +14,20 @@
Weight int
// The administrative state of the member, which is up (true) or down (false).
- AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"`
+ AdminStateUp bool `json:"admin_state_up"`
// Owner of the member. Only an administrative user can specify a tenant ID
// other than its own.
- TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
+ TenantID string `json:"tenant_id"`
// The pool to which the member belongs.
- PoolID string `json:"pool_id" mapstructure:"pool_id"`
+ PoolID string `json:"pool_id"`
// The IP address of the member.
Address string
// The port on which the application is hosted.
- ProtocolPort int `json:"protocol_port" mapstructure:"protocol_port"`
+ ProtocolPort int `json:"protocol_port"`
// The unique ID for the member.
ID string
@@ -43,43 +42,33 @@
// NextPageURL is invoked when a paginated collection of members has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
-func (p MemberPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"members_links"`
+func (page MemberPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"members_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a MemberPage struct is empty.
-func (p MemberPage) IsEmpty() (bool, error) {
- is, err := ExtractMembers(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+func (page MemberPage) IsEmpty() (bool, error) {
+ is, err := ExtractMembers(page)
+ return len(is) == 0, err
}
// ExtractMembers accepts a Page struct, specifically a MemberPage struct,
// and extracts the elements into a slice of Member structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractMembers(page pagination.Page) ([]Member, error) {
- var resp struct {
- Members []Member `mapstructure:"members" json:"members"`
+ r := page.(MemberPage)
+ var s struct {
+ Members []Member `json:"members"`
}
-
- err := mapstructure.Decode(page.(MemberPage).Body, &resp)
- if err != nil {
- return nil, err
- }
-
- return resp.Members, nil
+ err := r.ExtractInto(&s)
+ return s.Members, err
}
type commonResult struct {
@@ -88,17 +77,11 @@
// Extract is a function that accepts a result and extracts a router.
func (r commonResult) Extract() (*Member, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res struct {
+ var s struct {
Member *Member `json:"member"`
}
-
- err := mapstructure.Decode(r.Body, &res)
-
- return res.Member, err
+ err := r.ExtractInto(&s)
+ return s.Member, err
}
// CreateResult represents the result of a create operation.
diff --git a/openstack/networking/v2/extensions/lbaas/monitors/results.go b/openstack/networking/v2/extensions/lbaas/monitors/results.go
index 5303df5..86c24bd 100644
--- a/openstack/networking/v2/extensions/lbaas/monitors/results.go
+++ b/openstack/networking/v2/extensions/lbaas/monitors/results.go
@@ -1,7 +1,6 @@
package monitors
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -27,7 +26,7 @@
// Owner of the VIP. Only an administrative user can specify a tenant ID
// other than its own.
- TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
+ TenantID string `json:"tenant_id"`
// The type of probe sent by the load balancer to verify the member state,
// which is PING, TCP, HTTP, or HTTPS.
@@ -42,20 +41,20 @@
// Number of allowed connection failures before changing the status of the
// member to INACTIVE. A valid value is from 1 to 10.
- MaxRetries int `json:"max_retries" mapstructure:"max_retries"`
+ MaxRetries int `json:"max_retries"`
// The HTTP method that the monitor uses for requests.
- HTTPMethod string `json:"http_method" mapstructure:"http_method"`
+ HTTPMethod string `json:"http_method"`
// The HTTP path of the request sent by the monitor to test the health of a
// member. Must be a string beginning with a forward slash (/).
- URLPath string `json:"url_path" mapstructure:"url_path"`
+ URLPath string `json:"url_path"`
// Expected HTTP codes for a passing HTTP(S) monitor.
- ExpectedCodes string `json:"expected_codes" mapstructure:"expected_codes"`
+ ExpectedCodes string `json:"expected_codes"`
// The administrative state of the health monitor, which is up (true) or down (false).
- AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"`
+ AdminStateUp bool `json:"admin_state_up"`
// The status of the health monitor. Indicates whether the health monitor is
// operational.
@@ -71,40 +70,34 @@
// NextPageURL is invoked when a paginated collection of monitors has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
-func (p MonitorPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"health_monitors_links"`
+func (page MonitorPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"health_monitors_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a PoolPage struct is empty.
-func (p MonitorPage) IsEmpty() (bool, error) {
- is, err := ExtractMonitors(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+func (page MonitorPage) IsEmpty() (bool, error) {
+ is, err := ExtractMonitors(page)
+ return len(is) == 0, err
}
// ExtractMonitors accepts a Page struct, specifically a MonitorPage struct,
// and extracts the elements into a slice of Monitor structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractMonitors(page pagination.Page) ([]Monitor, error) {
- var resp struct {
- Monitors []Monitor `mapstructure:"health_monitors" json:"health_monitors"`
+ r := page.(MonitorPage)
+ var s struct {
+ Monitors []Monitor `json:"health_monitors"`
}
-
- err := mapstructure.Decode(page.(MonitorPage).Body, &resp)
-
- return resp.Monitors, err
+ err := r.ExtractInto(&s)
+ return s.Monitors, err
}
type commonResult struct {
@@ -113,17 +106,11 @@
// Extract is a function that accepts a result and extracts a monitor.
func (r commonResult) Extract() (*Monitor, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Monitor *Monitor `json:"health_monitor"`
}
-
- var res struct {
- Monitor *Monitor `json:"health_monitor" mapstructure:"health_monitor"`
- }
-
- err := mapstructure.Decode(r.Body, &res)
-
- return res.Monitor, err
+ err := r.ExtractInto(&s)
+ return s.Monitor, err
}
// CreateResult represents the result of a create operation.
diff --git a/openstack/networking/v2/extensions/lbaas/pools/results.go b/openstack/networking/v2/extensions/lbaas/pools/results.go
index 3308002..135046a 100644
--- a/openstack/networking/v2/extensions/lbaas/pools/results.go
+++ b/openstack/networking/v2/extensions/lbaas/pools/results.go
@@ -1,7 +1,6 @@
package pools
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -18,7 +17,7 @@
// The load-balancer algorithm, which is round-robin, least-connections, and
// so on. This value, which must be supported, is dependent on the provider.
// Round-robin must be supported.
- LBMethod string `json:"lb_method" mapstructure:"lb_method"`
+ LBMethod string `json:"lb_method"`
// The protocol of the pool, which is TCP, HTTP, or HTTPS.
Protocol string
@@ -27,30 +26,30 @@
Description string
// The IDs of associated monitors which check the health of the pool members.
- MonitorIDs []string `json:"health_monitors" mapstructure:"health_monitors"`
+ MonitorIDs []string `json:"health_monitors"`
// The network on which the members of the pool will be located. Only members
// that are on this network can be added to the pool.
- SubnetID string `json:"subnet_id" mapstructure:"subnet_id"`
+ SubnetID string `json:"subnet_id"`
// Owner of the pool. Only an administrative user can specify a tenant ID
// other than its own.
- TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
+ TenantID string `json:"tenant_id"`
// The administrative state of the pool, which is up (true) or down (false).
- AdminStateUp bool `json:"admin_state_up" mapstructure:"admin_state_up"`
+ AdminStateUp bool `json:"admin_state_up"`
// Pool name. Does not have to be unique.
Name string
// List of member IDs that belong to the pool.
- MemberIDs []string `json:"members" mapstructure:"members"`
+ MemberIDs []string `json:"members"`
// The unique ID for the pool.
ID string
// The ID of the virtual IP associated with this pool
- VIPID string `json:"vip_id" mapstructure:"vip_id"`
+ VIPID string `json:"vip_id"`
// The provider
Provider string
@@ -65,40 +64,33 @@
// NextPageURL is invoked when a paginated collection of pools has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
-func (p PoolPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"pools_links"`
+func (page PoolPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"pools_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a PoolPage struct is empty.
-func (p PoolPage) IsEmpty() (bool, error) {
- is, err := ExtractPools(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+func (page PoolPage) IsEmpty() (bool, error) {
+ is, err := ExtractPools(page)
+ return len(is) == 0, err
}
// ExtractPools accepts a Page struct, specifically a RouterPage struct,
// and extracts the elements into a slice of Router structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractPools(page pagination.Page) ([]Pool, error) {
- var resp struct {
- Pools []Pool `mapstructure:"pools" json:"pools"`
+ r := page.(PoolPage)
+ var s struct {
+ Pools []Pool `json:"pools"`
}
-
- err := mapstructure.Decode(page.(PoolPage).Body, &resp)
-
- return resp.Pools, err
+ err := r.ExtractInto(&s)
+ return s.Pools, err
}
type commonResult struct {
@@ -107,17 +99,11 @@
// Extract is a function that accepts a result and extracts a router.
func (r commonResult) Extract() (*Pool, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res struct {
+ var s struct {
Pool *Pool `json:"pool"`
}
-
- err := mapstructure.Decode(r.Body, &res)
-
- return res.Pool, err
+ err := r.ExtractInto(&s)
+ return s.Pool, err
}
// CreateResult represents the result of a create operation.
diff --git a/openstack/networking/v2/extensions/lbaas/vips/results.go b/openstack/networking/v2/extensions/lbaas/vips/results.go
index d7322ca..398c981 100644
--- a/openstack/networking/v2/extensions/lbaas/vips/results.go
+++ b/openstack/networking/v2/extensions/lbaas/vips/results.go
@@ -1,7 +1,6 @@
package vips
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -23,10 +22,10 @@
// same member of the pool.
type SessionPersistence struct {
// The type of persistence mode
- Type string `mapstructure:"type" json:"type"`
+ Type string `json:"type"`
// Name of cookie if persistence mode is set appropriately
- CookieName string `mapstructure:"cookie_name" json:"cookie_name,omitempty"`
+ CookieName string `json:"cookie_name,omitempty"`
}
// VirtualIP is the primary load balancing configuration object that specifies
@@ -36,49 +35,49 @@
// server", a "vserver" or a "listener".
type VirtualIP struct {
// The unique ID for the VIP.
- ID string `mapstructure:"id" json:"id"`
+ ID string `json:"id"`
// Owner of the VIP. Only an admin user can specify a tenant ID other than its own.
- TenantID string `mapstructure:"tenant_id" json:"tenant_id"`
+ TenantID string `json:"tenant_id"`
// Human-readable name for the VIP. Does not have to be unique.
- Name string `mapstructure:"name" json:"name"`
+ Name string `json:"name"`
// Human-readable description for the VIP.
- Description string `mapstructure:"description" json:"description"`
+ Description string `json:"description"`
// The ID of the subnet on which to allocate the VIP address.
- SubnetID string `mapstructure:"subnet_id" json:"subnet_id"`
+ SubnetID string `json:"subnet_id"`
// The IP address of the VIP.
- Address string `mapstructure:"address" json:"address"`
+ Address string `json:"address"`
// The protocol of the VIP address. A valid value is TCP, HTTP, or HTTPS.
- Protocol string `mapstructure:"protocol" json:"protocol"`
+ Protocol string `json:"protocol"`
// The port on which to listen to client traffic that is associated with the
// VIP address. A valid value is from 0 to 65535.
- ProtocolPort int `mapstructure:"protocol_port" json:"protocol_port"`
+ ProtocolPort int `json:"protocol_port"`
// The ID of the pool with which the VIP is associated.
- PoolID string `mapstructure:"pool_id" json:"pool_id"`
+ PoolID string `json:"pool_id"`
// The ID of the port which belongs to the load balancer
- PortID string `mapstructure:"port_id" json:"port_id"`
+ PortID string `json:"port_id"`
// Indicates whether connections in the same session will be processed by the
// same pool member or not.
- Persistence SessionPersistence `mapstructure:"session_persistence" json:"session_persistence"`
+ Persistence SessionPersistence `json:"session_persistence"`
// The maximum number of connections allowed for the VIP. Default is -1,
// meaning no limit.
- ConnLimit int `mapstructure:"connection_limit" json:"connection_limit"`
+ ConnLimit int `json:"connection_limit"`
// The administrative state of the VIP. A valid value is true (UP) or false (DOWN).
- AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"`
+ AdminStateUp bool `json:"admin_state_up"`
// The status of the VIP. Indicates whether the VIP is operational.
- Status string `mapstructure:"status" json:"status"`
+ Status string `json:"status"`
}
// VIPPage is the page returned by a pager when traversing over a
@@ -90,40 +89,33 @@
// NextPageURL is invoked when a paginated collection of routers has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
-func (p VIPPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"vips_links"`
+func (page VIPPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"vips_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
-// IsEmpty checks whether a RouterPage struct is empty.
-func (p VIPPage) IsEmpty() (bool, error) {
- is, err := ExtractVIPs(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+// IsEmpty checks whether a VIPPage struct is empty.
+func (page VIPPage) IsEmpty() (bool, error) {
+ is, err := ExtractVIPs(page)
+ return len(is) == 0, err
}
// ExtractVIPs accepts a Page struct, specifically a VIPPage struct,
// and extracts the elements into a slice of VirtualIP structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractVIPs(page pagination.Page) ([]VirtualIP, error) {
- var resp struct {
- VIPs []VirtualIP `mapstructure:"vips" json:"vips"`
+ r := page.(VIPPage)
+ var s struct {
+ VIPs []VirtualIP `json:"vips"`
}
-
- err := mapstructure.Decode(page.(VIPPage).Body, &resp)
-
- return resp.VIPs, err
+ err := r.ExtractInto(&s)
+ return s.VIPs, err
}
type commonResult struct {
@@ -132,17 +124,11 @@
// Extract is a function that accepts a result and extracts a router.
func (r commonResult) Extract() (*VirtualIP, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ VirtualIP *VirtualIP `json:"vip" json:"vip"`
}
-
- var res struct {
- VirtualIP *VirtualIP `mapstructure:"vip" json:"vip"`
- }
-
- err := mapstructure.Decode(r.Body, &res)
-
- return res.VirtualIP, err
+ err := r.ExtractInto(&s)
+ return s.VirtualIP, err
}
// CreateResult represents the result of a create operation.
diff --git a/openstack/networking/v2/extensions/provider/results.go b/openstack/networking/v2/extensions/provider/results.go
index 9590ae5..f437461 100755
--- a/openstack/networking/v2/extensions/provider/results.go
+++ b/openstack/networking/v2/extensions/provider/results.go
@@ -1,7 +1,6 @@
package provider
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -22,30 +21,30 @@
// NetworkExtAttrs represents an extended form of a Network with additional fields.
type NetworkExtAttrs struct {
// UUID for the network
- ID string `mapstructure:"id" json:"id"`
+ ID string `json:"id"`
// Human-readable name for the network. Might not be unique.
- Name string `mapstructure:"name" json:"name"`
+ Name string `json:"name"`
// The administrative state of network. If false (down), the network does not forward packets.
- AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"`
+ AdminStateUp bool `json:"admin_state_up"`
// Indicates whether network is currently operational. Possible values include
// `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional values.
- Status string `mapstructure:"status" json:"status"`
+ Status string `json:"status"`
// Subnets associated with this network.
- Subnets []string `mapstructure:"subnets" json:"subnets"`
+ Subnets []string `json:"subnets"`
// Owner of network. Only admin users can specify a tenant_id other than its own.
- TenantID string `mapstructure:"tenant_id" json:"tenant_id"`
+ TenantID string `json:"tenant_id"`
// Specifies whether the network resource can be accessed by any tenant or not.
- Shared bool `mapstructure:"shared" json:"shared"`
+ Shared bool `json:"shared"`
// Specifies the nature of the physical network mapped to this network
// resource. Examples are flat, vlan, or gre.
- NetworkType string `json:"provider:network_type" mapstructure:"provider:network_type"`
+ NetworkType string `json:"provider:network_type"`
// Identifies the physical network on top of which this network object is
// being implemented. The OpenStack Networking API does not expose any facility
@@ -53,72 +52,53 @@
// the Open vSwitch plug-in this is a symbolic name which is then mapped to
// specific bridges on each compute host through the Open vSwitch plug-in
// configuration file.
- PhysicalNetwork string `json:"provider:physical_network" mapstructure:"provider:physical_network"`
+ PhysicalNetwork string `json:"provider:physical_network"`
// Identifies an isolated segment on the physical network; the nature of the
// segment depends on the segmentation model defined by network_type. For
// instance, if network_type is vlan, then this is a vlan identifier;
// otherwise, if network_type is gre, then this will be a gre key.
- SegmentationID string `json:"provider:segmentation_id" mapstructure:"provider:segmentation_id"`
+ SegmentationID string `json:"provider:segmentation_id"`
}
// ExtractGet decorates a GetResult struct returned from a networks.Get()
// function with extended attributes.
func ExtractGet(r networks.GetResult) (*NetworkExtAttrs, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res struct {
+ var s struct {
Network *NetworkExtAttrs `json:"network"`
}
-
- err := mapstructure.WeakDecode(r.Body, &res)
-
- return res.Network, err
+ err := r.ExtractInto(&s)
+ return s.Network, err
}
// ExtractCreate decorates a CreateResult struct returned from a networks.Create()
// function with extended attributes.
func ExtractCreate(r networks.CreateResult) (*NetworkExtAttrs, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res struct {
+ var s struct {
Network *NetworkExtAttrs `json:"network"`
}
-
- err := mapstructure.WeakDecode(r.Body, &res)
-
- return res.Network, err
+ err := r.ExtractInto(&s)
+ return s.Network, err
}
// ExtractUpdate decorates a UpdateResult struct returned from a
// networks.Update() function with extended attributes.
func ExtractUpdate(r networks.UpdateResult) (*NetworkExtAttrs, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res struct {
+ var s struct {
Network *NetworkExtAttrs `json:"network"`
}
-
- err := mapstructure.WeakDecode(r.Body, &res)
-
- return res.Network, err
+ err := r.ExtractInto(&s)
+ return s.Network, err
}
// ExtractList accepts a Page struct, specifically a NetworkPage struct, and
// extracts the elements into a slice of NetworkExtAttrs structs. In other
// words, a generic collection is mapped into a relevant slice.
func ExtractList(page pagination.Page) ([]NetworkExtAttrs, error) {
- var resp struct {
- Networks []NetworkExtAttrs `mapstructure:"networks" json:"networks"`
+ r := page.(networks.NetworkPage)
+ var s struct {
+ Networks []NetworkExtAttrs `json:"networks" json:"networks"`
}
-
- err := mapstructure.WeakDecode(page.(networks.NetworkPage).Body, &resp)
-
- return resp.Networks, err
+ err := r.ExtractInto(&s)
+ return s.Networks, err
}
diff --git a/openstack/networking/v2/extensions/provider/results_test.go b/openstack/networking/v2/extensions/provider/results_test.go
index 90d6ad1..59f06cc 100644
--- a/openstack/networking/v2/extensions/provider/results_test.go
+++ b/openstack/networking/v2/extensions/provider/results_test.go
@@ -49,7 +49,7 @@
"tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e",
"shared": true,
"id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324",
- "provider:segmentation_id": 1234567890,
+ "provider:segmentation_id": "1234567890",
"provider:physical_network": null,
"provider:network_type": "local"
}
diff --git a/openstack/networking/v2/extensions/security/groups/results.go b/openstack/networking/v2/extensions/security/groups/results.go
index 9530cde..7479e19 100644
--- a/openstack/networking/v2/extensions/security/groups/results.go
+++ b/openstack/networking/v2/extensions/security/groups/results.go
@@ -1,7 +1,6 @@
package groups
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/rules"
"github.com/gophercloud/gophercloud/pagination"
@@ -21,11 +20,11 @@
// A slice of security group rules that dictate the permitted behaviour for
// traffic entering and leaving the group.
- Rules []rules.SecGroupRule `json:"security_group_rules" mapstructure:"security_group_rules"`
+ Rules []rules.SecGroupRule `json:"security_group_rules"`
// Owner of the security group. Only admin users can specify a TenantID
// other than their own.
- TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
+ TenantID string `json:"tenant_id"`
}
// SecGroupPage is the page returned by a pager when traversing over a
@@ -37,40 +36,34 @@
// NextPageURL is invoked when a paginated collection of security groups has
// reached the end of a page and the pager seeks to traverse over a new one. In
// order to do this, it needs to construct the next page's URL.
-func (p SecGroupPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"security_groups_links"`
+func (page SecGroupPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"security_groups_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a SecGroupPage struct is empty.
-func (p SecGroupPage) IsEmpty() (bool, error) {
- is, err := ExtractGroups(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+func (page SecGroupPage) IsEmpty() (bool, error) {
+ is, err := ExtractGroups(page)
+ return len(is) == 0, err
}
// ExtractGroups accepts a Page struct, specifically a SecGroupPage struct,
// and extracts the elements into a slice of SecGroup structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractGroups(page pagination.Page) ([]SecGroup, error) {
- var resp struct {
- SecGroups []SecGroup `mapstructure:"security_groups" json:"security_groups"`
+ r := page.(SecGroupPage)
+ var s struct {
+ SecGroups []SecGroup `json:"security_groups"`
}
-
- err := mapstructure.Decode(page.(SecGroupPage).Body, &resp)
-
- return resp.SecGroups, err
+ err := r.ExtractInto(&s)
+ return s.SecGroups, err
}
type commonResult struct {
@@ -79,17 +72,11 @@
// Extract is a function that accepts a result and extracts a security group.
func (r commonResult) Extract() (*SecGroup, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ SecGroup *SecGroup `json:"security_group"`
}
-
- var res struct {
- SecGroup *SecGroup `mapstructure:"security_group" json:"security_group"`
- }
-
- err := mapstructure.Decode(r.Body, &res)
-
- return res.SecGroup, err
+ err := r.ExtractInto(&s)
+ return s.SecGroup, err
}
// CreateResult represents the result of a create operation.
diff --git a/openstack/networking/v2/extensions/security/rules/results.go b/openstack/networking/v2/extensions/security/rules/results.go
index 1181ebb..a9d6f1b 100644
--- a/openstack/networking/v2/extensions/security/rules/results.go
+++ b/openstack/networking/v2/extensions/security/rules/results.go
@@ -1,7 +1,6 @@
package rules
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -20,21 +19,21 @@
// Must be IPv4 or IPv6, and addresses represented in CIDR must match the
// ingress or egress rules.
- EtherType string `json:"ethertype" mapstructure:"ethertype"`
+ EtherType string `json:"ethertype"`
// The security group ID to associate with this security group rule.
- SecGroupID string `json:"security_group_id" mapstructure:"security_group_id"`
+ SecGroupID string `json:"security_group_id"`
// The minimum port number in the range that is matched by the security group
// rule. If the protocol is TCP or UDP, this value must be less than or equal
// to the value of the PortRangeMax attribute. If the protocol is ICMP, this
// value must be an ICMP type.
- PortRangeMin int `json:"port_range_min" mapstructure:"port_range_min"`
+ PortRangeMin int `json:"port_range_min"`
// The maximum port number in the range that is matched by the security group
// rule. The PortRangeMin attribute constrains the PortRangeMax attribute. If
// the protocol is ICMP, this value must be an ICMP type.
- PortRangeMax int `json:"port_range_max" mapstructure:"port_range_max"`
+ PortRangeMax int `json:"port_range_max"`
// The protocol that is matched by the security group rule. Valid values are
// "tcp", "udp", "icmp" or an empty string.
@@ -42,15 +41,15 @@
// The remote group ID to be associated with this security group rule. You
// can specify either RemoteGroupID or RemoteIPPrefix.
- RemoteGroupID string `json:"remote_group_id" mapstructure:"remote_group_id"`
+ RemoteGroupID string `json:"remote_group_id"`
// The remote IP prefix to be associated with this security group rule. You
// can specify either RemoteGroupID or RemoteIPPrefix . This attribute
// matches the specified IP prefix as the source IP address of the IP packet.
- RemoteIPPrefix string `json:"remote_ip_prefix" mapstructure:"remote_ip_prefix"`
+ RemoteIPPrefix string `json:"remote_ip_prefix"`
// The owner of this security group rule.
- TenantID string `json:"tenant_id" mapstructure:"tenant_id"`
+ TenantID string `json:"tenant_id"`
}
// SecGroupRulePage is the page returned by a pager when traversing over a
@@ -62,40 +61,33 @@
// NextPageURL is invoked when a paginated collection of security group rules has
// reached the end of a page and the pager seeks to traverse over a new one. In
// order to do this, it needs to construct the next page's URL.
-func (p SecGroupRulePage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"security_group_rules_links"`
+func (page SecGroupRulePage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"security_group_rules_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a SecGroupRulePage struct is empty.
-func (p SecGroupRulePage) IsEmpty() (bool, error) {
- is, err := ExtractRules(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+func (page SecGroupRulePage) IsEmpty() (bool, error) {
+ is, err := ExtractRules(page)
+ return len(is) == 0, err
}
// ExtractRules accepts a Page struct, specifically a SecGroupRulePage struct,
// and extracts the elements into a slice of SecGroupRule structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractRules(page pagination.Page) ([]SecGroupRule, error) {
- var resp struct {
- SecGroupRules []SecGroupRule `mapstructure:"security_group_rules" json:"security_group_rules"`
+ r := page.(SecGroupRulePage)
+ var s struct {
+ SecGroupRules []SecGroupRule `json:"security_group_rules"`
}
-
- err := mapstructure.Decode(page.(SecGroupRulePage).Body, &resp)
-
- return resp.SecGroupRules, err
+ err := r.ExtractInto(&s)
+ return s.SecGroupRules, err
}
type commonResult struct {
@@ -104,17 +96,11 @@
// Extract is a function that accepts a result and extracts a security rule.
func (r commonResult) Extract() (*SecGroupRule, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ SecGroupRule *SecGroupRule `json:"security_group_rule"`
}
-
- var res struct {
- SecGroupRule *SecGroupRule `mapstructure:"security_group_rule" json:"security_group_rule"`
- }
-
- err := mapstructure.Decode(r.Body, &res)
-
- return res.SecGroupRule, err
+ err := r.ExtractInto(&s)
+ return s.SecGroupRule, err
}
// CreateResult represents the result of a create operation.
diff --git a/openstack/networking/v2/networks/results.go b/openstack/networking/v2/networks/results.go
index 7251273..7f64ddb 100644
--- a/openstack/networking/v2/networks/results.go
+++ b/openstack/networking/v2/networks/results.go
@@ -1,7 +1,6 @@
package networks
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -12,17 +11,11 @@
// Extract is a function that accepts a result and extracts a network resource.
func (r commonResult) Extract() (*Network, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res struct {
+ var s struct {
Network *Network `json:"network"`
}
-
- err := mapstructure.Decode(r.Body, &res)
-
- return res.Network, err
+ err := r.ExtractInto(&s)
+ return s.Network, err
}
// CreateResult represents the result of a create operation.
@@ -48,26 +41,26 @@
// Network represents, well, a network.
type Network struct {
// UUID for the network
- ID string `mapstructure:"id" json:"id"`
+ ID string `json:"id"`
// Human-readable name for the network. Might not be unique.
- Name string `mapstructure:"name" json:"name"`
+ Name string `json:"name"`
// The administrative state of network. If false (down), the network does not forward packets.
- AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"`
+ AdminStateUp bool `json:"admin_state_up"`
// Indicates whether network is currently operational. Possible values include
// `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional values.
- Status string `mapstructure:"status" json:"status"`
+ Status string `json:"status"`
// Subnets associated with this network.
- Subnets []string `mapstructure:"subnets" json:"subnets"`
+ Subnets []string `json:"subnets"`
// Owner of network. Only admin users can specify a tenant_id other than its own.
- TenantID string `mapstructure:"tenant_id" json:"tenant_id"`
+ TenantID string `json:"tenant_id"`
// Specifies whether the network resource can be accessed by any tenant or not.
- Shared bool `mapstructure:"shared" json:"shared"`
+ Shared bool `json:"shared"`
}
// NetworkPage is the page returned by a pager when traversing over a
@@ -79,38 +72,31 @@
// NextPageURL is invoked when a paginated collection of networks has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
-func (p NetworkPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"networks_links"`
+func (page NetworkPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"networks_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a NetworkPage struct is empty.
-func (p NetworkPage) IsEmpty() (bool, error) {
- is, err := ExtractNetworks(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+func (page NetworkPage) IsEmpty() (bool, error) {
+ is, err := ExtractNetworks(page)
+ return len(is) == 0, err
}
// ExtractNetworks accepts a Page struct, specifically a NetworkPage struct,
// and extracts the elements into a slice of Network structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractNetworks(page pagination.Page) ([]Network, error) {
- var resp struct {
- Networks []Network `mapstructure:"networks" json:"networks"`
+ r := page.(NetworkPage)
+ var s struct {
+ Networks []Network `json:"networks"`
}
-
- err := mapstructure.Decode(page.(NetworkPage).Body, &resp)
-
- return resp.Networks, err
+ err := r.ExtractInto(&s)
+ return s.Networks, err
}
diff --git a/openstack/networking/v2/ports/results.go b/openstack/networking/v2/ports/results.go
index 0908fda..e757a54 100644
--- a/openstack/networking/v2/ports/results.go
+++ b/openstack/networking/v2/ports/results.go
@@ -1,7 +1,6 @@
package ports
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -12,16 +11,11 @@
// Extract is a function that accepts a result and extracts a port resource.
func (r commonResult) Extract() (*Port, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res struct {
+ var s struct {
Port *Port `json:"port"`
}
- err := mapstructure.Decode(r.Body, &res)
-
- return res.Port, err
+ err := r.ExtractInto(&s)
+ return s.Port, err
}
// CreateResult represents the result of a create operation.
@@ -46,44 +40,45 @@
// IP is a sub-struct that represents an individual IP.
type IP struct {
- SubnetID string `mapstructure:"subnet_id" json:"subnet_id"`
- IPAddress string `mapstructure:"ip_address" json:"ip_address,omitempty"`
+ SubnetID string `json:"subnet_id"`
+ IPAddress string `json:"ip_address,omitempty"`
}
+// AddressPair contains the IP Address and the MAC address.
type AddressPair struct {
- IPAddress string `mapstructure:"ip_address" json:"ip_address,omitempty"`
- MACAddress string `mapstructure:"mac_address" json:"mac_address,omitempty"`
+ IPAddress string `json:"ip_address,omitempty"`
+ MACAddress string `json:"mac_address,omitempty"`
}
// Port represents a Neutron port. See package documentation for a top-level
// description of what this is.
type Port struct {
// UUID for the port.
- ID string `mapstructure:"id" json:"id"`
+ ID string `json:"id"`
// Network that this port is associated with.
- NetworkID string `mapstructure:"network_id" json:"network_id"`
+ NetworkID string `json:"network_id"`
// Human-readable name for the port. Might not be unique.
- Name string `mapstructure:"name" json:"name"`
+ Name string `json:"name"`
// Administrative state of port. If false (down), port does not forward packets.
- AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"`
+ AdminStateUp bool `json:"admin_state_up"`
// Indicates whether network is currently operational. Possible values include
// `ACTIVE', `DOWN', `BUILD', or `ERROR'. Plug-ins might define additional values.
- Status string `mapstructure:"status" json:"status"`
+ Status string `json:"status"`
// Mac address to use on this port.
- MACAddress string `mapstructure:"mac_address" json:"mac_address"`
+ MACAddress string `json:"mac_address"`
// Specifies IP addresses for the port thus associating the port itself with
// the subnets where the IP addresses are picked from
- FixedIPs []IP `mapstructure:"fixed_ips" json:"fixed_ips"`
+ FixedIPs []IP `json:"fixed_ips"`
// Owner of network. Only admin users can specify a tenant_id other than its own.
- TenantID string `mapstructure:"tenant_id" json:"tenant_id"`
+ TenantID string `json:"tenant_id"`
// Identifies the entity (e.g.: dhcp agent) using this port.
- DeviceOwner string `mapstructure:"device_owner" json:"device_owner"`
+ DeviceOwner string `json:"device_owner"`
// Specifies the IDs of any security groups associated with a port.
- SecurityGroups []string `mapstructure:"security_groups" json:"security_groups"`
+ SecurityGroups []string `json:"security_groups"`
// Identifies the device (e.g., virtual server) using this port.
- DeviceID string `mapstructure:"device_id" json:"device_id"`
+ DeviceID string `json:"device_id"`
// Identifies the list of IP addresses the port will recognize/accept
- AllowedAddressPairs []AddressPair `mapstructure:"allowed_address_pairs" json:"allowed_address_pairs"`
+ AllowedAddressPairs []AddressPair `json:"allowed_address_pairs"`
}
// PortPage is the page returned by a pager when traversing over a collection
@@ -95,38 +90,31 @@
// NextPageURL is invoked when a paginated collection of ports has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
-func (p PortPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"ports_links"`
+func (page PortPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"ports_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a PortPage struct is empty.
-func (p PortPage) IsEmpty() (bool, error) {
- is, err := ExtractPorts(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+func (page PortPage) IsEmpty() (bool, error) {
+ is, err := ExtractPorts(page)
+ return len(is) == 0, err
}
// ExtractPorts accepts a Page struct, specifically a PortPage struct,
// and extracts the elements into a slice of Port structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractPorts(page pagination.Page) ([]Port, error) {
- var resp struct {
- Ports []Port `mapstructure:"ports" json:"ports"`
+ r := page.(PortPage)
+ var s struct {
+ Ports []Port `json:"ports"`
}
-
- err := mapstructure.Decode(page.(PortPage).Body, &resp)
-
- return resp.Ports, err
+ err := r.ExtractInto(&s)
+ return s.Ports, err
}
diff --git a/openstack/networking/v2/subnets/results.go b/openstack/networking/v2/subnets/results.go
index 2a80f6a..22cff1e 100644
--- a/openstack/networking/v2/subnets/results.go
+++ b/openstack/networking/v2/subnets/results.go
@@ -1,7 +1,6 @@
package subnets
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -12,17 +11,11 @@
// Extract is a function that accepts a result and extracts a subnet resource.
func (r commonResult) Extract() (*Subnet, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res struct {
+ var s struct {
Subnet *Subnet `json:"subnet"`
}
-
- err := mapstructure.Decode(r.Body, &res)
-
- return res.Subnet, err
+ err := r.ExtractInto(&s)
+ return s.Subnet, err
}
// CreateResult represents the result of a create operation.
@@ -55,35 +48,35 @@
// HostRoute represents a route that should be used by devices with IPs from
// a subnet (not including local subnet route).
type HostRoute struct {
- DestinationCIDR string `mapstructure:"destination" json:"destination"`
- NextHop string `mapstructure:"nexthop" json:"nexthop"`
+ DestinationCIDR string `json:"destination"`
+ NextHop string `json:"nexthop"`
}
// Subnet represents a subnet. See package documentation for a top-level
// description of what this is.
type Subnet struct {
// UUID representing the subnet
- ID string `mapstructure:"id" json:"id"`
+ ID string `json:"id"`
// UUID of the parent network
- NetworkID string `mapstructure:"network_id" json:"network_id"`
+ NetworkID string `json:"network_id"`
// Human-readable name for the subnet. Might not be unique.
- Name string `mapstructure:"name" json:"name"`
+ Name string `json:"name"`
// IP version, either `4' or `6'
- IPVersion int `mapstructure:"ip_version" json:"ip_version"`
+ IPVersion int `json:"ip_version"`
// CIDR representing IP range for this subnet, based on IP version
- CIDR string `mapstructure:"cidr" json:"cidr"`
+ CIDR string `json:"cidr"`
// Default gateway used by devices in this subnet
- GatewayIP string `mapstructure:"gateway_ip" json:"gateway_ip"`
+ GatewayIP string `json:"gateway_ip"`
// DNS name servers used by hosts in this subnet.
- DNSNameservers []string `mapstructure:"dns_nameservers" json:"dns_nameservers"`
+ DNSNameservers []string `json:"dns_nameservers"`
// Sub-ranges of CIDR available for dynamic allocation to ports. See AllocationPool.
- AllocationPools []AllocationPool `mapstructure:"allocation_pools" json:"allocation_pools"`
+ AllocationPools []AllocationPool `json:"allocation_pools"`
// Routes that should be used by devices with IPs from this subnet (not including local subnet route).
- HostRoutes []HostRoute `mapstructure:"host_routes" json:"host_routes"`
+ HostRoutes []HostRoute `json:"host_routes"`
// Specifies whether DHCP is enabled for this subnet or not.
- EnableDHCP bool `mapstructure:"enable_dhcp" json:"enable_dhcp"`
+ EnableDHCP bool `json:"enable_dhcp"`
// Owner of network. Only admin users can specify a tenant_id other than its own.
- TenantID string `mapstructure:"tenant_id" json:"tenant_id"`
+ TenantID string `json:"tenant_id"`
}
// SubnetPage is the page returned by a pager when traversing over a collection
@@ -95,38 +88,30 @@
// NextPageURL is invoked when a paginated collection of subnets has reached
// the end of a page and the pager seeks to traverse over a new one. In order
// to do this, it needs to construct the next page's URL.
-func (p SubnetPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"subnets_links"`
+func (page SubnetPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"subnets_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
+ return gophercloud.ExtractNextURL(s.Links)
}
// IsEmpty checks whether a SubnetPage struct is empty.
-func (p SubnetPage) IsEmpty() (bool, error) {
- is, err := ExtractSubnets(p)
- if err != nil {
- return true, nil
- }
- return len(is) == 0, nil
+func (page SubnetPage) IsEmpty() (bool, error) {
+ is, err := ExtractSubnets(page)
+ return len(is) == 0, err
}
// ExtractSubnets accepts a Page struct, specifically a SubnetPage struct,
// and extracts the elements into a slice of Subnet structs. In other words,
// a generic collection is mapped into a relevant slice.
func ExtractSubnets(page pagination.Page) ([]Subnet, error) {
- var resp struct {
- Subnets []Subnet `mapstructure:"subnets" json:"subnets"`
+ var s struct {
+ Subnets []Subnet `json:"subnets"`
}
-
- err := mapstructure.Decode(page.(SubnetPage).Body, &resp)
-
- return resp.Subnets, err
+ err := (page.(SubnetPage)).ExtractInto(&s)
+ return s.Subnets, err
}
diff --git a/openstack/objectstorage/v1/accounts/fixtures.go b/openstack/objectstorage/v1/accounts/fixtures.go
index 66589bf..16327e8 100644
--- a/openstack/objectstorage/v1/accounts/fixtures.go
+++ b/openstack/objectstorage/v1/accounts/fixtures.go
@@ -20,6 +20,7 @@
w.Header().Set("X-Account-Container-Count", "2")
w.Header().Set("X-Account-Bytes-Used", "14")
w.Header().Set("X-Account-Meta-Subject", "books")
+ w.Header().Set("Date", "Fri, 17 Jan 2014 16:09:56 GMT")
w.WriteHeader(http.StatusNoContent)
})
@@ -33,6 +34,7 @@
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
th.TestHeader(t, r, "X-Account-Meta-Gophercloud-Test", "accounts")
+ w.Header().Set("Date", "Fri, 17 Jan 2014 16:09:56 GMT")
w.WriteHeader(http.StatusNoContent)
})
}
diff --git a/openstack/objectstorage/v1/accounts/requests_test.go b/openstack/objectstorage/v1/accounts/requests_test.go
index 31ebccc..8aba591 100644
--- a/openstack/objectstorage/v1/accounts/requests_test.go
+++ b/openstack/objectstorage/v1/accounts/requests_test.go
@@ -13,8 +13,8 @@
HandleUpdateAccountSuccessfully(t)
options := &UpdateOpts{Metadata: map[string]string{"gophercloud-test": "accounts"}}
- res := Update(fake.ServiceClient(), options)
- th.AssertNoErr(t, res.Err)
+ _, err := Update(fake.ServiceClient(), options).Extract()
+ th.AssertNoErr(t, err)
}
func TestGetAccount(t *testing.T) {
@@ -27,6 +27,6 @@
th.AssertNoErr(t, res.Err)
actualMetadata, _ := res.ExtractMetadata()
th.CheckDeepEquals(t, expectedMetadata, actualMetadata)
- //headers, err := res.Extract()
- //th.AssertNoErr(t, err)
+ _, err := res.Extract()
+ th.AssertNoErr(t, err)
}
diff --git a/openstack/objectstorage/v1/accounts/results.go b/openstack/objectstorage/v1/accounts/results.go
index 89cd905..50032bd 100644
--- a/openstack/objectstorage/v1/accounts/results.go
+++ b/openstack/objectstorage/v1/accounts/results.go
@@ -2,7 +2,6 @@
import (
"strings"
- "time"
"github.com/gophercloud/gophercloud"
)
@@ -14,46 +13,31 @@
// UpdateHeader represents the headers returned in the response from an Update request.
type UpdateHeader struct {
- ContentLength string `mapstructure:"Content-Length"`
- ContentType string `mapstructure:"Content-Type"`
- Date time.Time `mapstructure:"-"`
- TransID string `mapstructure:"X-Trans-Id"`
+ ContentLength string `json:"Content-Length"`
+ ContentType string `json:"Content-Type"`
+ Date gophercloud.JSONRFC1123 `json:"Date"`
+ TransID string `json:"X-Trans-Id"`
}
// Extract will return a struct of headers returned from a call to Get. To obtain
// a map of headers, call the ExtractHeader method on the GetResult.
-func (ur UpdateResult) Extract() (UpdateHeader, error) {
- var uh UpdateHeader
- if ur.Err != nil {
- return uh, ur.Err
- }
-
- if err := gophercloud.DecodeHeader(ur.Header, &uh); err != nil {
- return uh, err
- }
-
- if date, ok := ur.Header["Date"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, ur.Header["Date"][0])
- if err != nil {
- return uh, err
- }
- uh.Date = t
- }
-
- return uh, nil
+func (ur UpdateResult) Extract() (*UpdateHeader, error) {
+ var uh *UpdateHeader
+ err := ur.ExtractInto(&uh)
+ return uh, err
}
// GetHeader represents the headers returned in the response from a Get request.
type GetHeader struct {
- BytesUsed int64 `mapstructure:"X-Account-Bytes-Used"`
- ContainerCount int `mapstructure:"X-Account-Container-Count"`
- ContentLength int64 `mapstructure:"Content-Length"`
- ContentType string `mapstructure:"Content-Type"`
- Date time.Time `mapstructure:"-"`
- ObjectCount int64 `mapstructure:"X-Account-Object-Count"`
- TransID string `mapstructure:"X-Trans-Id"`
- TempURLKey string `mapstructure:"X-Account-Meta-Temp-URL-Key"`
- TempURLKey2 string `mapstructure:"X-Account-Meta-Temp-URL-Key-2"`
+ BytesUsed string `json:"X-Account-Bytes-Used"`
+ ContainerCount string `json:"X-Account-Container-Count"`
+ ContentLength string `json:"Content-Length"`
+ ContentType string `json:"Content-Type"`
+ Date gophercloud.JSONRFC1123 `json:"Date"`
+ ObjectCount string `json:"X-Account-Object-Count"`
+ TransID string `json:"X-Trans-Id"`
+ TempURLKey string `json:"X-Account-Meta-Temp-URL-Key"`
+ TempURLKey2 string `json:"X-Account-Meta-Temp-URL-Key-2"`
}
// GetResult is returned from a call to the Get function.
@@ -63,25 +47,10 @@
// Extract will return a struct of headers returned from a call to Get. To obtain
// a map of headers, call the ExtractHeader method on the GetResult.
-func (gr GetResult) Extract() (GetHeader, error) {
- var gh GetHeader
- if gr.Err != nil {
- return gh, gr.Err
- }
-
- if err := gophercloud.DecodeHeader(gr.Header, &gh); err != nil {
- return gh, err
- }
-
- if date, ok := gr.Header["Date"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, gr.Header["Date"][0])
- if err != nil {
- return gh, err
- }
- gh.Date = t
- }
-
- return gh, nil
+func (gr GetResult) Extract() (*GetHeader, error) {
+ var gh *GetHeader
+ err := gr.ExtractInto(&gh)
+ return gh, err
}
// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
diff --git a/openstack/objectstorage/v1/containers/results.go b/openstack/objectstorage/v1/containers/results.go
index 4413c74..9eec3f4 100644
--- a/openstack/objectstorage/v1/containers/results.go
+++ b/openstack/objectstorage/v1/containers/results.go
@@ -3,24 +3,21 @@
import (
"fmt"
"strings"
- "time"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
-
- "github.com/mitchellh/mapstructure"
)
// Container represents a container resource.
type Container struct {
// The total number of bytes stored in the container.
- Bytes int `json:"bytes" mapstructure:"bytes"`
+ Bytes int `json:"bytes"`
// The total number of objects stored in the container.
- Count int `json:"count" mapstructure:"count"`
+ Count int `json:"count"`
// The name of the container.
- Name string `json:"name" mapstructure:"name"`
+ Name string `json:"name"`
}
// ContainerPage is the page returned by a pager when traversing over a
@@ -29,13 +26,10 @@
pagination.MarkerPageBase
}
-// IsEmpty returns true if a ListResult contains no container names.
+//IsEmpty returns true if a ListResult contains no container names.
func (r ContainerPage) IsEmpty() (bool, error) {
names, err := ExtractNames(r)
- if err != nil {
- return true, err
- }
- return len(names) == 0, nil
+ return len(names) == 0, err
}
// LastMarker returns the last container name in a ListResult.
@@ -51,17 +45,10 @@
}
// ExtractInfo is a function that takes a ListResult and returns the containers' information.
-func ExtractInfo(page pagination.Page) ([]Container, error) {
- untyped := page.(ContainerPage).Body.([]interface{})
- results := make([]Container, len(untyped))
- for index, each := range untyped {
- container := each.(map[string]interface{})
- err := mapstructure.Decode(container, &results[index])
- if err != nil {
- return results, err
- }
- }
- return results, nil
+func ExtractInfo(r pagination.Page) ([]Container, error) {
+ var s []Container
+ err := (r.(ContainerPage)).ExtractInto(&s)
+ return s, err
}
// ExtractNames is a function that takes a ListResult and returns the containers' names.
@@ -99,16 +86,16 @@
// GetHeader represents the headers returned in the response from a Get request.
type GetHeader struct {
- AcceptRanges string `mapstructure:"Accept-Ranges"`
- BytesUsed int64 `mapstructure:"X-Account-Bytes-Used"`
- ContentLength int64 `mapstructure:"Content-Length"`
- ContentType string `mapstructure:"Content-Type"`
- Date time.Time `mapstructure:"-"`
- ObjectCount int64 `mapstructure:"X-Container-Object-Count"`
- Read string `mapstructure:"X-Container-Read"`
- TransID string `mapstructure:"X-Trans-Id"`
- VersionsLocation string `mapstructure:"X-Versions-Location"`
- Write string `mapstructure:"X-Container-Write"`
+ AcceptRanges string `json:"Accept-Ranges"`
+ BytesUsed string `json:"X-Account-Bytes-Used"`
+ ContentLength string `json:"Content-Length"`
+ ContentType string `json:"Content-Type"`
+ Date gophercloud.JSONRFC1123 `json:"Date"`
+ ObjectCount string `json:"X-Container-Object-Count"`
+ Read string `json:"X-Container-Read"`
+ TransID string `json:"X-Trans-Id"`
+ VersionsLocation string `json:"X-Versions-Location"`
+ Write string `json:"X-Container-Write"`
}
// GetResult represents the result of a get operation.
@@ -118,35 +105,20 @@
// Extract will return a struct of headers returned from a call to Get. To obtain
// a map of headers, call the ExtractHeader method on the GetResult.
-func (gr GetResult) Extract() (GetHeader, error) {
- var gh GetHeader
- if gr.Err != nil {
- return gh, gr.Err
- }
-
- if err := gophercloud.DecodeHeader(gr.Header, &gh); err != nil {
- return gh, err
- }
-
- if date, ok := gr.Header["Date"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, gr.Header["Date"][0])
- if err != nil {
- return gh, err
- }
- gh.Date = t
- }
-
- return gh, nil
+func (r GetResult) Extract() (*GetHeader, error) {
+ var s *GetHeader
+ err := r.ExtractInto(&s)
+ return s, err
}
// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
// and returns the custom metadata associated with the container.
-func (gr GetResult) ExtractMetadata() (map[string]string, error) {
- if gr.Err != nil {
- return nil, gr.Err
+func (r GetResult) ExtractMetadata() (map[string]string, error) {
+ if r.Err != nil {
+ return nil, r.Err
}
metadata := make(map[string]string)
- for k, v := range gr.Header {
+ for k, v := range r.Header {
if strings.HasPrefix(k, "X-Container-Meta-") {
key := strings.TrimPrefix(k, "X-Container-Meta-")
metadata[key] = v[0]
@@ -157,10 +129,10 @@
// CreateHeader represents the headers returned in the response from a Create request.
type CreateHeader struct {
- ContentLength int64 `mapstructure:"Content-Length"`
- ContentType string `mapstructure:"Content-Type"`
- Date time.Time `mapstructure:"-"`
- TransID string `mapstructure:"X-Trans-Id"`
+ ContentLength string `json:"Content-Length"`
+ ContentType string `json:"Content-Type"`
+ Date gophercloud.JSONRFC1123 `json:"Date"`
+ TransID string `json:"X-Trans-Id"`
}
// CreateResult represents the result of a create operation. To extract the
@@ -172,33 +144,18 @@
// Extract will return a struct of headers returned from a call to Create. To obtain
// a map of headers, call the ExtractHeader method on the CreateResult.
-func (cr CreateResult) Extract() (CreateHeader, error) {
- var ch CreateHeader
- if cr.Err != nil {
- return ch, cr.Err
- }
-
- if err := gophercloud.DecodeHeader(cr.Header, &ch); err != nil {
- return ch, err
- }
-
- if date, ok := cr.Header["Date"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, cr.Header["Date"][0])
- if err != nil {
- return ch, err
- }
- ch.Date = t
- }
-
- return ch, nil
+func (r CreateResult) Extract() (*CreateHeader, error) {
+ var s *CreateHeader
+ err := r.ExtractInto(&s)
+ return s, err
}
// UpdateHeader represents the headers returned in the response from a Update request.
type UpdateHeader struct {
- ContentLength int64 `mapstructure:"Content-Length"`
- ContentType string `mapstructure:"Content-Type"`
- Date time.Time `mapstructure:"-"`
- TransID string `mapstructure:"X-Trans-Id"`
+ ContentLength string `json:"Content-Length"`
+ ContentType string `json:"Content-Type"`
+ Date gophercloud.JSONRFC1123 `json:"Date"`
+ TransID string `json:"X-Trans-Id"`
}
// UpdateResult represents the result of an update operation. To extract the
@@ -210,33 +167,18 @@
// Extract will return a struct of headers returned from a call to Update. To obtain
// a map of headers, call the ExtractHeader method on the UpdateResult.
-func (ur UpdateResult) Extract() (UpdateHeader, error) {
- var uh UpdateHeader
- if ur.Err != nil {
- return uh, ur.Err
- }
-
- if err := gophercloud.DecodeHeader(ur.Header, &uh); err != nil {
- return uh, err
- }
-
- if date, ok := ur.Header["Date"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, ur.Header["Date"][0])
- if err != nil {
- return uh, err
- }
- uh.Date = t
- }
-
- return uh, nil
+func (r UpdateResult) Extract() (*UpdateHeader, error) {
+ var s *UpdateHeader
+ err := r.ExtractInto(&s)
+ return s, err
}
// DeleteHeader represents the headers returned in the response from a Delete request.
type DeleteHeader struct {
- ContentLength int64 `mapstructure:"Content-Length"`
- ContentType string `mapstructure:"Content-Type"`
- Date time.Time `mapstructure:"-"`
- TransID string `mapstructure:"X-Trans-Id"`
+ ContentLength string `json:"Content-Length"`
+ ContentType string `json:"Content-Type"`
+ Date gophercloud.JSONRFC1123 `json:"Date"`
+ TransID string `json:"X-Trans-Id"`
}
// DeleteResult represents the result of a delete operation. To extract the
@@ -248,23 +190,8 @@
// Extract will return a struct of headers returned from a call to Delete. To obtain
// a map of headers, call the ExtractHeader method on the DeleteResult.
-func (dr DeleteResult) Extract() (DeleteHeader, error) {
- var dh DeleteHeader
- if dr.Err != nil {
- return dh, dr.Err
- }
-
- if err := gophercloud.DecodeHeader(dr.Header, &dh); err != nil {
- return dh, err
- }
-
- if date, ok := dr.Header["Date"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, dr.Header["Date"][0])
- if err != nil {
- return dh, err
- }
- dh.Date = t
- }
-
- return dh, nil
+func (r DeleteResult) Extract() (*DeleteHeader, error) {
+ var s *DeleteHeader
+ err := r.ExtractInto(&s)
+ return s, err
}
diff --git a/openstack/objectstorage/v1/objects/results.go b/openstack/objectstorage/v1/objects/results.go
index 530b072..c0d532b 100644
--- a/openstack/objectstorage/v1/objects/results.go
+++ b/openstack/objectstorage/v1/objects/results.go
@@ -4,34 +4,30 @@
"fmt"
"io"
"io/ioutil"
- "strconv"
"strings"
- "time"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
-
- "github.com/mitchellh/mapstructure"
)
// Object is a structure that holds information related to a storage object.
type Object struct {
// Bytes is the total number of bytes that comprise the object.
- Bytes int64 `json:"bytes" mapstructure:"bytes"`
+ Bytes int64 `json:"bytes"`
// ContentType is the content type of the object.
- ContentType string `json:"content_type" mapstructure:"content_type"`
+ ContentType string `json:"content_type"`
// Hash represents the MD5 checksum value of the object's content.
- Hash string `json:"hash" mapstructure:"hash"`
+ Hash string `json:"hash"`
// LastModified is the RFC3339Milli time the object was last modified, represented
// as a string. For any given object (obj), this value may be parsed to a time.Time:
// lastModified, err := time.Parse(gophercloud.RFC3339Milli, obj.LastModified)
- LastModified string `json:"last_modified" mapstructure:"last_modified"`
+ LastModified string `json:"last_modified"`
// Name is the unique name for the object.
- Name string `json:"name" mapstructure:"name"`
+ Name string `json:"name"`
}
// ObjectPage is a single page of objects that is returned from a call to the
@@ -43,10 +39,7 @@
// IsEmpty returns true if a ListResult contains no object names.
func (r ObjectPage) IsEmpty() (bool, error) {
names, err := ExtractNames(r)
- if err != nil {
- return true, err
- }
- return len(names) == 0, nil
+ return len(names) == 0, err
}
// LastMarker returns the last object name in a ListResult.
@@ -62,26 +55,19 @@
}
// ExtractInfo is a function that takes a page of objects and returns their full information.
-func ExtractInfo(page pagination.Page) ([]Object, error) {
- untyped := page.(ObjectPage).Body.([]interface{})
- results := make([]Object, len(untyped))
- for index, each := range untyped {
- object := each.(map[string]interface{})
- err := mapstructure.Decode(object, &results[index])
- if err != nil {
- return results, err
- }
- }
- return results, nil
+func ExtractInfo(r pagination.Page) ([]Object, error) {
+ var s []Object
+ err := (r.(ObjectPage)).ExtractInto(&s)
+ return s, err
}
// ExtractNames is a function that takes a page of objects and returns only their names.
-func ExtractNames(page pagination.Page) ([]string, error) {
- casted := page.(ObjectPage)
+func ExtractNames(r pagination.Page) ([]string, error) {
+ casted := r.(ObjectPage)
ct := casted.Header.Get("Content-Type")
switch {
case strings.HasPrefix(ct, "application/json"):
- parsed, err := ExtractInfo(page)
+ parsed, err := ExtractInfo(r)
if err != nil {
return nil, err
}
@@ -95,7 +81,7 @@
case strings.HasPrefix(ct, "text/plain"):
names := make([]string, 0, 50)
- body := string(page.(ObjectPage).Body.([]uint8))
+ body := string(r.(ObjectPage).Body.([]uint8))
for _, name := range strings.Split(body, "\n") {
if len(name) > 0 {
names = append(names, name)
@@ -112,18 +98,18 @@
// DownloadHeader represents the headers returned in the response from a Download request.
type DownloadHeader struct {
- AcceptRanges string `mapstructure:"Accept-Ranges"`
- ContentDisposition string `mapstructure:"Content-Disposition"`
- ContentEncoding string `mapstructure:"Content-Encoding"`
- ContentLength int64 `mapstructure:"Content-Length"`
- ContentType string `mapstructure:"Content-Type"`
- Date time.Time `mapstructure:"-"`
- DeleteAt time.Time `mapstructure:"-"`
- ETag string `mapstructure:"Etag"`
- LastModified time.Time `mapstructure:"-"`
- ObjectManifest string `mapstructure:"X-Object-Manifest"`
- StaticLargeObject bool `mapstructure:"X-Static-Large-Object"`
- TransID string `mapstructure:"X-Trans-Id"`
+ AcceptRanges string `json:"Accept-Ranges"`
+ ContentDisposition string `json:"Content-Disposition"`
+ ContentEncoding string `json:"Content-Encoding"`
+ ContentLength string `json:"Content-Length"`
+ ContentType string `json:"Content-Type"`
+ Date gophercloud.JSONRFC1123 `json:"Date"`
+ DeleteAt gophercloud.JSONUnix `json:"X-Delete-At"`
+ ETag string `json:"Etag"`
+ LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
+ ObjectManifest string `json:"X-Object-Manifest"`
+ StaticLargeObject bool `json:"X-Static-Large-Object"`
+ TransID string `json:"X-Trans-Id"`
}
// DownloadResult is a *http.Response that is returned from a call to the Download function.
@@ -134,41 +120,10 @@
// Extract will return a struct of headers returned from a call to Download. To obtain
// a map of headers, call the ExtractHeader method on the DownloadResult.
-func (dr DownloadResult) Extract() (DownloadHeader, error) {
- var dh DownloadHeader
- if dr.Err != nil {
- return dh, dr.Err
- }
-
- if err := gophercloud.DecodeHeader(dr.Header, &dh); err != nil {
- return dh, err
- }
-
- if date, ok := dr.Header["Date"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, date[0])
- if err != nil {
- return dh, err
- }
- dh.Date = t
- }
-
- if date, ok := dr.Header["Last-Modified"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, date[0])
- if err != nil {
- return dh, err
- }
- dh.LastModified = t
- }
-
- if date, ok := dr.Header["X-Delete-At"]; ok && len(date) > 0 {
- unix, err := strconv.ParseInt(date[0], 10, 64)
- if err != nil {
- return dh, err
- }
- dh.DeleteAt = time.Unix(unix, 0)
- }
-
- return dh, nil
+func (r DownloadResult) Extract() (*DownloadHeader, error) {
+ var s *DownloadHeader
+ err := r.ExtractInto(&s)
+ return s, err
}
// ExtractContent is a function that takes a DownloadResult's io.Reader body
@@ -176,31 +131,32 @@
// the nature of io.Reader is forward-only - meaning that it can only be read
// once and not rewound. You can recreate a reader from the output of this
// function by using bytes.NewReader(downloadBytes)
-func (dr DownloadResult) ExtractContent() ([]byte, error) {
- if dr.Err != nil {
- return nil, dr.Err
+func (r *DownloadResult) ExtractContent() ([]byte, error) {
+ if r.Err != nil {
+ return nil, r.Err
}
- body, err := ioutil.ReadAll(dr.Body)
+ defer r.Body.Close()
+ body, err := ioutil.ReadAll(r.Body)
if err != nil {
return nil, err
}
- dr.Body.Close()
+ r.Body.Close()
return body, nil
}
// GetHeader represents the headers returned in the response from a Get request.
type GetHeader struct {
- ContentDisposition string `mapstructure:"Content-Disposition"`
- ContentEncoding string `mapstructure:"Content-Encoding"`
- ContentLength int64 `mapstructure:"Content-Length"`
- ContentType string `mapstructure:"Content-Type"`
- Date time.Time `mapstructure:"-"`
- DeleteAt time.Time `mapstructure:"-"`
- ETag string `mapstructure:"Etag"`
- LastModified time.Time `mapstructure:"-"`
- ObjectManifest string `mapstructure:"X-Object-Manifest"`
- StaticLargeObject bool `mapstructure:"X-Static-Large-Object"`
- TransID string `mapstructure:"X-Trans-Id"`
+ ContentDisposition string `json:"Content-Disposition"`
+ ContentEncoding string `json:"Content-Encoding"`
+ ContentLength string `json:"Content-Length"`
+ ContentType string `json:"Content-Type"`
+ Date gophercloud.JSONRFC1123 `json:"Date"`
+ DeleteAt gophercloud.JSONUnix `json:"X-Delete-At"`
+ ETag string `json:"Etag"`
+ LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
+ ObjectManifest string `json:"X-Object-Manifest"`
+ StaticLargeObject bool `json:"X-Static-Large-Object"`
+ TransID string `json:"X-Trans-Id"`
}
// GetResult is a *http.Response that is returned from a call to the Get function.
@@ -210,51 +166,20 @@
// Extract will return a struct of headers returned from a call to Get. To obtain
// a map of headers, call the ExtractHeader method on the GetResult.
-func (gr GetResult) Extract() (GetHeader, error) {
- var gh GetHeader
- if gr.Err != nil {
- return gh, gr.Err
- }
-
- if err := gophercloud.DecodeHeader(gr.Header, &gh); err != nil {
- return gh, err
- }
-
- if date, ok := gr.Header["Date"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, gr.Header["Date"][0])
- if err != nil {
- return gh, err
- }
- gh.Date = t
- }
-
- if date, ok := gr.Header["Last-Modified"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, gr.Header["Last-Modified"][0])
- if err != nil {
- return gh, err
- }
- gh.LastModified = t
- }
-
- if date, ok := gr.Header["X-Delete-At"]; ok && len(date) > 0 {
- unix, err := strconv.ParseInt(date[0], 10, 64)
- if err != nil {
- return gh, err
- }
- gh.DeleteAt = time.Unix(unix, 0)
- }
-
- return gh, nil
+func (r GetResult) Extract() (*GetHeader, error) {
+ var s *GetHeader
+ err := r.ExtractInto(&s)
+ return s, err
}
// ExtractMetadata is a function that takes a GetResult (of type *http.Response)
// and returns the custom metadata associated with the object.
-func (gr GetResult) ExtractMetadata() (map[string]string, error) {
- if gr.Err != nil {
- return nil, gr.Err
+func (r GetResult) ExtractMetadata() (map[string]string, error) {
+ if r.Err != nil {
+ return nil, r.Err
}
metadata := make(map[string]string)
- for k, v := range gr.Header {
+ for k, v := range r.Header {
if strings.HasPrefix(k, "X-Object-Meta-") {
key := strings.TrimPrefix(k, "X-Object-Meta-")
metadata[key] = v[0]
@@ -265,12 +190,12 @@
// CreateHeader represents the headers returned in the response from a Create request.
type CreateHeader struct {
- ContentLength int64 `mapstructure:"Content-Length"`
- ContentType string `mapstructure:"Content-Type"`
- Date time.Time `mapstructure:"-"`
- ETag string `mapstructure:"Etag"`
- LastModified time.Time `mapstructure:"-"`
- TransID string `mapstructure:"X-Trans-Id"`
+ ContentLength string `json:"Content-Length"`
+ ContentType string `json:"Content-Type"`
+ Date gophercloud.JSONRFC1123 `json:"Date"`
+ ETag string `json:"Etag"`
+ LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
+ TransID string `json:"X-Trans-Id"`
}
// CreateResult represents the result of a create operation.
@@ -280,41 +205,18 @@
// Extract will return a struct of headers returned from a call to Create. To obtain
// a map of headers, call the ExtractHeader method on the CreateResult.
-func (cr CreateResult) Extract() (CreateHeader, error) {
- var ch CreateHeader
- if cr.Err != nil {
- return ch, cr.Err
- }
-
- if err := gophercloud.DecodeHeader(cr.Header, &ch); err != nil {
- return ch, err
- }
-
- if date, ok := cr.Header["Date"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, cr.Header["Date"][0])
- if err != nil {
- return ch, err
- }
- ch.Date = t
- }
-
- if date, ok := cr.Header["Last-Modified"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, cr.Header["Last-Modified"][0])
- if err != nil {
- return ch, err
- }
- ch.LastModified = t
- }
-
- return ch, nil
+func (r CreateResult) Extract() (*CreateHeader, error) {
+ var s *CreateHeader
+ err := r.ExtractInto(&s)
+ return s, err
}
// UpdateHeader represents the headers returned in the response from a Update request.
type UpdateHeader struct {
- ContentLength int64 `mapstructure:"Content-Length"`
- ContentType string `mapstructure:"Content-Type"`
- Date time.Time `mapstructure:"-"`
- TransID string `mapstructure:"X-Trans-Id"`
+ ContentLength string `json:"Content-Length"`
+ ContentType string `json:"Content-Type"`
+ Date gophercloud.JSONRFC1123 `json:"Date"`
+ TransID string `json:"X-Trans-Id"`
}
// UpdateResult represents the result of an update operation.
@@ -324,33 +226,18 @@
// Extract will return a struct of headers returned from a call to Update. To obtain
// a map of headers, call the ExtractHeader method on the UpdateResult.
-func (ur UpdateResult) Extract() (UpdateHeader, error) {
- var uh UpdateHeader
- if ur.Err != nil {
- return uh, ur.Err
- }
-
- if err := gophercloud.DecodeHeader(ur.Header, &uh); err != nil {
- return uh, err
- }
-
- if date, ok := ur.Header["Date"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, ur.Header["Date"][0])
- if err != nil {
- return uh, err
- }
- uh.Date = t
- }
-
- return uh, nil
+func (r UpdateResult) Extract() (*UpdateHeader, error) {
+ var s *UpdateHeader
+ err := r.ExtractInto(&s)
+ return s, err
}
// DeleteHeader represents the headers returned in the response from a Delete request.
type DeleteHeader struct {
- ContentLength int64 `mapstructure:"Content-Length"`
- ContentType string `mapstructure:"Content-Type"`
- Date time.Time `mapstructure:"-"`
- TransID string `mapstructure:"X-Trans-Id"`
+ ContentLength string `json:"Content-Length"`
+ ContentType string `json:"Content-Type"`
+ Date gophercloud.JSONRFC1123 `json:"Date"`
+ TransID string `json:"X-Trans-Id"`
}
// DeleteResult represents the result of a delete operation.
@@ -360,37 +247,22 @@
// Extract will return a struct of headers returned from a call to Delete. To obtain
// a map of headers, call the ExtractHeader method on the DeleteResult.
-func (dr DeleteResult) Extract() (DeleteHeader, error) {
- var dh DeleteHeader
- if dr.Err != nil {
- return dh, dr.Err
- }
-
- if err := gophercloud.DecodeHeader(dr.Header, &dh); err != nil {
- return dh, err
- }
-
- if date, ok := dr.Header["Date"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, dr.Header["Date"][0])
- if err != nil {
- return dh, err
- }
- dh.Date = t
- }
-
- return dh, nil
+func (r DeleteResult) Extract() (*DeleteHeader, error) {
+ var s *DeleteHeader
+ err := r.ExtractInto(&s)
+ return s, err
}
// CopyHeader represents the headers returned in the response from a Copy request.
type CopyHeader struct {
- ContentLength int64 `mapstructure:"Content-Length"`
- ContentType string `mapstructure:"Content-Type"`
- CopiedFrom string `mapstructure:"X-Copied-From"`
- CopiedFromLastModified time.Time `mapstructure:"-"`
- Date time.Time `mapstructure:"-"`
- ETag string `mapstructure:"Etag"`
- LastModified time.Time `mapstructure:"-"`
- TransID string `mapstructure:"X-Trans-Id"`
+ ContentLength int64 `json:"Content-Length"`
+ ContentType string `json:"Content-Type"`
+ CopiedFrom string `json:"X-Copied-From"`
+ CopiedFromLastModified gophercloud.JSONRFC1123 `json:"X-Copied-From-Last-Modified"`
+ Date gophercloud.JSONRFC1123 `json:"Date"`
+ ETag string `json:"Etag"`
+ LastModified gophercloud.JSONRFC1123 `json:"Last-Modified"`
+ TransID string `json:"X-Trans-Id"`
}
// CopyResult represents the result of a copy operation.
@@ -400,39 +272,8 @@
// Extract will return a struct of headers returned from a call to Copy. To obtain
// a map of headers, call the ExtractHeader method on the CopyResult.
-func (cr CopyResult) Extract() (CopyHeader, error) {
- var ch CopyHeader
- if cr.Err != nil {
- return ch, cr.Err
- }
-
- if err := gophercloud.DecodeHeader(cr.Header, &ch); err != nil {
- return ch, err
- }
-
- if date, ok := cr.Header["Date"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, cr.Header["Date"][0])
- if err != nil {
- return ch, err
- }
- ch.Date = t
- }
-
- if date, ok := cr.Header["Last-Modified"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, cr.Header["Last-Modified"][0])
- if err != nil {
- return ch, err
- }
- ch.LastModified = t
- }
-
- if date, ok := cr.Header["X-Copied-From-Last-Modified"]; ok && len(date) > 0 {
- t, err := time.Parse(time.RFC1123, cr.Header["X-Copied-From-Last-Modified"][0])
- if err != nil {
- return ch, err
- }
- ch.CopiedFromLastModified = t
- }
-
- return ch, nil
+func (r CopyResult) Extract() (*CopyHeader, error) {
+ var s *CopyHeader
+ err := r.ExtractInto(&s)
+ return s, err
}
diff --git a/openstack/orchestration/v1/apiversions/results.go b/openstack/orchestration/v1/apiversions/results.go
index 0373ccc..a7c22a2 100644
--- a/openstack/orchestration/v1/apiversions/results.go
+++ b/openstack/orchestration/v1/apiversions/results.go
@@ -1,7 +1,6 @@
package apiversions
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -9,9 +8,9 @@
// APIVersion represents an API version for Neutron. It contains the status of
// the API, and its unique ID.
type APIVersion struct {
- Status string `mapstructure:"status"`
- ID string `mapstructure:"id"`
- Links []gophercloud.Link `mapstructure:"links"`
+ Status string `json:"status"`
+ ID string `json:"id"`
+ Links []gophercloud.Link `json:"links"`
}
// APIVersionPage is the page returned by a pager when traversing over a
@@ -23,20 +22,15 @@
// IsEmpty checks whether an APIVersionPage struct is empty.
func (r APIVersionPage) IsEmpty() (bool, error) {
is, err := ExtractAPIVersions(r)
- if err != nil {
- return true, err
- }
- return len(is) == 0, nil
+ return len(is) == 0, err
}
// ExtractAPIVersions takes a collection page, extracts all of the elements,
// and returns them a slice of APIVersion structs. It is effectively a cast.
-func ExtractAPIVersions(page pagination.Page) ([]APIVersion, error) {
- var resp struct {
- Versions []APIVersion `mapstructure:"versions"`
+func ExtractAPIVersions(r pagination.Page) ([]APIVersion, error) {
+ var s struct {
+ APIVersions []APIVersion `json:"versions"`
}
-
- err := mapstructure.Decode(page.(APIVersionPage).Body, &resp)
-
- return resp.Versions, err
+ err := (r.(APIVersionPage)).ExtractInto(&s)
+ return s.APIVersions, err
}
diff --git a/openstack/orchestration/v1/buildinfo/results.go b/openstack/orchestration/v1/buildinfo/results.go
index fe655a3..c3d2cdb 100644
--- a/openstack/orchestration/v1/buildinfo/results.go
+++ b/openstack/orchestration/v1/buildinfo/results.go
@@ -1,19 +1,18 @@
package buildinfo
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
)
// Revision represents the API/Engine revision of a Heat deployment.
type Revision struct {
- Revision string `mapstructure:"revision"`
+ Revision string `json:"revision"`
}
// BuildInfo represents the build information for a Heat deployment.
type BuildInfo struct {
- API Revision `mapstructure:"api"`
- Engine Revision `mapstructure:"engine"`
+ API Revision `json:"api"`
+ Engine Revision `json:"engine"`
}
// GetResult represents the result of a Get operation.
@@ -24,14 +23,7 @@
// Extract returns a pointer to a BuildInfo object and is called after a
// Get operation.
func (r GetResult) Extract() (*BuildInfo, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res BuildInfo
- if err := mapstructure.Decode(r.Body, &res); err != nil {
- return nil, err
- }
-
- return &res, nil
+ var s *BuildInfo
+ err := r.ExtractInto(&s)
+ return s, err
}
diff --git a/openstack/orchestration/v1/stackevents/fixtures.go b/openstack/orchestration/v1/stackevents/fixtures.go
index b6ac274..48524e5 100644
--- a/openstack/orchestration/v1/stackevents/fixtures.go
+++ b/openstack/orchestration/v1/stackevents/fixtures.go
@@ -15,7 +15,7 @@
var FindExpected = []Event{
Event{
ResourceName: "hello_world",
- Time: time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
+ Time: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC)),
Links: []gophercloud.Link{
gophercloud.Link{
Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/06feb26f-9298-4a9b-8749-9d770e5d577a",
@@ -38,7 +38,7 @@
},
Event{
ResourceName: "hello_world",
- Time: time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC),
+ Time: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC)),
Links: []gophercloud.Link{
gophercloud.Link{
Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18",
@@ -132,7 +132,7 @@
var ListExpected = []Event{
Event{
ResourceName: "hello_world",
- Time: time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
+ Time: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC)),
Links: []gophercloud.Link{
gophercloud.Link{
Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/06feb26f-9298-4a9b-8749-9d770e5d577a",
@@ -155,7 +155,7 @@
},
Event{
ResourceName: "hello_world",
- Time: time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC),
+ Time: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC)),
Links: []gophercloud.Link{
gophercloud.Link{
Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18",
@@ -257,7 +257,7 @@
var ListResourceEventsExpected = []Event{
Event{
ResourceName: "hello_world",
- Time: time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
+ Time: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC)),
Links: []gophercloud.Link{
gophercloud.Link{
Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/06feb26f-9298-4a9b-8749-9d770e5d577a",
@@ -280,7 +280,7 @@
},
Event{
ResourceName: "hello_world",
- Time: time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC),
+ Time: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC)),
Links: []gophercloud.Link{
gophercloud.Link{
Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18",
@@ -381,7 +381,7 @@
// GetExpected represents the expected object from a Get request.
var GetExpected = &Event{
ResourceName: "hello_world",
- Time: time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC),
+ Time: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 27, 0, time.UTC)),
Links: []gophercloud.Link{
gophercloud.Link{
Href: "http://166.78.160.107:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/5f57cff9-93fc-424e-9f78-df0515e7f48b/resources/hello_world/events/93940999-7d40-44ae-8de4-19624e7b8d18",
diff --git a/openstack/orchestration/v1/stackevents/results.go b/openstack/orchestration/v1/stackevents/results.go
index ac94bb5..6c7f183 100644
--- a/openstack/orchestration/v1/stackevents/results.go
+++ b/openstack/orchestration/v1/stackevents/results.go
@@ -1,11 +1,6 @@
package stackevents
import (
- "fmt"
- "reflect"
- "time"
-
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -13,23 +8,23 @@
// Event represents a stack event.
type Event struct {
// The name of the resource for which the event occurred.
- ResourceName string `mapstructure:"resource_name"`
+ ResourceName string `json:"resource_name"`
// The time the event occurred.
- Time time.Time `mapstructure:"-"`
+ Time gophercloud.JSONRFC3339NoZ `json:"event_time"`
// The URLs to the event.
- Links []gophercloud.Link `mapstructure:"links"`
+ Links []gophercloud.Link `json:"links"`
// The logical ID of the stack resource.
- LogicalResourceID string `mapstructure:"logical_resource_id"`
+ LogicalResourceID string `json:"logical_resource_id"`
// The reason of the status of the event.
- ResourceStatusReason string `mapstructure:"resource_status_reason"`
+ ResourceStatusReason string `json:"resource_status_reason"`
// The status of the event.
- ResourceStatus string `mapstructure:"resource_status"`
+ ResourceStatus string `json:"resource_status"`
// The physical ID of the stack resource.
- PhysicalResourceID string `mapstructure:"physical_resource_id"`
+ PhysicalResourceID string `json:"physical_resource_id"`
// The event ID.
- ID string `mapstructure:"id"`
+ ID string `json:"id"`
// Properties of the stack resource.
- ResourceProperties map[string]interface{} `mapstructure:"resource_properties"`
+ ResourceProperties map[string]interface{} `json:"resource_properties"`
}
// FindResult represents the result of a Find operation.
@@ -40,32 +35,11 @@
// Extract returns a slice of Event objects and is called after a
// Find operation.
func (r FindResult) Extract() ([]Event, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Events []Event `json:"events"`
}
-
- var res struct {
- Res []Event `mapstructure:"events"`
- }
-
- if err := mapstructure.Decode(r.Body, &res); err != nil {
- return nil, err
- }
-
- events := r.Body.(map[string]interface{})["events"].([]interface{})
-
- for i, eventRaw := range events {
- event := eventRaw.(map[string]interface{})
- if date, ok := event["event_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- res.Res[i].Time = t
- }
- }
-
- return res.Res, nil
+ err := r.ExtractInto(&s)
+ return s.Events, err
}
// EventPage abstracts the raw results of making a List() request against the API.
@@ -78,10 +52,7 @@
// IsEmpty returns true if a page contains no Server results.
func (r EventPage) IsEmpty() (bool, error) {
events, err := ExtractEvents(r)
- if err != nil {
- return true, err
- }
- return len(events) == 0, nil
+ return len(events) == 0, err
}
// LastMarker returns the last stack ID in a ListResult.
@@ -97,39 +68,12 @@
}
// ExtractEvents interprets the results of a single page from a List() call, producing a slice of Event entities.
-func ExtractEvents(page pagination.Page) ([]Event, error) {
- casted := page.(EventPage).Body
-
- var res struct {
- Res []Event `mapstructure:"events"`
+func ExtractEvents(r pagination.Page) ([]Event, error) {
+ var s struct {
+ Events []Event `json:"events"`
}
-
- if err := mapstructure.Decode(casted, &res); err != nil {
- return nil, err
- }
-
- var events []interface{}
- switch casted.(type) {
- case map[string]interface{}:
- events = casted.(map[string]interface{})["events"].([]interface{})
- case map[string][]interface{}:
- events = casted.(map[string][]interface{})["events"]
- default:
- return res.Res, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted))
- }
-
- for i, eventRaw := range events {
- event := eventRaw.(map[string]interface{})
- if date, ok := event["event_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- res.Res[i].Time = t
- }
- }
-
- return res.Res, nil
+ err := (r.(EventPage)).ExtractInto(&s)
+ return s.Events, err
}
// ExtractResourceEvents interprets the results of a single page from a
@@ -146,27 +90,9 @@
// Extract returns a pointer to an Event object and is called after a
// Get operation.
func (r GetResult) Extract() (*Event, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Event *Event `json:"event"`
}
-
- var res struct {
- Res *Event `mapstructure:"event"`
- }
-
- if err := mapstructure.Decode(r.Body, &res); err != nil {
- return nil, err
- }
-
- event := r.Body.(map[string]interface{})["event"].(map[string]interface{})
-
- if date, ok := event["event_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- res.Res.Time = t
- }
-
- return res.Res, nil
+ err := r.ExtractInto(&s)
+ return s.Event, err
}
diff --git a/openstack/orchestration/v1/stackresources/fixtures.go b/openstack/orchestration/v1/stackresources/fixtures.go
index cdf1f3c..a622f7f 100644
--- a/openstack/orchestration/v1/stackresources/fixtures.go
+++ b/openstack/orchestration/v1/stackresources/fixtures.go
@@ -27,8 +27,8 @@
},
LogicalID: "hello_world",
StatusReason: "state changed",
- UpdatedTime: time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
- CreationTime: time.Date(2015, 2, 5, 21, 33, 10, 0, time.UTC),
+ UpdatedTime: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC)),
+ CreationTime: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 10, 0, time.UTC)),
RequiredBy: []interface{}{},
Status: "CREATE_IN_PROGRESS",
PhysicalID: "49181cd6-169a-4130-9455-31185bbfc5bf",
@@ -98,8 +98,8 @@
},
LogicalID: "hello_world",
StatusReason: "state changed",
- UpdatedTime: time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC),
- CreationTime: time.Date(2015, 2, 5, 21, 33, 10, 0, time.UTC),
+ UpdatedTime: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 11, 0, time.UTC)),
+ CreationTime: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 5, 21, 33, 10, 0, time.UTC)),
RequiredBy: []interface{}{},
Status: "CREATE_IN_PROGRESS",
PhysicalID: "49181cd6-169a-4130-9455-31185bbfc5bf",
@@ -176,7 +176,7 @@
LogicalID: "wordpress_instance",
Attributes: map[string]interface{}{"SXSW": "atx"},
StatusReason: "state changed",
- UpdatedTime: time.Date(2014, 12, 10, 18, 34, 35, 0, time.UTC),
+ UpdatedTime: gophercloud.JSONRFC3339NoZ(time.Date(2014, 12, 10, 18, 34, 35, 0, time.UTC)),
RequiredBy: []interface{}{},
Status: "CREATE_COMPLETE",
PhysicalID: "00e3a2fe-c65d-403c-9483-4db9930dd194",
diff --git a/openstack/orchestration/v1/stackresources/results.go b/openstack/orchestration/v1/stackresources/results.go
index edbd34f..951f144 100644
--- a/openstack/orchestration/v1/stackresources/results.go
+++ b/openstack/orchestration/v1/stackresources/results.go
@@ -2,29 +2,25 @@
import (
"encoding/json"
- "fmt"
- "reflect"
- "time"
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
// Resource represents a stack resource.
type Resource struct {
- Attributes map[string]interface{} `mapstructure:"attributes"`
- CreationTime time.Time `mapstructure:"-"`
- Description string `mapstructure:"description"`
- Links []gophercloud.Link `mapstructure:"links"`
- LogicalID string `mapstructure:"logical_resource_id"`
- Name string `mapstructure:"resource_name"`
- PhysicalID string `mapstructure:"physical_resource_id"`
- RequiredBy []interface{} `mapstructure:"required_by"`
- Status string `mapstructure:"resource_status"`
- StatusReason string `mapstructure:"resource_status_reason"`
- Type string `mapstructure:"resource_type"`
- UpdatedTime time.Time `mapstructure:"-"`
+ Attributes map[string]interface{} `json:"attributes"`
+ CreationTime gophercloud.JSONRFC3339NoZ `json:"creation_time"`
+ Description string `json:"description"`
+ Links []gophercloud.Link `json:"links"`
+ LogicalID string `json:"logical_resource_id"`
+ Name string `json:"resource_name"`
+ PhysicalID string `json:"physical_resource_id"`
+ RequiredBy []interface{} `json:"required_by"`
+ Status string `json:"resource_status"`
+ StatusReason string `json:"resource_status_reason"`
+ Type string `json:"resource_type"`
+ UpdatedTime gophercloud.JSONRFC3339NoZ `json:"updated_time"`
}
// FindResult represents the result of a Find operation.
@@ -35,39 +31,11 @@
// Extract returns a slice of Resource objects and is called after a
// Find operation.
func (r FindResult) Extract() ([]Resource, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Resources []Resource `json:"resources"`
}
-
- var res struct {
- Res []Resource `mapstructure:"resources"`
- }
-
- if err := mapstructure.Decode(r.Body, &res); err != nil {
- return nil, err
- }
-
- resources := r.Body.(map[string]interface{})["resources"].([]interface{})
-
- for i, resourceRaw := range resources {
- resource := resourceRaw.(map[string]interface{})
- if date, ok := resource["updated_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- res.Res[i].UpdatedTime = t
- }
- if date, ok := resource["creation_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- res.Res[i].CreationTime = t
- }
- }
-
- return res.Res, nil
+ err := r.ExtractInto(&s)
+ return s.Resources, err
}
// ResourcePage abstracts the raw results of making a List() request against the API.
@@ -80,51 +48,16 @@
// IsEmpty returns true if a page contains no Server results.
func (r ResourcePage) IsEmpty() (bool, error) {
resources, err := ExtractResources(r)
- if err != nil {
- return true, err
- }
- return len(resources) == 0, nil
+ return len(resources) == 0, err
}
// ExtractResources interprets the results of a single page from a List() call, producing a slice of Resource entities.
-func ExtractResources(page pagination.Page) ([]Resource, error) {
- casted := page.(ResourcePage).Body
-
- var response struct {
- Resources []Resource `mapstructure:"resources"`
+func ExtractResources(r pagination.Page) ([]Resource, error) {
+ var s struct {
+ Resources []Resource `json:"resources"`
}
- if err := mapstructure.Decode(casted, &response); err != nil {
- return nil, err
- }
- var resources []interface{}
- switch casted.(type) {
- case map[string]interface{}:
- resources = casted.(map[string]interface{})["resources"].([]interface{})
- case map[string][]interface{}:
- resources = casted.(map[string][]interface{})["resources"]
- default:
- return response.Resources, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted))
- }
-
- for i, resourceRaw := range resources {
- resource := resourceRaw.(map[string]interface{})
- if date, ok := resource["updated_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- response.Resources[i].UpdatedTime = t
- }
- if date, ok := resource["creation_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- response.Resources[i].CreationTime = t
- }
- }
-
- return response.Resources, nil
+ err := (r.(ResourcePage)).ExtractInto(&s)
+ return s.Resources, err
}
// GetResult represents the result of a Get operation.
@@ -135,36 +68,11 @@
// Extract returns a pointer to a Resource object and is called after a
// Get operation.
func (r GetResult) Extract() (*Resource, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Resource *Resource `json:"resource"`
}
-
- var res struct {
- Res *Resource `mapstructure:"resource"`
- }
-
- if err := mapstructure.Decode(r.Body, &res); err != nil {
- return nil, err
- }
-
- resource := r.Body.(map[string]interface{})["resource"].(map[string]interface{})
-
- if date, ok := resource["updated_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- res.Res.UpdatedTime = t
- }
- if date, ok := resource["creation_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- res.Res.CreationTime = t
- }
-
- return res.Res, nil
+ err := r.ExtractInto(&s)
+ return s.Resource, err
}
// MetadataResult represents the result of a Metadata operation.
@@ -175,19 +83,11 @@
// Extract returns a map object and is called after a
// Metadata operation.
func (r MetadataResult) Extract() (map[string]string, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Meta map[string]string `json:"metadata"`
}
-
- var res struct {
- Meta map[string]string `mapstructure:"metadata"`
- }
-
- if err := mapstructure.Decode(r.Body, &res); err != nil {
- return nil, err
- }
-
- return res.Meta, nil
+ err := r.ExtractInto(&s)
+ return s.Meta, err
}
// ResourceTypePage abstracts the raw results of making a ListTypes() request against the API.
@@ -200,10 +100,7 @@
// IsEmpty returns true if a ResourceTypePage contains no resource types.
func (r ResourceTypePage) IsEmpty() (bool, error) {
rts, err := ExtractResourceTypes(r)
- if err != nil {
- return true, err
- }
- return len(rts) == 0, nil
+ return len(rts) == 0, err
}
// ResourceTypes represents the type that holds the result of ExtractResourceTypes.
@@ -223,25 +120,20 @@
}
// ExtractResourceTypes extracts and returns resource types.
-func ExtractResourceTypes(page pagination.Page) (ResourceTypes, error) {
- casted := page.(ResourceTypePage).Body
-
- var response struct {
- ResourceTypes ResourceTypes `mapstructure:"resource_types"`
+func ExtractResourceTypes(r pagination.Page) (ResourceTypes, error) {
+ var s struct {
+ ResourceTypes ResourceTypes `json:"resource_types"`
}
-
- if err := mapstructure.Decode(casted, &response); err != nil {
- return nil, err
- }
- return response.ResourceTypes, nil
+ err := (r.(ResourceTypePage)).ExtractInto(&s)
+ return s.ResourceTypes, err
}
// TypeSchema represents a stack resource schema.
type TypeSchema struct {
- Attributes map[string]interface{} `mapstructure:"attributes"`
- Properties map[string]interface{} `mapstrucutre:"properties"`
- ResourceType string `mapstructure:"resource_type"`
- SupportStatus map[string]interface{} `mapstructure:"support_status"`
+ Attributes map[string]interface{} `json:"attributes"`
+ Properties map[string]interface{} `json:"properties"`
+ ResourceType string `json:"resource_type"`
+ SupportStatus map[string]interface{} `json:"support_status"`
}
// SchemaResult represents the result of a Schema operation.
@@ -252,17 +144,9 @@
// Extract returns a pointer to a TypeSchema object and is called after a
// Schema operation.
func (r SchemaResult) Extract() (*TypeSchema, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res TypeSchema
-
- if err := mapstructure.Decode(r.Body, &res); err != nil {
- return nil, err
- }
-
- return &res, nil
+ var s *TypeSchema
+ err := r.ExtractInto(&s)
+ return s, err
}
// TemplateResult represents the result of a Template operation.
diff --git a/openstack/orchestration/v1/stacks/fixtures.go b/openstack/orchestration/v1/stacks/fixtures.go
index 49e4168..f1d66f4 100644
--- a/openstack/orchestration/v1/stacks/fixtures.go
+++ b/openstack/orchestration/v1/stacks/fixtures.go
@@ -60,7 +60,7 @@
},
StatusReason: "Stack CREATE completed successfully",
Name: "postman_stack",
- CreationTime: time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC),
+ CreationTime: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC)),
Status: "CREATE_COMPLETE",
ID: "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
Tags: []string{"rackspace", "atx"},
@@ -75,8 +75,8 @@
},
StatusReason: "Stack successfully updated",
Name: "gophercloud-test-stack-2",
- CreationTime: time.Date(2014, 12, 11, 17, 39, 16, 0, time.UTC),
- UpdatedTime: time.Date(2014, 12, 11, 17, 40, 37, 0, time.UTC),
+ CreationTime: gophercloud.JSONRFC3339NoZ(time.Date(2014, 12, 11, 17, 39, 16, 0, time.UTC)),
+ UpdatedTime: gophercloud.JSONRFC3339NoZ(time.Date(2014, 12, 11, 17, 40, 37, 0, time.UTC)),
Status: "UPDATE_COMPLETE",
ID: "db6977b2-27aa-4775-9ae7-6213212d4ada",
Tags: []string{"sfo", "satx"},
@@ -157,7 +157,7 @@
StatusReason: "Stack CREATE completed successfully",
Name: "postman_stack",
Outputs: []map[string]interface{}{},
- CreationTime: time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC),
+ CreationTime: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC)),
Links: []gophercloud.Link{
gophercloud.Link{
Href: "http://166.76.160.117:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87",
@@ -255,7 +255,7 @@
"OS::stack_id": "16ef0584-4458-41eb-87c8-0dc8d5f66c87",
},
Name: "postman_stack",
- CreationTime: time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC),
+ CreationTime: gophercloud.JSONRFC3339NoZ(time.Date(2015, 2, 3, 20, 7, 39, 0, time.UTC)),
Links: []gophercloud.Link{
gophercloud.Link{
Href: "http://166.76.160.117:8004/v1/98606384f58d4ad0b3db7d0d779549ac/stacks/postman_stack/16ef0584-4458-41eb-87c8-0dc8d5f66c87",
diff --git a/openstack/orchestration/v1/stacks/results.go b/openstack/orchestration/v1/stacks/results.go
index 72855ff..5da178e 100644
--- a/openstack/orchestration/v1/stacks/results.go
+++ b/openstack/orchestration/v1/stacks/results.go
@@ -2,19 +2,15 @@
import (
"encoding/json"
- "fmt"
- "reflect"
- "time"
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
// CreatedStack represents the object extracted from a Create operation.
type CreatedStack struct {
- ID string `mapstructure:"id"`
- Links []gophercloud.Link `mapstructure:"links"`
+ ID string `json:"id"`
+ Links []gophercloud.Link `json:"links"`
}
// CreateResult represents the result of a Create operation.
@@ -25,19 +21,11 @@
// Extract returns a pointer to a CreatedStack object and is called after a
// Create operation.
func (r CreateResult) Extract() (*CreatedStack, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ CreatedStack *CreatedStack `json:"stack"`
}
-
- var res struct {
- Stack *CreatedStack `mapstructure:"stack"`
- }
-
- if err := mapstructure.Decode(r.Body, &res); err != nil {
- return nil, err
- }
-
- return res.Stack, nil
+ err := r.ExtractInto(&s)
+ return s.CreatedStack, err
}
// AdoptResult represents the result of an Adopt operation. AdoptResult has the
@@ -54,90 +42,50 @@
// IsEmpty returns true if a ListResult contains no Stacks.
func (r StackPage) IsEmpty() (bool, error) {
stacks, err := ExtractStacks(r)
- if err != nil {
- return true, err
- }
- return len(stacks) == 0, nil
+ return len(stacks) == 0, err
}
// ListedStack represents an element in the slice extracted from a List operation.
type ListedStack struct {
- CreationTime time.Time `mapstructure:"-"`
- Description string `mapstructure:"description"`
- ID string `mapstructure:"id"`
- Links []gophercloud.Link `mapstructure:"links"`
- Name string `mapstructure:"stack_name"`
- Status string `mapstructure:"stack_status"`
- StatusReason string `mapstructure:"stack_status_reason"`
- Tags []string `mapstructure:"tags"`
- UpdatedTime time.Time `mapstructure:"-"`
+ CreationTime gophercloud.JSONRFC3339NoZ `json:"creation_time"`
+ Description string `json:"description"`
+ ID string `json:"id"`
+ Links []gophercloud.Link `json:"links"`
+ Name string `json:"stack_name"`
+ Status string `json:"stack_status"`
+ StatusReason string `json:"stack_status_reason"`
+ Tags []string `json:"tags"`
+ UpdatedTime gophercloud.JSONRFC3339NoZ `json:"updated_time"`
}
// ExtractStacks extracts and returns a slice of ListedStack. It is used while iterating
// over a stacks.List call.
-func ExtractStacks(page pagination.Page) ([]ListedStack, error) {
- casted := page.(StackPage).Body
-
- var res struct {
- Stacks []ListedStack `mapstructure:"stacks"`
+func ExtractStacks(r pagination.Page) ([]ListedStack, error) {
+ var s struct {
+ ListedStacks []ListedStack `json:"stacks"`
}
-
- err := mapstructure.Decode(casted, &res)
- if err != nil {
- return nil, err
- }
-
- var rawStacks []interface{}
- switch casted.(type) {
- case map[string]interface{}:
- rawStacks = casted.(map[string]interface{})["stacks"].([]interface{})
- case map[string][]interface{}:
- rawStacks = casted.(map[string][]interface{})["stacks"]
- default:
- return res.Stacks, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted))
- }
-
- for i := range rawStacks {
- thisStack := (rawStacks[i]).(map[string]interface{})
-
- if t, ok := thisStack["creation_time"].(string); ok && t != "" {
- creationTime, err := time.Parse(gophercloud.StackFmtTime, t)
- if err != nil {
- return res.Stacks, err
- }
- res.Stacks[i].CreationTime = creationTime
- }
-
- if t, ok := thisStack["updated_time"].(string); ok && t != "" {
- updatedTime, err := time.Parse(gophercloud.StackFmtTime, t)
- if err != nil {
- return res.Stacks, err
- }
- res.Stacks[i].UpdatedTime = updatedTime
- }
- }
-
- return res.Stacks, nil
+ err := (r.(StackPage)).ExtractInto(&s)
+ return s.ListedStacks, err
}
// RetrievedStack represents the object extracted from a Get operation.
type RetrievedStack struct {
- Capabilities []interface{} `mapstructure:"capabilities"`
- CreationTime time.Time `mapstructure:"-"`
- Description string `mapstructure:"description"`
- DisableRollback bool `mapstructure:"disable_rollback"`
- ID string `mapstructure:"id"`
- Links []gophercloud.Link `mapstructure:"links"`
- NotificationTopics []interface{} `mapstructure:"notification_topics"`
- Outputs []map[string]interface{} `mapstructure:"outputs"`
- Parameters map[string]string `mapstructure:"parameters"`
- Name string `mapstructure:"stack_name"`
- Status string `mapstructure:"stack_status"`
- StatusReason string `mapstructure:"stack_status_reason"`
- Tags []string `mapstructure:"tags"`
- TemplateDescription string `mapstructure:"template_description"`
- Timeout int `mapstructure:"timeout_mins"`
- UpdatedTime time.Time `mapstructure:"-"`
+ Capabilities []interface{} `json:"capabilities"`
+ CreationTime gophercloud.JSONRFC3339NoZ `json:"creation_time"`
+ Description string `json:"description"`
+ DisableRollback bool `json:"disable_rollback"`
+ ID string `json:"id"`
+ Links []gophercloud.Link `json:"links"`
+ NotificationTopics []interface{} `json:"notification_topics"`
+ Outputs []map[string]interface{} `json:"outputs"`
+ Parameters map[string]string `json:"parameters"`
+ Name string `json:"stack_name"`
+ Status string `json:"stack_status"`
+ StatusReason string `json:"stack_status_reason"`
+ Tags []string `json:"tags"`
+ TemplateDescription string `json:"template_description"`
+ Timeout int `json:"timeout_mins"`
+ UpdatedTime gophercloud.JSONRFC3339NoZ `json:"updated_time"`
}
// GetResult represents the result of a Get operation.
@@ -148,46 +96,11 @@
// Extract returns a pointer to a RetrievedStack object and is called after a
// Get operation.
func (r GetResult) Extract() (*RetrievedStack, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Stack *RetrievedStack `json:"stack"`
}
-
- var res struct {
- Stack *RetrievedStack `mapstructure:"stack"`
- }
-
- config := &mapstructure.DecoderConfig{
- Result: &res,
- WeaklyTypedInput: true,
- }
- decoder, err := mapstructure.NewDecoder(config)
- if err != nil {
- return nil, err
- }
-
- if err := decoder.Decode(r.Body); err != nil {
- return nil, err
- }
-
- b := r.Body.(map[string]interface{})["stack"].(map[string]interface{})
-
- if date, ok := b["creation_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- res.Stack.CreationTime = t
- }
-
- if date, ok := b["updated_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- res.Stack.UpdatedTime = t
- }
-
- return res.Stack, err
+ err := r.ExtractInto(&s)
+ return s.Stack, err
}
// UpdateResult represents the result of a Update operation.
@@ -202,19 +115,19 @@
// PreviewedStack represents the result of a Preview operation.
type PreviewedStack struct {
- Capabilities []interface{} `mapstructure:"capabilities"`
- CreationTime time.Time `mapstructure:"-"`
- Description string `mapstructure:"description"`
- DisableRollback bool `mapstructure:"disable_rollback"`
- ID string `mapstructure:"id"`
- Links []gophercloud.Link `mapstructure:"links"`
- Name string `mapstructure:"stack_name"`
- NotificationTopics []interface{} `mapstructure:"notification_topics"`
- Parameters map[string]string `mapstructure:"parameters"`
- Resources []interface{} `mapstructure:"resources"`
- TemplateDescription string `mapstructure:"template_description"`
- Timeout int `mapstructure:"timeout_mins"`
- UpdatedTime time.Time `mapstructure:"-"`
+ Capabilities []interface{} `json:"capabilities"`
+ CreationTime gophercloud.JSONRFC3339NoZ `json:"creation_time"`
+ Description string `json:"description"`
+ DisableRollback bool `json:"disable_rollback"`
+ ID string `json:"id"`
+ Links []gophercloud.Link `json:"links"`
+ Name string `json:"stack_name"`
+ NotificationTopics []interface{} `json:"notification_topics"`
+ Parameters map[string]string `json:"parameters"`
+ Resources []interface{} `json:"resources"`
+ TemplateDescription string `json:"template_description"`
+ Timeout int `json:"timeout_mins"`
+ UpdatedTime gophercloud.JSONRFC3339NoZ `json:"updated_time"`
}
// PreviewResult represents the result of a Preview operation.
@@ -225,60 +138,25 @@
// Extract returns a pointer to a PreviewedStack object and is called after a
// Preview operation.
func (r PreviewResult) Extract() (*PreviewedStack, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ PreviewedStack *PreviewedStack `json:"stack"`
}
-
- var res struct {
- Stack *PreviewedStack `mapstructure:"stack"`
- }
-
- config := &mapstructure.DecoderConfig{
- Result: &res,
- WeaklyTypedInput: true,
- }
- decoder, err := mapstructure.NewDecoder(config)
- if err != nil {
- return nil, err
- }
-
- if err := decoder.Decode(r.Body); err != nil {
- return nil, err
- }
-
- b := r.Body.(map[string]interface{})["stack"].(map[string]interface{})
-
- if date, ok := b["creation_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- res.Stack.CreationTime = t
- }
-
- if date, ok := b["updated_time"]; ok && date != nil {
- t, err := time.Parse(gophercloud.StackFmtTime, date.(string))
- if err != nil {
- return nil, err
- }
- res.Stack.UpdatedTime = t
- }
-
- return res.Stack, err
+ err := r.ExtractInto(&s)
+ return s.PreviewedStack, err
}
// AbandonedStack represents the result of an Abandon operation.
type AbandonedStack struct {
- Status string `mapstructure:"status"`
- Name string `mapstructure:"name"`
- Template map[string]interface{} `mapstructure:"template"`
- Action string `mapstructure:"action"`
- ID string `mapstructure:"id"`
- Resources map[string]interface{} `mapstructure:"resources"`
- Files map[string]string `mapstructure:"files"`
- StackUserProjectID string `mapstructure:"stack_user_project_id"`
- ProjectID string `mapstructure:"project_id"`
- Environment map[string]interface{} `mapstructure:"environment"`
+ Status string `json:"status"`
+ Name string `json:"name"`
+ Template map[string]interface{} `json:"template"`
+ Action string `json:"action"`
+ ID string `json:"id"`
+ Resources map[string]interface{} `json:"resources"`
+ Files map[string]string `json:"files"`
+ StackUserProjectID string `json:"stack_user_project_id"`
+ ProjectID string `json:"project_id"`
+ Environment map[string]interface{} `json:"environment"`
}
// AbandonResult represents the result of an Abandon operation.
@@ -289,17 +167,9 @@
// Extract returns a pointer to an AbandonedStack object and is called after an
// Abandon operation.
func (r AbandonResult) Extract() (*AbandonedStack, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res AbandonedStack
-
- if err := mapstructure.Decode(r.Body, &res); err != nil {
- return nil, err
- }
-
- return &res, nil
+ var s *AbandonedStack
+ err := r.ExtractInto(&s)
+ return s, err
}
// String converts an AbandonResult to a string. This is useful to when passing
diff --git a/openstack/orchestration/v1/stacktemplates/results.go b/openstack/orchestration/v1/stacktemplates/results.go
index 7f4ea25..bca959b 100644
--- a/openstack/orchestration/v1/stacktemplates/results.go
+++ b/openstack/orchestration/v1/stacktemplates/results.go
@@ -2,7 +2,7 @@
import (
"encoding/json"
- "github.com/mitchellh/mapstructure"
+
"github.com/gophercloud/gophercloud"
)
@@ -25,9 +25,9 @@
// ValidatedTemplate represents the parsed object returned from a Validate request.
type ValidatedTemplate struct {
- Description string `mapstructure:"Description"`
- Parameters map[string]interface{} `mapstructure:"Parameters"`
- ParameterGroups map[string]interface{} `mapstructure:"ParameterGroups"`
+ Description string `json:"Description"`
+ Parameters map[string]interface{} `json:"Parameters"`
+ ParameterGroups map[string]interface{} `json:"ParameterGroups"`
}
// ValidateResult represents the result of a Validate operation.
@@ -38,14 +38,7 @@
// Extract returns a pointer to a ValidatedTemplate object and is called after a
// Validate operation.
func (r ValidateResult) Extract() (*ValidatedTemplate, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- var res ValidatedTemplate
- if err := mapstructure.Decode(r.Body, &res); err != nil {
- return nil, err
- }
-
- return &res, nil
+ var s *ValidatedTemplate
+ err := r.ExtractInto(&s)
+ return s, err
}