diff --git a/.changelog/3135.txt b/.changelog/3135.txt new file mode 100644 index 0000000000..d8d7c3a2ca --- /dev/null +++ b/.changelog/3135.txt @@ -0,0 +1,6 @@ +```release-note:new-resource +`google_iap_brand` +``` +```release-note:new-resource +`google_iap_client` +``` diff --git a/google-beta/provider.go b/google-beta/provider.go index e99858de81..b7219b6d55 100644 --- a/google-beta/provider.go +++ b/google-beta/provider.go @@ -569,9 +569,9 @@ func Provider() terraform.ResourceProvider { return provider } -// Generated resources: 129 +// Generated resources: 131 // Generated IAM resources: 54 -// Total generated resources: 183 +// Total generated resources: 185 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -710,6 +710,8 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_iap_tunnel_instance_iam_binding": ResourceIamBinding(IapTunnelInstanceIamSchema, IapTunnelInstanceIamUpdaterProducer, IapTunnelInstanceIdParseFunc), "google_iap_tunnel_instance_iam_member": ResourceIamMember(IapTunnelInstanceIamSchema, IapTunnelInstanceIamUpdaterProducer, IapTunnelInstanceIdParseFunc), "google_iap_tunnel_instance_iam_policy": ResourceIamPolicy(IapTunnelInstanceIamSchema, IapTunnelInstanceIamUpdaterProducer, IapTunnelInstanceIdParseFunc), + "google_iap_brand": resourceIapBrand(), + "google_iap_client": resourceIapClient(), "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-beta/provider_test.go b/google-beta/provider_test.go index 414771c0d2..cdd8f3c242 100644 --- a/google-beta/provider_test.go +++ b/google-beta/provider_test.go @@ -60,6 +60,10 @@ var orgEnvVars = []string{ "GOOGLE_ORG", } +var orgEnvDomainVars = []string{ + "GOOGLE_ORG_DOMAIN", +} + var serviceAccountEnvVars = []string{ "GOOGLE_SERVICE_ACCOUNT", } @@ -656,6 +660,11 @@ func getTestOrgFromEnv(t *testing.T) string { return multiEnvSearch(orgEnvVars) } +func getTestOrgDomainFromEnv(t *testing.T) string { + skipIfEnvNotSet(t, orgEnvDomainVars...) + return multiEnvSearch(orgEnvDomainVars) +} + func getTestOrgTargetFromEnv(t *testing.T) string { skipIfEnvNotSet(t, orgTargetEnvVars...) return multiEnvSearch(orgTargetEnvVars) diff --git a/google-beta/resource_iap_brand.go b/google-beta/resource_iap_brand.go new file mode 100644 index 0000000000..2ca039915c --- /dev/null +++ b/google-beta/resource_iap_brand.go @@ -0,0 +1,223 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// 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/helper/schema" +) + +func resourceIapBrand() *schema.Resource { + return &schema.Resource{ + Create: resourceIapBrandCreate, + Read: resourceIapBrandRead, + Delete: resourceIapBrandDelete, + + Importer: &schema.ResourceImporter{ + State: resourceIapBrandImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "application_title": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Application name displayed on OAuth consent screen.`, + }, + "support_email": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Support email displayed on the OAuth consent screen. Can be either a +user or group email. When a user email is specified, the caller must +be the user with the associated email address. When a group email is +specified, the caller can be either a user or a service account which +is an owner of the specified group in Cloud Identity.`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `Output only. Identifier of the brand, in the format +'projects/{project_number}/brands/{brand_id}'. NOTE: The brand +identification corresponds to the project number as only one +brand per project can be created.`, + }, + "org_internal_only": { + Type: schema.TypeBool, + Computed: true, + Description: `Whether the brand is only intended for usage inside the GSuite organization only.`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + } +} + +func resourceIapBrandCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + obj := make(map[string]interface{}) + supportEmailProp, err := expandIapBrandSupportEmail(d.Get("support_email"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("support_email"); !isEmptyValue(reflect.ValueOf(supportEmailProp)) && (ok || !reflect.DeepEqual(v, supportEmailProp)) { + obj["supportEmail"] = supportEmailProp + } + applicationTitleProp, err := expandIapBrandApplicationTitle(d.Get("application_title"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("application_title"); !isEmptyValue(reflect.ValueOf(applicationTitleProp)) && (ok || !reflect.DeepEqual(v, applicationTitleProp)) { + obj["applicationTitle"] = applicationTitleProp + } + + url, err := replaceVars(d, config, "{{IapBasePath}}projects/{{project}}/brands") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new Brand: %#v", obj) + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating Brand: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating Brand %q: %#v", d.Id(), res) + + // `name` is autogenerated from the api so needs to be set post-create + name, ok := res["name"] + if !ok { + return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.") + } + d.Set("name", name.(string)) + d.SetId(name.(string)) + + return resourceIapBrandRead(d, meta) +} + +func resourceIapBrandRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{IapBasePath}}{{name}}") + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequest(config, "GET", project, url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("IapBrand %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading Brand: %s", err) + } + + if err := d.Set("support_email", flattenIapBrandSupportEmail(res["supportEmail"], d, config)); err != nil { + return fmt.Errorf("Error reading Brand: %s", err) + } + if err := d.Set("application_title", flattenIapBrandApplicationTitle(res["applicationTitle"], d, config)); err != nil { + return fmt.Errorf("Error reading Brand: %s", err) + } + if err := d.Set("org_internal_only", flattenIapBrandOrgInternalOnly(res["orgInternalOnly"], d, config)); err != nil { + return fmt.Errorf("Error reading Brand: %s", err) + } + if err := d.Set("name", flattenIapBrandName(res["name"], d, config)); err != nil { + return fmt.Errorf("Error reading Brand: %s", err) + } + + return nil +} + +func resourceIapBrandDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[WARNING] Iap Brand resources"+ + " cannot be deleted from GCP. The resource %s will be removed from Terraform"+ + " state, but will still be present on the server.", d.Id()) + d.SetId("") + + return nil +} + +func resourceIapBrandImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + + // current import_formats can't import fields with forward slashes in their value + if err := parseImportId([]string{"(?P.+)"}, d, config); err != nil { + return nil, err + } + + nameParts := strings.Split(d.Get("name").(string), "/") + if len(nameParts) != 4 { + return nil, fmt.Errorf( + "Saw %s when the name is expected to have shape %s", + d.Get("name"), + "projects/{{project}}/brands/{{name}}", + ) + } + + d.Set("project", nameParts[1]) + return []*schema.ResourceData{d}, nil +} + +func flattenIapBrandSupportEmail(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenIapBrandApplicationTitle(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenIapBrandOrgInternalOnly(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenIapBrandName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func expandIapBrandSupportEmail(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandIapBrandApplicationTitle(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google-beta/resource_iap_brand_test.go b/google-beta/resource_iap_brand_test.go new file mode 100644 index 0000000000..2a35fe4133 --- /dev/null +++ b/google-beta/resource_iap_brand_test.go @@ -0,0 +1,55 @@ +package google + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccIapBrand_iapBrandExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "org_id": getTestOrgFromEnv(t), + "org_domain": getTestOrgDomainFromEnv(t), + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccIapBrand_iapBrandExample(context), + }, + { + ResourceName: "google_iap_brand.project_brand", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"project"}, + }, + }, + }) +} + +func testAccIapBrand_iapBrandExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = google_project.project.project_id + service = "iap.googleapis.com" +} + +resource "google_iap_brand" "project_brand" { + support_email = "support@%{org_domain}" + application_title = "Cloud IAP protected Application" + project = google_project_service.project_service.project +} +`, context) +} diff --git a/google-beta/resource_iap_client.go b/google-beta/resource_iap_client.go new file mode 100644 index 0000000000..2776f2ab26 --- /dev/null +++ b/google-beta/resource_iap_client.go @@ -0,0 +1,197 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// 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/helper/schema" +) + +func resourceIapClient() *schema.Resource { + return &schema.Resource{ + Create: resourceIapClientCreate, + Read: resourceIapClientRead, + Delete: resourceIapClientDelete, + + Importer: &schema.ResourceImporter{ + State: resourceIapClientImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "brand": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Identifier of the brand to which this client +is attached to. The format is +'projects/{project_number}/brands/{brand_id}/identityAwareProxyClients/{client_id}'.`, + }, + "display_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Human-friendly name given to the OAuth client.`, + }, + "client_id": { + Type: schema.TypeString, + Computed: true, + Description: `Output only. Unique identifier of the OAuth client.`, + }, + "secret": { + Type: schema.TypeString, + Computed: true, + Description: `Output only. Client secret of the OAuth client.`, + Sensitive: true, + }, + }, + } +} + +func resourceIapClientCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + obj := make(map[string]interface{}) + displayNameProp, err := expandIapClientDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + + url, err := replaceVars(d, config, "{{IapBasePath}}{{brand}}/identityAwareProxyClients") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new Client: %#v", obj) + res, err := sendRequestWithTimeout(config, "POST", "", url, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating Client: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "{{brand}}/identityAwareProxyClients/{{client_id}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating Client %q: %#v", d.Id(), res) + + brand := d.Get("brand") + clientId := flattenIapClientClientId(res["name"], d, config) + + d.Set("client_id", clientId) + d.SetId(fmt.Sprintf("%s/identityAwareProxyClients/%s", brand, clientId)) + + return resourceIapClientRead(d, meta) +} + +func resourceIapClientRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{IapBasePath}}{{brand}}/identityAwareProxyClients/{{client_id}}") + if err != nil { + return err + } + + res, err := sendRequest(config, "GET", "", url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("IapClient %q", d.Id())) + } + + if err := d.Set("secret", flattenIapClientSecret(res["secret"], d, config)); err != nil { + return fmt.Errorf("Error reading Client: %s", err) + } + if err := d.Set("display_name", flattenIapClientDisplayName(res["displayName"], d, config)); err != nil { + return fmt.Errorf("Error reading Client: %s", err) + } + if err := d.Set("client_id", flattenIapClientClientId(res["name"], d, config)); err != nil { + return fmt.Errorf("Error reading Client: %s", err) + } + + return nil +} + +func resourceIapClientDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{IapBasePath}}{{brand}}/identityAwareProxyClients/{{client_id}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting Client %q", d.Id()) + + res, err := sendRequestWithTimeout(config, "DELETE", "", url, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "Client") + } + + log.Printf("[DEBUG] Finished deleting Client %q: %#v", d.Id(), res) + return nil +} + +func resourceIapClientImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + + // current import_formats can't import fields with forward slashes in their value + if err := parseImportId([]string{"(?P.+)"}, d, config); err != nil { + return nil, err + } + + nameParts := strings.Split(d.Get("brand").(string), "/") + if len(nameParts) != 6 { + return nil, fmt.Errorf( + "Saw %s when the name is expected to have shape %s", + d.Get("brand").(string), + "projects/{{project_number}}/brands/{{brand_id}}/identityAwareProxyClients/{{client_id}}", + ) + } + + d.Set("brand", fmt.Sprintf("projects/%s/brands/%s", nameParts[1], nameParts[3])) + d.Set("client_id", nameParts[5]) + return []*schema.ResourceData{d}, nil +} + +func flattenIapClientSecret(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenIapClientDisplayName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenIapClientClientId(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return v + } + return NameFromSelfLinkStateFunc(v) +} + +func expandIapClientDisplayName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google-beta/resource_iap_client_generated_test.go b/google-beta/resource_iap_client_generated_test.go new file mode 100644 index 0000000000..69d291c423 --- /dev/null +++ b/google-beta/resource_iap_client_generated_test.go @@ -0,0 +1,103 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// 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" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccIapClient_iapClientExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "org_id": getTestOrgFromEnv(t), + "org_domain": getTestOrgDomainFromEnv(t), + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckIapClientDestroy, + Steps: []resource.TestStep{ + { + Config: testAccIapClient_iapClientExample(context), + }, + { + ResourceName: "google_iap_client.project_client", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"brand"}, + }, + }, + }) +} + +func testAccIapClient_iapClientExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "%{org_id}" +} + +resource "google_project_service" "project_service" { + project = google_project.project.project_id + service = "iap.googleapis.com" +} + +resource "google_iap_brand" "project_brand" { + support_email = "support@%{org_domain}" + application_title = "Cloud IAP protected Application" + project = google_project_service.project_service.project +} + +resource "google_iap_client" "project_client" { + display_name = "Test Client" + brand = google_iap_brand.project_brand.name +} +`, context) +} + +func testAccCheckIapClientDestroy(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_iap_client" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := testAccProvider.Meta().(*Config) + + url, err := replaceVarsForTest(config, rs, "{{IapBasePath}}{{brand}}/identityAwareProxyClients/{{client_id}}") + if err != nil { + return err + } + + _, err = sendRequest(config, "GET", "", url, nil) + if err == nil { + return fmt.Errorf("IapClient still exists at %s", url) + } + } + + return nil +} diff --git a/google-beta/resource_iap_client_sweeper_test.go b/google-beta/resource_iap_client_sweeper_test.go new file mode 100644 index 0000000000..2e3e113dd3 --- /dev/null +++ b/google-beta/resource_iap_client_sweeper_test.go @@ -0,0 +1,119 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// 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 ( + "context" + "log" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func init() { + resource.AddTestSweepers("IapClient", &resource.Sweeper{ + Name: "IapClient", + F: testSweepIapClient, + }) +} + +// At the time of writing, the CI only passes us-central1 as the region +func testSweepIapClient(region string) error { + resourceName := "IapClient" + log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName) + + config, err := sharedConfigForRegion(region) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err) + return err + } + + err = config.LoadAndValidate(context.Background()) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err) + return err + } + + // Setup variables to replace in list template + d := &ResourceDataMock{ + FieldsInSchema: map[string]interface{}{ + "project": config.Project, + "region": region, + "location": region, + "zone": "-", + }, + } + + listTemplate := strings.Split("https://iap.googleapis.com/v1/{{brand}}/identityAwareProxyClients", "?")[0] + listUrl, err := replaceVars(d, config, listTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err) + return nil + } + + res, err := sendRequest(config, "GET", config.Project, listUrl, nil) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err) + return nil + } + + resourceList, ok := res["clients"] + if !ok { + log.Printf("[INFO][SWEEPER_LOG] Nothing found in response.") + return nil + } + + rl := resourceList.([]interface{}) + + log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName) + // items who don't match the tf-test prefix + nonPrefixCount := 0 + for _, ri := range rl { + obj := ri.(map[string]interface{}) + if obj["name"] == nil { + log.Printf("[INFO][SWEEPER_LOG] %s resource name was nil", resourceName) + return nil + } + + name := GetResourceNameFromSelfLink(obj["name"].(string)) + // Only sweep resources with the test prefix + if !strings.HasPrefix(name, "tf-test") { + nonPrefixCount++ + continue + } + + deleteTemplate := "https://iap.googleapis.com/v1/{{brand}}/identityAwareProxyClients/{{client_id}}" + deleteUrl, err := replaceVars(d, config, deleteTemplate) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err) + return nil + } + deleteUrl = deleteUrl + name + + // Don't wait on operations as we may have a lot to delete + _, err = sendRequest(config, "DELETE", config.Project, deleteUrl, nil) + if err != nil { + log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", deleteUrl, err) + } else { + log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name) + } + } + + if nonPrefixCount > 0 { + log.Printf("[INFO][SWEEPER_LOG] %d items without tf_test prefix remain.", nonPrefixCount) + } + + return nil +} diff --git a/website/docs/r/iap_brand.html.markdown b/website/docs/r/iap_brand.html.markdown new file mode 100644 index 0000000000..37a5934798 --- /dev/null +++ b/website/docs/r/iap_brand.html.markdown @@ -0,0 +1,120 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# 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-Aware Proxy" +layout: "google" +page_title: "Google: google_iap_brand" +sidebar_current: "docs-google-iap-brand" +description: |- + OAuth brand data. +--- + +# google\_iap\_brand + +OAuth brand data. Only "Organization Internal" brands can be created +programatically via API. To convert it into an external brands +please use the GCP Console. + + +~> **Note:** Brands can be created only once for a Google Cloud Platform +project and cannot be deleted. Destroying a Terraform-managed Brand +will remove it from state but *will not delete the resource on the server.* + + + +## Example Usage - Iap Brand + + +```hcl +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "123456789" +} + +resource "google_project_service" "project_service" { + project = google_project.project.project_id + service = "iap.googleapis.com" +} + +resource "google_iap_brand" "project_brand" { + support_email = "support@example.com" + application_title = "Cloud IAP protected Application" + project = google_project_service.project_service.project +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `support_email` - + (Required) + Support email displayed on the OAuth consent screen. Can be either a + user or group email. When a user email is specified, the caller must + be the user with the associated email address. When a group email is + specified, the caller can be either a user or a service account which + is an owner of the specified group in Cloud Identity. + +* `application_title` - + (Required) + Application name displayed on OAuth consent screen. + + +- - - + + +* `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 `{{name}}` + +* `org_internal_only` - + Whether the brand is only intended for usage inside the GSuite organization only. + +* `name` - + Output only. Identifier of the brand, in the format + `projects/{project_number}/brands/{brand_id}`. NOTE: The brand + identification corresponds to the project number as only one + brand per project can be created. + + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## Import + +Brand can be imported using any of these accepted formats: + +``` +$ terraform import google_iap_brand.default {{name}} +``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/docs/r/iap_client.html.markdown b/website/docs/r/iap_client.html.markdown new file mode 100644 index 0000000000..962c68c75c --- /dev/null +++ b/website/docs/r/iap_client.html.markdown @@ -0,0 +1,114 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# 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-Aware Proxy" +layout: "google" +page_title: "Google: google_iap_client" +sidebar_current: "docs-google-iap-client" +description: |- + Contains the data that describes an Identity Aware Proxy owned client. +--- + +# google\_iap\_client + +Contains the data that describes an Identity Aware Proxy owned client. + + + + +## Example Usage - Iap Client + + +```hcl +resource "google_project" "project" { + project_id = "tf-test%{random_suffix}" + name = "tf-test%{random_suffix}" + org_id = "123456789" +} + +resource "google_project_service" "project_service" { + project = google_project.project.project_id + service = "iap.googleapis.com" +} + +resource "google_iap_brand" "project_brand" { + support_email = "support@example.com" + application_title = "Cloud IAP protected Application" + project = google_project_service.project_service.project +} + +resource "google_iap_client" "project_client" { + display_name = "Test Client" + brand = google_iap_brand.project_brand.name +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `display_name` - + (Required) + Human-friendly name given to the OAuth client. + +* `brand` - + (Required) + Identifier of the brand to which this client + is attached to. The format is + `projects/{project_number}/brands/{brand_id}/identityAwareProxyClients/{client_id}`. + + +- - - + + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `{{brand}}/identityAwareProxyClients/{{client_id}}` + +* `secret` - + Output only. Client secret of the OAuth client. + +* `client_id` - + Output only. Unique identifier of the OAuth client. + + +* `client_id`: The OAuth2 ID of the client. + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## Import + +Client can be imported using any of these accepted formats: + +``` +$ terraform import google_iap_client.default {{brand}}/identityAwareProxyClients/{{client_id}} +$ terraform import google_iap_client.default {{brand}}/{{client_id}} +``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. diff --git a/website/google.erb b/website/google.erb index c4f17a3e88..775b99b60f 100644 --- a/website/google.erb +++ b/website/google.erb @@ -1128,6 +1128,12 @@ > Google IAP Resources