Skip to content

Commit cb20fed

Browse files
artifactregistry: fix invalid cleanup policy in plan (#14451) (#10324)
[upstream:c1e59dd6e81fb80731eb644ab96314da1ad6aa55] Signed-off-by: Modular Magician <[email protected]>
1 parent 8d7a423 commit cb20fed

File tree

3 files changed

+122
-19
lines changed

3 files changed

+122
-19
lines changed

.changelog/14451.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
artifactregistry: fixed an issue where changes to `cleanup_policies` were not being applied correctly in `google_artifact_registry_repository` resource
3+
```

google-beta/services/artifactregistry/resource_artifact_registry_repository.go

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -94,39 +94,71 @@ func parseDurationAsSeconds(v string) (int, bool) {
9494

9595
// Like tpgresource.DurationDiffSuppress, but supports 'd'
9696
func durationDiffSuppress(k, oldr, newr string, d *schema.ResourceData) bool {
97-
o, n := d.GetChange(k)
98-
old, ok := o.(string)
97+
oldSeconds, ok := parseDurationAsSeconds(oldr)
9998
if !ok {
10099
return false
101100
}
102-
new, ok := n.(string)
103-
if !ok {
104-
return false
105-
}
106-
if old == new {
107-
return true
108-
}
109-
oldSeconds, ok := parseDurationAsSeconds(old)
110-
if !ok {
111-
return false
112-
}
113-
newSeconds, ok := parseDurationAsSeconds(new)
101+
newSeconds, ok := parseDurationAsSeconds(newr)
114102
if !ok {
115103
return false
116104
}
117105
return oldSeconds == newSeconds
118106
}
119107

120108
func mapHashID(v any) int {
121-
obj, ok := v.(map[string]any)
109+
replaceNestedValue(v, []string{"condition", "older_than"}, expandDuration)
110+
replaceNestedValue(v, []string{"condition", "newer_than"}, expandDuration)
111+
return schema.HashString(fmt.Sprintf("%v", v))
112+
}
113+
114+
func expandDuration(v any) (any, bool) {
115+
if val, ok := v.(string); ok {
116+
if secs, ok := parseDurationAsSeconds(val); ok {
117+
return fmt.Sprintf("%ds", secs), true
118+
}
119+
}
120+
return nil, false
121+
122+
}
123+
124+
// Replace a value in a schema object, if it exists.
125+
// Nested maps follow the pattern map[string]any -> [1]any -> map[string]any
126+
func replaceNestedValue(obj any, keys []string, replaceFunc func(any) (any, bool)) {
127+
if len(keys) == 0 {
128+
return
129+
}
130+
next := obj
131+
for _, key := range keys[:len(keys)-1] {
132+
nextMap, ok := next.(map[string]any)
133+
if !ok {
134+
return
135+
}
136+
arrObj, ok := nextMap[key]
137+
if !ok {
138+
return
139+
}
140+
arr, ok := arrObj.([]any)
141+
if !ok {
142+
return
143+
}
144+
if len(arr) != 1 {
145+
return
146+
}
147+
next = arr[0]
148+
}
149+
lastMap, ok := next.(map[string]any)
122150
if !ok {
123-
return 0
151+
return
124152
}
125-
s, ok := obj["id"].(string)
153+
lastKey := keys[len(keys)-1]
154+
last, ok := lastMap[lastKey]
126155
if !ok {
127-
return 0
156+
return
157+
}
158+
result, ok := replaceFunc(last)
159+
if ok {
160+
lastMap[lastKey] = result
128161
}
129-
return schema.HashString(s)
130162
}
131163

132164
func isDefaultEnum(val any) bool {

google-beta/services/artifactregistry/resource_artifact_registry_repository_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,74 @@ func TestAccArtifactRegistryRepository_kfp(t *testing.T) {
154154
})
155155
}
156156

157+
func TestAccArtifactRegistryRepository_cleanup(t *testing.T) {
158+
t.Parallel()
159+
160+
repositoryID := fmt.Sprintf("tf-test-%d", acctest.RandInt(t))
161+
162+
acctest.VcrTest(t, resource.TestCase{
163+
PreCheck: func() { acctest.AccTestPreCheck(t) },
164+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
165+
CheckDestroy: testAccCheckArtifactRegistryRepositoryDestroyProducer(t),
166+
Steps: []resource.TestStep{
167+
{
168+
Config: testAccArtifactRegistryRepository_cleanup(repositoryID),
169+
},
170+
{
171+
ResourceName: "google_artifact_registry_repository.test",
172+
ImportState: true,
173+
ImportStateVerify: true,
174+
},
175+
{
176+
Config: testAccArtifactRegistryRepository_cleanup2(repositoryID),
177+
PlanOnly: true,
178+
ExpectNonEmptyPlan: true,
179+
},
180+
{
181+
Config: testAccArtifactRegistryRepository_cleanup2(repositoryID),
182+
},
183+
},
184+
})
185+
}
186+
187+
func testAccArtifactRegistryRepository_cleanup(repositoryID string) string {
188+
return fmt.Sprintf(`
189+
resource "google_artifact_registry_repository" "test" {
190+
repository_id = "%s"
191+
location = "us-central1"
192+
description = "cleanup with non-second time"
193+
format = "DOCKER"
194+
195+
cleanup_policies {
196+
id = "delete"
197+
action = "DELETE"
198+
condition {
199+
older_than = "7d"
200+
}
201+
}
202+
}
203+
`, repositoryID)
204+
}
205+
206+
func testAccArtifactRegistryRepository_cleanup2(repositoryID string) string {
207+
return fmt.Sprintf(`
208+
resource "google_artifact_registry_repository" "test" {
209+
repository_id = "%s"
210+
location = "us-central1"
211+
description = "cleanup with non-second time"
212+
format = "DOCKER"
213+
214+
cleanup_policies {
215+
id = "delete"
216+
action = "DELETE"
217+
condition {
218+
older_than = "10d"
219+
}
220+
}
221+
}
222+
`, repositoryID)
223+
}
224+
157225
func testAccArtifactRegistryRepository_update(repositoryID string) string {
158226
return fmt.Sprintf(`
159227
resource "google_artifact_registry_repository" "test" {

0 commit comments

Comments
 (0)