Shuffled resources into sub-packages and upgraded to new pagination idiom
diff --git a/acceptance/openstack/networking/v2/apiversion_test.go b/acceptance/openstack/networking/v2/apiversion_test.go
new file mode 100644
index 0000000..79198c5
--- /dev/null
+++ b/acceptance/openstack/networking/v2/apiversion_test.go
@@ -0,0 +1,51 @@
+// +build acceptance networking
+
+package v2
+
+import (
+ "testing"
+
+ "github.com/rackspace/gophercloud"
+ "github.com/rackspace/gophercloud/openstack/networking/v2/apiversions"
+ th "github.com/rackspace/gophercloud/testhelper"
+)
+
+func TestListAPIVersions(t *testing.T) {
+ Setup(t)
+ defer Teardown()
+
+ pager := apiversions.ListVersions(Client)
+ err := pager.EachPage(func(page gophercloud.Page) (bool, error) {
+ t.Logf("--- Page ---")
+
+ versions, err := apiversions.ExtractAPIVersions(page)
+ th.AssertNoErr(t, err)
+
+ for _, v := range versions {
+ t.Logf("API Version: ID [%s] Status [%s]", v.ID, v.Status)
+ }
+
+ return true, nil
+ })
+ th.CheckNoErr(t, err)
+}
+
+func TestListAPIResources(t *testing.T) {
+ Setup(t)
+ defer Teardown()
+
+ pager := apiversions.ListVersionResources(Client, "v2.0")
+ err := pager.EachPage(func(page gophercloud.Page) (bool, error) {
+ t.Logf("--- Page ---")
+
+ vrs, err := apiversions.ExtractVersionResources(page)
+ th.AssertNoErr(t, err)
+
+ for _, vr := range vrs {
+ t.Logf("Network: Name [%s] Collection [%s]", vr.Name, vr.Collection)
+ }
+
+ return true, nil
+ })
+ th.CheckNoErr(t, err)
+}
diff --git a/acceptance/openstack/networking/v2/extension_test.go b/acceptance/openstack/networking/v2/extension_test.go
new file mode 100644
index 0000000..2cbe3a7
--- /dev/null
+++ b/acceptance/openstack/networking/v2/extension_test.go
@@ -0,0 +1,45 @@
+// +build acceptance networking
+
+package v2
+
+import (
+ "testing"
+
+ "github.com/rackspace/gophercloud"
+ "github.com/rackspace/gophercloud/openstack/networking/v2/extensions"
+ th "github.com/rackspace/gophercloud/testhelper"
+)
+
+func TestListExts(t *testing.T) {
+ Setup(t)
+ defer Teardown()
+
+ pager := extensions.List(Client)
+ err := pager.EachPage(func(page gophercloud.Page) (bool, error) {
+ t.Logf("--- Page ---")
+
+ exts, err := extensions.ExtractExtensions(page)
+ th.AssertNoErr(t, err)
+
+ for _, ext := range exts {
+ t.Logf("Extension: Name [%s] Description [%s]", ext.Name, ext.Description)
+ }
+
+ return true, nil
+ })
+ th.CheckNoErr(t, err)
+}
+
+func TestGetExt(t *testing.T) {
+ Setup(t)
+ defer Teardown()
+
+ ext, err := extensions.Get(Client, "service-type")
+ th.AssertNoErr(t, err)
+
+ th.AssertEquals(t, ext.Updated, "2013-01-20T00:00:00-00:00")
+ th.AssertEquals(t, ext.Name, "Neutron Service Type Management")
+ th.AssertEquals(t, ext.Namespace, "http://docs.openstack.org/ext/neutron/service-type/api/v1.0")
+ th.AssertEquals(t, ext.Alias, "service-type")
+ th.AssertEquals(t, ext.Description, "API for retrieving service providers for Neutron advanced services")
+}
diff --git a/acceptance/openstack/networking/v2/network_test.go b/acceptance/openstack/networking/v2/network_test.go
index 53b9f59..6eb7182 100644
--- a/acceptance/openstack/networking/v2/network_test.go
+++ b/acceptance/openstack/networking/v2/network_test.go
@@ -4,6 +4,7 @@
import (
"os"
+ "strconv"
"testing"
"github.com/rackspace/gophercloud"
@@ -13,9 +14,7 @@
th "github.com/rackspace/gophercloud/testhelper"
)
-var (
- Client *gophercloud.ServiceClient
-)
+var Client *gophercloud.ServiceClient
func NewClient() (*gophercloud.ServiceClient, error) {
opts, err := utils.AuthOptions()
@@ -44,60 +43,25 @@
Client = nil
}
-func TestListAPIVersions(t *testing.T) {
- Setup(t)
- defer Teardown()
-
- res, err := networks.APIVersions(Client)
- th.AssertNoErr(t, err)
-
- err = gophercloud.EachPage(res, func(page gophercloud.Collection) bool {
- t.Logf("--- Page ---")
- for _, v := range networks.ToAPIVersions(page) {
- t.Logf("API version: ID [%s] Status [%s]", v.ID, v.Status)
- }
- return true
- })
- th.AssertNoErr(t, err)
-}
-
-func TestGetApiInfo(t *testing.T) {
- Setup(t)
- defer Teardown()
-
- res, err := networks.APIInfo(Client, "v2.0")
- th.AssertNoErr(t, err)
-
- err = gophercloud.EachPage(res, func(page gophercloud.Collection) bool {
- t.Logf("--- Page ---")
- for _, r := range networks.ToAPIResource(page) {
- t.Logf("API resource: Name [%s] Collection [%s]", r.Name, r.Collection)
- }
- return true
- })
- th.AssertNoErr(t, err)
-}
-
-func TestListExts(t *testing.T) {
- //networks.Extensions()
-}
-
-func TestGetExt(t *testing.T) {
- Setup(t)
- defer Teardown()
-
- ext, err := networks.GetExtension(Client, "service-type")
- th.AssertNoErr(t, err)
-
- th.AssertEquals(t, ext.Updated, "2013-01-20T00:00:00-00:00")
- th.AssertEquals(t, ext.Name, "Neutron Service Type Management")
- th.AssertEquals(t, ext.Namespace, "http://docs.openstack.org/ext/neutron/service-type/api/v1.0")
- th.AssertEquals(t, ext.Alias, "service-type")
- th.AssertEquals(t, ext.Description, "API for retrieving service providers for Neutron advanced services")
-}
-
func TestListNetworks(t *testing.T) {
- //networks.List()
+ Setup(t)
+ defer Teardown()
+
+ pager := networks.List(Client, networks.ListOpts{})
+ err := pager.EachPage(func(page gophercloud.Page) (bool, error) {
+ t.Logf("--- Page ---")
+
+ networks, err := networks.ExtractNetworks(page)
+ th.AssertNoErr(t, err)
+
+ for _, n := range networks {
+ t.Logf("Network: ID [%s] Name [%s] Status [%s] Is shared? [%s]",
+ n.ID, n.Name, n.Status, strconv.FormatBool(n.Shared))
+ }
+
+ return true, nil
+ })
+ th.CheckNoErr(t, err)
}
func TestNetworkCRUDOperations(t *testing.T) {
@@ -134,7 +98,7 @@
th.AssertEquals(t, n.Name, "new_network_name")
// Delete network
- err := networks.Delete(Client, networkID)
+ err = networks.Delete(Client, networkID)
th.AssertNoErr(t, err)
}
diff --git a/openstack/networking/v2/api_versions/doc.go b/openstack/networking/v2/api_versions/doc.go
deleted file mode 100644
index 83c4a6a..0000000
--- a/openstack/networking/v2/api_versions/doc.go
+++ /dev/null
@@ -1 +0,0 @@
-package networks
diff --git a/openstack/networking/v2/api_versions/errors.go b/openstack/networking/v2/api_versions/errors.go
deleted file mode 100644
index 83c4a6a..0000000
--- a/openstack/networking/v2/api_versions/errors.go
+++ /dev/null
@@ -1 +0,0 @@
-package networks
diff --git a/openstack/networking/v2/api_versions/requests.go b/openstack/networking/v2/api_versions/requests.go
deleted file mode 100644
index 90e2de3..0000000
--- a/openstack/networking/v2/api_versions/requests.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package networks
-
-import (
- "github.com/racker/perigee"
- "github.com/rackspace/gophercloud"
-)
-
-func List(c *gophercloud.ServiceClient) (*APIVersionsList, error) {
- var resp APIVersionsList
- _, err := perigee.Request("GET", APIVersionsURL(c), perigee.Options{
- MoreHeaders: c.Provider.AuthenticatedHeaders(),
- Results: &resp,
- OkCodes: []int{200},
- })
- if err != nil {
- return nil, err
- }
-
- return &resp, nil
-}
-
-func Get(c *gophercloud.ServiceClient, v string) (*APIInfoList, error) {
- var resp APIInfoList
- _, err := perigee.Request("GET", APIInfoURL(c, v), perigee.Options{
- MoreHeaders: c.Provider.AuthenticatedHeaders(),
- Results: &resp,
- OkCodes: []int{200},
- })
- if err != nil {
- return nil, err
- }
-
- return &resp, nil
-}
diff --git a/openstack/networking/v2/api_versions/results.go b/openstack/networking/v2/api_versions/results.go
deleted file mode 100644
index 159f03a..0000000
--- a/openstack/networking/v2/api_versions/results.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package networks
-
-type APIVersion struct {
- Status string
- ID string
-}
-
-type APIResource struct {
- Name string
- Collection string
-}
diff --git a/openstack/networking/v2/apiversions/doc.go b/openstack/networking/v2/apiversions/doc.go
new file mode 100644
index 0000000..76bdb14
--- /dev/null
+++ b/openstack/networking/v2/apiversions/doc.go
@@ -0,0 +1 @@
+package apiversions
diff --git a/openstack/networking/v2/apiversions/errors.go b/openstack/networking/v2/apiversions/errors.go
new file mode 100644
index 0000000..76bdb14
--- /dev/null
+++ b/openstack/networking/v2/apiversions/errors.go
@@ -0,0 +1 @@
+package apiversions
diff --git a/openstack/networking/v2/apiversions/requests.go b/openstack/networking/v2/apiversions/requests.go
new file mode 100644
index 0000000..8e3ff32
--- /dev/null
+++ b/openstack/networking/v2/apiversions/requests.go
@@ -0,0 +1,11 @@
+package apiversions
+
+import "github.com/rackspace/gophercloud"
+
+func ListVersions(c *gophercloud.ServiceClient) gophercloud.Pager {
+ return gophercloud.NewLinkedPager(c, APIVersionsURL(c))
+}
+
+func ListVersionResources(c *gophercloud.ServiceClient, v string) gophercloud.Pager {
+ return gophercloud.NewLinkedPager(c, APIInfoURL(c, v))
+}
diff --git a/openstack/networking/v2/api_versions/requests_test.go b/openstack/networking/v2/apiversions/requests_test.go
similarity index 63%
rename from openstack/networking/v2/api_versions/requests_test.go
rename to openstack/networking/v2/apiversions/requests_test.go
index cbcc8ae..0922318 100644
--- a/openstack/networking/v2/api_versions/requests_test.go
+++ b/openstack/networking/v2/apiversions/requests_test.go
@@ -1,4 +1,4 @@
-package networks
+package apiversions
import (
"fmt"
@@ -20,7 +20,7 @@
}
}
-func TestList(t *testing.T) {
+func TestListVersions(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()
@@ -48,21 +48,31 @@
}`)
})
- res, err := List(ServiceClient())
- th.AssertNoErr(t, err)
+ count := 0
- coll, err := gophercloud.AllPages(res)
- th.AssertNoErr(t, err)
+ ListVersions(ServiceClient()).EachPage(func(page gophercloud.Page) (bool, error) {
+ count++
+ actual, err := ExtractAPIVersions(page)
+ if err != nil {
+ t.Errorf("Failed to extract API versions: %v", err)
+ return false, err
+ }
- actual := ToAPIVersions(coll)
+ expected := []APIVersion{
+ APIVersion{
+ Status: "CURRENT",
+ ID: "v2.0",
+ },
+ }
- expected := []APIVersion{
- APIVersion{
- Status: "CURRENT",
- ID: "v2.0",
- },
+ th.AssertDeepEquals(t, expected, actual)
+
+ return true, nil
+ })
+
+ if count != 1 {
+ t.Errorf("Expected 1 page, got %d", count)
}
- th.AssertDeepEquals(t, expected, actual)
}
func TestAPIInfo(t *testing.T) {
@@ -114,26 +124,37 @@
`)
})
- res, err := Get(ServiceClient(), "v2.0")
- th.AssertNoErr(t, err)
+ count := 0
- coll, err := gophercloud.AllPages(res)
- th.AssertNoErr(t, err)
+ ListVersionResources(ServiceClient(), "v2.0").EachPage(func(page gophercloud.Page) (bool, error) {
+ count++
+ actual, err := ExtractVersionResources(page)
+ if err != nil {
+ t.Errorf("Failed to extract version resources: %v", err)
+ return false, err
+ }
- actual := ToAPIResource(coll)
- expected := []APIResource{
- APIResource{
- Name: "subnet",
- Collection: "subnets",
- },
- APIResource{
- Name: "network",
- Collection: "networks",
- },
- APIResource{
- Name: "port",
- Collection: "ports",
- },
+ expected := []APIVersionResource{
+ APIVersionResource{
+ Name: "subnet",
+ Collection: "subnets",
+ },
+ APIVersionResource{
+ Name: "network",
+ Collection: "networks",
+ },
+ APIVersionResource{
+ Name: "port",
+ Collection: "ports",
+ },
+ }
+
+ th.AssertDeepEquals(t, expected, actual)
+
+ return true, nil
+ })
+
+ if count != 1 {
+ t.Errorf("Expected 1 page, got %d", count)
}
- th.AssertDeepEquals(t, expected, actual)
}
diff --git a/openstack/networking/v2/apiversions/results.go b/openstack/networking/v2/apiversions/results.go
new file mode 100644
index 0000000..dbf40eb
--- /dev/null
+++ b/openstack/networking/v2/apiversions/results.go
@@ -0,0 +1,42 @@
+package apiversions
+
+import (
+ "github.com/mitchellh/mapstructure"
+ "github.com/rackspace/gophercloud"
+)
+
+type APIVersion struct {
+ Status string `mapstructure:"status" json:"status"`
+ ID string `mapstructure:"id" json:"id"`
+}
+
+func ExtractAPIVersions(page gophercloud.Page) ([]APIVersion, error) {
+ var resp struct {
+ Versions []APIVersion `mapstructure:"versions"`
+ }
+
+ err := mapstructure.Decode(page.(gophercloud.LinkedPage).Body, &resp)
+ if err != nil {
+ return nil, err
+ }
+
+ return resp.Versions, nil
+}
+
+type APIVersionResource struct {
+ Name string `mapstructure:"name" json:"name"`
+ Collection string `mapstructure:"collection" json:"collection"`
+}
+
+func ExtractVersionResources(page gophercloud.Page) ([]APIVersionResource, error) {
+ var resp struct {
+ APIVersionResources []APIVersionResource `mapstructure:"resources"`
+ }
+
+ err := mapstructure.Decode(page.(gophercloud.LinkedPage).Body, &resp)
+ if err != nil {
+ return nil, err
+ }
+
+ return resp.APIVersionResources, nil
+}
diff --git a/openstack/networking/v2/api_versions/urls.go b/openstack/networking/v2/apiversions/urls.go
similarity index 93%
rename from openstack/networking/v2/api_versions/urls.go
rename to openstack/networking/v2/apiversions/urls.go
index 3f49261..e66434e 100644
--- a/openstack/networking/v2/api_versions/urls.go
+++ b/openstack/networking/v2/apiversions/urls.go
@@ -1,4 +1,4 @@
-package networks
+package apiversions
import (
"strings"
diff --git a/openstack/networking/v2/api_versions/urls_test.go b/openstack/networking/v2/apiversions/urls_test.go
similarity index 96%
rename from openstack/networking/v2/api_versions/urls_test.go
rename to openstack/networking/v2/apiversions/urls_test.go
index 1ef7f81..383ba59 100644
--- a/openstack/networking/v2/api_versions/urls_test.go
+++ b/openstack/networking/v2/apiversions/urls_test.go
@@ -1,4 +1,4 @@
-package networks
+package apiversions
import (
"testing"
diff --git a/openstack/networking/v2/extensions/doc.go b/openstack/networking/v2/extensions/doc.go
index 83c4a6a..aeec0fa 100644
--- a/openstack/networking/v2/extensions/doc.go
+++ b/openstack/networking/v2/extensions/doc.go
@@ -1 +1 @@
-package networks
+package extensions
diff --git a/openstack/networking/v2/extensions/errors.go b/openstack/networking/v2/extensions/errors.go
index 83c4a6a..aeec0fa 100644
--- a/openstack/networking/v2/extensions/errors.go
+++ b/openstack/networking/v2/extensions/errors.go
@@ -1 +1 @@
-package networks
+package extensions
diff --git a/openstack/networking/v2/extensions/requests.go b/openstack/networking/v2/extensions/requests.go
index b406c51..1ef7b6d 100644
--- a/openstack/networking/v2/extensions/requests.go
+++ b/openstack/networking/v2/extensions/requests.go
@@ -1,4 +1,4 @@
-package networks
+package extensions
import (
"github.com/racker/perigee"
@@ -20,3 +20,7 @@
}
return &ext, nil
}
+
+func List(c *gophercloud.ServiceClient) gophercloud.Pager {
+ return gophercloud.NewLinkedPager(c, ListExtensionURL(c))
+}
diff --git a/openstack/networking/v2/extensions/requests_test.go b/openstack/networking/v2/extensions/requests_test.go
index 5ae7ec6..ae2fbcb 100644
--- a/openstack/networking/v2/extensions/requests_test.go
+++ b/openstack/networking/v2/extensions/requests_test.go
@@ -1,4 +1,4 @@
-package networks
+package extensions
import (
"fmt"
@@ -21,14 +21,66 @@
}
func TestList(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+ th.Mux.HandleFunc("/v2.0/extensions", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "GET")
+ th.TestHeader(t, r, "X-Auth-Token", TokenID)
+
+ w.Header().Add("Content-Type", "application/json")
+
+ fmt.Fprintf(w, `
+{
+ "extensions": [
+ {
+ "updated": "2013-01-20T00:00:00-00:00",
+ "name": "Neutron Service Type Management",
+ "links": [],
+ "namespace": "http://docs.openstack.org/ext/neutron/service-type/api/v1.0",
+ "alias": "service-type",
+ "description": "API for retrieving service providers for Neutron advanced services"
+ }
+ ]
+}
+ `)
+ })
+
+ count := 0
+
+ List(ServiceClient()).EachPage(func(page gophercloud.Page) (bool, error) {
+ count++
+ actual, err := ExtractExtensions(page)
+ if err != nil {
+ t.Errorf("Failed to extract extensions: %v", err)
+ }
+
+ expected := []Extension{
+ Extension{
+ Updated: "2013-01-20T00:00:00-00:00",
+ Name: "Neutron Service Type Management",
+ Links: []interface{}{},
+ Namespace: "http://docs.openstack.org/ext/neutron/service-type/api/v1.0",
+ Alias: "service-type",
+ Description: "API for retrieving service providers for Neutron advanced services",
+ },
+ }
+
+ th.AssertDeepEquals(t, expected, actual)
+
+ return true, nil
+ })
+
+ if count != 1 {
+ t.Errorf("Expected 1 page, got %d", count)
+ }
}
func TestGet(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()
- th.Mux.HandleFunc("/v2.0/extension/agent", func(w http.ResponseWriter, r *http.Request) {
+ th.Mux.HandleFunc("/v2.0/extensions/agent", func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "GET")
th.TestHeader(t, r, "X-Auth-Token", TokenID)
diff --git a/openstack/networking/v2/extensions/results.go b/openstack/networking/v2/extensions/results.go
index 3b21644..c249149 100644
--- a/openstack/networking/v2/extensions/results.go
+++ b/openstack/networking/v2/extensions/results.go
@@ -1,4 +1,9 @@
-package networks
+package extensions
+
+import (
+ "github.com/mitchellh/mapstructure"
+ "github.com/rackspace/gophercloud"
+)
type Extension struct {
Updated string `json:"updated"`
@@ -8,3 +13,16 @@
Alias string `json:"alias"`
Description string `json:"description"`
}
+
+func ExtractExtensions(page gophercloud.Page) ([]Extension, error) {
+ var resp struct {
+ Extensions []Extension `mapstructure:"extensions"`
+ }
+
+ err := mapstructure.Decode(page.(gophercloud.LinkedPage).Body, &resp)
+ if err != nil {
+ return nil, err
+ }
+
+ return resp.Extensions, nil
+}
diff --git a/openstack/networking/v2/extensions/urls.go b/openstack/networking/v2/extensions/urls.go
index d70dd9b..608b25f 100644
--- a/openstack/networking/v2/extensions/urls.go
+++ b/openstack/networking/v2/extensions/urls.go
@@ -1,4 +1,4 @@
-package networks
+package extensions
import "github.com/rackspace/gophercloud"
@@ -7,3 +7,7 @@
func ExtensionURL(c *gophercloud.ServiceClient, name string) string {
return c.ServiceURL(Version, "extensions", name)
}
+
+func ListExtensionURL(c *gophercloud.ServiceClient) string {
+ return c.ServiceURL(Version, "extensions")
+}
diff --git a/openstack/networking/v2/extensions/urls_test.go b/openstack/networking/v2/extensions/urls_test.go
index af01cb9..34731cd 100644
--- a/openstack/networking/v2/extensions/urls_test.go
+++ b/openstack/networking/v2/extensions/urls_test.go
@@ -1,4 +1,4 @@
-package networks
+package extensions
import (
"testing"
@@ -18,3 +18,9 @@
expected := Endpoint + "v2.0/extensions/agent"
th.AssertEquals(t, expected, actual)
}
+
+func TestListExtensionURL(t *testing.T) {
+ actual := ListExtensionURL(EndpointClient())
+ expected := Endpoint + "v2.0/extensions"
+ th.AssertEquals(t, expected, actual)
+}
diff --git a/openstack/networking/v2/networks/requests.go b/openstack/networking/v2/networks/requests.go
index 06b0fe7..98e70d1 100644
--- a/openstack/networking/v2/networks/requests.go
+++ b/openstack/networking/v2/networks/requests.go
@@ -1,10 +1,24 @@
package networks
import (
+ "strconv"
+
"github.com/racker/perigee"
"github.com/rackspace/gophercloud"
+ "github.com/rackspace/gophercloud/openstack/utils"
)
+type ListOpts struct {
+ Status string
+ Name string
+ AdminStateUp *bool
+ TenantID string
+ Shared *bool
+ ID string
+ Page int
+ PerPage int
+}
+
type NetworkOpts struct {
AdminStateUp bool
Name string
@@ -12,12 +26,54 @@
TenantID string
}
-func Get(c *gophercloud.ServiceClient, id string) (*NetworkResult, error) {
- var n NetworkResult
- _, err := perigee.Request("GET", NetworkURL(c, id), perigee.Options{
+func ptrToStr(val *bool) string {
+ if *val == true {
+ return "true"
+ } else if *val == false {
+ return "false"
+ } else {
+ return ""
+ }
+}
+
+func List(c *gophercloud.ServiceClient, opts ListOpts) gophercloud.Pager {
+ // Build query parameters
+ q := make(map[string]string)
+ if opts.Status != "" {
+ q["status"] = opts.Status
+ }
+ if opts.Name != "" {
+ q["name"] = opts.Name
+ }
+ if opts.AdminStateUp != nil {
+ q["admin_state_up"] = ptrToStr(opts.AdminStateUp)
+ }
+ if opts.TenantID != "" {
+ q["tenant_id"] = opts.TenantID
+ }
+ if opts.Shared != nil {
+ q["shared"] = ptrToStr(opts.Shared)
+ }
+ if opts.ID != "" {
+ q["id"] = opts.ID
+ }
+ if opts.Page != 0 {
+ q["page"] = strconv.Itoa(opts.Page)
+ }
+ if opts.PerPage != 0 {
+ q["per_page"] = strconv.Itoa(opts.PerPage)
+ }
+
+ u := ListURL(c) + utils.BuildQuery(q)
+ return gophercloud.NewLinkedPager(c, u)
+}
+
+func Get(c *gophercloud.ServiceClient, id string) (*Network, error) {
+ var n Network
+ _, err := perigee.Request("GET", GetURL(c, id), perigee.Options{
MoreHeaders: c.Provider.AuthenticatedHeaders(),
Results: &struct {
- Network *NetworkResult `json:"network"`
+ Network *Network `json:"network"`
}{&n},
OkCodes: []int{200},
})
@@ -73,7 +129,7 @@
return res.Network, nil
}
-func Update(c *gophercloud.ServiceClient, networkID string, opts NetworkOpts) (*NetworkResult, error) {
+func Update(c *gophercloud.ServiceClient, networkID string, opts NetworkOpts) (*Network, error) {
// Define structures
type network struct {
AdminStateUp bool `json:"admin_state_up"`
@@ -86,7 +142,7 @@
Network network `json:"network"`
}
type response struct {
- Network *NetworkResult `json:"network"`
+ Network *Network `json:"network"`
}
// Populate request body
@@ -102,7 +158,7 @@
// Send request to API
var res response
- _, err := perigee.Request("PUT", NetworkURL(c, networkID), perigee.Options{
+ _, err := perigee.Request("PUT", GetURL(c, networkID), perigee.Options{
MoreHeaders: c.Provider.AuthenticatedHeaders(),
ReqBody: &reqBody,
Results: &res,
@@ -114,3 +170,11 @@
return res.Network, nil
}
+
+func Delete(c *gophercloud.ServiceClient, networkID string) error {
+ _, err := perigee.Request("DELETE", DeleteURL(c, networkID), perigee.Options{
+ MoreHeaders: c.Provider.AuthenticatedHeaders(),
+ OkCodes: []int{204},
+ })
+ return err
+}
diff --git a/openstack/networking/v2/networks/requests_test.go b/openstack/networking/v2/networks/requests_test.go
index 6fa8222..e677f8e 100644
--- a/openstack/networking/v2/networks/requests_test.go
+++ b/openstack/networking/v2/networks/requests_test.go
@@ -20,6 +20,105 @@
}
}
+func TestList(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ th.Mux.HandleFunc("/v2.0/networks", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "GET")
+ th.TestHeader(t, r, "X-Auth-Token", TokenID)
+
+ w.Header().Add("Content-Type", "application/json")
+ w.WriteHeader(http.StatusOK)
+
+ fmt.Fprintf(w, `
+{
+ "networks": [
+ {
+ "status": "ACTIVE",
+ "subnets": [
+ "54d6f61d-db07-451c-9ab3-b9609b6b6f0b"
+ ],
+ "name": "private-network",
+ "provider:physical_network": null,
+ "admin_state_up": true,
+ "tenant_id": "4fd44f30292945e481c7b8a0c8908869",
+ "provider:network_type": "local",
+ "router:external": true,
+ "shared": true,
+ "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22",
+ "provider:segmentation_id": null
+ },
+ {
+ "status": "ACTIVE",
+ "subnets": [
+ "08eae331-0402-425a-923c-34f7cfe39c1b"
+ ],
+ "name": "private",
+ "provider:physical_network": null,
+ "admin_state_up": true,
+ "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e",
+ "provider:network_type": "local",
+ "router:external": true,
+ "shared": true,
+ "id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324",
+ "provider:segmentation_id": null
+ }
+ ]
+}
+ `)
+ })
+
+ client := ServiceClient()
+ count := 0
+
+ List(client, ListOpts{}).EachPage(func(page gophercloud.Page) (bool, error) {
+ count++
+ actual, err := ExtractNetworks(page)
+ if err != nil {
+ t.Errorf("Failed to extract networks: %v", err)
+ return false, err
+ }
+
+ expected := []Network{
+ Network{
+ Status: "ACTIVE",
+ Subnets: []interface{}{"54d6f61d-db07-451c-9ab3-b9609b6b6f0b"},
+ Name: "private-network",
+ ProviderPhysicalNetwork: "",
+ AdminStateUp: true,
+ TenantID: "4fd44f30292945e481c7b8a0c8908869",
+ ProviderNetworkType: "local",
+ RouterExternal: true,
+ Shared: true,
+ ID: "d32019d3-bc6e-4319-9c1d-6722fc136a22",
+ ProviderSegmentationID: 0,
+ },
+ Network{
+ Status: "ACTIVE",
+ Subnets: []interface{}{"08eae331-0402-425a-923c-34f7cfe39c1b"},
+ Name: "private",
+ ProviderPhysicalNetwork: "",
+ AdminStateUp: true,
+ TenantID: "26a7980765d0414dbc1fc1f88cdb7e6e",
+ ProviderNetworkType: "local",
+ RouterExternal: true,
+ Shared: true,
+ ID: "db193ab3-96e3-4cb3-8fc5-05f4296d0324",
+ ProviderSegmentationID: 0,
+ },
+ }
+
+ th.CheckDeepEquals(t, expected, actual)
+
+ return true, nil
+ })
+
+ if count != 1 {
+ t.Errorf("Expected 1 page, got %d", count)
+ }
+}
+
func TestGet(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()
diff --git a/openstack/networking/v2/networks/results.go b/openstack/networking/v2/networks/results.go
index 4678793..b23395a 100644
--- a/openstack/networking/v2/networks/results.go
+++ b/openstack/networking/v2/networks/results.go
@@ -1,5 +1,10 @@
package networks
+import (
+ "github.com/mitchellh/mapstructure"
+ "github.com/rackspace/gophercloud"
+)
+
type NetworkProvider struct {
ProviderSegmentationID int `json:"provider:segmentation_id"`
ProviderPhysicalNetwork string `json:"provider:physical_network"`
@@ -7,19 +12,17 @@
}
type Network struct {
- Status string `json:"status"`
- Subnets []interface{} `json:"subnets"`
- Name string `json:"name"`
- AdminStateUp bool `json:"admin_state_up"`
- TenantID string `json:"tenant_id"`
- Shared bool `json:"shared"`
- ID string `json:"id"`
-}
-
-type NetworkResult struct {
- Network
- NetworkProvider
- RouterExternal bool `json:"router:external"`
+ Status string `mapstructure:"status" json:"status"`
+ Subnets []interface{} `mapstructure:"subnets" json:"subnets"`
+ Name string `mapstructure:"name" json:"name"`
+ AdminStateUp bool `mapstructure:"admin_state_up" json:"admin_state_up"`
+ TenantID string `mapstructure:"tenant_id" json:"tenant_id"`
+ Shared bool `mapstructure:"shared" json:"shared"`
+ ID string `mapstructure:"id" json:"id"`
+ ProviderSegmentationID int `mapstructure:"provider:segmentation_id" json:"provider:segmentation_id"`
+ ProviderPhysicalNetwork string `mapstructure:"provider:physical_network" json:"provider:physical_network"`
+ ProviderNetworkType string `mapstructure:"provider:network_type" json:"provider:network_type"`
+ RouterExternal bool `mapstructure:"router:external" json:"router:external"`
}
type NetworkCreateResult struct {
@@ -27,3 +30,16 @@
Segments []NetworkProvider `json:"segments"`
PortSecurityEnabled bool `json:"port_security_enabled"`
}
+
+func ExtractNetworks(page gophercloud.Page) ([]Network, error) {
+ var resp struct {
+ Networks []Network `mapstructure:"networks" json:"networks"`
+ }
+
+ err := mapstructure.Decode(page.(gophercloud.LinkedPage).Body, &resp)
+ if err != nil {
+ return nil, err
+ }
+
+ return resp.Networks, nil
+}
diff --git a/openstack/networking/v2/networks/urls.go b/openstack/networking/v2/networks/urls.go
index 13fcc03..a0d660a 100644
--- a/openstack/networking/v2/networks/urls.go
+++ b/openstack/networking/v2/networks/urls.go
@@ -4,10 +4,26 @@
const Version = "v2.0"
-func NetworkURL(c *gophercloud.ServiceClient, id string) string {
+func ResourceURL(c *gophercloud.ServiceClient, id string) string {
return c.ServiceURL(Version, "networks", id)
}
-func CreateURL(c *gophercloud.ServiceClient) string {
+func RootURL(c *gophercloud.ServiceClient) string {
return c.ServiceURL(Version, "networks")
}
+
+func GetURL(c *gophercloud.ServiceClient, id string) string {
+ return ResourceURL(c, id)
+}
+
+func ListURL(c *gophercloud.ServiceClient) string {
+ return RootURL(c)
+}
+
+func CreateURL(c *gophercloud.ServiceClient) string {
+ return RootURL(c)
+}
+
+func DeleteURL(c *gophercloud.ServiceClient, id string) string {
+ return ResourceURL(c, id)
+}
diff --git a/openstack/networking/v2/networks/urls_test.go b/openstack/networking/v2/networks/urls_test.go
index b8970a2..84a7ae6 100644
--- a/openstack/networking/v2/networks/urls_test.go
+++ b/openstack/networking/v2/networks/urls_test.go
@@ -13,8 +13,8 @@
return &gophercloud.ServiceClient{Endpoint: Endpoint}
}
-func TestNetworkURL(t *testing.T) {
- actual := NetworkURL(EndpointClient(), "foo")
+func TestGetURL(t *testing.T) {
+ actual := GetURL(EndpointClient(), "foo")
expected := Endpoint + "v2.0/networks/foo"
th.AssertEquals(t, expected, actual)
}
@@ -24,3 +24,15 @@
expected := Endpoint + "v2.0/networks"
th.AssertEquals(t, expected, actual)
}
+
+func TestListURL(t *testing.T) {
+ actual := CreateURL(EndpointClient())
+ expected := Endpoint + "v2.0/networks"
+ th.AssertEquals(t, expected, actual)
+}
+
+func TestDeleteURL(t *testing.T) {
+ actual := DeleteURL(EndpointClient(), "foo")
+ expected := Endpoint + "v2.0/networks/foo"
+ th.AssertEquals(t, expected, actual)
+}