terraform-provider-google/google/resource_google_project_organization_policy_test.go
The Magician f34848f974 Document that a policy must be defined. (#3611)
Signed-off-by: Modular Magician <magic-modules@google.com>
2019-05-16 13:10:44 -07:00

427 lines
12 KiB
Go

package google
import (
"fmt"
"reflect"
"sort"
"strings"
"testing"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"google.golang.org/api/cloudresourcemanager/v1"
)
// Since each test here is acting on the same project, run the tests serially to
// avoid race conditions and aborted operations.
func TestAccProjectOrganizationPolicy(t *testing.T) {
testCases := map[string]func(t *testing.T){
"boolean": testAccProjectOrganizationPolicy_boolean,
"list_allowAll": testAccProjectOrganizationPolicy_list_allowAll,
"list_allowSome": testAccProjectOrganizationPolicy_list_allowSome,
"list_denySome": testAccProjectOrganizationPolicy_list_denySome,
"list_update": testAccProjectOrganizationPolicy_list_update,
"restore_policy": testAccProjectOrganizationPolicy_restore_defaultTrue,
"empty_policy": testAccProjectOrganizationPolicy_none,
}
for name, tc := range testCases {
// shadow the tc variable into scope so that when
// the loop continues, if t.Run hasn't executed tc(t)
// yet, we don't have a race condition
// see https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables
tc := tc
t.Run(name, func(t *testing.T) {
tc(t)
})
}
}
func testAccProjectOrganizationPolicy_boolean(t *testing.T) {
projectId := getTestProjectFromEnv()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
Steps: []resource.TestStep{
{
// Test creation of an enforced boolean policy
Config: testAccProjectOrganizationPolicyConfig_boolean(projectId, true),
Check: testAccCheckGoogleProjectOrganizationBooleanPolicy("bool", true),
},
{
// Test update from enforced to not
Config: testAccProjectOrganizationPolicyConfig_boolean(projectId, false),
Check: testAccCheckGoogleProjectOrganizationBooleanPolicy("bool", false),
},
{
Config: " ",
Destroy: true,
},
{
// Test creation of a not enforced boolean policy
Config: testAccProjectOrganizationPolicyConfig_boolean(projectId, false),
Check: testAccCheckGoogleProjectOrganizationBooleanPolicy("bool", false),
},
{
// Test update from not enforced to enforced
Config: testAccProjectOrganizationPolicyConfig_boolean(projectId, true),
Check: testAccCheckGoogleProjectOrganizationBooleanPolicy("bool", true),
},
},
})
}
func testAccProjectOrganizationPolicy_list_allowAll(t *testing.T) {
projectId := getTestProjectFromEnv()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccProjectOrganizationPolicyConfig_list_allowAll(projectId),
Check: testAccCheckGoogleProjectOrganizationListPolicyAll("list", "ALLOW"),
},
{
ResourceName: "google_project_organization_policy.list",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func testAccProjectOrganizationPolicy_list_allowSome(t *testing.T) {
project := getTestProjectFromEnv()
canonicalProject := canonicalProjectId(project)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccProjectOrganizationPolicyConfig_list_allowSome(project),
Check: testAccCheckGoogleProjectOrganizationListPolicyAllowedValues("list", []string{canonicalProject}),
},
{
ResourceName: "google_project_organization_policy.list",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func testAccProjectOrganizationPolicy_list_denySome(t *testing.T) {
projectId := getTestProjectFromEnv()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccProjectOrganizationPolicyConfig_list_denySome(projectId),
Check: testAccCheckGoogleProjectOrganizationListPolicyDeniedValues("list", DENIED_ORG_POLICIES),
},
{
ResourceName: "google_project_organization_policy.list",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func testAccProjectOrganizationPolicy_list_update(t *testing.T) {
projectId := getTestProjectFromEnv()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccProjectOrganizationPolicyConfig_list_allowAll(projectId),
Check: testAccCheckGoogleProjectOrganizationListPolicyAll("list", "ALLOW"),
},
{
Config: testAccProjectOrganizationPolicyConfig_list_denySome(projectId),
Check: testAccCheckGoogleProjectOrganizationListPolicyDeniedValues("list", DENIED_ORG_POLICIES),
},
{
ResourceName: "google_project_organization_policy.list",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func testAccProjectOrganizationPolicy_restore_defaultTrue(t *testing.T) {
projectId := getTestProjectFromEnv()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccProjectOrganizationPolicyConfig_restore_defaultTrue(projectId),
Check: getGoogleProjectOrganizationRestoreDefaultTrue("restore", &cloudresourcemanager.RestoreDefault{}),
},
{
ResourceName: "google_project_organization_policy.restore",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func testAccProjectOrganizationPolicy_none(t *testing.T) {
projectId := getTestProjectFromEnv()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckGoogleProjectOrganizationPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccProjectOrganizationPolicyConfig_none(projectId),
Check: testAccCheckGoogleProjectOrganizationPolicyDestroy,
},
{
ResourceName: "google_project_organization_policy.none",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func testAccCheckGoogleProjectOrganizationPolicyDestroy(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)
for _, rs := range s.RootModule().Resources {
if rs.Type != "google_project_organization_policy" {
continue
}
projectId := canonicalProjectId(rs.Primary.Attributes["project"])
constraint := canonicalOrgPolicyConstraint(rs.Primary.Attributes["constraint"])
policy, err := config.clientResourceManager.Projects.GetOrgPolicy(projectId, &cloudresourcemanager.GetOrgPolicyRequest{
Constraint: constraint,
}).Do()
if err != nil {
return err
}
if policy.ListPolicy != nil || policy.BooleanPolicy != nil {
return fmt.Errorf("Org policy with constraint '%s' hasn't been cleared", constraint)
}
}
return nil
}
func testAccCheckGoogleProjectOrganizationBooleanPolicy(n string, enforced bool) resource.TestCheckFunc {
return func(s *terraform.State) error {
policy, err := getGoogleProjectOrganizationPolicyTestResource(s, n)
if err != nil {
return err
}
if policy.BooleanPolicy.Enforced != enforced {
return fmt.Errorf("Expected boolean policy enforcement to be '%t', got '%t'", enforced, policy.BooleanPolicy.Enforced)
}
return nil
}
}
func testAccCheckGoogleProjectOrganizationListPolicyAll(n, policyType string) resource.TestCheckFunc {
return func(s *terraform.State) error {
policy, err := getGoogleProjectOrganizationPolicyTestResource(s, n)
if err != nil {
return err
}
if policy.ListPolicy == nil {
return nil
}
if len(policy.ListPolicy.AllowedValues) > 0 || len(policy.ListPolicy.DeniedValues) > 0 {
return fmt.Errorf("The `values` field shouldn't be set")
}
if policy.ListPolicy.AllValues != policyType {
return fmt.Errorf("The list policy should %s all values", policyType)
}
return nil
}
}
func testAccCheckGoogleProjectOrganizationListPolicyAllowedValues(n string, values []string) resource.TestCheckFunc {
return func(s *terraform.State) error {
policy, err := getGoogleProjectOrganizationPolicyTestResource(s, n)
if err != nil {
return err
}
sort.Strings(policy.ListPolicy.AllowedValues)
sort.Strings(values)
if !reflect.DeepEqual(policy.ListPolicy.AllowedValues, values) {
return fmt.Errorf("Expected the list policy to allow '%s', instead allowed '%s'", values, policy.ListPolicy.AllowedValues)
}
return nil
}
}
func testAccCheckGoogleProjectOrganizationListPolicyDeniedValues(n string, values []string) resource.TestCheckFunc {
return func(s *terraform.State) error {
policy, err := getGoogleProjectOrganizationPolicyTestResource(s, n)
if err != nil {
return err
}
sort.Strings(policy.ListPolicy.DeniedValues)
sort.Strings(values)
if !reflect.DeepEqual(policy.ListPolicy.DeniedValues, values) {
return fmt.Errorf("Expected the list policy to deny '%s', instead denied '%s'", values, policy.ListPolicy.DeniedValues)
}
return nil
}
}
func getGoogleProjectOrganizationRestoreDefaultTrue(n string, policyDefault *cloudresourcemanager.RestoreDefault) resource.TestCheckFunc {
return func(s *terraform.State) error {
policy, err := getGoogleProjectOrganizationPolicyTestResource(s, n)
if err != nil {
return err
}
if !reflect.DeepEqual(policy.RestoreDefault, policyDefault) {
return fmt.Errorf("Expected the restore default '%s', instead denied, %s", policyDefault, policy.RestoreDefault)
}
return nil
}
}
func getGoogleProjectOrganizationPolicyTestResource(s *terraform.State, n string) (*cloudresourcemanager.OrgPolicy, error) {
rn := "google_project_organization_policy." + n
rs, ok := s.RootModule().Resources[rn]
if !ok {
return nil, fmt.Errorf("Not found: %s", rn)
}
if rs.Primary.ID == "" {
return nil, fmt.Errorf("No ID is set")
}
config := testAccProvider.Meta().(*Config)
projectId := canonicalProjectId(rs.Primary.Attributes["project"])
return config.clientResourceManager.Projects.GetOrgPolicy(projectId, &cloudresourcemanager.GetOrgPolicyRequest{
Constraint: rs.Primary.Attributes["constraint"],
}).Do()
}
func testAccProjectOrganizationPolicyConfig_boolean(pid string, enforced bool) string {
return fmt.Sprintf(`
resource "google_project_organization_policy" "bool" {
project = "%s"
constraint = "constraints/compute.disableSerialPortAccess"
boolean_policy {
enforced = %t
}
}
`, pid, enforced)
}
func testAccProjectOrganizationPolicyConfig_list_allowAll(pid string) string {
return fmt.Sprintf(`
resource "google_project_organization_policy" "list" {
project = "%s"
constraint = "constraints/serviceuser.services"
list_policy {
allow {
all = true
}
}
}
`, pid)
}
func testAccProjectOrganizationPolicyConfig_list_allowSome(pid string) string {
return fmt.Sprintf(`
resource "google_project_organization_policy" "list" {
project = "%s"
constraint = "constraints/compute.trustedImageProjects"
list_policy {
allow {
values = ["projects/%s"]
}
}
}
`, pid, pid)
}
func testAccProjectOrganizationPolicyConfig_list_denySome(pid string) string {
return fmt.Sprintf(`
resource "google_project_organization_policy" "list" {
project = "%s"
constraint = "constraints/serviceuser.services"
list_policy {
deny {
values = [
"doubleclicksearch.googleapis.com",
"replicapoolupdater.googleapis.com",
]
}
}
}
`, pid)
}
func testAccProjectOrganizationPolicyConfig_restore_defaultTrue(pid string) string {
return fmt.Sprintf(`
resource "google_project_organization_policy" "restore" {
project = "%s"
constraint = "constraints/serviceuser.services"
restore_policy {
default = true
}
}
`, pid)
}
func testAccProjectOrganizationPolicyConfig_none(pid string) string {
return fmt.Sprintf(`
resource "google_project_organization_policy" "none" {
project = "%s"
constraint = "constraints/serviceuser.services"
}
`, pid)
}
func canonicalProjectId(project string) string {
if strings.HasPrefix(project, "projects/") {
return project
}
return fmt.Sprintf("projects/%s", project)
}