From 5eeae083280f9122041be308e5be9d3420e1adb3 Mon Sep 17 00:00:00 2001 From: Tomer Heber Date: Mon, 22 Jul 2024 08:24:23 -0500 Subject: [PATCH 01/10] Fix: importing a non-existent environment show an 'Authentication error' in variable sets instead (#901) --- env0/resource_environment.go | 12 ++++++---- env0/resource_environment_test.go | 38 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/env0/resource_environment.go b/env0/resource_environment.go index 2446553c..cfd3d018 100644 --- a/env0/resource_environment.go +++ b/env0/resource_environment.go @@ -1340,6 +1340,7 @@ func getEnvironmentById(environmentId string, meta interface{}) (client.Environm func resourceEnvironmentImporter(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { id := d.Id() var getErr diag.Diagnostics + var environment client.Environment _, err := uuid.Parse(id) if err == nil { @@ -1350,6 +1351,11 @@ func resourceEnvironmentImporter(ctx context.Context, d *schema.ResourceData, me environment, getErr = getEnvironmentByName(meta, id, "", false) } + + if getErr != nil { + return nil, errors.New(getErr[0].Summary) + } + apiClient := meta.(client.ApiClientInterface) d.SetId(environment.Id) @@ -1406,9 +1412,5 @@ func resourceEnvironmentImporter(ctx context.Context, d *schema.ResourceData, me d.Set("vcs_pr_comments_enabled", environment.VcsCommandsAlias != "" || environment.VcsPrCommentsEnabled) - if getErr != nil { - return nil, errors.New(getErr[0].Summary) - } else { - return []*schema.ResourceData{d}, nil - } + return []*schema.ResourceData{d}, nil } diff --git a/env0/resource_environment_test.go b/env0/resource_environment_test.go index e7ac6e1f..ef2a0b16 100644 --- a/env0/resource_environment_test.go +++ b/env0/resource_environment_test.go @@ -744,6 +744,44 @@ func TestUnitEnvironmentResource(t *testing.T) { }) }) + t.Run("Import By Id - not found", func(t *testing.T) { + testCase := resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: createEnvironmentResourceConfig(environment), + }, + { + ResourceName: resourceNameImport, + ImportState: true, + ImportStateId: environment.Id, + ExpectError: regexp.MustCompile("Could not find environment: error"), + }, + }, + } + + runUnitTest(t, testCase, func(mock *client.MockApiClientInterface) { + mock.EXPECT().Template(environment.LatestDeploymentLog.BlueprintId).Times(1).Return(template, nil) + mock.EXPECT().EnvironmentCreate(client.EnvironmentCreate{ + Name: environment.Name, + ProjectId: environment.ProjectId, + WorkspaceName: environment.WorkspaceName, + AutoDeployByCustomGlob: autoDeployByCustomGlobDefault, + TerragruntWorkingDirectory: environment.TerragruntWorkingDirectory, + VcsCommandsAlias: environment.VcsCommandsAlias, + DeployRequest: &client.DeployRequest{ + BlueprintId: templateId, + }, + IsRemoteBackend: &isRemoteBackendFalse, + K8sNamespace: environment.K8sNamespace, + }).Times(1).Return(environment, nil) + mock.EXPECT().Environment(environment.Id).Times(1).Return(environment, nil) + mock.EXPECT().ConfigurationVariablesByScope(client.ScopeEnvironment, environment.Id).Times(1).Return(client.ConfigurationChanges{}, nil) + mock.EXPECT().ConfigurationSetsAssignments("ENVIRONMENT", environment.Id).Times(1).Return(nil, nil) + mock.EXPECT().Environment(environment.Id).Times(1).Return(client.Environment{}, errors.New("error")) + mock.EXPECT().EnvironmentDestroy(environment.Id).Times(1) + }) + }) + t.Run("Success create and remove drift cron", func(t *testing.T) { testCase := resource.TestCase{ Steps: []resource.TestStep{ From 850c77f58a955ee3983ceab19583013f82df7fe1 Mon Sep 17 00:00:00 2001 From: Arel Rabinowitz <30493345+RLRabinowitz@users.noreply.github.com> Date: Wed, 24 Jul 2024 19:05:44 +0300 Subject: [PATCH 02/10] Change description of variable_sets field on environment_resource (#905) --- docs/resources/environment.md | 2 +- env0/resource_environment.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/resources/environment.md b/docs/resources/environment.md index a30f7a3e..b76acd04 100644 --- a/docs/resources/environment.md +++ b/docs/resources/environment.md @@ -84,7 +84,7 @@ Important note: the template must first be assigned to the same project as the e Important note: After the environment is created, this field cannot be modified. - `terragrunt_working_directory` (String) The working directory path to be used by a Terragrunt template. If left empty '/' is used. Note: modifying this field destroys the current environment and creates a new one - `ttl` (String) the date the environment should be destroyed at (iso format). omitting this attribute will result in infinite ttl. -- `variable_sets` (List of String) a list of variable set to assign to this environment. Note: must not be used with 'env0_variable_set_assignment' +- `variable_sets` (List of String) a list of IDs of variable sets to assign to this environment. Note: must not be used with 'env0_variable_set_assignment' - `vcs_commands_alias` (String) set an alias for this environment in favor of running VCS commands using PR comments against it. Additional details: https://docs.env0.com/docs/plan-and-apply-from-pr-comments - `vcs_pr_comments_enabled` (Boolean) set to 'true' to enable running VCS PR plan/apply commands using PR comments. This can be set to 'true' (enabled) without setting alias in 'vcs_commands_alias'. Additional details: https://docs.env0.com/docs/plan-and-apply-from-pr-comments#configuration - `without_template_settings` (Block List, Max: 1) settings for creating an environment without a template (see [below for nested schema](#nestedblock--without_template_settings)) diff --git a/env0/resource_environment.go b/env0/resource_environment.go index cfd3d018..696b2d03 100644 --- a/env0/resource_environment.go +++ b/env0/resource_environment.go @@ -362,7 +362,7 @@ func resourceEnvironment() *schema.Resource { }, "variable_sets": { Type: schema.TypeList, - Description: "a list of variable set to assign to this environment. Note: must not be used with 'env0_variable_set_assignment'", + Description: "a list of IDs of variable sets to assign to this environment. Note: must not be used with 'env0_variable_set_assignment'", Optional: true, Elem: &schema.Schema{ Type: schema.TypeString, From 9581439e54e9fd44958f03177bb7661c7da49cdf Mon Sep 17 00:00:00 2001 From: Tomer Heber Date: Thu, 25 Jul 2024 16:24:28 -0500 Subject: [PATCH 03/10] Fix: env0_environment does not redeploy when revision is changed in without_template_settings (#907) --- env0/resource_environment.go | 13 +++++++++++-- env0/resource_environment_test.go | 7 +++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/env0/resource_environment.go b/env0/resource_environment.go index 696b2d03..71cc9ccf 100644 --- a/env0/resource_environment.go +++ b/env0/resource_environment.go @@ -732,6 +732,12 @@ func shouldUpdateTemplate(d *schema.ResourceData) bool { } func shouldDeploy(d *schema.ResourceData) bool { + if _, ok := d.GetOk("without_template_settings.0"); ok { + if d.HasChange("without_template_settings.0.revision") { + return true + } + } + return d.HasChanges("revision", "configuration", "sub_environment_configuration", "variable_sets") } @@ -1126,8 +1132,7 @@ func getDeployPayload(d *schema.ResourceData, apiClient client.ApiClientInterfac var err error if isTemplateless(d) { - templateId, ok := d.GetOk("without_template_settings.0.id") - if ok { + if templateId, ok := d.GetOk("without_template_settings.0.id"); ok { payload.BlueprintId = templateId.(string) } } else { @@ -1139,6 +1144,10 @@ func getDeployPayload(d *schema.ResourceData, apiClient client.ApiClientInterfac } if isRedeploy { + if revision, ok := d.GetOk("without_template_settings.0.revision"); ok { + payload.BlueprintRevision = revision.(string) + } + if configuration, ok := d.GetOk("configuration"); ok && isRedeploy { configurationChanges := getConfigurationVariablesFromSchema(configuration.([]interface{})) scope := client.ScopeEnvironment diff --git a/env0/resource_environment_test.go b/env0/resource_environment_test.go index ef2a0b16..13730cc5 100644 --- a/env0/resource_environment_test.go +++ b/env0/resource_environment_test.go @@ -2541,6 +2541,13 @@ func TestUnitEnvironmentWithoutTemplateResource(t *testing.T) { // Update mock.EXPECT().TemplateUpdate(template.Id, templateUpdatePayload).Times(1).Return(updatedTemplate, nil), + mock.EXPECT().ConfigurationSetsAssignments("ENVIRONMENT", environment.Id).Times(1).Return(nil, nil), + mock.EXPECT().EnvironmentDeploy(environment.Id, client.DeployRequest{ + BlueprintId: template.Id, + BlueprintRevision: updatedTemplate.Revision, + }).Times(1).Return(client.EnvironmentDeployResponse{ + Id: environment.Id, + }, nil), // Read mock.EXPECT().Environment(environment.Id).Times(1).Return(environment, nil), From 53688250324d8bd9b437dba099161f022a826d2b Mon Sep 17 00:00:00 2001 From: Tomer Heber Date: Fri, 26 Jul 2024 13:41:09 -0500 Subject: [PATCH 04/10] Feat: add token_name as a field for data env0_template (#903) --- client/template.go | 1 + env0/data_template.go | 20 +++++++++----------- env0/data_template_test.go | 2 ++ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/client/template.go b/client/template.go index 9f9e8691..0c7c9bf6 100644 --- a/client/template.go +++ b/client/template.go @@ -63,6 +63,7 @@ type Template struct { HelmChartName string `json:"helmChartName" tfschema:",omitempty"` IsGitLab bool `json:"isGitLab" tfschema:"is_gitlab"` TerragruntTfBinary string `json:"terragruntTfBinary" tfschema:",omitempty"` + TokenName string `json:"tokenName"` } type TemplateCreatePayload struct { diff --git a/env0/data_template.go b/env0/data_template.go index db1a2933..0ca36aba 100644 --- a/env0/data_template.go +++ b/env0/data_template.go @@ -84,12 +84,12 @@ func dataTemplate() *schema.Resource { "github_installation_id": { Type: schema.TypeInt, Description: "The env0 application installation id on the relevant github repository", - Optional: true, + Computed: true, }, "token_id": { Type: schema.TypeString, Description: "The token id used for private git repos or for integration with GitLab", - Optional: true, + Computed: true, }, "terraform_version": { Type: schema.TypeString, @@ -100,58 +100,56 @@ func dataTemplate() *schema.Resource { Type: schema.TypeString, Description: "terragrunt version to use", Computed: true, - Optional: true, }, "is_gitlab_enterprise": { Type: schema.TypeBool, Description: "Does this template use gitlab enterprise repository?", - Optional: true, Computed: true, }, "bitbucket_client_key": { Type: schema.TypeString, Description: "the bitbucket client key used for integration", - Optional: true, Computed: true, }, "is_bitbucket_server": { Type: schema.TypeBool, Description: "true if this template uses bitbucket server repository", - Optional: true, Computed: true, }, "is_github_enterprise": { Type: schema.TypeBool, Description: "true if this template uses github enterprise repository", - Optional: true, Computed: true, }, "is_azure_devops": { Type: schema.TypeBool, Description: "true if this template integrates with azure dev ops", - Optional: true, Computed: true, }, "ssh_keys": { Type: schema.TypeList, Description: "an array of references to 'data_ssh_key' to use when accessing git over ssh", - Optional: true, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "id": { Type: schema.TypeString, Description: "ssh key id", - Required: true, + Computed: true, }, "name": { Type: schema.TypeString, Description: "ssh key name", - Required: true, + Computed: true, }, }, }, }, + "token_name": { + Type: schema.TypeString, + Description: "the token name used for integration with GitLab", + Computed: true, + }, }, } } diff --git a/env0/data_template_test.go b/env0/data_template_test.go index d931b7d6..4f477307 100644 --- a/env0/data_template_test.go +++ b/env0/data_template_test.go @@ -42,6 +42,7 @@ func TestUnitTemplateData(t *testing.T) { }, IsBitbucketServer: true, IsAzureDevOps: true, + TokenName: "tokenname", } getValidTestCase := func(input map[string]interface{}) resource.TestCase { @@ -69,6 +70,7 @@ func TestUnitTemplateData(t *testing.T) { resource.TestCheckResourceAttr(resourceFullName, "ssh_keys.0.name", template.SshKeys[0].Name), resource.TestCheckResourceAttr(resourceFullName, "is_bitbucket_server", "true"), resource.TestCheckResourceAttr(resourceFullName, "is_azure_devops", "true"), + resource.TestCheckResourceAttr(resourceFullName, "token_name", template.TokenName), ), }, }, From a5e6cf30823721d95065c7dff28a4438a561d7b2 Mon Sep 17 00:00:00 2001 From: update generated docs action Date: Fri, 26 Jul 2024 18:42:03 +0000 Subject: [PATCH 05/10] Update docs --- docs/data-sources/template.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/docs/data-sources/template.md b/docs/data-sources/template.md index 99579c82..d9c3a308 100644 --- a/docs/data-sources/template.md +++ b/docs/data-sources/template.md @@ -23,21 +23,18 @@ data "env0_template" "example" { ### Optional -- `bitbucket_client_key` (String) the bitbucket client key used for integration -- `github_installation_id` (Number) The env0 application installation id on the relevant github repository - `id` (String) id of the template -- `is_azure_devops` (Boolean) true if this template integrates with azure dev ops -- `is_bitbucket_server` (Boolean) true if this template uses bitbucket server repository -- `is_github_enterprise` (Boolean) true if this template uses github enterprise repository -- `is_gitlab_enterprise` (Boolean) Does this template use gitlab enterprise repository? - `name` (String) the name of the template -- `ssh_keys` (Block List) an array of references to 'data_ssh_key' to use when accessing git over ssh (see [below for nested schema](#nestedblock--ssh_keys)) -- `terragrunt_version` (String) terragrunt version to use -- `token_id` (String) The token id used for private git repos or for integration with GitLab ### Read-Only +- `bitbucket_client_key` (String) the bitbucket client key used for integration - `description` (String) description for the template +- `github_installation_id` (Number) The env0 application installation id on the relevant github repository +- `is_azure_devops` (Boolean) true if this template integrates with azure dev ops +- `is_bitbucket_server` (Boolean) true if this template uses bitbucket server repository +- `is_github_enterprise` (Boolean) true if this template uses github enterprise repository +- `is_gitlab_enterprise` (Boolean) Does this template use gitlab enterprise repository? - `path` (String) terraform / terrgrunt folder inside source code repository - `project_ids` (List of String) which projects may access this template (id of project) - `repository` (String) template source code repository url @@ -46,13 +43,17 @@ data "env0_template" "example" { - `retry_on_deploy_only_when_matches_regex` (String) if specified, will only retry (on deploy) if error matches specified regex - `retry_on_destroy_only_when_matches_regex` (String) if specified, will only retry (on destroy) if error matches specified regex - `revision` (String) source code revision (branch / tag) to use +- `ssh_keys` (List of Object) an array of references to 'data_ssh_key' to use when accessing git over ssh (see [below for nested schema](#nestedatt--ssh_keys)) - `terraform_version` (String) terraform version to use +- `terragrunt_version` (String) terragrunt version to use +- `token_id` (String) The token id used for private git repos or for integration with GitLab +- `token_name` (String) the token name used for integration with GitLab - `type` (String) template type (allowed values: terraform, terragrunt, pulumi, k8s, workflow, cloudformation, helm, opentofu) - + ### Nested Schema for `ssh_keys` -Required: +Read-Only: -- `id` (String) ssh key id -- `name` (String) ssh key name +- `id` (String) +- `name` (String) From eefc91ba1312092362f8ea88350b50576ccbafc2 Mon Sep 17 00:00:00 2001 From: Tomer Heber Date: Fri, 26 Jul 2024 14:16:05 -0500 Subject: [PATCH 06/10] Feat: cannot create env0_environment without_template_settings for GitLab (#911) --- client/template.go | 4 ++-- env0/resource_template.go | 5 +++++ env0/resource_template_test.go | 13 +++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/client/template.go b/client/template.go index 0c7c9bf6..94c08a65 100644 --- a/client/template.go +++ b/client/template.go @@ -63,7 +63,7 @@ type Template struct { HelmChartName string `json:"helmChartName" tfschema:",omitempty"` IsGitLab bool `json:"isGitLab" tfschema:"is_gitlab"` TerragruntTfBinary string `json:"terragruntTfBinary" tfschema:",omitempty"` - TokenName string `json:"tokenName"` + TokenName string `json:"tokenName" tfschema:",omitempty"` } type TemplateCreatePayload struct { @@ -75,7 +75,7 @@ type TemplateCreatePayload struct { Repository string `json:"repository"` Path string `json:"path,omitempty"` IsGitLab bool `json:"isGitLab"` - TokenName string `json:"tokenName"` + TokenName string `json:"tokenName,omitempty"` TokenId string `json:"tokenId,omitempty"` GithubInstallationId int `json:"githubInstallationId,omitempty"` GitlabProjectId int `json:"gitlabProjectId,omitempty"` diff --git a/env0/resource_template.go b/env0/resource_template.go index 52eb2338..80e39c3e 100644 --- a/env0/resource_template.go +++ b/env0/resource_template.go @@ -244,6 +244,11 @@ func getTemplateSchema(prefix string) map[string]*schema.Schema { Description: "the binary to use if the template type is 'terragrunt'. Valid values 'opentofu' and 'terraform'. For new templates defaults to 'opentofu'", ValidateDiagFunc: NewStringInValidator([]string{"opentofu", "terraform"}), }, + "token_name": { + Type: schema.TypeString, + Optional: true, + Description: "token name for Gitlab", + }, } if prefix == "" { diff --git a/env0/resource_template_test.go b/env0/resource_template_test.go index 384377de..02307106 100644 --- a/env0/resource_template_test.go +++ b/env0/resource_template_test.go @@ -84,6 +84,7 @@ func TestUnitTemplateResource(t *testing.T) { Type: "terraform", TokenId: "1", TerraformVersion: "0.12.24", + TokenName: "token_name", } gitlabTemplateProjectId := 10 gitlabUpdatedTemplate := client.Template{ @@ -107,6 +108,7 @@ func TestUnitTemplateResource(t *testing.T) { TerragruntVersion: "0.26.1", TokenId: "2", TerraformVersion: "0.15.1", + TokenName: "token_name2", } gitlabTemplateUpdatedProjectId := 15 githubTemplate := client.Template{ @@ -487,6 +489,9 @@ func TestUnitTemplateResource(t *testing.T) { if template.TokenId != "" { templateAsDictionary["token_id"] = template.TokenId } + if template.TokenName != "" { + templateAsDictionary["token_name"] = template.TokenName + } if template.Id == gitlabTemplate.Id { if template.Name == gitlabUpdatedTemplate.Name { templateAsDictionary["gitlab_project_id"] = gitlabTemplateUpdatedProjectId @@ -575,6 +580,11 @@ func TestUnitTemplateResource(t *testing.T) { pathAssertion = resource.TestCheckNoResourceAttr(resourceFullName, "path") } + tokenNameAssertion := resource.TestCheckResourceAttr(resourceFullName, "token_name", template.TokenName) + if template.TokenName == "" { + tokenNameAssertion = resource.TestCheckNoResourceAttr(resourceFullName, "token_name") + } + return resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(resourceFullName, "id", template.Id), resource.TestCheckResourceAttr(resourceFullName, "name", template.Name), @@ -598,6 +608,7 @@ func TestUnitTemplateResource(t *testing.T) { resource.TestCheckResourceAttr(resourceFullName, "is_terragrunt_run_all", strconv.FormatBool(template.IsTerragruntRunAll)), resource.TestCheckResourceAttr(resourceFullName, "is_azure_devops", strconv.FormatBool(template.IsAzureDevOps)), resource.TestCheckResourceAttr(resourceFullName, "is_helm_repository", strconv.FormatBool(template.IsHelmRepository)), + tokenNameAssertion, ) } @@ -651,6 +662,7 @@ func TestUnitTemplateResource(t *testing.T) { IsHelmRepository: templateUseCase.template.IsHelmRepository, HelmChartName: templateUseCase.template.HelmChartName, OpentofuVersion: templateUseCase.template.OpentofuVersion, + TokenName: templateUseCase.template.TokenName, } updateTemplateCreateTemplate := client.TemplateCreatePayload{ @@ -677,6 +689,7 @@ func TestUnitTemplateResource(t *testing.T) { IsHelmRepository: templateUseCase.updatedTemplate.IsHelmRepository, HelmChartName: templateUseCase.updatedTemplate.HelmChartName, OpentofuVersion: templateUseCase.updatedTemplate.OpentofuVersion, + TokenName: templateUseCase.updatedTemplate.TokenName, } if templateUseCase.template.Type == "terragrunt" { From 6545da9c64b3b9895407e664d1f846f50668d13c Mon Sep 17 00:00:00 2001 From: update generated docs action Date: Fri, 26 Jul 2024 19:16:57 +0000 Subject: [PATCH 07/10] Update docs --- docs/resources/environment.md | 1 + docs/resources/template.md | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/resources/environment.md b/docs/resources/environment.md index b76acd04..0779d069 100644 --- a/docs/resources/environment.md +++ b/docs/resources/environment.md @@ -188,6 +188,7 @@ Optional: - `terragrunt_tf_binary` (String) the binary to use if the template type is 'terragrunt'. Valid values 'opentofu' and 'terraform'. For new templates defaults to 'opentofu' - `terragrunt_version` (String) the Terragrunt version to use (example: 0.36.5) - `token_id` (String) the git token id to be used +- `token_name` (String) token name for Gitlab - `type` (String) template type (allowed values: terraform, terragrunt, pulumi, k8s, workflow, cloudformation, helm, opentofu) Read-Only: diff --git a/docs/resources/template.md b/docs/resources/template.md index 273365c2..bb3030f8 100644 --- a/docs/resources/template.md +++ b/docs/resources/template.md @@ -87,6 +87,7 @@ resource "env0_template_project_assignment" "assignment" { - `terragrunt_tf_binary` (String) the binary to use if the template type is 'terragrunt'. Valid values 'opentofu' and 'terraform'. For new templates defaults to 'opentofu' - `terragrunt_version` (String) the Terragrunt version to use (example: 0.36.5) - `token_id` (String) the git token id to be used +- `token_name` (String) token name for Gitlab - `type` (String) template type (allowed values: terraform, terragrunt, pulumi, k8s, workflow, cloudformation, helm, opentofu) ### Read-Only From 0c906ea9d129e3a21252d4a1f847a6ef2c5da7b9 Mon Sep 17 00:00:00 2001 From: Tomer Heber Date: Mon, 29 Jul 2024 09:30:17 -0500 Subject: [PATCH 08/10] Fix: Drift Notification for Variable Sets (due to ordering) in env0_environment (#910) --- env0/resource_environment.go | 29 ++++++++++++++++++++++++++++- env0/resource_environment_test.go | 16 ++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/env0/resource_environment.go b/env0/resource_environment.go index 71cc9ccf..f7f8dfb1 100644 --- a/env0/resource_environment.go +++ b/env0/resource_environment.go @@ -446,7 +446,34 @@ func setEnvironmentSchema(ctx context.Context, d *schema.ResourceData, environme setEnvironmentConfigurationSchema(ctx, d, configurationVariables) if d.Get("variable_sets") != nil { - if err := d.Set("variable_sets", variableSetsIds); err != nil { + // To avoid drifts keep the schema order as much as possible. + variableSetsFromSchema := getEnvironmentVariableSetIdsFromSchema(d) + sortedVariablesSet := []string{} + + for _, schemav := range variableSetsFromSchema { + for _, newv := range variableSetsIds { + if schemav == newv { + sortedVariablesSet = append(sortedVariablesSet, schemav) + break + } + } + } + + for _, newv := range variableSetsIds { + found := false + for _, sortedv := range sortedVariablesSet { + if newv == sortedv { + found = true + break + } + } + + if !found { + sortedVariablesSet = append(sortedVariablesSet, newv) + } + } + + if err := d.Set("variable_sets", sortedVariablesSet); err != nil { return fmt.Errorf("failed to set variable_sets value: %w", err) } } diff --git a/env0/resource_environment_test.go b/env0/resource_environment_test.go index 13730cc5..7bd060d9 100644 --- a/env0/resource_environment_test.go +++ b/env0/resource_environment_test.go @@ -371,6 +371,18 @@ func TestUnitEnvironmentResource(t *testing.T) { } updatedConfigurationSets := []client.ConfigurationSet{ + { + Id: "id2", + AssignmentScope: "ENVIRONMENT", + }, + { + Id: "id3", + AssignmentScope: "ENVIRONMENT", + }, + } + + // Same as updatedConfigurationSets, but in a different order. + updatedConfigurationSets2 := []client.ConfigurationSet{ { Id: "id3", AssignmentScope: "ENVIRONMENT", @@ -398,7 +410,7 @@ func TestUnitEnvironmentResource(t *testing.T) { environmentDeployRequest := client.DeployRequest{ BlueprintId: environment.LatestDeploymentLog.BlueprintId, ConfigurationSetChanges: &client.ConfigurationSetChanges{ - Assign: []string{updatedConfigurationSets[0].Id}, + Assign: []string{updatedConfigurationSets[1].Id}, Unassign: []string{configurationSets[0].Id}, }, } @@ -465,7 +477,7 @@ func TestUnitEnvironmentResource(t *testing.T) { mock.EXPECT().Environment(environment.Id).Times(1).Return(environment, nil), mock.EXPECT().ConfigurationVariablesByScope(client.ScopeEnvironment, environment.Id).Times(1).Return(client.ConfigurationChanges{}, nil), - mock.EXPECT().ConfigurationSetsAssignments("ENVIRONMENT", environment.Id).Times(1).Return(updatedConfigurationSets, nil), + mock.EXPECT().ConfigurationSetsAssignments("ENVIRONMENT", environment.Id).Times(1).Return(updatedConfigurationSets2, nil), mock.EXPECT().EnvironmentDestroy(environment.Id).Times(1), ) From 56f68091fae40710c6b9f73960ff71e128e67bea Mon Sep 17 00:00:00 2001 From: Andrew Way Date: Mon, 29 Jul 2024 08:42:36 -0700 Subject: [PATCH 09/10] chore: make moduleProvider required (#912) --- env0/resource_module.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env0/resource_module.go b/env0/resource_module.go index 097c52a8..6a0adae2 100644 --- a/env0/resource_module.go +++ b/env0/resource_module.go @@ -36,7 +36,7 @@ func resourceModule() *schema.Resource { "module_provider": { Type: schema.TypeString, Description: "the provider name in the module source (Match pattern: ^[0-9a-z]{0,64}$)", - Optional: true, + Required: true, ValidateDiagFunc: NewRegexValidator(`^[0-9a-z]{0,64}$`), }, "repository": { From e7b53a156e3e687993d1a66248f651d87e495597 Mon Sep 17 00:00:00 2001 From: update generated docs action Date: Mon, 29 Jul 2024 15:43:10 +0000 Subject: [PATCH 10/10] Update docs --- docs/resources/module.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/resources/module.md b/docs/resources/module.md index 7b4a081f..f999e31a 100644 --- a/docs/resources/module.md +++ b/docs/resources/module.md @@ -28,6 +28,7 @@ resource "env0_module" "example" { ### Required - `module_name` (String) name of the module (Match pattern: ^[0-9A-Za-z](?:[0-9A-Za-z-_]{0,62}[0-9A-Za-z])?$) +- `module_provider` (String) the provider name in the module source (Match pattern: ^[0-9a-z]{0,64}$) - `repository` (String) the repository containing the module files ### Optional @@ -36,7 +37,6 @@ resource "env0_module" "example" { - `description` (String) description of the module - `github_installation_id` (Number) the env0 application installation id on the relevant Github repository - `is_azure_devops` (Boolean) true if this module integrates with azure dev ops -- `module_provider` (String) the provider name in the module source (Match pattern: ^[0-9a-z]{0,64}$) - `module_test_enabled` (Boolean) set to 'true' to enable module test (defaults to 'false') - `opentofu_version` (String) the opentofu version to use, Can only be set if 'module_test_enabled' is enabled - `path` (String) the folder in the repository to create the module from