From 7be875cee7de7b724be182df76890e085fc27a7d Mon Sep 17 00:00:00 2001 From: Meet Rathod Date: Fri, 8 Dec 2023 15:44:28 +0530 Subject: [PATCH] Add YamlDiffSuppressFunction to avoid unecessary changes in plan (#794) (#808) * Add YamlDiffSuppressFunction to avoid unecessary changes in plan * Add YamlDiffSuppressFunction tests Co-authored-by: Aleksei Larkov --- helpers/yamls.go | 22 +++++++ helpers/yamls_test.go | 59 +++++++++++++++++++ .../environment/resource_environment.go | 7 ++- .../resource_environment_group.go | 7 ++- .../resource_environment_service_overrides.go | 7 ++- .../infrastructure/resource_Infrastructure.go | 7 ++- .../manual_freeze/resource_manual_freeze.go | 9 +-- .../platform/pipeline/resource_pipeline.go | 23 ++++---- .../platform/service/resource_service.go | 9 +-- .../resource_service_overrides_v2.go | 7 ++- .../platform/triggers/resource_triggers.go | 7 ++- 11 files changed, 127 insertions(+), 37 deletions(-) create mode 100644 helpers/yamls.go create mode 100644 helpers/yamls_test.go diff --git a/helpers/yamls.go b/helpers/yamls.go new file mode 100644 index 000000000..de4f18e50 --- /dev/null +++ b/helpers/yamls.go @@ -0,0 +1,22 @@ +package helpers + +import ( + "reflect" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "gopkg.in/yaml.v3" +) + +// YamlDiffSuppressFunction returns true if two content of yaml strings are identical. +// That helps to avoid unnecessary changes in plan if the yaml format was changed only, but not the data. +func YamlDiffSuppressFunction(k, old, new string, d *schema.ResourceData) bool { + var oldYaml, newYaml interface{} + if err := yaml.Unmarshal([]byte(old), &oldYaml); err != nil { + return false + } + if err := yaml.Unmarshal([]byte(new), &newYaml); err != nil { + return false + } + return reflect.DeepEqual(oldYaml, newYaml) + +} diff --git a/helpers/yamls_test.go b/helpers/yamls_test.go new file mode 100644 index 000000000..794f8dc9c --- /dev/null +++ b/helpers/yamls_test.go @@ -0,0 +1,59 @@ +package helpers_test + +import ( + "testing" + + "github.com/harness/terraform-provider-harness/helpers" + "github.com/stretchr/testify/require" +) + +func TestYamlDiffSuppressFunction(t *testing.T) { + require.True(t, helpers.YamlDiffSuppressFunction("", "", "", nil)) + + require.True(t, helpers.YamlDiffSuppressFunction("", + `--- +field1: value1 +field2: value2 +`, + `--- +field2: value2 +field1: value1 +`, nil)) + + require.True(t, helpers.YamlDiffSuppressFunction("", + `--- +"field1": "value1" +"field2": "value2" +`, + `--- +field2: value2 +field1: value1 +`, nil)) + + require.False(t, helpers.YamlDiffSuppressFunction("", + `--- +field1: value1 +`, + `--- +field2: value2 +`, nil)) + + require.False(t, helpers.YamlDiffSuppressFunction("", + `--- +field1: value1 +`, + `--- +field1: value1 +field2: value2 +`, nil)) + + require.False(t, helpers.YamlDiffSuppressFunction("", + `--- +field1: value1 +field2: value2 +`, + `--- +field1: value1 +`, nil)) + +} diff --git a/internal/service/platform/environment/resource_environment.go b/internal/service/platform/environment/resource_environment.go index 30e8528d8..c6ac1be95 100644 --- a/internal/service/platform/environment/resource_environment.go +++ b/internal/service/platform/environment/resource_environment.go @@ -39,9 +39,10 @@ func ResourceEnvironment() *schema.Resource { ValidateFunc: validation.StringInSlice(nextgen.EnvironmentTypeValues, false), }, "yaml": { - Description: "Environment YAML." + helpers.Descriptions.YamlText.String(), - Type: schema.TypeString, - Optional: true, + Description: "Environment YAML." + helpers.Descriptions.YamlText.String(), + Type: schema.TypeString, + Optional: true, + DiffSuppressFunc: helpers.YamlDiffSuppressFunction, }, "force_delete": { Description: "Enable this flag for force deletion of environments", diff --git a/internal/service/platform/environment_group/resource_environment_group.go b/internal/service/platform/environment_group/resource_environment_group.go index b8f0c8b72..6d063b0fe 100644 --- a/internal/service/platform/environment_group/resource_environment_group.go +++ b/internal/service/platform/environment_group/resource_environment_group.go @@ -46,9 +46,10 @@ func ResourceEnvironmentGroup() *schema.Resource { Computed: true, }, "yaml": { - Description: "Env group YAML." + helpers.Descriptions.YamlText.String(), - Type: schema.TypeString, - Required: true, + Description: "Env group YAML." + helpers.Descriptions.YamlText.String(), + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: helpers.YamlDiffSuppressFunction, }, "force_delete": { Description: "Enable this flag for force deletion of environment group", diff --git a/internal/service/platform/environment_service_overrides/resource_environment_service_overrides.go b/internal/service/platform/environment_service_overrides/resource_environment_service_overrides.go index 8624b9338..f4c0cb827 100644 --- a/internal/service/platform/environment_service_overrides/resource_environment_service_overrides.go +++ b/internal/service/platform/environment_service_overrides/resource_environment_service_overrides.go @@ -40,9 +40,10 @@ func ResourceEnvironmentServiceOverrides() *schema.Resource { Required: true, }, "yaml": { - Description: "Environment Service Overrides YAML." + helpers.Descriptions.YamlText.String(), - Type: schema.TypeString, - Required: true, + Description: "Environment Service Overrides YAML." + helpers.Descriptions.YamlText.String(), + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: helpers.YamlDiffSuppressFunction, }, }, } diff --git a/internal/service/platform/infrastructure/resource_Infrastructure.go b/internal/service/platform/infrastructure/resource_Infrastructure.go index a93461742..b45eacfb4 100644 --- a/internal/service/platform/infrastructure/resource_Infrastructure.go +++ b/internal/service/platform/infrastructure/resource_Infrastructure.go @@ -41,9 +41,10 @@ func ResourceInfrastructure() *schema.Resource { Required: true, }, "yaml": { - Description: "Infrastructure YAML." + helpers.Descriptions.YamlText.String(), - Type: schema.TypeString, - Required: true, + Description: "Infrastructure YAML." + helpers.Descriptions.YamlText.String(), + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: helpers.YamlDiffSuppressFunction, }, "deployment_type": { Description: fmt.Sprintf("Infrastructure deployment type. Valid values are %s.", strings.Join(nextgen.InfrastructureDeploymentypeValues, ", ")), diff --git a/internal/service/platform/manual_freeze/resource_manual_freeze.go b/internal/service/platform/manual_freeze/resource_manual_freeze.go index 5f7258e8f..ea68fb583 100644 --- a/internal/service/platform/manual_freeze/resource_manual_freeze.go +++ b/internal/service/platform/manual_freeze/resource_manual_freeze.go @@ -76,9 +76,10 @@ func ResourceManualFreeze() *schema.Resource { Computed: true, }, "yaml": { - Description: "Yaml of the freeze", - Type: schema.TypeString, - Required: true, + Description: "Yaml of the freeze", + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: helpers.YamlDiffSuppressFunction, }, "current_or_upcoming_windows": { Description: "Current or upcoming windows", @@ -274,7 +275,7 @@ func readFreezeResponse(d *schema.ResourceData, freezeResponse *nextgen.FreezeDe }, }) } else { - d.Set("current_or_upcoming_windows", nil); + d.Set("current_or_upcoming_windows", nil) } d.Set("freeze_windows", expandFreezeWindows(freezeResponse.Windows)) } diff --git a/internal/service/platform/pipeline/resource_pipeline.go b/internal/service/platform/pipeline/resource_pipeline.go index 9700c0215..574f1b058 100644 --- a/internal/service/platform/pipeline/resource_pipeline.go +++ b/internal/service/platform/pipeline/resource_pipeline.go @@ -25,36 +25,37 @@ func ResourcePipeline() *schema.Resource { Schema: map[string]*schema.Schema{ "yaml": { - Description: "YAML of the pipeline." + helpers.Descriptions.YamlText.String(), - Type: schema.TypeString, - Optional: true, - Computed: true, + Description: "YAML of the pipeline." + helpers.Descriptions.YamlText.String(), + Type: schema.TypeString, + Optional: true, + Computed: true, + DiffSuppressFunc: helpers.YamlDiffSuppressFunction, }, "git_details": { Description: "Contains parameters related to creating an Entity for Git Experience.", Type: schema.TypeList, MaxItems: 1, Optional: true, - Computed: true, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "branch_name": { Description: "Name of the branch.", Type: schema.TypeString, Optional: true, - Computed: true, + Computed: true, }, "file_path": { Description: "File path of the Entity in the repository.", Type: schema.TypeString, Optional: true, - Computed: true, + Computed: true, }, "commit_message": { Description: "Commit message used for the merge commit.", Type: schema.TypeString, Optional: true, - Computed: true, + Computed: true, }, "base_branch": { Description: "Name of the default branch (this checks out a new branch titled by branch_name).", @@ -66,20 +67,20 @@ func ResourcePipeline() *schema.Resource { Description: "Identifier of the Harness Connector used for CRUD operations on the Entity." + helpers.Descriptions.ConnectorRefText.String(), Type: schema.TypeString, Optional: true, - Computed: true, + Computed: true, }, "store_type": { Description: "Specifies whether the Entity is to be stored in Git or not. Possible values: INLINE, REMOTE.", Type: schema.TypeString, Optional: true, ValidateFunc: validation.StringInSlice([]string{"INLINE", "REMOTE"}, false), - Computed: true, + Computed: true, }, "repo_name": { Description: "Name of the repository.", Type: schema.TypeString, Optional: true, - Computed: true, + Computed: true, }, "last_object_id": { Description: "Last object identifier (for Github). To be provided only when updating Pipeline.", diff --git a/internal/service/platform/service/resource_service.go b/internal/service/platform/service/resource_service.go index c4bfb6233..31f7004e5 100644 --- a/internal/service/platform/service/resource_service.go +++ b/internal/service/platform/service/resource_service.go @@ -24,10 +24,11 @@ func ResourceService() *schema.Resource { Schema: map[string]*schema.Schema{ "yaml": { - Description: "Service YAML." + helpers.Descriptions.YamlText.String(), - Type: schema.TypeString, - Optional: true, - Computed: true, + Description: "Service YAML." + helpers.Descriptions.YamlText.String(), + Type: schema.TypeString, + Optional: true, + Computed: true, + DiffSuppressFunc: helpers.YamlDiffSuppressFunction, }, "force_delete": { Description: "Enable this flag for force deletion of service", diff --git a/internal/service/platform/service_overrides_v2/resource_service_overrides_v2.go b/internal/service/platform/service_overrides_v2/resource_service_overrides_v2.go index 84ef90999..c6aedff74 100644 --- a/internal/service/platform/service_overrides_v2/resource_service_overrides_v2.go +++ b/internal/service/platform/service_overrides_v2/resource_service_overrides_v2.go @@ -52,9 +52,10 @@ func ResourceServiceOverrides() *schema.Resource { Required: true, }, "yaml": { - Description: "The yaml of the overrides spec object.", - Type: schema.TypeString, - Required: true, + Description: "The yaml of the overrides spec object.", + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: helpers.YamlDiffSuppressFunction, }, "identifier": { Description: "The identifier of the override entity.", diff --git a/internal/service/platform/triggers/resource_triggers.go b/internal/service/platform/triggers/resource_triggers.go index 20474db44..7c5862448 100644 --- a/internal/service/platform/triggers/resource_triggers.go +++ b/internal/service/platform/triggers/resource_triggers.go @@ -33,9 +33,10 @@ func ResourceTriggers() *schema.Resource { Optional: true, }, "yaml": { - Description: "trigger yaml." + helpers.Descriptions.YamlText.String(), - Type: schema.TypeString, - Required: true, + Description: "trigger yaml." + helpers.Descriptions.YamlText.String(), + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: helpers.YamlDiffSuppressFunction, }, "if_match": { Description: "if-Match",