diff --git a/.changelog/11513.txt b/.changelog/11513.txt new file mode 100644 index 00000000000..42b910df155 --- /dev/null +++ b/.changelog/11513.txt @@ -0,0 +1,3 @@ +```release-note:none + +``` \ No newline at end of file diff --git a/google/acctest/resource_test_utils.go b/google/acctest/resource_test_utils.go index 541a942d9a4..a7829591bd0 100644 --- a/google/acctest/resource_test_utils.go +++ b/google/acctest/resource_test_utils.go @@ -3,17 +3,40 @@ package acctest import ( + "context" + "errors" "fmt" + "slices" "testing" "time" + tfjson "github.com/hashicorp/terraform-json" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/plancheck" "github.com/hashicorp/terraform-plugin-testing/terraform" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" ) // General test utils +var _ plancheck.PlanCheck = expectNoDelete{} + +type expectNoDelete struct{} + +func (e expectNoDelete) CheckPlan(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) { + var result error + for _, rc := range req.Plan.ResourceChanges { + if slices.Contains(rc.Change.Actions, tfjson.ActionDelete) { + result = errors.Join(result, fmt.Errorf("expected no deletion of resources, but %s has planned deletion", rc.Address)) + } + } + resp.Error = result +} + +func ExpectNoDelete() plancheck.PlanCheck { + return expectNoDelete{} +} + // TestExtractResourceAttr navigates a test's state to find the specified resource (or data source) attribute and makes the value // accessible via the attributeValue string pointer. func TestExtractResourceAttr(resourceName string, attributeName string, attributeValue *string) resource.TestCheckFunc { diff --git a/google/services/composer/resource_composer_environment_test.go b/google/services/composer/resource_composer_environment_test.go index f7eaf08c802..ce898d021a0 100644 --- a/google/services/composer/resource_composer_environment_test.go +++ b/google/services/composer/resource_composer_environment_test.go @@ -82,6 +82,8 @@ func TestAccComposerEnvironment_basic(t *testing.T) { // Checks that all updatable fields can be updated in one apply // (PATCH for Environments only is per-field) func TestAccComposerEnvironment_update(t *testing.T) { + // Currently failing + acctest.SkipIfVcr(t) t.Parallel() envName := fmt.Sprintf("%s-%d", testComposerEnvironmentPrefix, acctest.RandInt(t)) @@ -281,6 +283,8 @@ func TestAccComposerEnvironment_withDatabaseConfig(t *testing.T) { } func TestAccComposerEnvironment_withWebServerConfig(t *testing.T) { + // Currently failing + acctest.SkipIfVcr(t) t.Parallel() envName := fmt.Sprintf("%s-%d", testComposerEnvironmentPrefix, acctest.RandInt(t)) network := fmt.Sprintf("%s-%d", testComposerNetworkPrefix, acctest.RandInt(t)) diff --git a/google/services/compute/resource_compute_global_address.go b/google/services/compute/resource_compute_global_address.go index 492be98b7fa..06b541bcdcb 100644 --- a/google/services/compute/resource_compute_global_address.go +++ b/google/services/compute/resource_compute_global_address.go @@ -155,6 +155,12 @@ when purpose=PRIVATE_SERVICE_CONNECT`, Description: `All of labels (key/value pairs) present on the resource in GCP, including the labels configured through Terraform, other clients and services.`, Elem: &schema.Schema{Type: schema.TypeString}, }, + "label_fingerprint": { + Type: schema.TypeString, + Computed: true, + Description: `The fingerprint used for optimistic locking of this resource. Used +internally during updates.`, + }, "terraform_labels": { Type: schema.TypeMap, Computed: true, @@ -203,6 +209,12 @@ func resourceComputeGlobalAddressCreate(d *schema.ResourceData, meta interface{} } else if v, ok := d.GetOkExists("name"); !tpgresource.IsEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) { obj["name"] = nameProp } + labelFingerprintProp, err := expandComputeGlobalAddressLabelFingerprint(d.Get("label_fingerprint"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("label_fingerprint"); !tpgresource.IsEmptyValue(reflect.ValueOf(labelFingerprintProp)) && (ok || !reflect.DeepEqual(v, labelFingerprintProp)) { + obj["labelFingerprint"] = labelFingerprintProp + } ipVersionProp, err := expandComputeGlobalAddressIpVersion(d.Get("ip_version"), d, config) if err != nil { return err @@ -418,6 +430,9 @@ func resourceComputeGlobalAddressRead(d *schema.ResourceData, meta interface{}) if err := d.Set("labels", flattenComputeGlobalAddressLabels(res["labels"], d, config)); err != nil { return fmt.Errorf("Error reading GlobalAddress: %s", err) } + if err := d.Set("label_fingerprint", flattenComputeGlobalAddressLabelFingerprint(res["labelFingerprint"], d, config)); err != nil { + return fmt.Errorf("Error reading GlobalAddress: %s", err) + } if err := d.Set("ip_version", flattenComputeGlobalAddressIpVersion(res["ipVersion"], d, config)); err != nil { return fmt.Errorf("Error reading GlobalAddress: %s", err) } @@ -463,9 +478,15 @@ func resourceComputeGlobalAddressUpdate(d *schema.ResourceData, meta interface{} d.Partial(true) - if d.HasChange("effective_labels") { + if d.HasChange("label_fingerprint") || d.HasChange("effective_labels") { obj := make(map[string]interface{}) + labelFingerprintProp, err := expandComputeGlobalAddressLabelFingerprint(d.Get("label_fingerprint"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("label_fingerprint"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, labelFingerprintProp)) { + obj["labelFingerprint"] = labelFingerprintProp + } labelsProp, err := expandComputeGlobalAddressEffectiveLabels(d.Get("effective_labels"), d, config) if err != nil { return err @@ -621,6 +642,10 @@ func flattenComputeGlobalAddressLabels(v interface{}, d *schema.ResourceData, co return transformed } +func flattenComputeGlobalAddressLabelFingerprint(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func flattenComputeGlobalAddressIpVersion(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { return v } @@ -688,6 +713,10 @@ func expandComputeGlobalAddressName(v interface{}, d tpgresource.TerraformResour return v, nil } +func expandComputeGlobalAddressLabelFingerprint(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + func expandComputeGlobalAddressIpVersion(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } diff --git a/google/services/compute/resource_compute_global_address_test.go b/google/services/compute/resource_compute_global_address_test.go index 9af2e5754c2..60b831a8b7e 100644 --- a/google/services/compute/resource_compute_global_address_test.go +++ b/google/services/compute/resource_compute_global_address_test.go @@ -8,8 +8,48 @@ import ( "testing" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/plancheck" ) +func TestAccComputeGlobalAddress_update(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckComputeGlobalAddressDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeGlobalAddress_update1(context), + }, + { + ResourceName: "google_compute_global_address.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, + }, + { + Config: testAccComputeGlobalAddress_update2(context), + ConfigPlanChecks: resource.ConfigPlanChecks{ + PreApply: []plancheck.PlanCheck{ + acctest.ExpectNoDelete(), + }, + }, + }, + { + ResourceName: "google_compute_global_address.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"labels", "terraform_labels"}, + }, + }, + }) +} + func TestAccComputeGlobalAddress_ipv6(t *testing.T) { t.Parallel() @@ -76,3 +116,47 @@ resource "google_compute_global_address" "foobar" { } `, networkName, addressName) } + +func testAccComputeGlobalAddress_update1(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_compute_network" "foobar" { + name = "tf-test-address-%{random_suffix}" +} + +resource "google_compute_global_address" "foobar" { + address = "172.20.181.0" + description = "Description" + name = "tf-test-address-%{random_suffix}" + labels = { + foo = "bar" + } + ip_version = "IPV4" + prefix_length = 24 + address_type = "INTERNAL" + purpose = "VPC_PEERING" + network = google_compute_network.foobar.self_link +} +`, context) +} + +func testAccComputeGlobalAddress_update2(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_compute_network" "foobar" { + name = "tf-test-address-%{random_suffix}" +} + +resource "google_compute_global_address" "foobar" { + address = "172.20.181.0" + description = "Description" + name = "tf-test-address-%{random_suffix}" + labels = { + foo = "baz" + } + ip_version = "IPV4" + prefix_length = 24 + address_type = "INTERNAL" + purpose = "VPC_PEERING" + network = google_compute_network.foobar.self_link +} +`, context) +} diff --git a/google/services/securitycentermanagement/resource_scc_management_folder_security_health_analytics_custom_module_test.go b/google/services/securitycentermanagement/resource_scc_management_folder_security_health_analytics_custom_module_test.go index 6ad61ff4cca..737decbfbc3 100644 --- a/google/services/securitycentermanagement/resource_scc_management_folder_security_health_analytics_custom_module_test.go +++ b/google/services/securitycentermanagement/resource_scc_management_folder_security_health_analytics_custom_module_test.go @@ -18,8 +18,7 @@ import ( // Custom Module tests cannot be run in parallel without running into 409 Conflict reponses. // Run them as individual steps of an update test instead. -func TestAccSecurityCenterManagementFolderSecurityHealthAnalyticsCustomModule(t *testing.T) { - t.Parallel() +func testAccSecurityCenterManagementFolderSecurityHealthAnalyticsCustomModule(t *testing.T) { context := map[string]interface{}{ "org_id": envvar.GetTestOrgFromEnv(t), diff --git a/google/services/securitycentermanagement/resource_scc_management_organization_event_threat_detection_custom_module_test.go b/google/services/securitycentermanagement/resource_scc_management_organization_event_threat_detection_custom_module_test.go index f31b5638f11..65b9d9371a5 100644 --- a/google/services/securitycentermanagement/resource_scc_management_organization_event_threat_detection_custom_module_test.go +++ b/google/services/securitycentermanagement/resource_scc_management_organization_event_threat_detection_custom_module_test.go @@ -16,8 +16,28 @@ import ( transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" ) -func TestAccSecurityCenterManagementOrganizationEventThreatDetectionCustomModule(t *testing.T) { - t.Parallel() +func TestAccSecurityCenterManagement(t *testing.T) { + testCases := map[string]func(t *testing.T){ + "orgSecurity": testAccSecurityCenterManagementOrganizationSecurityHealthAnalyticsCustomModule, + "folderSecurity": testAccSecurityCenterManagementFolderSecurityHealthAnalyticsCustomModule, + "projectSecurity": testAccSecurityCenterManagementProjectSecurityHealthAnalyticsCustomModule, + "organization": testAccSecurityCenterManagementOrganizationEventThreatDetectionCustomModule, + } + + for name, tc := range testCases { + // shadow the tc variable into scope so that when + // the loop continues, if t.Run hasn't executed tc(t) + // yet, we don't have a race condition + // see https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables + tc := tc + t.Run(name, func(t *testing.T) { + tc(t) + }) + } +} + +func testAccSecurityCenterManagementOrganizationEventThreatDetectionCustomModule(t *testing.T) { + // t.Parallel() context := map[string]interface{}{ "org_id": envvar.GetTestOrgFromEnv(t), diff --git a/google/services/securitycentermanagement/resource_scc_management_organization_project_security_health_analytics_custom_module_test.go b/google/services/securitycentermanagement/resource_scc_management_organization_project_security_health_analytics_custom_module_test.go index 98d156bbd6d..54bc5135d0f 100644 --- a/google/services/securitycentermanagement/resource_scc_management_organization_project_security_health_analytics_custom_module_test.go +++ b/google/services/securitycentermanagement/resource_scc_management_organization_project_security_health_analytics_custom_module_test.go @@ -17,8 +17,7 @@ import ( // Custom Module tests cannot be run in parallel without running into 409 Conflict reponses. // Run them as individual steps of an update test instead. -func TestAccSecurityCenterManagementProjectSecurityHealthAnalyticsCustomModule(t *testing.T) { - t.Parallel() +func testAccSecurityCenterManagementProjectSecurityHealthAnalyticsCustomModule(t *testing.T) { context := map[string]interface{}{ "random_suffix": acctest.RandString(t, 10), diff --git a/google/services/securitycentermanagement/resource_scc_management_organization_security_health_analytics_custom_module_test.go b/google/services/securitycentermanagement/resource_scc_management_organization_security_health_analytics_custom_module_test.go index 607999b19ba..c74ac4d04d2 100644 --- a/google/services/securitycentermanagement/resource_scc_management_organization_security_health_analytics_custom_module_test.go +++ b/google/services/securitycentermanagement/resource_scc_management_organization_security_health_analytics_custom_module_test.go @@ -18,8 +18,7 @@ import ( // Custom Module tests cannot be run in parallel without running into 409 Conflict reponses. // Run them as individual steps of an update test instead. -func TestAccSecurityCenterManagementOrganizationSecurityHealthAnalyticsCustomModule(t *testing.T) { - t.Parallel() +func testAccSecurityCenterManagementOrganizationSecurityHealthAnalyticsCustomModule(t *testing.T) { context := map[string]interface{}{ "org_id": envvar.GetTestOrgFromEnv(t), diff --git a/google/services/vmwareengine/resource_vmwareengine_private_cloud.go b/google/services/vmwareengine/resource_vmwareengine_private_cloud.go index 051f38b8d21..bdfb9afbbe0 100644 --- a/google/services/vmwareengine/resource_vmwareengine_private_cloud.go +++ b/google/services/vmwareengine/resource_vmwareengine_private_cloud.go @@ -27,6 +27,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "google.golang.org/api/googleapi" "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" @@ -67,6 +68,52 @@ func isMultiNodePrivateCloud(d *schema.ResourceData) bool { return false } +func isPrivateCloudInDeletedState(config *transport_tpg.Config, d *schema.ResourceData, billingProject string, userAgent string) (bool, error) { + baseurl, err := tpgresource.ReplaceVars(d, config, "{{VmwareengineBasePath}}projects/{{project}}/locations/{{location}}/privateClouds/{{name}}") + if err != nil { + return false, err + } + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: baseurl, + UserAgent: userAgent, + }) + if err != nil { + if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { + log.Printf("[DEBUG] No existing private cloud found") + return false, nil + } + return false, err + } + // if resource exists but is marked for deletion + v, ok := res["state"] + if ok && v.(string) == "DELETED" { + log.Printf("[DEBUG] The Private cloud exists and is marked for deletion.") + return true, nil + } + return false, nil +} + +// Check if private cloud is absent or if it exists in a deleted state. +func pollCheckForPrivateCloudAbsence(resp map[string]interface{}, respErr error) transport_tpg.PollResult { + if respErr != nil { + if transport_tpg.IsGoogleApiErrorWithCode(respErr, 404) { + return transport_tpg.SuccessPollResult() + } + return transport_tpg.ErrorPollResult(respErr) + } + // if resource exists but is marked for deletion + log.Printf("[DEBUG] Fetching state of the private cloud.") + v, ok := resp["state"] + if ok && v.(string) == "DELETED" { + log.Printf("[DEBUG] The Private cloud has been successfully marked for delayed deletion.") + return transport_tpg.SuccessPollResult() + } + return transport_tpg.PendingStatusPollResult("found") +} + func ResourceVmwareenginePrivateCloud() *schema.Resource { return &schema.Resource{ Create: resourceVmwareenginePrivateCloudCreate, @@ -400,6 +447,21 @@ func resourceVmwareenginePrivateCloudCreate(d *schema.ResourceData, meta interfa } headers := make(http.Header) + // Check if the project exists in a deleted state + pcMarkedForDeletion, err := isPrivateCloudInDeletedState(config, d, billingProject, userAgent) + if err != nil { + return fmt.Errorf("Error checking if Private Cloud exists and is marked for deletion: %s", err) + } + if pcMarkedForDeletion { + log.Printf("[DEBUG] Private Cloud exists and is marked for deletion. Triggering UNDELETE of the Private Cloud.\n") + url, err = tpgresource.ReplaceVars(d, config, "{{VmwareengineBasePath}}projects/{{project}}/locations/{{location}}/privateClouds/{{name}}:undelete") + if err != nil { + return err + } + obj = make(map[string]interface{}) + } else { + log.Printf("[DEBUG] Private Cloud is not found to be marked for deletion. Triggering CREATE of the Private Cloud.\n") + } res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ Config: config, Method: "POST", @@ -742,18 +804,11 @@ func resourceVmwareenginePrivateCloudDelete(d *schema.ResourceData, meta interfa if err != nil { return res, err } - // if resource exists but is marked for deletion - log.Printf("[DEBUG] Fetching state of the private cloud.") - v, ok := res["state"] - if ok && v.(string) == "DELETED" { - log.Printf("[DEBUG] The Private cloud has been successfully marked for delayed deletion.") - return nil, nil - } return res, nil } } - err = transport_tpg.PollingWaitTime(privateCloudPollRead(d, meta), transport_tpg.PollCheckForAbsence, "Deleting PrivateCloud", d.Timeout(schema.TimeoutDelete), 10) + err = transport_tpg.PollingWaitTime(privateCloudPollRead(d, meta), pollCheckForPrivateCloudAbsence, "Deleting PrivateCloud", d.Timeout(schema.TimeoutDelete), 10) if err != nil { return fmt.Errorf("Error waiting to delete PrivateCloud: %s", err) } diff --git a/google/services/vmwareengine/resource_vmwareengine_private_cloud_test.go b/google/services/vmwareengine/resource_vmwareengine_private_cloud_test.go index 995df2c47e6..677358e07f4 100644 --- a/google/services/vmwareengine/resource_vmwareengine_private_cloud_test.go +++ b/google/services/vmwareengine/resource_vmwareengine_private_cloud_test.go @@ -49,13 +49,13 @@ func TestAccVmwareenginePrivateCloud_vmwareEnginePrivateCloudUpdate(t *testing.T testAccCheckGoogleVmwareengineVcenterCredentialsMeta("data.google_vmwareengine_vcenter_credentials.vcenter-ds"), ), }, - { ResourceName: "google_vmwareengine_private_cloud.vmw-engine-pc", ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"location", "name", "update_time", "type", "deletion_delay_hours", "send_deletion_delay_hours_if_zero"}, }, + { Config: testVmwareenginePrivateCloudUpdateConfig(context), Check: resource.ComposeTestCheckFunc( @@ -69,13 +69,43 @@ func TestAccVmwareenginePrivateCloud_vmwareEnginePrivateCloudUpdate(t *testing.T }), ), }, + { + ResourceName: "google_vmwareengine_private_cloud.vmw-engine-pc", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location", "name", "update_time", "type", "deletion_delay_hours", "send_deletion_delay_hours_if_zero"}, + }, + { + Config: testVmwareenginePrivateCloudDelayedDeleteConfig(context), + }, + { + ResourceName: "google_vmwareengine_network.vmw-engine-nw", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"location", "name"}, + }, + + { + Config: testVmwareenginePrivateCloudUndeleteConfig(context), + Check: resource.ComposeTestCheckFunc( + acctest.CheckDataSourceStateMatchesResourceStateWithIgnores( + "data.google_vmwareengine_private_cloud.ds", + "google_vmwareengine_private_cloud.vmw-engine-pc", + map[string]struct{}{ + "type": {}, + "deletion_delay_hours": {}, + "send_deletion_delay_hours_if_zero": {}, + }), + ), + }, { ResourceName: "google_vmwareengine_private_cloud.vmw-engine-pc", ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"location", "name", "update_time", "type", "deletion_delay_hours", "send_deletion_delay_hours_if_zero"}, }, + { Config: testVmwareengineSubnetImportConfig(context), Check: resource.ComposeTestCheckFunc( @@ -88,6 +118,7 @@ func TestAccVmwareenginePrivateCloud_vmwareEnginePrivateCloudUpdate(t *testing.T ImportStateVerify: true, ImportStateVerifyIgnore: []string{"parent", "name"}, }, + { Config: testVmwareengineSubnetUpdateConfig(context), }, @@ -106,6 +137,14 @@ func testVmwareenginePrivateCloudCreateConfig(context map[string]interface{}) st } func testVmwareenginePrivateCloudUpdateConfig(context map[string]interface{}) string { + return testVmwareenginePrivateCloudConfig(context, "sample updated description", "STANDARD", 3, 8) + testVmwareengineVcenterNSXCredentailsConfig(context) +} + +func testVmwareenginePrivateCloudDelayedDeleteConfig(context map[string]interface{}) string { + return testVmwareenginePrivateCloudDeletedConfig(context) +} + +func testVmwareenginePrivateCloudUndeleteConfig(context map[string]interface{}) string { return testVmwareenginePrivateCloudConfig(context, "sample updated description", "STANDARD", 3, 0) + testVmwareengineVcenterNSXCredentailsConfig(context) } @@ -123,7 +162,7 @@ func testVmwareenginePrivateCloudConfig(context map[string]interface{}, descript context["description"] = description context["type"] = pcType return acctest.Nprintf(` -resource "google_vmwareengine_network" "default-nw" { +resource "google_vmwareengine_network" "vmw-engine-nw" { name = "tf-test-pc-nw-%{random_suffix}" location = "global" type = "STANDARD" @@ -139,7 +178,7 @@ resource "google_vmwareengine_private_cloud" "vmw-engine-pc" { send_deletion_delay_hours_if_zero = true network_config { management_cidr = "192.168.0.0/24" - vmware_engine_network = google_vmwareengine_network.default-nw.id + vmware_engine_network = google_vmwareengine_network.vmw-engine-nw.id } management_cluster { cluster_id = "tf-test-sample-mgmt-cluster-custom-core-count%{random_suffix}" @@ -161,6 +200,17 @@ data "google_vmwareengine_private_cloud" "ds" { `, context) } +func testVmwareenginePrivateCloudDeletedConfig(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_vmwareengine_network" "vmw-engine-nw" { + name = "tf-test-pc-nw-%{random_suffix}" + location = "global" + type = "STANDARD" + description = "PC network description." +} +`, context) +} + func testVmwareengineVcenterNSXCredentailsConfig(context map[string]interface{}) string { return acctest.Nprintf(` data "google_vmwareengine_nsx_credentials" "nsx-ds" { diff --git a/website/docs/r/compute_global_address.html.markdown b/website/docs/r/compute_global_address.html.markdown index 35cca779475..d21100e9a3d 100644 --- a/website/docs/r/compute_global_address.html.markdown +++ b/website/docs/r/compute_global_address.html.markdown @@ -150,7 +150,6 @@ In addition to the arguments listed above, the following computed attributes are Creation timestamp in RFC3339 text format. * `label_fingerprint` - - ([Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) The fingerprint used for optimistic locking of this resource. Used internally during updates.