remove unused files from previous version; they are confusing people.
diff --git a/acceptance/00-authentication.go b/acceptance/00-authentication.go
deleted file mode 100644
index 6467203..0000000
--- a/acceptance/00-authentication.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "fmt"
- "github.com/rackspace/gophercloud"
- "os"
- "strings"
-)
-
-func main() {
- provider, username, _, apiKey := getCredentials()
-
- if !strings.Contains(provider, "rackspace") {
- fmt.Fprintf(os.Stdout, "Skipping test because provider doesn't support API_KEYs\n")
- return
- }
-
- _, err := gophercloud.Authenticate(
- provider,
- gophercloud.AuthOptions{
- Username: username,
- ApiKey: apiKey,
- },
- )
- if err != nil {
- panic(err)
- }
-}
diff --git a/acceptance/01-authentication.go b/acceptance/01-authentication.go
deleted file mode 100644
index 5cc9d38..0000000
--- a/acceptance/01-authentication.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "github.com/rackspace/gophercloud"
-)
-
-func main() {
- provider, username, password, _ := getCredentials()
-
- _, err := gophercloud.Authenticate(
- provider,
- gophercloud.AuthOptions{
- Username: username,
- Password: password,
- },
- )
- if err != nil {
- panic(err)
- }
-}
diff --git a/acceptance/02-list-servers.go b/acceptance/02-list-servers.go
deleted file mode 100644
index 772852e..0000000
--- a/acceptance/02-list-servers.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// +build acceptance,old
-
-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) {
- tryFullDetails(api)
- tryLinksOnly(api)
- })
- })
-}
-
-func tryLinksOnly(api gophercloud.CloudServersProvider) {
- servers, err := api.ListServersLinksOnly()
- if err != nil {
- panic(err)
- }
-
- if !*quiet {
- fmt.Println("Id,Name")
- for _, s := range servers {
- if s.AccessIPv4 != "" {
- panic("IPv4 not expected")
- }
-
- if s.Status != "" {
- panic("Status not expected")
- }
-
- if s.Progress != 0 {
- panic("Progress not expected")
- }
-
- fmt.Printf("%s,\"%s\"\n", s.Id, s.Name)
- }
- }
-}
-
-func tryFullDetails(api gophercloud.CloudServersProvider) {
- servers, err := api.ListServers()
- if err != nil {
- panic(err)
- }
-
- if !*quiet {
- fmt.Println("Id,Name,AccessIPv4,Status,Progress")
- for _, s := range servers {
- fmt.Printf("%s,\"%s\",%s,%s,%d\n", s.Id, s.Name, s.AccessIPv4, s.Status, s.Progress)
- }
- }
-}
diff --git a/acceptance/03-get-server-details.go b/acceptance/03-get-server-details.go
deleted file mode 100644
index 01140a9..0000000
--- a/acceptance/03-get-server-details.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/rackspace/gophercloud"
- "os"
- "github.com/racker/perigee"
-)
-
-var id = flag.String("i", "", "Server ID to get info on. Defaults to first server in your account if unspecified.")
-var rgn = flag.String("r", "", "Datacenter region. Leave blank for default region.")
-var quiet = flag.Bool("quiet", false, "Run quietly, for acceptance testing. $? non-zero if issue.")
-
-func main() {
- flag.Parse()
-
- resultCode := 0
- withIdentity(false, func(auth gophercloud.AccessProvider) {
- withServerApi(auth, func(servers gophercloud.CloudServersProvider) {
- var (
- err error
- serverId string
- deleteAfterwards bool
- )
-
- // Figure out which server to provide server details for.
- if *id == "" {
- deleteAfterwards, serverId, err = locateAServer(servers)
- if err != nil {
- panic(err)
- }
- if deleteAfterwards {
- defer servers.DeleteServerById(serverId)
- }
- } else {
- serverId = *id
- }
-
- // Grab server details by ID, and provide a report.
- s, err := servers.ServerById(serverId)
- if err != nil {
- panic(err)
- }
-
- configs := []string{
- "Access IPv4: %s\n",
- "Access IPv6: %s\n",
- " Created: %s\n",
- " Flavor: %s\n",
- " Host ID: %s\n",
- " ID: %s\n",
- " Image: %s\n",
- " Name: %s\n",
- " Progress: %s\n",
- " Status: %s\n",
- " Tenant ID: %s\n",
- " Updated: %s\n",
- " User ID: %s\n",
- }
-
- values := []string{
- s.AccessIPv4,
- s.AccessIPv6,
- s.Created,
- s.Flavor.Id,
- s.HostId,
- s.Id,
- s.Image.Id,
- s.Name,
- fmt.Sprintf("%d", s.Progress),
- s.Status,
- s.TenantId,
- s.Updated,
- s.UserId,
- }
-
- if !*quiet {
- fmt.Println("Server info:")
- for i, _ := range configs {
- fmt.Printf(configs[i], values[i])
- }
- }
- })
-
- // Negative test -- We should absolutely never panic for a server that doesn't exist.
- withServerApi(auth, func(servers gophercloud.CloudServersProvider) {
- _, err := servers.ServerById(randomString("garbage", 32))
- if err == nil {
- fmt.Printf("Expected a 404 response when looking for a server known not to exist\n")
- resultCode = 1
- }
- perigeeError, ok := err.(*perigee.UnexpectedResponseCodeError)
- if !ok {
- fmt.Printf("Unexpected error type\n")
- resultCode = 1
- } else {
- if perigeeError.Actual != 404 {
- fmt.Printf("Expected a 404 error code\n")
- }
- }
- })
- })
- os.Exit(resultCode)
-}
-
-// locateAServer queries the set of servers owned by the user. If at least one
-// exists, the first found is picked, and its ID is returned. Otherwise, a new
-// server will be created, and its ID returned.
-//
-// deleteAfter will be true if the caller should schedule a call to DeleteServerById()
-// to clean up.
-func locateAServer(servers gophercloud.CloudServersProvider) (deleteAfter bool, id string, err error) {
- ss, err := servers.ListServers()
- if err != nil {
- return false, "", err
- }
-
- if len(ss) > 0 {
- // We could just cheat and dump the server details from ss[0].
- // But, that tests ListServers(), and not ServerById(). So, we
- // elect not to cheat.
- return false, ss[0].Id, nil
- }
-
- serverId, err := createServer(servers, "", "", "", "")
- if err != nil {
- return false, "", err
- }
- err = waitForServerState(servers, serverId, "ACTIVE")
- return true, serverId, err
-}
diff --git a/acceptance/04-create-server.go b/acceptance/04-create-server.go
deleted file mode 100644
index 03fd606..0000000
--- a/acceptance/04-create-server.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/rackspace/gophercloud"
-)
-
-var region, serverName, imageRef, flavorRef *string
-var adminPass = flag.String("a", "", "Administrator password (auto-assigned if none)")
-var quiet = flag.Bool("quiet", false, "Quiet mode for acceptance tests. $? non-zero if error.")
-
-func configure() {
- region = flag.String("r", "", "Region in which to create the server. Leave blank for provider-default region.")
- serverName = flag.String("n", randomString("ACPTTEST--", 16), "Server name (what you see in the control panel)")
- imageRef = flag.String("i", "", "ID of image to deploy onto the server")
- flavorRef = flag.String("f", "", "Flavor of server to deploy image upon")
-
- flag.Parse()
-}
-
-func main() {
- configure()
-
- withIdentity(false, func(auth gophercloud.AccessProvider) {
- withServerApi(auth, func(servers gophercloud.CloudServersProvider) {
- _, err := createServer(servers, *imageRef, *flavorRef, *serverName, *adminPass)
- if err != nil {
- panic(err)
- }
-
- allServers, err := servers.ListServers()
- if err != nil {
- panic(err)
- }
-
- if !*quiet {
- fmt.Printf("ID,Name,Status,Progress\n")
- for _, i := range allServers {
- fmt.Printf("%s,\"%s\",%s,%d\n", i.Id, i.Name, i.Status, i.Progress)
- }
- }
- })
- })
-}
diff --git a/acceptance/05-list-images.go b/acceptance/05-list-images.go
deleted file mode 100644
index 5ead18b..0000000
--- a/acceptance/05-list-images.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/rackspace/gophercloud"
-)
-
-var quiet = flag.Bool("quiet", false, "Quiet mode for acceptance testing. $? non-zero on error though.")
-var rgn = flag.String("r", "", "Datacenter region to interrogate. Leave blank for provider-default region.")
-
-func main() {
- flag.Parse()
-
- withIdentity(false, func(auth gophercloud.AccessProvider) {
- withServerApi(auth, func(servers gophercloud.CloudServersProvider) {
- images, err := servers.ListImages()
- if err != nil {
- panic(err)
- }
-
- if !*quiet {
- fmt.Println("ID,Name,MinRam,MinDisk")
- for _, image := range images {
- fmt.Printf("%s,\"%s\",%d,%d\n", image.Id, image.Name, image.MinRam, image.MinDisk)
- }
- }
- })
- })
-}
diff --git a/acceptance/06-list-flavors.go b/acceptance/06-list-flavors.go
deleted file mode 100644
index 65db7da..0000000
--- a/acceptance/06-list-flavors.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/rackspace/gophercloud"
-)
-
-var quiet = flag.Bool("quiet", false, "Quiet mode for acceptance testing. $? non-zero on error though.")
-var rgn = flag.String("r", "", "Datacenter region to interrogate. Leave blank for provider-default region.")
-
-func main() {
- flag.Parse()
-
- withIdentity(false, func(auth gophercloud.AccessProvider) {
- withServerApi(auth, func(servers gophercloud.CloudServersProvider) {
- flavors, err := servers.ListFlavors()
- if err != nil {
- panic(err)
- }
-
- if !*quiet {
- fmt.Println("ID,Name,MinRam,MinDisk")
- for _, f := range flavors {
- fmt.Printf("%s,\"%s\",%d,%d\n", f.Id, f.Name, f.Ram, f.Disk)
- }
- }
- })
- })
-}
diff --git a/acceptance/07-change-admin-password.go b/acceptance/07-change-admin-password.go
deleted file mode 100644
index 880fbe8..0000000
--- a/acceptance/07-change-admin-password.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/rackspace/gophercloud"
-)
-
-var quiet = flag.Bool("quiet", false, "Quiet mode, for acceptance testing. $? still indicates errors though.")
-var serverId = flag.String("i", "", "ID of server whose admin password is to be changed.")
-var newPass = flag.String("p", "", "New password for the server.")
-
-func main() {
- flag.Parse()
-
- withIdentity(false, func(acc gophercloud.AccessProvider) {
- withServerApi(acc, func(api gophercloud.CloudServersProvider) {
- // If user doesn't explicitly provide a server ID, create one dynamically.
- if *serverId == "" {
- var err error
- *serverId, err = createServer(api, "", "", "", "")
- if err != nil {
- panic(err)
- }
- waitForServerState(api, *serverId, "ACTIVE")
- }
-
- // If no password is provided, create one dynamically.
- if *newPass == "" {
- *newPass = randomString("", 16)
- }
-
- // Submit the request for changing the admin password.
- // Note that we don't verify this actually completes;
- // doing so is beyond the scope of the SDK, and should be
- // the responsibility of your specific OpenStack provider.
- err := api.SetAdminPassword(*serverId, *newPass)
- if err != nil {
- panic(err)
- }
-
- if !*quiet {
- fmt.Println("Password change request submitted.")
- }
- })
- })
-}
diff --git a/acceptance/08-reauthentication.go b/acceptance/08-reauthentication.go
deleted file mode 100644
index c46f5bb..0000000
--- a/acceptance/08-reauthentication.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/rackspace/gophercloud"
-)
-
-var quiet = flag.Bool("quiet", false, "Quiet mode for acceptance testing. $? non-zero on error though.")
-var rgn = flag.String("r", "", "Datacenter region to interrogate. Leave blank for provider-default region.")
-
-func main() {
- flag.Parse()
-
- // Invoke withIdentity such that re-auth is enabled.
- withIdentity(true, func(auth gophercloud.AccessProvider) {
- token1 := auth.AuthToken()
-
- withServerApi(auth, func(servers gophercloud.CloudServersProvider) {
- // Just to confirm everything works, we should be able to list images without error.
- _, err := servers.ListImages()
- if err != nil {
- panic(err)
- }
-
- // Revoke our current authentication token.
- auth.Revoke(auth.AuthToken())
-
- // Attempt to list images again. This should _succeed_, because we enabled re-authentication.
- _, err = servers.ListImages()
- if err != nil {
- panic(err)
- }
-
- // However, our new authentication token should differ.
- token2 := auth.AuthToken()
-
- if !*quiet {
- fmt.Println("Old authentication token: ", token1)
- fmt.Println("New authentication token: ", token2)
- }
-
- if token1 == token2 {
- panic("Tokens should differ")
- }
- })
- })
-}
diff --git a/acceptance/09-resize-server.go b/acceptance/09-resize-server.go
deleted file mode 100644
index a2ef3c8..0000000
--- a/acceptance/09-resize-server.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/rackspace/gophercloud"
- "time"
-)
-
-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) {
- // These tests are going to take some time to complete.
- // So, we'll do two tests at the same time to help amortize test time.
- done := make(chan bool)
- go resizeRejectTest(api, done)
- go resizeAcceptTest(api, done)
- _ = <-done
- _ = <-done
-
- if !*quiet {
- fmt.Println("Done.")
- }
- })
- })
-}
-
-// Perform the resize test, but reject the resize request.
-func resizeRejectTest(api gophercloud.CloudServersProvider, done chan bool) {
- withServer(api, func(id string) {
- newFlavorId := findAlternativeFlavor()
- err := api.ResizeServer(id, randomString("ACPTTEST", 24), newFlavorId, "")
- if err != nil {
- panic(err)
- }
-
- waitForServerState(api, id, "VERIFY_RESIZE")
-
- err = api.RevertResize(id)
- if err != nil {
- panic(err)
- }
- })
- done <- true
-}
-
-// Perform the resize test, but accept the resize request.
-func resizeAcceptTest(api gophercloud.CloudServersProvider, done chan bool) {
- withServer(api, func(id string) {
- newFlavorId := findAlternativeFlavor()
- err := api.ResizeServer(id, randomString("ACPTTEST", 24), newFlavorId, "")
- if err != nil {
- panic(err)
- }
-
- waitForServerState(api, id, "VERIFY_RESIZE")
-
- err = api.ConfirmResize(id)
- if err != nil {
- panic(err)
- }
- })
- done <- true
-}
-
-func withServer(api gophercloud.CloudServersProvider, f func(string)) {
- id, err := createServer(api, "", "", "", "")
- if err != nil {
- panic(err)
- }
-
- for {
- s, err := api.ServerById(id)
- if err != nil {
- panic(err)
- }
- if s.Status == "ACTIVE" {
- break
- }
- time.Sleep(10 * time.Second)
- }
-
- f(id)
-
- // I've learned that resizing an instance can fail if a delete request
- // comes in prior to its completion. This ends up leaving the server
- // in an error state, and neither the resize NOR the delete complete.
- // This is a bug in OpenStack, as far as I'm concerned, but thankfully,
- // there's an easy work-around -- just wait for your server to return to
- // active state first!
- waitForServerState(api, id, "ACTIVE")
- err = api.DeleteServerById(id)
- if err != nil {
- panic(err)
- }
-}
diff --git a/acceptance/10-reboot-server.go b/acceptance/10-reboot-server.go
deleted file mode 100644
index ba6215a..0000000
--- a/acceptance/10-reboot-server.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// +build acceptance,old
-
-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(servers gophercloud.CloudServersProvider) {
- log("Creating server")
- serverId, err := createServer(servers, "", "", "", "")
- if err != nil {
- panic(err)
- }
- waitForServerState(servers, serverId, "ACTIVE")
-
- log("Soft-rebooting server")
- servers.RebootServer(serverId, false)
- waitForServerState(servers, serverId, "REBOOT")
- waitForServerState(servers, serverId, "ACTIVE")
-
- log("Hard-rebooting server")
- servers.RebootServer(serverId, true)
- waitForServerState(servers, serverId, "HARD_REBOOT")
- waitForServerState(servers, serverId, "ACTIVE")
-
- log("Done")
- servers.DeleteServerById(serverId)
- })
- })
-}
-
-func log(s string) {
- if !*quiet {
- fmt.Println(s)
- }
-}
diff --git a/acceptance/11-rescue-unrescue-server.go b/acceptance/11-rescue-unrescue-server.go
deleted file mode 100644
index 008ad9d..0000000
--- a/acceptance/11-rescue-unrescue-server.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// +build acceptance,old
-
-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(servers gophercloud.CloudServersProvider) {
- log("Creating server")
- id, err := createServer(servers, "", "", "", "")
- if err != nil {
- panic(err)
- }
- waitForServerState(servers, id, "ACTIVE")
- defer servers.DeleteServerById(id)
-
- log("Rescuing server")
- adminPass, err := servers.RescueServer(id)
- if err != nil {
- panic(err)
- }
- log(" Admin password = " + adminPass)
- if len(adminPass) < 1 {
- panic("Empty admin password")
- }
- waitForServerState(servers, id, "RESCUE")
-
- log("Unrescuing server")
- err = servers.UnrescueServer(id)
- if err != nil {
- panic(err)
- }
- waitForServerState(servers, id, "ACTIVE")
-
- log("Done")
- })
- })
-}
-
-func log(s string) {
- if !*quiet {
- fmt.Println(s)
- }
-}
diff --git a/acceptance/12-update-server.go b/acceptance/12-update-server.go
deleted file mode 100644
index c0191f1..0000000
--- a/acceptance/12-update-server.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// +build acceptance,old
-
-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(servers gophercloud.CloudServersProvider) {
- log("Creating server")
- id, err := createServer(servers, "", "", "", "")
- if err != nil {
- panic(err)
- }
- waitForServerState(servers, id, "ACTIVE")
- defer servers.DeleteServerById(id)
-
- log("Updating name of server")
- newName := randomString("ACPTTEST", 32)
- newDetails, err := servers.UpdateServer(id, gophercloud.NewServerSettings{
- Name: newName,
- })
- if err != nil {
- panic(err)
- }
- if newDetails.Name != newName {
- panic("Name change didn't appear to take")
- }
-
- log("Done")
- })
- })
-}
-
-func log(s string) {
- if !*quiet {
- fmt.Println(s)
- }
-}
diff --git a/acceptance/13-rebuild-server.go b/acceptance/13-rebuild-server.go
deleted file mode 100644
index ae7e19f..0000000
--- a/acceptance/13-rebuild-server.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// +build acceptance,old
-
-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(servers gophercloud.CloudServersProvider) {
- log("Creating server")
- id, err := createServer(servers, "", "", "", "")
- if err != nil {
- panic(err)
- }
- waitForServerState(servers, id, "ACTIVE")
- defer servers.DeleteServerById(id)
-
- log("Rebuilding server")
- newDetails, err := servers.RebuildServer(id, gophercloud.NewServer{
- Name: randomString("ACPTTEST", 32),
- ImageRef: findAlternativeImage(),
- FlavorRef: findAlternativeFlavor(),
- AdminPass: randomString("", 16),
- })
- if err != nil {
- panic(err)
- }
- waitForServerState(servers, newDetails.Id, "ACTIVE")
-
- log("Done")
- })
- })
-}
-
-func log(s string) {
- if !*quiet {
- fmt.Println(s)
- }
-}
diff --git a/acceptance/14-list-addresses.go b/acceptance/14-list-addresses.go
deleted file mode 100644
index 1d7d26b..0000000
--- a/acceptance/14-list-addresses.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// +build acceptance,old
-
-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)
- 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.")
- }
- if !*quiet {
- fmt.Println("Addresses:")
- fmt.Printf("%+v\n", addresses)
- }
-}
-
-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/acceptance/15-list-keypairs.go b/acceptance/15-list-keypairs.go
deleted file mode 100644
index 1a617ed..0000000
--- a/acceptance/15-list-keypairs.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/rackspace/gophercloud"
-)
-
-var quiet = flag.Bool("quiet", false, "Quiet mode for acceptance testing. $? non-zero on error though.")
-var rgn = flag.String("r", "", "Datacenter region to interrogate. Leave blank for provider-default region.")
-
-func main() {
- flag.Parse()
-
- withIdentity(false, func(auth gophercloud.AccessProvider) {
- withServerApi(auth, func(servers gophercloud.CloudServersProvider) {
- keypairs, err := servers.ListKeyPairs()
- if err != nil {
- panic(err)
- }
-
- if !*quiet {
- fmt.Println("name,fingerprint,publickey")
- for _, key := range keypairs {
- fmt.Printf("%s,%s,%s\n", key.Name, key.FingerPrint, key.PublicKey)
- }
- }
- })
- })
-}
diff --git a/acceptance/16-create-delete-keypair.go b/acceptance/16-create-delete-keypair.go
deleted file mode 100644
index f59e51c..0000000
--- a/acceptance/16-create-delete-keypair.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/rackspace/gophercloud"
-)
-
-var quiet = flag.Bool("quiet", false, "Quiet mode for acceptance testing. $? non-zero on error though.")
-var rgn = flag.String("r", "", "Datacenter region to interrogate. Leave blank for provider-default region.")
-
-func main() {
- flag.Parse()
-
- withIdentity(false, func(auth gophercloud.AccessProvider) {
- withServerApi(auth, func(servers gophercloud.CloudServersProvider) {
- name := randomString("ACPTTEST", 16)
- kp := gophercloud.NewKeyPair{
- Name: name,
- }
- keypair, err := servers.CreateKeyPair(kp)
- if err != nil {
- panic(err)
- }
- if !*quiet {
- fmt.Printf("%s,%s,%s\n", keypair.Name, keypair.FingerPrint, keypair.PublicKey)
- }
-
- keypair, err = servers.ShowKeyPair(name)
- if err != nil {
- panic(err)
- }
- if !*quiet {
- fmt.Printf("%s,%s,%s\n", keypair.Name, keypair.FingerPrint, keypair.PublicKey)
- }
-
- err = servers.DeleteKeyPair(name)
- if err != nil {
- panic(err)
- }
- })
- })
-}
diff --git a/acceptance/17-create-delete-image.go b/acceptance/17-create-delete-image.go
deleted file mode 100644
index b3d80a3..0000000
--- a/acceptance/17-create-delete-image.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/rackspace/gophercloud"
-)
-
-var quiet = flag.Bool("quiet", false, "Quiet mode for acceptance testing. $? non-zero on error though.")
-var rgn = flag.String("r", "", "Datacenter region to interrogate. Leave blank for provider-default region.")
-
-func main() {
- flag.Parse()
-
- withIdentity(false, func(auth gophercloud.AccessProvider) {
- withServerApi(auth, func(servers gophercloud.CloudServersProvider) {
- log("Creating server")
- serverId, err := createServer(servers, "", "", "", "")
- if err != nil {
- panic(err)
- }
- waitForServerState(servers, serverId, "ACTIVE")
-
- log("Creating image")
- name := randomString("ACPTTEST", 16)
- createImage := gophercloud.CreateImage{
- Name: name,
- }
- imageId, err := servers.CreateImage(serverId, createImage)
- if err != nil {
- panic(err)
- }
- waitForImageState(servers, imageId, "ACTIVE")
-
- log("Deleting server")
- servers.DeleteServerById(serverId)
-
- log("Deleting image")
- servers.DeleteImageById(imageId)
-
- log("Done")
- })
- })
-}
-
-func log(s string) {
- if !*quiet {
- fmt.Println(s)
- }
-}
diff --git a/acceptance/18-osutil-authentication.go b/acceptance/18-osutil-authentication.go
deleted file mode 100644
index 01ff4e9..0000000
--- a/acceptance/18-osutil-authentication.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "github.com/rackspace/gophercloud"
- "github.com/rackspace/gophercloud/osutil"
-)
-
-func main() {
- provider, authOptions, err := osutil.AuthOptions()
- if err != nil {
- panic(err)
- }
- _, err = gophercloud.Authenticate(provider, authOptions)
- if err != nil {
- panic(err)
- }
-}
diff --git a/acceptance/19-list-addresses-0.1.go b/acceptance/19-list-addresses-0.1.go
deleted file mode 100644
index d60557b..0000000
--- a/acceptance/19-list-addresses-0.1.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// +build acceptance,old
-
-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/acceptance/99-delete-server.go b/acceptance/99-delete-server.go
deleted file mode 100644
index 3e38ba4..0000000
--- a/acceptance/99-delete-server.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "flag"
- "fmt"
- "github.com/rackspace/gophercloud"
-)
-
-var quiet = flag.Bool("quiet", false, "Quiet operation for acceptance tests. $? non-zero if problem.")
-var region = flag.String("r", "", "Datacenter region. Leave blank for provider-default region.")
-
-func main() {
- flag.Parse()
-
- withIdentity(false, func(auth gophercloud.AccessProvider) {
- withServerApi(auth, func(servers gophercloud.CloudServersProvider) {
- // Grab a listing of all servers.
- ss, err := servers.ListServers()
- if err != nil {
- panic(err)
- }
-
- // And for each one that starts with the ACPTTEST prefix, delete it.
- // These are likely left-overs from previously running acceptance tests.
- // Note that 04-create-servers.go is intended to leak servers by intention,
- // so as to test this code. :)
- n := 0
- for _, s := range ss {
- if len(s.Name) < 8 {
- continue
- }
- if s.Name[0:8] == "ACPTTEST" {
- err := servers.DeleteServerById(s.Id)
- if err != nil {
- panic(err)
- }
- n++
- }
- }
-
- if !*quiet {
- fmt.Printf("%d servers removed.\n", n)
- }
- })
- })
-}
diff --git a/acceptance/libargs.go b/acceptance/libargs.go
deleted file mode 100644
index a9bb92f..0000000
--- a/acceptance/libargs.go
+++ /dev/null
@@ -1,208 +0,0 @@
-// +build acceptance,old
-
-package main
-
-import (
- "crypto/rand"
- "fmt"
- "github.com/rackspace/gophercloud"
- "os"
- "strings"
- "time"
-)
-
-// getCredentials will verify existence of needed credential information
-// provided through environment variables. This function will not return
-// if at least one piece of required information is missing.
-func getCredentials() (provider, username, password, apiKey string) {
- provider = os.Getenv("SDK_PROVIDER")
- username = os.Getenv("SDK_USERNAME")
- password = os.Getenv("SDK_PASSWORD")
- apiKey = os.Getenv("SDK_API_KEY")
-
- if (provider == "") || (username == "") || (password == "") {
- fmt.Fprintf(os.Stderr, "One or more of the following environment variables aren't set:\n")
- fmt.Fprintf(os.Stderr, " SDK_PROVIDER=\"%s\"\n", provider)
- fmt.Fprintf(os.Stderr, " SDK_USERNAME=\"%s\"\n", username)
- fmt.Fprintf(os.Stderr, " SDK_PASSWORD=\"%s\"\n", password)
- os.Exit(1)
- }
-
- return
-}
-
-// randomString generates a string of given length, but random content.
-// All content will be within the ASCII graphic character set.
-// (Implementation from Even Shaw's contribution on
-// http://stackoverflow.com/questions/12771930/what-is-the-fastest-way-to-generate-a-long-random-string-in-go).
-func randomString(prefix string, n int) string {
- const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
- var bytes = make([]byte, n)
- rand.Read(bytes)
- for i, b := range bytes {
- bytes[i] = alphanum[b%byte(len(alphanum))]
- }
- return prefix + string(bytes)
-}
-
-// aSuitableImage finds a minimal image for use in dynamically creating servers.
-// If none can be found, this function will panic.
-func aSuitableImage(api gophercloud.CloudServersProvider) string {
- images, err := api.ListImages()
- if err != nil {
- panic(err)
- }
-
- // TODO(sfalvo):
- // Works for Rackspace, might not work for your provider!
- // Need to figure out why ListImages() provides 0 values for
- // Ram and Disk fields.
- //
- // Until then, just return Ubuntu 12.04 LTS.
- for i := 0; i < len(images); i++ {
- if strings.Contains(images[i].Name, "Ubuntu 12.04 LTS") {
- return images[i].Id
- }
- }
- panic("Image for Ubuntu 12.04 LTS not found.")
-}
-
-// aSuitableFlavor finds the minimum flavor capable of running the test image
-// chosen by aSuitableImage. If none can be found, this function will panic.
-func aSuitableFlavor(api gophercloud.CloudServersProvider) string {
- flavors, err := api.ListFlavors()
- if err != nil {
- panic(err)
- }
-
- // TODO(sfalvo):
- // Works for Rackspace, might not work for your provider!
- // Need to figure out why ListFlavors() provides 0 values for
- // Ram and Disk fields.
- //
- // Until then, just return Ubuntu 12.04 LTS.
- for i := 0; i < len(flavors); i++ {
- if flavors[i].Id == "2" {
- return flavors[i].Id
- }
- }
- panic("Flavor 2 (512MB 1-core 20GB machine) not found.")
-}
-
-// createServer creates a new server in a manner compatible with acceptance testing.
-// In particular, it ensures that the name of the server always starts with "ACPTTEST--",
-// which the delete servers acceptance test relies on to identify servers to delete.
-// Passing in empty image and flavor references will force the use of reasonable defaults.
-// An empty name string will result in a dynamically created name prefixed with "ACPTTEST--".
-// A blank admin password will cause a password to be automatically generated; however,
-// at present no means of recovering this password exists, as no acceptance tests yet require
-// this data.
-func createServer(servers gophercloud.CloudServersProvider, imageRef, flavorRef, name, adminPass string) (string, error) {
- if imageRef == "" {
- imageRef = aSuitableImage(servers)
- }
-
- if flavorRef == "" {
- flavorRef = aSuitableFlavor(servers)
- }
-
- if len(name) < 1 {
- name = randomString("ACPTTEST", 16)
- }
-
- if (len(name) < 8) || (name[0:8] != "ACPTTEST") {
- name = fmt.Sprintf("ACPTTEST--%s", name)
- }
-
- newServer, err := servers.CreateServer(gophercloud.NewServer{
- Name: name,
- ImageRef: imageRef,
- FlavorRef: flavorRef,
- AdminPass: adminPass,
- })
-
- if err != nil {
- return "", err
- }
-
- return newServer.Id, nil
-}
-
-// findAlternativeFlavor locates a flavor to resize a server to. It is guaranteed to be different
-// than what aSuitableFlavor() returns. If none could be found, this function will panic.
-func findAlternativeFlavor() string {
- return "3" // 1GB image, up from 512MB image
-}
-
-// findAlternativeImage locates an image to resize or rebuild a server with. It is guaranteed to be
-// different than what aSuitableImage() returns. If none could be found, this function will panic.
-func findAlternativeImage() string {
- return "c6f9c411-e708-4952-91e5-62ded5ea4d3e"
-}
-
-// withIdentity authenticates the user against the provider's identity service, and provides an
-// accessor for additional services.
-func withIdentity(ar bool, f func(gophercloud.AccessProvider)) {
- provider, username, password, _ := getCredentials()
- acc, err := gophercloud.Authenticate(
- provider,
- gophercloud.AuthOptions{
- Username: username,
- Password: password,
- AllowReauth: ar,
- },
- )
- if err != nil {
- panic(err)
- }
-
- f(acc)
-}
-
-// withServerApi acquires the cloud servers API.
-func withServerApi(acc gophercloud.AccessProvider, f func(gophercloud.CloudServersProvider)) {
- api, err := gophercloud.ServersApi(acc, gophercloud.ApiCriteria{
- Name: "cloudServersOpenStack",
- VersionId: "2",
- UrlChoice: gophercloud.PublicURL,
- })
- if err != nil {
- panic(err)
- }
-
- f(api)
-}
-
-// waitForServerState polls, every 10 seconds, for a given server to appear in the indicated state.
-// This call will block forever if it never appears in the desired state, so if a timeout is required,
-// make sure to call this function in a goroutine.
-func waitForServerState(api gophercloud.CloudServersProvider, id, state string) error {
- for {
- s, err := api.ServerById(id)
- if err != nil {
- return err
- }
- if s.Status == state {
- return nil
- }
- time.Sleep(10 * time.Second)
- }
- panic("Impossible")
-}
-
-// waitForImageState polls, every 10 seconds, for a given image to appear in the indicated state.
-// This call will block forever if it never appears in the desired state, so if a timeout is required,
-// make sure to call this function in a goroutine.
-func waitForImageState(api gophercloud.CloudServersProvider, id, state string) error {
- for {
- s, err := api.ImageById(id)
- if err != nil {
- return err
- }
- if s.Status == state {
- return nil
- }
- time.Sleep(10 * time.Second)
- }
- panic("Impossible")
-}
diff --git a/api_fetch.go b/api_fetch.go
deleted file mode 100644
index 353df75..0000000
--- a/api_fetch.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package gophercloud
-
-import (
- "github.com/mitchellh/mapstructure"
-)
-
-//The default generic openstack api
-var OpenstackApi = map[string]interface{}{
- "Name": "nova",
- "UrlChoice": PublicURL,
-}
-
-// Api for use with rackspace
-var RackspaceApi = map[string]interface{}{
- "Name": "cloudServersOpenStack",
- "VersionId": "2",
- "UrlChoice": PublicURL,
-}
-
-//Populates an ApiCriteria struct with the api values
-//from one of the api maps
-func PopulateApi(variant string) (ApiCriteria, error) {
- var Api ApiCriteria
- var variantMap map[string]interface{}
-
- switch variant {
- case "":
- variantMap = OpenstackApi
-
- case "openstack":
- variantMap = OpenstackApi
-
- case "rackspace":
- variantMap = RackspaceApi
- }
-
- err := mapstructure.Decode(variantMap, &Api)
- if err != nil {
- return Api, err
- }
- return Api, err
-}
diff --git a/authenticate.go b/authenticate.go
deleted file mode 100644
index ff609aa..0000000
--- a/authenticate.go
+++ /dev/null
@@ -1,257 +0,0 @@
-package gophercloud
-
-import (
- "fmt"
- "github.com/racker/perigee"
-)
-
-// AuthOptions lets anyone calling Authenticate() supply the required access credentials.
-// At present, only Identity V2 API support exists; therefore, only Username, Password,
-// and optionally, TenantId are provided. If future Identity API versions become available,
-// alternative fields unique to those versions may appear here.
-type AuthOptions struct {
- // Username and Password are required if using Identity V2 API.
- // Consult with your provider's control panel to discover your
- // account's username and password.
- Username, Password string
-
- // ApiKey used for providers that support Api Key authentication
- ApiKey string
-
- // The TenantId field is optional for the Identity V2 API.
- TenantId string
-
- // The TenantName can be specified instead of the TenantId
- TenantName string
-
- // AllowReauth should be set to true if you grant permission for Gophercloud to cache
- // your credentials in memory, and to allow Gophercloud to attempt to re-authenticate
- // automatically if/when your token expires. If you set it to false, it will not cache
- // these settings, but re-authentication will not be possible. This setting defaults
- // to false.
- AllowReauth bool
-}
-
-// AuthContainer provides a JSON encoding wrapper for passing credentials to the Identity
-// service. You will not work with this structure directly.
-type AuthContainer struct {
- Auth Auth `json:"auth"`
-}
-
-// Auth provides a JSON encoding wrapper for passing credentials to the Identity
-// service. You will not work with this structure directly.
-type Auth struct {
- PasswordCredentials *PasswordCredentials `json:"passwordCredentials,omitempty"`
- ApiKeyCredentials *ApiKeyCredentials `json:"RAX-KSKEY:apiKeyCredentials,omitempty"`
- TenantId string `json:"tenantId,omitempty"`
- TenantName string `json:"tenantName,omitempty"`
-}
-
-// PasswordCredentials provides a JSON encoding wrapper for passing credentials to the Identity
-// service. You will not work with this structure directly.
-type PasswordCredentials struct {
- Username string `json:"username"`
- Password string `json:"password"`
-}
-
-type ApiKeyCredentials struct {
- Username string `json:"username"`
- ApiKey string `json:"apiKey"`
-}
-
-// Access encapsulates the API token and its relevant fields, as well as the
-// services catalog that Identity API returns once authenticated.
-type Access struct {
- Token Token
- ServiceCatalog []CatalogEntry
- User User
- provider Provider `json:"-"`
- options AuthOptions `json:"-"`
- context *Context `json:"-"`
-}
-
-// Token encapsulates an authentication token and when it expires. It also includes
-// tenant information if available.
-type Token struct {
- Id, Expires string
- Tenant Tenant
-}
-
-// Tenant encapsulates tenant authentication information. If, after authentication,
-// no tenant information is supplied, both Id and Name will be "".
-type Tenant struct {
- Id, Name string
-}
-
-// User encapsulates the user credentials, and provides visibility in what
-// the user can do through its role assignments.
-type User struct {
- Id, Name string
- XRaxDefaultRegion string `json:"RAX-AUTH:defaultRegion"`
- Roles []Role
-}
-
-// Role encapsulates a permission that a user can rely on.
-type Role struct {
- Description, Id, Name string
-}
-
-// CatalogEntry encapsulates a service catalog record.
-type CatalogEntry struct {
- Name, Type string
- Endpoints []EntryEndpoint
-}
-
-// EntryEndpoint encapsulates how to get to the API of some service.
-type EntryEndpoint struct {
- Region, TenantId string
- PublicURL, InternalURL string
- VersionId, VersionInfo, VersionList string
-}
-
-type AuthError struct {
- StatusCode int
-}
-
-func (ae *AuthError) Error() string {
- switch ae.StatusCode {
- case 401:
- return "Auth failed. Bad credentials."
-
- default:
- return fmt.Sprintf("Auth failed. Status code is: %s.", ae.StatusCode)
- }
-}
-
-//
-func getAuthCredentials(options AuthOptions) Auth {
- if options.ApiKey == "" {
- return Auth{
- PasswordCredentials: &PasswordCredentials{
- Username: options.Username,
- Password: options.Password,
- },
- TenantId: options.TenantId,
- TenantName: options.TenantName,
- }
- } else {
- return Auth{
- ApiKeyCredentials: &ApiKeyCredentials{
- Username: options.Username,
- ApiKey: options.ApiKey,
- },
- TenantId: options.TenantId,
- TenantName: options.TenantName,
- }
- }
-}
-
-// papersPlease contains the common logic between authentication and re-authentication.
-// The name, obviously a joke on the process of authentication, was chosen because
-// of how many other entities exist in the program containing the word Auth or Authorization.
-// I didn't need another one.
-func (c *Context) papersPlease(p Provider, options AuthOptions) (*Access, error) {
- var access *Access
- access = new(Access)
-
- if (options.Username == "") || (options.Password == "" && options.ApiKey == "") {
- return nil, ErrCredentials
- }
-
- resp, err := perigee.Request("POST", p.AuthEndpoint, perigee.Options{
- CustomClient: c.httpClient,
- ReqBody: &AuthContainer{
- Auth: getAuthCredentials(options),
- },
- Results: &struct {
- Access **Access `json:"access"`
- }{
- &access,
- },
- })
-
- if err == nil {
- switch resp.StatusCode {
- case 200:
- access.options = options
- access.provider = p
- access.context = c
-
- default:
- err = &AuthError {
- StatusCode: resp.StatusCode,
- }
- }
- }
-
- return access, err
-}
-
-// Authenticate() grants access to the OpenStack-compatible provider API.
-//
-// Providers are identified through a unique key string.
-// See the RegisterProvider() method for more details.
-//
-// The supplied AuthOptions instance allows the client to specify only those credentials
-// relevant for the authentication request. At present, support exists for OpenStack
-// Identity V2 API only; support for V3 will become available as soon as documentation for it
-// becomes readily available.
-//
-// For Identity V2 API requirements, you must provide at least the Username and Password
-// options. The TenantId field is optional, and defaults to "".
-func (c *Context) Authenticate(provider string, options AuthOptions) (*Access, error) {
- p, err := c.ProviderByName(provider)
- if err != nil {
- return nil, err
- }
- return c.papersPlease(p, options)
-}
-
-// Reauthenticate attempts to reauthenticate using the configured access credentials, if
-// allowed. This method takes no action unless your AuthOptions has the AllowReauth flag
-// set to true.
-func (a *Access) Reauthenticate() error {
- var other *Access
- var err error
-
- if a.options.AllowReauth {
- other, err = a.context.papersPlease(a.provider, a.options)
- if err == nil {
- *a = *other
- }
- }
- return err
-}
-
-// See AccessProvider interface definition for details.
-func (a *Access) FirstEndpointUrlByCriteria(ac ApiCriteria) string {
- ep := FindFirstEndpointByCriteria(a.ServiceCatalog, ac)
- urls := []string{ep.PublicURL, ep.InternalURL}
- return urls[ac.UrlChoice]
-}
-
-// See AccessProvider interface definition for details.
-func (a *Access) AuthToken() string {
- return a.Token.Id
-}
-
-// See AccessProvider interface definition for details.
-func (a *Access) Revoke(tok string) error {
- url := a.provider.AuthEndpoint + "/" + tok
- err := perigee.Delete(url, perigee.Options{
- MoreHeaders: map[string]string{
- "X-Auth-Token": a.AuthToken(),
- },
- OkCodes: []int{204},
- })
- return err
-}
-
-// See ServiceCatalogerForIdentityV2 interface definition for details.
-// Note that the raw slice is returend; be careful not to alter the fields of any members,
-// for other components of Gophercloud may depend upon them.
-// If this becomes a problem in the future,
-// a future revision may return a deep-copy of the service catalog instead.
-func (a *Access) V2ServiceCatalog() []CatalogEntry {
- return a.ServiceCatalog
-}
diff --git a/authenticate_test.go b/authenticate_test.go
deleted file mode 100644
index b05c780..0000000
--- a/authenticate_test.go
+++ /dev/null
@@ -1,264 +0,0 @@
-package gophercloud
-
-import (
- "net/http"
- "testing"
-)
-
-const SUCCESSFUL_RESPONSE = `{
- "access": {
- "serviceCatalog": [{
- "endpoints": [{
- "publicURL": "https://ord.servers.api.rackspacecloud.com/v2/12345",
- "region": "ORD",
- "tenantId": "12345",
- "versionId": "2",
- "versionInfo": "https://ord.servers.api.rackspacecloud.com/v2",
- "versionList": "https://ord.servers.api.rackspacecloud.com/"
- },{
- "publicURL": "https://dfw.servers.api.rackspacecloud.com/v2/12345",
- "region": "DFW",
- "tenantId": "12345",
- "versionId": "2",
- "versionInfo": "https://dfw.servers.api.rackspacecloud.com/v2",
- "versionList": "https://dfw.servers.api.rackspacecloud.com/"
- }],
- "name": "cloudServersOpenStack",
- "type": "compute"
- },{
- "endpoints": [{
- "publicURL": "https://ord.databases.api.rackspacecloud.com/v1.0/12345",
- "region": "ORD",
- "tenantId": "12345"
- }],
- "name": "cloudDatabases",
- "type": "rax:database"
- }],
- "token": {
- "expires": "2012-04-13T13:15:00.000-05:00",
- "id": "aaaaa-bbbbb-ccccc-dddd"
- },
- "user": {
- "RAX-AUTH:defaultRegion": "DFW",
- "id": "161418",
- "name": "demoauthor",
- "roles": [{
- "description": "User Admin Role.",
- "id": "3",
- "name": "identity:user-admin"
- }]
- }
- }
-}
-`
-
-func TestAuthProvider(t *testing.T) {
- tt := newTransport().WithResponse(SUCCESSFUL_RESPONSE)
- c := TestContext().UseCustomClient(&http.Client{
- Transport: tt,
- })
-
- _, err := c.Authenticate("", AuthOptions{})
- if err == nil {
- t.Error("Expected error for empty provider string")
- return
- }
- _, err = c.Authenticate("unknown-provider", AuthOptions{Username: "u", Password: "p"})
- if err == nil {
- t.Error("Expected error for unknown service provider")
- return
- }
-
- err = c.RegisterProvider("provider", Provider{AuthEndpoint: "/"})
- if err != nil {
- t.Error(err)
- return
- }
- _, err = c.Authenticate("provider", AuthOptions{Username: "u", Password: "p"})
- if err != nil {
- t.Error(err)
- return
- }
- if tt.called != 1 {
- t.Error("Expected transport to be called once.")
- return
- }
-}
-
-func TestTenantIdEncoding(t *testing.T) {
- tt := newTransport().WithResponse(SUCCESSFUL_RESPONSE)
- c := TestContext().
- UseCustomClient(&http.Client{
- Transport: tt,
- }).
- WithProvider("provider", Provider{AuthEndpoint: "/"})
-
- tt.IgnoreTenantId()
- _, err := c.Authenticate("provider", AuthOptions{
- Username: "u",
- Password: "p",
- })
- if err != nil {
- t.Error(err)
- return
- }
- if tt.tenantIdFound {
- t.Error("Tenant ID should not have been encoded")
- return
- }
-
- tt.ExpectTenantId()
- _, err = c.Authenticate("provider", AuthOptions{
- Username: "u",
- Password: "p",
- TenantId: "t",
- })
- if err != nil {
- t.Error(err)
- return
- }
- if !tt.tenantIdFound {
- t.Error("Tenant ID should have been encoded")
- return
- }
-}
-
-func TestUserNameAndPassword(t *testing.T) {
- c := TestContext().
- WithProvider("provider", Provider{AuthEndpoint: "http://localhost/"}).
- UseCustomClient(&http.Client{Transport: newTransport().WithResponse(SUCCESSFUL_RESPONSE)})
-
- credentials := []AuthOptions{
- {},
- {Username: "u"},
- {Password: "p"},
- }
- for i, auth := range credentials {
- _, err := c.Authenticate("provider", auth)
- if err == nil {
- t.Error("Expected error from missing credentials (%d)", i)
- return
- }
- }
-
- _, err := c.Authenticate("provider", AuthOptions{Username: "u", Password: "p"})
- if err != nil {
- t.Error(err)
- return
- }
-}
-
-func TestUserNameAndApiKey(t *testing.T) {
- c := TestContext().
- WithProvider("provider", Provider{AuthEndpoint: "http://localhost/"}).
- UseCustomClient(&http.Client{Transport: newTransport().WithResponse(SUCCESSFUL_RESPONSE)})
-
- credentials := []AuthOptions{
- {},
- {Username: "u"},
- {ApiKey: "a"},
- }
- for i, auth := range credentials {
- _, err := c.Authenticate("provider", auth)
- if err == nil {
- t.Error("Expected error from missing credentials (%d)", i)
- return
- }
- }
-
- _, err := c.Authenticate("provider", AuthOptions{Username: "u", ApiKey: "a"})
- if err != nil {
- t.Error(err)
- return
- }
-}
-
-func TestTokenAcquisition(t *testing.T) {
- c := TestContext().
- UseCustomClient(&http.Client{Transport: newTransport().WithResponse(SUCCESSFUL_RESPONSE)}).
- WithProvider("provider", Provider{AuthEndpoint: "http://localhost/"})
-
- acc, err := c.Authenticate("provider", AuthOptions{Username: "u", Password: "p"})
- if err != nil {
- t.Error(err)
- return
- }
-
- tok := acc.Token
- if (tok.Id == "") || (tok.Expires == "") {
- t.Error("Expected a valid token for successful login; got %s, %s", tok.Id, tok.Expires)
- return
- }
-}
-
-func TestServiceCatalogAcquisition(t *testing.T) {
- c := TestContext().
- UseCustomClient(&http.Client{Transport: newTransport().WithResponse(SUCCESSFUL_RESPONSE)}).
- WithProvider("provider", Provider{AuthEndpoint: "http://localhost/"})
-
- acc, err := c.Authenticate("provider", AuthOptions{Username: "u", Password: "p"})
- if err != nil {
- t.Error(err)
- return
- }
-
- svcs := acc.ServiceCatalog
- if len(svcs) < 2 {
- t.Error("Expected 2 service catalog entries; got %d", len(svcs))
- return
- }
-
- types := map[string]bool{
- "compute": true,
- "rax:database": true,
- }
- for _, entry := range svcs {
- if !types[entry.Type] {
- t.Error("Expected to find type %s.", entry.Type)
- return
- }
- }
-}
-
-func TestUserAcquisition(t *testing.T) {
- c := TestContext().
- UseCustomClient(&http.Client{Transport: newTransport().WithResponse(SUCCESSFUL_RESPONSE)}).
- WithProvider("provider", Provider{AuthEndpoint: "http://localhost/"})
-
- acc, err := c.Authenticate("provider", AuthOptions{Username: "u", Password: "p"})
- if err != nil {
- t.Error(err)
- return
- }
-
- u := acc.User
- if u.Id != "161418" {
- t.Error("Expected user ID of 16148; got", u.Id)
- return
- }
-}
-
-func TestAuthenticationNeverReauths(t *testing.T) {
- tt := newTransport().WithError(401)
- c := TestContext().
- UseCustomClient(&http.Client{Transport: tt}).
- WithProvider("provider", Provider{AuthEndpoint: "http://localhost"})
-
- _, err := c.Authenticate("provider", AuthOptions{Username: "u", Password: "p"})
- if err == nil {
- t.Error("Expected an error from a 401 Unauthorized response")
- return
- }
-
- rc, _ := ActualResponseCode(err)
- if rc != 401 {
- t.Error("Expected a 401 error code")
- return
- }
-
- err = tt.VerifyCalls(t, 1)
- if err != nil {
- // Test object already flagged.
- return
- }
-}
diff --git a/common_types.go b/common_types.go
deleted file mode 100644
index 044b308..0000000
--- a/common_types.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package gophercloud
-
-// Link is used for JSON (un)marshalling.
-// It provides RESTful links to a resource.
-type Link struct {
- Href string `json:"href"`
- Rel string `json:"rel"`
- Type string `json:"type"`
-}
-
-// FileConfig structures represent a blob of data which must appear at a
-// a specific location in a server's filesystem. The file contents are
-// base-64 encoded.
-type FileConfig struct {
- Path string `json:"path"`
- Contents string `json:"contents"`
-}
-
-// NetworkConfig structures represent an affinity between a server and a
-// specific, uniquely identified network. Networks are identified through
-// universally unique IDs.
-type NetworkConfig struct {
- Uuid string `json:"uuid"`
-}
diff --git a/context.go b/context.go
deleted file mode 100644
index a41cc6d..0000000
--- a/context.go
+++ /dev/null
@@ -1,135 +0,0 @@
-package gophercloud
-
-import (
- "net/http"
- "strings"
-)
-
-// Provider structures exist for each tangible provider of OpenStack service.
-// For example, Rackspace, Hewlett-Packard, and NASA might have their own instance of this structure.
-//
-// At a minimum, a provider must expose an authentication endpoint.
-type Provider struct {
- AuthEndpoint string
-}
-
-// ReauthHandlerFunc functions are responsible for somehow performing the task of
-// reauthentication.
-type ReauthHandlerFunc func(AccessProvider) error
-
-// Context structures encapsulate Gophercloud-global state in a manner which
-// facilitates easier unit testing. As a user of this SDK, you'll never
-// have to use this structure, except when contributing new code to the SDK.
-type Context struct {
- // providerMap serves as a directory of supported providers.
- providerMap map[string]Provider
-
- // httpClient refers to the current HTTP client interface to use.
- httpClient *http.Client
-
- // reauthHandler provides the functionality needed to re-authenticate
- // if that feature is enabled. Note: in order to allow for automatic
- // re-authentication, the Context object will need to remember your
- // username, password, and tenant ID as provided in the initial call
- // to Authenticate(). If you do not desire this, you'll need to handle
- // reauthentication yourself through other means. Two methods exist:
- // the first approach is to just handle errors yourself at the application
- // layer, and the other is through a custom reauthentication handler
- // set through the WithReauthHandler() method.
- reauthHandler ReauthHandlerFunc
-}
-
-// TestContext yields a new Context instance, pre-initialized with a barren
-// state suitable for per-unit-test customization. This configuration consists
-// of:
-//
-// * An empty provider map.
-//
-// * An HTTP client built by the net/http package (see http://godoc.org/net/http#Client).
-func TestContext() *Context {
- return &Context{
- providerMap: make(map[string]Provider),
- httpClient: &http.Client{},
- reauthHandler: func(acc AccessProvider) error {
- return acc.Reauthenticate()
- },
- }
-}
-
-// UseCustomClient configures the context to use a customized HTTP client
-// instance. By default, TestContext() will return a Context which uses
-// the net/http package's default client instance.
-func (c *Context) UseCustomClient(hc *http.Client) *Context {
- c.httpClient = hc
- return c
-}
-
-// RegisterProvider allows a unit test to register a mythical provider convenient for testing.
-// If the provider structure lacks adequate configuration, or the configuration given has some
-// detectable error, an ErrConfiguration error will result.
-func (c *Context) RegisterProvider(name string, p Provider) error {
- if p.AuthEndpoint == "" {
- return ErrConfiguration
- }
-
- c.providerMap[name] = p
- return nil
-}
-
-// WithProvider offers convenience for unit tests.
-func (c *Context) WithProvider(name string, p Provider) *Context {
- err := c.RegisterProvider(name, p)
- if err != nil {
- panic(err)
- }
- return c
-}
-
-// ProviderByName will locate a provider amongst those previously registered, if it exists.
-// If the named provider has not been registered, an ErrProvider error will result.
-//
-// You may also specify a custom Identity API URL.
-// Any provider name that contains the characters "://", in that order, will be treated as a custom Identity API URL.
-// Custom URLs, important for private cloud deployments, overrides all provider configurations.
-func (c *Context) ProviderByName(name string) (p Provider, err error) {
- for provider, descriptor := range c.providerMap {
- if name == provider {
- return descriptor, nil
- }
- }
- if strings.Contains(name, "://") {
- p = Provider{
- AuthEndpoint: name,
- }
- return p, nil
- }
- return Provider{}, ErrProvider
-}
-
-// Instantiates a Cloud Servers API for the provider given.
-func (c *Context) ServersApi(acc AccessProvider, criteria ApiCriteria) (CloudServersProvider, error) {
- url := acc.FirstEndpointUrlByCriteria(criteria)
- if url == "" {
- return nil, ErrEndpoint
- }
-
- gcp := &genericServersProvider{
- endpoint: url,
- context: c,
- access: acc,
- }
-
- return gcp, nil
-}
-
-// WithReauthHandler configures the context to handle reauthentication attempts using the supplied
-// funtion. By default, reauthentication happens by invoking Authenticate(), which is unlikely to be
-// useful in a unit test.
-//
-// Do not confuse this function with WithReauth()! Although they work together to support reauthentication,
-// WithReauth() actually contains the decision-making logic to determine when to perform a reauth,
-// while WithReauthHandler() is used to configure what a reauth actually entails.
-func (c *Context) WithReauthHandler(f ReauthHandlerFunc) *Context {
- c.reauthHandler = f
- return c
-}
diff --git a/context_test.go b/context_test.go
deleted file mode 100644
index 2936526..0000000
--- a/context_test.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package gophercloud
-
-import (
- "testing"
-)
-
-func TestProviderRegistry(t *testing.T) {
- c := TestContext()
-
- _, err := c.ProviderByName("aProvider")
- if err == nil {
- t.Error("Expected error when looking for a provider by non-existant name")
- return
- }
-
- err = c.RegisterProvider("aProvider", Provider{})
- if err != ErrConfiguration {
- t.Error("Unexpected error/nil when registering a provider w/out an auth endpoint\n %s", err)
- return
- }
-
- _ = c.RegisterProvider("aProvider", Provider{AuthEndpoint: "http://localhost/auth"})
- _, err = c.ProviderByName("aProvider")
- if err != nil {
- t.Error(err)
- return
- }
-}
diff --git a/errors.go b/errors.go
deleted file mode 100644
index 1719fd2..0000000
--- a/errors.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package gophercloud
-
-import (
- "fmt"
-)
-
-// ErrNotImplemented should be used only while developing new SDK features.
-// No established function or method will ever produce this error.
-var ErrNotImplemented = fmt.Errorf("Not implemented")
-
-// ErrProvider errors occur when attempting to reference an unsupported
-// provider. More often than not, this error happens due to a typo in
-// the name.
-var ErrProvider = fmt.Errorf("Missing or incorrect provider")
-
-// ErrCredentials errors happen when attempting to authenticate using a
-// set of credentials not recognized by the Authenticate() method.
-// For example, not providing a username or password when attempting to
-// authenticate against an Identity V2 API.
-var ErrCredentials = fmt.Errorf("Missing or incomplete credentials")
-
-// ErrConfiguration errors happen when attempting to add a new provider, and
-// the provider added lacks a correct or consistent configuration.
-// For example, all providers must expose at least an Identity V2 API
-// for authentication; if this endpoint isn't specified, you may receive
-// this error when attempting to register it against a context.
-var ErrConfiguration = fmt.Errorf("Missing or incomplete configuration")
-
-// ErrEndpoint errors happen when no endpoint with the desired characteristics
-// exists in the service catalog. This can also happen if your tenant lacks
-// adequate permissions to access a given endpoint.
-var ErrEndpoint = fmt.Errorf("Missing endpoint, or insufficient privileges to access endpoint")
-
-// ErrError errors happen when you attempt to discover the response code
-// 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/flavors.go b/flavors.go
deleted file mode 100644
index eb864d5..0000000
--- a/flavors.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package gophercloud
-
-import (
- "github.com/racker/perigee"
-)
-
-// See CloudServersProvider interface for details.
-func (gsp *genericServersProvider) ListFlavors() ([]Flavor, error) {
- var fs []Flavor
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := gsp.endpoint + "/flavors/detail"
- return perigee.Get(url, perigee.Options{
- CustomClient: gsp.context.httpClient,
- Results: &struct{ Flavors *[]Flavor }{&fs},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
- return fs, err
-}
-
-// FlavorLink provides a reference to a flavor by either ID or by direct URL.
-// Some services use just the ID, others use just the URL.
-// This structure provides a common means of expressing both in a single field.
-type FlavorLink struct {
- Id string `json:"id"`
- Links []Link `json:"links"`
-}
-
-// Flavor records represent (virtual) hardware configurations for server resources in a region.
-//
-// The Id field contains the flavor's unique identifier.
-// For example, this identifier will be useful when specifying which hardware configuration to use for a new server instance.
-//
-// The Disk and Ram fields provide a measure of storage space offered by the flavor, in GB and MB, respectively.
-//
-// The Name field provides a human-readable moniker for the flavor.
-//
-// Swap indicates how much space is reserved for swap.
-// If not provided, this field will be set to 0.
-//
-// VCpus indicates how many (virtual) CPUs are available for this flavor.
-type Flavor struct {
- OsFlvDisabled bool `json:"OS-FLV-DISABLED:disabled"`
- Disk int `json:"disk"`
- Id string `json:"id"`
- Links []Link `json:"links"`
- Name string `json:"name"`
- Ram int `json:"ram"`
- RxTxFactor float64 `json:"rxtx_factor"`
- Swap int `json:"swap"`
- VCpus int `json:"vcpus"`
-}
diff --git a/floating_ips.go b/floating_ips.go
deleted file mode 100644
index 1163667..0000000
--- a/floating_ips.go
+++ /dev/null
@@ -1,88 +0,0 @@
-package gophercloud
-
-import (
- "errors"
- "fmt"
- "github.com/racker/perigee"
-)
-
-func (gsp *genericServersProvider) ListFloatingIps() ([]FloatingIp, error) {
- var fips []FloatingIp
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := gsp.endpoint + "/os-floating-ips"
- return perigee.Get(url, perigee.Options{
- CustomClient: gsp.context.httpClient,
- Results: &struct {
- FloatingIps *[]FloatingIp `json:"floating_ips"`
- }{&fips},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
- return fips, err
-}
-
-func (gsp *genericServersProvider) CreateFloatingIp(pool string) (FloatingIp, error) {
- fip := new(FloatingIp)
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := gsp.endpoint + "/os-floating-ips"
- return perigee.Post(url, perigee.Options{
- CustomClient: gsp.context.httpClient,
- ReqBody: map[string]string{
- "pool": pool,
- },
- Results: &struct {
- FloatingIp **FloatingIp `json:"floating_ip"`
- }{&fip},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
-
- if fip.Ip == "" {
- return *fip, errors.New("Error creating floating IP")
- }
-
- return *fip, err
-}
-
-func (gsp *genericServersProvider) AssociateFloatingIp(serverId string, ip FloatingIp) error {
- return gsp.context.WithReauth(gsp.access, func() error {
- ep := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, serverId)
- return perigee.Post(ep, perigee.Options{
- CustomClient: gsp.context.httpClient,
- ReqBody: map[string](map[string]string){
- "addFloatingIp": map[string]string{"address": ip.Ip},
- },
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- OkCodes: []int{202},
- })
- })
-}
-
-func (gsp *genericServersProvider) DeleteFloatingIp(ip FloatingIp) error {
- return gsp.context.WithReauth(gsp.access, func() error {
- ep := fmt.Sprintf("%s/os-floating-ips/%d", gsp.endpoint, ip.Id)
- return perigee.Delete(ep, perigee.Options{
- CustomClient: gsp.context.httpClient,
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- OkCodes: []int{202},
- })
- })
-}
-
-type FloatingIp struct {
- Id int `json:"id"`
- Pool string `json:"pool"`
- Ip string `json:"ip"`
- FixedIp string `json:"fixed_ip"`
- InstanceId string `json:"instance_id"`
-}
diff --git a/global_context.go b/global_context.go
deleted file mode 100644
index 89d283b..0000000
--- a/global_context.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package gophercloud
-
-import (
- "github.com/racker/perigee"
-)
-
-// globalContext is the, well, "global context."
-// Most of this SDK is written in a manner to facilitate easier testing,
-// which doesn't require all the configuration a real-world application would require.
-// However, for real-world deployments, applications should be able to rely on a consistent configuration of providers, etc.
-var globalContext *Context
-
-// providers is the set of supported providers.
-var providers = map[string]Provider{
- "rackspace-us": {
- AuthEndpoint: "https://identity.api.rackspacecloud.com/v2.0/tokens",
- },
- "rackspace-uk": {
- AuthEndpoint: "https://lon.identity.api.rackspacecloud.com/v2.0/tokens",
- },
-}
-
-// Initialize the global context to sane configuration.
-// The Go runtime ensures this function is called before main(),
-// thus guaranteeing proper configuration before your application ever runs.
-func init() {
- globalContext = TestContext()
- for name, descriptor := range providers {
- globalContext.RegisterProvider(name, descriptor)
- }
-}
-
-// Authenticate() grants access to the OpenStack-compatible provider API.
-//
-// Providers are identified through a unique key string.
-// Specifying an unsupported provider will result in an ErrProvider error.
-// However, you may also specify a custom Identity API URL.
-// Any provider name that contains the characters "://", in that order, will be treated as a custom Identity API URL.
-// Custom URLs, important for private cloud deployments, overrides all provider configurations.
-//
-// The supplied AuthOptions instance allows the client to specify only those credentials
-// relevant for the authentication request. At present, support exists for OpenStack
-// Identity V2 API only; support for V3 will become available as soon as documentation for it
-// becomes readily available.
-//
-// For Identity V2 API requirements, you must provide at least the Username and Password
-// options. The TenantId field is optional, and defaults to "".
-func Authenticate(provider string, options AuthOptions) (*Access, error) {
- return globalContext.Authenticate(provider, options)
-}
-
-// Instantiates a Cloud Servers object for the provider given.
-func ServersApi(acc AccessProvider, criteria ApiCriteria) (CloudServersProvider, error) {
- return globalContext.ServersApi(acc, criteria)
-}
-
-// ActualResponseCode inspects a returned error, and discovers the actual response actual
-// response code that caused the error to be raised.
-func ActualResponseCode(e error) (int, error) {
- if err, typeOk := e.(*perigee.UnexpectedResponseCodeError); typeOk {
- return err.Actual, nil
- } else if err, typeOk := e.(*AuthError); typeOk{
- return err.StatusCode, nil
- }
-
- return 0, ErrError
-}
diff --git a/images.go b/images.go
deleted file mode 100644
index a23e0bb..0000000
--- a/images.go
+++ /dev/null
@@ -1,106 +0,0 @@
-package gophercloud
-
-import (
- "github.com/racker/perigee"
-)
-
-// See the CloudImagesProvider interface for details.
-func (gsp *genericServersProvider) ListImages() ([]Image, error) {
- var is []Image
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := gsp.endpoint + "/images/detail"
- return perigee.Get(url, perigee.Options{
- CustomClient: gsp.context.httpClient,
- Results: &struct{ Images *[]Image }{&is},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
- return is, err
-}
-
-func (gsp *genericServersProvider) ImageById(id string) (*Image, error) {
- var is *Image
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := gsp.endpoint + "/images/" + id
- return perigee.Get(url, perigee.Options{
- CustomClient: gsp.context.httpClient,
- Results: &struct{ Image **Image }{&is},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
- return is, err
-}
-
-func (gsp *genericServersProvider) DeleteImageById(id string) error {
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := gsp.endpoint + "/images/" + id
- _, err := perigee.Request("DELETE", url, perigee.Options{
- CustomClient: gsp.context.httpClient,
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- return err
- })
- return err
-}
-
-// ImageLink provides a reference to a image by either ID or by direct URL.
-// Some services use just the ID, others use just the URL.
-// This structure provides a common means of expressing both in a single field.
-type ImageLink struct {
- Id string `json:"id"`
- Links []Link `json:"links"`
-}
-
-// Image is used for JSON (un)marshalling.
-// It provides a description of an OS image.
-//
-// The Id field contains the image's unique identifier.
-// For example, this identifier will be useful for specifying which operating system to install on a new server instance.
-//
-// The MinDisk and MinRam fields specify the minimum resources a server must provide to be able to install the image.
-//
-// The Name field provides a human-readable moniker for the OS image.
-//
-// The Progress and Status fields indicate image-creation status.
-// Any usable image will have 100% progress.
-//
-// The Updated field indicates the last time this image was changed.
-//
-// OsDcfDiskConfig indicates the server's boot volume configuration.
-// Valid values are:
-// AUTO
-// ----
-// The server is built with a single partition the size of the target flavor disk.
-// The file system is automatically adjusted to fit the entire partition.
-// This keeps things simple and automated.
-// AUTO is valid only for images and servers with a single partition that use the EXT3 file system.
-// This is the default setting for applicable Rackspace base images.
-//
-// MANUAL
-// ------
-// The server is built using whatever partition scheme and file system is in the source image.
-// If the target flavor disk is larger,
-// the remaining disk space is left unpartitioned.
-// This enables images to have non-EXT3 file systems, multiple partitions, and so on,
-// and enables you to manage the disk configuration.
-//
-type Image struct {
- Created string `json:"created"`
- Id string `json:"id"`
- Links []Link `json:"links"`
- MinDisk int `json:"minDisk"`
- MinRam int `json:"minRam"`
- Name string `json:"name"`
- Progress int `json:"progress"`
- Status string `json:"status"`
- Updated string `json:"updated"`
- OsDcfDiskConfig string `json:"OS-DCF:diskConfig"`
-}
diff --git a/interfaces.go b/interfaces.go
deleted file mode 100644
index 71c0be4..0000000
--- a/interfaces.go
+++ /dev/null
@@ -1,229 +0,0 @@
-package gophercloud
-
-// AccessProvider instances encapsulate a Keystone authentication interface.
-type AccessProvider interface {
- // FirstEndpointUrlByCriteria searches through the service catalog for the first
- // matching entry endpoint fulfilling the provided criteria. If nothing found,
- // return "". Otherwise, return either the public or internal URL for the
- // endpoint, depending on both its existence and the setting of the ApiCriteria.UrlChoice
- // field.
- FirstEndpointUrlByCriteria(ApiCriteria) string
-
- // AuthToken provides a copy of the current authentication token for the user's credentials.
- // Note that AuthToken() will not automatically refresh an expired token.
- AuthToken() string
-
- // Revoke allows you to terminate any program's access to the OpenStack API by token ID.
- Revoke(string) error
-
- // Reauthenticate attempts to acquire a new authentication token, if the feature is enabled by
- // AuthOptions.AllowReauth.
- Reauthenticate() error
-}
-
-// ServiceCatalogerIdentityV2 interface provides direct access to the service catalog as offered by the Identity V2 API.
-// We regret we need to fracture the namespace of what should otherwise be a simple concept; however,
-// the OpenStack community saw fit to render V3's service catalog completely incompatible with V2.
-type ServiceCatalogerForIdentityV2 interface {
- V2ServiceCatalog() []CatalogEntry
-}
-
-// CloudServersProvider instances encapsulate a Cloud Servers API, should one exist in the service catalog
-// for your provider.
-type CloudServersProvider interface {
- // Servers
-
- // ListServers provides a complete list of servers hosted by the user
- // in a given region. This function differs from ListServersLinksOnly()
- // in that it returns all available details for each server returned.
- ListServers() ([]Server, error)
-
- // ListServers provides a complete list of servers hosted by the user
- // in a given region. This function differs from ListServers() in that
- // it returns only IDs and links to each server returned.
- //
- // This function should be used only under certain circumstances.
- // It's most useful for checking to see if a server with a given ID exists,
- // or that you have permission to work with that server. It's also useful
- // when the cost of retrieving the server link list plus the overhead of manually
- // invoking ServerById() for each of the servers you're interested in is less than
- // just calling ListServers() to begin with. This may be a consideration, for
- // example, with mobile applications.
- //
- // In other cases, you probably should just call ListServers() and cache the
- // results to conserve overall bandwidth and reduce your access rate on the API.
- ListServersLinksOnly() ([]Server, error)
-
- // ServerById will retrieve a detailed server description given the unique ID
- // of a server. The ID can be returned by either ListServers() or by ListServersLinksOnly().
- ServerById(id string) (*Server, error)
-
- // CreateServer requests a new server to be created by the cloud server provider.
- // The user must pass in a pointer to an initialized NewServerContainer structure.
- // Please refer to the NewServerContainer documentation for more details.
- //
- // If the NewServer structure's AdminPass is empty (""), a password will be
- // automatically generated by your OpenStack provider, and returned through the
- // AdminPass field of the result. Take care, however; this will be the only time
- // this happens. No other means exists in the public API to acquire a password
- // for a pre-existing server. If you lose it, you'll need to call SetAdminPassword()
- // to set a new one.
- CreateServer(ns NewServer) (*NewServer, error)
-
- // DeleteServerById requests that the server with the assigned ID be removed
- // from your account. The delete happens asynchronously.
- DeleteServerById(id string) error
-
- // SetAdminPassword requests that the server with the specified ID have its
- // administrative password changed. For Linux, BSD, or other POSIX-like
- // system, this password corresponds to the root user. For Windows machines,
- // the Administrator password will be affected instead.
- SetAdminPassword(id string, pw string) error
-
- // ResizeServer can be a short-hand for RebuildServer where only the size of the server
- // changes. Note that after the resize operation is requested, you will need to confirm
- // the resize has completed for changes to take effect permanently. Changes will assume
- // to be confirmed even without an explicit confirmation after 24 hours from the initial
- // request.
- ResizeServer(id, newName, newFlavor, newDiskConfig string) error
-
- // RevertResize will reject a server's resized configuration, thus
- // rolling back to the original server.
- RevertResize(id string) error
-
- // ConfirmResizeServer will acknowledge a server's resized configuration.
- ConfirmResize(id string) error
-
- // RebootServer requests that the server with the specified ID be rebooted.
- // Two reboot mechanisms exist.
- //
- // - Hard. This will physically power-cycle the unit.
- // - Soft. This will attempt to use the server's software-based mechanisms to restart
- // the machine. E.g., "shutdown -r now" on Linux.
- RebootServer(id string, hard bool) error
-
- // RescueServer requests that the server with the specified ID be placed into
- // a state of maintenance. The server instance is replaced with a new instance,
- // of the same flavor and image. This new image will have the boot volume of the
- // original machine mounted as a secondary device, so that repair and administration
- // may occur. Use UnrescueServer() to restore the server to its previous state.
- // Note also that many providers will impose a time limit for how long a server may
- // exist in rescue mode! Consult the API documentation for your provider for
- // details.
- RescueServer(id string) (string, error)
-
- // UnrescueServer requests that a server in rescue state be placed into its nominal
- // operating state.
- UnrescueServer(id string) error
-
- // UpdateServer alters one or more fields of the identified server's Server record.
- // However, not all fields may be altered. Presently, only Name, AccessIPv4, and
- // AccessIPv6 fields may be altered. If unspecified, or set to an empty or zero
- // value, the corresponding field remains unaltered.
- //
- // This function returns the new set of server details if successful.
- UpdateServer(id string, newValues NewServerSettings) (*Server, error)
-
- // RebuildServer reprovisions a server to the specifications given by the
- // NewServer structure. The following fields are guaranteed to be recognized:
- //
- // Name (required) AccessIPv4
- // imageRef (required) AccessIPv6
- // AdminPass (required) Metadata
- // Personality
- //
- // Other providers may reserve the right to act on additional fields.
- RebuildServer(id string, ns NewServer) (*Server, error)
-
- // CreateImage will create a new image from the specified server id returning the id of the new image.
- CreateImage(id string, ci CreateImage) (string, 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)
-
- // 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)
-
- // ListFloatingIps yields the list of all floating IP addresses allocated to the current project.
- ListFloatingIps() ([]FloatingIp, error)
-
- // CreateFloatingIp allocates a new IP from the named pool to the current project.
- CreateFloatingIp(pool string) (FloatingIp, error)
-
- // DeleteFloatingIp returns the specified IP from the current project to the pool.
- DeleteFloatingIp(ip FloatingIp) error
-
- // AssociateFloatingIp associates the given floating IP to the given server id.
- AssociateFloatingIp(serverId string, ip FloatingIp) error
-
- // Images
-
- // ListImages yields the list of available operating system images. This function
- // returns full details for each image, if available.
- ListImages() ([]Image, error)
-
- // ImageById yields details about a specific image.
- ImageById(id string) (*Image, error)
-
- // DeleteImageById will delete the specific image.
- DeleteImageById(id string) error
-
- // Flavors
-
- // ListFlavors yields the list of available system flavors. This function
- // returns full details for each flavor, if available.
- ListFlavors() ([]Flavor, error)
-
- // KeyPairs
-
- // ListKeyPairs yields the list of available keypairs.
- ListKeyPairs() ([]KeyPair, error)
-
- // CreateKeyPairs will create or generate a new keypair.
- CreateKeyPair(nkp NewKeyPair) (KeyPair, error)
-
- // DeleteKeyPair wil delete a keypair.
- DeleteKeyPair(name string) error
-
- // ShowKeyPair will yield the named keypair.
- ShowKeyPair(name string) (KeyPair, error)
-
- // ListSecurityGroups provides a listing of security groups for the tenant.
- // This method works only if the provider supports the os-security-groups extension.
- ListSecurityGroups() ([]SecurityGroup, error)
-
- // CreateSecurityGroup lets a tenant create a new security group.
- // Only the SecurityGroup fields which are specified will be marshalled to the API.
- // This method works only if the provider supports the os-security-groups extension.
- CreateSecurityGroup(desired SecurityGroup) (*SecurityGroup, error)
-
- // ListSecurityGroupsByServerId provides a list of security groups which apply to the indicated server.
- // This method works only if the provider supports the os-security-groups extension.
- ListSecurityGroupsByServerId(id string) ([]SecurityGroup, error)
-
- // SecurityGroupById returns a security group corresponding to the provided ID number.
- // This method works only if the provider supports the os-security-groups extension.
- SecurityGroupById(id int) (*SecurityGroup, error)
-
- // DeleteSecurityGroupById disposes of a security group corresponding to the provided ID number.
- // This method works only if the provider supports the os-security-groups extension.
- DeleteSecurityGroupById(id int) error
-
- // ListDefaultSGRules lists default security group rules.
- // This method only works if the provider supports the os-security-groups-default-rules extension.
- ListDefaultSGRules() ([]SGRule, error)
-
- // CreateDefaultSGRule creates a default security group rule.
- // This method only works if the provider supports the os-security-groups-default-rules extension.
- CreateDefaultSGRule(SGRule) (*SGRule, error)
-
- // GetSGRule obtains information for a specified security group rule.
- // This method only works if the provider supports the os-security-groups-default-rules extension.
- GetSGRule(string) (*SGRule, error)
-}
diff --git a/keypairs.go b/keypairs.go
deleted file mode 100644
index 9ab8ea7..0000000
--- a/keypairs.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package gophercloud
-
-import (
- "github.com/racker/perigee"
-)
-
-// See the CloudImagesProvider interface for details.
-func (gsp *genericServersProvider) ListKeyPairs() ([]KeyPair, error) {
- type KeyPairs struct {
- KeyPairs []struct {
- KeyPair KeyPair `json:"keypair"`
- } `json:"keypairs"`
- }
-
- var kp KeyPairs
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := gsp.endpoint + "/os-keypairs"
- return perigee.Get(url, perigee.Options{
- CustomClient: gsp.context.httpClient,
- Results: &kp,
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
-
- // Flatten out the list of keypairs
- var keypairs []KeyPair
- for _, k := range kp.KeyPairs {
- keypairs = append(keypairs, k.KeyPair)
- }
- return keypairs, err
-}
-
-func (gsp *genericServersProvider) CreateKeyPair(nkp NewKeyPair) (KeyPair, error) {
- var kp KeyPair
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := gsp.endpoint + "/os-keypairs"
- return perigee.Post(url, perigee.Options{
- ReqBody: &struct {
- KeyPair *NewKeyPair `json:"keypair"`
- }{&nkp},
- CustomClient: gsp.context.httpClient,
- Results: &struct{ KeyPair *KeyPair }{&kp},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
- return kp, err
-}
-
-// See the CloudImagesProvider interface for details.
-func (gsp *genericServersProvider) DeleteKeyPair(name string) error {
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := gsp.endpoint + "/os-keypairs/" + name
- return perigee.Delete(url, perigee.Options{
- CustomClient: gsp.context.httpClient,
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- OkCodes: []int{202},
- })
- })
- return err
-}
-
-func (gsp *genericServersProvider) ShowKeyPair(name string) (KeyPair, error) {
- var kp KeyPair
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := gsp.endpoint + "/os-keypairs/" + name
- return perigee.Get(url, perigee.Options{
- CustomClient: gsp.context.httpClient,
- Results: &struct{ KeyPair *KeyPair }{&kp},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
- return kp, err
-}
-
-type KeyPair struct {
- FingerPrint string `json:"fingerprint"`
- Name string `json:"name"`
- PrivateKey string `json:"private_key,omitempty"`
- PublicKey string `json:"public_key"`
- UserID string `json:"user_id,omitempty"`
-}
-
-type NewKeyPair struct {
- Name string `json:"name"`
- PublicKey string `json:"public_key,omitempty"`
-}
diff --git a/osutil/auth.go b/osutil/auth.go
deleted file mode 100644
index 409846c..0000000
--- a/osutil/auth.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package osutil
-
-import (
- "fmt"
- "github.com/rackspace/gophercloud"
- "os"
-)
-
-var (
- nilOptions = gophercloud.AuthOptions{}
-
- // ErrNoAuthUrl errors occur when the value of the OS_AUTH_URL environment variable cannot be determined.
- ErrNoAuthUrl = fmt.Errorf("Environment variable OS_AUTH_URL needs to be set.")
-
- // ErrNoUsername errors occur when the value of the OS_USERNAME environment variable cannot be determined.
- ErrNoUsername = fmt.Errorf("Environment variable OS_USERNAME needs to be set.")
-
- // ErrNoPassword errors occur when the value of the OS_PASSWORD environment variable cannot be determined.
- ErrNoPassword = fmt.Errorf("Environment variable OS_PASSWORD or OS_API_KEY needs to be set.")
-)
-
-// AuthOptions fills out a gophercloud.AuthOptions structure with the settings found on the various OpenStack
-// OS_* environment variables. The following variables provide sources of truth: OS_AUTH_URL, OS_USERNAME,
-// OS_PASSWORD, OS_TENANT_ID, and OS_TENANT_NAME. Of these, OS_USERNAME, OS_PASSWORD, and OS_AUTH_URL must
-// have settings, or an error will result. OS_TENANT_ID and OS_TENANT_NAME are optional.
-//
-// The value of OS_AUTH_URL will be returned directly to the caller, for subsequent use in
-// gophercloud.Authenticate()'s Provider parameter. This function will not interpret the value of OS_AUTH_URL,
-// so as a convenient extention, you may set OS_AUTH_URL to, e.g., "rackspace-uk", or any other Gophercloud-recognized
-// provider shortcuts. For broad compatibility, especially with local installations, you should probably
-// avoid the temptation to do this.
-func AuthOptions() (string, gophercloud.AuthOptions, error) {
- provider := os.Getenv("OS_AUTH_URL")
- username := os.Getenv("OS_USERNAME")
- password := os.Getenv("OS_PASSWORD")
- tenantId := os.Getenv("OS_TENANT_ID")
- tenantName := os.Getenv("OS_TENANT_NAME")
-
- if provider == "" {
- return "", nilOptions, ErrNoAuthUrl
- }
-
- if username == "" {
- return "", nilOptions, ErrNoUsername
- }
-
- if password == "" {
- return "", nilOptions, ErrNoPassword
- }
-
- ao := gophercloud.AuthOptions{
- Username: username,
- Password: password,
- TenantId: tenantId,
- TenantName: tenantName,
- }
-
- return provider, ao, nil
-}
diff --git a/osutil/region.go b/osutil/region.go
deleted file mode 100644
index f7df507..0000000
--- a/osutil/region.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package osutil
-
-import "os"
-
-// Region provides a means of querying the OS_REGION_NAME environment variable.
-// At present, you may also use os.Getenv("OS_REGION_NAME") as well.
-func Region() string {
- return os.Getenv("OS_REGION_NAME")
-}
diff --git a/reauth.go b/reauth.go
deleted file mode 100644
index 342aca4..0000000
--- a/reauth.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package gophercloud
-
-import (
- "github.com/racker/perigee"
-)
-
-// WithReauth wraps a Perigee request fragment with logic to perform re-authentication
-// if it's deemed necessary.
-//
-// Do not confuse this function with WithReauth()! Although they work together to support reauthentication,
-// WithReauth() actually contains the decision-making logic to determine when to perform a reauth,
-// while WithReauthHandler() is used to configure what a reauth actually entails.
-func (c *Context) WithReauth(ap AccessProvider, f func() error) error {
- err := f()
- cause, ok := err.(*perigee.UnexpectedResponseCodeError)
- if ok && cause.Actual == 401 {
- err = c.reauthHandler(ap)
- if err == nil {
- err = f()
- }
- }
- return err
-}
-
-// This is like WithReauth above but returns a perigee Response object
-func (c *Context) ResponseWithReauth(ap AccessProvider, f func() (*perigee.Response, error)) (*perigee.Response, error) {
- response, err := f()
- cause, ok := err.(*perigee.UnexpectedResponseCodeError)
- if ok && cause.Actual == 401 {
- err = c.reauthHandler(ap)
- if err == nil {
- response, err = f()
- }
- }
- return response, err
-}
diff --git a/reauth_test.go b/reauth_test.go
deleted file mode 100644
index e3501b8..0000000
--- a/reauth_test.go
+++ /dev/null
@@ -1,133 +0,0 @@
-package gophercloud
-
-import (
- "github.com/racker/perigee"
- "testing"
-)
-
-// This reauth-handler does nothing, and returns no error.
-func doNothing(_ AccessProvider) error {
- return nil
-}
-
-func TestOtherErrorsPropegate(t *testing.T) {
- calls := 0
- c := TestContext().WithReauthHandler(doNothing)
-
- err := c.WithReauth(nil, func() error {
- calls++
- return &perigee.UnexpectedResponseCodeError{
- Expected: []int{204},
- Actual: 404,
- }
- })
-
- if err == nil {
- t.Error("Expected MyError to be returned; got nil instead.")
- return
- }
- if _, ok := err.(*perigee.UnexpectedResponseCodeError); !ok {
- t.Error("Expected UnexpectedResponseCodeError; got %#v", err)
- return
- }
- if calls != 1 {
- t.Errorf("Expected the body to be invoked once; found %d calls instead", calls)
- return
- }
-}
-
-func Test401ErrorCausesBodyInvokation2ndTime(t *testing.T) {
- calls := 0
- c := TestContext().WithReauthHandler(doNothing)
-
- err := c.WithReauth(nil, func() error {
- calls++
- return &perigee.UnexpectedResponseCodeError{
- Expected: []int{204},
- Actual: 401,
- }
- })
-
- if err == nil {
- t.Error("Expected MyError to be returned; got nil instead.")
- return
- }
- if calls != 2 {
- t.Errorf("Expected the body to be invoked once; found %d calls instead", calls)
- return
- }
-}
-
-func TestReauthAttemptShouldHappen(t *testing.T) {
- calls := 0
- c := TestContext().WithReauthHandler(func(_ AccessProvider) error {
- calls++
- return nil
- })
- c.WithReauth(nil, func() error {
- return &perigee.UnexpectedResponseCodeError{
- Expected: []int{204},
- Actual: 401,
- }
- })
-
- if calls != 1 {
- t.Errorf("Expected Reauthenticator to be called once; found %d instead", calls)
- return
- }
-}
-
-type MyError struct{}
-
-func (*MyError) Error() string {
- return "MyError instance"
-}
-
-func TestReauthErrorShouldPropegate(t *testing.T) {
- c := TestContext().WithReauthHandler(func(_ AccessProvider) error {
- return &MyError{}
- })
-
- err := c.WithReauth(nil, func() error {
- return &perigee.UnexpectedResponseCodeError{
- Expected: []int{204},
- Actual: 401,
- }
- })
-
- if _, ok := err.(*MyError); !ok {
- t.Errorf("Expected a MyError; got %#v", err)
- return
- }
-}
-
-type MyAccess struct{}
-
-func (my *MyAccess) FirstEndpointUrlByCriteria(ApiCriteria) string {
- return ""
-}
-func (my *MyAccess) AuthToken() string {
- return ""
-}
-func (my *MyAccess) Revoke(string) error {
- return nil
-}
-func (my *MyAccess) Reauthenticate() error {
- return nil
-}
-
-func TestReauthHandlerUsesSameAccessProvider(t *testing.T) {
- fakeAccess := &MyAccess{}
- c := TestContext().WithReauthHandler(func(acc AccessProvider) error {
- if acc != fakeAccess {
- t.Errorf("Expected acc = fakeAccess")
- }
- return nil
- })
- c.WithReauth(fakeAccess, func() error {
- return &perigee.UnexpectedResponseCodeError{
- Expected: []int{204},
- Actual: 401,
- }
- })
-}
diff --git a/servers.go b/servers.go
deleted file mode 100644
index c102169..0000000
--- a/servers.go
+++ /dev/null
@@ -1,736 +0,0 @@
-// TODO(sfalvo): Remove Rackspace-specific Server structure fields and refactor them into a provider-specific access method.
-// Be sure to update godocs accordingly.
-
-package gophercloud
-
-import (
- "fmt"
- "github.com/racker/perigee"
- "strings"
-)
-
-// genericServersProvider structures provide the implementation for generic OpenStack-compatible
-// CloudServersProvider interfaces.
-type genericServersProvider struct {
- // endpoint refers to the provider's API endpoint base URL. This will be used to construct
- // and issue queries.
- endpoint string
-
- // Test context (if any) in which to issue requests.
- context *Context
-
- // access associates this API provider with a set of credentials,
- // which may be automatically renewed if they near expiration.
- access AccessProvider
-}
-
-// See the CloudServersProvider interface for details.
-func (gcp *genericServersProvider) ListServersLinksOnly() ([]Server, error) {
- var ss []Server
-
- err := gcp.context.WithReauth(gcp.access, func() error {
- url := gcp.endpoint + "/servers"
- return perigee.Get(url, perigee.Options{
- CustomClient: gcp.context.httpClient,
- Results: &struct{ Servers *[]Server }{&ss},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gcp.access.AuthToken(),
- },
- })
- })
- return ss, err
-}
-
-// See the CloudServersProvider interface for details.
-func (gcp *genericServersProvider) ListServers() ([]Server, error) {
- var ss []Server
-
- err := gcp.context.WithReauth(gcp.access, func() error {
- url := gcp.endpoint + "/servers/detail"
- return perigee.Get(url, perigee.Options{
- CustomClient: gcp.context.httpClient,
- Results: &struct{ Servers *[]Server }{&ss},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gcp.access.AuthToken(),
- },
- })
- })
- return ss, err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) ServerById(id string) (*Server, error) {
- var s *Server
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := gsp.endpoint + "/servers/" + id
- return perigee.Get(url, perigee.Options{
- Results: &struct{ Server **Server }{&s},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- OkCodes: []int{200},
- })
- })
- return s, err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) CreateServer(ns NewServer) (*NewServer, error) {
- var s *NewServer
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- ep := gsp.endpoint + "/servers"
- return perigee.Post(ep, perigee.Options{
- ReqBody: &struct {
- Server *NewServer `json:"server"`
- }{&ns},
- Results: &struct{ Server **NewServer }{&s},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- OkCodes: []int{202},
- })
- })
-
- return s, err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) DeleteServerById(id string) error {
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := gsp.endpoint + "/servers/" + id
- return perigee.Delete(url, perigee.Options{
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- OkCodes: []int{204},
- })
- })
- return err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) SetAdminPassword(id, pw string) error {
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
- return perigee.Post(url, perigee.Options{
- ReqBody: &struct {
- ChangePassword struct {
- AdminPass string `json:"adminPass"`
- } `json:"changePassword"`
- }{
- struct {
- AdminPass string `json:"adminPass"`
- }{pw},
- },
- OkCodes: []int{202},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
- return err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) ResizeServer(id, newName, newFlavor, newDiskConfig string) error {
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
- rr := ResizeRequest{
- Name: newName,
- FlavorRef: newFlavor,
- DiskConfig: newDiskConfig,
- }
- return perigee.Post(url, perigee.Options{
- ReqBody: &struct {
- Resize ResizeRequest `json:"resize"`
- }{rr},
- OkCodes: []int{202},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
- return err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) RevertResize(id string) error {
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
- return perigee.Post(url, perigee.Options{
- ReqBody: &struct {
- RevertResize *int `json:"revertResize"`
- }{nil},
- OkCodes: []int{202},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
- return err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) ConfirmResize(id string) error {
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
- return perigee.Post(url, perigee.Options{
- ReqBody: &struct {
- ConfirmResize *int `json:"confirmResize"`
- }{nil},
- OkCodes: []int{204},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
- return err
-}
-
-// See the CloudServersProvider interface for details
-func (gsp *genericServersProvider) RebootServer(id string, hard bool) error {
- return gsp.context.WithReauth(gsp.access, func() error {
- url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
- types := map[bool]string{false: "SOFT", true: "HARD"}
- return perigee.Post(url, perigee.Options{
- ReqBody: &struct {
- Reboot struct {
- Type string `json:"type"`
- } `json:"reboot"`
- }{
- struct {
- Type string `json:"type"`
- }{types[hard]},
- },
- OkCodes: []int{202},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- })
- })
-}
-
-// See the CloudServersProvider interface for details
-func (gsp *genericServersProvider) RescueServer(id string) (string, error) {
- var pw *string
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
- return perigee.Post(url, perigee.Options{
- ReqBody: &struct {
- Rescue string `json:"rescue"`
- }{"none"},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- Results: &struct {
- AdminPass **string `json:"adminPass"`
- }{&pw},
- })
- })
- return *pw, err
-}
-
-// See the CloudServersProvider interface for details
-func (gsp *genericServersProvider) UnrescueServer(id string) error {
- return gsp.context.WithReauth(gsp.access, func() error {
- url := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
- return perigee.Post(url, perigee.Options{
- ReqBody: &struct {
- Unrescue *int `json:"unrescue"`
- }{nil},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- OkCodes: []int{202},
- })
- })
-}
-
-// See the CloudServersProvider interface for details
-func (gsp *genericServersProvider) UpdateServer(id string, changes NewServerSettings) (*Server, error) {
- var svr *Server
- err := gsp.context.WithReauth(gsp.access, func() error {
- url := fmt.Sprintf("%s/servers/%s", gsp.endpoint, id)
- return perigee.Put(url, perigee.Options{
- ReqBody: &struct {
- Server NewServerSettings `json:"server"`
- }{changes},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- Results: &struct {
- Server **Server `json:"server"`
- }{&svr},
- })
- })
- return svr, err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) RebuildServer(id string, ns NewServer) (*Server, error) {
- var s *Server
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- ep := fmt.Sprintf("%s/servers/%s/action", gsp.endpoint, id)
- return perigee.Post(ep, perigee.Options{
- ReqBody: &struct {
- Rebuild *NewServer `json:"rebuild"`
- }{&ns},
- Results: &struct{ Server **Server }{&s},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- OkCodes: []int{202},
- })
- })
-
- 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
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) ListAddressesByNetwork(id, networkLabel string) (NetworkAddress, error) {
- pas := make(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)
- return perigee.Request("POST", ep, perigee.Options{
- ReqBody: &struct {
- CreateImage *CreateImage `json:"createImage"`
- }{&ci},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- OkCodes: []int{200, 202},
- })
- })
-
- if err != nil {
- return "", err
- }
- location, err := response.HttpResponse.Location()
- if err != nil {
- return "", err
- }
-
- // Return the last element of the location which is the image id
- locationArr := strings.Split(location.Path, "/")
- return locationArr[len(locationArr)-1], err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) ListSecurityGroups() ([]SecurityGroup, error) {
- var sgs []SecurityGroup
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- ep := fmt.Sprintf("%s/os-security-groups", gsp.endpoint)
- return perigee.Get(ep, perigee.Options{
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- Results: &struct {
- SecurityGroups *[]SecurityGroup `json:"security_groups"`
- }{&sgs},
- })
- })
- return sgs, err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) CreateSecurityGroup(desired SecurityGroup) (*SecurityGroup, error) {
- var actual *SecurityGroup
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- ep := fmt.Sprintf("%s/os-security-groups", gsp.endpoint)
- return perigee.Post(ep, perigee.Options{
- ReqBody: struct {
- AddSecurityGroup SecurityGroup `json:"security_group"`
- }{desired},
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- Results: &struct {
- SecurityGroup **SecurityGroup `json:"security_group"`
- }{&actual},
- })
- })
- return actual, err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) ListSecurityGroupsByServerId(id string) ([]SecurityGroup, error) {
- var sgs []SecurityGroup
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- ep := fmt.Sprintf("%s/servers/%s/os-security-groups", gsp.endpoint, id)
- return perigee.Get(ep, perigee.Options{
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- Results: &struct {
- SecurityGroups *[]SecurityGroup `json:"security_groups"`
- }{&sgs},
- })
- })
- return sgs, err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) SecurityGroupById(id int) (*SecurityGroup, error) {
- var actual *SecurityGroup
-
- err := gsp.context.WithReauth(gsp.access, func() error {
- ep := fmt.Sprintf("%s/os-security-groups/%d", gsp.endpoint, id)
- return perigee.Get(ep, perigee.Options{
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- Results: &struct {
- SecurityGroup **SecurityGroup `json:"security_group"`
- }{&actual},
- })
- })
- return actual, err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) DeleteSecurityGroupById(id int) error {
- err := gsp.context.WithReauth(gsp.access, func() error {
- ep := fmt.Sprintf("%s/os-security-groups/%d", gsp.endpoint, id)
- return perigee.Delete(ep, perigee.Options{
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- OkCodes: []int{202},
- })
- })
- return err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) ListDefaultSGRules() ([]SGRule, error) {
- var sgrs []SGRule
- err := gsp.context.WithReauth(gsp.access, func() error {
- ep := fmt.Sprintf("%s/os-security-group-default-rules", gsp.endpoint)
- return perigee.Get(ep, perigee.Options{
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- Results: &struct{Security_group_default_rules *[]SGRule}{&sgrs},
- })
- })
- return sgrs, err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) CreateDefaultSGRule(r SGRule) (*SGRule, error) {
- var sgr *SGRule
- err := gsp.context.WithReauth(gsp.access, func() error {
- ep := fmt.Sprintf("%s/os-security-group-default-rules", gsp.endpoint)
- return perigee.Post(ep, perigee.Options{
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- Results: &struct{Security_group_default_rule **SGRule}{&sgr},
- ReqBody: struct{Security_group_default_rule SGRule `json:"security_group_default_rule"`}{r},
- })
- })
- return sgr, err
-}
-
-// See the CloudServersProvider interface for details.
-func (gsp *genericServersProvider) GetSGRule(id string) (*SGRule, error) {
- var sgr *SGRule
- err := gsp.context.WithReauth(gsp.access, func() error {
- ep := fmt.Sprintf("%s/os-security-group-default-rules/%s", gsp.endpoint, id)
- return perigee.Get(ep, perigee.Options{
- MoreHeaders: map[string]string{
- "X-Auth-Token": gsp.access.AuthToken(),
- },
- Results: &struct{Security_group_default_rule **SGRule}{&sgr},
- })
- })
- return sgr, err
-}
-
-// SecurityGroup provides a description of a security group, including all its rules.
-type SecurityGroup struct {
- Description string `json:"description,omitempty"`
- Id int `json:"id,omitempty"`
- Name string `json:"name,omitempty"`
- Rules []SGRule `json:"rules,omitempty"`
- TenantId string `json:"tenant_id,omitempty"`
-}
-
-// SGRule encapsulates a single rule which applies to a security group.
-// This definition is just a guess, based on the documentation found in another extension here: http://docs.openstack.org/api/openstack-compute/2/content/GET_os-security-group-default-rules-v2_listSecGroupDefaultRules_v2__tenant_id__os-security-group-rules_ext-os-security-group-default-rules.html
-type SGRule struct {
- FromPort int `json:"from_port,omitempty"`
- Id int `json:"id,omitempty"`
- IpProtocol string `json:"ip_protocol,omitempty"`
- IpRange map[string]interface{} `json:"ip_range,omitempty"`
- ToPort int `json:"to_port,omitempty"`
-}
-
-// RaxBandwidth provides measurement of server bandwidth consumed over a given audit interval.
-type RaxBandwidth struct {
- AuditPeriodEnd string `json:"audit_period_end"`
- AuditPeriodStart string `json:"audit_period_start"`
- BandwidthInbound int64 `json:"bandwidth_inbound"`
- BandwidthOutbound int64 `json:"bandwidth_outbound"`
- Interface string `json:"interface"`
-}
-
-// A VersionedAddress denotes either an IPv4 or IPv6 (depending on version indicated)
-// address.
-type VersionedAddress struct {
- Addr string `json:"addr"`
- Version int `json:"version"`
-}
-
-// An AddressSet provides a set of public and private IP addresses for a resource.
-// Each address has a version to identify if IPv4 or IPv6.
-type AddressSet struct {
- Public []VersionedAddress `json:"public"`
- 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.
-//
-// Addresses provides addresses for any attached isolated networks.
-// The version field indicates whether the IP address is version 4 or 6.
-//
-// Created tells when the server entity was created.
-//
-// The Flavor field includes the flavor ID and flavor links.
-//
-// The compute provisioning algorithm has an anti-affinity property that
-// attempts to spread customer VMs across hosts.
-// Under certain situations,
-// VMs from the same customer might be placed on the same host.
-// The HostId field represents the host your server runs on and
-// can be used to determine this scenario if it is relevant to your application.
-// Note that HostId is unique only per account; it is not globally unique.
-//
-// Id provides the server's unique identifier.
-// This field must be treated opaquely.
-//
-// Image indicates which image is installed on the server.
-//
-// Links provides one or more means of accessing the server.
-//
-// Metadata provides a small key-value store for application-specific information.
-//
-// Name provides a human-readable name for the server.
-//
-// Progress indicates how far along it is towards being provisioned.
-// 100 represents complete, while 0 represents just beginning.
-//
-// Status provides an indication of what the server's doing at the moment.
-// A server will be in ACTIVE state if it's ready for use.
-//
-// OsDcfDiskConfig indicates the server's boot volume configuration.
-// Valid values are:
-// AUTO
-// ----
-// The server is built with a single partition the size of the target flavor disk.
-// The file system is automatically adjusted to fit the entire partition.
-// This keeps things simple and automated.
-// AUTO is valid only for images and servers with a single partition that use the EXT3 file system.
-// This is the default setting for applicable Rackspace base images.
-//
-// MANUAL
-// ------
-// The server is built using whatever partition scheme and file system is in the source image.
-// If the target flavor disk is larger,
-// the remaining disk space is left unpartitioned.
-// This enables images to have non-EXT3 file systems, multiple partitions, and so on,
-// and enables you to manage the disk configuration.
-//
-// RaxBandwidth provides measures of the server's inbound and outbound bandwidth per interface.
-//
-// OsExtStsPowerState provides an indication of the server's power.
-// This field appears to be a set of flag bits:
-//
-// ... 4 3 2 1 0
-// +--//--+---+---+---+---+
-// | .... | 0 | S | 0 | I |
-// +--//--+---+---+---+---+
-// | |
-// | +--- 0=Instance is down.
-// | 1=Instance is up.
-// |
-// +----------- 0=Server is switched ON.
-// 1=Server is switched OFF.
-// (note reverse logic.)
-//
-// Unused bits should be ignored when read, and written as 0 for future compatibility.
-//
-// OsExtStsTaskState and OsExtStsVmState work together
-// to provide visibility in the provisioning process for the instance.
-// Consult Rackspace documentation at
-// 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"`
- Created string `json:"created"`
- Flavor FlavorLink `json:"flavor"`
- HostId string `json:"hostId"`
- Id string `json:"id"`
- Image ImageLink `json:"image"`
- Links []Link `json:"links"`
- Metadata map[string]string `json:"metadata"`
- Name string `json:"name"`
- Progress int `json:"progress"`
- Status string `json:"status"`
- TenantId string `json:"tenant_id"`
- Updated string `json:"updated"`
- UserId string `json:"user_id"`
- OsDcfDiskConfig string `json:"OS-DCF:diskConfig"`
- RaxBandwidth []RaxBandwidth `json:"rax-bandwidth:bandwidth"`
- OsExtStsPowerState int `json:"OS-EXT-STS:power_state"`
- OsExtStsTaskState string `json:"OS-EXT-STS:task_state"`
- OsExtStsVmState string `json:"OS-EXT-STS:vm_state"`
-}
-
-// NewServerSettings structures record those fields of the Server structure to change
-// when updating a server (see UpdateServer method).
-type NewServerSettings struct {
- Name string `json:"name,omitempty"`
- AccessIPv4 string `json:"accessIPv4,omitempty"`
- AccessIPv6 string `json:"accessIPv6,omitempty"`
-}
-
-// NewServer structures are used for both requests and responses.
-// The fields discussed below are relevent for server-creation purposes.
-//
-// The Name field contains the desired name of the server.
-// Note that (at present) Rackspace permits more than one server with the same name;
-// however, software should not depend on this.
-// Not only will Rackspace support thank you, so will your own devops engineers.
-// A name is required.
-//
-// The ImageRef field contains the ID of the desired software image to place on the server.
-// This ID must be found in the image slice returned by the Images() function.
-// This field is required.
-//
-// The FlavorRef field contains the ID of the server configuration desired for deployment.
-// This ID must be found in the flavor slice returned by the Flavors() function.
-// This field is required.
-//
-// For OsDcfDiskConfig, refer to the Image or Server structure documentation.
-// This field defaults to "AUTO" if not explicitly provided.
-//
-// Metadata contains a small key/value association of arbitrary data.
-// Neither Rackspace nor OpenStack places significance on this field in any way.
-// This field defaults to an empty map if not provided.
-//
-// Personality specifies the contents of certain files in the server's filesystem.
-// The files and their contents are mapped through a slice of FileConfig structures.
-// If not provided, all filesystem entities retain their image-specific configuration.
-//
-// Networks specifies an affinity for the server's various networks and interfaces.
-// Networks are identified through UUIDs; see NetworkConfig structure documentation for more details.
-// If not provided, network affinity is determined automatically.
-//
-// The AdminPass field may be used to provide a root- or administrator-password
-// during the server provisioning process.
-// If not provided, a random password will be automatically generated and returned in this field.
-//
-// The following fields are intended to be used to communicate certain results about the server being provisioned.
-// When attempting to create a new server, these fields MUST not be provided.
-// They'll be filled in by the response received from the Rackspace APIs.
-//
-// The Id field contains the server's unique identifier.
-// The identifier's scope is best assumed to be bound by the user's account, unless other arrangements have been made with Rackspace.
-//
-// Any Links provided are used to refer to the server specifically by URL.
-// These links are useful for making additional REST calls not explicitly supported by Gorax.
-type NewServer struct {
- Name string `json:"name,omitempty"`
- ImageRef string `json:"imageRef,omitempty"`
- FlavorRef string `json:"flavorRef,omitempty"`
- Metadata map[string]string `json:"metadata,omitempty"`
- Personality []FileConfig `json:"personality,omitempty"`
- Networks []NetworkConfig `json:"networks,omitempty"`
- AdminPass string `json:"adminPass,omitempty"`
- KeyPairName string `json:"key_name,omitempty"`
- Id string `json:"id,omitempty"`
- Links []Link `json:"links,omitempty"`
- OsDcfDiskConfig string `json:"OS-DCF:diskConfig,omitempty"`
- SecurityGroup []map[string]interface{} `json:"security_groups,omitempty"`
- ConfigDrive bool `json:"config_drive"`
- UserData string `json:"user_data"`
-}
-
-// ResizeRequest structures are used internally to encode to JSON the parameters required to resize a server instance.
-// Client applications will not use this structure (no API accepts an instance of this structure).
-// See the Region method ResizeServer() for more details on how to resize a server.
-type ResizeRequest struct {
- Name string `json:"name,omitempty"`
- FlavorRef string `json:"flavorRef"`
- DiskConfig string `json:"OS-DCF:diskConfig,omitempty"`
-}
-
-type CreateImage struct {
- Name string `json:"name"`
- Metadata map[string]string `json:"metadata,omitempty"`
-}
diff --git a/servers_test.go b/servers_test.go
deleted file mode 100644
index 60c71c8..0000000
--- a/servers_test.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package gophercloud
-
-import (
- "net/http"
- "testing"
-)
-
-type testAccess struct {
- public, internal string
- calledFirstEndpointByCriteria int
-}
-
-func (ta *testAccess) FirstEndpointUrlByCriteria(ac ApiCriteria) string {
- ta.calledFirstEndpointByCriteria++
- urls := []string{ta.public, ta.internal}
- return urls[ac.UrlChoice]
-}
-
-func (ta *testAccess) AuthToken() string {
- return ""
-}
-
-func (ta *testAccess) Revoke(string) error {
- return nil
-}
-
-func (ta *testAccess) Reauthenticate() error {
- return nil
-}
-
-func TestGetServersApi(t *testing.T) {
- c := TestContext().UseCustomClient(&http.Client{Transport: newTransport().WithResponse("Hello")})
-
- acc := &testAccess{
- public: "http://localhost:8080",
- internal: "http://localhost:8086",
- }
-
- _, err := c.ServersApi(acc, ApiCriteria{
- Name: "cloudComputeOpenStack",
- Region: "dfw",
- VersionId: "2",
- })
-
- if err != nil {
- t.Error(err)
- return
- }
-
- if acc.calledFirstEndpointByCriteria != 1 {
- t.Error("Expected FirstEndpointByCriteria to be called")
- return
- }
-}
diff --git a/service_catalog.go b/service_catalog.go
deleted file mode 100644
index e6cf4a0..0000000
--- a/service_catalog.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package gophercloud
-
-import (
- "os"
- "strings"
-)
-
-// ApiCriteria provides one or more criteria for the SDK to look for appropriate endpoints.
-// Fields left unspecified or otherwise set to their zero-values are assumed to not be
-// relevant, and do not participate in the endpoint search.
-//
-// Name specifies the desired service catalog entry name.
-// Type specifies the desired service catalog entry type.
-// Region specifies the desired endpoint region.
-// If unset, Gophercloud will try to use the region set in the
-// OS_REGION_NAME environment variable. If that's not set,
-// region comparison will not occur. If OS_REGION_NAME is set
-// and IgnoreEnvVars is also set, OS_REGION_NAME will be ignored.
-// VersionId specifies the desired version of the endpoint.
-// Note that this field is matched exactly, and is (at present)
-// opaque to Gophercloud. Thus, requesting a version 2
-// endpoint will _not_ match a version 3 endpoint.
-// The UrlChoice field inidicates whether or not gophercloud
-// should use the public or internal endpoint URL if a
-// candidate endpoint is found.
-// IgnoreEnvVars instructs Gophercloud to ignore helpful environment variables.
-type ApiCriteria struct {
- Name string
- Type string
- Region string
- VersionId string
- UrlChoice int
- IgnoreEnvVars bool
-}
-
-// The choices available for UrlChoice. See the ApiCriteria structure for details.
-const (
- PublicURL = iota
- InternalURL
-)
-
-// Given a set of criteria to match on, locate the first candidate endpoint
-// in the provided service catalog.
-//
-// If nothing found, the result will be a zero-valued EntryEndpoint (all URLs
-// set to "").
-func FindFirstEndpointByCriteria(entries []CatalogEntry, ac ApiCriteria) EntryEndpoint {
- rgn := strings.ToUpper(ac.Region)
- if (rgn == "") && !ac.IgnoreEnvVars {
- rgn = os.Getenv("OS_REGION_NAME")
- }
-
- for _, entry := range entries {
- if (ac.Name != "") && (ac.Name != entry.Name) {
- continue
- }
-
- if (ac.Type != "") && (ac.Type != entry.Type) {
- continue
- }
-
- for _, endpoint := range entry.Endpoints {
- if (rgn != "") && (rgn != strings.ToUpper(endpoint.Region)) {
- continue
- }
-
- if (ac.VersionId != "") && (ac.VersionId != endpoint.VersionId) {
- continue
- }
-
- return endpoint
- }
- }
- return EntryEndpoint{}
-}
diff --git a/service_catalog_test.go b/service_catalog_test.go
deleted file mode 100644
index b78f01f..0000000
--- a/service_catalog_test.go
+++ /dev/null
@@ -1,190 +0,0 @@
-package gophercloud
-
-import (
- "os"
- "testing"
-)
-
-// TestFFEBCViaEnvVariable exercises only those calls where a region
-// parameter is required, but is provided by an environment variable.
-func TestFFEBCViaEnvVariable(t *testing.T) {
- changeRegion("RGN")
-
- endpoint := FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "", ""),
- ApiCriteria{Name: "test"},
- )
- if endpoint.PublicURL != "" {
- t.Error("If provided, the Region qualifier must exclude endpoints with missing or mismatching regions.")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "rgn", ""),
- ApiCriteria{Name: "test"},
- )
- if endpoint.PublicURL != "http://localhost" {
- t.Error("Regions are case insensitive.")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "rgn", ""),
- ApiCriteria{Name: "test", VersionId: "2"},
- )
- if endpoint.PublicURL != "" {
- t.Error("Missing version ID means no match.")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "rgn", "3"),
- ApiCriteria{Name: "test", VersionId: "2"},
- )
- if endpoint.PublicURL != "" {
- t.Error("Mismatched version ID means no match.")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "rgn", "2"),
- ApiCriteria{Name: "test", VersionId: "2"},
- )
- if endpoint.PublicURL != "http://localhost" {
- t.Error("All search criteria met; endpoint expected.")
- return
- }
-}
-
-// TestFFEBCViaRegionOption exercises only those calls where a region
-// parameter is specified explicitly. The region option overrides
-// any defined OS_REGION_NAME environment setting.
-func TestFFEBCViaRegionOption(t *testing.T) {
- changeRegion("Starfleet Command")
-
- endpoint := FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "", ""),
- ApiCriteria{Name: "test", Region: "RGN"},
- )
- if endpoint.PublicURL != "" {
- t.Error("If provided, the Region qualifier must exclude endpoints with missing or mismatching regions.")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "rgn", ""),
- ApiCriteria{Name: "test", Region: "RGN"},
- )
- if endpoint.PublicURL != "http://localhost" {
- t.Error("Regions are case insensitive.")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "rgn", ""),
- ApiCriteria{Name: "test", Region: "RGN", VersionId: "2"},
- )
- if endpoint.PublicURL != "" {
- t.Error("Missing version ID means no match.")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "rgn", "3"),
- ApiCriteria{Name: "test", Region: "RGN", VersionId: "2"},
- )
- if endpoint.PublicURL != "" {
- t.Error("Mismatched version ID means no match.")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "rgn", "2"),
- ApiCriteria{Name: "test", Region: "RGN", VersionId: "2"},
- )
- if endpoint.PublicURL != "http://localhost" {
- t.Error("All search criteria met; endpoint expected.")
- return
- }
-}
-
-// TestFFEBCWithoutRegion exercises only those calls where a region
-// is irrelevant. Just to make sure, though, we enforce Gophercloud
-// from paying any attention to OS_REGION_NAME if it happens to be set.
-func TestFindFirstEndpointByCriteria(t *testing.T) {
- endpoint := FindFirstEndpointByCriteria([]CatalogEntry{}, ApiCriteria{Name: "test", IgnoreEnvVars: true})
- if endpoint.PublicURL != "" {
- t.Error("Not expecting to find anything in an empty service catalog.")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- []CatalogEntry{
- {Name: "test"},
- },
- ApiCriteria{Name: "test", IgnoreEnvVars: true},
- )
- if endpoint.PublicURL != "" {
- t.Error("Even though we have a matching entry, no endpoints exist")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "", ""),
- ApiCriteria{Name: "test", IgnoreEnvVars: true},
- )
- if endpoint.PublicURL != "http://localhost" {
- t.Error("Looking for an endpoint by name but without region or version ID should match first entry endpoint.")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "", ""),
- ApiCriteria{Type: "compute", IgnoreEnvVars: true},
- )
- if endpoint.PublicURL != "http://localhost" {
- t.Error("Looking for an endpoint by type but without region or version ID should match first entry endpoint.")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "", ""),
- ApiCriteria{Type: "identity", IgnoreEnvVars: true},
- )
- if endpoint.PublicURL != "" {
- t.Error("Returned mismatched type.")
- return
- }
-
- endpoint = FindFirstEndpointByCriteria(
- catalog("test", "compute", "http://localhost", "ord", "2"),
- ApiCriteria{Name: "test", VersionId: "2", IgnoreEnvVars: true},
- )
- if endpoint.PublicURL != "http://localhost" {
- t.Error("Sometimes, you might not care what region your stuff is in.")
- return
- }
-}
-
-func catalog(name, entry_type, url, region, version string) []CatalogEntry {
- return []CatalogEntry{
- {
- Name: name,
- Type: entry_type,
- Endpoints: []EntryEndpoint{
- {
- PublicURL: url,
- Region: region,
- VersionId: version,
- },
- },
- },
- }
-}
-
-func changeRegion(r string) {
- err := os.Setenv("OS_REGION_NAME", r)
- if err != nil {
- panic(err)
- }
-}
diff --git a/transport_double_test.go b/transport_double_test.go
deleted file mode 100644
index ef7f19a..0000000
--- a/transport_double_test.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package gophercloud
-
-import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "net/http"
- "strings"
- "testing"
-)
-
-type transport struct {
- called int
- response string
- expectTenantId bool
- tenantIdFound bool
- status int
-}
-
-func (t *transport) RoundTrip(req *http.Request) (rsp *http.Response, err error) {
- var authContainer *AuthContainer
-
- t.called++
-
- headers := make(http.Header)
- headers.Add("Content-Type", "application/xml; charset=UTF-8")
-
- body := ioutil.NopCloser(strings.NewReader(t.response))
-
- if t.status == 0 {
- t.status = 200
- }
- statusMsg := "OK"
- if (t.status < 200) || (299 < t.status) {
- statusMsg = "Error"
- }
-
- rsp = &http.Response{
- Status: fmt.Sprintf("%d %s", t.status, statusMsg),
- StatusCode: t.status,
- Proto: "HTTP/1.1",
- ProtoMajor: 1,
- ProtoMinor: 1,
- Header: headers,
- Body: body,
- ContentLength: -1,
- TransferEncoding: nil,
- Close: true,
- Trailer: nil,
- Request: req,
- }
-
- bytes, err := ioutil.ReadAll(req.Body)
- if err != nil {
- return nil, err
- }
- err = json.Unmarshal(bytes, &authContainer)
- if err != nil {
- return nil, err
- }
- t.tenantIdFound = (authContainer.Auth.TenantId != "")
-
- if t.tenantIdFound != t.expectTenantId {
- rsp.Status = "500 Internal Server Error"
- rsp.StatusCode = 500
- }
- return
-}
-
-func newTransport() *transport {
- return &transport{}
-}
-
-func (t *transport) IgnoreTenantId() *transport {
- t.expectTenantId = false
- return t
-}
-
-func (t *transport) ExpectTenantId() *transport {
- t.expectTenantId = true
- return t
-}
-
-func (t *transport) WithResponse(r string) *transport {
- t.response = r
- t.status = 200
- return t
-}
-
-func (t *transport) WithError(code int) *transport {
- t.response = fmt.Sprintf("Error %d", code)
- t.status = code
- return t
-}
-
-func (t *transport) VerifyCalls(test *testing.T, n int) error {
- if t.called != n {
- err := fmt.Errorf("Expected Transport to be called %d times; found %d instead", n, t.called)
- test.Error(err)
- return err
- }
- return nil
-}