From 6a39e717ae4a6be8b6a77b9c0ca3fb7a00da710c Mon Sep 17 00:00:00 2001 From: The Magician Date: Tue, 27 Sep 2022 15:25:17 -0700 Subject: [PATCH] Add new Config entity to Identitytoolkit (#6587) (#12665) Signed-off-by: Modular Magician Signed-off-by: Modular Magician --- .changelog/6587.txt | 3 + google/provider.go | 5 +- google/resource_identity_platform_config.go | 260 ++++++++++++++++++ ...identity_platform_config_generated_test.go | 69 +++++ .../r/identity_platform_config.html.markdown | 110 ++++++++ 5 files changed, 445 insertions(+), 2 deletions(-) create mode 100644 .changelog/6587.txt create mode 100644 google/resource_identity_platform_config.go create mode 100644 google/resource_identity_platform_config_generated_test.go create mode 100644 website/docs/r/identity_platform_config.html.markdown diff --git a/.changelog/6587.txt b/.changelog/6587.txt new file mode 100644 index 0000000000..81125ec5bd --- /dev/null +++ b/.changelog/6587.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +`google_identity_platform_config` +``` diff --git a/google/provider.go b/google/provider.go index 9d83ccc9ea..f18d2c4e9f 100644 --- a/google/provider.go +++ b/google/provider.go @@ -890,9 +890,9 @@ func Provider() *schema.Provider { return provider } -// Generated resources: 234 +// Generated resources: 235 // Generated IAM resources: 138 -// Total generated resources: 372 +// Total generated resources: 373 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -1166,6 +1166,7 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_iap_tunnel_iam_policy": ResourceIamPolicy(IapTunnelIamSchema, IapTunnelIamUpdaterProducer, IapTunnelIdParseFunc), "google_iap_brand": resourceIapBrand(), "google_iap_client": resourceIapClient(), + "google_identity_platform_config": resourceIdentityPlatformConfig(), "google_identity_platform_default_supported_idp_config": resourceIdentityPlatformDefaultSupportedIdpConfig(), "google_identity_platform_tenant_default_supported_idp_config": resourceIdentityPlatformTenantDefaultSupportedIdpConfig(), "google_identity_platform_inbound_saml_config": resourceIdentityPlatformInboundSamlConfig(), diff --git a/google/resource_identity_platform_config.go b/google/resource_identity_platform_config.go new file mode 100644 index 0000000000..b313a9c3a5 --- /dev/null +++ b/google/resource_identity_platform_config.go @@ -0,0 +1,260 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "log" + "reflect" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceIdentityPlatformConfig() *schema.Resource { + return &schema.Resource{ + Create: resourceIdentityPlatformConfigCreate, + Read: resourceIdentityPlatformConfigRead, + Update: resourceIdentityPlatformConfigUpdate, + Delete: resourceIdentityPlatformConfigDelete, + + Importer: &schema.ResourceImporter{ + State: resourceIdentityPlatformConfigImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + Update: schema.DefaultTimeout(20 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "autodelete_anonymous_users": { + Type: schema.TypeBool, + Optional: true, + Description: `Whether anonymous users will be auto-deleted after a period of 30 days`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `The name of the Config resource`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + UseJSONNumber: true, + } +} + +func resourceIdentityPlatformConfigCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + autodeleteAnonymousUsersProp, err := expandIdentityPlatformConfigAutodeleteAnonymousUsers(d.Get("autodelete_anonymous_users"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("autodelete_anonymous_users"); !isEmptyValue(reflect.ValueOf(autodeleteAnonymousUsersProp)) && (ok || !reflect.DeepEqual(v, autodeleteAnonymousUsersProp)) { + obj["autodeleteAnonymousUsers"] = autodeleteAnonymousUsersProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/identityPlatform:initializeAuth") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new Config: %#v", obj) + billingProject := "" + + project, err := getProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for Config: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestWithTimeout(config, "POST", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating Config: %s", err) + } + if err := d.Set("name", flattenIdentityPlatformConfigName(res["name"], d, config)); err != nil { + return fmt.Errorf(`Error setting computed identity field "name": %s`, err) + } + + // Store the ID now + id, err := replaceVars(d, config, "projects/{{project}}/config") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating Config %q: %#v", d.Id(), res) + + return resourceIdentityPlatformConfigRead(d, meta) +} + +func resourceIdentityPlatformConfigRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/config") + if err != nil { + return err + } + + billingProject := "" + + project, err := getProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for Config: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequest(config, "GET", billingProject, url, userAgent, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("IdentityPlatformConfig %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading Config: %s", err) + } + + if err := d.Set("name", flattenIdentityPlatformConfigName(res["name"], d, config)); err != nil { + return fmt.Errorf("Error reading Config: %s", err) + } + if err := d.Set("autodelete_anonymous_users", flattenIdentityPlatformConfigAutodeleteAnonymousUsers(res["autodeleteAnonymousUsers"], d, config)); err != nil { + return fmt.Errorf("Error reading Config: %s", err) + } + + return nil +} + +func resourceIdentityPlatformConfigUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := getProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for Config: %s", err) + } + billingProject = project + + obj := make(map[string]interface{}) + autodeleteAnonymousUsersProp, err := expandIdentityPlatformConfigAutodeleteAnonymousUsers(d.Get("autodelete_anonymous_users"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("autodelete_anonymous_users"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, autodeleteAnonymousUsersProp)) { + obj["autodeleteAnonymousUsers"] = autodeleteAnonymousUsersProp + } + + url, err := replaceVars(d, config, "{{IdentityPlatformBasePath}}projects/{{project}}/config") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating Config %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("autodelete_anonymous_users") { + updateMask = append(updateMask, "autodeleteAnonymousUsers") + } + // updateMask is a URL parameter but not present in the schema, so replaceVars + // won't set it + url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestWithTimeout(config, "PATCH", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return fmt.Errorf("Error updating Config %q: %s", d.Id(), err) + } else { + log.Printf("[DEBUG] Finished updating Config %q: %#v", d.Id(), res) + } + + return resourceIdentityPlatformConfigRead(d, meta) +} + +func resourceIdentityPlatformConfigDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[WARNING] IdentityPlatform Config resources"+ + " cannot be deleted from Google Cloud. The resource %s will be removed from Terraform"+ + " state, but will still be present on Google Cloud.", d.Id()) + d.SetId("") + + return nil +} + +func resourceIdentityPlatformConfigImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{ + "projects/(?P[^/]+)/config", + "projects/(?P[^/]+)", + "(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "projects/{{project}}/config") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenIdentityPlatformConfigName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenIdentityPlatformConfigAutodeleteAnonymousUsers(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func expandIdentityPlatformConfigAutodeleteAnonymousUsers(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google/resource_identity_platform_config_generated_test.go b/google/resource_identity_platform_config_generated_test.go new file mode 100644 index 0000000000..5a3b37556e --- /dev/null +++ b/google/resource_identity_platform_config_generated_test.go @@ -0,0 +1,69 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccIdentityPlatformConfig_identityPlatformConfigBasicExample(t *testing.T) { + skipIfVcr(t) + t.Parallel() + + context := map[string]interface{}{ + "org_id": getTestOrgFromEnv(t), + "billing_acct": getTestBillingAccountFromEnv(t), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIdentityPlatformConfig_identityPlatformConfigBasicExample(context), + }, + { + ResourceName: "google_identity_platform_config.default", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccIdentityPlatformConfig_identityPlatformConfigBasicExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "default" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_acct}" +} + +resource "google_project_service" "apigee" { + project = google_project.project.project_id + service = "identitytoolkit.googleapis.com" +} + + +resource "google_identity_platform_config" "default" { + project = google_project.default.project_id + autodelete_anonymous_users = true +} +`, context) +} diff --git a/website/docs/r/identity_platform_config.html.markdown b/website/docs/r/identity_platform_config.html.markdown new file mode 100644 index 0000000000..880ef1ffbb --- /dev/null +++ b/website/docs/r/identity_platform_config.html.markdown @@ -0,0 +1,110 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Identity Platform" +page_title: "Google: google_identity_platform_config" +description: |- + Identity Platform configuration for a Cloud project. +--- + +# google\_identity\_platform\_config + +Identity Platform configuration for a Cloud project. Identity Platform is an +end-to-end authentication system for third-party users to access apps +and services. + +This entity is created only once during intialization and cannot be deleted, +individual Identity Providers may be disabled instead. This resource may only +be created in billing-enabled projects. + + +To get more information about Config, see: + +* [API documentation](https://cloud.google.com/identity-platform/docs/reference/rest/v2/Config) +* How-to Guides + * [Official Documentation](https://cloud.google.com/identity-platform/docs) + +## Example Usage - Identity Platform Config Basic + + +```hcl +resource "google_project" "default" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "123456789" + billing_account = "000000-0000000-0000000-000000" +} + +resource "google_project_service" "apigee" { + project = google_project.project.project_id + service = "identitytoolkit.googleapis.com" +} + + +resource "google_identity_platform_config" "default" { + project = google_project.default.project_id + autodelete_anonymous_users = true +} +``` + +## Argument Reference + +The following arguments are supported: + + + +- - - + + +* `autodelete_anonymous_users` - + (Optional) + Whether anonymous users will be auto-deleted after a period of 30 days + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `projects/{{project}}/config` + +* `name` - + The name of the Config resource + + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 20 minutes. +- `update` - Default is 20 minutes. +- `delete` - Default is 20 minutes. + +## Import + + +Config can be imported using any of these accepted formats: + +``` +$ terraform import google_identity_platform_config.default projects/{{project}}/config +$ terraform import google_identity_platform_config.default projects/{{project}} +$ terraform import google_identity_platform_config.default {{project}} +``` + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override).