Rackspace Auto Scale: Add policies Get()
diff --git a/rackspace/autoscale/v1/policies/fixtures.go b/rackspace/autoscale/v1/policies/fixtures.go
index 442a891..587c5e7 100644
--- a/rackspace/autoscale/v1/policies/fixtures.go
+++ b/rackspace/autoscale/v1/policies/fixtures.go
@@ -98,6 +98,25 @@
 ]
 `
 
+// PolicyGetBody contains the canned body of a policies.Get response.
+const PolicyGetBody = `
+{
+  "policy": {
+    "name": "webhook policy",
+    "links": [
+      {
+        "href": "https://dfw.autoscale.api.rackspacecloud.com/v1.0/123456/groups/60b15dad-5ea1-43fa-9a12-a1d737b4da07/policies/2b48d247-0282-4b9d-8775-5c4b67e8e649/",
+        "rel": "self"
+      }
+    ],
+    "changePercent": 3.3,
+    "cooldown": 300,
+    "type": "webhook",
+    "id": "2b48d247-0282-4b9d-8775-5c4b67e8e649"
+  }
+}
+`
+
 var (
 	// WebhookPolicy is a Policy corresponding to the first result in PolicyListBody.
 	WebhookPolicy = Policy{
@@ -133,7 +152,7 @@
 
 // HandlePolicyListSuccessfully sets up the test server to respond to a policies List request.
 func HandlePolicyListSuccessfully(t *testing.T) {
-	path := "/groups/10eb3219-1b12-4b34-b1e4-e10ee4f24c65/policies"
+	path := "/groups/60b15dad-5ea1-43fa-9a12-a1d737b4da07/policies"
 
 	th.Mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "GET")
@@ -147,7 +166,7 @@
 
 // HandlePolicyCreateSuccessfully sets up the test server to respond to a policies Create request.
 func HandlePolicyCreateSuccessfully(t *testing.T) {
-	path := "/groups/10eb3219-1b12-4b34-b1e4-e10ee4f24c65/policies"
+	path := "/groups/60b15dad-5ea1-43fa-9a12-a1d737b4da07/policies"
 
 	th.Mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
 		th.TestMethod(t, r, "POST")
@@ -163,3 +182,20 @@
 		fmt.Fprintf(w, PolicyCreateBody)
 	})
 }
+
+// HandlePolicyGetSuccessfully sets up the test server to respond to a policies Get request.
+func HandlePolicyGetSuccessfully(t *testing.T) {
+	groupID := "60b15dad-5ea1-43fa-9a12-a1d737b4da07"
+	policyID := "2b48d247-0282-4b9d-8775-5c4b67e8e649"
+
+	path := fmt.Sprintf("/groups/%s/policies/%s", groupID, policyID)
+
+	th.Mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "GET")
+		th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+
+		w.Header().Add("Content-Type", "application/json")
+
+		fmt.Fprintf(w, PolicyGetBody)
+	})
+}
diff --git a/rackspace/autoscale/v1/policies/requests.go b/rackspace/autoscale/v1/policies/requests.go
index 69ad7cd..ab3d5eb 100644
--- a/rackspace/autoscale/v1/policies/requests.go
+++ b/rackspace/autoscale/v1/policies/requests.go
@@ -120,3 +120,12 @@
 
 	return res
 }
+
+// Get requests the details of a single policy with the given ID.
+func Get(client *gophercloud.ServiceClient, groupID, policyID string) GetResult {
+	var result GetResult
+
+	_, result.Err = client.Get(getURL(client, groupID, policyID), &result.Body, nil)
+
+	return result
+}
diff --git a/rackspace/autoscale/v1/policies/requests_test.go b/rackspace/autoscale/v1/policies/requests_test.go
index bf49816..b600377 100644
--- a/rackspace/autoscale/v1/policies/requests_test.go
+++ b/rackspace/autoscale/v1/policies/requests_test.go
@@ -9,7 +9,8 @@
 )
 
 const (
-	groupID = "10eb3219-1b12-4b34-b1e4-e10ee4f24c65"
+	groupID         = "60b15dad-5ea1-43fa-9a12-a1d737b4da07"
+	webhookPolicyID = "2b48d247-0282-4b9d-8775-5c4b67e8e649"
 )
 
 func TestList(t *testing.T) {
@@ -18,7 +19,7 @@
 	HandlePolicyListSuccessfully(t)
 
 	pages := 0
-	pager := List(client.ServiceClient(), "10eb3219-1b12-4b34-b1e4-e10ee4f24c65")
+	pager := List(client.ServiceClient(), "60b15dad-5ea1-43fa-9a12-a1d737b4da07")
 
 	err := pager.EachPage(func(page pagination.Page) (bool, error) {
 		pages++
@@ -94,3 +95,16 @@
 	th.CheckDeepEquals(t, OneTimePolicy, policies[1])
 	th.CheckDeepEquals(t, SundayAfternoonPolicy, policies[2])
 }
+
+func TestGet(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandlePolicyGetSuccessfully(t)
+
+	client := client.ServiceClient()
+
+	policy, err := Get(client, groupID, webhookPolicyID).Extract()
+
+	th.AssertNoErr(t, err)
+	th.CheckDeepEquals(t, WebhookPolicy, *policy)
+}
diff --git a/rackspace/autoscale/v1/policies/results.go b/rackspace/autoscale/v1/policies/results.go
index e50ea78..e92d636 100644
--- a/rackspace/autoscale/v1/policies/results.go
+++ b/rackspace/autoscale/v1/policies/results.go
@@ -11,6 +11,21 @@
 	gophercloud.Result
 }
 
+// Extract interprets any policyResult as a Policy, if possible.
+func (r policyResult) Extract() (*Policy, error) {
+	if r.Err != nil {
+		return nil, r.Err
+	}
+
+	var response struct {
+		Policy Policy `mapstructure:"policy"`
+	}
+
+	err := mapstructure.Decode(r.Body, &response)
+
+	return &response.Policy, err
+}
+
 // CreateResult represents the result of a create operation.
 type CreateResult struct {
 	policyResult
@@ -27,6 +42,11 @@
 	return commonExtractPolicies(res.Body)
 }
 
+// GetResult temporarily contains the response from a Get call.
+type GetResult struct {
+	policyResult
+}
+
 // Policy represents a scaling policy.
 type Policy struct {
 	// UUID for the policy.
diff --git a/rackspace/autoscale/v1/policies/urls.go b/rackspace/autoscale/v1/policies/urls.go
index e837c7f..ebbd154 100644
--- a/rackspace/autoscale/v1/policies/urls.go
+++ b/rackspace/autoscale/v1/policies/urls.go
@@ -9,3 +9,7 @@
 func createURL(c *gophercloud.ServiceClient, groupID string) string {
 	return c.ServiceURL("groups", groupID, "policies")
 }
+
+func getURL(c *gophercloud.ServiceClient, groupID, policyID string) string {
+	return c.ServiceURL("groups", groupID, "policies", policyID)
+}