From 822b9fc6b45f9f9d0c169ebb6805d283665dd4dd Mon Sep 17 00:00:00 2001 From: Mauritz Uphoff <39736813+h3adex@users.noreply.github.com> Date: Wed, 3 Sep 2025 10:58:01 +0200 Subject: [PATCH] bugfix(serverbackup): state drift in volume-id because of changed order (#979) * fix: state drift in backup-properties.volume-id because of changed order in API response --------- Signed-off-by: Mauritz Uphoff Co-authored-by: Marcel Jacek --- .../serverbackup/schedule/resource.go | 30 ++++++++++++++++--- .../serverbackup/serverbackup_acc_test.go | 4 +-- .../serverupdate/serverupdate_acc_test.go | 4 +-- stackit/internal/testutil/testutil.go | 2 ++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/stackit/internal/services/serverbackup/schedule/resource.go b/stackit/internal/services/serverbackup/schedule/resource.go index cc0ee969..5ba73f48 100644 --- a/stackit/internal/services/serverbackup/schedule/resource.go +++ b/stackit/internal/services/serverbackup/schedule/resource.go @@ -7,6 +7,8 @@ import ( "strconv" "strings" + "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" + "github.com/hashicorp/terraform-plugin-framework/diag" serverbackupUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/serverbackup/utils" "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" @@ -206,6 +208,9 @@ func (r *scheduleResource) Schema(_ context.Context, _ resource.SchemaRequest, r "volume_ids": schema.ListAttribute{ ElementType: types.StringType, Optional: true, + Validators: []validator.List{ + listvalidator.SizeAtLeast(1), + }, }, "name": schema.StringAttribute{ Required: true, @@ -455,14 +460,31 @@ func mapFields(ctx context.Context, schedule *serverbackup.BackupSchedule, model model.BackupProperties = nil return nil } - ids, diags := types.ListValueFrom(ctx, types.StringType, schedule.BackupProperties.VolumeIds) - if diags.HasError() { - return fmt.Errorf("failed to map hosts: %w", core.DiagsToError(diags)) + + volIds := types.ListNull(types.StringType) + if schedule.BackupProperties.VolumeIds != nil { + var modelVolIds []string + if model.BackupProperties != nil { + var err error + modelVolIds, err = utils.ListValuetoStringSlice(model.BackupProperties.VolumeIds) + if err != nil { + return err + } + } + + respVolIds := *schedule.BackupProperties.VolumeIds + reconciledVolIds := utils.ReconcileStringSlices(modelVolIds, respVolIds) + + var diags diag.Diagnostics + volIds, diags = types.ListValueFrom(ctx, types.StringType, reconciledVolIds) + if diags.HasError() { + return fmt.Errorf("failed to map volumeIds: %w", core.DiagsToError(diags)) + } } model.BackupProperties = &scheduleBackupPropertiesModel{ BackupName: types.StringValue(*schedule.BackupProperties.Name), RetentionPeriod: types.Int64Value(*schedule.BackupProperties.RetentionPeriod), - VolumeIds: ids, + VolumeIds: volIds, } model.Region = types.StringValue(region) return nil diff --git a/stackit/internal/services/serverbackup/serverbackup_acc_test.go b/stackit/internal/services/serverbackup/serverbackup_acc_test.go index ed5bf9e0..9793291b 100644 --- a/stackit/internal/services/serverbackup/serverbackup_acc_test.go +++ b/stackit/internal/services/serverbackup/serverbackup_acc_test.go @@ -88,7 +88,7 @@ func TestAccServerBackupScheduleMinResource(t *testing.T) { }, // Creation { - Config: resourceMinConfig, + Config: testutil.ServerBackupProviderConfig() + "\n" + resourceMinConfig, ConfigVariables: testConfigVarsMin, Check: resource.ComposeAggregateTestCheckFunc( // Backup schedule data @@ -180,7 +180,7 @@ func TestAccServerBackupScheduleMaxResource(t *testing.T) { }, // Creation { - Config: resourceMaxConfig, + Config: testutil.ServerBackupProviderConfig() + "\n" + resourceMaxConfig, ConfigVariables: testConfigVarsMax, Check: resource.ComposeAggregateTestCheckFunc( // Backup schedule data diff --git a/stackit/internal/services/serverupdate/serverupdate_acc_test.go b/stackit/internal/services/serverupdate/serverupdate_acc_test.go index 4851e65c..33a0253a 100644 --- a/stackit/internal/services/serverupdate/serverupdate_acc_test.go +++ b/stackit/internal/services/serverupdate/serverupdate_acc_test.go @@ -90,7 +90,7 @@ func TestAccServerUpdateScheduleMinResource(t *testing.T) { // Creation { ConfigVariables: testConfigVarsMin, - Config: resourceMinConfig, + Config: testutil.ServerUpdateProviderConfig() + "\n" + resourceMinConfig, Check: resource.ComposeAggregateTestCheckFunc( // Update schedule data resource.TestCheckResourceAttr("stackit_server_update_schedule.test_schedule", "project_id", testutil.ConvertConfigVariable(testConfigVarsMin["project_id"])), @@ -177,7 +177,7 @@ func TestAccServerUpdateScheduleMaxResource(t *testing.T) { // Creation { ConfigVariables: testConfigVarsMax, - Config: resourceMaxConfig, + Config: testutil.ServerUpdateProviderConfig() + "\n" + resourceMaxConfig, Check: resource.ComposeAggregateTestCheckFunc( // Update schedule data resource.TestCheckResourceAttr("stackit_server_update_schedule.test_schedule", "project_id", testutil.ConvertConfigVariable(testConfigVarsMax["project_id"])), diff --git a/stackit/internal/testutil/testutil.go b/stackit/internal/testutil/testutil.go index aee5ee68..45660fa7 100644 --- a/stackit/internal/testutil/testutil.go +++ b/stackit/internal/testutil/testutil.go @@ -379,11 +379,13 @@ func ServerBackupProviderConfig() string { return ` provider "stackit" { default_region = "eu01" + enable_beta_resources = true }` } return fmt.Sprintf(` provider "stackit" { server_backup_custom_endpoint = "%s" + enable_beta_resources = true }`, ServerBackupCustomEndpoint, )