Adding API resource operation
diff --git a/openstack/networking/v2/networks/requests.go b/openstack/networking/v2/networks/requests.go
index da97f56..21055a8 100644
--- a/openstack/networking/v2/networks/requests.go
+++ b/openstack/networking/v2/networks/requests.go
@@ -22,10 +22,22 @@
}
func APIVersions(c *gophercloud.ServiceClient) (*APIVersionsList, error) {
- url := APIVersionsURL(c)
-
var resp APIVersionsList
- _, err := perigee.Request("GET", url, perigee.Options{
+ _, 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 APIInfo(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},
diff --git a/openstack/networking/v2/networks/requests_test.go b/openstack/networking/v2/networks/requests_test.go
index fe11a93..4d4bfe1 100644
--- a/openstack/networking/v2/networks/requests_test.go
+++ b/openstack/networking/v2/networks/requests_test.go
@@ -71,3 +71,83 @@
t.Errorf("Expected %#v, got %#v", expected, actual)
}
}
+
+func TestAPIInfo(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ th.Mux.HandleFunc("/v2.0/", 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, `
+{
+ "resources": [
+ {
+ "links": [
+ {
+ "href": "http://23.253.228.211:9696/v2.0/subnets",
+ "rel": "self"
+ }
+ ],
+ "name": "subnet",
+ "collection": "subnets"
+ },
+ {
+ "links": [
+ {
+ "href": "http://23.253.228.211:9696/v2.0/networks",
+ "rel": "self"
+ }
+ ],
+ "name": "network",
+ "collection": "networks"
+ },
+ {
+ "links": [
+ {
+ "href": "http://23.253.228.211:9696/v2.0/ports",
+ "rel": "self"
+ }
+ ],
+ "name": "port",
+ "collection": "ports"
+ }
+ ]
+}
+ `)
+ })
+
+ c := ServiceClient()
+
+ res, err := APIInfo(c, "v2.0")
+ if err != nil {
+ t.Fatalf("Error getting API info: %v", err)
+ }
+
+ coll, err := gophercloud.AllPages(res)
+
+ actual := ToAPIResource(coll)
+
+ expected := []APIResource{
+ APIResource{
+ Name: "subnet",
+ Collection: "subnets",
+ },
+ APIResource{
+ Name: "network",
+ Collection: "networks",
+ },
+ APIResource{
+ Name: "port",
+ Collection: "ports",
+ },
+ }
+
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("Expected %#v, got %#v", expected, actual)
+ }
+}
diff --git a/openstack/networking/v2/networks/results.go b/openstack/networking/v2/networks/results.go
index eabf6bc..e601c57 100644
--- a/openstack/networking/v2/networks/results.go
+++ b/openstack/networking/v2/networks/results.go
@@ -80,3 +80,51 @@
func ToAPIVersions(results gophercloud.Collection) []APIVersion {
return results.(*APIVersionsList).APIVersions
}
+
+type APIResource struct {
+ Name string
+ Collection string
+}
+
+type APIInfoList struct {
+ gophercloud.PaginationLinks `json:"links"`
+ Client *gophercloud.ServiceClient
+ APIResources []APIResource `json:"resources"`
+}
+
+func (list APIInfoList) Pager() gophercloud.Pager {
+ return gophercloud.NewLinkPager(list)
+}
+
+func (list APIInfoList) Concat(other gophercloud.Collection) gophercloud.Collection {
+ return APIInfoList{
+ Client: list.Client,
+ APIResources: append(list.APIResources, ToAPIResource(other)...),
+ }
+}
+
+func (list APIInfoList) Service() *gophercloud.ServiceClient {
+ return list.Client
+}
+
+func (list APIInfoList) Links() gophercloud.PaginationLinks {
+ return list.PaginationLinks
+}
+
+func (list APIInfoList) Interpret(json interface{}) (gophercloud.LinkCollection, error) {
+ mapped, ok := json.(map[string]interface{})
+ if !ok {
+ return nil, fmt.Errorf("Unexpected JSON response: %#v", json)
+ }
+
+ var result APIInfoList
+ err := mapstructure.Decode(mapped, &result)
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+func ToAPIResource(results gophercloud.Collection) []APIResource {
+ return results.(*APIInfoList).APIResources
+}
diff --git a/openstack/networking/v2/networks/urls.go b/openstack/networking/v2/networks/urls.go
index 012e486..3f49261 100644
--- a/openstack/networking/v2/networks/urls.go
+++ b/openstack/networking/v2/networks/urls.go
@@ -1,9 +1,15 @@
package networks
import (
+ "strings"
+
"github.com/rackspace/gophercloud"
)
func APIVersionsURL(c *gophercloud.ServiceClient) string {
return c.ServiceURL("")
}
+
+func APIInfoURL(c *gophercloud.ServiceClient, version string) string {
+ return c.ServiceURL(strings.TrimRight(version, "/") + "/")
+}
diff --git a/openstack/networking/v2/networks/urls_test.go b/openstack/networking/v2/networks/urls_test.go
index 87ae69e..a6c57e2 100644
--- a/openstack/networking/v2/networks/urls_test.go
+++ b/openstack/networking/v2/networks/urls_test.go
@@ -8,11 +8,22 @@
const Endpoint = "http://localhost:57909/v3/"
+func EndpointClient() *gophercloud.ServiceClient {
+ return &gophercloud.ServiceClient{Endpoint: Endpoint}
+}
+
func TestAPIVersionsURL(t *testing.T) {
- client := gophercloud.ServiceClient{Endpoint: Endpoint}
- actual := APIVersionsURL(&client)
+ actual := APIVersionsURL(EndpointClient())
expected := Endpoint
if expected != actual {
t.Errorf("[%s] does not match expected [%s]", actual, expected)
}
}
+
+func TestAPIInfoURL(t *testing.T) {
+ actual := APIInfoURL(EndpointClient(), "v2.0")
+ expected := Endpoint + "v2.0/"
+ if expected != actual {
+ t.Fatalf("[%s] does not match expected [%s]", actual, expected)
+ }
+}