diff --git a/client/model.go b/client/model.go index 708bc5e9..1b3e9a71 100644 --- a/client/model.go +++ b/client/model.go @@ -219,6 +219,7 @@ type TemplateCreatePayload struct { Revision string `json:"revision"` OrganizationId string `json:"organizationId"` TerraformVersion string `json:"terraformVersion"` + IsGitlabEnterprise bool `json:"isGitLabEnterprise"` } type TemplateAssignmentToProjectPayload struct { @@ -263,6 +264,7 @@ type Template struct { SshKeys []TemplateSshKey `json:"sshKeys"` Type string `json:"type"` GithubInstallationId int `json:"githubInstallationId"` + IsGitlabEnterprise bool `json:"isGitLabEnterprise"` TokenId string `json:"tokenId,omitempty"` GitlabProjectId int `json:"gitlabProjectId,omitempty"` UpdatedAt string `json:"updatedAt"` diff --git a/docs/resources/environment_scheduling.md b/docs/resources/environment_scheduling.md index b7bd1da6..f7e7f2c3 100644 --- a/docs/resources/environment_scheduling.md +++ b/docs/resources/environment_scheduling.md @@ -19,8 +19,8 @@ data "env0_environment" "example" { resource "env0_environment_schedling" "example" { environment_id = data.env0_environment.example.id - deploy_cron = "5 * * * *" - destroy_cron = "10 * * * *" + deploy_cron = "5 * * * *" + destroy_cron = "10 * * * *" } ``` diff --git a/docs/resources/template.md b/docs/resources/template.md index c2bafeb5..e31dfd84 100644 --- a/docs/resources/template.md +++ b/docs/resources/template.md @@ -49,6 +49,7 @@ resource "env0_template_project_assignment" "assignment" { - **github_installation_id** (Number) The env0 application installation id on the relevant github repository - **gitlab_project_id** (Number) The project id of the relevant repository - **id** (String) The ID of this resource. +- **is_gitlab_enterprise** (Boolean) Does this template use gitlab enterprise repository? - **path** (String) terraform / terragrunt file folder inside source code - **retries_on_deploy** (Number) number of times to retry when deploying an environment based on this template - **retries_on_destroy** (Number) number of times to retry when destroying an environment based on this template diff --git a/env0/data_template.go b/env0/data_template.go index b77811c1..df4b85a4 100644 --- a/env0/data_template.go +++ b/env0/data_template.go @@ -94,6 +94,12 @@ func dataTemplate() *schema.Resource { Description: "terraform version to use", Computed: true, }, + "is_gitlab_enterprise": { + Type: schema.TypeBool, + Description: "Does this template use gitlab enterprise repository?", + Optional: true, + Computed: true, + }, }, } } @@ -148,6 +154,10 @@ func dataTemplateRead(ctx context.Context, d *schema.ResourceData, meta interfac d.Set("gitlab_project_id", template.GitlabProjectId) } + if template.IsGitlabEnterprise == true { + d.Set("is_gitlab_enterprise", template.IsGitlabEnterprise) + } + return nil } diff --git a/env0/resource_template.go b/env0/resource_template.go index a8eb72fc..6c9e8322 100644 --- a/env0/resource_template.go +++ b/env0/resource_template.go @@ -95,19 +95,23 @@ func resourceTemplate() *schema.Resource { RequiredWith: []string{"retries_on_destroy"}, }, "github_installation_id": { - Type: schema.TypeInt, - Description: "The env0 application installation id on the relevant github repository", - Optional: true, + Type: schema.TypeInt, + Description: "The env0 application installation id on the relevant github repository", + Optional: true, + ConflictsWith: []string{"token_id"}, }, "token_id": { - Type: schema.TypeString, - Description: "The token id used for private git repos or for integration with GitLab, you can get this value by using a data resource of an existing Gitlab template or contact our support team", - Optional: true, + Type: schema.TypeString, + Description: "The token id used for private git repos or for integration with GitLab, you can get this value by using a data resource of an existing Gitlab template or contact our support team", + Optional: true, + RequiredWith: []string{"gitlab_project_id"}, + ConflictsWith: []string{"github_installation_id"}, }, "gitlab_project_id": { - Type: schema.TypeInt, - Description: "The project id of the relevant repository", - Optional: true, + Type: schema.TypeInt, + Description: "The project id of the relevant repository", + Optional: true, + RequiredWith: []string{"token_id"}, }, "terraform_version": { Type: schema.TypeString, @@ -115,6 +119,13 @@ func resourceTemplate() *schema.Resource { Optional: true, Default: "0.15.1", }, + "is_gitlab_enterprise": { + Type: schema.TypeBool, + Description: "Does this template use gitlab enterprise repository?", + Optional: true, + Default: "false", + ConflictsWith: []string{"gitlab_project_id", "token_id", "github_installation_id"}, + }, }, } } @@ -132,20 +143,12 @@ func templateCreatePayloadFromParameters(d *schema.ResourceData) (client.Templat } if tokenId, ok := d.GetOk("token_id"); ok { result.TokenId = tokenId.(string) - } - if gitlabProjectId, ok := d.GetOk("gitlab_project_id"); ok { - result.GitlabProjectId = gitlabProjectId.(int) - } - - if result.GitlabProjectId != 0 && result.TokenId == "" { - return client.TemplateCreatePayload{}, diag.Errorf("Cannot set gitlab_project_id without token_id") - } - - if result.GithubInstallationId != 0 && result.TokenId != "" { - return client.TemplateCreatePayload{}, diag.Errorf("Cannot set token_id and github_installation_id for the same template") - } else { + result.GitlabProjectId = d.Get("gitlab_project_id").(int) result.IsGitLab = result.TokenId != "" } + if isGitlabEnterprise, ok := d.GetOk("is_gitlab_enterprise"); ok { + result.IsGitlabEnterprise = isGitlabEnterprise.(bool) + } if path, ok := d.GetOk("path"); ok { result.Path = path.(string) @@ -246,8 +249,12 @@ func resourceTemplateRead(ctx context.Context, d *schema.ResourceData, meta inte d.Set("name", template.Name) d.Set("description", template.Description) - d.Set("github_installation_id", template.GithubInstallationId) - d.Set("token_id", template.TokenId) + if template.GithubInstallationId != 0 { + d.Set("github_installation_id", template.GithubInstallationId) + } + if template.TokenId != "" { + d.Set("token_id", template.TokenId) + } d.Set("repository", template.Repository) d.Set("path", template.Path) d.Set("revision", template.Revision) diff --git a/env0/resource_template_test.go b/env0/resource_template_test.go index 91365198..4308b730 100644 --- a/env0/resource_template_test.go +++ b/env0/resource_template_test.go @@ -17,6 +17,134 @@ func TestUnitTemplateResource(t *testing.T) { const defaultType = client.TemplateTypeTerraform var resourceFullName = resourceAccessor(resourceType, resourceName) + gleeTemplate := client.Template{ + Id: "id0", + Name: "template0", + Description: "description0", + Repository: "env0/repo", + Path: "path/zero", + Revision: "branch-zero", + Retry: client.TemplateRetry{ + OnDeploy: &client.TemplateRetryOn{ + Times: 2, + ErrorRegex: "RetryMeForDeploy.*", + }, + OnDestroy: &client.TemplateRetryOn{ + Times: 1, + ErrorRegex: "RetryMeForDestroy.*", + }, + }, + Type: "terraform", + IsGitlabEnterprise: true, + TerraformVersion: "0.12.24", + } + gleeUpdatedTemplate := client.Template{ + Id: gleeTemplate.Id, + Name: "new-name", + Description: "new-description", + Repository: "env0/repo-new", + Path: "path/zero/new", + Revision: "branch-zero-new", + Retry: client.TemplateRetry{ + OnDeploy: &client.TemplateRetryOn{ + Times: 1, + ErrorRegex: "NewForDeploy.*", + }, + OnDestroy: &client.TemplateRetryOn{ + Times: 2, + ErrorRegex: "NewForDestroy.*", + }, + }, + Type: "terragrunt", + IsGitlabEnterprise: true, + TerraformVersion: "0.15.1", + } + gitlabTemplate := client.Template{ + Id: "id0", + Name: "template0", + Description: "description0", + Repository: "env0/repo", + Path: "path/zero", + Revision: "branch-zero", + Retry: client.TemplateRetry{ + OnDeploy: &client.TemplateRetryOn{ + Times: 2, + ErrorRegex: "RetryMeForDeploy.*", + }, + OnDestroy: &client.TemplateRetryOn{ + Times: 1, + ErrorRegex: "RetryMeForDestroy.*", + }, + }, + Type: "terraform", + TokenId: "1", + GitlabProjectId: 10, + TerraformVersion: "0.12.24", + } + gitlabUpdatedTemplate := client.Template{ + Id: gitlabTemplate.Id, + Name: "new-name", + Description: "new-description", + Repository: "env0/repo-new", + Path: "path/zero/new", + Revision: "branch-zero-new", + Retry: client.TemplateRetry{ + OnDeploy: &client.TemplateRetryOn{ + Times: 1, + ErrorRegex: "NewForDeploy.*", + }, + OnDestroy: &client.TemplateRetryOn{ + Times: 2, + ErrorRegex: "NewForDestroy.*", + }, + }, + Type: "terragrunt", + TokenId: "2", + GitlabProjectId: 2, + TerraformVersion: "0.15.1", + } + githubTemplate := client.Template{ + Id: "id0", + Name: "template0", + Description: "description0", + Repository: "env0/repo", + Path: "path/zero", + Revision: "branch-zero", + Retry: client.TemplateRetry{ + OnDeploy: &client.TemplateRetryOn{ + Times: 2, + ErrorRegex: "RetryMeForDeploy.*", + }, + OnDestroy: &client.TemplateRetryOn{ + Times: 1, + ErrorRegex: "RetryMeForDestroy.*", + }, + }, + Type: "terraform", + GithubInstallationId: 1, + TerraformVersion: "0.12.24", + } + githubUpdatedTemplate := client.Template{ + Id: githubTemplate.Id, + Name: "new-name", + Description: "new-description", + Repository: "env0/repo-new", + Path: "path/zero/new", + Revision: "branch-zero-new", + Retry: client.TemplateRetry{ + OnDeploy: &client.TemplateRetryOn{ + Times: 1, + ErrorRegex: "NewForDeploy.*", + }, + OnDestroy: &client.TemplateRetryOn{ + Times: 2, + ErrorRegex: "NewForDestroy.*", + }, + }, + Type: "terragrunt", + GithubInstallationId: 2, + TerraformVersion: "0.15.1", + } fullTemplateResourceConfig := func(resourceType string, resourceName string, template client.Template) string { templateAsDictionary := map[string]interface{}{ @@ -60,231 +188,113 @@ func TestUnitTemplateResource(t *testing.T) { if template.GithubInstallationId != 0 { templateAsDictionary["github_installation_id"] = template.GithubInstallationId } + if template.IsGitlabEnterprise != false { + templateAsDictionary["is_gitlab_enterprise"] = template.IsGitlabEnterprise + } return resourceConfigCreate(resourceType, resourceName, templateAsDictionary) } + fullTemplateResourceCheck := func(resourceFullName string, template client.Template) resource.TestCheckFunc { + gitlabProjectIdAssertion := resource.TestCheckResourceAttr(resourceFullName, "gitlab_project_id", strconv.Itoa(template.GitlabProjectId)) + if template.GitlabProjectId == 0 { + gitlabProjectIdAssertion = resource.TestCheckNoResourceAttr(resourceFullName, "gitlab_project_id") + } + + tokenIdAssertion := resource.TestCheckResourceAttr(resourceFullName, "token_id", template.TokenId) + if template.TokenId == "" { + tokenIdAssertion = resource.TestCheckNoResourceAttr(resourceFullName, "token_id") + } + + githubInstallationIdAssertion := resource.TestCheckResourceAttr(resourceFullName, "github_installation_id", strconv.Itoa(template.GithubInstallationId)) + if template.GithubInstallationId == 0 { + githubInstallationIdAssertion = resource.TestCheckNoResourceAttr(resourceFullName, "github_installation_id") + } + + return resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(resourceFullName, "id", template.Id), + resource.TestCheckResourceAttr(resourceFullName, "name", template.Name), + resource.TestCheckResourceAttr(resourceFullName, "description", template.Description), + resource.TestCheckResourceAttr(resourceFullName, "repository", template.Repository), + resource.TestCheckResourceAttr(resourceFullName, "path", template.Path), + resource.TestCheckResourceAttr(resourceFullName, "type", template.Type), + resource.TestCheckResourceAttr(resourceFullName, "retries_on_deploy", strconv.Itoa(template.Retry.OnDeploy.Times)), + resource.TestCheckResourceAttr(resourceFullName, "retry_on_deploy_only_when_matches_regex", template.Retry.OnDeploy.ErrorRegex), + resource.TestCheckResourceAttr(resourceFullName, "retries_on_destroy", strconv.Itoa(template.Retry.OnDestroy.Times)), + resource.TestCheckResourceAttr(resourceFullName, "retry_on_destroy_only_when_matches_regex", template.Retry.OnDestroy.ErrorRegex), + resource.TestCheckResourceAttr(resourceFullName, "is_gitlab_enterprise", strconv.FormatBool(template.IsGitlabEnterprise)), + tokenIdAssertion, + gitlabProjectIdAssertion, + githubInstallationIdAssertion, + resource.TestCheckResourceAttr(resourceFullName, "terraform_version", template.TerraformVersion), + ) + } - t.Run("Full Github template (without SSH keys)", func(t *testing.T) { - template := client.Template{ - Id: "id0", - Name: "template0", - Description: "description0", - Repository: "env0/repo", - Path: "path/zero", - Revision: "branch-zero", - Retry: client.TemplateRetry{ - OnDeploy: &client.TemplateRetryOn{ - Times: 2, - ErrorRegex: "RetryMeForDeploy.*", - }, - OnDestroy: &client.TemplateRetryOn{ - Times: 1, - ErrorRegex: "RetryMeForDestroy.*", - }, - }, - Type: "terraform", - GithubInstallationId: 1, - TerraformVersion: "0.12.24", - } - - updatedTemplate := client.Template{ - Id: template.Id, - Name: "new-name", - Description: "new-description", - Repository: "env0/repo-new", - Path: "path/zero/new", - Revision: "branch-zero-new", - Retry: client.TemplateRetry{ - OnDeploy: &client.TemplateRetryOn{ - Times: 1, - ErrorRegex: "NewForDeploy.*", - }, - OnDestroy: &client.TemplateRetryOn{ - Times: 2, - ErrorRegex: "NewForDestroy.*", - }, - }, - Type: "terragrunt", - GithubInstallationId: 2, - TerraformVersion: "0.15.1", - } - - fullTemplateResourceCheck := func(resourceFullName string, template client.Template) resource.TestCheckFunc { - return resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(resourceFullName, "id", template.Id), - resource.TestCheckResourceAttr(resourceFullName, "name", template.Name), - resource.TestCheckResourceAttr(resourceFullName, "description", template.Description), - resource.TestCheckResourceAttr(resourceFullName, "repository", template.Repository), - resource.TestCheckResourceAttr(resourceFullName, "path", template.Path), - resource.TestCheckResourceAttr(resourceFullName, "type", template.Type), - resource.TestCheckResourceAttr(resourceFullName, "retries_on_deploy", strconv.Itoa(template.Retry.OnDeploy.Times)), - resource.TestCheckResourceAttr(resourceFullName, "retry_on_deploy_only_when_matches_regex", template.Retry.OnDeploy.ErrorRegex), - resource.TestCheckResourceAttr(resourceFullName, "retries_on_destroy", strconv.Itoa(template.Retry.OnDestroy.Times)), - resource.TestCheckResourceAttr(resourceFullName, "retry_on_destroy_only_when_matches_regex", template.Retry.OnDestroy.ErrorRegex), - resource.TestCheckResourceAttr(resourceFullName, "github_installation_id", strconv.Itoa(template.GithubInstallationId)), - resource.TestCheckResourceAttr(resourceFullName, "terraform_version", template.TerraformVersion), - ) - } - - testCase := resource.TestCase{ - Steps: []resource.TestStep{ - { - Config: fullTemplateResourceConfig(resourceType, resourceName, template), - Check: fullTemplateResourceCheck(resourceFullName, template), - }, - { - Config: fullTemplateResourceConfig(resourceType, resourceName, updatedTemplate), - Check: fullTemplateResourceCheck(resourceFullName, updatedTemplate), - }, - }, - } - - runUnitTest(t, testCase, func(mock *client.MockApiClientInterface) { - gomock.InOrder( - mock.EXPECT().Template(template.Id).Times(2).Return(template, nil), // 1 after create, 1 before update - mock.EXPECT().Template(template.Id).Times(1).Return(updatedTemplate, nil), // 1 after update - ) - mock.EXPECT().TemplateCreate(client.TemplateCreatePayload{ - Name: template.Name, - Repository: template.Repository, - Description: template.Description, - GithubInstallationId: template.GithubInstallationId, - IsGitLab: false, - Path: template.Path, - Revision: template.Revision, + var templateUseCases = []struct { + vcs string + template client.Template + updatedTemplate client.Template + }{ + {"GitLab EE", gleeTemplate, gleeUpdatedTemplate}, + {"GitLab", gitlabTemplate, gitlabUpdatedTemplate}, + {"GitHub", githubTemplate, githubUpdatedTemplate}, + } + for _, templateUseCase := range templateUseCases { + t.Run("Full "+templateUseCase.vcs+" template (without SSH keys)", func(t *testing.T) { + templateCreatePayload := client.TemplateCreatePayload{ + Name: templateUseCase.template.Name, + Repository: templateUseCase.template.Repository, + Description: templateUseCase.template.Description, + GithubInstallationId: templateUseCase.template.GithubInstallationId, + IsGitlabEnterprise: templateUseCase.template.IsGitlabEnterprise, + IsGitLab: templateUseCase.template.TokenId != "", + GitlabProjectId: templateUseCase.template.GitlabProjectId, + TokenId: templateUseCase.template.TokenId, + Path: templateUseCase.template.Path, + Revision: templateUseCase.template.Revision, Type: client.TemplateTypeTerraform, - Retry: template.Retry, - TerraformVersion: template.TerraformVersion, - }).Times(1).Return(template, nil) - mock.EXPECT().TemplateUpdate(template.Id, client.TemplateCreatePayload{ - Name: updatedTemplate.Name, - Repository: updatedTemplate.Repository, - Description: updatedTemplate.Description, - GithubInstallationId: updatedTemplate.GithubInstallationId, - IsGitLab: false, - Path: updatedTemplate.Path, - Revision: updatedTemplate.Revision, + Retry: templateUseCase.template.Retry, + TerraformVersion: templateUseCase.template.TerraformVersion, + } + updateTemplateCreateTemplate := client.TemplateCreatePayload{ + Name: templateUseCase.updatedTemplate.Name, + Repository: templateUseCase.updatedTemplate.Repository, + Description: templateUseCase.updatedTemplate.Description, + GithubInstallationId: templateUseCase.updatedTemplate.GithubInstallationId, + IsGitlabEnterprise: templateUseCase.updatedTemplate.IsGitlabEnterprise, + IsGitLab: templateUseCase.updatedTemplate.TokenId != "", + GitlabProjectId: templateUseCase.updatedTemplate.GitlabProjectId, + TokenId: templateUseCase.updatedTemplate.TokenId, + Path: templateUseCase.updatedTemplate.Path, + Revision: templateUseCase.updatedTemplate.Revision, Type: client.TemplateTypeTerragrunt, - Retry: updatedTemplate.Retry, - TerraformVersion: updatedTemplate.TerraformVersion, - }).Times(1).Return(updatedTemplate, nil) - mock.EXPECT().TemplateDelete(template.Id).Times(1).Return(nil) - }) - }) - - t.Run("Full Gitlab template (without SSH keys)", func(t *testing.T) { - template := client.Template{ - Id: "id0", - Name: "template0", - Description: "description0", - Repository: "env0/repo", - Path: "path/zero", - Revision: "branch-zero", - Retry: client.TemplateRetry{ - OnDeploy: &client.TemplateRetryOn{ - Times: 2, - ErrorRegex: "RetryMeForDeploy.*", - }, - OnDestroy: &client.TemplateRetryOn{ - Times: 1, - ErrorRegex: "RetryMeForDestroy.*", - }, - }, - Type: "terraform", - TokenId: "1", - GitlabProjectId: 10, - TerraformVersion: "0.12.24", - } - - updatedTemplate := client.Template{ - Id: template.Id, - Name: "new-name", - Description: "new-description", - Repository: "env0/repo-new", - Path: "path/zero/new", - Revision: "branch-zero-new", - Retry: client.TemplateRetry{ - OnDeploy: &client.TemplateRetryOn{ - Times: 1, - ErrorRegex: "NewForDeploy.*", - }, - OnDestroy: &client.TemplateRetryOn{ - Times: 2, - ErrorRegex: "NewForDestroy.*", - }, - }, - Type: "terragrunt", - TokenId: "2", - GitlabProjectId: 2, - TerraformVersion: "0.15.1", - } - - fullTemplateResourceCheck := func(resourceFullName string, template client.Template) resource.TestCheckFunc { - return resource.ComposeAggregateTestCheckFunc( - resource.TestCheckResourceAttr(resourceFullName, "id", template.Id), - resource.TestCheckResourceAttr(resourceFullName, "name", template.Name), - resource.TestCheckResourceAttr(resourceFullName, "description", template.Description), - resource.TestCheckResourceAttr(resourceFullName, "repository", template.Repository), - resource.TestCheckResourceAttr(resourceFullName, "path", template.Path), - resource.TestCheckResourceAttr(resourceFullName, "type", template.Type), - resource.TestCheckResourceAttr(resourceFullName, "retries_on_deploy", strconv.Itoa(template.Retry.OnDeploy.Times)), - resource.TestCheckResourceAttr(resourceFullName, "retry_on_deploy_only_when_matches_regex", template.Retry.OnDeploy.ErrorRegex), - resource.TestCheckResourceAttr(resourceFullName, "retries_on_destroy", strconv.Itoa(template.Retry.OnDestroy.Times)), - resource.TestCheckResourceAttr(resourceFullName, "retry_on_destroy_only_when_matches_regex", template.Retry.OnDestroy.ErrorRegex), - resource.TestCheckResourceAttr(resourceFullName, "token_id", template.TokenId), - resource.TestCheckResourceAttr(resourceFullName, "gitlab_project_id", strconv.Itoa(template.GitlabProjectId)), - resource.TestCheckResourceAttr(resourceFullName, "terraform_version", template.TerraformVersion), - ) - } + Retry: templateUseCase.updatedTemplate.Retry, + TerraformVersion: templateUseCase.updatedTemplate.TerraformVersion, + } - testCase := resource.TestCase{ - Steps: []resource.TestStep{ - { - Config: fullTemplateResourceConfig(resourceType, resourceName, template), - Check: fullTemplateResourceCheck(resourceFullName, template), - }, - { - Config: fullTemplateResourceConfig(resourceType, resourceName, updatedTemplate), - Check: fullTemplateResourceCheck(resourceFullName, updatedTemplate), + testCase := resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: fullTemplateResourceConfig(resourceType, resourceName, templateUseCase.template), + Check: fullTemplateResourceCheck(resourceFullName, templateUseCase.template), + }, + { + Config: fullTemplateResourceConfig(resourceType, resourceName, templateUseCase.updatedTemplate), + Check: fullTemplateResourceCheck(resourceFullName, templateUseCase.updatedTemplate), + }, }, - }, - } + } - runUnitTest(t, testCase, func(mock *client.MockApiClientInterface) { - gomock.InOrder( - mock.EXPECT().Template(template.Id).Times(2).Return(template, nil), // 1 after create, 1 before update - mock.EXPECT().Template(template.Id).Times(1).Return(updatedTemplate, nil), // 1 after update - ) - mock.EXPECT().TemplateCreate(client.TemplateCreatePayload{ - Name: template.Name, - Repository: template.Repository, - Description: template.Description, - TokenId: template.TokenId, - GitlabProjectId: template.GitlabProjectId, - IsGitLab: true, - Path: template.Path, - Revision: template.Revision, - Type: client.TemplateTypeTerraform, - Retry: template.Retry, - TerraformVersion: template.TerraformVersion, - }).Times(1).Return(template, nil) - mock.EXPECT().TemplateUpdate(template.Id, client.TemplateCreatePayload{ - Name: updatedTemplate.Name, - Repository: updatedTemplate.Repository, - Description: updatedTemplate.Description, - TokenId: updatedTemplate.TokenId, - GitlabProjectId: updatedTemplate.GitlabProjectId, - IsGitLab: true, - Path: updatedTemplate.Path, - Revision: updatedTemplate.Revision, - Type: client.TemplateTypeTerragrunt, - Retry: updatedTemplate.Retry, - TerraformVersion: updatedTemplate.TerraformVersion, - }).Times(1).Return(updatedTemplate, nil) - mock.EXPECT().TemplateDelete(template.Id).Times(1).Return(nil) + runUnitTest(t, testCase, func(mock *client.MockApiClientInterface) { + gomock.InOrder( + mock.EXPECT().Template(templateUseCase.template.Id).Times(2).Return(templateUseCase.template, nil), // 1 after create, 1 before update + mock.EXPECT().Template(templateUseCase.template.Id).Times(1).Return(templateUseCase.updatedTemplate, nil), // 1 after update + ) + mock.EXPECT().TemplateCreate(templateCreatePayload).Times(1).Return(templateUseCase.template, nil) + mock.EXPECT().TemplateUpdate(templateUseCase.updatedTemplate.Id, updateTemplateCreateTemplate).Times(1).Return(templateUseCase.updatedTemplate, nil) + mock.EXPECT().TemplateDelete(templateUseCase.updatedTemplate.Id).Times(1).Return(nil) + }) }) - }) - + } t.Run("Basic template", func(t *testing.T) { template := client.Template{ Id: "id0", @@ -505,22 +515,34 @@ func TestUnitTemplateResource(t *testing.T) { } }) - t.Run("Mixed Gitlab and Github template", func(t *testing.T) { - var testCases []resource.TestCase + var mixedUsecases = []struct { + firstVcs string + secondVcs string + tfObject map[string]interface{} + exception string + }{ + {"GitLab", "GitHub", map[string]interface{}{"name": "test", "repository": "env0/test", "github_installation_id": 1, "token_id": "2"}, "\"github_installation_id\": conflicts with token_id"}, + {"GitLab", "GitLab EE", map[string]interface{}{"name": "test", "repository": "env0/test", "token_id": "2", "is_gitlab_enterprise": "true"}, "\"is_gitlab_enterprise\": conflicts with token_id"}, + {"GitHub", "GitLab EE", map[string]interface{}{"name": "test", "repository": "env0/test", "github_installation_id": 1, "is_gitlab_enterprise": "true"}, "\"is_gitlab_enterprise\": conflicts with github_installation_id"}, + } + for _, mixUseCase := range mixedUsecases { + t.Run("Mixed "+mixUseCase.firstVcs+" and "+mixUseCase.secondVcs+" template", func(t *testing.T) { + var testCases []resource.TestCase - testCases = append(testCases, resource.TestCase{ - Steps: []resource.TestStep{ - { - Config: resourceConfigCreate(resourceType, resourceName, map[string]interface{}{"name": "test", "repository": "env0/test", "github_installation_id": 1, "token_id": "2"}), - ExpectError: regexp.MustCompile("Cannot set token_id and github_installation_id for the same template"), + testCases = append(testCases, resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: resourceConfigCreate(resourceType, resourceName, mixUseCase.tfObject), + ExpectError: regexp.MustCompile(mixUseCase.exception), + }, }, - }, - }) + }) - for _, testCase := range testCases { - runUnitTest(t, testCase, func(mockFunc *client.MockApiClientInterface) {}) - } - }) + for _, testCase := range testCases { + runUnitTest(t, testCase, func(mockFunc *client.MockApiClientInterface) {}) + } + }) + } t.Run("Should not trigger terraform changes when gitlab_project_id is provided", func(t *testing.T) { template := client.Template{