Skip to content

Commit

Permalink
Fix: drift in value of env0_configuration_variable in every plan
Browse files Browse the repository at this point in the history
  • Loading branch information
TomerHeber committed Aug 18, 2024
1 parent 6e3153f commit 1a36c55
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ linters-settings:
errcheck:
exclude-functions:
- (*github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.ResourceData).Set
goconst:
ignore-tests: true
2 changes: 1 addition & 1 deletion client/configuration_variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (c *ConfigurationVariableSchema) ResourceDataSliceStructValueWrite(values m

type ConfigurationVariable struct {
ScopeId string `json:"scopeId,omitempty"`
Value string `json:"value"`
Value string `json:"value" tfschema:"-"`
OrganizationId string `json:"organizationId,omitempty"`
UserId string `json:"userId,omitempty"`
IsSensitive *bool `json:"isSensitive,omitempty"`
Expand Down
4 changes: 4 additions & 0 deletions env0/data_configuration_variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ func dataConfigurationVariableRead(ctx context.Context, d *schema.ResourceData,
return diag.Errorf("schema resource data serialization failed: %v", err)
}

if variable.IsSensitive == nil || !*variable.IsSensitive {
d.Set("value", variable.Value)
}

d.Set("enum", variable.Schema.Enum)

if variable.Schema.Format != client.Text {
Expand Down
12 changes: 9 additions & 3 deletions env0/resource_configuration_variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func getConfigurationVariableCreateParams(d *schema.ResourceData) (*client.Confi
func resourceConfigurationVariableCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
params, err := getConfigurationVariableCreateParams(d)
if err != nil {
return diag.Errorf(err.Error())
return diag.FromErr(err)
}

apiClient := meta.(client.ApiClientInterface)
Expand All @@ -195,7 +195,9 @@ func getEnum(d *schema.ResourceData, selectedValue string) ([]string, error) {
if enumValue == nil {
return nil, fmt.Errorf("an empty enum value is not allowed (at index %d)", i)
}

actualEnumValues = append(actualEnumValues, enumValue.(string))

if enumValue == selectedValue {
valueExists = true
}
Expand Down Expand Up @@ -223,13 +225,17 @@ func resourceConfigurationVariableRead(ctx context.Context, d *schema.ResourceDa
return diag.Errorf("schema resource data serialization failed: %v", err)
}

if variable.IsSensitive == nil || !*variable.IsSensitive {
d.Set("value", variable.Value)
}

return nil
}

func resourceConfigurationVariableUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
params, err := getConfigurationVariableCreateParams(d)
if err != nil {
return diag.Errorf(err.Error())
return diag.FromErr(err)
}

apiClient := meta.(client.ApiClientInterface)
Expand Down Expand Up @@ -280,7 +286,7 @@ func resourceConfigurationVariableImport(ctx context.Context, d *schema.Resource
var scopeName string

if variable.Scope == client.ScopeTemplate {
scopeName = strings.ToLower(fmt.Sprintf("%s_id", templateScope))
scopeName = strings.ToLower(templateScope + "_id")
} else {
scopeName = strings.ToLower(fmt.Sprintf("%s_id", variable.Scope))
}
Expand Down
47 changes: 44 additions & 3 deletions env0/resource_configuration_variable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/env0/terraform-provider-env0/client"
"github.com/env0/terraform-provider-env0/client/http"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"go.uber.org/mock/gomock"
)
Expand Down Expand Up @@ -50,6 +51,7 @@ func TestUnitConfigurationVariableResource(t *testing.T) {
IsRequired: *configVar.IsRequired,
IsReadOnly: *configVar.IsReadOnly,
}

t.Run("Create", func(t *testing.T) {
createTestCase := resource.TestCase{
Steps: []resource.TestStep{
Expand All @@ -74,6 +76,47 @@ func TestUnitConfigurationVariableResource(t *testing.T) {
})
})

t.Run("Create sensitive", func(t *testing.T) {
createSenstiveConfig := client.ConfigurationVariableCreateParams{
Name: "name",
Value: "value",
IsSensitive: true,
Scope: client.ScopeGlobal,
}

sensitiveConfig := client.ConfigurationVariable{
Id: uuid.NewString(),
Name: createSenstiveConfig.Name,
Value: "*",
IsSensitive: boolPtr(true),
Scope: client.ScopeGlobal,
}

createTestCase := resource.TestCase{
Steps: []resource.TestStep{
{
Config: resourceConfigCreate(resourceType, resourceName, map[string]interface{}{
"name": createSenstiveConfig.Name,
"value": createSenstiveConfig.Value,
"is_sensitive": true,
}),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(accessor, "id", sensitiveConfig.Id),
resource.TestCheckResourceAttr(accessor, "name", createSenstiveConfig.Name),
resource.TestCheckResourceAttr(accessor, "value", createSenstiveConfig.Value),
resource.TestCheckResourceAttr(accessor, "is_sensitive", strconv.FormatBool(true)),
),
},
},
}

runUnitTest(t, createTestCase, func(mock *client.MockApiClientInterface) {
mock.EXPECT().ConfigurationVariableCreate(createSenstiveConfig).Times(1).Return(sensitiveConfig, nil)
mock.EXPECT().ConfigurationVariablesById(sensitiveConfig.Id).Times(1).Return(sensitiveConfig, nil)
mock.EXPECT().ConfigurationVariableDelete(sensitiveConfig.Id).Times(1).Return(nil)
})
})

t.Run("Create Two with readonly", func(t *testing.T) {
// https://github.com/env0/terraform-provider-env0/issues/215
// we want to create two variables, one org level with read only and another in lower level and see we can still manage both - double apply and destroy
Expand Down Expand Up @@ -286,7 +329,6 @@ resource "{{.resourceType}}" "{{.projResourceName}}" {

for _, format := range []client.Format{client.HCL, client.JSON} {
t.Run("Create "+string(format)+" Variable", func(t *testing.T) {

expectedVariable := `{
A = "A"
B = "B"
Expand Down Expand Up @@ -627,8 +669,8 @@ resource "%s" "test" {
IsRequired: *configVarImport.IsRequired,
IsReadOnly: *configVarImport.IsReadOnly,
}
t.Run("import by name", func(t *testing.T) {

t.Run("import by name", func(t *testing.T) {
createTestCaseForImport := resource.TestCase{
Steps: []resource.TestStep{
{
Expand All @@ -653,7 +695,6 @@ resource "%s" "test" {
})

t.Run("import by id", func(t *testing.T) {

createTestCaseForImport := resource.TestCase{
Steps: []resource.TestStep{
{
Expand Down

0 comments on commit 1a36c55

Please sign in to comment.