Skip to content

Commit

Permalink
add new resource iam_folders_policy_binding. addresses hashicorp/terr…
Browse files Browse the repository at this point in the history
derekchu-google authored Nov 11, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent a5e30bb commit aebe935
Showing 4 changed files with 360 additions and 0 deletions.
190 changes: 190 additions & 0 deletions mmv1/products/iam3/FoldersPolicyBinding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# Copyright 2024 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

---
name: 'FoldersPolicyBinding'
description: A policy binding to a folder
references:
guides:
'Apply a policy binding': 'https://cloud.google.com/iam/docs/principal-access-boundary-policies-create#create_binding'
api: 'https://cloud.google.com/iam/docs/reference/rest/v3beta/folders.locations.policyBindings'
min_version: 'beta'
id_format: 'folders/{{folder}}/locations/{{location}}/policyBindings/{{policy_binding_id}}'
base_url: 'folders/{{folder}}/locations/{{location}}/policyBindings'
self_link: 'folders/{{folder}}/locations/{{location}}/policyBindings/{{policy_binding_id}}'
create_url: 'folders/{{folder}}/locations/{{location}}/policyBindings?policyBindingId={{policy_binding_id}}'
update_verb: 'PATCH'
update_mask: true
import_format:
- 'folders/{{folder}}/locations/{{location}}/policyBindings/{{policy_binding_id}}'
timeouts:
insert_minutes: 20
update_minutes: 20
delete_minutes: 20
custom_code:
post_delete: 'templates/terraform/post_delete/sleep.go.tmpl'
autogen_async: true
async:
actions: ['create', 'delete', 'update']
type: 'OpAsync'
operation:
base_url: '{{op_id}}'
path: 'name'
wait_ms: 1000
result:
path: 'response'
resource_inside_response: true
error:
path: 'error'
message: 'message'
examples:
- name: 'iam_folders_policy_binding'
min_version: 'beta'
primary_resource_id: 'my-folder-binding'
test_env_vars:
org_id: 'ORG_ID'
vars:
pab_policy_id: 'my-pab-policy'
display_name: 'test folder binding'
folder_binding_id: 'test-folder-binding'
folder_name: 'test folder'
external_providers: ["time"]
parameters:
- name: 'folder'
type: String
description: |
The parent folder for the PolicyBinding.
url_param_only: true
required: true
immutable: true
- name: 'location'
type: String
description: |
The location of the PolicyBinding.
url_param_only: true
required: true
immutable: true
- name: 'policyBindingId'
type: String
description: |
The Policy Binding ID.
url_param_only: true
required: true
immutable: true
properties:
- name: 'name'
type: String
description: |
The name of the policy binding in the format `{binding_parent/locations/{location}/policyBindings/{policy_binding_id}`
output: true
- name: 'uid'
type: String
description: |
Output only. The globally unique ID of the policy binding. Assigned when the policy binding is created.
output: true
- name: 'etag'
type: String
description: |
Optional. The etag for the policy binding. If this is provided on update, it must match the server's etag.
output: true
- name: 'displayName'
type: String
description: |
Optional. The description of the policy binding. Must be less than or equal to 63 characters.
- name: 'annotations'
type: KeyValueAnnotations
description: |
Optional. User defined annotations. See https://google.aip.dev/148#annotations for more details such as format and size limitations
- name: 'target'
type: NestedObject
description: |
Target is the full resource name of the resource to which the policy will be bound. Immutable once set.
required: true
properties:
- name: 'principalSet'
type: String
description: |
Required. Immutable. The resource name of the policy to be bound.
The binding parent and policy must belong to the same Organization (or Project).
immutable: true
- name: 'policyKind'
type: String
description: |
Immutable. The kind of the policy to attach in this binding. This
field must be one of the following: - Left empty (will be automatically set
to the policy kind) - The input policy kind Possible values: POLICY_KIND_UNSPECIFIED PRINCIPAL_ACCESS_BOUNDARY ACCESS
immutable: true
- name: 'policy'
type: String
description: |
Required. Immutable. The resource name of the policy to be bound. The binding parent and policy must belong to the same Organization (or Project).
required: true
immutable: true
- name: 'policyUid'
type: String
description: |
Output only. The globally unique ID of the policy to be bound.
output: true
- name: 'condition'
type: NestedObject
description: |
Represents a textual expression in the Common Expression Language
(CEL) syntax. CEL is a C-like expression language. The syntax and semantics of
CEL are documented at https://github.com/google/cel-spec.
Example (Comparison):
title: \"Summary size limit\"
description: \"Determines if a summary is less than 100 chars\"
expression: \"document.summary.size() < 100\"
Example
(Equality):
title: \"Requestor is owner\"
description: \"Determines if requestor is the document owner\"
expression: \"document.owner == request.auth.claims.email\" Example
(Logic):
title: \"Public documents\"
description: \"Determine whether the document should be publicly visible\"
expression: \"document.type != 'private' && document.type != 'internal'\"
Example (Data Manipulation):
title: \"Notification string\"
description: \"Create a notification string with a timestamp.\"
expression: \"'New message received at ' + string(document.create_time)\"
The exact variables and functions that may be referenced within an expression are
determined by the service that evaluates it. See the service documentation for
additional information.
properties:
- name: 'expression'
type: String
description: |
Textual representation of an expression in Common Expression Language syntax.
- name: 'title'
type: String
description: |
Optional. Title for the expression, i.e. a short string describing its purpose. This can be used e.g. in UIs which allow to enter the expression.
- name: 'description'
type: String
description: |
Optional. Description of the expression. This is a longer text which describes the expression, e.g. when hovered over it in a UI.
- name: 'location'
type: String
description: |
Optional. String indicating the location of the expression for error reporting, e.g. a file name and a position in the file.
- name: 'createTime'
type: String
description: |
Output only. The time when the policy binding was created.
output: true
- name: 'updateTime'
type: String
description: |
Output only. The time when the policy binding was most recently updated.
output: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
resource "google_iam_principal_access_boundary_policy" "pab_policy" {
provider = google-beta
organization = "{{index $.TestEnvVars "org_id"}}"
location = "global"
display_name = "{{index $.Vars "display_name"}}"
principal_access_boundary_policy_id = "{{index $.Vars "pab_policy_id"}}"
}

resource "google_folder" "folder" {
provider = google-beta
display_name = "{{index $.Vars "folder_name"}}"
parent = "organizations/{{index $.TestEnvVars "org_id"}}"
deletion_protection = false
}

resource "time_sleep" "wait_120s" {
depends_on = [google_folder.folder]
create_duration = "120s"
}

resource "google_iam_folders_policy_binding" "{{$.PrimaryResourceId}}" {
provider = google-beta
folder = google_folder.folder.folder_id
location = "global"
display_name = "{{index $.Vars "display_name"}}"
policy_kind = "PRINCIPAL_ACCESS_BOUNDARY"
policy_binding_id = "{{index $.Vars "folder_binding_id"}}"
policy = "organizations/{{index $.TestEnvVars "org_id"}}/locations/global/principalAccessBoundaryPolicies/${google_iam_principal_access_boundary_policy.pab_policy.principal_access_boundary_policy_id}"
target {
principal_set = "//cloudresourcemanager.googleapis.com/folders/${google_folder.folder.folder_id}"
}
depends_on = [time_sleep.wait_120s]
}
3 changes: 3 additions & 0 deletions mmv1/templates/terraform/post_delete/sleep.go.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This is useful if the resource in question doesn't have a perfectly consistent API
// That is, if the deletion of a dependent resource has not propagated.
time.Sleep(5 * time.Second)
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package iam3_test
{{- if ne $.TargetVersionName "ga" }}

import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"

"github.com/hashicorp/terraform-provider-google/google/acctest"
"github.com/hashicorp/terraform-provider-google/google/envvar"
)

func TestAccIAM3FoldersPolicyBinding_iamFoldersPolicyBindingExample_update(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"org_id": envvar.GetTestOrgFromEnv(t),
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t),
ExternalProviders: map[string]resource.ExternalProvider{
"time": {},
},
CheckDestroy: testAccCheckIAM3FoldersPolicyBindingDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccIAM3FoldersPolicyBinding_iamFoldersPolicyBindingExample_full(context),
},
{
ResourceName: "google_iam_folders_policy_binding.my-folder-binding",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"annotations", "folder", "location", "policy_binding_id"},
},
{
Config: testAccIAM3FoldersPolicyBinding_iamFoldersPolicyBindingExample_update(context),
},
{
ResourceName: "google_iam_folders_policy_binding.my-folder-binding",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"annotations", "folder", "location", "policy_binding_id"},
},
},
})
}

func testAccIAM3FoldersPolicyBinding_iamFoldersPolicyBindingExample_full(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_iam_principal_access_boundary_policy" "pab_policy" {
provider = google-beta
organization = "%{org_id}"
location = "global"
display_name = "test folder binding%{random_suffix}"
principal_access_boundary_policy_id = "tf-test-my-pab-policy%{random_suffix}"
}

resource "google_folder" "folder" {
provider = google-beta
display_name = "test folder%{random_suffix}"
parent = "organizations/%{org_id}"
deletion_protection = false
}

resource "time_sleep" "wait_120s" {
depends_on = [google_folder.folder]
create_duration = "120s"
}

resource "google_iam_folders_policy_binding" "my-folder-binding" {
provider = google-beta
folder = google_folder.folder.folder_id
location = "global"
display_name = "test folder binding%{random_suffix}"
policy_kind = "PRINCIPAL_ACCESS_BOUNDARY"
policy_binding_id = "tf-test-folder-binding%{random_suffix}"
policy = "organizations/%{org_id}/locations/global/principalAccessBoundaryPolicies/${google_iam_principal_access_boundary_policy.pab_policy.principal_access_boundary_policy_id}"
target {
principal_set = "//cloudresourcemanager.googleapis.com/folders/${google_folder.folder.folder_id}"
}
depends_on = [time_sleep.wait_120s]
}
`, context)
}

func testAccIAM3FoldersPolicyBinding_iamFoldersPolicyBindingExample_update(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_iam_principal_access_boundary_policy" "pab_policy" {
provider = google-beta
organization = "%{org_id}"
location = "global"
display_name = "test folder binding%{random_suffix}"
principal_access_boundary_policy_id = "tf-test-my-pab-policy%{random_suffix}"
}

resource "google_folder" "folder" {
provider = google-beta
display_name = "test folder%{random_suffix}"
parent = "organizations/%{org_id}"
deletion_protection = false
}

resource "time_sleep" "wait_120s" {
depends_on = [google_folder.folder]
create_duration = "120s"
}

resource "google_iam_folders_policy_binding" "my-folder-binding" {
provider = google-beta
folder = google_folder.folder.folder_id
location = "global"
display_name = "test folder binding%{random_suffix}"
policy_kind = "PRINCIPAL_ACCESS_BOUNDARY"
policy_binding_id = "tf-test-folder-binding%{random_suffix}"
policy = "organizations/%{org_id}/locations/global/principalAccessBoundaryPolicies/${google_iam_principal_access_boundary_policy.pab_policy.principal_access_boundary_policy_id}"
annotations = {"foo": "bar"}
target {
principal_set = "//cloudresourcemanager.googleapis.com/folders/${google_folder.folder.folder_id}"
}
condition {
description = "test condition"
expression = "principal.subject == 'al@a.com'"
location = "test location"
title = "test title"
}
depends_on = [time_sleep.wait_120s]
}
`, context)
}

{{- end }}

0 comments on commit aebe935

Please sign in to comment.