Add ListAddresses method for cloud servers
diff --git a/acceptance/14-list-addresses.go b/acceptance/14-list-addresses.go
new file mode 100644
index 0000000..d1835e1
--- /dev/null
+++ b/acceptance/14-list-addresses.go
@@ -0,0 +1,44 @@
+package main
+
+import (
+ "fmt"
+ "flag"
+ "github.com/rackspace/gophercloud"
+)
+
+var quiet = flag.Bool("quiet", false, "Quiet mode, for acceptance testing. $? still indicates errors though.")
+
+func main() {
+ flag.Parse()
+ withIdentity(false, func(acc gophercloud.AccessProvider) {
+ withServerApi(acc, func(servers gophercloud.CloudServersProvider) {
+ log("Creating server")
+ id, err := createServer(servers, "", "", "", "")
+ 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)
+ }
+
+ log("Done")
+ })
+ })
+}
+
+func log(s... interface{}) {
+ if !*quiet {
+ fmt.Println(s...)
+ }
+}
diff --git a/errors.go b/errors.go
index 5ea3991..1719fd2 100644
--- a/errors.go
+++ b/errors.go
@@ -35,3 +35,10 @@
// responsible for a previous request bombing with an error, but pass in an
// error interface which doesn't belong to the web client.
var ErrError = fmt.Errorf("Attempt to solicit actual HTTP response code from error entity which doesn't know")
+
+// WarnUnauthoritative warnings happen when a service believes its response
+// to be correct, but is not in a position of knowing for sure at the moment.
+// For example, the service could be responding with cached data that has
+// exceeded its time-to-live setting, but which has not yet received an official
+// update from an authoritative source.
+var WarnUnauthoritative = fmt.Errorf("Unauthoritative data")
diff --git a/interfaces.go b/interfaces.go
index 626e531..c986fce 100644
--- a/interfaces.go
+++ b/interfaces.go
@@ -128,6 +128,14 @@
// Other providers may reserve the right to act on additional fields.
RebuildServer(id string, ns NewServer) (*Server, error)
+ // Addresses
+
+ // ListAddresses yields the list of available addresses for the server.
+ // This information is also returned by ServerById() in the Server.Addresses
+ // field. However, if you have a lot of servers and all you need are addresses,
+ // this function might be more efficient.
+ ListAddresses(id string) (AddressSet, error)
+
// Images
// ListImages yields the list of available operating system images. This function
diff --git a/servers.go b/servers.go
index 85f49ff..7133d93 100644
--- a/servers.go
+++ b/servers.go
@@ -288,6 +288,32 @@
return s, err
}
+// See the CloudServersProvider interface for details.
+func (gsp *genericServersProvider) ListAddresses(id string) (AddressSet, error) {
+ var pas *AddressSet
+ var statusCode int
+
+ err := gsp.context.WithReauth(gsp.access, func() error {
+ ep := fmt.Sprintf("%s/servers/%s/ips", gsp.endpoint, id)
+ return perigee.Get(ep, perigee.Options{
+ Results: &struct{ Addresses **AddressSet }{&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
+}
+
// RaxBandwidth provides measurement of server bandwidth consumed over a given audit interval.
type RaxBandwidth struct {
AuditPeriodEnd string `json:"audit_period_end"`