mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-09-06 09:06:44 +00:00
188 lines
6.0 KiB
Go
188 lines
6.0 KiB
Go
package google
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"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"
|
|
)
|
|
|
|
// Bindings and members are tested serially to avoid concurrent updates of the org's IAM policy.
|
|
// When concurrent changes happen, the behavior is to abort and ask the user to retry allowing
|
|
// them to see the new diff instead of blindly overriding the policy stored in GCP. This desired
|
|
// behavior however induces flakiness in our acceptance tests, hence the need for running them
|
|
// serially.
|
|
func TestAccOrganizationIam(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
org := getTestOrgFromEnv(t)
|
|
account := acctest.RandomWithPrefix("tf-test")
|
|
roleId := "tfIamTest" + acctest.RandString(10)
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
Providers: testAccProviders,
|
|
Steps: []resource.TestStep{
|
|
{
|
|
// Test Iam Binding creation
|
|
Config: testAccOrganizationIamBinding_basic(account, roleId, org),
|
|
Check: testAccCheckGoogleOrganizationIamBindingExists("foo", "test-role", []string{
|
|
fmt.Sprintf("serviceAccount:%s@%s.iam.gserviceaccount.com", account, getTestProjectFromEnv()),
|
|
}),
|
|
},
|
|
{
|
|
// Test Iam Binding update
|
|
Config: testAccOrganizationIamBinding_update(account, roleId, org),
|
|
Check: testAccCheckGoogleOrganizationIamBindingExists("foo", "test-role", []string{
|
|
fmt.Sprintf("serviceAccount:%s@%s.iam.gserviceaccount.com", account, getTestProjectFromEnv()),
|
|
fmt.Sprintf("serviceAccount:%s-2@%s.iam.gserviceaccount.com", account, getTestProjectFromEnv()),
|
|
}),
|
|
},
|
|
{
|
|
// Test Iam Member creation (no update for member, no need to test)
|
|
Config: testAccOrganizationIamMember_basic(account, org),
|
|
Check: testAccCheckGoogleOrganizationIamMemberExists("foo", "roles/browser",
|
|
fmt.Sprintf("serviceAccount:%s@%s.iam.gserviceaccount.com", account, getTestProjectFromEnv()),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func testAccCheckGoogleOrganizationIamBindingExists(bindingResourceName, roleResourceName string, members []string) resource.TestCheckFunc {
|
|
return func(s *terraform.State) error {
|
|
bindingRs, ok := s.RootModule().Resources["google_organization_iam_binding."+bindingResourceName]
|
|
if !ok {
|
|
return fmt.Errorf("Not found: %s", bindingResourceName)
|
|
}
|
|
|
|
roleRs, ok := s.RootModule().Resources["google_organization_iam_custom_role."+roleResourceName]
|
|
if !ok {
|
|
return fmt.Errorf("Not found: %s", roleResourceName)
|
|
}
|
|
|
|
config := testAccProvider.Meta().(*Config)
|
|
p, err := config.clientResourceManager.Organizations.GetIamPolicy("organizations/"+bindingRs.Primary.Attributes["org_id"], &cloudresourcemanager.GetIamPolicyRequest{}).Do()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, binding := range p.Bindings {
|
|
if binding.Role == roleRs.Primary.ID {
|
|
sort.Strings(members)
|
|
sort.Strings(binding.Members)
|
|
|
|
if reflect.DeepEqual(members, binding.Members) {
|
|
return nil
|
|
}
|
|
|
|
return fmt.Errorf("Binding found but expected members is %v, got %v", members, binding.Members)
|
|
}
|
|
}
|
|
|
|
return fmt.Errorf("No binding for role %q", roleRs.Primary.ID)
|
|
}
|
|
}
|
|
|
|
func testAccCheckGoogleOrganizationIamMemberExists(n, role, member string) resource.TestCheckFunc {
|
|
return func(s *terraform.State) error {
|
|
rs, ok := s.RootModule().Resources["google_organization_iam_member."+n]
|
|
if !ok {
|
|
return fmt.Errorf("Not found: %s", n)
|
|
}
|
|
|
|
config := testAccProvider.Meta().(*Config)
|
|
p, err := config.clientResourceManager.Organizations.GetIamPolicy("organizations/"+rs.Primary.Attributes["org_id"], &cloudresourcemanager.GetIamPolicyRequest{}).Do()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, binding := range p.Bindings {
|
|
if binding.Role == role {
|
|
for _, m := range binding.Members {
|
|
if m == member {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
return fmt.Errorf("Missing member %q, got %v", member, binding.Members)
|
|
}
|
|
}
|
|
|
|
return fmt.Errorf("No binding for role %q", role)
|
|
}
|
|
}
|
|
|
|
// We are using a custom role since iam_binding is authoritative on the member list and
|
|
// we want to avoid removing members from an existing role to prevent unwanted side effects.
|
|
func testAccOrganizationIamBinding_basic(account, role, org string) string {
|
|
return fmt.Sprintf(`
|
|
resource "google_service_account" "test-account" {
|
|
account_id = "%s"
|
|
display_name = "Iam Testing Account"
|
|
}
|
|
|
|
resource "google_organization_iam_custom_role" "test-role" {
|
|
role_id = "%s"
|
|
org_id = "%s"
|
|
title = "Iam Testing Role"
|
|
permissions = ["genomics.datasets.get"]
|
|
}
|
|
|
|
resource "google_organization_iam_binding" "foo" {
|
|
org_id = "%s"
|
|
role = "${google_organization_iam_custom_role.test-role.id}"
|
|
members = ["serviceAccount:${google_service_account.test-account.email}"]
|
|
}
|
|
`, account, role, org, org)
|
|
}
|
|
|
|
func testAccOrganizationIamBinding_update(account, role, org string) string {
|
|
return fmt.Sprintf(`
|
|
resource "google_service_account" "test-account" {
|
|
account_id = "%s"
|
|
display_name = "Iam Testing Account"
|
|
}
|
|
|
|
resource "google_organization_iam_custom_role" "test-role" {
|
|
role_id = "%s"
|
|
org_id = "%s"
|
|
title = "Iam Testing Role"
|
|
permissions = ["genomics.datasets.get"]
|
|
}
|
|
|
|
resource "google_service_account" "test-account-2" {
|
|
account_id = "%s-2"
|
|
display_name = "Iam Testing Account"
|
|
}
|
|
|
|
resource "google_organization_iam_binding" "foo" {
|
|
org_id = "%s"
|
|
role = "${google_organization_iam_custom_role.test-role.id}"
|
|
members = [
|
|
"serviceAccount:${google_service_account.test-account.email}",
|
|
"serviceAccount:${google_service_account.test-account-2.email}"
|
|
]
|
|
}
|
|
`, account, role, org, account, org)
|
|
}
|
|
|
|
func testAccOrganizationIamMember_basic(account, org string) string {
|
|
return fmt.Sprintf(`
|
|
resource "google_service_account" "test-account" {
|
|
account_id = "%s"
|
|
display_name = "Iam Testing Account"
|
|
}
|
|
|
|
resource "google_organization_iam_member" "foo" {
|
|
org_id = "%s"
|
|
role = "roles/browser"
|
|
member = "serviceAccount:${google_service_account.test-account.email}"
|
|
}
|
|
`, account, org)
|
|
}
|