remove mapstructure from blockstorage,cdn,compute,db pkgs
diff --git a/openstack/compute/v2/extensions/bootfromvolume/requests_test.go b/openstack/compute/v2/extensions/bootfromvolume/requests_test.go
index 1c096a9..2359a77 100644
--- a/openstack/compute/v2/extensions/bootfromvolume/requests_test.go
+++ b/openstack/compute/v2/extensions/bootfromvolume/requests_test.go
@@ -32,8 +32,6 @@
"name": "createdserver",
"imageRef": "asdfasdfasdf",
"flavorRef": "performance1-1",
- "flavorName": "",
- "imageName": "",
"block_device_mapping_v2":[
{
"uuid":"123456",
@@ -94,8 +92,6 @@
"name": "createdserver",
"imageRef": "asdfasdfasdf",
"flavorRef": "performance1-1",
- "flavorName": "",
- "imageName": "",
"block_device_mapping_v2":[
{
"boot_index": "0",
diff --git a/openstack/compute/v2/extensions/defsecrules/results.go b/openstack/compute/v2/extensions/defsecrules/results.go
index 4adfa91..00d0bb5 100644
--- a/openstack/compute/v2/extensions/defsecrules/results.go
+++ b/openstack/compute/v2/extensions/defsecrules/results.go
@@ -1,8 +1,6 @@
package defsecrules
import (
- "github.com/mitchellh/mapstructure"
-
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/secgroups"
"github.com/gophercloud/gophercloud/pagination"
@@ -29,14 +27,12 @@
// ExtractDefaultRules returns a slice of DefaultRules contained in a single
// page of results.
func ExtractDefaultRules(page pagination.Page) ([]DefaultRule, error) {
- casted := page.(DefaultRulePage).Body
- var response struct {
- Rules []DefaultRule `mapstructure:"security_group_default_rules"`
+ r := page.(DefaultRulePage)
+ var s struct {
+ DefaultRules []DefaultRule `json:"security_group_default_rules"`
}
-
- err := mapstructure.WeakDecode(casted, &response)
-
- return response.Rules, err
+ err := r.ExtractInto(&s)
+ return s.DefaultRules, err
}
type commonResult struct {
@@ -55,15 +51,9 @@
// Extract will extract a DefaultRule struct from most responses.
func (r commonResult) Extract() (*DefaultRule, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ DefaultRule DefaultRule `json:"security_group_default_rule"`
}
-
- var response struct {
- Rule DefaultRule `mapstructure:"security_group_default_rule"`
- }
-
- err := mapstructure.WeakDecode(r.Body, &response)
-
- return &response.Rule, err
+ err := r.ExtractInto(&s)
+ return &s.DefaultRule, err
}
diff --git a/openstack/compute/v2/extensions/diskconfig/requests_test.go b/openstack/compute/v2/extensions/diskconfig/requests_test.go
index 61057d4..2e3ae18 100644
--- a/openstack/compute/v2/extensions/diskconfig/requests_test.go
+++ b/openstack/compute/v2/extensions/diskconfig/requests_test.go
@@ -25,8 +25,6 @@
"name": "createdserver",
"imageRef": "asdfasdfasdf",
"flavorRef": "performance1-1",
- "flavorName": "",
- "imageName": "",
"OS-DCF:diskConfig": "MANUAL"
}
}
diff --git a/openstack/compute/v2/extensions/diskconfig/results.go b/openstack/compute/v2/extensions/diskconfig/results.go
index b05c5b5..1957e12 100644
--- a/openstack/compute/v2/extensions/diskconfig/results.go
+++ b/openstack/compute/v2/extensions/diskconfig/results.go
@@ -1,60 +1,8 @@
package diskconfig
-import (
- "github.com/mitchellh/mapstructure"
- "github.com/gophercloud/gophercloud"
- "github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
- "github.com/gophercloud/gophercloud/pagination"
-)
+import "github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
-func commonExtract(result gophercloud.Result) (*DiskConfig, error) {
- var resp struct {
- Server struct {
- DiskConfig string `mapstructure:"OS-DCF:diskConfig"`
- } `mapstructure:"server"`
- }
-
- err := mapstructure.Decode(result.Body, &resp)
- if err != nil {
- return nil, err
- }
-
- config := DiskConfig(resp.Server.DiskConfig)
- return &config, nil
-}
-
-// ExtractGet returns the disk configuration from a servers.Get call.
-func ExtractGet(result servers.GetResult) (*DiskConfig, error) {
- return commonExtract(result.Result)
-}
-
-// ExtractUpdate returns the disk configuration from a servers.Update call.
-func ExtractUpdate(result servers.UpdateResult) (*DiskConfig, error) {
- return commonExtract(result.Result)
-}
-
-// ExtractRebuild returns the disk configuration from a servers.Rebuild call.
-func ExtractRebuild(result servers.RebuildResult) (*DiskConfig, error) {
- return commonExtract(result.Result)
-}
-
-// ExtractDiskConfig returns the DiskConfig setting for a specific server acquired from an
-// servers.ExtractServers call, while iterating through a Pager.
-func ExtractDiskConfig(page pagination.Page, index int) (*DiskConfig, error) {
- casted := page.(servers.ServerPage).Body
-
- type server struct {
- DiskConfig string `mapstructure:"OS-DCF:diskConfig"`
- }
- var response struct {
- Servers []server `mapstructure:"servers"`
- }
-
- err := mapstructure.Decode(casted, &response)
- if err != nil {
- return nil, err
- }
-
- config := DiskConfig(response.Servers[index].DiskConfig)
- return &config, nil
+type ServerWithDiskConfig struct {
+ servers.Server
+ DiskConfig DiskConfig `json:"OS-DCF:diskConfig"`
}
diff --git a/openstack/compute/v2/extensions/diskconfig/results_test.go b/openstack/compute/v2/extensions/diskconfig/results_test.go
deleted file mode 100644
index 7c5b6c9..0000000
--- a/openstack/compute/v2/extensions/diskconfig/results_test.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package diskconfig
-
-import (
- "testing"
-
- "github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
- "github.com/gophercloud/gophercloud/pagination"
- th "github.com/gophercloud/gophercloud/testhelper"
- "github.com/gophercloud/gophercloud/testhelper/client"
-)
-
-func TestExtractGet(t *testing.T) {
- th.SetupHTTP()
- defer th.TeardownHTTP()
- servers.HandleServerGetSuccessfully(t)
-
- config, err := ExtractGet(servers.Get(client.ServiceClient(), "1234asdf"))
- th.AssertNoErr(t, err)
- th.CheckEquals(t, Manual, *config)
-}
-
-func TestExtractUpdate(t *testing.T) {
- th.SetupHTTP()
- defer th.TeardownHTTP()
- servers.HandleServerUpdateSuccessfully(t)
-
- r := servers.Update(client.ServiceClient(), "1234asdf", servers.UpdateOpts{
- Name: "new-name",
- })
- config, err := ExtractUpdate(r)
- th.AssertNoErr(t, err)
- th.CheckEquals(t, Manual, *config)
-}
-
-func TestExtractRebuild(t *testing.T) {
- th.SetupHTTP()
- defer th.TeardownHTTP()
- servers.HandleRebuildSuccessfully(t, servers.SingleServerBody)
-
- r := servers.Rebuild(client.ServiceClient(), "1234asdf", servers.RebuildOpts{
- Name: "new-name",
- AdminPass: "swordfish",
- ImageID: "http://104.130.131.164:8774/fcad67a6189847c4aecfa3c81a05783b/images/f90f6034-2570-4974-8351-6b49732ef2eb",
- AccessIPv4: "1.2.3.4",
- })
- config, err := ExtractRebuild(r)
- th.AssertNoErr(t, err)
- th.CheckEquals(t, Manual, *config)
-}
-
-func TestExtractList(t *testing.T) {
- th.SetupHTTP()
- defer th.TeardownHTTP()
- servers.HandleServerListSuccessfully(t)
-
- pages := 0
- err := servers.List(client.ServiceClient(), nil).EachPage(func(page pagination.Page) (bool, error) {
- pages++
-
- config, err := ExtractDiskConfig(page, 0)
- th.AssertNoErr(t, err)
- th.CheckEquals(t, Manual, *config)
-
- return true, nil
- })
- th.AssertNoErr(t, err)
- th.CheckEquals(t, pages, 1)
-}
diff --git a/openstack/compute/v2/extensions/floatingip/doc.go b/openstack/compute/v2/extensions/floatingip/doc.go
deleted file mode 100644
index f74f58c..0000000
--- a/openstack/compute/v2/extensions/floatingip/doc.go
+++ /dev/null
@@ -1,3 +0,0 @@
-// Package floatingip provides the ability to manage floating ips through
-// nova-network
-package floatingip
diff --git a/openstack/compute/v2/extensions/floatingips/doc.go b/openstack/compute/v2/extensions/floatingips/doc.go
new file mode 100644
index 0000000..6682fa6
--- /dev/null
+++ b/openstack/compute/v2/extensions/floatingips/doc.go
@@ -0,0 +1,3 @@
+// Package floatingips provides the ability to manage floating ips through
+// nova-network
+package floatingips
diff --git a/openstack/compute/v2/extensions/floatingip/fixtures.go b/openstack/compute/v2/extensions/floatingips/fixtures.go
similarity index 97%
rename from openstack/compute/v2/extensions/floatingip/fixtures.go
rename to openstack/compute/v2/extensions/floatingips/fixtures.go
index a75e051..b369ea2 100644
--- a/openstack/compute/v2/extensions/floatingip/fixtures.go
+++ b/openstack/compute/v2/extensions/floatingips/fixtures.go
@@ -1,6 +1,6 @@
// +build fixtures
-package floatingip
+package floatingips
import (
"fmt"
@@ -17,14 +17,14 @@
"floating_ips": [
{
"fixed_ip": null,
- "id": 1,
+ "id": "1",
"instance_id": null,
"ip": "10.10.10.1",
"pool": "nova"
},
{
"fixed_ip": "166.78.185.201",
- "id": 2,
+ "id": "2",
"instance_id": "4d8c3732-a248-40ed-bebc-539a6ffd25c0",
"ip": "10.10.10.2",
"pool": "nova"
@@ -38,7 +38,7 @@
{
"floating_ip": {
"fixed_ip": "166.78.185.201",
- "id": 2,
+ "id": "2",
"instance_id": "4d8c3732-a248-40ed-bebc-539a6ffd25c0",
"ip": "10.10.10.2",
"pool": "nova"
@@ -51,7 +51,7 @@
{
"floating_ip": {
"fixed_ip": null,
- "id": 1,
+ "id": "1",
"instance_id": null,
"ip": "10.10.10.1",
"pool": "nova"
diff --git a/openstack/compute/v2/extensions/floatingip/requests.go b/openstack/compute/v2/extensions/floatingips/requests.go
similarity index 98%
rename from openstack/compute/v2/extensions/floatingip/requests.go
rename to openstack/compute/v2/extensions/floatingips/requests.go
index c6c0ea9..d99033e 100644
--- a/openstack/compute/v2/extensions/floatingip/requests.go
+++ b/openstack/compute/v2/extensions/floatingips/requests.go
@@ -1,4 +1,4 @@
-package floatingip
+package floatingips
import (
"errors"
@@ -10,7 +10,7 @@
// List returns a Pager that allows you to iterate over a collection of FloatingIPs.
func List(client *gophercloud.ServiceClient) pagination.Pager {
return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page {
- return FloatingIPsPage{pagination.SinglePageBase(r)}
+ return FloatingIPPage{pagination.SinglePageBase(r)}
})
}
diff --git a/openstack/compute/v2/extensions/floatingip/requests_test.go b/openstack/compute/v2/extensions/floatingips/requests_test.go
similarity index 99%
rename from openstack/compute/v2/extensions/floatingip/requests_test.go
rename to openstack/compute/v2/extensions/floatingips/requests_test.go
index df979f8..705c92f 100644
--- a/openstack/compute/v2/extensions/floatingip/requests_test.go
+++ b/openstack/compute/v2/extensions/floatingips/requests_test.go
@@ -1,4 +1,4 @@
-package floatingip
+package floatingips
import (
"testing"
diff --git a/openstack/compute/v2/extensions/floatingip/results.go b/openstack/compute/v2/extensions/floatingips/results.go
similarity index 70%
rename from openstack/compute/v2/extensions/floatingip/results.go
rename to openstack/compute/v2/extensions/floatingips/results.go
index 1e115f4..c77ed77 100644
--- a/openstack/compute/v2/extensions/floatingip/results.go
+++ b/openstack/compute/v2/extensions/floatingips/results.go
@@ -1,7 +1,6 @@
-package floatingip
+package floatingips
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -9,29 +8,29 @@
// A FloatingIP is an IP that can be associated with an instance
type FloatingIP struct {
// ID is a unique ID of the Floating IP
- ID string `mapstructure:"id"`
+ ID string `json:"id"`
// FixedIP is the IP of the instance related to the Floating IP
- FixedIP string `mapstructure:"fixed_ip,omitempty"`
+ FixedIP string `json:"fixed_ip,omitempty"`
// InstanceID is the ID of the instance that is using the Floating IP
- InstanceID string `mapstructure:"instance_id"`
+ InstanceID string `json:"instance_id"`
// IP is the actual Floating IP
- IP string `mapstructure:"ip"`
+ IP string `json:"ip"`
// Pool is the pool of floating IPs that this floating IP belongs to
- Pool string `mapstructure:"pool"`
+ Pool string `json:"pool"`
}
-// FloatingIPsPage stores a single, only page of FloatingIPs
+// FloatingIPPage stores a single, only page of FloatingIPs
// results from a List call.
-type FloatingIPsPage struct {
+type FloatingIPPage struct {
pagination.SinglePageBase
}
// IsEmpty determines whether or not a FloatingIPsPage is empty.
-func (page FloatingIPsPage) IsEmpty() (bool, error) {
+func (page FloatingIPPage) IsEmpty() (bool, error) {
va, err := ExtractFloatingIPs(page)
return len(va) == 0, err
}
@@ -39,16 +38,15 @@
// ExtractFloatingIPs interprets a page of results as a slice of
// FloatingIPs.
func ExtractFloatingIPs(page pagination.Page) ([]FloatingIP, error) {
- casted := page.(FloatingIPsPage).Body
- var response struct {
- FloatingIPs []FloatingIP `mapstructure:"floating_ips"`
+ r := page.(FloatingIPPage)
+ var s struct {
+ FloatingIPs []FloatingIP `json:"floating_ips"`
}
-
- err := mapstructure.WeakDecode(casted, &response)
-
- return response.FloatingIPs, err
+ err := r.ExtractInto(&s)
+ return s.FloatingIPs, err
}
+// FloatingIPResult is the raw result from a FloatingIP request.
type FloatingIPResult struct {
gophercloud.Result
}
@@ -56,16 +54,11 @@
// Extract is a method that attempts to interpret any FloatingIP resource
// response as a FloatingIP struct.
func (r FloatingIPResult) Extract() (*FloatingIP, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ FloatingIP *FloatingIP `json:"floating_ip"`
}
-
- var res struct {
- FloatingIP *FloatingIP `json:"floating_ip" mapstructure:"floating_ip"`
- }
-
- err := mapstructure.WeakDecode(r.Body, &res)
- return res.FloatingIP, err
+ err := r.ExtractInto(&s)
+ return s.FloatingIP, err
}
// CreateResult is the response from a Create operation. Call its Extract method to interpret it
diff --git a/openstack/compute/v2/extensions/floatingip/urls.go b/openstack/compute/v2/extensions/floatingips/urls.go
similarity index 97%
rename from openstack/compute/v2/extensions/floatingip/urls.go
rename to openstack/compute/v2/extensions/floatingips/urls.go
index 0d02413..f8181da 100644
--- a/openstack/compute/v2/extensions/floatingip/urls.go
+++ b/openstack/compute/v2/extensions/floatingips/urls.go
@@ -1,4 +1,4 @@
-package floatingip
+package floatingips
import "github.com/gophercloud/gophercloud"
diff --git a/openstack/compute/v2/extensions/floatingip/urls_test.go b/openstack/compute/v2/extensions/floatingips/urls_test.go
similarity index 98%
rename from openstack/compute/v2/extensions/floatingip/urls_test.go
rename to openstack/compute/v2/extensions/floatingips/urls_test.go
index 5c62a80..ff1489e 100644
--- a/openstack/compute/v2/extensions/floatingip/urls_test.go
+++ b/openstack/compute/v2/extensions/floatingips/urls_test.go
@@ -1,4 +1,4 @@
-package floatingip
+package floatingips
import (
"testing"
diff --git a/openstack/compute/v2/extensions/keypairs/results.go b/openstack/compute/v2/extensions/keypairs/results.go
index 58a51d2..2b40943 100644
--- a/openstack/compute/v2/extensions/keypairs/results.go
+++ b/openstack/compute/v2/extensions/keypairs/results.go
@@ -1,7 +1,6 @@
package keypairs
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -10,22 +9,22 @@
// servers.
type KeyPair struct {
// Name is used to refer to this keypair from other services within this region.
- Name string `mapstructure:"name"`
+ Name string `json:"name"`
// Fingerprint is a short sequence of bytes that can be used to authenticate or validate a longer
// public key.
- Fingerprint string `mapstructure:"fingerprint"`
+ Fingerprint string `json:"fingerprint"`
// PublicKey is the public key from this pair, in OpenSSH format. "ssh-rsa AAAAB3Nz..."
- PublicKey string `mapstructure:"public_key"`
+ PublicKey string `json:"public_key"`
// PrivateKey is the private key from this pair, in PEM format.
// "-----BEGIN RSA PRIVATE KEY-----\nMIICXA..." It is only present if this keypair was just
// returned from a Create call
- PrivateKey string `mapstructure:"private_key"`
+ PrivateKey string `json:"private_key"`
// UserID is the user who owns this keypair.
- UserID string `mapstructure:"user_id"`
+ UserID string `json:"user_id"`
}
// KeyPairPage stores a single, only page of KeyPair results from a List call.
@@ -41,17 +40,16 @@
// ExtractKeyPairs interprets a page of results as a slice of KeyPairs.
func ExtractKeyPairs(page pagination.Page) ([]KeyPair, error) {
+ r := page.(KeyPairPage)
type pair struct {
- KeyPair KeyPair `mapstructure:"keypair"`
+ KeyPair KeyPair `json:"keypair"`
}
-
- var resp struct {
- KeyPairs []pair `mapstructure:"keypairs"`
+ var s struct {
+ KeyPairs []pair `json:"keypairs"`
}
-
- err := mapstructure.Decode(page.(KeyPairPage).Body, &resp)
- results := make([]KeyPair, len(resp.KeyPairs))
- for i, pair := range resp.KeyPairs {
+ err := r.ExtractInto(&s)
+ results := make([]KeyPair, len(s.KeyPairs))
+ for i, pair := range s.KeyPairs {
results[i] = pair.KeyPair
}
return results, err
@@ -63,16 +61,11 @@
// Extract is a method that attempts to interpret any KeyPair resource response as a KeyPair struct.
func (r keyPairResult) Extract() (*KeyPair, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ KeyPair *KeyPair `json:"keypair"`
}
-
- var res struct {
- KeyPair *KeyPair `json:"keypair" mapstructure:"keypair"`
- }
-
- err := mapstructure.Decode(r.Body, &res)
- return res.KeyPair, err
+ err := r.ExtractInto(&s)
+ return s.KeyPair, err
}
// CreateResult is the response from a Create operation. Call its Extract method to interpret it
diff --git a/openstack/compute/v2/extensions/networks/fixtures.go b/openstack/compute/v2/extensions/networks/fixtures.go
index f94f331..ffa4282 100644
--- a/openstack/compute/v2/extensions/networks/fixtures.go
+++ b/openstack/compute/v2/extensions/networks/fixtures.go
@@ -8,6 +8,7 @@
"testing"
"time"
+ "github.com/gophercloud/gophercloud"
th "github.com/gophercloud/gophercloud/testhelper"
"github.com/gophercloud/gophercloud/testhelper/client"
)
@@ -22,9 +23,8 @@
"broadcast": "10.0.0.7",
"cidr": "10.0.0.0/29",
"cidr_v6": null,
- "created_at": "2011-08-15 06:19:19.387525",
+ "created_at": "2011-08-15T06:19:19.387525",
"deleted": false,
- "deleted_at": null,
"dhcp_start": "10.0.0.3",
"dns1": null,
"dns2": null,
@@ -40,7 +40,7 @@
"priority": null,
"project_id": "1234",
"rxtx_base": null,
- "updated_at": "2011-08-16 09:26:13.048257",
+ "updated_at": "2011-08-16T09:26:13.048257",
"vlan": 100,
"vpn_private_address": "10.0.0.2",
"vpn_public_address": "127.0.0.1",
@@ -52,9 +52,8 @@
"broadcast": "10.0.0.15",
"cidr": "10.0.0.10/29",
"cidr_v6": null,
- "created_at": "2011-08-15 06:19:19.885495",
+ "created_at": "2011-08-15T06:19:19.387525",
"deleted": false,
- "deleted_at": null,
"dhcp_start": "10.0.0.11",
"dns1": null,
"dns2": null,
@@ -70,7 +69,6 @@
"priority": null,
"project_id": null,
"rxtx_base": null,
- "updated_at": null,
"vlan": 101,
"vpn_private_address": "10.0.0.10",
"vpn_public_address": null,
@@ -89,9 +87,8 @@
"broadcast": "10.0.0.15",
"cidr": "10.0.0.10/29",
"cidr_v6": null,
- "created_at": "2011-08-15 06:19:19.885495",
+ "created_at": "2011-08-15T06:19:19.387525",
"deleted": false,
- "deleted_at": null,
"dhcp_start": "10.0.0.11",
"dns1": null,
"dns2": null,
@@ -107,7 +104,6 @@
"priority": null,
"project_id": null,
"rxtx_base": null,
- "updated_at": null,
"vlan": 101,
"vpn_private_address": "10.0.0.10",
"vpn_public_address": null,
@@ -124,9 +120,9 @@
Broadcast: "10.0.0.7",
CIDR: "10.0.0.0/29",
CIDRv6: "",
- CreatedAt: time.Date(2011, 8, 15, 6, 19, 19, 387525000, time.UTC),
+ CreatedAt: gophercloud.JSONRFC3339MilliNoZ(time.Date(2011, 8, 15, 6, 19, 19, 387525000, time.UTC)),
Deleted: false,
- DeletedAt: nilTime,
+ DeletedAt: gophercloud.JSONRFC3339MilliNoZ(nilTime),
DHCPStart: "10.0.0.3",
DNS1: "",
DNS2: "",
@@ -142,7 +138,7 @@
Priority: 0,
ProjectID: "1234",
RXTXBase: 0,
- UpdatedAt: time.Date(2011, 8, 16, 9, 26, 13, 48257000, time.UTC),
+ UpdatedAt: gophercloud.JSONRFC3339MilliNoZ(time.Date(2011, 8, 16, 9, 26, 13, 48257000, time.UTC)),
VLAN: 100,
VPNPrivateAddress: "10.0.0.2",
VPNPublicAddress: "127.0.0.1",
@@ -156,9 +152,9 @@
Broadcast: "10.0.0.15",
CIDR: "10.0.0.10/29",
CIDRv6: "",
- CreatedAt: time.Date(2011, 8, 15, 6, 19, 19, 885495000, time.UTC),
+ CreatedAt: gophercloud.JSONRFC3339MilliNoZ(time.Date(2011, 8, 15, 6, 19, 19, 387525000, time.UTC)),
Deleted: false,
- DeletedAt: nilTime,
+ DeletedAt: gophercloud.JSONRFC3339MilliNoZ(nilTime),
DHCPStart: "10.0.0.11",
DNS1: "",
DNS2: "",
@@ -174,7 +170,7 @@
Priority: 0,
ProjectID: "",
RXTXBase: 0,
- UpdatedAt: nilTime,
+ UpdatedAt: gophercloud.JSONRFC3339MilliNoZ(nilTime),
VLAN: 101,
VPNPrivateAddress: "10.0.0.10",
VPNPublicAddress: "",
diff --git a/openstack/compute/v2/extensions/networks/results.go b/openstack/compute/v2/extensions/networks/results.go
index 3ed7c68..d9b746e 100644
--- a/openstack/compute/v2/extensions/networks/results.go
+++ b/openstack/compute/v2/extensions/networks/results.go
@@ -1,10 +1,6 @@
package networks
import (
- "fmt"
- "time"
-
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -12,88 +8,88 @@
// A Network represents a nova-network that an instance communicates on
type Network struct {
// The Bridge that VIFs on this network are connected to
- Bridge string `mapstructure:"bridge"`
+ Bridge string `json:"bridge"`
// BridgeInterface is what interface is connected to the Bridge
- BridgeInterface string `mapstructure:"bridge_interface"`
+ BridgeInterface string `json:"bridge_interface"`
// The Broadcast address of the network.
- Broadcast string `mapstructure:"broadcast"`
+ Broadcast string `json:"broadcast"`
// CIDR is the IPv4 subnet.
- CIDR string `mapstructure:"cidr"`
+ CIDR string `json:"cidr"`
// CIDRv6 is the IPv6 subnet.
- CIDRv6 string `mapstructure:"cidr_v6"`
+ CIDRv6 string `json:"cidr_v6"`
// CreatedAt is when the network was created..
- CreatedAt time.Time `mapstructure:"-"`
+ CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at,omitempty"`
// Deleted shows if the network has been deleted.
- Deleted bool `mapstructure:"deleted"`
+ Deleted bool `json:"deleted"`
// DeletedAt is the time when the network was deleted.
- DeletedAt time.Time `mapstructure:"-"`
+ DeletedAt gophercloud.JSONRFC3339MilliNoZ `json:"deleted_at,omitempty"`
// DHCPStart is the start of the DHCP address range.
- DHCPStart string `mapstructure:"dhcp_start"`
+ DHCPStart string `json:"dhcp_start"`
// DNS1 is the first DNS server to use through DHCP.
- DNS1 string `mapstructure:"dns_1"`
+ DNS1 string `json:"dns_1"`
// DNS2 is the first DNS server to use through DHCP.
- DNS2 string `mapstructure:"dns_2"`
+ DNS2 string `json:"dns_2"`
// Gateway is the network gateway.
- Gateway string `mapstructure:"gateway"`
+ Gateway string `json:"gateway"`
// Gatewayv6 is the IPv6 network gateway.
- Gatewayv6 string `mapstructure:"gateway_v6"`
+ Gatewayv6 string `json:"gateway_v6"`
// Host is the host that the network service is running on.
- Host string `mapstructure:"host"`
+ Host string `json:"host"`
// ID is the UUID of the network.
- ID string `mapstructure:"id"`
+ ID string `json:"id"`
// Injected determines if network information is injected into the host.
- Injected bool `mapstructure:"injected"`
+ Injected bool `json:"injected"`
// Label is the common name that the network has..
- Label string `mapstructure:"label"`
+ Label string `json:"label"`
// MultiHost is if multi-host networking is enablec..
- MultiHost bool `mapstructure:"multi_host"`
+ MultiHost bool `json:"multi_host"`
// Netmask is the network netmask.
- Netmask string `mapstructure:"netmask"`
+ Netmask string `json:"netmask"`
// Netmaskv6 is the IPv6 netmask.
- Netmaskv6 string `mapstructure:"netmask_v6"`
+ Netmaskv6 string `json:"netmask_v6"`
// Priority is the network interface priority.
- Priority int `mapstructure:"priority"`
+ Priority int `json:"priority"`
// ProjectID is the project associated with this network.
- ProjectID string `mapstructure:"project_id"`
+ ProjectID string `json:"project_id"`
// RXTXBase configures bandwidth entitlement.
- RXTXBase int `mapstructure:"rxtx_base"`
+ RXTXBase int `json:"rxtx_base"`
// UpdatedAt is the time when the network was last updated.
- UpdatedAt time.Time `mapstructure:"-"`
+ UpdatedAt gophercloud.JSONRFC3339MilliNoZ `json:"updated_at,omitempty"`
// VLAN is the vlan this network runs on.
- VLAN int `mapstructure:"vlan"`
+ VLAN int `json:"vlan"`
// VPNPrivateAddress is the private address of the CloudPipe VPN.
- VPNPrivateAddress string `mapstructure:"vpn_private_address"`
+ VPNPrivateAddress string `json:"vpn_private_address"`
// VPNPublicAddress is the public address of the CloudPipe VPN.
- VPNPublicAddress string `mapstructure:"vpn_public_address"`
+ VPNPublicAddress string `json:"vpn_public_address"`
// VPNPublicPort is the port of the CloudPipe VPN.
- VPNPublicPort int `mapstructure:"vpn_public_port"`
+ VPNPublicPort int `json:"vpn_public_port"`
}
// NetworkPage stores a single, only page of Networks
@@ -110,51 +106,12 @@
// ExtractNetworks interprets a page of results as a slice of Networks
func ExtractNetworks(page pagination.Page) ([]Network, error) {
- var res struct {
- Networks []Network `mapstructure:"networks"`
+ r := page.(NetworkPage)
+ var s struct {
+ Networks []Network `json:"networks"`
}
-
- err := mapstructure.Decode(page.(NetworkPage).Body, &res)
-
- var rawNetworks []interface{}
- body := page.(NetworkPage).Body
- switch body.(type) {
- case map[string]interface{}:
- rawNetworks = body.(map[string]interface{})["networks"].([]interface{})
- case map[string][]interface{}:
- rawNetworks = body.(map[string][]interface{})["networks"]
- default:
- return res.Networks, fmt.Errorf("Unknown type")
- }
-
- for i := range rawNetworks {
- thisNetwork := rawNetworks[i].(map[string]interface{})
- if t, ok := thisNetwork["created_at"].(string); ok && t != "" {
- createdAt, err := time.Parse("2006-01-02 15:04:05.000000", t)
- if err != nil {
- return res.Networks, err
- }
- res.Networks[i].CreatedAt = createdAt
- }
-
- if t, ok := thisNetwork["updated_at"].(string); ok && t != "" {
- updatedAt, err := time.Parse("2006-01-02 15:04:05.000000", t)
- if err != nil {
- return res.Networks, err
- }
- res.Networks[i].UpdatedAt = updatedAt
- }
-
- if t, ok := thisNetwork["deleted_at"].(string); ok && t != "" {
- deletedAt, err := time.Parse("2006-01-02 15:04:05.000000", t)
- if err != nil {
- return res.Networks, err
- }
- res.Networks[i].DeletedAt = deletedAt
- }
- }
-
- return res.Networks, err
+ err := r.ExtractInto(&s)
+ return s.Networks, err
}
type NetworkResult struct {
@@ -164,55 +121,11 @@
// Extract is a method that attempts to interpret any Network resource
// response as a Network struct.
func (r NetworkResult) Extract() (*Network, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Network *Network `json:"network"`
}
-
- var res struct {
- Network *Network `json:"network" mapstructure:"network"`
- }
-
- 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{})["network"].(map[string]interface{})
-
- if t, ok := b["created_at"].(string); ok && t != "" {
- createdAt, err := time.Parse("2006-01-02 15:04:05.000000", t)
- if err != nil {
- return res.Network, err
- }
- res.Network.CreatedAt = createdAt
- }
-
- if t, ok := b["updated_at"].(string); ok && t != "" {
- updatedAt, err := time.Parse("2006-01-02 15:04:05.000000", t)
- if err != nil {
- return res.Network, err
- }
- res.Network.UpdatedAt = updatedAt
- }
-
- if t, ok := b["deleted_at"].(string); ok && t != "" {
- deletedAt, err := time.Parse("2006-01-02 15:04:05.000000", t)
- if err != nil {
- return res.Network, err
- }
- res.Network.DeletedAt = deletedAt
- }
-
- return res.Network, err
-
+ err := r.ExtractInto(&s)
+ return s.Network, err
}
// GetResult is the response from a Get operation. Call its Extract method to interpret it
diff --git a/openstack/compute/v2/extensions/schedulerhints/requests_test.go b/openstack/compute/v2/extensions/schedulerhints/requests_test.go
index 4e7c190..605b72b 100644
--- a/openstack/compute/v2/extensions/schedulerhints/requests_test.go
+++ b/openstack/compute/v2/extensions/schedulerhints/requests_test.go
@@ -39,9 +39,7 @@
"server": {
"name": "createdserver",
"imageRef": "asdfasdfasdf",
- "flavorRef": "performance1-1",
- "flavorName": "",
- "imageName": ""
+ "flavorRef": "performance1-1"
},
"os:scheduler_hints": {
"group": "101aed42-22d9-4a3e-9ba1-21103b0d1aba",
@@ -99,9 +97,7 @@
"server": {
"name": "createdserver",
"imageRef": "asdfasdfasdf",
- "flavorRef": "performance1-1",
- "flavorName": "",
- "imageName": ""
+ "flavorRef": "performance1-1"
},
"os:scheduler_hints": {
"group": "101aed42-22d9-4a3e-9ba1-21103b0d1aba",
diff --git a/openstack/compute/v2/extensions/secgroups/fixtures.go b/openstack/compute/v2/extensions/secgroups/fixtures.go
index 0667b00..0f97ac8 100644
--- a/openstack/compute/v2/extensions/secgroups/fixtures.go
+++ b/openstack/compute/v2/extensions/secgroups/fixtures.go
@@ -163,7 +163,7 @@
fmt.Fprintf(w, `
{
"security_group": {
- "id": 12345
+ "id": "12345"
}
}
`)
diff --git a/openstack/compute/v2/extensions/secgroups/results.go b/openstack/compute/v2/extensions/secgroups/results.go
index d7d0936..5e18c0b 100644
--- a/openstack/compute/v2/extensions/secgroups/results.go
+++ b/openstack/compute/v2/extensions/secgroups/results.go
@@ -1,8 +1,6 @@
package secgroups
import (
- "github.com/mitchellh/mapstructure"
-
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -24,7 +22,7 @@
Rules []Rule
// The ID of the tenant to which this security group belongs.
- TenantID string `mapstructure:"tenant_id"`
+ TenantID string `json:"tenant_id"`
}
// Rule represents a security group rule, a policy which determines how a
@@ -36,19 +34,19 @@
ID string
// The lower bound of the port range which this security group should open up
- FromPort int `mapstructure:"from_port"`
+ FromPort int `json:"from_port"`
// The upper bound of the port range which this security group should open up
- ToPort int `mapstructure:"to_port"`
+ ToPort int `json:"to_port"`
// The IP protocol (e.g. TCP) which the security group accepts
- IPProtocol string `mapstructure:"ip_protocol"`
+ IPProtocol string `json:"ip_protocol"`
// The CIDR IP range whose traffic can be received
- IPRange IPRange `mapstructure:"ip_range"`
+ IPRange IPRange `json:"ip_range"`
// The security group ID to which this rule belongs
- ParentGroupID string `mapstructure:"parent_group_id"`
+ ParentGroupID string `json:"parent_group_id"`
// Not documented.
Group Group
@@ -62,7 +60,7 @@
// Group represents a group.
type Group struct {
- TenantID string `mapstructure:"tenant_id"`
+ TenantID string `json:"tenant_id"`
Name string
}
@@ -74,22 +72,17 @@
// IsEmpty determines whether or not a page of Security Groups contains any results.
func (page SecurityGroupPage) IsEmpty() (bool, error) {
users, err := ExtractSecurityGroups(page)
- if err != nil {
- return false, err
- }
- return len(users) == 0, nil
+ return len(users) == 0, err
}
// ExtractSecurityGroups returns a slice of SecurityGroups contained in a single page of results.
func ExtractSecurityGroups(page pagination.Page) ([]SecurityGroup, error) {
- casted := page.(SecurityGroupPage).Body
- var response struct {
- SecurityGroups []SecurityGroup `mapstructure:"security_groups"`
+ r := page.(SecurityGroupPage)
+ var s struct {
+ SecurityGroups []SecurityGroup `json:"security_groups"`
}
-
- err := mapstructure.WeakDecode(casted, &response)
-
- return response.SecurityGroups, err
+ err := r.ExtractInto(&s)
+ return s.SecurityGroups, err
}
type commonResult struct {
@@ -113,17 +106,11 @@
// Extract will extract a SecurityGroup struct from most responses.
func (r commonResult) Extract() (*SecurityGroup, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ SecurityGroup *SecurityGroup `json:"security_group"`
}
-
- var response struct {
- SecurityGroup SecurityGroup `mapstructure:"security_group"`
- }
-
- err := mapstructure.WeakDecode(r.Body, &response)
-
- return &response.SecurityGroup, err
+ err := r.ExtractInto(&s)
+ return s.SecurityGroup, err
}
// CreateRuleResult represents the result when adding rules to a security group.
@@ -133,15 +120,9 @@
// Extract will extract a Rule struct from a CreateRuleResult.
func (r CreateRuleResult) Extract() (*Rule, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Rule *Rule `json:"security_group_rule"`
}
-
- var response struct {
- Rule Rule `mapstructure:"security_group_rule"`
- }
-
- err := mapstructure.WeakDecode(r.Body, &response)
-
- return &response.Rule, err
+ err := r.ExtractInto(&s)
+ return s.Rule, err
}
diff --git a/openstack/compute/v2/extensions/servergroups/requests.go b/openstack/compute/v2/extensions/servergroups/requests.go
index 02e6de2..e3b2493 100644
--- a/openstack/compute/v2/extensions/servergroups/requests.go
+++ b/openstack/compute/v2/extensions/servergroups/requests.go
@@ -10,7 +10,7 @@
// List returns a Pager that allows you to iterate over a collection of ServerGroups.
func List(client *gophercloud.ServiceClient) pagination.Pager {
return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page {
- return ServerGroupsPage{pagination.SinglePageBase(r)}
+ return ServerGroupPage{pagination.SinglePageBase(r)}
})
}
diff --git a/openstack/compute/v2/extensions/servergroups/results.go b/openstack/compute/v2/extensions/servergroups/results.go
index 2b59551..ff64a7e 100644
--- a/openstack/compute/v2/extensions/servergroups/results.go
+++ b/openstack/compute/v2/extensions/servergroups/results.go
@@ -1,7 +1,6 @@
package servergroups
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -9,29 +8,29 @@
// A ServerGroup creates a policy for instance placement in the cloud
type ServerGroup struct {
// ID is the unique ID of the Server Group.
- ID string `mapstructure:"id"`
+ ID string `json:"id"`
// Name is the common name of the server group.
- Name string `mapstructure:"name"`
+ Name string `json:"name"`
// Polices are the group policies.
- Policies []string `mapstructure:"policies"`
+ Policies []string `json:"policies"`
// Members are the members of the server group.
- Members []string `mapstructure:"members"`
+ Members []string `json:"members"`
// Metadata includes a list of all user-specified key-value pairs attached to the Server Group.
Metadata map[string]interface{}
}
-// ServerGroupsPage stores a single, only page of ServerGroups
+// ServerGroupPage stores a single, only page of ServerGroups
// results from a List call.
-type ServerGroupsPage struct {
+type ServerGroupPage struct {
pagination.SinglePageBase
}
// IsEmpty determines whether or not a ServerGroupsPage is empty.
-func (page ServerGroupsPage) IsEmpty() (bool, error) {
+func (page ServerGroupPage) IsEmpty() (bool, error) {
va, err := ExtractServerGroups(page)
return len(va) == 0, err
}
@@ -39,14 +38,12 @@
// ExtractServerGroups interprets a page of results as a slice of
// ServerGroups.
func ExtractServerGroups(page pagination.Page) ([]ServerGroup, error) {
- casted := page.(ServerGroupsPage).Body
- var response struct {
- ServerGroups []ServerGroup `mapstructure:"server_groups"`
+ r := page.(ServerGroupPage)
+ var s struct {
+ ServerGroups []ServerGroup `json:"server_groups"`
}
-
- err := mapstructure.WeakDecode(casted, &response)
-
- return response.ServerGroups, err
+ err := r.ExtractInto(&s)
+ return s.ServerGroups, err
}
type ServerGroupResult struct {
@@ -56,16 +53,11 @@
// Extract is a method that attempts to interpret any Server Group resource
// response as a ServerGroup struct.
func (r ServerGroupResult) Extract() (*ServerGroup, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ ServerGroup *ServerGroup `json:"server_group"`
}
-
- var res struct {
- ServerGroup *ServerGroup `json:"server_group" mapstructure:"server_group"`
- }
-
- err := mapstructure.WeakDecode(r.Body, &res)
- return res.ServerGroup, err
+ err := r.ExtractInto(&s)
+ return s.ServerGroup, err
}
// CreateResult is the response from a Create operation. Call its Extract method to interpret it
diff --git a/openstack/compute/v2/extensions/tenantnetworks/results.go b/openstack/compute/v2/extensions/tenantnetworks/results.go
index f55a27e..5db5cbd 100644
--- a/openstack/compute/v2/extensions/tenantnetworks/results.go
+++ b/openstack/compute/v2/extensions/tenantnetworks/results.go
@@ -1,7 +1,6 @@
package tenantnetworks
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -9,13 +8,13 @@
// A Network represents a nova-network that an instance communicates on
type Network struct {
// CIDR is the IPv4 subnet.
- CIDR string `mapstructure:"cidr"`
+ CIDR string `json:"cidr"`
// ID is the UUID of the network.
- ID string `mapstructure:"id"`
+ ID string `json:"id"`
// Name is the common name that the network has.
- Name string `mapstructure:"label"`
+ Name string `json:"label"`
}
// NetworkPage stores a single, only page of Networks
@@ -32,14 +31,12 @@
// ExtractNetworks interprets a page of results as a slice of Networks
func ExtractNetworks(page pagination.Page) ([]Network, error) {
- networks := page.(NetworkPage).Body
- var res struct {
- Networks []Network `mapstructure:"networks"`
+ r := page.(NetworkPage)
+ var s struct {
+ Networks []Network `json:"networks"`
}
-
- err := mapstructure.WeakDecode(networks, &res)
-
- return res.Networks, err
+ err := r.ExtractInto(&s)
+ return s.Networks, err
}
type NetworkResult struct {
@@ -49,16 +46,11 @@
// Extract is a method that attempts to interpret any Network resource
// response as a Network struct.
func (r NetworkResult) Extract() (*Network, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Network *Network `json:"network"`
}
-
- var res struct {
- Network *Network `json:"network" mapstructure:"network"`
- }
-
- err := mapstructure.Decode(r.Body, &res)
- return res.Network, err
+ err := r.ExtractInto(&s)
+ return s.Network, err
}
// GetResult is the response from a Get operation. Call its Extract method to interpret it
diff --git a/openstack/compute/v2/extensions/volumeattach/results.go b/openstack/compute/v2/extensions/volumeattach/results.go
index 76aeee7..62e7398 100644
--- a/openstack/compute/v2/extensions/volumeattach/results.go
+++ b/openstack/compute/v2/extensions/volumeattach/results.go
@@ -1,24 +1,23 @@
package volumeattach
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
-// VolumeAttach controls the attachment of a volume to an instance.
+// VolumeAttachment controls the attachment of a volume to an instance.
type VolumeAttachment struct {
// ID is a unique id of the attachment
- ID string `mapstructure:"id"`
+ ID string `json:"id"`
// Device is what device the volume is attached as
- Device string `mapstructure:"device"`
+ Device string `json:"device"`
// VolumeID is the ID of the attached volume
- VolumeID string `mapstructure:"volumeId"`
+ VolumeID string `json:"volumeId"`
// ServerID is the ID of the instance that has the volume attached
- ServerID string `mapstructure:"serverId"`
+ ServerID string `json:"serverId"`
}
// VolumeAttachmentsPage stores a single, only page of VolumeAttachments
@@ -36,14 +35,12 @@
// ExtractVolumeAttachments interprets a page of results as a slice of
// VolumeAttachments.
func ExtractVolumeAttachments(page pagination.Page) ([]VolumeAttachment, error) {
- casted := page.(VolumeAttachmentsPage).Body
- var response struct {
- VolumeAttachments []VolumeAttachment `mapstructure:"volumeAttachments"`
+ r := page.(VolumeAttachmentsPage)
+ var s struct {
+ VolumeAttachments []VolumeAttachment `json:"volumeAttachments"`
}
-
- err := mapstructure.WeakDecode(casted, &response)
-
- return response.VolumeAttachments, err
+ err := r.ExtractInto(&s)
+ return s.VolumeAttachments, err
}
type VolumeAttachmentResult struct {
@@ -53,16 +50,11 @@
// Extract is a method that attempts to interpret any VolumeAttachment resource
// response as a VolumeAttachment struct.
func (r VolumeAttachmentResult) Extract() (*VolumeAttachment, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ VolumeAttachment *VolumeAttachment `json:"volumeAttachment"`
}
-
- var res struct {
- VolumeAttachment *VolumeAttachment `json:"volumeAttachment" mapstructure:"volumeAttachment"`
- }
-
- err := mapstructure.Decode(r.Body, &res)
- return res.VolumeAttachment, err
+ err := r.ExtractInto(&s)
+ return s.VolumeAttachment, err
}
// CreateResult is the response from a Create operation. Call its Extract method to interpret it
diff --git a/openstack/compute/v2/flavors/results.go b/openstack/compute/v2/flavors/results.go
index 785cbe2..3f14e76 100644
--- a/openstack/compute/v2/flavors/results.go
+++ b/openstack/compute/v2/flavors/results.go
@@ -2,9 +2,7 @@
import (
"errors"
- "reflect"
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -18,48 +16,35 @@
}
// Extract provides access to the individual Flavor returned by the Get function.
-func (gr GetResult) Extract() (*Flavor, error) {
- if gr.Err != nil {
- return nil, gr.Err
+func (r GetResult) Extract() (*Flavor, error) {
+ var s struct {
+ Flavor *Flavor `json:"flavor"`
}
-
- var result struct {
- Flavor Flavor `mapstructure:"flavor"`
- }
-
- cfg := &mapstructure.DecoderConfig{
- DecodeHook: defaulter,
- Result: &result,
- }
- decoder, err := mapstructure.NewDecoder(cfg)
- if err != nil {
- return nil, err
- }
- err = decoder.Decode(gr.Body)
- return &result.Flavor, err
+ err := r.ExtractInto(&s)
+ return s.Flavor, err
}
// Flavor records represent (virtual) hardware configurations for server resources in a region.
type Flavor struct {
// The Id field contains the flavor's unique identifier.
// For example, this identifier will be useful when specifying which hardware configuration to use for a new server instance.
- ID string `mapstructure:"id"`
+ ID string `json:"id"`
// The Disk and RA< fields provide a measure of storage space offered by the flavor, in GB and MB, respectively.
- Disk int `mapstructure:"disk"`
- RAM int `mapstructure:"ram"`
+ Disk int `json:"disk"`
+ RAM int `json:"ram"`
// The Name field provides a human-readable moniker for the flavor.
- Name string `mapstructure:"name"`
+ Name string `json:"name"`
- RxTxFactor float64 `mapstructure:"rxtx_factor"`
+ RxTxFactor float64 `json:"rxtx_factor"`
// Swap indicates how much space is reserved for swap.
// If not provided, this field will be set to 0.
- Swap int `mapstructure:"swap"`
+ Swap int `json:"swap"`
// VCPUs indicates how many (virtual) CPUs are available for this flavor.
- VCPUs int `mapstructure:"vcpus"`
+ VCPUs int `json:"vcpus"`
}
// FlavorPage contains a single page of the response from a List call.
@@ -68,55 +53,29 @@
}
// IsEmpty determines if a page contains any results.
-func (p FlavorPage) IsEmpty() (bool, error) {
- flavors, err := ExtractFlavors(p)
- if err != nil {
- return true, err
- }
- return len(flavors) == 0, nil
+func (page FlavorPage) IsEmpty() (bool, error) {
+ flavors, err := ExtractFlavors(page)
+ return len(flavors) == 0, err
}
// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
-func (p FlavorPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"flavors_links"`
+func (page FlavorPage) NextPageURL() (string, error) {
+ var s struct {
+ Links []gophercloud.Link `json:"flavors_links"`
}
-
- var r resp
- err := mapstructure.Decode(p.Body, &r)
+ err := page.ExtractInto(&s)
if err != nil {
return "", err
}
-
- return gophercloud.ExtractNextURL(r.Links)
-}
-
-func defaulter(from, to reflect.Kind, v interface{}) (interface{}, error) {
- if (from == reflect.String) && (to == reflect.Int) {
- return 0, nil
- }
- return v, nil
+ return gophercloud.ExtractNextURL(s.Links)
}
// ExtractFlavors provides access to the list of flavors in a page acquired from the List operation.
func ExtractFlavors(page pagination.Page) ([]Flavor, error) {
- casted := page.(FlavorPage).Body
- var container struct {
- Flavors []Flavor `mapstructure:"flavors"`
+ r := page.(FlavorPage)
+ var s struct {
+ Flavors []Flavor `json:"flavors"`
}
-
- cfg := &mapstructure.DecoderConfig{
- DecodeHook: defaulter,
- Result: &container,
- }
- decoder, err := mapstructure.NewDecoder(cfg)
- if err != nil {
- return container.Flavors, err
- }
- err = decoder.Decode(casted)
- if err != nil {
- return container.Flavors, err
- }
-
- return container.Flavors, nil
+ err := r.ExtractInto(&s)
+ return s.Flavors, err
}
diff --git a/openstack/compute/v2/images/results.go b/openstack/compute/v2/images/results.go
index beee0dc..c9832d4 100644
--- a/openstack/compute/v2/images/results.go
+++ b/openstack/compute/v2/images/results.go
@@ -1,7 +1,6 @@
package images
import (
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -17,17 +16,12 @@
}
// Extract interprets a GetResult as an Image.
-func (gr GetResult) Extract() (*Image, error) {
- if gr.Err != nil {
- return nil, gr.Err
+func (r GetResult) Extract() (*Image, error) {
+ var s struct {
+ Image *Image `json:"image"`
}
-
- var decoded struct {
- Image Image `mapstructure:"image"`
- }
-
- err := mapstructure.Decode(gr.Body, &decoded)
- return &decoded.Image, err
+ err := r.ExtractInto(&s)
+ return s.Image, err
}
// Image is used for JSON (un)marshalling.
@@ -62,34 +56,27 @@
// IsEmpty returns true if a page contains no Image results.
func (page ImagePage) IsEmpty() (bool, error) {
images, err := ExtractImages(page)
- if err != nil {
- return true, err
- }
- return len(images) == 0, nil
+ return len(images) == 0, err
}
// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
func (page ImagePage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"images_links"`
+ var s struct {
+ Links []gophercloud.Link `json:"images_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)
}
// ExtractImages converts a page of List results into a slice of usable Image structs.
func ExtractImages(page pagination.Page) ([]Image, error) {
- casted := page.(ImagePage).Body
- var results struct {
- Images []Image `mapstructure:"images"`
+ r := page.(ImagePage)
+ var s struct {
+ Images []Image `json:"images"`
}
-
- err := mapstructure.Decode(casted, &results)
- return results.Images, err
+ err := r.ExtractInto(&s)
+ return s.Images, err
}
diff --git a/openstack/compute/v2/servers/requests.go b/openstack/compute/v2/servers/requests.go
index 7c964d2..06db312 100644
--- a/openstack/compute/v2/servers/requests.go
+++ b/openstack/compute/v2/servers/requests.go
@@ -195,9 +195,7 @@
server["name"] = opts.Name
server["imageRef"] = opts.ImageRef
- server["imageName"] = opts.ImageName
server["flavorRef"] = opts.FlavorRef
- server["flavorName"] = opts.FlavorName
if opts.UserData != nil {
encoded := base64.StdEncoding.EncodeToString(opts.UserData)
@@ -503,10 +501,13 @@
return server, err
}
- server["name"] = opts.Name
server["adminPass"] = opts.AdminPass
server["imageRef"] = opts.ImageID
+ if opts.Name != "" {
+ server["name"] = opts.Name
+ }
+
if opts.AccessIPv4 != "" {
server["accessIPv4"] = opts.AccessIPv4
}
diff --git a/openstack/compute/v2/servers/results.go b/openstack/compute/v2/servers/results.go
index 665b8c8..2517e65 100644
--- a/openstack/compute/v2/servers/results.go
+++ b/openstack/compute/v2/servers/results.go
@@ -1,12 +1,10 @@
package servers
import (
- "reflect"
"fmt"
- "path"
"net/url"
+ "path"
- "github.com/mitchellh/mapstructure"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/pagination"
)
@@ -17,29 +15,11 @@
// Extract interprets any serverResult as a Server, if possible.
func (r serverResult) Extract() (*Server, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Server *Server `json:"server"`
}
-
- var response struct {
- Server Server `mapstructure:"server"`
- }
-
- config := &mapstructure.DecoderConfig{
- DecodeHook: toMapFromString,
- Result: &response,
- }
- decoder, err := mapstructure.NewDecoder(config)
- if err != nil {
- return nil, err
- }
-
- err = decoder.Decode(r.Body)
- if err != nil {
- return nil, err
- }
-
- return &response.Server, nil
+ err := r.ExtractInto(&s)
+ return s.Server, err
}
// CreateResult temporarily contains the response from a Create call.
@@ -92,40 +72,35 @@
if err != nil {
return "", fmt.Errorf("Failed to parse the image id: %s", err.Error())
}
- imageId := path.Base(u.Path)
- if imageId == "." || imageId == "/" {
+ imageID := path.Base(u.Path)
+ if imageID == "." || imageID == "/" {
return "", fmt.Errorf("Failed to parse the ID of newly created image: %s", u)
}
- return imageId, nil
+ return imageID, nil
}
// Extract interprets any RescueResult as an AdminPass, if possible.
func (r RescueResult) Extract() (string, error) {
- if r.Err != nil {
- return "", r.Err
+ var s struct {
+ AdminPass string `json:"adminPass"`
}
-
- var response struct {
- AdminPass string `mapstructure:"adminPass"`
- }
-
- err := mapstructure.Decode(r.Body, &response)
- return response.AdminPass, err
+ err := r.ExtractInto(&s)
+ return s.AdminPass, err
}
// Server exposes only the standard OpenStack fields corresponding to a given server on the user's account.
type Server struct {
// ID uniquely identifies this server amongst all other servers, including those not accessible to the current tenant.
- ID string
+ ID string `json:"id"`
// TenantID identifies the tenant owning this server resource.
- TenantID string `mapstructure:"tenant_id"`
+ TenantID string `json:"tenant_id"`
// UserID uniquely identifies the user account owning the tenant.
- UserID string `mapstructure:"user_id"`
+ UserID string `json:"user_id"`
// Name contains the human-readable name for the server.
- Name string
+ Name string `json:"name"`
// Updated and Created contain ISO-8601 timestamps of when the state of the server last changed, and when it was created.
Updated string
@@ -159,14 +134,14 @@
Links []interface{}
// KeyName indicates which public key was injected into the server on launch.
- KeyName string `json:"key_name" mapstructure:"key_name"`
+ KeyName string `json:"key_name"`
// AdminPass will generally be empty (""). However, it will contain the administrative password chosen when provisioning a new server without a set AdminPass setting in the first place.
// Note that this is the ONLY time this field will be valid.
- AdminPass string `json:"adminPass" mapstructure:"adminPass"`
+ AdminPass string `json:"adminPass"`
// SecurityGroups includes the security groups that this instance has applied to it
- SecurityGroups []map[string]interface{} `json:"security_groups" mapstructure:"security_groups"`
+ SecurityGroups []map[string]interface{} `json:"security_groups"`
}
// ServerPage abstracts the raw results of making a List() request against the API.
@@ -179,47 +154,29 @@
// IsEmpty returns true if a page contains no Server results.
func (page ServerPage) IsEmpty() (bool, error) {
servers, err := ExtractServers(page)
- if err != nil {
- return true, err
- }
- return len(servers) == 0, nil
+ return len(servers) == 0, err
}
// NextPageURL uses the response's embedded link reference to navigate to the next page of results.
func (page ServerPage) NextPageURL() (string, error) {
- type resp struct {
- Links []gophercloud.Link `mapstructure:"servers_links"`
+ var s struct {
+ Links []gophercloud.Link `json:"servers_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)
}
// ExtractServers interprets the results of a single page from a List() call, producing a slice of Server entities.
func ExtractServers(page pagination.Page) ([]Server, error) {
- casted := page.(ServerPage).Body
-
- var response struct {
- Servers []Server `mapstructure:"servers"`
+ r := page.(ServerPage)
+ var s struct {
+ Servers []Server `json:"servers"`
}
-
- config := &mapstructure.DecoderConfig{
- DecodeHook: toMapFromString,
- Result: &response,
- }
- decoder, err := mapstructure.NewDecoder(config)
- if err != nil {
- return nil, err
- }
-
- err = decoder.Decode(casted)
-
- return response.Servers, err
+ err := r.ExtractInto(&s)
+ return s.Servers, err
}
// MetadataResult contains the result of a call for (potentially) multiple key-value pairs.
@@ -264,43 +221,26 @@
// Extract interprets any MetadataResult as a Metadata, if possible.
func (r MetadataResult) Extract() (map[string]string, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Metadata map[string]string `json:"metadata"`
}
-
- var response struct {
- Metadata map[string]string `mapstructure:"metadata"`
- }
-
- err := mapstructure.Decode(r.Body, &response)
- return response.Metadata, err
+ err := r.ExtractInto(&s)
+ return s.Metadata, err
}
// Extract interprets any MetadatumResult as a Metadatum, if possible.
func (r MetadatumResult) Extract() (map[string]string, error) {
- if r.Err != nil {
- return nil, r.Err
+ var s struct {
+ Metadatum map[string]string `json:"meta"`
}
-
- var response struct {
- Metadatum map[string]string `mapstructure:"meta"`
- }
-
- err := mapstructure.Decode(r.Body, &response)
- return response.Metadatum, err
-}
-
-func toMapFromString(from reflect.Kind, to reflect.Kind, data interface{}) (interface{}, error) {
- if (from == reflect.String) && (to == reflect.Map) {
- return map[string]interface{}{}, nil
- }
- return data, nil
+ err := r.ExtractInto(&s)
+ return s.Metadatum, err
}
// Address represents an IP address.
type Address struct {
- Version int `mapstructure:"version"`
- Address string `mapstructure:"addr"`
+ Version int `json:"version"`
+ Address string `json:"addr"`
}
// AddressPage abstracts the raw results of making a ListAddresses() request against the API.
@@ -313,27 +253,18 @@
// IsEmpty returns true if an AddressPage contains no networks.
func (r AddressPage) IsEmpty() (bool, error) {
addresses, err := ExtractAddresses(r)
- if err != nil {
- return true, err
- }
- return len(addresses) == 0, nil
+ return len(addresses) == 0, err
}
// ExtractAddresses interprets the results of a single page from a ListAddresses() call,
// producing a map of addresses.
func ExtractAddresses(page pagination.Page) (map[string][]Address, error) {
- casted := page.(AddressPage).Body
-
- var response struct {
- Addresses map[string][]Address `mapstructure:"addresses"`
+ r := page.(AddressPage)
+ var s struct {
+ Addresses map[string][]Address `json:"addresses"`
}
-
- err := mapstructure.Decode(casted, &response)
- if err != nil {
- return nil, err
- }
-
- return response.Addresses, err
+ err := r.ExtractInto(&s)
+ return s.Addresses, err
}
// NetworkAddressPage abstracts the raw results of making a ListAddressesByNetwork() request against the API.
@@ -346,27 +277,23 @@
// IsEmpty returns true if a NetworkAddressPage contains no addresses.
func (r NetworkAddressPage) IsEmpty() (bool, error) {
addresses, err := ExtractNetworkAddresses(r)
- if err != nil {
- return true, err
- }
- return len(addresses) == 0, nil
+ return len(addresses) == 0, err
}
// ExtractNetworkAddresses interprets the results of a single page from a ListAddressesByNetwork() call,
// producing a slice of addresses.
func ExtractNetworkAddresses(page pagination.Page) ([]Address, error) {
- casted := page.(NetworkAddressPage).Body
-
- var response map[string][]Address
- err := mapstructure.Decode(casted, &response)
+ r := page.(NetworkAddressPage)
+ var s map[string][]Address
+ err := r.ExtractInto(&s)
if err != nil {
return nil, err
}
var key string
- for k := range response {
+ for k := range s {
key = k
}
- return response[key], err
+ return s[key], err
}