From 2c12c61cf6805aaf2ac4826881f5ccaf090b7974 Mon Sep 17 00:00:00 2001 From: Murad Biashimov Date: Wed, 30 Oct 2024 09:48:32 +0100 Subject: [PATCH] feat: allow to purge additional_disk_space --- internal/schemautil/custom_diff.go | 64 +++++++++++++++++++++- internal/schemautil/service.go | 33 ++--------- internal/sdkprovider/service/pg/pg_test.go | 2 +- 3 files changed, 68 insertions(+), 31 deletions(-) diff --git a/internal/schemautil/custom_diff.go b/internal/schemautil/custom_diff.go index 5f149295b..893e57d7d 100644 --- a/internal/schemautil/custom_diff.go +++ b/internal/schemautil/custom_diff.go @@ -6,11 +6,15 @@ import ( "strings" "github.com/aiven/aiven-go-client/v2" + avngen "github.com/aiven/go-client-codegen" + "github.com/aiven/go-client-codegen/handler/service" "github.com/docker/go-units" "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "golang.org/x/exp/slices" + + "github.com/aiven/terraform-provider-aiven/internal/common" ) func CustomizeDiffGenericService(serviceType string) schema.CustomizeDiffFunc { @@ -27,7 +31,10 @@ func CustomizeDiffGenericService(serviceType string) schema.CustomizeDiffFunc { ), customdiff.IfValueChange("additional_disk_space", ShouldNotBeEmpty, - CustomizeDiffCheckDiskSpace, + customdiff.Sequence( + CustomizeDiffCheckDiskSpace, + CustomizeDiffAdditionalDiskSpace, + ), ), customdiff.IfValueChange("service_integrations", ShouldNotBeEmpty, @@ -254,3 +261,58 @@ func checkForMultipleValues(v cty.Value) error { return nil } + +// CustomizeDiffAdditionalDiskSpace +// 1. checks that additional_disk_space is not set if autoscaler is enabled +// 2. outputs a diff for a computed field, which otherwise would be suppressed when removed +func CustomizeDiffAdditionalDiskSpace(ctx context.Context, diff *schema.ResourceDiff, _ interface{}) error { + client, err := common.GenClient() + if err != nil { + return err + } + + s, err := client.ServiceGet(ctx, diff.Get("project").(string), diff.Get("service_name").(string)) + if avngen.IsNotFound(err) { + // The service does not exist, so we cannot check if autoscaler is enabled + return nil + } + + if err != nil { + return err + } + + isAutoscalerEnabled := false + for _, i := range s.ServiceIntegrations { + if i.IntegrationType == service.IntegrationTypeAutoscaler { + isAutoscalerEnabled = true + break + } + } + + k := "additional_disk_space" + + // Validates autoscaler enabled + c := diff.GetRawConfig() + isSet := !(c.IsNull() || c.AsValueMap()[k].IsNull()) + if isSet { + if isAutoscalerEnabled { + // Autoscaler is enabled, so we cannot set additional_disk_space + return ErrAutoscalerConflict + } + + // It is in the config file, lets TF handle it + return nil + } + + if isAutoscalerEnabled { + // If the autoscaler is enabled, we don't need to manage the field, + // it will change its value automatically + return nil + } + + // It is not set but has a value (ShouldNotBeEmpty proves it has). + // That means the value is being removed. + // We must output a diff for the computed field, + // which otherwise TF will suppress it + return diff.SetNew(k, "0B") +} diff --git a/internal/schemautil/service.go b/internal/schemautil/service.go index 8d043efb2..6b1b65229 100644 --- a/internal/schemautil/service.go +++ b/internal/schemautil/service.go @@ -516,17 +516,6 @@ func ResourceServiceUpdate(ctx context.Context, d *schema.ResourceData, m interf return diag.FromErr(err) } - // Note: Only service_integrations are needed here, but no specific API exists yet. - s, err := avnGen.ServiceGet(ctx, projectName, serviceName, service.ServiceGetIncludeSecrets(true)) - if err != nil { - return diag.Errorf("unable to GET service %s: %s", d.Id(), err) - } - - autoscalerIntegrations := getIntegrationsForTerraform(s.ServiceIntegrations, service.IntegrationTypeAutoscaler) - if _, ok := d.GetOk("additional_disk_space"); ok && len(autoscalerIntegrations) > 0 { - return diag.FromErr(ErrAutoscalerConflict) - } - cloud := d.Get("cloud_name").(string) plan := d.Get("plan").(string) powered := true @@ -691,31 +680,17 @@ func copyServicePropertiesFromAPIResponseToTerraform( if s.DiskSpaceMb != nil { diskSpace = *s.DiskSpaceMb } - additionalDiskSpace := diskSpace - servicePlanParams.DiskSizeMBDefault - - _, isAdditionalDiskSpaceSet := d.GetOk("additional_disk_space") - _, isDiskSpaceSet := d.GetOk("disk_space") - // Handles two different cases: - // - // 1. During import when neither `additional_disk_space` nor `disk_space` are set - // 2. During create / update when `additional_disk_space` is set - if additionalDiskSpace > 0 && (!isDiskSpaceSet || isAdditionalDiskSpaceSet) { - if err := d.Set("additional_disk_space", HumanReadableByteSize(additionalDiskSpace*units.MiB)); err != nil { - return err - } - if err := d.Set("disk_space", nil); err != nil { - return err - } + additionalDiskSpace := diskSpace - servicePlanParams.DiskSizeMBDefault + if err := d.Set("additional_disk_space", HumanReadableByteSize(additionalDiskSpace*units.MiB)); err != nil { + return err } + _, isDiskSpaceSet := d.GetOk("disk_space") if isDiskSpaceSet && diskSpace > 0 { if err := d.Set("disk_space", HumanReadableByteSize(diskSpace*units.MiB)); err != nil { return err } - if err := d.Set("additional_disk_space", nil); err != nil { - return err - } } if err := d.Set("disk_space_used", HumanReadableByteSize(diskSpace*units.MiB)); err != nil { diff --git a/internal/sdkprovider/service/pg/pg_test.go b/internal/sdkprovider/service/pg/pg_test.go index 22eb37a56..13290a95b 100644 --- a/internal/sdkprovider/service/pg/pg_test.go +++ b/internal/sdkprovider/service/pg/pg_test.go @@ -265,7 +265,7 @@ func TestAccAivenPG_deleting_additional_disk_size(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "maintenance_window_dow", "monday"), resource.TestCheckResourceAttr(resourceName, "maintenance_window_time", "10:00:00"), resource.TestCheckResourceAttr(resourceName, "disk_space_default", "80GiB"), - resource.TestCheckResourceAttr(resourceName, "disk_space_used", "100GiB"), + resource.TestCheckResourceAttr(resourceName, "disk_space_used", "80GiB"), resource.TestCheckResourceAttr(resourceName, "termination_protection", "false"), ), },