Skip to content

Commit b4fdcc0

Browse files
Fix failed tests related to google_service_networking_connection (#8904) (#15934)
* Bootstrap service networking connection * Revert tests * Rename network names * Modify tests * Fix tests * Catch the error when deleteConnection fails * Fix test TestAccVertexAIIndexEndpoint_updated * Fix test TestAccAlloydbInstance_createInstanceWithNetworkConfigAndAllocatedIPRange * Fix test Signed-off-by: Modular Magician <[email protected]>
1 parent 525c7bf commit b4fdcc0

23 files changed

+466
-787
lines changed

.changelog/8904.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:breaking-change
2+
servicenetworking: used the `deleteConnection` method to delete the resource `google_service_networking_connection`
3+
```

google/acctest/bootstrap_test_utils.go

+131
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
tpgcompute "github.com/hashicorp/terraform-provider-google/google/services/compute"
1616
"github.com/hashicorp/terraform-provider-google/google/services/privateca"
1717
"github.com/hashicorp/terraform-provider-google/google/services/resourcemanager"
18+
tpgservicenetworking "github.com/hashicorp/terraform-provider-google/google/services/servicenetworking"
1819
"github.com/hashicorp/terraform-provider-google/google/services/sql"
1920
"github.com/hashicorp/terraform-provider-google/google/tpgiamresource"
2021
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
@@ -25,6 +26,7 @@ import (
2526
cloudresourcemanager "google.golang.org/api/cloudresourcemanager/v1"
2627
iam "google.golang.org/api/iam/v1"
2728
"google.golang.org/api/iamcredentials/v1"
29+
"google.golang.org/api/servicenetworking/v1"
2830
"google.golang.org/api/serviceusage/v1"
2931
sqladmin "google.golang.org/api/sqladmin/v1beta4"
3032
)
@@ -356,6 +358,135 @@ func BootstrapSharedTestNetwork(t *testing.T, testId string) string {
356358
return network.Name
357359
}
358360

361+
const SharedTestGlobalAddressPrefix = "tf-bootstrap-addr-"
362+
363+
func BootstrapSharedTestGlobalAddress(t *testing.T, testId, networkId string) string {
364+
project := envvar.GetTestProjectFromEnv()
365+
addressName := SharedTestGlobalAddressPrefix + testId
366+
367+
config := BootstrapConfig(t)
368+
if config == nil {
369+
return ""
370+
}
371+
372+
log.Printf("[DEBUG] Getting shared test global address %q", addressName)
373+
_, err := config.NewComputeClient(config.UserAgent).GlobalAddresses.Get(project, addressName).Do()
374+
if err != nil && transport_tpg.IsGoogleApiErrorWithCode(err, 404) {
375+
log.Printf("[DEBUG] Global address %q not found, bootstrapping", addressName)
376+
url := fmt.Sprintf("%sprojects/%s/global/addresses", config.ComputeBasePath, project)
377+
netObj := map[string]interface{}{
378+
"name": addressName,
379+
"address_type": "INTERNAL",
380+
"purpose": "VPC_PEERING",
381+
"prefix_length": 16,
382+
"network": networkId,
383+
}
384+
385+
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
386+
Config: config,
387+
Method: "POST",
388+
Project: project,
389+
RawURL: url,
390+
UserAgent: config.UserAgent,
391+
Body: netObj,
392+
Timeout: 4 * time.Minute,
393+
})
394+
if err != nil {
395+
t.Fatalf("Error bootstrapping shared test global address %q: %s", addressName, err)
396+
}
397+
398+
log.Printf("[DEBUG] Waiting for global address creation to finish")
399+
err = tpgcompute.ComputeOperationWaitTime(config, res, project, "Error bootstrapping shared test global address", config.UserAgent, 4*time.Minute)
400+
if err != nil {
401+
t.Fatalf("Error bootstrapping shared test global address %q: %s", addressName, err)
402+
}
403+
}
404+
405+
address, err := config.NewComputeClient(config.UserAgent).GlobalAddresses.Get(project, addressName).Do()
406+
if err != nil {
407+
t.Errorf("Error getting shared test global address %q: %s", addressName, err)
408+
}
409+
if address == nil {
410+
t.Fatalf("Error getting shared test global address %q: is nil", addressName)
411+
}
412+
return address.Name
413+
}
414+
415+
// BootstrapSharedServiceNetworkingConnection will create a shared network
416+
// if it hasn't been created in the test project, a global address
417+
// if it hasn't been created in the test project, and a service networking connection
418+
// if it hasn't been created in the test project.
419+
//
420+
// BootstrapSharedServiceNetworkingConnection returns a persistent compute network name
421+
// for a test or set of tests.
422+
//
423+
// To delete a service networking conneciton, all of the service instances that use that connection
424+
// must be deleted first. After the service instances are deleted, some service producers delay the deletion
425+
// utnil a waiting period has passed. For example, after four days that you delete a SQL instance,
426+
// the service networking connection can be deleted.
427+
// That is the reason to use the shared service networking connection for thest resources.
428+
// https://cloud.google.com/vpc/docs/configure-private-services-access#removing-connection
429+
//
430+
// testId specifies the test for which a shared network and a gobal address are used/initialized.
431+
func BootstrapSharedServiceNetworkingConnection(t *testing.T, testId string) string {
432+
parentService := "services/servicenetworking.googleapis.com"
433+
project := envvar.GetTestProjectFromEnv()
434+
projectNumber := envvar.GetTestProjectNumberFromEnv()
435+
436+
config := BootstrapConfig(t)
437+
if config == nil {
438+
return ""
439+
}
440+
441+
networkName := BootstrapSharedTestNetwork(t, testId)
442+
networkId := fmt.Sprintf("projects/%v/global/networks/%v", projectNumber, networkName)
443+
globalAddressName := BootstrapSharedTestGlobalAddress(t, testId, networkId)
444+
445+
readCall := config.NewServiceNetworkingClient(config.UserAgent).Services.Connections.List(parentService).Network(networkId)
446+
if config.UserProjectOverride {
447+
readCall.Header().Add("X-Goog-User-Project", project)
448+
}
449+
response, err := readCall.Do()
450+
if err != nil {
451+
t.Errorf("Error getting shared test service networking connection: %s", err)
452+
}
453+
454+
var connection *servicenetworking.Connection
455+
for _, c := range response.Connections {
456+
if c.Network == networkId {
457+
connection = c
458+
break
459+
}
460+
}
461+
462+
if connection == nil {
463+
log.Printf("[DEBUG] Service networking connection not found, bootstrapping")
464+
465+
connection := &servicenetworking.Connection{
466+
Network: networkId,
467+
ReservedPeeringRanges: []string{globalAddressName},
468+
}
469+
470+
createCall := config.NewServiceNetworkingClient(config.UserAgent).Services.Connections.Create(parentService, connection)
471+
if config.UserProjectOverride {
472+
createCall.Header().Add("X-Goog-User-Project", project)
473+
}
474+
op, err := createCall.Do()
475+
if err != nil {
476+
t.Fatalf("Error bootstrapping shared test service networking connection: %s", err)
477+
}
478+
479+
log.Printf("[DEBUG] Waiting for service networking connection creation to finish")
480+
if err := tpgservicenetworking.ServiceNetworkingOperationWaitTime(config, op, "Create Service Networking Connection", config.UserAgent, project, 4*time.Minute); err != nil {
481+
t.Fatalf("Error bootstrapping shared test service networking connection: %s", err)
482+
}
483+
}
484+
485+
log.Printf("[DEBUG] Getting shared test service networking connection")
486+
487+
return networkName
488+
}
489+
359490
var SharedServicePerimeterProjectPrefix = "tf-bootstrap-sp-"
360491

361492
func BootstrapServicePerimeterProjects(t *testing.T, desiredProjects int) []*cloudresourcemanager.Project {

google/services/alloydb/resource_alloydb_backup_test.go

+41-67
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func TestAccAlloydbBackup_update(t *testing.T) {
1414

1515
random_suffix := acctest.RandString(t, 10)
1616
context := map[string]interface{}{
17-
"network_name": "tf-test-alloydb-network" + random_suffix,
17+
"network_name": acctest.BootstrapSharedServiceNetworkingConnection(t, "alloydb-backup-update-1"),
1818
"random_suffix": random_suffix,
1919
}
2020

@@ -24,7 +24,7 @@ func TestAccAlloydbBackup_update(t *testing.T) {
2424
CheckDestroy: testAccCheckAlloydbBackupDestroyProducer(t),
2525
Steps: []resource.TestStep{
2626
{
27-
Config: testAccAlloydbBackup_alloydbBackupFullExample(context),
27+
Config: testAccAlloydbBackup_alloydbBackupBasic(context),
2828
},
2929
{
3030
ResourceName: "google_alloydb_backup.default",
@@ -45,8 +45,7 @@ func TestAccAlloydbBackup_update(t *testing.T) {
4545
})
4646
}
4747

48-
// Updates "label" field from testAccAlloydbBackup_alloydbBackupFullExample
49-
func testAccAlloydbBackup_update(context map[string]interface{}) string {
48+
func testAccAlloydbBackup_alloydbBackupBasic(context map[string]interface{}) string {
5049
return acctest.Nprintf(`
5150
resource "google_alloydb_backup" "default" {
5251
location = "us-central1"
@@ -55,41 +54,58 @@ resource "google_alloydb_backup" "default" {
5554
5655
description = "example description"
5756
labels = {
58-
"label" = "updated_key"
59-
"label2" = "updated_key2"
57+
"label" = "key"
6058
}
6159
depends_on = [google_alloydb_instance.default]
6260
}
6361
6462
resource "google_alloydb_cluster" "default" {
6563
cluster_id = "tf-test-alloydb-cluster%{random_suffix}"
6664
location = "us-central1"
67-
network = google_compute_network.default.id
65+
network = data.google_compute_network.default.id
6866
}
6967
7068
resource "google_alloydb_instance" "default" {
7169
cluster = google_alloydb_cluster.default.name
7270
instance_id = "tf-test-alloydb-instance%{random_suffix}"
7371
instance_type = "PRIMARY"
72+
}
73+
74+
data "google_compute_network" "default" {
75+
name = "%{network_name}"
76+
}
77+
`, context)
78+
}
79+
80+
// Updates "label" field
81+
func testAccAlloydbBackup_update(context map[string]interface{}) string {
82+
return acctest.Nprintf(`
83+
resource "google_alloydb_backup" "default" {
84+
location = "us-central1"
85+
backup_id = "tf-test-alloydb-backup%{random_suffix}"
86+
cluster_name = google_alloydb_cluster.default.name
7487
75-
depends_on = [google_service_networking_connection.vpc_connection]
88+
description = "example description"
89+
labels = {
90+
"label" = "updated_key"
91+
"label2" = "updated_key2"
92+
}
93+
depends_on = [google_alloydb_instance.default]
7694
}
7795
78-
resource "google_compute_global_address" "private_ip_alloc" {
79-
name = "tf-test-alloydb-cluster%{random_suffix}"
80-
address_type = "INTERNAL"
81-
purpose = "VPC_PEERING"
82-
prefix_length = 16
83-
network = google_compute_network.default.id
96+
resource "google_alloydb_cluster" "default" {
97+
cluster_id = "tf-test-alloydb-cluster%{random_suffix}"
98+
location = "us-central1"
99+
network = data.google_compute_network.default.id
84100
}
85101
86-
resource "google_service_networking_connection" "vpc_connection" {
87-
network = google_compute_network.default.id
88-
service = "servicenetworking.googleapis.com"
89-
reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name]
102+
resource "google_alloydb_instance" "default" {
103+
cluster = google_alloydb_cluster.default.name
104+
instance_id = "tf-test-alloydb-instance%{random_suffix}"
105+
instance_type = "PRIMARY"
90106
}
91107
92-
resource "google_compute_network" "default" {
108+
data "google_compute_network" "default" {
93109
name = "%{network_name}"
94110
}
95111
`, context)
@@ -101,7 +117,7 @@ func TestAccAlloydbBackup_createBackupWithMandatoryFields(t *testing.T) {
101117

102118
context := map[string]interface{}{
103119
"random_suffix": acctest.RandString(t, 10),
104-
"network_name": "tf-test-" + acctest.RandString(t, 10),
120+
"network_name": acctest.BootstrapSharedServiceNetworkingConnection(t, "alloydb-backup-mandatory-1"),
105121
}
106122

107123
acctest.VcrTest(t, resource.TestCase{
@@ -128,45 +144,19 @@ resource "google_alloydb_backup" "default" {
128144
resource "google_alloydb_cluster" "default" {
129145
location = "us-central1"
130146
cluster_id = "tf-test-alloydb-cluster%{random_suffix}"
131-
network = google_compute_network.default.id
147+
network = data.google_compute_network.default.id
132148
}
133149
134150
data "google_project" "project" { }
135151
136-
resource "google_compute_network" "default" {
152+
data "google_compute_network" "default" {
137153
name = "%{network_name}"
138154
}
139155
140156
resource "google_alloydb_instance" "default" {
141157
cluster = google_alloydb_cluster.default.name
142158
instance_id = "tf-test-alloydb-instance%{random_suffix}"
143159
instance_type = "PRIMARY"
144-
145-
depends_on = [google_service_networking_connection.vpc_connection]
146-
}
147-
148-
resource "google_compute_global_address" "private_ip_alloc" {
149-
name = "tf-test-alloydb-cluster%{random_suffix}"
150-
address_type = "INTERNAL"
151-
purpose = "VPC_PEERING"
152-
prefix_length = 16
153-
network = google_compute_network.default.id
154-
lifecycle {
155-
ignore_changes = [
156-
address,
157-
creation_timestamp,
158-
id,
159-
network,
160-
project,
161-
self_link
162-
]
163-
}
164-
}
165-
166-
resource "google_service_networking_connection" "vpc_connection" {
167-
network = google_compute_network.default.id
168-
service = "servicenetworking.googleapis.com"
169-
reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name]
170160
}
171161
`, context)
172162
}
@@ -175,7 +165,7 @@ func TestAccAlloydbBackup_usingCMEK(t *testing.T) {
175165
t.Parallel()
176166

177167
context := map[string]interface{}{
178-
"network_name": "tf-test-" + acctest.RandString(t, 10),
168+
"network_name": acctest.BootstrapSharedServiceNetworkingConnection(t, "alloydb-backup-cmek-1"),
179169
"random_suffix": acctest.RandString(t, 10),
180170
"key_name": "tf-test-key-" + acctest.RandString(t, 10),
181171
}
@@ -218,32 +208,16 @@ resource "google_alloydb_backup" "default" {
218208
resource "google_alloydb_cluster" "default" {
219209
cluster_id = "tf-test-alloydb-cluster%{random_suffix}"
220210
location = "us-central1"
221-
network = google_compute_network.default.id
211+
network = data.google_compute_network.default.id
222212
}
223213
224214
resource "google_alloydb_instance" "default" {
225215
cluster = google_alloydb_cluster.default.name
226216
instance_id = "tf-test-alloydb-instance%{random_suffix}"
227217
instance_type = "PRIMARY"
228-
229-
depends_on = [google_service_networking_connection.vpc_connection]
230-
}
231-
232-
resource "google_compute_global_address" "private_ip_alloc" {
233-
name = "tf-test-alloydb-cluster%{random_suffix}"
234-
address_type = "INTERNAL"
235-
purpose = "VPC_PEERING"
236-
prefix_length = 16
237-
network = google_compute_network.default.id
238-
}
239-
240-
resource "google_service_networking_connection" "vpc_connection" {
241-
network = google_compute_network.default.id
242-
service = "servicenetworking.googleapis.com"
243-
reserved_peering_ranges = [google_compute_global_address.private_ip_alloc.name]
244218
}
245219
246-
resource "google_compute_network" "default" {
220+
data "google_compute_network" "default" {
247221
name = "%{network_name}"
248222
}
249223
data "google_project" "project" {}

0 commit comments

Comments
 (0)