Identity v3 Projects Create (#165)
* Identity v3 Projects Create
* Removing unused createErr function
diff --git a/openstack/identity/v3/projects/requests.go b/openstack/identity/v3/projects/requests.go
index 73e4c4c..07b9371 100644
--- a/openstack/identity/v3/projects/requests.go
+++ b/openstack/identity/v3/projects/requests.go
@@ -83,3 +83,46 @@
})
return
}
+
+// CreateOptsBuilder allows extensions to add additional parameters to
+// the Create request.
+type CreateOptsBuilder interface {
+ ToProjectCreateMap() (map[string]interface{}, error)
+}
+
+// CreateOpts allows you to modify the details included in the Create request.
+type CreateOpts struct {
+ // DomainID is the ID this project will belong under.
+ DomainID string `json:"domain_id,omitempty"`
+
+ // Enabled sets the project status to enabled or disabled.
+ Enabled *bool `json:"enabled,omitempty"`
+
+ // IsDomain indicates if this project is a domain.
+ IsDomain *bool `json:"is_domain,omitempty"`
+
+ // Name is the name of the project.
+ Name string `json:"name,required"`
+
+ // ParentID specifies the parent project of this new project.
+ ParentID string `json:"parent_id,omitempty"`
+
+ // Description is the description of the project.
+ Description string `json:"description,omitempty"`
+}
+
+// ToProjectCreateMap formats a CreateOpts into a create request.
+func (opts CreateOpts) ToProjectCreateMap() (map[string]interface{}, error) {
+ return gophercloud.BuildRequestBody(opts, "project")
+}
+
+// Create creates a new Project.
+func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
+ b, err := opts.ToProjectCreateMap()
+ if err != nil {
+ r.Err = err
+ return
+ }
+ _, r.Err = client.Post(createURL(client), &b, &r.Body, nil)
+ return
+}
diff --git a/openstack/identity/v3/projects/results.go b/openstack/identity/v3/projects/results.go
index 2ec05a8..c828ff8 100644
--- a/openstack/identity/v3/projects/results.go
+++ b/openstack/identity/v3/projects/results.go
@@ -14,6 +14,11 @@
projectResult
}
+// CreateResult temporarily contains the reponse from the Create call.
+type CreateResult struct {
+ projectResult
+}
+
// Project is a base unit of ownership.
type Project struct {
// IsDomain indicates whether the project is a domain.
diff --git a/openstack/identity/v3/projects/testing/fixtures.go b/openstack/identity/v3/projects/testing/fixtures.go
index cb10313..0c839b8 100644
--- a/openstack/identity/v3/projects/testing/fixtures.go
+++ b/openstack/identity/v3/projects/testing/fixtures.go
@@ -55,6 +55,16 @@
}
`
+// CreateRequest provides the input to a Create request.
+const CreateRequest = `
+{
+ "project": {
+ "description": "The team that is red",
+ "name": "Red Team"
+ }
+}
+`
+
// RedTeam is a Project fixture.
var RedTeam = projects.Project{
IsDomain: false,
@@ -107,3 +117,16 @@
fmt.Fprintf(w, GetOutput)
})
}
+
+// HandleCreateProjectSuccessfully creates an HTTP handler at `/projects` on the
+// test handler mux that tests project creation.
+func HandleCreateProjectSuccessfully(t *testing.T) {
+ th.Mux.HandleFunc("/projects", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "POST")
+ th.TestHeader(t, r, "X-Auth-Token", client.TokenID)
+ th.TestJSONRequest(t, r, CreateRequest)
+
+ w.WriteHeader(http.StatusCreated)
+ fmt.Fprintf(w, GetOutput)
+ })
+}
diff --git a/openstack/identity/v3/projects/testing/requests_test.go b/openstack/identity/v3/projects/testing/requests_test.go
index eeb2049..daed4eb 100644
--- a/openstack/identity/v3/projects/testing/requests_test.go
+++ b/openstack/identity/v3/projects/testing/requests_test.go
@@ -38,3 +38,18 @@
th.AssertNoErr(t, err)
th.CheckDeepEquals(t, RedTeam, *actual)
}
+
+func TestCreateProject(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+ HandleCreateProjectSuccessfully(t)
+
+ createOpts := projects.CreateOpts{
+ Name: "Red Team",
+ Description: "The team that is red",
+ }
+
+ actual, err := projects.Create(client.ServiceClient(), createOpts).Extract()
+ th.AssertNoErr(t, err)
+ th.CheckDeepEquals(t, RedTeam, *actual)
+}
diff --git a/openstack/identity/v3/projects/urls.go b/openstack/identity/v3/projects/urls.go
index 5effbfb..7be9dc2 100644
--- a/openstack/identity/v3/projects/urls.go
+++ b/openstack/identity/v3/projects/urls.go
@@ -9,3 +9,7 @@
func getURL(client *gophercloud.ServiceClient, projectID string) string {
return client.ServiceURL("projects", projectID)
}
+
+func createURL(client *gophercloud.ServiceClient) string {
+ return client.ServiceURL("projects")
+}