Implement and test service creation.
diff --git a/openstack/identity/v3/services/doc.go b/openstack/identity/v3/services/doc.go
new file mode 100644
index 0000000..c4772c0
--- /dev/null
+++ b/openstack/identity/v3/services/doc.go
@@ -0,0 +1,4 @@
+/*
+Package services queries and manages the service catalog.
+*/
+package services
diff --git a/openstack/identity/v3/services/requests.go b/openstack/identity/v3/services/requests.go
new file mode 100644
index 0000000..a752d57
--- /dev/null
+++ b/openstack/identity/v3/services/requests.go
@@ -0,0 +1,32 @@
+package services
+
+import (
+ "github.com/racker/perigee"
+ "github.com/rackspace/gophercloud"
+)
+
+// Create adds a new service of the requested type to the catalog.
+func Create(client *gophercloud.ServiceClient, serviceType string) (*ServiceResult, error) {
+ type request struct {
+ Type string `json:"type"`
+ }
+
+ type response struct {
+ Service ServiceResult `json:"service"`
+ }
+
+ req := request{Type: serviceType}
+ var resp response
+
+ _, err := perigee.Request("POST", getListURL(client), perigee.Options{
+ MoreHeaders: client.AuthenticatedHeaders(),
+ ReqBody: &req,
+ Results: &resp,
+ OkCodes: []int{201},
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return &resp.Service, nil
+}
diff --git a/openstack/identity/v3/services/requests_test.go b/openstack/identity/v3/services/requests_test.go
new file mode 100644
index 0000000..d2637c4
--- /dev/null
+++ b/openstack/identity/v3/services/requests_test.go
@@ -0,0 +1,57 @@
+package services
+
+import (
+ "fmt"
+ "net/http"
+ "testing"
+
+ "github.com/rackspace/gophercloud"
+ "github.com/rackspace/gophercloud/testhelper"
+)
+
+func TestCreateSuccessful(t *testing.T) {
+ testhelper.SetupHTTP()
+ defer testhelper.TeardownHTTP()
+
+ testhelper.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) {
+ testhelper.TestMethod(t, r, "POST")
+ testhelper.TestHeader(t, r, "X-Auth-Token", "1111")
+ testhelper.TestJSONRequest(t, r, `{ "type": "compute" }`)
+
+ w.Header().Add("Content-Type", "application/json")
+ w.WriteHeader(http.StatusCreated)
+ fmt.Fprintf(w, `{
+ "service": {
+ "description": "Here's your service",
+ "id": "1234",
+ "name": "InscrutableOpenStackProjectName",
+ "type": "compute"
+ }
+ }`)
+ })
+
+ client := gophercloud.ServiceClient{
+ ProviderClient: gophercloud.ProviderClient{
+ TokenID: "1111",
+ },
+ Endpoint: testhelper.Endpoint(),
+ }
+
+ result, err := Create(&client, "compute")
+ if err != nil {
+ t.Fatalf("Unexpected error from Create: %v", err)
+ }
+
+ if result.Description == nil || *result.Description != "Here's your service" {
+ t.Errorf("Service description was unexpected [%s]", result.Description)
+ }
+ if result.ID != "1234" {
+ t.Errorf("Service ID was unexpected [%s]", result.ID)
+ }
+ if result.Name != "InscrutableOpenStackProjectName" {
+ t.Errorf("Service name was unexpected [%s]", result.Name)
+ }
+ if result.Type != "compute" {
+ t.Errorf("Service type was unexpected [%s]", result.Type)
+ }
+}
diff --git a/openstack/identity/v3/services/results.go b/openstack/identity/v3/services/results.go
new file mode 100644
index 0000000..baf8d6b
--- /dev/null
+++ b/openstack/identity/v3/services/results.go
@@ -0,0 +1,9 @@
+package services
+
+// ServiceResult is the result of a list or information query.
+type ServiceResult struct {
+ Description *string `json:"description,omitempty"`
+ ID string `json:"id"`
+ Name string `json:"name"`
+ Type string `json:"type"`
+}
diff --git a/openstack/identity/v3/services/urls.go b/openstack/identity/v3/services/urls.go
new file mode 100644
index 0000000..b555cb7
--- /dev/null
+++ b/openstack/identity/v3/services/urls.go
@@ -0,0 +1,11 @@
+package services
+
+import "github.com/rackspace/gophercloud"
+
+func getListURL(client *gophercloud.ServiceClient) string {
+ return client.ServiceURL("services")
+}
+
+func getServiceURL(client *gophercloud.ServiceClient, serviceID string) string {
+ return ""
+}
diff --git a/openstack/identity/v3/services/urls_test.go b/openstack/identity/v3/services/urls_test.go
new file mode 100644
index 0000000..fd2d46a
--- /dev/null
+++ b/openstack/identity/v3/services/urls_test.go
@@ -0,0 +1,15 @@
+package services
+
+import (
+ "testing"
+
+ "github.com/rackspace/gophercloud"
+)
+
+func TestGetListURL(t *testing.T) {
+ client := gophercloud.ServiceClient{Endpoint: "http://localhost:5000/v3/"}
+ url := getListURL(&client)
+ if url != "http://localhost:5000/v3/services" {
+ t.Errorf("Unexpected list URL generated: [%s]", url)
+ }
+}