Refactor address set code for greater flexibility.
For some reason, this code doesn't work. While the refactor does not
appear to break acceptance/14-list-addresses, I simply _cannot_ find a
reason why it won't work for acceptance/19-list-addresses-0.1. If
anyone can review this code and let me know what I'm doing wrong, I'd be
most appreciative!
diff --git a/acceptance/19-list-addresses-0.1.go b/acceptance/19-list-addresses-0.1.go
new file mode 100644
index 0000000..7df2ad5
--- /dev/null
+++ b/acceptance/19-list-addresses-0.1.go
@@ -0,0 +1,56 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "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(api gophercloud.CloudServersProvider) {
+ log("Creating server")
+ id, err := createServer(api, "", "", "", "")
+ if err != nil {
+ panic(err)
+ }
+ waitForServerState(api, id, "ACTIVE")
+ defer api.DeleteServerById(id)
+
+ tryAllAddresses(id, api)
+
+ log("Done")
+ })
+ })
+}
+
+func tryAllAddresses(id string, api gophercloud.CloudServersProvider) {
+ log("Getting the server instance")
+ s, err := api.ServerById(id)
+ if err != nil {
+ panic(err)
+ }
+
+ log("Getting the complete set of pools")
+ ps, err := s.AllAddressPools()
+ if err != nil {
+ panic(err)
+ }
+
+ log("Listing IPs for each pool")
+ for k, v := range ps {
+ log(fmt.Sprintf(" Pool %s", k))
+ for _, a := range v {
+ log(fmt.Sprintf(" IP: %s, Version: %d", a.Addr, a.Version))
+ }
+ }
+}
+
+func log(s ...interface{}) {
+ if !*quiet {
+ fmt.Println(s...)
+ }
+}
diff --git a/servers.go b/servers.go
index fc5925d..634acaf 100644
--- a/servers.go
+++ b/servers.go
@@ -5,6 +5,7 @@
import (
"fmt"
+ "github.com/mitchellh/mapstructure"
"github.com/racker/perigee"
"strings"
)
@@ -55,6 +56,22 @@
},
})
})
+
+ // Compatibility with v0.0.x -- we "map" our public and private
+ // addresses into a legacy structure field for the benefit of
+ // earlier software.
+
+ if err != nil {
+ return ss, err
+ }
+
+ for _, s := range ss {
+ err = mapstructure.Decode(s.rawAddresses, &s.Addresses)
+ if err != nil {
+ return ss, err
+ }
+ }
+
return ss, err
}
@@ -71,6 +88,17 @@
},
})
})
+
+ // Compatibility with v0.0.x -- we "map" our public and private
+ // addresses into a legacy structure field for the benefit of
+ // earlier software.
+
+ if err != nil {
+ return s, err
+ }
+
+ err = mapstructure.Decode(s.rawAddresses, &s.Addresses)
+
return s, err
}
@@ -400,6 +428,8 @@
//
// Addresses provides addresses for any attached isolated networks.
// The version field indicates whether the IP address is version 4 or 6.
+// Note: only public and private pools appear here.
+// To get the complete set, use the AllAddressPools() method instead.
//
// Created tells when the server entity was created.
//
@@ -473,9 +503,9 @@
// http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_extensions.html#ext_status
// for more details. It's too lengthy to include here.
type Server struct {
- AccessIPv4 string `json:"accessIPv4"`
- AccessIPv6 string `json:"accessIPv6"`
- Addresses AddressSet `json:"addresses"`
+ AccessIPv4 string `json:"accessIPv4"`
+ AccessIPv6 string `json:"accessIPv6"`
+ Addresses AddressSet
Created string `json:"created"`
Flavor FlavorLink `json:"flavor"`
HostId string `json:"hostId"`
@@ -494,6 +524,27 @@
OsExtStsPowerState int `json:"OS-EXT-STS:power_state"`
OsExtStsTaskState string `json:"OS-EXT-STS:task_state"`
OsExtStsVmState string `json:"OS-EXT-STS:vm_state"`
+
+ rawAddresses map[string]interface{} `json:"addresses"`
+}
+
+// AllAddressPools returns a complete set of address pools available on the server.
+// The name of each pool supported keys the map.
+// The value of the map contains the addresses provided in the corresponding pool.
+func (s *Server) AllAddressPools() (map[string][]VersionedAddress, error) {
+ fmt.Printf("-- %#v\n", s.rawAddresses)
+ m := make(map[string][]VersionedAddress, 0)
+ for pool, subtree := range s.rawAddresses {
+ fmt.Println("POOL: ", pool)
+ fmt.Printf(" %#v\n", subtree)
+ v := make([]VersionedAddress, 0)
+ err := mapstructure.Decode(subtree, &v)
+ if err != nil {
+ return nil, err
+ }
+ m[pool] = v
+ }
+ return m, nil
}
// NewServerSettings structures record those fields of the Server structure to change