mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-07-03 08:42:39 +00:00
Add 'google_folder_iam_binding' and 'google_folder_iam_member' resources (#1076)
This commit is contained in:
parent
509614e404
commit
21e0075f6f
|
@ -2,11 +2,13 @@ package google
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/errwrap"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"google.golang.org/api/cloudresourcemanager/v1"
|
||||
resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1"
|
||||
"strings"
|
||||
"google.golang.org/api/googleapi"
|
||||
)
|
||||
|
||||
var IamFolderSchema = map[string]*schema.Schema{
|
||||
|
@ -35,19 +37,7 @@ func FolderIdParseFunc(d *schema.ResourceData, _ *Config) error {
|
|||
}
|
||||
|
||||
func (u *FolderIamUpdater) GetResourceIamPolicy() (*cloudresourcemanager.Policy, error) {
|
||||
p, err := u.Config.clientResourceManagerV2Beta1.Folders.GetIamPolicy(u.folderId,
|
||||
&resourceManagerV2Beta1.GetIamPolicyRequest{}).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error retrieving IAM policy for %s: %s", u.DescribeResource(), err)
|
||||
}
|
||||
|
||||
v1Policy, err := v2BetaPolicyToV1(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return v1Policy, nil
|
||||
return getFolderIamPolicyByFolderName(u.folderId, u.Config)
|
||||
}
|
||||
|
||||
func (u *FolderIamUpdater) SetResourceIamPolicy(policy *cloudresourcemanager.Policy) error {
|
||||
|
@ -105,3 +95,42 @@ func v2BetaPolicyToV1(in *resourceManagerV2Beta1.Policy) (*cloudresourcemanager.
|
|||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Retrieve the existing IAM Policy for a folder
|
||||
func getFolderIamPolicyByFolderName(folderName string, config *Config) (*cloudresourcemanager.Policy, error) {
|
||||
p, err := config.clientResourceManagerV2Beta1.Folders.GetIamPolicy(folderName,
|
||||
&resourceManagerV2Beta1.GetIamPolicyRequest{}).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error retrieving IAM policy for folder %q: %s", folderName, err)
|
||||
}
|
||||
|
||||
v1Policy, err := v2BetaPolicyToV1(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return v1Policy, nil
|
||||
}
|
||||
|
||||
func getFolderIamPolicyByParentAndDisplayName(parent, displayName string, config *Config) (*cloudresourcemanager.Policy, error) {
|
||||
queryString := fmt.Sprintf("lifecycleState=ACTIVE AND parent=%s AND displayName=%s", parent, displayName)
|
||||
searchRequest := &resourceManagerV2Beta1.SearchFoldersRequest{
|
||||
Query: queryString,
|
||||
}
|
||||
searchResponse, err := config.clientResourceManagerV2Beta1.Folders.Search(searchRequest).Do()
|
||||
if err != nil {
|
||||
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
|
||||
return nil, fmt.Errorf("Folder Not Found: %s,%s", parent, displayName)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Error reading folders: %s", err)
|
||||
}
|
||||
|
||||
folders := searchResponse.Folders
|
||||
if len(folders) != 1 {
|
||||
return nil, fmt.Errorf("More than one folder found")
|
||||
}
|
||||
|
||||
return getFolderIamPolicyByFolderName(folders[0].Name, config)
|
||||
}
|
||||
|
|
|
@ -142,6 +142,8 @@ func Provider() terraform.ResourceProvider {
|
|||
"google_dns_record_set": resourceDnsRecordSet(),
|
||||
"google_endpoints_service": resourceEndpointsService(),
|
||||
"google_folder": resourceGoogleFolder(),
|
||||
"google_folder_iam_binding": ResourceIamBindingWithImport(IamFolderSchema, NewFolderIamUpdater, FolderIdParseFunc),
|
||||
"google_folder_iam_member": ResourceIamMemberWithImport(IamFolderSchema, NewFolderIamUpdater, FolderIdParseFunc),
|
||||
"google_folder_iam_policy": ResourceIamPolicyWithImport(IamFolderSchema, NewFolderIamUpdater, FolderIdParseFunc),
|
||||
"google_folder_organization_policy": resourceGoogleFolderOrganizationPolicy(),
|
||||
"google_logging_billing_account_sink": resourceLoggingBillingAccountSink(),
|
||||
|
|
323
google/resource_google_folder_iam_binding_test.go
Normal file
323
google/resource_google_folder_iam_binding_test.go
Normal file
|
@ -0,0 +1,323 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"google.golang.org/api/cloudresourcemanager/v1"
|
||||
)
|
||||
|
||||
// Test that an IAM binding can be applied to a folder
|
||||
func TestAccGoogleFolderIamBinding_basic(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org := getTestOrgFromEnv(t)
|
||||
fname := "terraform-" + acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
// Create a new folder
|
||||
{
|
||||
Config: testAccGoogleFolderIamBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccGoogleFolderExistingPolicy(org, fname),
|
||||
),
|
||||
},
|
||||
// Apply an IAM binding
|
||||
{
|
||||
Config: testAccGoogleFolderAssociateBindingBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_binding.acceptance", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:admin@hashicorptest.com"},
|
||||
}, org, fname),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Test that multiple IAM bindings can be applied to a folder, one at a time
|
||||
func TestAccGoogleFolderIamBinding_multiple(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org := getTestOrgFromEnv(t)
|
||||
fname := "terraform-" + acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
// Create a new folder
|
||||
{
|
||||
Config: testAccGoogleFolderIamBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccGoogleFolderExistingPolicy(org, fname),
|
||||
),
|
||||
},
|
||||
// Apply an IAM binding
|
||||
{
|
||||
Config: testAccGoogleFolderAssociateBindingBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_binding.acceptance", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:admin@hashicorptest.com"},
|
||||
}, org, fname),
|
||||
),
|
||||
},
|
||||
// Apply another IAM binding
|
||||
{
|
||||
Config: testAccGoogleFolderAssociateBindingMultiple(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_binding.multiple", &cloudresourcemanager.Binding{
|
||||
Role: "roles/viewer",
|
||||
Members: []string{"user:paddy@hashicorp.com"},
|
||||
}, org, fname),
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_binding.multiple", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:admin@hashicorptest.com"},
|
||||
}, org, fname),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Test that multiple IAM bindings can be applied to a folder all at once
|
||||
func TestAccGoogleFolderIamBinding_multipleAtOnce(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org := getTestOrgFromEnv(t)
|
||||
fname := "terraform-" + acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
// Create a new folder
|
||||
{
|
||||
Config: testAccGoogleFolderIamBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccGoogleFolderExistingPolicy(org, fname),
|
||||
),
|
||||
},
|
||||
// Apply an IAM binding
|
||||
{
|
||||
Config: testAccGoogleFolderAssociateBindingMultiple(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_binding.acceptance", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:admin@hashicorptest.com"},
|
||||
}, org, fname),
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_binding.multiple", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:admin@hashicorptest.com"},
|
||||
}, org, fname),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Test that an IAM binding can be updated once applied to a folder
|
||||
func TestAccGoogleFolderIamBinding_update(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org := getTestOrgFromEnv(t)
|
||||
fname := "terraform-" + acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
// Create a new folder
|
||||
{
|
||||
Config: testAccGoogleFolderIamBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccGoogleFolderExistingPolicy(org, fname),
|
||||
),
|
||||
},
|
||||
// Apply an IAM binding
|
||||
{
|
||||
Config: testAccGoogleFolderAssociateBindingBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_binding.acceptance", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:admin@hashicorptest.com"},
|
||||
}, org, fname),
|
||||
),
|
||||
},
|
||||
// Apply an updated IAM binding
|
||||
{
|
||||
Config: testAccGoogleFolderAssociateBindingUpdated(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_binding.updated", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:admin@hashicorptest.com", "user:paddy@hashicorp.com"},
|
||||
}, org, fname),
|
||||
),
|
||||
},
|
||||
// Drop the original member
|
||||
{
|
||||
Config: testAccGoogleFolderAssociateBindingDropMemberFromBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_binding.dropped", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:paddy@hashicorp.com"},
|
||||
}, org, fname),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Test that an IAM binding can be removed from a folder
|
||||
func TestAccGoogleFolderIamBinding_remove(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org := getTestOrgFromEnv(t)
|
||||
fname := "terraform-" + acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
// Create a new folder
|
||||
{
|
||||
Config: testAccGoogleFolderIamBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccGoogleFolderExistingPolicy(org, fname),
|
||||
),
|
||||
},
|
||||
// Apply multiple IAM bindings
|
||||
{
|
||||
Config: testAccGoogleFolderAssociateBindingMultiple(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_binding.multiple", &cloudresourcemanager.Binding{
|
||||
Role: "roles/viewer",
|
||||
Members: []string{"user:paddy@hashicorp.com"},
|
||||
}, org, fname),
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_binding.acceptance", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:admin@hashicorptest.com"},
|
||||
}, org, fname),
|
||||
),
|
||||
},
|
||||
// Remove the bindings
|
||||
{
|
||||
Config: testAccGoogleFolderIamBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccGoogleFolderExistingPolicy(org, fname),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckGoogleFolderIamBindingExists(key string, expected *cloudresourcemanager.Binding, org, fname string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
folderPolicy, err := getFolderIamPolicyByParentAndDisplayName("organizations/"+org, fname, config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to retrieve IAM policy for folder %q: %s", fname, err)
|
||||
}
|
||||
|
||||
var result *cloudresourcemanager.Binding
|
||||
for _, binding := range folderPolicy.Bindings {
|
||||
if binding.Role == expected.Role {
|
||||
result = binding
|
||||
break
|
||||
}
|
||||
}
|
||||
if result == nil {
|
||||
return fmt.Errorf("IAM policy for folder %q had no role %q, got %#v", fname, expected.Role, folderPolicy.Bindings)
|
||||
}
|
||||
if len(result.Members) != len(expected.Members) {
|
||||
return fmt.Errorf("Got %v as members for role %q of folder %q, expected %v", result.Members, expected.Role, fname, expected.Members)
|
||||
}
|
||||
sort.Strings(result.Members)
|
||||
sort.Strings(expected.Members)
|
||||
for pos, exp := range expected.Members {
|
||||
if result.Members[pos] != exp {
|
||||
return fmt.Errorf("Expected members for role %q of folder %q to be %v, got %v", expected.Role, fname, expected.Members, result.Members)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccGoogleFolderIamBasic(org, fname string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_folder" "acceptance" {
|
||||
parent = "organizations/%s"
|
||||
display_name = "%s"
|
||||
}
|
||||
`, org, fname)
|
||||
}
|
||||
|
||||
func testAccGoogleFolderAssociateBindingBasic(org, fname string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_folder" "acceptance" {
|
||||
parent = "organizations/%s"
|
||||
display_name = "%s"
|
||||
}
|
||||
|
||||
resource "google_folder_iam_binding" "acceptance" {
|
||||
folder = "${google_folder.acceptance.name}"
|
||||
members = ["user:admin@hashicorptest.com"]
|
||||
role = "roles/compute.instanceAdmin"
|
||||
}
|
||||
`, org, fname)
|
||||
}
|
||||
|
||||
func testAccGoogleFolderAssociateBindingMultiple(org, fname string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_folder" "acceptance" {
|
||||
parent = "organizations/%s"
|
||||
display_name = "%s"
|
||||
}
|
||||
|
||||
resource "google_folder_iam_binding" "acceptance" {
|
||||
folder = "${google_folder.acceptance.name}"
|
||||
members = ["user:admin@hashicorptest.com"]
|
||||
role = "roles/compute.instanceAdmin"
|
||||
}
|
||||
|
||||
resource "google_folder_iam_binding" "multiple" {
|
||||
folder = "${google_folder.acceptance.name}"
|
||||
members = ["user:paddy@hashicorp.com"]
|
||||
role = "roles/viewer"
|
||||
}
|
||||
`, org, fname)
|
||||
}
|
||||
|
||||
func testAccGoogleFolderAssociateBindingUpdated(org, fname string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_folder" "acceptance" {
|
||||
parent = "organizations/%s"
|
||||
display_name = "%s"
|
||||
}
|
||||
|
||||
resource "google_folder_iam_binding" "acceptance" {
|
||||
folder = "${google_folder.acceptance.name}"
|
||||
members = ["user:admin@hashicorptest.com", "user:paddy@hashicorp.com"]
|
||||
role = "roles/compute.instanceAdmin"
|
||||
}
|
||||
`, org, fname)
|
||||
}
|
||||
|
||||
func testAccGoogleFolderAssociateBindingDropMemberFromBasic(org, fname string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_folder" "acceptance" {
|
||||
parent = "organizations/%s"
|
||||
display_name = "%s"
|
||||
}
|
||||
|
||||
resource "google_folder_iam_binding" "dropped" {
|
||||
folder = "${google_folder.acceptance.name}"
|
||||
members = ["user:paddy@hashicorp.com"]
|
||||
role = "roles/compute.instanceAdmin"
|
||||
}
|
||||
`, org, fname)
|
||||
}
|
156
google/resource_google_folder_iam_member_test.go
Normal file
156
google/resource_google_folder_iam_member_test.go
Normal file
|
@ -0,0 +1,156 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"google.golang.org/api/cloudresourcemanager/v1"
|
||||
)
|
||||
|
||||
// Test that an IAM binding can be applied to a folder
|
||||
func TestAccGoogleFolderIamMember_basic(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org := getTestOrgFromEnv(t)
|
||||
fname := "terraform-" + acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
// Create a new folder
|
||||
{
|
||||
Config: testAccGoogleFolderIamBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccGoogleFolderExistingPolicy(org, fname),
|
||||
),
|
||||
},
|
||||
// Apply an IAM binding
|
||||
{
|
||||
Config: testAccGoogleFolderAssociateMemberBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_member.acceptance", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:admin@hashicorptest.com"},
|
||||
}, org, fname),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Test that multiple IAM bindings can be applied to a folder
|
||||
func TestAccGoogleFolderIamMember_multiple(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org := getTestOrgFromEnv(t)
|
||||
fname := "terraform-" + acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
// Create a new folder
|
||||
{
|
||||
Config: testAccGoogleFolderIamBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccGoogleFolderExistingPolicy(org, fname),
|
||||
),
|
||||
},
|
||||
// Apply an IAM binding
|
||||
{
|
||||
Config: testAccGoogleFolderAssociateMemberBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_member.acceptance", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:admin@hashicorptest.com"},
|
||||
}, org, fname),
|
||||
),
|
||||
},
|
||||
// Apply another IAM binding
|
||||
{
|
||||
Config: testAccGoogleFolderAssociateMemberMultiple(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_member.multiple", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:admin@hashicorptest.com", "user:paddy@hashicorp.com"},
|
||||
}, org, fname),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Test that an IAM binding can be removed from a folder
|
||||
func TestAccGoogleFolderIamMember_remove(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org := getTestOrgFromEnv(t)
|
||||
fname := "terraform-" + acctest.RandString(10)
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
Steps: []resource.TestStep{
|
||||
// Create a new folder
|
||||
{
|
||||
Config: testAccGoogleFolderIamBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccGoogleFolderExistingPolicy(org, fname),
|
||||
),
|
||||
},
|
||||
// Apply multiple IAM bindings
|
||||
{
|
||||
Config: testAccGoogleFolderAssociateMemberMultiple(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGoogleFolderIamBindingExists("google_folder_iam_member.acceptance", &cloudresourcemanager.Binding{
|
||||
Role: "roles/compute.instanceAdmin",
|
||||
Members: []string{"user:admin@hashicorptest.com", "user:paddy@hashicorp.com"},
|
||||
}, org, fname),
|
||||
),
|
||||
},
|
||||
// Remove the bindings
|
||||
{
|
||||
Config: testAccGoogleFolderIamBasic(org, fname),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccGoogleFolderExistingPolicy(org, fname),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccGoogleFolderAssociateMemberBasic(org, fname string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_folder" "acceptance" {
|
||||
parent = "organizations/%s"
|
||||
display_name = "%s"
|
||||
}
|
||||
|
||||
resource "google_folder_iam_member" "acceptance" {
|
||||
folder = "${google_folder.acceptance.name}"
|
||||
member = "user:admin@hashicorptest.com"
|
||||
role = "roles/compute.instanceAdmin"
|
||||
}
|
||||
`, org, fname)
|
||||
}
|
||||
|
||||
func testAccGoogleFolderAssociateMemberMultiple(org, fname string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_folder" "acceptance" {
|
||||
parent = "organizations/%s"
|
||||
display_name = "%s"
|
||||
}
|
||||
|
||||
resource "google_folder_iam_member" "acceptance" {
|
||||
folder = "${google_folder.acceptance.name}"
|
||||
member = "user:admin@hashicorptest.com"
|
||||
role = "roles/compute.instanceAdmin"
|
||||
}
|
||||
|
||||
resource "google_folder_iam_member" "multiple" {
|
||||
folder = "${google_folder.acceptance.name}"
|
||||
member = "user:paddy@hashicorp.com"
|
||||
role = "roles/compute.instanceAdmin"
|
||||
}
|
||||
`, org, fname)
|
||||
}
|
|
@ -3,12 +3,13 @@ package google
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAccGoogleFolderIamPolicy_basic(t *testing.T) {
|
||||
|
@ -145,6 +146,22 @@ func testAccCheckGoogleFolderIamPolicy(n string, policy *resourceManagerV2Beta1.
|
|||
}
|
||||
}
|
||||
|
||||
// Confirm that a folder has an IAM policy with at least 1 binding
|
||||
func testAccGoogleFolderExistingPolicy(org, fname string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
c := testAccProvider.Meta().(*Config)
|
||||
var err error
|
||||
originalPolicy, err = getFolderIamPolicyByParentAndDisplayName("organizations/"+org, fname, c)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to retrieve IAM Policy for folder %q: %s", fname, err)
|
||||
}
|
||||
if len(originalPolicy.Bindings) == 0 {
|
||||
return fmt.Errorf("Refuse to run test against folder with zero IAM Bindings. This is likely an error in the test code that is not properly identifying the IAM policy of a folder.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccGoogleFolderIamPolicy_basic(folder, parent string, policy *resourceManagerV2Beta1.Policy) string {
|
||||
var bindingBuffer bytes.Buffer
|
||||
|
||||
|
|
66
website/docs/r/google_folder_iam_binding.html.markdown
Normal file
66
website/docs/r/google_folder_iam_binding.html.markdown
Normal file
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
layout: "google"
|
||||
page_title: "Google: google_folder_iam_binding"
|
||||
sidebar_current: "docs-google-folder-iam-binding"
|
||||
description: |-
|
||||
Allows management of a single binding with an IAM policy for a Google Cloud Platform folder.
|
||||
---
|
||||
|
||||
# google\_folder\_iam\_binding
|
||||
|
||||
Allows creation and management of a single binding within IAM policy for
|
||||
an existing Google Cloud Platform folder.
|
||||
|
||||
~> **Note:** This resource _must not_ be used in conjunction with
|
||||
`google_folder_iam_policy` or they will fight over what your policy
|
||||
should be.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```hcl
|
||||
resource "google_folder" "department1" {
|
||||
display_name = "Department 1"
|
||||
parent = "organizations/1234567"
|
||||
}
|
||||
|
||||
resource "google_folder_iam_binding" "admin" {
|
||||
folder = "${google_folder.department1.name}"
|
||||
role = "roles/editor"
|
||||
|
||||
members = [
|
||||
"user:jane@example.com",
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `folder` - (Required) The resource name of the folder the policy is attached to. Its format is folders/{folder_id}.
|
||||
|
||||
* `members` (Required) - An array of identites that will be granted the privilege in the `role`.
|
||||
Each entry can have one of the following values:
|
||||
* **user:{emailid}**: An email address that represents a specific Google account. For example, alice@gmail.com or joe@example.com.
|
||||
* **serviceAccount:{emailid}**: An email address that represents a service account. For example, my-other-app@appspot.gserviceaccount.com.
|
||||
* **group:{emailid}**: An email address that represents a Google group. For example, admins@example.com.
|
||||
* **domain:{domain}**: A Google Apps domain name that represents all the users of that domain. For example, google.com or example.com.
|
||||
|
||||
* `role` - (Required) The role that should be applied. Only one
|
||||
`google_folder_iam_binding` can be used per role. Note that custom roles must be of the format
|
||||
`[projects|organizations]/{parent-name}/roles/{role-name}`.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
In addition to the arguments listed above, the following computed attributes are
|
||||
exported:
|
||||
|
||||
* `etag` - (Computed) The etag of the folder's IAM policy.
|
||||
|
||||
## Import
|
||||
|
||||
IAM binding imports use space-delimited identifiers; first the resource in question and then the role. These bindings can be imported using the `folder` and role, e.g.
|
||||
|
||||
```
|
||||
$ terraform import google_folder_iam_binding.viewer "folder-name roles/viewer"
|
||||
```
|
63
website/docs/r/google_folder_iam_member.html.markdown
Normal file
63
website/docs/r/google_folder_iam_member.html.markdown
Normal file
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
layout: "google"
|
||||
page_title: "Google: google_folder_iam_member"
|
||||
sidebar_current: "docs-google-folder-iam-member"
|
||||
description: |-
|
||||
Allows management of a single member for a single binding on the IAM policy for a Google Cloud Platform folder.
|
||||
---
|
||||
|
||||
# google\_folder\_iam\_member
|
||||
|
||||
Allows creation and management of a single member for a single binding within
|
||||
the IAM policy for an existing Google Cloud Platform folder.
|
||||
|
||||
~> **Note:** This resource _must not_ be used in conjunction with
|
||||
`google_folder_iam_policy` or they will fight over what your policy
|
||||
should be. Similarly, roles controlled by `google_folder_iam_binding`
|
||||
should not be assigned to using `google_folder_iam_member`.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```hcl
|
||||
resource "google_folder" "department1" {
|
||||
display_name = "Department 1"
|
||||
parent = "organizations/1234567"
|
||||
}
|
||||
|
||||
resource "google_folder_iam_member" "admin" {
|
||||
folder = "${google_folder.department1.name}"
|
||||
role = "roles/editor"
|
||||
member = "user:jane@example.com"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `folder` - (Required) The resource name of the folder the policy is attached to. Its format is folders/{folder_id}.
|
||||
|
||||
* `member` - (Required) The identity that will be granted the privilege in the `role`.
|
||||
This field can have one of the following values:
|
||||
* **user:{emailid}**: An email address that represents a specific Google account. For example, alice@gmail.com or joe@example.com.
|
||||
* **serviceAccount:{emailid}**: An email address that represents a service account. For example, my-other-app@appspot.gserviceaccount.com.
|
||||
* **group:{emailid}**: An email address that represents a Google group. For example, admins@example.com.
|
||||
* **domain:{domain}**: A Google Apps domain name that represents all the users of that domain. For example, google.com or example.com.
|
||||
|
||||
* `role` - (Required) The role that should be applied. Note that custom roles must be of the format
|
||||
`[projects|organizations]/{parent-name}/roles/{role-name}`.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
In addition to the arguments listed above, the following computed attributes are
|
||||
exported:
|
||||
|
||||
* `etag` - (Computed) The etag of the folder's IAM policy.
|
||||
|
||||
## Import
|
||||
|
||||
IAM member imports use space-delimited identifiers; the resource in question, the role, and the account. This member resource can be imported using the `folder`, role, and account e.g.
|
||||
|
||||
```
|
||||
$ terraform import google_folder_iam_member.my_project "folder-name roles/viewer foo@example.com"
|
||||
```
|
|
@ -122,6 +122,12 @@
|
|||
<li<%= sidebar_current("docs-google-folder-x") %>>
|
||||
<a href="/docs/providers/google/r/google_folder.html">google_folder</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-google-folder-iam-binding") %>>
|
||||
<a href="/docs/providers/google/r/google_folder_iam_binding.html">google_folder_iam_binding</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-google-folder-iam-member") %>>
|
||||
<a href="/docs/providers/google/r/google_folder_iam_member.html">google_folder_iam_member</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-google-folder-iam-policy") %>>
|
||||
<a href="/docs/providers/google/r/google_folder_iam_policy.html">google_folder_iam_policy</a>
|
||||
</li>
|
||||
|
|
Loading…
Reference in New Issue
Block a user