From 135f5c414473a9ce8497f3c16af8c798f4b7b4b7 Mon Sep 17 00:00:00 2001 From: Vincent Roseberry Date: Thu, 3 May 2018 09:53:22 -0700 Subject: [PATCH] Allow setting folder_id to empty string on google_project (#1425) * Allow setting folder_id to empty string on google_project * Simplify logic * Update Changelog --- CHANGELOG.md | 1 + google/resource_google_project.go | 41 ++++++++++++++++---------- google/resource_google_project_test.go | 35 ++++++++++++++++++++++ 3 files changed, 61 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa2f9cff..eb02832b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ FEATURES: IMPROVEMENTS: * compute: Autogenerate `google_vpn_gateway` [GH-1409] * compute: add `enable_flow_logs` field to subnetwork [GH-1385] +* project: Don't fail if `folder_id` and `org_id` are set but one is empty for `google_project` [GH-1425] ## 1.11.0 (May 01, 2018) diff --git a/google/resource_google_project.go b/google/resource_google_project.go index d16dbcdb..acdd28f3 100644 --- a/google/resource_google_project.go +++ b/google/resource_google_project.go @@ -51,17 +51,15 @@ func resourceGoogleProject() *schema.Resource { Required: true, }, "org_id": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Computed: true, - ConflictsWith: []string{"folder_id"}, + Type: schema.TypeString, + Optional: true, + Computed: true, }, "folder_id": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Computed: true, - ConflictsWith: []string{"org_id"}, - StateFunc: parseFolderId, + Type: schema.TypeString, + Optional: true, + Computed: true, + StateFunc: parseFolderId, }, "policy_data": &schema.Schema{ Type: schema.TypeString, @@ -105,7 +103,9 @@ func resourceGoogleProjectCreate(d *schema.ResourceData, meta interface{}) error Name: d.Get("name").(string), } - getParentResourceId(d, project) + if err := getParentResourceId(d, project); err != nil { + return err + } if _, ok := d.GetOk("labels"); ok { project.Labels = expandLabels(d) @@ -215,20 +215,27 @@ func prefixedProject(pid string) string { } func getParentResourceId(d *schema.ResourceData, p *cloudresourcemanager.Project) error { - if v, ok := d.GetOk("org_id"); ok { - org_id := v.(string) + orgId := d.Get("org_id").(string) + folderId := d.Get("folder_id").(string) + + if orgId != "" && folderId != "" { + return fmt.Errorf("'org_id' and 'folder_id' cannot be both set.") + } + + if orgId != "" { p.Parent = &cloudresourcemanager.ResourceId{ - Id: org_id, + Id: orgId, Type: "organization", } } - if v, ok := d.GetOk("folder_id"); ok { + if folderId != "" { p.Parent = &cloudresourcemanager.ResourceId{ - Id: parseFolderId(v), + Id: parseFolderId(folderId), Type: "folder", } } + return nil } @@ -271,7 +278,9 @@ func resourceGoogleProjectUpdate(d *schema.ResourceData, meta interface{}) error // Project parent has changed if d.HasChange("org_id") || d.HasChange("folder_id") { - getParentResourceId(d, p) + if err := getParentResourceId(d, p); err != nil { + return err + } // Do update on project p, err = config.clientResourceManager.Projects.Update(p.ProjectId, p).Do() diff --git a/google/resource_google_project_test.go b/google/resource_google_project_test.go index c38eec5d..a599c62b 100644 --- a/google/resource_google_project_test.go +++ b/google/resource_google_project_test.go @@ -170,6 +170,23 @@ func TestAccProject_deleteDefaultNetwork(t *testing.T) { }) } +func TestAccProject_parentFolder(t *testing.T) { + t.Parallel() + + org := getTestOrgFromEnv(t) + pid := "terraform-" + acctest.RandString(10) + folderDisplayName := "tf-test-" + acctest.RandString(10) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccProject_parentFolder(pid, pname, folderDisplayName, org), + }, + }, + }) +} + func testAccCheckGoogleProjectExists(r, pid string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[r] @@ -314,6 +331,24 @@ resource "google_project" "acceptance" { }`, pid, name, org, billing) } +func testAccProject_parentFolder(pid, projectName, folderName, org string) string { + return fmt.Sprintf(` +resource "google_project" "acceptance" { + project_id = "%s" + name = "%s" + # ensures we can set both org_id and folder_id as long as only one is not empty. + org_id = "" + folder_id = "${google_folder.folder1.id}" +} + +resource "google_folder" "folder1" { + display_name = "%s" + parent = "organizations/%s" +} + +`, pid, projectName, folderName, org) +} + func skipIfEnvNotSet(t *testing.T, envs ...string) { for _, k := range envs { if os.Getenv(k) == "" {