From 262661a05f14c04dce7750453081350c5bbd7116 Mon Sep 17 00:00:00 2001 From: Evan Brown Date: Tue, 23 Aug 2016 21:34:54 +0100 Subject: [PATCH] providers/google: Add documentation for google_iam_policy resource --- ...nt.go => data_source_google_iam_policy.go} | 42 +++++++------ .../google/resource_google_project.go | 19 ++---- .../google/resource_google_project_test.go | 15 +++-- .../google/d/google_iam_policy.html.markdown | 60 ++++++++++++++++++ .../google/r/google_project.html.markdown | 61 +++++++++++++++++++ 5 files changed, 156 insertions(+), 41 deletions(-) rename builtin/providers/google/{data_source_google_iam_policy_document.go => data_source_google_iam_policy.go} (84%) create mode 100644 website/source/docs/providers/google/d/google_iam_policy.html.markdown create mode 100644 website/source/docs/providers/google/r/google_project.html.markdown diff --git a/builtin/providers/google/data_source_google_iam_policy_document.go b/builtin/providers/google/data_source_google_iam_policy.go similarity index 84% rename from builtin/providers/google/data_source_google_iam_policy_document.go rename to builtin/providers/google/data_source_google_iam_policy.go index 79cdabd5d..e47b0f009 100644 --- a/builtin/providers/google/data_source_google_iam_policy_document.go +++ b/builtin/providers/google/data_source_google_iam_policy.go @@ -9,6 +9,25 @@ import ( "google.golang.org/api/cloudresourcemanager/v1" ) +var iamBinding *schema.Schema = &schema.Schema{ + Type: schema.TypeSet, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "role": { + Type: schema.TypeString, + Required: true, + }, + "members": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + }, + }, +} + // dataSourceGoogleIamPolicy returns a *schema.Resource that allows a customer // to express a Google Cloud IAM policy in a data resource. This is an example // of how the schema would be used in a config: @@ -25,25 +44,8 @@ func dataSourceGoogleIamPolicy() *schema.Resource { return &schema.Resource{ Read: dataSourceGoogleIamPolicyRead, Schema: map[string]*schema.Schema{ - "binding": { - Type: schema.TypeSet, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "role": { - Type: schema.TypeString, - Required: true, - }, - "members": { - Type: schema.TypeSet, - Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, - }, - }, - }, - }, - "policy": { + "binding": iamBinding, + "policy_data": { Type: schema.TypeString, Computed: true, }, @@ -81,7 +83,7 @@ func dataSourceGoogleIamPolicyRead(d *schema.ResourceData, meta interface{}) err } pstring := string(pjson) - d.Set("policy", pstring) + d.Set("policy_data", pstring) d.SetId(strconv.Itoa(hashcode.String(pstring))) return nil diff --git a/builtin/providers/google/resource_google_project.go b/builtin/providers/google/resource_google_project.go index b922951bb..b46d66145 100644 --- a/builtin/providers/google/resource_google_project.go +++ b/builtin/providers/google/resource_google_project.go @@ -31,31 +31,23 @@ func resourceGoogleProject() *schema.Resource { Delete: resourceGoogleProjectDelete, Schema: map[string]*schema.Schema{ - "project": &schema.Schema{ + "id": &schema.Schema{ Type: schema.TypeString, Required: true, ForceNew: true, }, - - "policy": &schema.Schema{ + "policy_data": &schema.Schema{ Type: schema.TypeString, Optional: true, }, - "name": &schema.Schema{ Type: schema.TypeString, Computed: true, }, - "number": &schema.Schema{ Type: schema.TypeString, Computed: true, }, - - "id": &schema.Schema{ - Type: schema.TypeString, - Computed: true, - }, }, } } @@ -77,7 +69,7 @@ func resourceGoogleProjectCreate(d *schema.ResourceData, meta interface{}) error } // Apply the IAM policy if it is set - if pString, ok := d.GetOk("policy"); ok { + if pString, ok := d.GetOk("policy_data"); ok { // The policy string is just a marshaled cloudresourcemanager.Policy. // Unmarshal it to a struct. var policy cloudresourcemanager.Policy @@ -116,6 +108,7 @@ func resourceGoogleProjectRead(d *schema.ResourceData, meta interface{}) error { if err != nil { return err } + d.SetId(project) // Confirm the project exists. // TODO(evanbrown): Support project creation @@ -141,10 +134,10 @@ func resourceGoogleProjectUpdate(d *schema.ResourceData, meta interface{}) error } // Policy has changed - if ok := d.HasChange("policy"); ok { + if ok := d.HasChange("policy_data"); ok { // The policy string is just a marshaled cloudresourcemanager.Policy. // Unmarshal it to a struct that contains the old and new policies - oldP, newP := d.GetChange("policy") + oldP, newP := d.GetChange("policy_data") oldPString := oldP.(string) newPString := newP.(string) diff --git a/builtin/providers/google/resource_google_project_test.go b/builtin/providers/google/resource_google_project_test.go index c5b4ad7c7..f9208e11e 100644 --- a/builtin/providers/google/resource_google_project_test.go +++ b/builtin/providers/google/resource_google_project_test.go @@ -133,9 +133,9 @@ func testAccCheckGoogleProjectIamPolicyIsMerged(projectRes, policyRes string, or var projectP, policyP cloudresourcemanager.Policy // The project should have a policy - ps, ok := project.Primary.Attributes["policy"] + ps, ok := project.Primary.Attributes["policy_data"] if !ok { - return fmt.Errorf("Project resource %q did not have a 'policy' attribute", project.Primary.ID) + return fmt.Errorf("Project resource %q did not have a 'policy_data' attribute. Attributes were %#v", project.Primary.Attributes["id"], project.Primary.Attributes) } if err := json.Unmarshal([]byte(ps), &projectP); err != nil { return err @@ -146,9 +146,9 @@ func testAccCheckGoogleProjectIamPolicyIsMerged(projectRes, policyRes string, or if !ok { return fmt.Errorf("Not found: %s", policyRes) } - ps, ok = policy.Primary.Attributes["policy"] + ps, ok = policy.Primary.Attributes["policy_data"] if !ok { - return fmt.Errorf("Policy resource %q did not have a 'policy' attribute", policy.Primary.ID) + return fmt.Errorf("Data policy resource %q did not have a 'policy_data' attribute. Attributes were %#v", policy.Primary.Attributes["id"], project.Primary.Attributes) } if err := json.Unmarshal([]byte(ps), &policyP); err != nil { return err @@ -158,7 +158,6 @@ func testAccCheckGoogleProjectIamPolicyIsMerged(projectRes, policyRes string, or if !reflect.DeepEqual(derefBindings(projectP.Bindings), derefBindings(policyP.Bindings)) { return fmt.Errorf("Project and data source policies do not match: project policy is %+v, data resource policy is %+v", derefBindings(projectP.Bindings), derefBindings(policyP.Bindings)) } - return nil // Merge the project policy in Terrafomr state with the policy the project had before the config was applied expected := make([]*cloudresourcemanager.Binding, 0) @@ -446,13 +445,13 @@ func (b Binding) Less(i, j int) bool { var testAccGoogleProject_basic = ` resource "google_project" "acceptance" { - project = "%v" + id = "%v" }` var testAccGoogleProject_policy1 = ` resource "google_project" "acceptance" { - project = "%v" - policy = "${data.google_iam_policy.admin.policy}" + id = "%v" + policy_data = "${data.google_iam_policy.admin.policy_data}" } data "google_iam_policy" "admin" { diff --git a/website/source/docs/providers/google/d/google_iam_policy.html.markdown b/website/source/docs/providers/google/d/google_iam_policy.html.markdown new file mode 100644 index 000000000..4151fdc9f --- /dev/null +++ b/website/source/docs/providers/google/d/google_iam_policy.html.markdown @@ -0,0 +1,60 @@ +--- +layout: "google" +page_title: "Google: google_iam_policy" +sidebar_current: "docs-google-datasource-iam-policy" +description: |- + Generates an IAM policy that can be referenced by other resources, applying + the policy to them. +--- + +# google\_iam\_policy + +Generates an IAM policy document that may be referenced by and applied to +other Google Cloud Platform resources, such as the `google_project` resource. + +``` +data "google_iam_policy" "admin" { + binding { + role = "roles/compute.instanceAdmin" + members = [ + "serviceAccount:your-custom-sa@your-project.iam.gserviceaccount.com", + ] + } + binding { + role = "roles/storage.objectViewer" + members = [ + "user:evanbrown@google.com", + ] + } +} +``` + +This data source is used to define IAM policies to apply to othe resources. +Currently, defining a policy through a datasource and referencing that policy +from another resource is the only way to apply an IAM policy to a resource. + +## Argument Reference + +The following arguments are supported: + +* `binding` (Required) - A nested configuration block (described below) + defining a binding to be included in the policy document. Multiple + `binding` arguments are supported. + +Each document configuration must have one or more `binding` blocks, which +each accept the following arguments: + +* `role` (Required) - The role/permission that will be granted to the members. + See the [IAM Roles](https://cloud.google.com/compute/docs/access/iam) documentation for a complete list of roles. +* `members` (Required) - An array of users/principals that will be granted + the privilege in the `role`. For a human user, prefix the user's e-mail + address with `user:` (e.g., `user:evandbrown@gmail.com`). For a service + account, prefix the service account e-mail address with `serviceAccount:` + (e.g., `serviceAccount:your-service-account@your-project.iam.gserviceaccount.com`). + +## Attributes Reference + +The following attribute is exported: + +* `policy_data` - The above bindings serialized in a format suitable for + referencing from a resource that supports IAM. diff --git a/website/source/docs/providers/google/r/google_project.html.markdown b/website/source/docs/providers/google/r/google_project.html.markdown new file mode 100644 index 000000000..72a34c5ca --- /dev/null +++ b/website/source/docs/providers/google/r/google_project.html.markdown @@ -0,0 +1,61 @@ +--- +layout: "google" +page_title: "Google: google_project" +sidebar_current: "docs-google-project" +description: |- + Allows management of a Google Cloud Platform project. +--- + +# google\_project + +Allows management of an existing Google Cloud Platform project, and is +currently limited to adding or modifying the IAM Policy for the project. + +When adding a policy to a project, the policy will be merged with the +project's existing policy. The policy is always specified in a +`google_iam_policy` data source and referencd from the project's +`policy_data` attribute. + +## Example Usage + +```js +resource "google_project" "my-project" { + id = "your-project-id" + policy_data = "${data.google_iam_policy.admin.policy}" +} + +data "google_iam_policy" "admin" { + binding { + role = "roles/storage.objectViewer" + members = [ + "user:evandbrown@gmail.com", + ] + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `id` - (Required) The project ID. + Changing this forces a new project to be referenced. + +* `policy` - (Optional) The `google_iam_policy` data source that represents + the IAM policy that will be applied to the project. The policy will be + merged with any existing policy applied to the project. + + Changing this updates the policy. + + Deleting this removes the policy, but leaves the original project policy + intact. If there are overlapping `binding` entries between the original + project policy and the data source policy, they will be removed. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are +exported: + +* `name` - The name of the project. + +* `number` - The numeric identifier of the project.