Repository: GoogleCloudPlatform/terraform-validator
Pull request #1487 (2023-03-24 15:47:18)

Adds folder resource conversion logic
<!-- Put a description of what this PR is for here, along with any references to issues that this resolves or contributes to -->




<!--
Replace each [ ] with [X] to check it. Switch to the preview view to make it easier to click on links.
These steps will speed up the review process, and we appreciate you spending time on them before sending
your code to be reviewed.
-->
If this PR is for Terraform, I acknowledge that I have:

- [x] Searched through the [issue tracker](https://github.com/hashicorp/terraform-provider-google/issues) for an open issue that this either resolves or contributes to, commented on it to claim it, and written "fixes {url}" or "part of {url}" in this PR description. If there were no relevant open issues, I opened one and commented that I would like to work on it (not necessary for very small changes).
- [x] [Generated Terraform](https://github.com/GoogleCloudPlatform/magic-modules#generating-the-terraform-providers), and ran `make test` and `make lint` to ensure it passes unit and linter tests.
- [x] Ensured that all new fields I added that can be set by a user appear in at least one [example](https://github.com/GoogleCloudPlatform/magic-modules/tree/main/mmv1/templates/terraform/examples) (for generated resources) or [third_party test](https://github.com/GoogleCloudPlatform/magic-modules/tree/main/mmv1/third_party/terraform/tests) (for handwritten resources or update tests).
- [ ] [Ran](https://github.com/hashicorp/terraform-provider-google/blob/main/.github/CONTRIBUTING.md#tests) relevant acceptance tests (If the acceptance tests do not yet pass or you are unable to run them, please let your reviewer know).
- [ ] Read the [Release Notes Guide](https://github.com/GoogleCloudPlatform/magic-modules/blob/main/.ci/RELEASE_NOTES_GUIDE.md) before writing my release note below.

<!-- AUTOCHANGELOG for Downstream PRs.

Please select one of the following "release-note:" headings:
    - release-note:enhancement
    - release-note:bug
    - release-note:note
    - release-note:new-resource
    - release-note:new-datasource
    - release-note:deprecation
    - release-note:breaking-change
    - release-note:none
    
Unless you choose release-note:none, please add a release note.

See .ci/RELEASE_NOTES_GUIDE.md for writing good release notes.

You can add more release note blocks if you want more than one CHANGELOG
entry for this PR.
-->
**Release Note Template for Downstream PRs (will be copied)**

```release-note:none
```

Derived from https://github.com/GoogleCloudPlatform/magic-modules/pull/7246


Patch:
diff --git a/converters/google/resources/cai.go b/converters/google/resources/cai.go
index 93c04246..b8f2e203 100644
--- a/converters/google/resources/cai.go
+++ b/converters/google/resources/cai.go
@@ -53,6 +53,14 @@ type AssetResource struct {
 	Data map[string]interface{} `json:"data,omitempty"`
 }
 
+type Folder struct {
+	Name        string `json:"name,omitempty"`
+	Parent      string `json:"parent,omitempty"`
+	DisplayName string `json:"display_name,omitempty"`
+	State string `json:"state,omitempty"`
+	CreateTime *Timestamp `json:"create_time,omitempty"`
+}
+
 type IAMPolicy struct {
 	Bindings []IAMBinding `json:"bindings"`
 }
diff --git a/converters/google/resources/folder.go b/converters/google/resources/folder.go
new file mode 100644
index 00000000..ef8dd572
--- /dev/null
+++ b/converters/google/resources/folder.go
@@ -0,0 +1,60 @@
+package google
+
+import "time"
+
+func resourceConverterFolder() ResourceConverter {
+	return ResourceConverter{
+		AssetType:         "cloudresourcemanager.googleapis.com/Folder",
+		Convert:           GetFolderCaiObject,
+	}
+}
+
+func GetFolderCaiObject(d TerraformResourceData, config *Config) ([]Asset, error) {
+	name, err := assetName(d, config, "//cloudresourcemanager.googleapis.com/folders/{{folder_id}}")
+	
+	if err != nil {
+		return []Asset{}, nil
+	}
+
+	if obj, err := GetFolderApiObject(d, config); err == nil {
+		return []Asset{{
+			Name: name,
+			Type: "cloudresourcemanager.googleapis.com/Folder",
+			Resource: &AssetResource{
+				Version:              "v1",
+				DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/compute/v1/rest",
+				DiscoveryName:        "Folder",
+				Data:                 obj,
+			},
+		}}, nil
+	} else {
+		return []Asset{}, err
+	}
+}
+
+func GetFolderApiObject(d TerraformResourceData, config *Config) (map[string]interface{}, error) {
+
+	folder := &Folder{
+		Name:        d.Get("name").(string),
+		Parent:	     d.Get("parent").(string),
+		DisplayName: d.Get("display_name").(string),
+		State:       d.Get("lifecycle_state").(string), 
+	}
+
+	if v, ok := d.GetOkExists("create_time"); ok {
+		folder.CreateTime = constructTime(v.(string))
+	}
+
+	return jsonMap(folder)
+}
+
+func constructTime(create_time string) *Timestamp{
+	if create_time == "" {
+		return &Timestamp{}
+	}
+	t,_:= time.Parse(time.RFC3339, create_time)
+	return &Timestamp{
+		Seconds: t.Unix(),
+		Nanos: t.UnixNano(),
+	}
+}
\ No newline at end of file
diff --git a/converters/google/resources/resource_converters.go b/converters/google/resources/resource_converters.go
index c6d396e9..5a80c7e0 100644
--- a/converters/google/resources/resource_converters.go
+++ b/converters/google/resources/resource_converters.go
@@ -253,6 +253,7 @@ func ResourceConverters() map[string][]ResourceConverter {
 		"google_organization_iam_member":      {resourceConverterOrganizationIamMember()},
 		"google_organization_policy":          {resourceConverterOrganizationPolicy()},
 		"google_project_organization_policy":  {resourceConverterProjectOrgPolicy()},
+		"google_folder":                       {resourceConverterFolder()},
 		"google_folder_iam_policy":            {resourceConverterFolderIamPolicy()},
 		"google_folder_iam_binding":           {resourceConverterFolderIamBinding()},
 		"google_folder_iam_member":            {resourceConverterFolderIamMember()},
diff --git a/go.mod b/go.mod
index 194de369..81a54edd 100644
--- a/go.mod
+++ b/go.mod
@@ -27,7 +27,7 @@ require (
 	github.com/hashicorp/terraform-json v0.14.0
 	github.com/hashicorp/terraform-plugin-framework v1.1.1
 	github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.0
-	github.com/hashicorp/terraform-provider-google v1.20.1-0.20230323165411-b56d5b17f674
+	github.com/hashicorp/terraform-provider-google v1.20.1-0.20230323171214-645972563318
 	github.com/mitchellh/go-homedir v1.1.0
 	github.com/pkg/errors v0.9.1
 	github.com/sirupsen/logrus v1.9.0
diff --git a/go.sum b/go.sum
index ec1faa9a..56d28842 100644
--- a/go.sum
+++ b/go.sum
@@ -553,8 +553,8 @@ github.com/hashicorp/terraform-plugin-mux v0.8.0 h1:WCTP66mZ+iIaIrCNJnjPEYnVjawT
 github.com/hashicorp/terraform-plugin-mux v0.8.0/go.mod h1:vdW0daEi8Kd4RFJmet5Ot+SIVB/B8SwQVJiYKQwdCy8=
 github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.0 h1:FtCLTiTcykdsURXPt/ku7fYXm3y19nbzbZcUxHx9RbI=
 github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.0/go.mod h1:80wf5oad1tW+oLnbXS4UTYmDCrl7BuN1Q+IA91X1a4Y=
-github.com/hashicorp/terraform-provider-google v1.20.1-0.20230323165411-b56d5b17f674 h1:cRLwz3ox06DJ1Jx6wu53r1RqqiPFhp19lAhctfWDilE=
-github.com/hashicorp/terraform-provider-google v1.20.1-0.20230323165411-b56d5b17f674/go.mod h1:Wn+5oEyIb0xoRzKqjLIZ8DE7bvH9WQ68mAb3G8RJrcE=
+github.com/hashicorp/terraform-provider-google v1.20.1-0.20230323171214-645972563318 h1:zvZS8vsFQqj1FCeTqtcj3BP0TeWi/F3/PcLL/JZyK5A=
+github.com/hashicorp/terraform-provider-google v1.20.1-0.20230323171214-645972563318/go.mod h1:Wn+5oEyIb0xoRzKqjLIZ8DE7bvH9WQ68mAb3G8RJrcE=
 github.com/hashicorp/terraform-registry-address v0.1.0 h1:W6JkV9wbum+m516rCl5/NjKxCyTVaaUBbzYcMzBDO3U=
 github.com/hashicorp/terraform-registry-address v0.1.0/go.mod h1:EnyO2jYO6j29DTHbJcm00E5nQTFeTtyZH3H5ycydQ5A=
 github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0=


Test patch:
diff --git a/testdata/templates/example_project_create.json b/testdata/templates/example_project_create.json
index 46784776..4a0b2702 100644
--- a/testdata/templates/example_project_create.json
+++ b/testdata/templates/example_project_create.json
@@ -32,5 +32,20 @@
         "projectId": "{{.Provider.project}}"
       }
     }
+  },
+  {
+    "name": "//cloudresourcemanager.googleapis.com/folders/placeholder-foobar",
+    "asset_type": "cloudresourcemanager.googleapis.com/Folder",
+    "resource": {
+      "version": "v1",
+      "discovery_document_uri": "https://www.googleapis.com/discovery/v1/apis/compute/v1/rest",
+      "discovery_name": "Folder",
+      "parent": "//cloudresourcemanager.googleapis.com/organizations/{{.OrgID}}",
+      "data": {
+        "display_name": "Department 1",
+        "parent": "organizations/{{.OrgID}}"
+      }
+    },
+    "ancestry_path": "organizations/{{.OrgID}}"
   }
 ]
diff --git a/testdata/templates/example_project_create.tf b/testdata/templates/example_project_create.tf
index 0097e904..695ba0e2 100644
--- a/testdata/templates/example_project_create.tf
+++ b/testdata/templates/example_project_create.tf
@@ -41,5 +41,5 @@ resource "google_project" "my_project-in-a-folder" {
 
 resource "google_folder" "department1" {
   display_name = "Department 1"
-  parent     = "organizations/1234567"
+  parent     = "organizations/{{.OrgID}}"
 }
diff --git a/testdata/templates/example_project_create.tfplan.json b/testdata/templates/example_project_create.tfplan.json
index e1bb09d6..86e6f549 100644
--- a/testdata/templates/example_project_create.tfplan.json
+++ b/testdata/templates/example_project_create.tfplan.json
@@ -13,7 +13,7 @@
           "schema_version": 0,
           "values": {
             "display_name": "Department 1",
-            "parent": "organizations/1234567",
+            "parent": "organizations/{{.OrgID}}",
             "timeouts": null
           }
         },
@@ -52,7 +52,7 @@
         "before": null,
         "after": {
           "display_name": "Department 1",
-          "parent": "organizations/1234567",
+          "parent": "organizations/{{.OrgID}}",
           "timeouts": null
         },
         "after_unknown": {
@@ -121,7 +121,7 @@
               "constant_value": "Department 1"
             },
             "parent": {
-              "constant_value": "organizations/1234567"
+              "constant_value": "organizations/{{.OrgID}}"
             }
           },
           "schema_version": 0
diff --git a/testdata/templates/example_project_create_empty_project_id.json b/testdata/templates/example_project_create_empty_project_id.json
index 724959c1..f489eaba 100644
--- a/testdata/templates/example_project_create_empty_project_id.json
+++ b/testdata/templates/example_project_create_empty_project_id.json
@@ -30,5 +30,20 @@
         }
       }
     }
+  },
+  {
+    "name": "//cloudresourcemanager.googleapis.com/folders/placeholder-foobar",
+    "asset_type": "cloudresourcemanager.googleapis.com/Folder",
+    "resource": {
+      "version": "v1",
+      "discovery_document_uri": "https://www.googleapis.com/discovery/v1/apis/compute/v1/rest",
+      "discovery_name": "Folder",
+      "parent": "//cloudresourcemanager.googleapis.com/organizations/{{.OrgID}}",
+      "data": {
+        "display_name": "Department 1",
+        "parent": "organizations/{{.OrgID}}"
+      }
+    },
+    "ancestry_path": "organizations/{{.OrgID}}"
   }
 ]
diff --git a/testdata/templates/example_project_create_empty_project_id.tf b/testdata/templates/example_project_create_empty_project_id.tf
index 57085b07..35b36903 100644
--- a/testdata/templates/example_project_create_empty_project_id.tf
+++ b/testdata/templates/example_project_create_empty_project_id.tf
@@ -47,5 +47,5 @@ resource "random_string" "suffix" {
 
 resource "google_folder" "department1" {
   display_name = "Department 1"
-  parent     = "organizations/1234567"
+  parent     = "organizations/{{.OrgID}}"
 }
diff --git a/testdata/templates/example_project_create_empty_project_id.tfplan.json b/testdata/templates/example_project_create_empty_project_id.tfplan.json
index f34cb526..18fd1dca 100644
--- a/testdata/templates/example_project_create_empty_project_id.tfplan.json
+++ b/testdata/templates/example_project_create_empty_project_id.tfplan.json
@@ -13,7 +13,7 @@
           "schema_version": 0,
           "values": {
             "display_name": "Department 1",
-            "parent": "organizations/1234567",
+            "parent": "organizations/{{.OrgID}}",
             "timeouts": null
           },
           "sensitive_values": {}
@@ -78,7 +78,7 @@
         "before": null,
         "after": {
           "display_name": "Department 1",
-          "parent": "organizations/1234567",
+          "parent": "organizations/{{.OrgID}}",
           "timeouts": null
         },
         "after_unknown": {
@@ -174,7 +174,7 @@
               "constant_value": "Department 1"
             },
             "parent": {
-              "constant_value": "organizations/1234567"
+              "constant_value": "organizations/{{.OrgID}}"
             }
           },
           "schema_version": 0
diff --git a/testdata/templates/example_project_create_empty_project_id_without_default_project.json b/testdata/templates/example_project_create_empty_project_id_without_default_project.json
index ab9f7a19..b9d2476b 100644
--- a/testdata/templates/example_project_create_empty_project_id_without_default_project.json
+++ b/testdata/templates/example_project_create_empty_project_id_without_default_project.json
@@ -30,5 +30,20 @@
       }
     },
     "ancestry_path": "organization/unknown"
+  },
+  {
+    "name": "//cloudresourcemanager.googleapis.com/folders/placeholder-folder",
+    "asset_type": "cloudresourcemanager.googleapis.com/Folder",
+    "resource": {
+      "version": "v1",
+      "discovery_document_uri": "https://www.googleapis.com/discovery/v1/apis/compute/v1/rest",
+      "discovery_name": "Folder",
+      "parent": "//cloudresourcemanager.googleapis.com/organizations/{{.OrgID}}",
+      "data": {
+        "display_name": "Department 1",
+        "parent": "organizations/{{.OrgID}}"
+      }
+    },
+    "ancestry_path": "organization/{{.OrgID}}"
   }
 ]