list server addresses operation and unit tests
diff --git a/openstack/compute/v2/servers/fixtures.go b/openstack/compute/v2/servers/fixtures.go
index 6125d53..8115e09 100644
--- a/openstack/compute/v2/servers/fixtures.go
+++ b/openstack/compute/v2/servers/fixtures.go
@@ -567,3 +567,53 @@
w.Write([]byte(`{ "metadata": {"foo":"baz", "this":"those"}}`))
})
}
+
+// ListAddressesExpected represents an expected repsonse from a ListAddresses request.
+var ListAddressesExpected = map[string][]Address{
+ "public": []Address{
+ Address{
+ Version: 4,
+ Address: "80.56.136.39",
+ },
+ Address{
+ Version: 6,
+ Address: "2001:4800:790e:510:be76:4eff:fe04:82a8",
+ },
+ },
+ "private": []Address{
+ Address{
+ Version: 4,
+ Address: "10.880.3.154",
+ },
+ },
+}
+
+// HandleAddressListSuccessfully sets up the test server to respond to a ListAddresses request.
+func HandleAddressListSuccessfully(t *testing.T) {
+ th.Mux.HandleFunc("/servers/asdfasdfasdf/ips", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "GET")
+ th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+
+ w.Header().Add("Content-Type", "application/json")
+ fmt.Fprintf(w, `{
+ "addresses": {
+ "public": [
+ {
+ "version": 4,
+ "addr": "50.56.176.35"
+ },
+ {
+ "version": 6,
+ "addr": "2001:4800:780e:510:be76:4eff:fe04:84a8"
+ }
+ ],
+ "private": [
+ {
+ "version": 4,
+ "addr": "10.180.3.155"
+ }
+ ]
+ }
+ }`)
+ })
+}
diff --git a/openstack/compute/v2/servers/requests.go b/openstack/compute/v2/servers/requests.go
index b7c1611..3a75b8f 100644
--- a/openstack/compute/v2/servers/requests.go
+++ b/openstack/compute/v2/servers/requests.go
@@ -719,3 +719,11 @@
})
return res
}
+
+// ListAddresses makes a request against the API to list the servers IP addresses.
+func ListAddresses(client *gophercloud.ServiceClient, id string) pagination.Pager {
+ createPageFn := func(r pagination.PageResult) pagination.Page {
+ return AddressPage{pagination.SinglePageBase(r)}
+ }
+ return pagination.NewPager(client, listAddressesURL(client, id), createPageFn)
+}
diff --git a/openstack/compute/v2/servers/requests_test.go b/openstack/compute/v2/servers/requests_test.go
index 017e793..75608c6 100644
--- a/openstack/compute/v2/servers/requests_test.go
+++ b/openstack/compute/v2/servers/requests_test.go
@@ -264,3 +264,27 @@
th.AssertNoErr(t, err)
th.AssertDeepEquals(t, expected, actual)
}
+
+func TestListAddresses(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+ HandleAddressListSuccessfully(t)
+
+ expected := ListAddressesExpected
+ pages := 0
+ err := ListAddresses(client.ServiceClient(), "asdfasdfasdf").EachPage(func(page pagination.Page) (bool, error) {
+ pages++
+
+ actual, err := ExtractAddresses(page)
+ th.AssertNoErr(t, err)
+
+ if len(actual) != 2 {
+ t.Fatalf("Expected 2 servers, got %d", len(actual))
+ }
+ th.CheckDeepEquals(t, expected, actual)
+
+ return true, nil
+ })
+ th.AssertNoErr(t, err)
+ th.CheckEquals(t, 1, pages)
+}
diff --git a/openstack/compute/v2/servers/results.go b/openstack/compute/v2/servers/results.go
index 1b22f21..494705f 100644
--- a/openstack/compute/v2/servers/results.go
+++ b/openstack/compute/v2/servers/results.go
@@ -194,7 +194,6 @@
err = decoder.Decode(casted)
- //err := mapstructure.Decode(casted, &response)
return response.Servers, err
}
@@ -272,3 +271,42 @@
}
return data, nil
}
+
+// Address represents an IP address.
+type Address struct {
+ Version int `mapstructure:"version"`
+ Address string `mapstructure:"addr"`
+}
+
+// AddressPage abstracts the raw results of making a List() request against the API.
+// As OpenStack extensions may freely alter the response bodies of structures returned
+// to the client, you may only safely access the data provided through the ExtractAddresses call.
+type AddressPage struct {
+ pagination.SinglePageBase
+}
+
+// IsEmpty returns true if an AddressPage contains no addresses.
+func (r AddressPage) IsEmpty() (bool, error) {
+ addresses, err := ExtractAddresses(r)
+ if err != nil {
+ return true, err
+ }
+ return len(addresses) == 0, nil
+}
+
+// ExtractAddresses interprets the results of a single page from a List() 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"`
+ }
+
+ err := mapstructure.Decode(casted, &response)
+ if err != nil {
+ return nil, err
+ }
+
+ return response.Addresses, err
+}
diff --git a/openstack/compute/v2/servers/urls.go b/openstack/compute/v2/servers/urls.go
index 4bc6586..faa62bd 100644
--- a/openstack/compute/v2/servers/urls.go
+++ b/openstack/compute/v2/servers/urls.go
@@ -37,3 +37,7 @@
func metadataURL(client *gophercloud.ServiceClient, id string) string {
return client.ServiceURL("servers", id, "metadata")
}
+
+func listAddressesURL(client *gophercloud.ServiceClient, id string) string {
+ return client.ServiceURL("servers", id, "ips")
+}