diff --git a/env0/data_templates.go b/env0/data_templates.go new file mode 100644 index 00000000..add0d444 --- /dev/null +++ b/env0/data_templates.go @@ -0,0 +1,48 @@ +package env0 + +import ( + "context" + + "github.com/env0/terraform-provider-env0/client" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataTemplates() *schema.Resource { + return &schema.Resource{ + ReadContext: dataTemplatesRead, + + Schema: map[string]*schema.Schema{ + "names": { + Type: schema.TypeList, + Description: "list of all templates (by name)", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + Description: "the template name", + }, + }, + }, + } +} + +func dataTemplatesRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + apiClient := meta.(client.ApiClientInterface) + templates, err := apiClient.Templates() + if err != nil { + return diag.Errorf("Could not get templates: %v", err) + } + + data := []string{} + + for _, template := range templates { + data = append(data, template.Name) + } + + d.Set("names", data) + + // Not really needed. But required by Terraform SDK - https://github.com/hashicorp/terraform-plugin-sdk/issues/541 + d.SetId("all_templates_names") + + return nil +} diff --git a/env0/data_templates_test.go b/env0/data_templates_test.go new file mode 100644 index 00000000..f4061a68 --- /dev/null +++ b/env0/data_templates_test.go @@ -0,0 +1,69 @@ +package env0 + +import ( + "errors" + "regexp" + "testing" + + "github.com/env0/terraform-provider-env0/client" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestTemplatesDataSource(t *testing.T) { + template1 := client.Template{ + Id: "id0", + Name: "name0", + } + + template2 := client.Template{ + Id: "id1", + Name: "name1", + } + + resourceType := "env0_templates" + resourceName := "test_templates" + accessor := dataSourceAccessor(resourceType, resourceName) + + getTestCase := func() resource.TestCase { + return resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: dataSourceConfigCreate(resourceType, resourceName, map[string]interface{}{}), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(accessor, "names.0", template1.Name), + resource.TestCheckResourceAttr(accessor, "names.1", template2.Name), + ), + }, + }, + } + } + + mockTemplates := func(returnValue []client.Template) func(mockFunc *client.MockApiClientInterface) { + return func(mock *client.MockApiClientInterface) { + mock.EXPECT().Templates().AnyTimes().Return(returnValue, nil) + } + } + + t.Run("Success", func(t *testing.T) { + runUnitTest(t, + getTestCase(), + mockTemplates([]client.Template{template1, template2}), + ) + }) + + t.Run("API Call Error", func(t *testing.T) { + runUnitTest(t, + resource.TestCase{ + Steps: []resource.TestStep{ + { + Config: dataSourceConfigCreate(resourceType, resourceName, map[string]interface{}{}), + ExpectError: regexp.MustCompile("error"), + }, + }, + }, + func(mock *client.MockApiClientInterface) { + mock.EXPECT().Templates().AnyTimes().Return(nil, errors.New("error")) + }, + ) + }) +} diff --git a/env0/provider.go b/env0/provider.go index 3e715da4..8c8e526b 100644 --- a/env0/provider.go +++ b/env0/provider.go @@ -53,6 +53,7 @@ func Provider(version string) plugin.ProviderFunc { "env0_project_policy": dataPolicy(), "env0_configuration_variable": dataConfigurationVariable(), "env0_template": dataTemplate(), + "env0_templates": dataTemplates(), "env0_ssh_key": dataSshKey(), "env0_aws_cost_credentials": dataCostCredentials(string(client.AwsCostCredentialsType)), "env0_azure_cost_credentials": dataCostCredentials(string(client.AzureCostCredentialsType)), diff --git a/examples/data-sources/env0_templates/data-source.tf b/examples/data-sources/env0_templates/data-source.tf new file mode 100644 index 00000000..dfef8aab --- /dev/null +++ b/examples/data-sources/env0_templates/data-source.tf @@ -0,0 +1,14 @@ +data "env0_templates" "all_templates" {} + +data "env0_template" "templates" { + for_each = toset(data.env0_templates.all_templates.names) + name = each.value +} + +output "template1_name" { + value = data.env0_template.templates["Github Test-111"].name +} + +output "template2_name" { + value = data.env0_template.templates["Github Test-222"].name +} diff --git a/tests/integration/022_templates/conf.tf b/tests/integration/022_templates/conf.tf new file mode 100644 index 00000000..8d6d2954 --- /dev/null +++ b/tests/integration/022_templates/conf.tf @@ -0,0 +1,15 @@ +terraform { + backend "local" { + } + required_providers { + env0 = { + source = "terraform-registry.env0.com/env0/env0" + } + } +} + +provider "env0" {} + +variable "second_run" { + default = false +} diff --git a/tests/integration/022_templates/expected_outputs.json b/tests/integration/022_templates/expected_outputs.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/tests/integration/022_templates/expected_outputs.json @@ -0,0 +1 @@ +{} diff --git a/tests/integration/022_templates/main.tf b/tests/integration/022_templates/main.tf new file mode 100644 index 00000000..4af7afbd --- /dev/null +++ b/tests/integration/022_templates/main.tf @@ -0,0 +1,44 @@ +provider "random" {} + +resource "random_string" "random" { + length = 8 + special = false + min_lower = 8 +} + +data "env0_template" "github_template" { + name = "Github Integrated Template" +} + +resource "env0_template" "github_template1" { + name = "Github Test ${random_string.random.result}-1" + description = "Template description - GitHub" + type = "terraform" + repository = data.env0_template.github_template.repository + github_installation_id = data.env0_template.github_template.github_installation_id + path = "misc/null-resource" + retries_on_deploy = 3 + retry_on_deploy_only_when_matches_regex = "abc" + retries_on_destroy = 1 + terraform_version = "0.15.1" +} + +resource "env0_template" "github_template2" { + name = "Github Test ${random_string.random.result}-2" + description = "Template description - GitHub" + type = "terraform" + repository = data.env0_template.github_template.repository + github_installation_id = data.env0_template.github_template.github_installation_id + path = "misc/null-resource" + retries_on_deploy = 3 + retry_on_deploy_only_when_matches_regex = "abc" + retries_on_destroy = 1 + terraform_version = "0.15.1" +} + +data "env0_templates" "all_templates" {} + +data "env0_template" "templates" { + for_each = toset(data.env0_templates.all_templates.names) + name = each.value +}