Skip to content

Commit e191810

Browse files
Enable update bpa support on BPA resource (#14102) (#10176)
[upstream:cb4456d46502224d3fe6b98d659c7d471ca120ea] Signed-off-by: Modular Magician <[email protected]>
1 parent 50775aa commit e191810

File tree

4 files changed

+369
-5
lines changed

4 files changed

+369
-5
lines changed

.changelog/14102.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
backupdr: added support for updating in-place to the `google_backup_dr_backup_plan_association` resource
3+
```

google-beta/services/backupdr/resource_backup_dr_backup_plan_association.go

Lines changed: 101 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"log"
2525
"net/http"
2626
"reflect"
27+
"strings"
2728
"time"
2829

2930
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
@@ -37,6 +38,7 @@ func ResourceBackupDRBackupPlanAssociation() *schema.Resource {
3738
return &schema.Resource{
3839
Create: resourceBackupDRBackupPlanAssociationCreate,
3940
Read: resourceBackupDRBackupPlanAssociationRead,
41+
Update: resourceBackupDRBackupPlanAssociationUpdate,
4042
Delete: resourceBackupDRBackupPlanAssociationDelete,
4143

4244
Importer: &schema.ResourceImporter{
@@ -45,6 +47,7 @@ func ResourceBackupDRBackupPlanAssociation() *schema.Resource {
4547

4648
Timeouts: &schema.ResourceTimeout{
4749
Create: schema.DefaultTimeout(60 * time.Minute),
50+
Update: schema.DefaultTimeout(20 * time.Minute),
4851
Delete: schema.DefaultTimeout(60 * time.Minute),
4952
},
5053

@@ -56,7 +59,6 @@ func ResourceBackupDRBackupPlanAssociation() *schema.Resource {
5659
"backup_plan": {
5760
Type: schema.TypeString,
5861
Required: true,
59-
ForceNew: true,
6062
DiffSuppressFunc: tpgresource.ProjectNumberDiffSuppress,
6163
Description: `The BP with which resource needs to be created
6264
Note:
@@ -66,25 +68,21 @@ Note:
6668
"backup_plan_association_id": {
6769
Type: schema.TypeString,
6870
Required: true,
69-
ForceNew: true,
7071
Description: `The id of backupplan association`,
7172
},
7273
"location": {
7374
Type: schema.TypeString,
7475
Required: true,
75-
ForceNew: true,
7676
Description: `The location for the backupplan association`,
7777
},
7878
"resource": {
7979
Type: schema.TypeString,
8080
Required: true,
81-
ForceNew: true,
8281
Description: `The resource for which BPA needs to be created`,
8382
},
8483
"resource_type": {
8584
Type: schema.TypeString,
8685
Required: true,
87-
ForceNew: true,
8886
Description: `The resource type of workload on which backupplan is applied.
8987
Examples include, "compute.googleapis.com/Instance", "compute.googleapis.com/Disk", and "compute.googleapis.com/RegionDisk"`,
9088
},
@@ -315,6 +313,104 @@ func resourceBackupDRBackupPlanAssociationRead(d *schema.ResourceData, meta inte
315313
return nil
316314
}
317315

316+
func resourceBackupDRBackupPlanAssociationUpdate(d *schema.ResourceData, meta interface{}) error {
317+
config := meta.(*transport_tpg.Config)
318+
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
319+
if err != nil {
320+
return err
321+
}
322+
323+
billingProject := ""
324+
325+
project, err := tpgresource.GetProject(d, config)
326+
if err != nil {
327+
return fmt.Errorf("Error fetching project for BackupPlanAssociation: %s", err)
328+
}
329+
billingProject = project
330+
331+
obj := make(map[string]interface{})
332+
resourceProp, err := expandBackupDRBackupPlanAssociationResource(d.Get("resource"), d, config)
333+
if err != nil {
334+
return err
335+
} else if v, ok := d.GetOkExists("resource"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, resourceProp)) {
336+
obj["resource"] = resourceProp
337+
}
338+
backupPlanProp, err := expandBackupDRBackupPlanAssociationBackupPlan(d.Get("backup_plan"), d, config)
339+
if err != nil {
340+
return err
341+
} else if v, ok := d.GetOkExists("backup_plan"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, backupPlanProp)) {
342+
obj["backupPlan"] = backupPlanProp
343+
}
344+
resourceTypeProp, err := expandBackupDRBackupPlanAssociationResourceType(d.Get("resource_type"), d, config)
345+
if err != nil {
346+
return err
347+
} else if v, ok := d.GetOkExists("resource_type"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, resourceTypeProp)) {
348+
obj["resourceType"] = resourceTypeProp
349+
}
350+
351+
url, err := tpgresource.ReplaceVars(d, config, "{{BackupDRBasePath}}projects/{{project}}/locations/{{location}}/backupPlanAssociations/{{backup_plan_association_id}}")
352+
if err != nil {
353+
return err
354+
}
355+
356+
log.Printf("[DEBUG] Updating BackupPlanAssociation %q: %#v", d.Id(), obj)
357+
headers := make(http.Header)
358+
updateMask := []string{}
359+
360+
if d.HasChange("resource") {
361+
updateMask = append(updateMask, "resource")
362+
}
363+
364+
if d.HasChange("backup_plan") {
365+
updateMask = append(updateMask, "backupPlan")
366+
}
367+
368+
if d.HasChange("resource_type") {
369+
updateMask = append(updateMask, "resourceType")
370+
}
371+
// updateMask is a URL parameter but not present in the schema, so ReplaceVars
372+
// won't set it
373+
url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
374+
if err != nil {
375+
return err
376+
}
377+
378+
// err == nil indicates that the billing_project value was found
379+
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
380+
billingProject = bp
381+
}
382+
383+
// if updateMask is empty we are not updating anything so skip the post
384+
if len(updateMask) > 0 {
385+
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
386+
Config: config,
387+
Method: "PATCH",
388+
Project: billingProject,
389+
RawURL: url,
390+
UserAgent: userAgent,
391+
Body: obj,
392+
Timeout: d.Timeout(schema.TimeoutUpdate),
393+
Headers: headers,
394+
})
395+
396+
if err != nil {
397+
return fmt.Errorf("Error updating BackupPlanAssociation %q: %s", d.Id(), err)
398+
} else {
399+
log.Printf("[DEBUG] Finished updating BackupPlanAssociation %q: %#v", d.Id(), res)
400+
}
401+
402+
err = BackupDROperationWaitTime(
403+
config, res, project, "Updating BackupPlanAssociation", userAgent,
404+
d.Timeout(schema.TimeoutUpdate))
405+
406+
if err != nil {
407+
return err
408+
}
409+
}
410+
411+
return resourceBackupDRBackupPlanAssociationRead(d, meta)
412+
}
413+
318414
func resourceBackupDRBackupPlanAssociationDelete(d *schema.ResourceData, meta interface{}) error {
319415
config := meta.(*transport_tpg.Config)
320416
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)

0 commit comments

Comments
 (0)