Skip to content

Commit

Permalink
azurerm_backup_policy_vm - split create and update function to fix …
Browse files Browse the repository at this point in the history
…lifecycle - ignore (#26591)
  • Loading branch information
mbfrahry authored Jul 11, 2024
1 parent 8aec850 commit 758bb53
Showing 1 changed file with 155 additions and 16 deletions.
171 changes: 155 additions & 16 deletions internal/services/recoveryservices/backup_policy_vm_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ import (

func resourceBackupProtectionPolicyVM() *pluginsdk.Resource {
return &pluginsdk.Resource{
Create: resourceBackupProtectionPolicyVMCreateUpdate,
Create: resourceBackupProtectionPolicyVMCreate,
Read: resourceBackupProtectionPolicyVMRead,
Update: resourceBackupProtectionPolicyVMCreateUpdate,
Update: resourceBackupProtectionPolicyVMUpdate,
Delete: resourceBackupProtectionPolicyVMDelete,

Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error {
Expand Down Expand Up @@ -103,15 +103,15 @@ func resourceBackupProtectionPolicyVM() *pluginsdk.Resource {
}
}

func resourceBackupProtectionPolicyVMCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error {
func resourceBackupProtectionPolicyVMCreate(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).RecoveryServices.ProtectionPoliciesClient
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
defer cancel()

id := protectionpolicies.NewBackupPolicyID(subscriptionId, d.Get("resource_group_name").(string), d.Get("recovery_vault_name").(string), d.Get("name").(string))

log.Printf("[DEBUG] Creating/updating %s", id)
log.Printf("[DEBUG] Creating %s", id)

// getting this ready now because its shared between *everything*, time is... complicated for this resource
timeOfDay := d.Get("backup.0.time").(string)
Expand All @@ -121,21 +121,19 @@ func resourceBackupProtectionPolicyVMCreateUpdate(d *pluginsdk.ResourceData, met
}
times := append(make([]string, 0), date.Time{Time: dateOfDay}.String())

if d.IsNewResource() {
existing, err := client.Get(ctx, id)
if err != nil {
if !response.WasNotFound(existing.HttpResponse) {
return fmt.Errorf("checking for presence of existing %s: %+v", id, err)
}
}

existing, err := client.Get(ctx, id)
if err != nil {
if !response.WasNotFound(existing.HttpResponse) {
return tf.ImportAsExistsError("azurerm_backup_policy_vm", id.ID())
return fmt.Errorf("checking for presence of existing %s: %+v", id, err)
}
}

if !response.WasNotFound(existing.HttpResponse) {
return tf.ImportAsExistsError("azurerm_backup_policy_vm", id.ID())
}

// Less than 7 daily backups is no longer supported for create/update
if (d.IsNewResource() || d.HasChange("retention_daily.0.count")) && (d.Get("retention_daily.0.count").(int) > 1 && d.Get("retention_daily.0.count").(int) < 7) {
if d.Get("retention_daily.0.count").(int) > 1 && d.Get("retention_daily.0.count").(int) < 7 {
return fmt.Errorf("The Azure API has recently changed behaviour so that provisioning a `count` for the `retention_daily` field can no longer be less than 7 days for new/updates to existing Backup Policies. Please ensure that `count` is greater than 7, currently %d", d.Get("retention_daily.0.count").(int))
}

Expand Down Expand Up @@ -173,7 +171,7 @@ func resourceBackupProtectionPolicyVMCreateUpdate(d *pluginsdk.ResourceData, met
}

if _, err = client.CreateOrUpdate(ctx, id, policy); err != nil {
return fmt.Errorf("creating/updating %s: %+v", id, err)
return fmt.Errorf("creating %s: %+v", id, err)
}

if err = resourceBackupProtectionPolicyVMWaitForUpdate(ctx, client, id, d); err != nil {
Expand Down Expand Up @@ -278,6 +276,147 @@ func resourceBackupProtectionPolicyVMRead(d *pluginsdk.ResourceData, meta interf
return nil
}

func resourceBackupProtectionPolicyVMUpdate(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).RecoveryServices.ProtectionPoliciesClient
ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := protectionpolicies.ParseBackupPolicyID(d.Id())
if err != nil {
return err
}

log.Printf("[DEBUG] Updating %s", id)

// getting this ready now because its shared between *everything*, time is... complicated for this resource
timeOfDay := d.Get("backup.0.time").(string)
dateOfDay, err := time.Parse(time.RFC3339, fmt.Sprintf("%sT%s:00Z", time.Now().Format("2006-01-02"), timeOfDay))
if err != nil {
return fmt.Errorf("generating time from %q for %s: %+v", timeOfDay, id, err)
}
times := append(make([]string, 0), date.Time{Time: dateOfDay}.String())

// Less than 7 daily backups is no longer supported for create/update
if d.HasChange("retention_daily.0.count") && (d.Get("retention_daily.0.count").(int) > 1 && d.Get("retention_daily.0.count").(int) < 7) {
return fmt.Errorf("the Azure API has recently changed behaviour so that provisioning a `count` for the `retention_daily` field can no longer be less than 7 days for new/updates to existing Backup Policies. Please ensure that `count` is greater than 7, currently %d", d.Get("retention_daily.0.count").(int))
}

existing, err := client.Get(ctx, *id)
if err != nil {
return err
}

if existing.Model == nil {
return fmt.Errorf("retrieving %s: `model` was nil", id)
}

if existing.Model.Properties == nil {
return fmt.Errorf("retrieving %s: `properties` was nil", id)
}

if _, ok := existing.Model.Properties.(protectionpolicies.AzureIaaSVMProtectionPolicy); !ok {
return fmt.Errorf("retrieving %s: `properties` was not a AzureIaaSVMProtectionPolicy", id)
}

model := *existing.Model
properties := existing.Model.Properties.(protectionpolicies.AzureIaaSVMProtectionPolicy)

properties.InstantRpRetentionRangeInDays = nil
if d.HasChange("instant_restore_retention_days") {
days := d.Get("instant_restore_retention_days").(int)
if properties.PolicyType != nil && protectionpolicies.IAASVMPolicyTypeVOne == *properties.PolicyType && days > 5 {
return fmt.Errorf("`instant_restore_retention_days` must be less than or equal to `5` when `policy_type` is `V1`")
}

properties.InstantRpRetentionRangeInDays = pointer.To(int64(days))
}

if d.HasChange("tiering_policy") {
properties.TieringPolicy = expandBackupProtectionPolicyVMTieringPolicy(d.Get("tiering_policy").([]interface{}))
}

if d.HasChange("timezone") {
properties.TimeZone = utils.String(d.Get("timezone").(string))
}

if d.HasChange("instant_restore_resource_group") {
properties.InstantRPDetails = expandBackupProtectionPolicyVMResourceGroup(d)
}

if d.HasChange("backup") {
schedulePolicy, err := expandBackupProtectionPolicyVMSchedule(d, times)
if err != nil {
return err
}
properties.SchedulePolicy = schedulePolicy
}

if d.HasChange("retention_daily") {
if properties.RetentionPolicy == nil {
properties.RetentionPolicy = &protectionpolicies.LongTermRetentionPolicy{}
}
retentionPolicy, ok := properties.RetentionPolicy.(protectionpolicies.LongTermRetentionPolicy)
if !ok {
properties.RetentionPolicy = &protectionpolicies.LongTermRetentionPolicy{}
}

retentionPolicy.DailySchedule = expandBackupProtectionPolicyVMRetentionDaily(d, times)
properties.RetentionPolicy = retentionPolicy
}

if d.HasChange("retention_weekly") {
if properties.RetentionPolicy == nil {
properties.RetentionPolicy = &protectionpolicies.LongTermRetentionPolicy{}
}
retentionPolicy, ok := properties.RetentionPolicy.(protectionpolicies.LongTermRetentionPolicy)
if !ok {
properties.RetentionPolicy = &protectionpolicies.LongTermRetentionPolicy{}
}

retentionPolicy.WeeklySchedule = expandBackupProtectionPolicyVMRetentionWeekly(d, times)
properties.RetentionPolicy = retentionPolicy
}

if d.HasChange("retention_monthly") {
if properties.RetentionPolicy == nil {
properties.RetentionPolicy = &protectionpolicies.LongTermRetentionPolicy{}
}
retentionPolicy, ok := properties.RetentionPolicy.(protectionpolicies.LongTermRetentionPolicy)
if !ok {
properties.RetentionPolicy = &protectionpolicies.LongTermRetentionPolicy{}
}

retentionPolicy.MonthlySchedule = expandBackupProtectionPolicyVMRetentionMonthly(d, times)
properties.RetentionPolicy = retentionPolicy
}

if d.HasChange("retention_yearly") {
if properties.RetentionPolicy == nil {
properties.RetentionPolicy = &protectionpolicies.LongTermRetentionPolicy{}
}
retentionPolicy, ok := properties.RetentionPolicy.(protectionpolicies.LongTermRetentionPolicy)
if !ok {
properties.RetentionPolicy = &protectionpolicies.LongTermRetentionPolicy{}
}

retentionPolicy.YearlySchedule = expandBackupProtectionPolicyVMRetentionYearly(d, times)
properties.RetentionPolicy = retentionPolicy
}

model.Properties = properties
if _, err = client.CreateOrUpdate(ctx, *id, model); err != nil {
return fmt.Errorf("updating %s: %+v", id, err)
}

if err = resourceBackupProtectionPolicyVMWaitForUpdate(ctx, client, *id, d); err != nil {
return err
}

d.SetId(id.ID())

return resourceBackupProtectionPolicyVMRead(d, meta)
}

func resourceBackupProtectionPolicyVMDelete(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).RecoveryServices.ProtectionPoliciesClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
Expand Down

0 comments on commit 758bb53

Please sign in to comment.