Merge pull request #44 from rackspace/delete-server

Delete server
diff --git a/acceptance/04-create-server.go b/acceptance/04-create-server.go
index bc5ff69..9d29b0e 100644
--- a/acceptance/04-create-server.go
+++ b/acceptance/04-create-server.go
@@ -15,7 +15,7 @@
 func configure() {
 	provider, username, password = getCredentials()
 	region = flag.String("r", "DFW", "Rackspace region in which to create the server")
-	serverName = flag.String("n", randomString(16), "Server name (what you see in the control panel)")
+	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")
 
diff --git a/acceptance/07-delete-server.go b/acceptance/07-delete-server.go
new file mode 100644
index 0000000..8d05e8e
--- /dev/null
+++ b/acceptance/07-delete-server.go
@@ -0,0 +1,56 @@
+package main
+
+import (
+	"fmt"
+	"flag"
+	"github.com/rackspace/gophercloud"
+)
+
+var quiet = flag.Bool("quiet", false, "Quiet operation for acceptance tests.  $? non-zero if problem.")
+var region = flag.String("r", "DFW", "Datacenter region")
+
+func main() {
+	provider, username, password := getCredentials()
+	flag.Parse()
+
+	auth, err := gophercloud.Authenticate(provider, gophercloud.AuthOptions{
+		Username: username,
+		Password: password,
+	})
+	if err != nil {
+		panic(err)
+	}
+
+	servers, err := gophercloud.ServersApi(auth, gophercloud.ApiCriteria{
+		Name:      "cloudServersOpenStack",
+		Region:    *region,
+		VersionId: "2",
+		UrlChoice: gophercloud.PublicURL,
+	})
+	if err != nil {
+		panic(err)
+	}
+
+	ss, err := servers.ListServers()
+	if err != nil {
+		panic(err)
+	}
+
+	n := 0
+	for _, s := range ss {
+		if len(s.Name) < 10 {
+			continue
+		}
+		if s.Name[0:10] == "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
index 0af62d4..1802591 100644
--- a/acceptance/libargs.go
+++ b/acceptance/libargs.go
@@ -29,12 +29,12 @@
 // 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(n int) string {
+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 string(bytes)
+    return prefix + string(bytes)
 }
\ No newline at end of file
diff --git a/interfaces.go b/interfaces.go
index b50fdf3..6d9b3c7 100644
--- a/interfaces.go
+++ b/interfaces.go
@@ -23,6 +23,7 @@
 	ListServers() ([]Server, error)
 	ServerById(id string) (*Server, error)
 	CreateServer(ns NewServer) (*NewServer, error)
+	DeleteServerById(id string) error
 
   // Images
 
diff --git a/servers.go b/servers.go
index 29a1fc5..30aa959 100644
--- a/servers.go
+++ b/servers.go
@@ -69,6 +69,18 @@
 	return s, err
 }
 
+// See the CloudServersProvider interface for details.
+func (gsp *genericServersProvider) DeleteServerById(id string) error {
+	url := gsp.endpoint + "/servers/" + id
+	err := perigee.Delete(url, perigee.Options{
+		MoreHeaders: map[string]string{
+			"X-Auth-Token": gsp.access.AuthToken(),
+		},
+		OkCodes: []int{204},
+	})
+	return err
+}
+
 // RaxBandwidth provides measurement of server bandwidth consumed over a given audit interval.
 type RaxBandwidth struct {
 	AuditPeriodEnd    string `json:"audit_period_end"`