Skip to content

Commit abed5cf

Browse files
CodeRepositoryIndex cascade deletion (#12601) (#9036)
[upstream:22008e516c62bcad85509e892707a4a01e36e6ea] Signed-off-by: Modular Magician <magic-modules@google.com>
1 parent 4b731bb commit abed5cf

File tree

5 files changed

+158
-143
lines changed

5 files changed

+158
-143
lines changed

.changelog/12601.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note: enhancement
2+
gemini: added `force_destroy` field to resource `google_code_repository_index`, enabling deletion of the resource even when it has dependent RepositoryGroups
3+
```

google-beta/services/gemini/resource_gemini_code_repository_index.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ SUSPENDED`,
122122
Computed: true,
123123
Description: `Output only. Update time stamp.`,
124124
},
125+
"force_destroy": {
126+
Type: schema.TypeBool,
127+
Optional: true,
128+
Description: `If set to true, will allow deletion of the CodeRepositoryIndex even if there are existing RepositoryGroups for the resource. These RepositoryGroups will also be deleted.`,
129+
Default: false,
130+
},
125131
"project": {
126132
Type: schema.TypeString,
127133
Optional: true,
@@ -271,6 +277,12 @@ func resourceGeminiCodeRepositoryIndexRead(d *schema.ResourceData, meta interfac
271277
return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("GeminiCodeRepositoryIndex %q", d.Id()))
272278
}
273279

280+
// Explicitly set virtual fields to default values if unset
281+
if _, ok := d.GetOkExists("force_destroy"); !ok {
282+
if err := d.Set("force_destroy", false); err != nil {
283+
return fmt.Errorf("Error setting force_destroy: %s", err)
284+
}
285+
}
274286
if err := d.Set("project", project); err != nil {
275287
return fmt.Errorf("Error reading CodeRepositoryIndex: %s", err)
276288
}
@@ -424,6 +436,12 @@ func resourceGeminiCodeRepositoryIndexDelete(d *schema.ResourceData, meta interf
424436
}
425437

426438
headers := make(http.Header)
439+
obj = make(map[string]interface{})
440+
if v, ok := d.GetOk("force_destroy"); ok {
441+
if v == true {
442+
obj["force"] = true
443+
}
444+
}
427445

428446
log.Printf("[DEBUG] Deleting CodeRepositoryIndex %q", d.Id())
429447
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
@@ -470,6 +488,11 @@ func resourceGeminiCodeRepositoryIndexImport(d *schema.ResourceData, meta interf
470488
}
471489
d.SetId(id)
472490

491+
// Explicitly set virtual fields to default values on import
492+
if err := d.Set("force_destroy", false); err != nil {
493+
return nil, fmt.Errorf("Error setting force_destroy: %s", err)
494+
}
495+
473496
return []*schema.ResourceData{d}, nil
474497
}
475498

google-beta/services/gemini/resource_gemini_code_repository_index_sweeper.go

Lines changed: 0 additions & 143 deletions
This file was deleted.

google-beta/services/gemini/resource_gemini_code_repository_index_test.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package gemini_test
44

55
import (
6+
"fmt"
67
"os"
78
"testing"
89

@@ -45,6 +46,136 @@ func TestAccGeminiCodeRepositoryIndex_update(t *testing.T) {
4546
})
4647
}
4748

49+
// TestAccGeminiCodeRepositoryIndex_delete checks if there is no error in deleting CRI along with children resource
50+
// note: this is an example of a bad usage, where RGs refer to the CRI using a string id, not a reference, as they
51+
// will be force-removed upon CRI deletion, because the CRI provider uses --force option by default
52+
// The plan after the _delete function should not be empty due to the child resource in plan
53+
func TestAccGeminiCodeRepositoryIndex_delete(t *testing.T) {
54+
bootstrappedKMS := acctest.BootstrapKMSKeyInLocation(t, "us-central1")
55+
randomSuffix := acctest.RandString(t, 10)
56+
context := map[string]interface{}{
57+
"random_suffix": randomSuffix,
58+
"project_id": os.Getenv("GOOGLE_PROJECT"),
59+
"kms_key": bootstrappedKMS.CryptoKey.Name,
60+
"cri_id": fmt.Sprintf("tf-test-cri-index-delete-example-%s", randomSuffix),
61+
}
62+
63+
acctest.VcrTest(t, resource.TestCase{
64+
PreCheck: func() { acctest.AccTestPreCheck(t) },
65+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t),
66+
Steps: []resource.TestStep{
67+
{
68+
Config: testAccGeminiCodeRepositoryIndex_withChildren_basic(context),
69+
},
70+
{
71+
ResourceName: "google_gemini_code_repository_index.example",
72+
ImportState: true,
73+
ImportStateVerify: true,
74+
ImportStateVerifyIgnore: []string{"code_repository_index_id", "labels", "location", "terraform_labels", "force_destroy"},
75+
},
76+
{
77+
Config: testAccGeminiCodeRepositoryIndex_withChildren_delete(context),
78+
ExpectNonEmptyPlan: true,
79+
PlanOnly: true,
80+
},
81+
},
82+
})
83+
}
84+
85+
func testAccGeminiCodeRepositoryIndex_withChildren_basic(context map[string]interface{}) string {
86+
return acctest.Nprintf(`
87+
resource "google_gemini_code_repository_index" "example" {
88+
provider = google-beta
89+
labels = {"ccfe_debug_note": "terraform_e2e_should_be_deleted"}
90+
location = "us-central1"
91+
code_repository_index_id = "%{cri_id}"
92+
force_destroy = true
93+
}
94+
95+
resource "google_gemini_repository_group" "example" {
96+
provider = google-beta
97+
location = "us-central1"
98+
code_repository_index = "%{cri_id}"
99+
repository_group_id = "tf-test-rg-repository-group-id-%{random_suffix}"
100+
repositories {
101+
resource = "projects/%{project_id}/locations/us-central1/connections/${google_developer_connect_connection.github_conn.connection_id}/gitRepositoryLinks/${google_developer_connect_git_repository_link.conn.git_repository_link_id}"
102+
branch_pattern = "main"
103+
}
104+
labels = {"label1": "value1"}
105+
depends_on = [
106+
google_gemini_code_repository_index.example
107+
]
108+
}
109+
110+
resource "google_developer_connect_git_repository_link" "conn" {
111+
provider = google-beta
112+
git_repository_link_id = "tf-test-repository-conn-delete"
113+
parent_connection = google_developer_connect_connection.github_conn.connection_id
114+
clone_uri = "https://github.com/CC-R-github-robot/tf-test.git"
115+
location = "us-central1"
116+
annotations = {}
117+
}
118+
119+
resource "google_developer_connect_connection" "github_conn" {
120+
provider = google-beta
121+
location = "us-central1"
122+
connection_id = "tf-test-cloudaicompanion-delete-%{random_suffix}"
123+
disabled = false
124+
125+
github_config {
126+
github_app = "DEVELOPER_CONNECT"
127+
app_installation_id = 54180648
128+
129+
authorizer_credential {
130+
oauth_token_secret_version = "projects/502367051001/secrets/tf-test-cloudaicompanion-github-oauthtoken-c42e5c/versions/1"
131+
}
132+
}
133+
}
134+
`, context)
135+
}
136+
137+
// Removed depends_on to not break plan test
138+
func testAccGeminiCodeRepositoryIndex_withChildren_delete(context map[string]interface{}) string {
139+
return acctest.Nprintf(`
140+
resource "google_gemini_repository_group" "example" {
141+
provider = google-beta
142+
location = "us-central1"
143+
code_repository_index = "%{cri_id}"
144+
repository_group_id = "tf-test-rg-repository-group-id-%{random_suffix}"
145+
repositories {
146+
resource = "projects/%{project_id}/locations/us-central1/connections/${google_developer_connect_connection.github_conn.connection_id}/gitRepositoryLinks/${google_developer_connect_git_repository_link.conn.git_repository_link_id}"
147+
branch_pattern = "main"
148+
}
149+
labels = {"label1": "value1"}
150+
}
151+
152+
resource "google_developer_connect_git_repository_link" "conn" {
153+
provider = google-beta
154+
git_repository_link_id = "tf-test-repository-conn-delete"
155+
parent_connection = google_developer_connect_connection.github_conn.connection_id
156+
clone_uri = "https://github.com/CC-R-github-robot/tf-test.git"
157+
location = "us-central1"
158+
annotations = {}
159+
}
160+
161+
resource "google_developer_connect_connection" "github_conn" {
162+
provider = google-beta
163+
location = "us-central1"
164+
connection_id = "tf-test-cloudaicompanion-delete-%{random_suffix}"
165+
disabled = false
166+
167+
github_config {
168+
github_app = "DEVELOPER_CONNECT"
169+
app_installation_id = 54180648
170+
171+
authorizer_credential {
172+
oauth_token_secret_version = "projects/502367051001/secrets/tf-test-cloudaicompanion-github-oauthtoken-c42e5c/versions/1"
173+
}
174+
}
175+
}
176+
`, context)
177+
}
178+
48179
func testAccGeminiCodeRepositoryIndex_basic(context map[string]interface{}) string {
49180
return acctest.Nprintf(`
50181
resource "google_gemini_code_repository_index" "example" {

website/docs/r/gemini_code_repository_index.html.markdown

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ The following arguments are supported:
6868
* `project` - (Optional) The ID of the project in which the resource belongs.
6969
If it is not provided, the provider project is used.
7070

71+
* `force_destroy` - (Optional) If set to true, will allow deletion of the CodeRepositoryIndex even if there are existing RepositoryGroups for the resource. These RepositoryGroups will also be deleted.
7172

7273
## Attributes Reference
7374

0 commit comments

Comments
 (0)