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)
+	}
+}