Add ability to change admin password on a server
diff --git a/acceptance/09-change-admin-password.go b/acceptance/09-change-admin-password.go
new file mode 100644
index 0000000..4804726
--- /dev/null
+++ b/acceptance/09-change-admin-password.go
@@ -0,0 +1,54 @@
+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() {
+	provider, username, password := getCredentials()
+	flag.Parse()
+
+	if *serverId == "" {
+		panic("Server ID expected [use -i option]")
+	}
+
+	if *newPass == "" {
+		panic("Password expected [use -p option]")
+	}
+
+	acc, err := gophercloud.Authenticate(
+		provider,
+		gophercloud.AuthOptions{
+			Username: username,
+			Password: password,
+		},
+	)
+	if err != nil {
+		panic(err)
+	}
+
+	api, err := gophercloud.ServersApi(acc, gophercloud.ApiCriteria{
+		Name:      "cloudServersOpenStack",
+		Region:    "DFW",
+		VersionId: "2",
+		UrlChoice: gophercloud.PublicURL,
+	})
+	if err != nil {
+		panic(err)
+	}
+
+	err = api.SetAdminPassword(*serverId, *newPass)
+	if err != nil {
+		panic(err)
+	}
+
+	if !*quiet {
+		fmt.Println("Password change request submitted.")
+	}
+}
diff --git a/interfaces.go b/interfaces.go
index 4342553..089b6dd 100644
--- a/interfaces.go
+++ b/interfaces.go
@@ -27,10 +27,11 @@
   // Servers
 
 	ListServers() ([]Server, error)
-  ListServersLinksOnly() ([]Server, error)
+	ListServersLinksOnly() ([]Server, error)
 	ServerById(id string) (*Server, error)
 	CreateServer(ns NewServer) (*NewServer, error)
 	DeleteServerById(id string) error
+	SetAdminPassword(id string, pw string) error
 
   // Images
 
diff --git a/servers.go b/servers.go
index 4f7cc1e..ee38e9f 100644
--- a/servers.go
+++ b/servers.go
@@ -5,6 +5,7 @@
 
 import (
 	"github.com/racker/perigee"
+	"fmt"
 )
 
 // genericServersProvider structures provide the implementation for generic OpenStack-compatible
@@ -107,6 +108,29 @@
 	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
+}
+
 // RaxBandwidth provides measurement of server bandwidth consumed over a given audit interval.
 type RaxBandwidth struct {
 	AuditPeriodEnd    string `json:"audit_period_end"`