Skip to content

Commit 933d462

Browse files
Switched force destroy to use a URL param instead of request body (#13887) (#22648)
[upstream:a4089b7747e67023e7e62b697c63d0b117aa1c72] Signed-off-by: Modular Magician <magic-modules@google.com>
1 parent 9315309 commit 933d462

File tree

3 files changed

+228
-7
lines changed

3 files changed

+228
-7
lines changed

.changelog/13887.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
gemini: fixed bug on `google_gemini_code_repository_index` where `force_destroy` field did nothing.
3+
```

google/services/gemini/resource_gemini_code_repository_index.go

+1-7
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ func resourceGeminiCodeRepositoryIndexDelete(d *schema.ResourceData, meta interf
420420
transport_tpg.MutexStore.Lock(lockName)
421421
defer transport_tpg.MutexStore.Unlock(lockName)
422422

423-
url, err := tpgresource.ReplaceVars(d, config, "{{GeminiBasePath}}projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{code_repository_index_id}}")
423+
url, err := tpgresource.ReplaceVars(d, config, "{{GeminiBasePath}}projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{code_repository_index_id}}?force={{force_destroy}}")
424424
if err != nil {
425425
return err
426426
}
@@ -433,12 +433,6 @@ func resourceGeminiCodeRepositoryIndexDelete(d *schema.ResourceData, meta interf
433433
}
434434

435435
headers := make(http.Header)
436-
obj = make(map[string]interface{})
437-
if v, ok := d.GetOk("force_destroy"); ok {
438-
if v == true {
439-
obj["force"] = true
440-
}
441-
}
442436

443437
log.Printf("[DEBUG] Deleting CodeRepositoryIndex %q", d.Id())
444438
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
// ----------------------------------------------------------------------------
5+
//
6+
// *** AUTO GENERATED CODE *** Type: MMv1 ***
7+
//
8+
// ----------------------------------------------------------------------------
9+
//
10+
// This code is generated by Magic Modules using the following:
11+
//
12+
// Configuration: https://github.com/GoogleCloudPlatform/magic-modules/tree/main/mmv1/products/gemini/CodeRepositoryIndex.yaml
13+
// Template: https://github.com/GoogleCloudPlatform/magic-modules/tree/main/mmv1/templates/terraform/sweeper_file.go.tmpl
14+
//
15+
// DO NOT EDIT this file directly. Any changes made to this file will be
16+
// overwritten during the next generation cycle.
17+
//
18+
// ----------------------------------------------------------------------------
19+
20+
package gemini
21+
22+
import (
23+
"context"
24+
"fmt"
25+
"log"
26+
"strings"
27+
"testing"
28+
29+
"github.com/hashicorp/terraform-provider-google/google/envvar"
30+
"github.com/hashicorp/terraform-provider-google/google/sweeper"
31+
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
32+
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
33+
)
34+
35+
func init() {
36+
// Initialize base sweeper object
37+
s := &sweeper.Sweeper{
38+
Name: "google_gemini_code_repository_index",
39+
ListAndAction: listAndActionGeminiCodeRepositoryIndex,
40+
DeleteFunction: testSweepGeminiCodeRepositoryIndex,
41+
}
42+
43+
// Register the sweeper
44+
sweeper.AddTestSweepers(s)
45+
}
46+
47+
func testSweepGeminiCodeRepositoryIndex(_ string) error {
48+
return listAndActionGeminiCodeRepositoryIndex(deleteResourceGeminiCodeRepositoryIndex)
49+
}
50+
51+
func listAndActionGeminiCodeRepositoryIndex(action sweeper.ResourceAction) error {
52+
var lastError error
53+
resourceName := "GeminiCodeRepositoryIndex"
54+
log.Printf("[INFO][SWEEPER_LOG] Starting sweeper for %s", resourceName)
55+
56+
// Prepare configurations to iterate over
57+
var configs []*tpgresource.ResourceDataMock
58+
t := &testing.T{}
59+
billingId := envvar.GetTestBillingAccountFromEnv(t)
60+
// Build URL substitution maps individually to ensure proper formatting
61+
intermediateValues := make([]map[string]string, 1)
62+
intermediateValues[0] = map[string]string{}
63+
intermediateValues[0]["force_destroy"] = "true"
64+
65+
// Create configs from intermediate values
66+
for _, values := range intermediateValues {
67+
mockConfig := &tpgresource.ResourceDataMock{
68+
FieldsInSchema: map[string]interface{}{
69+
"project": envvar.GetTestProjectFromEnv(),
70+
"billing_account": billingId,
71+
},
72+
}
73+
74+
// Apply all provided values
75+
for key, value := range values {
76+
mockConfig.FieldsInSchema[key] = value
77+
}
78+
79+
// Set fallback values for common fields
80+
region, hasRegion := mockConfig.FieldsInSchema["region"].(string)
81+
if !hasRegion {
82+
region = "us-central1"
83+
mockConfig.FieldsInSchema["region"] = region
84+
}
85+
86+
if _, hasLocation := mockConfig.FieldsInSchema["location"]; !hasLocation {
87+
mockConfig.FieldsInSchema["location"] = region
88+
}
89+
90+
if _, hasZone := mockConfig.FieldsInSchema["zone"]; !hasZone {
91+
mockConfig.FieldsInSchema["zone"] = region + "-a"
92+
}
93+
94+
configs = append(configs, mockConfig)
95+
}
96+
97+
// Process all configurations (either from parent resources or direct substitutions)
98+
for _, mockConfig := range configs {
99+
// Get region from config
100+
region := sweeper.GetFieldOrDefault(mockConfig, "region", "us-central1")
101+
102+
// Create shared config for this region
103+
config, err := sweeper.SharedConfigForRegion(region)
104+
if err != nil {
105+
log.Printf("[INFO][SWEEPER_LOG] error getting shared config for region: %s", err)
106+
lastError = err
107+
continue
108+
}
109+
110+
err = config.LoadAndValidate(context.Background())
111+
if err != nil {
112+
log.Printf("[INFO][SWEEPER_LOG] error loading: %s", err)
113+
lastError = err
114+
continue
115+
}
116+
117+
// Prepare list URL
118+
listTemplate := strings.Split("https://cloudaicompanion.googleapis.com/v1/projects/{{project}}/locations/{{location}}/codeRepositoryIndexes", "?")[0]
119+
listUrl, err := tpgresource.ReplaceVars(mockConfig, config, listTemplate)
120+
if err != nil {
121+
log.Printf("[INFO][SWEEPER_LOG] error preparing sweeper list url: %s", err)
122+
lastError = err
123+
continue
124+
}
125+
126+
// Log additional info for parent-based resources
127+
log.Printf("[INFO][SWEEPER_LOG] Listing %s resources at %s", resourceName, listUrl)
128+
129+
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
130+
Config: config,
131+
Method: "GET",
132+
Project: config.Project,
133+
RawURL: listUrl,
134+
UserAgent: config.UserAgent,
135+
})
136+
if err != nil {
137+
log.Printf("[INFO][SWEEPER_LOG] Error in response from request %s: %s", listUrl, err)
138+
lastError = err
139+
continue
140+
}
141+
142+
// First try the expected resource key
143+
resourceList, ok := res["codeRepositoryIndices"]
144+
if ok {
145+
log.Printf("[INFO][SWEEPER_LOG] Found resources under expected key 'codeRepositoryIndices'")
146+
} else {
147+
// Next, try the common "items" pattern
148+
resourceList, ok = res["items"]
149+
if ok {
150+
log.Printf("[INFO][SWEEPER_LOG] Found resources under standard 'items' key")
151+
} else {
152+
log.Printf("[INFO][SWEEPER_LOG] no resources found")
153+
continue
154+
}
155+
}
156+
rl := resourceList.([]interface{})
157+
158+
log.Printf("[INFO][SWEEPER_LOG] Found %d items in %s list response.", len(rl), resourceName)
159+
// Keep count of items that aren't sweepable for logging.
160+
nonPrefixCount := 0
161+
for _, ri := range rl {
162+
obj, ok := ri.(map[string]interface{})
163+
if !ok {
164+
log.Printf("[INFO][SWEEPER_LOG] Item was not a map: %T", ri)
165+
continue
166+
}
167+
168+
if err := action(config, mockConfig, obj); err != nil {
169+
log.Printf("[INFO][SWEEPER_LOG] Error in action: %s", err)
170+
lastError = err
171+
} else {
172+
nonPrefixCount++
173+
}
174+
}
175+
}
176+
177+
return lastError
178+
}
179+
180+
func deleteResourceGeminiCodeRepositoryIndex(config *transport_tpg.Config, d *tpgresource.ResourceDataMock, obj map[string]interface{}) error {
181+
var deletionerror error
182+
resourceName := "GeminiCodeRepositoryIndex"
183+
var name string
184+
// Id detected in the delete URL, attempt to use id.
185+
if obj["id"] != nil {
186+
name = tpgresource.GetResourceNameFromSelfLink(obj["id"].(string))
187+
} else if obj["name"] != nil {
188+
name = tpgresource.GetResourceNameFromSelfLink(obj["name"].(string))
189+
} else {
190+
log.Printf("[INFO][SWEEPER_LOG] %s resource name and id were nil", resourceName)
191+
return fmt.Errorf("%s resource name was nil", resourceName)
192+
}
193+
194+
// Skip resources that shouldn't be sweeped
195+
if !sweeper.IsSweepableTestResource(name) {
196+
return nil
197+
}
198+
199+
deleteTemplate := "https://cloudaicompanion.googleapis.com/v1/projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{code_repository_index_id}}?force={{force_destroy}}"
200+
201+
url, err := tpgresource.ReplaceVars(d, config, deleteTemplate)
202+
if err != nil {
203+
log.Printf("[INFO][SWEEPER_LOG] error preparing delete url: %s", err)
204+
deletionerror = err
205+
}
206+
url = url + name
207+
208+
// Don't wait on operations as we may have a lot to delete
209+
_, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
210+
Config: config,
211+
Method: "DELETE",
212+
Project: config.Project,
213+
RawURL: url,
214+
UserAgent: config.UserAgent,
215+
})
216+
if err != nil {
217+
log.Printf("[INFO][SWEEPER_LOG] Error deleting for url %s : %s", url, err)
218+
deletionerror = err
219+
} else {
220+
log.Printf("[INFO][SWEEPER_LOG] Sent delete request for %s resource: %s", resourceName, name)
221+
}
222+
223+
return deletionerror
224+
}

0 commit comments

Comments
 (0)