Fixes #21
diff --git a/acceptance/14-list-addresses.go b/acceptance/14-list-addresses.go
index d1835e1..128b25a 100644
--- a/acceptance/14-list-addresses.go
+++ b/acceptance/14-list-addresses.go
@@ -11,32 +11,52 @@
func main() {
flag.Parse()
withIdentity(false, func(acc gophercloud.AccessProvider) {
- withServerApi(acc, func(servers gophercloud.CloudServersProvider) {
+ withServerApi(acc, func(api gophercloud.CloudServersProvider) {
log("Creating server")
- id, err := createServer(servers, "", "", "", "")
+ id, err := createServer(api, "", "", "", "")
if err != nil {
panic(err)
}
- waitForServerState(servers, id, "ACTIVE")
- defer servers.DeleteServerById(id)
-
- log("Getting list of addresses...")
- addresses, err := servers.ListAddresses(id)
- if (err != nil) && (err != gophercloud.WarnUnauthoritative) {
- panic(err)
- }
- if err == gophercloud.WarnUnauthoritative {
- log("Uh oh -- got a response back, but it's not authoritative for some reason.")
- }
- for _, addr := range addresses.Public {
- log("Address:", addr.Addr, " IPv", addr.Version)
- }
+ waitForServerState(api, id, "ACTIVE")
+ defer api.DeleteServerById(id)
+
+ tryAllAddresses(id, api)
+ tryAddressesByNetwork("public", id, api)
+ tryAddressesByNetwork("private", id, api)
log("Done")
})
})
}
+func tryAllAddresses(id string, api gophercloud.CloudServersProvider) {
+ log("Getting list of all addresses...")
+ addresses, err := api.ListAddresses(id)
+ if (err != nil) && (err != gophercloud.WarnUnauthoritative) {
+ panic(err)
+ }
+ if err == gophercloud.WarnUnauthoritative {
+ log("Uh oh -- got a response back, but it's not authoritative for some reason.")
+ }
+ for _, addr := range addresses.Public {
+ log("Address:", addr.Addr, " IPv", addr.Version)
+ }
+}
+
+func tryAddressesByNetwork(networkLabel string, id string, api gophercloud.CloudServersProvider) {
+ log("Getting list of addresses on", networkLabel, "network...")
+ network, err := api.ListAddressesByNetwork(id, networkLabel)
+ if (err != nil) && (err != gophercloud.WarnUnauthoritative) {
+ panic(err)
+ }
+ if err == gophercloud.WarnUnauthoritative {
+ log("Uh oh -- got a response back, but it's not authoritative for some reason.")
+ }
+ for _, addr := range network[networkLabel]{
+ log("Address:", addr.Addr, " IPv", addr.Version)
+ }
+}
+
func log(s... interface{}) {
if !*quiet {
fmt.Println(s...)
diff --git a/interfaces.go b/interfaces.go
index 4982937..b680bec 100644
--- a/interfaces.go
+++ b/interfaces.go
@@ -139,6 +139,10 @@
// this function might be more efficient.
ListAddresses(id string) (AddressSet, error)
+ // ListAddressesByNetwork yields the list of available addresses for a given server id and networkLabel.
+ // Example: ListAddressesByNetwork("234-4353-4jfrj-43j2s", "private")
+ ListAddressesByNetwork(id, networkLabel string) (NetworkAddress, error)
+
// Images
// ListImages yields the list of available operating system images. This function
diff --git a/servers.go b/servers.go
index 6ca8d24..dacf9f6 100644
--- a/servers.go
+++ b/servers.go
@@ -316,6 +316,32 @@
}
// See the CloudServersProvider interface for details.
+func (gsp *genericServersProvider) ListAddressesByNetwork(id, networkLabel string) (NetworkAddress, error){
+ var pas NetworkAddress
+ var statusCode int
+
+ err := gsp.context.WithReauth(gsp.access, func() error {
+ ep := fmt.Sprintf("%s/servers/%s/ips/%s", gsp.endpoint, id, networkLabel)
+ return perigee.Get(ep, perigee.Options{
+ Results: &pas,
+ MoreHeaders: map[string]string{
+ "X-Auth-Token": gsp.access.AuthToken(),
+ },
+ OkCodes: []int{200, 203},
+ StatusCode: &statusCode,
+ })
+ })
+
+ if err != nil {
+ if statusCode == 203 {
+ err = WarnUnauthoritative
+ }
+ }
+
+ return pas, err
+}
+
+// See the CloudServersProvider interface for details.
func (gsp *genericServersProvider) CreateImage(id string, ci CreateImage) (string, error) {
response, err := gsp.context.ResponseWithReauth(gsp.access, func() (*perigee.Response, error) {
ep := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
@@ -366,6 +392,8 @@
Private []VersionedAddress `json:"private"`
}
+type NetworkAddress map[string][]VersionedAddress
+
// Server records represent (virtual) hardware instances (not configurations) accessible by the user.
//
// The AccessIPv4 / AccessIPv6 fields provides IP addresses for the server in the IPv4 or IPv6 format, respectively.