From d02111128ca0239087fe0213bc84e07b2831d9a1 Mon Sep 17 00:00:00 2001 From: Tomer Heber Date: Fri, 9 Jun 2023 16:06:34 +0300 Subject: [PATCH] Feat: helm template support + helm repo vcs option support --- client/template.go | 4 ++ env0/resource_template.go | 17 +++++++ env0/resource_template_test.go | 64 +++++++++++++++++++++++++- tests/integration/004_template/main.tf | 17 +++++++ 4 files changed, 101 insertions(+), 1 deletion(-) diff --git a/client/template.go b/client/template.go index 56c6fa28..5211f0bc 100644 --- a/client/template.go +++ b/client/template.go @@ -58,6 +58,8 @@ type Template struct { FileName string `json:"fileName,omitempty" tfschema:",omitempty"` IsTerragruntRunAll bool `json:"isTerragruntRunAll"` IsAzureDevOps bool `json:"isAzureDevOps" tfschema:"is_azure_devops"` + IsHelmRepository bool `json:"isHelmRepository"` + HelmChartName string `json:"helmChartName,omitempty" tfschema:",omitempty"` } type TemplateCreatePayload struct { @@ -84,6 +86,8 @@ type TemplateCreatePayload struct { FileName string `json:"fileName,omitempty"` IsTerragruntRunAll bool `json:"isTerragruntRunAll"` IsAzureDevOps bool `json:"isAzureDevOps" tfschema:"is_azure_devops"` + IsHelmRepository bool `json:"isHelmRepository"` + HelmChartName string `json:"helmChartName,omitempty"` } type TemplateAssignmentToProjectPayload struct { diff --git a/env0/resource_template.go b/env0/resource_template.go index 076ff00f..8ff4f3fe 100644 --- a/env0/resource_template.go +++ b/env0/resource_template.go @@ -21,6 +21,7 @@ var allowedTemplateTypes = []string{ "k8s", "workflow", "cloudformation", + "helm", } func getTemplateSchema(prefix string) map[string]*schema.Schema { @@ -33,6 +34,8 @@ func getTemplateSchema(prefix string) map[string]*schema.Schema { "is_bitbucket_server", "is_github_enterprise", "is_azure_devops", + "helm_chart_name", + "is_helm_repository", } allVCSAttributesBut := func(strs ...string) []string { @@ -208,6 +211,20 @@ func getTemplateSchema(prefix string) map[string]*schema.Schema { ConflictsWith: allVCSAttributesBut("is_azure_devops", "token_id"), RequiredWith: requiredWith("token_id"), }, + "helm_chart_name": { + Type: schema.TypeString, + Optional: true, + Description: "the helm chart name. Required if is_helm_repository is set to 'true'", + ConflictsWith: allVCSAttributesBut("helm_chart_name", "is_helm_repository"), + }, + "is_helm_repository": { + Type: schema.TypeBool, + Optional: true, + Description: "true if this template integrates with a helm repository", + Default: "false", + ConflictsWith: allVCSAttributesBut("helm_chart_name", "is_helm_repository"), + RequiredWith: requiredWith("helm_chart_name"), + }, } if prefix == "" { diff --git a/env0/resource_template_test.go b/env0/resource_template_test.go index 3f77c58e..3f894abc 100644 --- a/env0/resource_template_test.go +++ b/env0/resource_template_test.go @@ -365,6 +365,50 @@ func TestUnitTemplateResource(t *testing.T) { TerraformVersion: "0.15.1", IsAzureDevOps: true, } + + helmTemplate := client.Template{ + Id: "helmTemplate", + Name: "template0", + Description: "description0", + Repository: "env0/repo", + Path: "path/zero/new", + Type: "helm", + HelmChartName: "chart1", + IsHelmRepository: true, + Retry: client.TemplateRetry{ + OnDeploy: &client.TemplateRetryOn{ + Times: 2, + ErrorRegex: "RetryMeForDeploy.*", + }, + OnDestroy: &client.TemplateRetryOn{ + Times: 1, + ErrorRegex: "RetryMeForDestroy.*", + }, + }, + TerraformVersion: "0.12.24", + } + helmUpdatedTemplate := client.Template{ + Id: helmTemplate.Id, + Name: "new-name", + Description: "new-description", + Repository: "env0/repo-new", + Path: "path/zero/new", + Type: "helm", + HelmChartName: "chart1", + IsHelmRepository: true, + Retry: client.TemplateRetry{ + OnDeploy: &client.TemplateRetryOn{ + Times: 2, + ErrorRegex: "RetryMeForDeploy.*", + }, + OnDestroy: &client.TemplateRetryOn{ + Times: 1, + ErrorRegex: "RetryMeForDestroy.*", + }, + }, + TerraformVersion: "0.12.24", + } + fullTemplateResourceConfig := func(resourceType string, resourceName string, template client.Template) string { templateAsDictionary := map[string]interface{}{ "name": template.Name, @@ -435,6 +479,12 @@ func TestUnitTemplateResource(t *testing.T) { if template.IsAzureDevOps { templateAsDictionary["is_azure_devops"] = true } + if template.IsHelmRepository { + templateAsDictionary["is_helm_repository"] = true + } + if template.HelmChartName != "" { + templateAsDictionary["helm_chart_name"] = template.HelmChartName + } return resourceConfigCreate(resourceType, resourceName, templateAsDictionary) } @@ -453,6 +503,11 @@ func TestUnitTemplateResource(t *testing.T) { tokenIdAssertion = resource.TestCheckNoResourceAttr(resourceFullName, "token_id") } + helmChartNameAssertion := resource.TestCheckResourceAttr(resourceFullName, "helm_chart_name", template.HelmChartName) + if template.HelmChartName == "" { + helmChartNameAssertion = resource.TestCheckNoResourceAttr(resourceFullName, "helm_chart_name") + } + filenameAssertion := resource.TestCheckResourceAttr(resourceFullName, "file_name", template.FileName) if template.FileName == "" { filenameAssertion = resource.TestCheckNoResourceAttr(resourceFullName, "file_name") @@ -485,9 +540,11 @@ func TestUnitTemplateResource(t *testing.T) { gitlabProjectIdAssertion, terragruntVersionAssertion, githubInstallationIdAssertion, + helmChartNameAssertion, resource.TestCheckResourceAttr(resourceFullName, "terraform_version", template.TerraformVersion), 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)), ) } @@ -504,6 +561,7 @@ func TestUnitTemplateResource(t *testing.T) { {"Bitbucket Server", bitbucketServerTemplate, bitbucketServerUpdatedTemplate}, {"Cloudformation", cloudformationTemplate, cloudformationUpdatedTemplate}, {"Azure DevOps", azureDevOpsTemplate, azureDevOpsUpdatedTemplate}, + {"Helm Chart", helmTemplate, helmUpdatedTemplate}, } for _, templateUseCase := range templateUseCases { t.Run("Full "+templateUseCase.vcs+" template (without SSH keys)", func(t *testing.T) { @@ -526,7 +584,7 @@ func TestUnitTemplateResource(t *testing.T) { TokenId: templateUseCase.template.TokenId, Path: templateUseCase.template.Path, Revision: templateUseCase.template.Revision, - Type: "terraform", + Type: templateUseCase.template.Type, Retry: templateUseCase.template.Retry, TerraformVersion: templateUseCase.template.TerraformVersion, BitbucketClientKey: templateUseCase.template.BitbucketClientKey, @@ -536,6 +594,8 @@ func TestUnitTemplateResource(t *testing.T) { TerragruntVersion: templateUseCase.template.TerragruntVersion, IsTerragruntRunAll: templateUseCase.template.IsTerragruntRunAll, IsAzureDevOps: templateUseCase.template.IsAzureDevOps, + IsHelmRepository: templateUseCase.template.IsHelmRepository, + HelmChartName: templateUseCase.template.HelmChartName, } updateTemplateCreateTemplate := client.TemplateCreatePayload{ Name: templateUseCase.updatedTemplate.Name, @@ -558,6 +618,8 @@ func TestUnitTemplateResource(t *testing.T) { TerragruntVersion: templateUseCase.updatedTemplate.TerragruntVersion, IsTerragruntRunAll: templateUseCase.updatedTemplate.IsTerragruntRunAll, IsAzureDevOps: templateUseCase.updatedTemplate.IsAzureDevOps, + IsHelmRepository: templateUseCase.template.IsHelmRepository, + HelmChartName: templateUseCase.template.HelmChartName, } if templateUseCase.vcs == "Cloudformation" { diff --git a/tests/integration/004_template/main.tf b/tests/integration/004_template/main.tf index e5f9936d..f0207371 100644 --- a/tests/integration/004_template/main.tf +++ b/tests/integration/004_template/main.tf @@ -80,6 +80,23 @@ resource "env0_template" "github_template_source_code" { terraform_version = "0.15.1" } +resource "env0_template" "helm_template" { + name = "helm-${random_string.random.result}-1" + description = "Template description helm" + repository = "https://github.com/env0/templates" + path = "misc/helm/dummy" + type = "helm" +} + +resource "env0_template" "helm_template_repo" { + name = "helm-${random_string.random.result}-2" + description = "Template description helm repo" + repository = "https://charts.bitnami.com/bitnami" + type = "helm" + helm_chart_name = "nginx" + is_helm_repository = true +} + data "env0_source_code_variables" "variables" { template_id = env0_template.github_template_source_code.id }