openstack/rackspace build info ops and unit tests
diff --git a/openstack/orchestration/v1/buildinfo/fixtures.go b/openstack/orchestration/v1/buildinfo/fixtures.go
new file mode 100644
index 0000000..20ea09b
--- /dev/null
+++ b/openstack/orchestration/v1/buildinfo/fixtures.go
@@ -0,0 +1,45 @@
+package buildinfo
+
+import (
+	"fmt"
+	"net/http"
+	"testing"
+
+	th "github.com/rackspace/gophercloud/testhelper"
+	fake "github.com/rackspace/gophercloud/testhelper/client"
+)
+
+// GetExpected represents the expected object from a Get request.
+var GetExpected = &BuildInfo{
+	API: Revision{
+		Revision: "2.4.5",
+	},
+	Engine: Revision{
+		Revision: "1.2.1",
+	},
+}
+
+// GetOutput represents the response body from a Get request.
+const GetOutput = `
+{
+  "api": {
+    "revision": "2.4.5"
+  },
+  "engine": {
+    "revision": "1.2.1"
+  }
+}`
+
+// HandleGetSuccessfully creates an HTTP handler at `/build_info`
+// on the test handler mux that responds with a `Get` response.
+func HandleGetSuccessfully(t *testing.T, output string) {
+	th.Mux.HandleFunc("/build_info", func(w http.ResponseWriter, r *http.Request) {
+		th.TestMethod(t, r, "GET")
+		th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+		th.TestHeader(t, r, "Accept", "application/json")
+
+		w.Header().Set("Content-Type", "application/json")
+		w.WriteHeader(http.StatusOK)
+		fmt.Fprintf(w, output)
+	})
+}
diff --git a/openstack/orchestration/v1/buildinfo/requests.go b/openstack/orchestration/v1/buildinfo/requests.go
new file mode 100644
index 0000000..c20b48c
--- /dev/null
+++ b/openstack/orchestration/v1/buildinfo/requests.go
@@ -0,0 +1,17 @@
+package buildinfo
+
+import (
+	"github.com/racker/perigee"
+	"github.com/rackspace/gophercloud"
+)
+
+// Get retreives data for the given stack template.
+func Get(c *gophercloud.ServiceClient) GetResult {
+	var res GetResult
+	_, res.Err = perigee.Request("GET", getURL(c), perigee.Options{
+		MoreHeaders: c.AuthenticatedHeaders(),
+		Results:     &res.Body,
+		OkCodes:     []int{200},
+	})
+	return res
+}
diff --git a/openstack/orchestration/v1/buildinfo/requests_test.go b/openstack/orchestration/v1/buildinfo/requests_test.go
new file mode 100644
index 0000000..1e0fe23
--- /dev/null
+++ b/openstack/orchestration/v1/buildinfo/requests_test.go
@@ -0,0 +1,20 @@
+package buildinfo
+
+import (
+	"testing"
+
+	th "github.com/rackspace/gophercloud/testhelper"
+	fake "github.com/rackspace/gophercloud/testhelper/client"
+)
+
+func TestGetTemplate(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	HandleGetSuccessfully(t, GetOutput)
+
+	actual, err := Get(fake.ServiceClient()).Extract()
+	th.AssertNoErr(t, err)
+
+	expected := GetExpected
+	th.AssertDeepEquals(t, expected, actual)
+}
diff --git a/openstack/orchestration/v1/buildinfo/results.go b/openstack/orchestration/v1/buildinfo/results.go
new file mode 100644
index 0000000..0e006b8
--- /dev/null
+++ b/openstack/orchestration/v1/buildinfo/results.go
@@ -0,0 +1,37 @@
+package buildinfo
+
+import (
+	"github.com/mitchellh/mapstructure"
+	"github.com/rackspace/gophercloud"
+)
+
+// Revision represents the API/Enging revision of a Heat deployment.
+type Revision struct {
+	Revision string `mapstructure:"revision"`
+}
+
+// BuildInfo represents the build information for a Heat deployment.
+type BuildInfo struct {
+	API    Revision `mapstructure:"api"`
+	Engine Revision `mapstructure:"engine"`
+}
+
+// GetResult represents the result of a Get operation.
+type GetResult struct {
+	gophercloud.Result
+}
+
+// Extract returns a pointer to a BuildInfo object and is called after a
+// Get operation.
+func (r GetResult) Extract() (*BuildInfo, error) {
+	if r.Err != nil {
+		return nil, r.Err
+	}
+
+	var res BuildInfo
+	if err := mapstructure.Decode(r.Body, &res); err != nil {
+		return nil, err
+	}
+
+	return &res, nil
+}
diff --git a/openstack/orchestration/v1/buildinfo/urls.go b/openstack/orchestration/v1/buildinfo/urls.go
new file mode 100644
index 0000000..2c873d0
--- /dev/null
+++ b/openstack/orchestration/v1/buildinfo/urls.go
@@ -0,0 +1,7 @@
+package buildinfo
+
+import "github.com/rackspace/gophercloud"
+
+func getURL(c *gophercloud.ServiceClient) string {
+	return c.ServiceURL("build_info")
+}
diff --git a/rackspace/orchestration/v1/buildinfo/delegate.go b/rackspace/orchestration/v1/buildinfo/delegate.go
new file mode 100644
index 0000000..c834e5c
--- /dev/null
+++ b/rackspace/orchestration/v1/buildinfo/delegate.go
@@ -0,0 +1,11 @@
+package buildinfo
+
+import (
+	"github.com/rackspace/gophercloud"
+	os "github.com/rackspace/gophercloud/openstack/orchestration/v1/buildinfo"
+)
+
+// Get retreives build info data for the Heat deployment.
+func Get(c *gophercloud.ServiceClient) os.GetResult {
+	return os.Get(c)
+}
diff --git a/rackspace/orchestration/v1/buildinfo/delegate_test.go b/rackspace/orchestration/v1/buildinfo/delegate_test.go
new file mode 100644
index 0000000..b25a690
--- /dev/null
+++ b/rackspace/orchestration/v1/buildinfo/delegate_test.go
@@ -0,0 +1,21 @@
+package buildinfo
+
+import (
+	"testing"
+
+	os "github.com/rackspace/gophercloud/openstack/orchestration/v1/buildinfo"
+	th "github.com/rackspace/gophercloud/testhelper"
+	fake "github.com/rackspace/gophercloud/testhelper/client"
+)
+
+func TestGetTemplate(t *testing.T) {
+	th.SetupHTTP()
+	defer th.TeardownHTTP()
+	os.HandleGetSuccessfully(t, os.GetOutput)
+
+	actual, err := Get(fake.ServiceClient()).Extract()
+	th.AssertNoErr(t, err)
+
+	expected := os.GetExpected
+	th.AssertDeepEquals(t, expected, actual)
+}