Skip to content

Commit afd41c2

Browse files
feat: add VDB group update and tag management with acceptance tests - addressing review comments
1 parent d084eca commit afd41c2

File tree

5 files changed

+269
-83
lines changed

5 files changed

+269
-83
lines changed

docs/resources/vdb_group.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ Creating a vdb group and assigning vdb with vdb_id = my_vdb_id
1010
resource "delphix_vdb_group" "vdb_group_name" {
1111
name = "my vdb group"
1212
vdb_ids = ["my_vdb_id"]
13+
tags {
14+
key = "environment"
15+
value = "production"
16+
}
17+
tags {
18+
key = "project"
19+
value = "terraform"
20+
}
1321
}
1422
```
1523

@@ -21,6 +29,10 @@ resource "delphix_vdb_group" "vdb_group_name" {
2129

2230
* `vdb_ids` - The list of VDB IDs in this VDBGroup.
2331

32+
* `tags` - The tags to be created for the VDB group. This is a map of 2 parameters:
33+
* `key` - The key of the tag.
34+
* `value` - The value of the tag.
35+
2436
## Attribute Reference
2537

2638
This resource exports same attributes as the arguments.

examples/vdb_group/main.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,12 @@ resource "delphix_vdb" "vdb_provision_loop" {
4848
resource "delphix_vdb_group" "this" {
4949
name = "random"
5050
vdb_ids = sort(flatten([for vdb in delphix_vdb.example : vdb.id]))
51+
tags {
52+
key = "environment"
53+
value = "production"
54+
}
55+
tags {
56+
key = "project"
57+
value = "terraform"
58+
}
5159
}

internal/provider/resource_vdb_group.go

Lines changed: 87 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package provider
22

33
import (
44
"context"
5+
"time"
56

67
"github.com/hashicorp/terraform-plugin-log/tflog"
78

@@ -18,6 +19,9 @@ func resourceVdbGroup() *schema.Resource {
1819
ReadContext: resourceVdbGroupRead,
1920
UpdateContext: resourceVdbGroupUpdate,
2021
DeleteContext: resourceVdbGroupDelete,
22+
Importer: &schema.ResourceImporter{
23+
StateContext: schema.ImportStatePassthroughContext,
24+
},
2125

2226
Schema: map[string]*schema.Schema{
2327
"id": {
@@ -38,6 +42,7 @@ func resourceVdbGroup() *schema.Resource {
3842
"tags": {
3943
Type: schema.TypeList,
4044
Optional: true,
45+
Computed: true,
4146
Elem: &schema.Resource{
4247
Schema: map[string]*schema.Schema{
4348
"key": {
@@ -105,24 +110,39 @@ func resourceVdbGroupRead(ctx context.Context, d *schema.ResourceData, meta inte
105110

106111
func resourceVdbGroupUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
107112
client := meta.(*apiClient).client
108-
109113
vdbGroupId := d.Id()
110114

111-
if d.HasChange("name") || d.HasChange("vdb_ids") {
112-
updateVdbGroupReq := *dctapi.NewUpdateVDBGroupParameters()
113-
if d.HasChange("name") {
114-
updateVdbGroupReq.SetName(d.Get("name").(string))
115+
// Existing update logic
116+
updateVdbGroupReq := *dctapi.NewUpdateVDBGroupParameters()
117+
if d.HasChange("name") {
118+
updateVdbGroupReq.SetName(d.Get("name").(string))
119+
}
120+
if d.HasChange("vdb_ids") {
121+
updateVdbGroupReq.SetVdbIds(toStringArray(d.Get("vdb_ids")))
122+
}
123+
124+
_, httpRes, err := client.VDBGroupsAPI.UpdateVdbGroupById(ctx, vdbGroupId).UpdateVDBGroupParameters(updateVdbGroupReq).Execute()
125+
if diags := apiErrorResponseHelper(ctx, nil, httpRes, err); diags != nil {
126+
return diags
127+
}
128+
129+
// Polling logic for name/vdb_ids update
130+
maxAttempts := 10
131+
for attempt := 1; attempt <= maxAttempts; attempt++ {
132+
status, err := PollVdbGroupStatus(ctx, client, vdbGroupId)
133+
if err != nil {
134+
return diag.FromErr(err)
115135
}
116-
if d.HasChange("vdb_ids") {
117-
updateVdbGroupReq.SetVdbIds(toStringArray(d.Get("vdb_ids")))
136+
if status == "RUNNING" {
137+
break
118138
}
119-
120-
_, httpRes, err := client.VDBGroupsAPI.UpdateVdbGroupById(ctx, vdbGroupId).UpdateVDBGroupParameters(updateVdbGroupReq).Execute()
121-
if diags := apiErrorResponseHelper(ctx, nil, httpRes, err); diags != nil {
122-
return diags
139+
if status == "FAILED" || status == "CANCELED" {
140+
return diag.Errorf("VDB group update failed with status: %s", status)
123141
}
142+
time.Sleep(time.Duration(STATUS_POLL_SLEEP_TIME) * time.Second)
124143
}
125144

145+
// Tag update logic
126146
if d.HasChange("tags") {
127147
oldTags, newTags := d.GetChange("tags")
128148
oldTagList := oldTags.([]interface{})
@@ -152,65 +172,85 @@ func resourceVdbGroupUpdate(ctx context.Context, d *schema.ResourceData, meta in
152172
newTagMap[key][value] = true
153173
}
154174

155-
// Delete removed tags
156-
for key, oldValues := range oldTagMap {
157-
newValues, exists := newTagMap[key]
158-
if !exists {
159-
// Key doesn't exist in new tags, delete all values for this key
175+
// If newTagList is empty, delete all existing tags
176+
if len(newTagList) == 0 {
177+
for key := range oldTagMap {
160178
deleteTag := *dctapi.NewDeleteTag()
161179
deleteTag.SetKey(key)
162180
httpRes, err := client.VDBGroupsAPI.DeleteVdbGroupTags(ctx, vdbGroupId).DeleteTag(deleteTag).Execute()
163181
if diags := apiErrorResponseHelper(ctx, nil, httpRes, err); diags != nil {
164182
return diags
165183
}
166-
} else {
167-
// Key exists, delete only values that are not in new tags
168-
for oldValue := range oldValues {
169-
if !newValues[oldValue] {
170-
deleteTag := *dctapi.NewDeleteTag()
171-
deleteTag.SetKey(key)
172-
deleteTag.SetValue(oldValue)
173-
httpRes, err := client.VDBGroupsAPI.DeleteVdbGroupTags(ctx, vdbGroupId).DeleteTag(deleteTag).Execute()
174-
if diags := apiErrorResponseHelper(ctx, nil, httpRes, err); diags != nil {
175-
return diags
184+
}
185+
} else {
186+
// Delete removed tags
187+
for key, oldValues := range oldTagMap {
188+
newValues, exists := newTagMap[key]
189+
if !exists {
190+
// Key doesn't exist in new tags, delete all values for this key
191+
deleteTag := *dctapi.NewDeleteTag()
192+
deleteTag.SetKey(key)
193+
httpRes, err := client.VDBGroupsAPI.DeleteVdbGroupTags(ctx, vdbGroupId).DeleteTag(deleteTag).Execute()
194+
if diags := apiErrorResponseHelper(ctx, nil, httpRes, err); diags != nil {
195+
return diags
196+
}
197+
} else {
198+
// Key exists, delete only values that are not in new tags
199+
for oldValue := range oldValues {
200+
if !newValues[oldValue] {
201+
deleteTag := *dctapi.NewDeleteTag()
202+
deleteTag.SetKey(key)
203+
deleteTag.SetValue(oldValue)
204+
httpRes, err := client.VDBGroupsAPI.DeleteVdbGroupTags(ctx, vdbGroupId).DeleteTag(deleteTag).Execute()
205+
if diags := apiErrorResponseHelper(ctx, nil, httpRes, err); diags != nil {
206+
return diags
207+
}
176208
}
177209
}
178210
}
179211
}
180-
}
181212

182-
// Create new tags
183-
var tags []dctapi.Tag
184-
for key, newValues := range newTagMap {
185-
oldValues, exists := oldTagMap[key]
186-
if !exists {
187-
// Key doesn't exist in old tags, create all values
188-
for value := range newValues {
189-
tag := *dctapi.NewTag(key, value)
190-
tags = append(tags, tag)
191-
}
192-
} else {
193-
// Key exists, create only new values
194-
for value := range newValues {
195-
if !oldValues[value] {
213+
// Create new tags
214+
var tags []dctapi.Tag
215+
for key, newValues := range newTagMap {
216+
oldValues, exists := oldTagMap[key]
217+
if !exists {
218+
// Key doesn't exist in old tags, create all values
219+
for value := range newValues {
196220
tag := *dctapi.NewTag(key, value)
197221
tags = append(tags, tag)
198222
}
223+
} else {
224+
// Key exists, create only new values
225+
for value := range newValues {
226+
if !oldValues[value] {
227+
tag := *dctapi.NewTag(key, value)
228+
tags = append(tags, tag)
229+
}
230+
}
199231
}
200232
}
201-
}
202-
if len(tags) > 0 {
203-
tagsRequest := *dctapi.NewTagsRequest(tags)
204-
_, httpRes, err := client.VDBGroupsAPI.CreateVdbGroupsTags(ctx, vdbGroupId).TagsRequest(tagsRequest).Execute()
205-
if diags := apiErrorResponseHelper(ctx, nil, httpRes, err); diags != nil {
206-
return diags
233+
if len(tags) > 0 {
234+
tagsRequest := *dctapi.NewTagsRequest(tags)
235+
_, httpRes, err := client.VDBGroupsAPI.CreateVdbGroupsTags(ctx, vdbGroupId).TagsRequest(tagsRequest).Execute()
236+
if diags := apiErrorResponseHelper(ctx, nil, httpRes, err); diags != nil {
237+
return diags
238+
}
207239
}
208240
}
209241
}
210242

211243
return resourceVdbGroupRead(ctx, d, meta)
212244
}
213245

246+
func PollVdbGroupStatus(ctx context.Context, client *dctapi.APIClient, vdbGroupId string) (string, error) {
247+
res, _, err := client.VDBGroupsAPI.GetVdbGroup(ctx, vdbGroupId).Execute()
248+
if err != nil {
249+
return "", err
250+
}
251+
return res.GetStatus(), nil
252+
}
253+
214254
func resourceVdbGroupDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
215255
client := meta.(*apiClient).client
216256

0 commit comments

Comments
 (0)