From 6077b79a8ba8cfa16292c962df5c993a0f62338f Mon Sep 17 00:00:00 2001 From: The Magician Date: Tue, 9 Jul 2024 15:23:48 -0700 Subject: [PATCH] Add data_source_google_site_verification_token (#10999) (#18688) [upstream:b33d6de70b36556872c5d0d870116b057878daf2] Signed-off-by: Modular Magician --- .changelog/10999.txt | 3 + .teamcity/components/inputs/services_beta.kt | 5 + .teamcity/components/inputs/services_ga.kt | 5 + google/fwmodels/provider_model.go | 1 + google/fwprovider/framework_provider.go | 6 + google/fwtransport/framework_config.go | 10 ++ google/provider/provider.go | 6 + google/provider/provider_mmv1_resources.go | 2 + ...a_source_google_site_verification_token.go | 149 ++++++++++++++++++ ...rce_google_site_verification_token_test.go | 105 ++++++++++++ google/sweeper/gcp_sweeper_test.go | 1 + google/transport/config.go | 9 ++ .../d/site_verification_token.html.markdown | 84 ++++++++++ 13 files changed, 386 insertions(+) create mode 100644 .changelog/10999.txt create mode 100644 google/services/siteverification/data_source_google_site_verification_token.go create mode 100644 google/services/siteverification/data_source_google_site_verification_token_test.go create mode 100644 website/docs/d/site_verification_token.html.markdown diff --git a/.changelog/10999.txt b/.changelog/10999.txt new file mode 100644 index 00000000000..2de90ada004 --- /dev/null +++ b/.changelog/10999.txt @@ -0,0 +1,3 @@ +```release-note:new-datasource +`google_site_verification_token` +``` \ No newline at end of file diff --git a/.teamcity/components/inputs/services_beta.kt b/.teamcity/components/inputs/services_beta.kt index 92b46f197d8..88daf1edbb6 100644 --- a/.teamcity/components/inputs/services_beta.kt +++ b/.teamcity/components/inputs/services_beta.kt @@ -661,6 +661,11 @@ var ServicesListBeta = mapOf( "displayName" to "Serviceusage", "path" to "./google-beta/services/serviceusage" ), + "siteverification" to mapOf( + "name" to "siteverification", + "displayName" to "Siteverification", + "path" to "./google-beta/services/siteverification" + ), "sourcerepo" to mapOf( "name" to "sourcerepo", "displayName" to "Sourcerepo", diff --git a/.teamcity/components/inputs/services_ga.kt b/.teamcity/components/inputs/services_ga.kt index c0d118fdc1b..1b0d2a1d8a6 100644 --- a/.teamcity/components/inputs/services_ga.kt +++ b/.teamcity/components/inputs/services_ga.kt @@ -656,6 +656,11 @@ var ServicesListGa = mapOf( "displayName" to "Serviceusage", "path" to "./google/services/serviceusage" ), + "siteverification" to mapOf( + "name" to "siteverification", + "displayName" to "Siteverification", + "path" to "./google/services/siteverification" + ), "sourcerepo" to mapOf( "name" to "sourcerepo", "displayName" to "Sourcerepo", diff --git a/google/fwmodels/provider_model.go b/google/fwmodels/provider_model.go index 886d9b2791a..79a4905c161 100644 --- a/google/fwmodels/provider_model.go +++ b/google/fwmodels/provider_model.go @@ -135,6 +135,7 @@ type ProviderModel struct { ServiceManagementCustomEndpoint types.String `tfsdk:"service_management_custom_endpoint"` ServiceNetworkingCustomEndpoint types.String `tfsdk:"service_networking_custom_endpoint"` ServiceUsageCustomEndpoint types.String `tfsdk:"service_usage_custom_endpoint"` + SiteVerificationCustomEndpoint types.String `tfsdk:"site_verification_custom_endpoint"` SourceRepoCustomEndpoint types.String `tfsdk:"source_repo_custom_endpoint"` SpannerCustomEndpoint types.String `tfsdk:"spanner_custom_endpoint"` SQLCustomEndpoint types.String `tfsdk:"sql_custom_endpoint"` diff --git a/google/fwprovider/framework_provider.go b/google/fwprovider/framework_provider.go index 026d78a2122..2e7e8864bec 100644 --- a/google/fwprovider/framework_provider.go +++ b/google/fwprovider/framework_provider.go @@ -786,6 +786,12 @@ func (p *FrameworkProvider) Schema(_ context.Context, _ provider.SchemaRequest, transport_tpg.CustomEndpointValidator(), }, }, + "site_verification_custom_endpoint": &schema.StringAttribute{ + Optional: true, + Validators: []validator.String{ + transport_tpg.CustomEndpointValidator(), + }, + }, "source_repo_custom_endpoint": &schema.StringAttribute{ Optional: true, Validators: []validator.String{ diff --git a/google/fwtransport/framework_config.go b/google/fwtransport/framework_config.go index e5ff8390134..6856302dfdc 100644 --- a/google/fwtransport/framework_config.go +++ b/google/fwtransport/framework_config.go @@ -158,6 +158,7 @@ type FrameworkProviderConfig struct { ServiceManagementBasePath string ServiceNetworkingBasePath string ServiceUsageBasePath string + SiteVerificationBasePath string SourceRepoBasePath string SpannerBasePath string SQLBasePath string @@ -317,6 +318,7 @@ func (p *FrameworkProviderConfig) LoadAndValidateFramework(ctx context.Context, p.ServiceManagementBasePath = data.ServiceManagementCustomEndpoint.ValueString() p.ServiceNetworkingBasePath = data.ServiceNetworkingCustomEndpoint.ValueString() p.ServiceUsageBasePath = data.ServiceUsageCustomEndpoint.ValueString() + p.SiteVerificationBasePath = data.SiteVerificationCustomEndpoint.ValueString() p.SourceRepoBasePath = data.SourceRepoCustomEndpoint.ValueString() p.SpannerBasePath = data.SpannerCustomEndpoint.ValueString() p.SQLBasePath = data.SQLCustomEndpoint.ValueString() @@ -1313,6 +1315,14 @@ func (p *FrameworkProviderConfig) HandleDefaults(ctx context.Context, data *fwmo data.ServiceUsageCustomEndpoint = types.StringValue(customEndpoint.(string)) } } + if data.SiteVerificationCustomEndpoint.IsNull() { + customEndpoint := transport_tpg.MultiEnvDefault([]string{ + "GOOGLE_SITE_VERIFICATION_CUSTOM_ENDPOINT", + }, transport_tpg.DefaultBasePaths[transport_tpg.SiteVerificationBasePathKey]) + if customEndpoint != nil { + data.SiteVerificationCustomEndpoint = types.StringValue(customEndpoint.(string)) + } + } if data.SourceRepoCustomEndpoint.IsNull() { customEndpoint := transport_tpg.MultiEnvDefault([]string{ "GOOGLE_SOURCE_REPO_CUSTOM_ENDPOINT", diff --git a/google/provider/provider.go b/google/provider/provider.go index 1e651bda625..e9934f589b7 100644 --- a/google/provider/provider.go +++ b/google/provider/provider.go @@ -679,6 +679,11 @@ func Provider() *schema.Provider { Optional: true, ValidateFunc: transport_tpg.ValidateCustomEndpoint, }, + "site_verification_custom_endpoint": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: transport_tpg.ValidateCustomEndpoint, + }, "source_repo_custom_endpoint": { Type: schema.TypeString, Optional: true, @@ -1043,6 +1048,7 @@ func ProviderConfigure(ctx context.Context, d *schema.ResourceData, p *schema.Pr config.ServiceManagementBasePath = d.Get("service_management_custom_endpoint").(string) config.ServiceNetworkingBasePath = d.Get("service_networking_custom_endpoint").(string) config.ServiceUsageBasePath = d.Get("service_usage_custom_endpoint").(string) + config.SiteVerificationBasePath = d.Get("site_verification_custom_endpoint").(string) config.SourceRepoBasePath = d.Get("source_repo_custom_endpoint").(string) config.SpannerBasePath = d.Get("spanner_custom_endpoint").(string) config.SQLBasePath = d.Get("sql_custom_endpoint").(string) diff --git a/google/provider/provider_mmv1_resources.go b/google/provider/provider_mmv1_resources.go index ccf5fa70cd3..17424f12880 100644 --- a/google/provider/provider_mmv1_resources.go +++ b/google/provider/provider_mmv1_resources.go @@ -129,6 +129,7 @@ import ( "github.com/hashicorp/terraform-provider-google/google/services/containeraws" "github.com/hashicorp/terraform-provider-google/google/services/containerazure" "github.com/hashicorp/terraform-provider-google/google/services/dataflow" + "github.com/hashicorp/terraform-provider-google/google/services/siteverification" "github.com/hashicorp/terraform-provider-google/google/tpgiamresource" ) @@ -272,6 +273,7 @@ var handwrittenDatasources = map[string]*schema.Resource{ "google_service_account_id_token": resourcemanager.DataSourceGoogleServiceAccountIdToken(), "google_service_account_jwt": resourcemanager.DataSourceGoogleServiceAccountJwt(), "google_service_account_key": resourcemanager.DataSourceGoogleServiceAccountKey(), + "google_site_verification_token": siteverification.DataSourceSiteVerificationToken(), "google_sourcerepo_repository": sourcerepo.DataSourceGoogleSourceRepoRepository(), "google_spanner_instance": spanner.DataSourceSpannerInstance(), "google_sql_ca_certs": sql.DataSourceGoogleSQLCaCerts(), diff --git a/google/services/siteverification/data_source_google_site_verification_token.go b/google/services/siteverification/data_source_google_site_verification_token.go new file mode 100644 index 00000000000..b0bbf20fecc --- /dev/null +++ b/google/services/siteverification/data_source_google_site_verification_token.go @@ -0,0 +1,149 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +package siteverification + +import ( + "fmt" + "log" + "net/http" + "reflect" + "regexp" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-provider-google/google/verify" +) + +func DataSourceSiteVerificationToken() *schema.Resource { + return &schema.Resource{ + Read: dataSourceSiteVerificationTokenRead, + + Timeouts: &schema.ResourceTimeout{ + Read: schema.DefaultTimeout(5 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "identifier": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The site identifier. If the type is set to SITE, the identifier is a URL. If the type is +set to INET_DOMAIN, the identifier is a domain name.`, + }, + "type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: verify.ValidateEnum([]string{"INET_DOMAIN", "SITE"}), + Description: `The type of resource to be verified, either a domain or a web site. Possible values: ["INET_DOMAIN", "SITE"]`, + }, + "verification_method": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: verify.ValidateEnum([]string{"ANALYTICS", "DNS_CNAME", "DNS_TXT", "FILE", "META", "TAG_MANAGER"}), + Description: `The verification method for the Site Verification system to use to verify +this site or domain. Possible values: ["ANALYTICS", "DNS_CNAME", "DNS_TXT", "FILE", "META", "TAG_MANAGER"]`, + }, + "token": { + Type: schema.TypeString, + Computed: true, + Description: `The returned token for use in subsequent verification steps.`, + }, + }, + UseJSONNumber: true, + } +} + +func dataSourceSiteVerificationTokenRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + site := make(map[string]interface{}) + typeProp, err := expandSiteVerificationTokenType(d.Get("type"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("type"); !tpgresource.IsEmptyValue(reflect.ValueOf(typeProp)) && (ok || !reflect.DeepEqual(v, typeProp)) { + site["type"] = typeProp + } + identifierProp, err := expandSiteVerificationTokenIdentifier(d.Get("identifier"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("identifier"); !tpgresource.IsEmptyValue(reflect.ValueOf(identifierProp)) && (ok || !reflect.DeepEqual(v, identifierProp)) { + site["identifier"] = identifierProp + } + obj["site"] = site + verification_methodProp, err := expandSiteVerificationTokenVerificationMethod(d.Get("verification_method"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("verification_method"); !tpgresource.IsEmptyValue(reflect.ValueOf(verification_methodProp)) && (ok || !reflect.DeepEqual(v, verification_methodProp)) { + obj["verificationMethod"] = verification_methodProp + } + + url, err := tpgresource.ReplaceVars(d, config, "{{SiteVerificationBasePath}}token") + if err != nil { + return err + } + + log.Printf("[DEBUG] Reading Token: %#v", obj) + billingProject := "" + + if parts := regexp.MustCompile(`projects\/([^\/]+)\/`).FindStringSubmatch(url); parts != nil { + billingProject = parts[1] + } + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + headers := make(http.Header) + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "POST", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + Body: obj, + Timeout: d.Timeout(schema.TimeoutCreate), + Headers: headers, + }) + if err != nil { + return fmt.Errorf("Error reading Token: %s", err) + } + + // Store the ID now + id, err := tpgresource.ReplaceVars(d, config, "{{identifier}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + if token, ok := res["token"].(string); ok { + d.Set("token", token) + } + + log.Printf("[DEBUG] Finished reading Token %q: %#v", d.Id(), res) + + return nil +} + +func expandSiteVerificationTokenType(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandSiteVerificationTokenIdentifier(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandSiteVerificationTokenVerificationMethod(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} diff --git a/google/services/siteverification/data_source_google_site_verification_token_test.go b/google/services/siteverification/data_source_google_site_verification_token_test.go new file mode 100644 index 00000000000..361699167e1 --- /dev/null +++ b/google/services/siteverification/data_source_google_site_verification_token_test.go @@ -0,0 +1,105 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +package siteverification_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-google/google/acctest" +) + +func TestAccSiteVerificationToken_siteverificationTokenSite(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "site": "https://www.example.com", + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccSiteVerificationToken_siteverificationTokenSite(context), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.google_site_verification_token.site_meta", "token"), + resource.TestCheckResourceAttr("data.google_site_verification_token.site_meta", "type", "SITE"), + resource.TestCheckResourceAttr("data.google_site_verification_token.site_meta", "identifier", context["site"].(string)), + resource.TestCheckResourceAttr("data.google_site_verification_token.site_meta", "verification_method", "META"), + ), + }, + }, + }) +} + +func testAccSiteVerificationToken_siteverificationTokenSite(context map[string]interface{}) string { + return acctest.Nprintf(` +provider "google" { + alias = "scoped" + user_project_override = true + scopes = [ + "https://www.googleapis.com/auth/siteverification", + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/userinfo.email", + ] +} + +data "google_site_verification_token" "site_meta" { + provider = google.scoped + type = "SITE" + identifier = "%{site}" + verification_method = "META" +} +`, context) +} + +func TestAccSiteVerificationToken_siteverificationTokenDomain(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "domain": "www.example.com", + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + ExternalProviders: map[string]resource.ExternalProvider{ + "time": {}, + }, + Steps: []resource.TestStep{ + { + Config: testAccSiteVerificationToken_siteverificationTokenDomain(context), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.google_site_verification_token.dns_text", "token"), + resource.TestCheckResourceAttr("data.google_site_verification_token.dns_text", "type", "INET_DOMAIN"), + resource.TestCheckResourceAttr("data.google_site_verification_token.dns_text", "identifier", context["domain"].(string)), + resource.TestCheckResourceAttr("data.google_site_verification_token.dns_text", "verification_method", "DNS_TXT"), + ), + }, + }, + }) +} + +func testAccSiteVerificationToken_siteverificationTokenDomain(context map[string]interface{}) string { + return acctest.Nprintf(` +provider "google" { + alias = "scoped" + user_project_override = true + scopes = [ + "https://www.googleapis.com/auth/siteverification", + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/userinfo.email", + ] +} + +data "google_site_verification_token" "dns_text" { + provider = google.scoped + type = "INET_DOMAIN" + identifier = "%{domain}" + verification_method = "DNS_TXT" +} +`, context) +} diff --git a/google/sweeper/gcp_sweeper_test.go b/google/sweeper/gcp_sweeper_test.go index 91a14669494..438a5964aaa 100644 --- a/google/sweeper/gcp_sweeper_test.go +++ b/google/sweeper/gcp_sweeper_test.go @@ -114,6 +114,7 @@ import ( _ "github.com/hashicorp/terraform-provider-google/google/services/servicemanagement" _ "github.com/hashicorp/terraform-provider-google/google/services/servicenetworking" _ "github.com/hashicorp/terraform-provider-google/google/services/serviceusage" + _ "github.com/hashicorp/terraform-provider-google/google/services/siteverification" _ "github.com/hashicorp/terraform-provider-google/google/services/sourcerepo" _ "github.com/hashicorp/terraform-provider-google/google/services/spanner" _ "github.com/hashicorp/terraform-provider-google/google/services/sql" diff --git a/google/transport/config.go b/google/transport/config.go index fcda6a244ee..947a062b9e1 100644 --- a/google/transport/config.go +++ b/google/transport/config.go @@ -294,6 +294,7 @@ type Config struct { ServiceManagementBasePath string ServiceNetworkingBasePath string ServiceUsageBasePath string + SiteVerificationBasePath string SourceRepoBasePath string SpannerBasePath string SQLBasePath string @@ -433,6 +434,7 @@ const SecuritypostureBasePathKey = "Securityposture" const ServiceManagementBasePathKey = "ServiceManagement" const ServiceNetworkingBasePathKey = "ServiceNetworking" const ServiceUsageBasePathKey = "ServiceUsage" +const SiteVerificationBasePathKey = "SiteVerification" const SourceRepoBasePathKey = "SourceRepo" const SpannerBasePathKey = "Spanner" const SQLBasePathKey = "SQL" @@ -566,6 +568,7 @@ var DefaultBasePaths = map[string]string{ ServiceManagementBasePathKey: "https://servicemanagement.googleapis.com/v1/", ServiceNetworkingBasePathKey: "https://servicenetworking.googleapis.com/v1/", ServiceUsageBasePathKey: "https://serviceusage.googleapis.com/v1/", + SiteVerificationBasePathKey: "https://www.googleapis.com/siteVerification/v1/", SourceRepoBasePathKey: "https://sourcerepo.googleapis.com/v1/", SpannerBasePathKey: "https://spanner.googleapis.com/v1/", SQLBasePathKey: "https://sqladmin.googleapis.com/sql/v1beta4/", @@ -1198,6 +1201,11 @@ func SetEndpointDefaults(d *schema.ResourceData) error { "GOOGLE_SERVICE_USAGE_CUSTOM_ENDPOINT", }, DefaultBasePaths[ServiceUsageBasePathKey])) } + if d.Get("site_verification_custom_endpoint") == "" { + d.Set("site_verification_custom_endpoint", MultiEnvDefault([]string{ + "GOOGLE_SITE_VERIFICATION_CUSTOM_ENDPOINT", + }, DefaultBasePaths[SiteVerificationBasePathKey])) + } if d.Get("source_repo_custom_endpoint") == "" { d.Set("source_repo_custom_endpoint", MultiEnvDefault([]string{ "GOOGLE_SOURCE_REPO_CUSTOM_ENDPOINT", @@ -2263,6 +2271,7 @@ func ConfigureBasePaths(c *Config) { c.ServiceManagementBasePath = DefaultBasePaths[ServiceManagementBasePathKey] c.ServiceNetworkingBasePath = DefaultBasePaths[ServiceNetworkingBasePathKey] c.ServiceUsageBasePath = DefaultBasePaths[ServiceUsageBasePathKey] + c.SiteVerificationBasePath = DefaultBasePaths[SiteVerificationBasePathKey] c.SourceRepoBasePath = DefaultBasePaths[SourceRepoBasePathKey] c.SpannerBasePath = DefaultBasePaths[SpannerBasePathKey] c.SQLBasePath = DefaultBasePaths[SQLBasePathKey] diff --git a/website/docs/d/site_verification_token.html.markdown b/website/docs/d/site_verification_token.html.markdown new file mode 100644 index 00000000000..066370eda29 --- /dev/null +++ b/website/docs/d/site_verification_token.html.markdown @@ -0,0 +1,84 @@ +subcategory: "Site Verification" +description: |- + A verification token is used to demonstrate ownership of a website or domain. +--- + +# google_site_verification_token + +A verification token is used to demonstrate ownership of a website or domain. + + +To get more information about Token, see: + +* [API documentation](https://developers.google.com/site-verification/v1) +* How-to Guides + * [Getting Started](https://developers.google.com/site-verification/v1/getting_started) + + + +## Example Usage - Site Verification via Site META Tag + +```hcl +data "google_site_verification_token" "example" { + type = "SITE" + identifier = "https://www.example.com" + verification_method = "META" +} +``` + +## Example Usage - Site Verification via DNS TXT Record + +```hcl +data "google_site_verification_token" "example" { + type = "INET_DOMAIN" + identifier = "www.example.com" + verification_method = "DNS_TXT" +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `type` - + (Required) + The type of resource to be verified, either a domain or a web site. + Possible values are: `INET_DOMAIN`, `SITE`. + +* `identifier` - + (Required) + The site identifier. If the type is set to SITE, the identifier is a URL. If the type is + set to INET_DOMAIN, the identifier is a domain name. + +* `verification_method` - + (Required) + The verification method for the Site Verification system to use to verify + this site or domain. + Possible values are: `ANALYTICS`, `DNS_CNAME`, `DNS_TXT`, `FILE`, `META`, `TAG_MANAGER`. + + +- - - + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `token` - + The generated token for use in subsequent verification steps. + + +## Timeouts + +This data source provides the following +[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options: + +- `read` - Default is 5 minutes. + +## User Project Overrides + +This data source supports [User Project Overrides](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference#user_project_override).