diff --git a/env0/data_teams.go b/env0/data_teams.go new file mode 100644 index 00000000..a1f4473b --- /dev/null +++ b/env0/data_teams.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 dataTeams() *schema.Resource { + return &schema.Resource{ + ReadContext: dataTeamsRead, + + Schema: map[string]*schema.Schema{ + "names": { + Type: schema.TypeList, + Description: "list of all teams (by name)", + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + Description: "the team name", + }, + }, + }, + } +} + +func dataTeamsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + apiClient := meta.(client.ApiClientInterface) + teams, err := apiClient.Teams() + if err != nil { + return diag.Errorf("Could not get teams: %v", err) + } + + data := []string{} + + for _, team := range teams { + data = append(data, team.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_teams_names") + + return nil +} diff --git a/env0/data_teams_test.go b/env0/data_teams_test.go new file mode 100644 index 00000000..af29386f --- /dev/null +++ b/env0/data_teams_test.go @@ -0,0 +1,71 @@ +package env0 + +import ( + "errors" + "regexp" + "testing" + + "github.com/env0/terraform-provider-env0/client" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestTeamsDataSource(t *testing.T) { + team1 := client.Team{ + Id: "id0", + Name: "name1", + Description: "A team's description", + } + + team2 := client.Team{ + Id: "id1", + Name: "name2", + Description: "A team's description", + } + + resourceType := "env0_teams" + resourceName := "test_teams" + 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", team1.Name), + resource.TestCheckResourceAttr(accessor, "names.1", team2.Name), + ), + }, + }, + } + } + + mockTeams := func(returnValue []client.Team) func(mockFunc *client.MockApiClientInterface) { + return func(mock *client.MockApiClientInterface) { + mock.EXPECT().Teams().AnyTimes().Return(returnValue, nil) + } + } + + t.Run("Success", func(t *testing.T) { + runUnitTest(t, + getTestCase(), + mockTeams([]client.Team{team1, team2}), + ) + }) + + 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().Teams().AnyTimes().Return(nil, errors.New("error")) + }, + ) + }) +} diff --git a/env0/provider.go b/env0/provider.go index 3a636b4e..3e715da4 100644 --- a/env0/provider.go +++ b/env0/provider.go @@ -61,6 +61,7 @@ func Provider(version string) plugin.ProviderFunc { "env0_gcp_credentials": dataGcpCredentials(), "env0_azure_credentials": dataAzureCredentials(), "env0_team": dataTeam(), + "env0_teams": dataTeams(), "env0_environment": dataEnvironment(), "env0_workflow_triggers": dataWorkflowTriggers(), "env0_notification": dataNotification(), diff --git a/examples/data-sources/env0_teams/data-source.tf b/examples/data-sources/env0_teams/data-source.tf new file mode 100644 index 00000000..c80793b9 --- /dev/null +++ b/examples/data-sources/env0_teams/data-source.tf @@ -0,0 +1,14 @@ +data "env0_teams" "all_teams" {} + +data "env0_team" "teams" { + for_each = toset(data.env0_teams.all_teams.names) + name = each.value +} + +output "team1_name" { + value = data.env0_team.teams["team1"].name +} + +output "team2_name" { + value = data.env0_team.teams["team2"].name +} \ No newline at end of file diff --git a/tests/integration/021_teams/conf.tf b/tests/integration/021_teams/conf.tf new file mode 100644 index 00000000..8d6d2954 --- /dev/null +++ b/tests/integration/021_teams/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/021_teams/expected_outputs.json b/tests/integration/021_teams/expected_outputs.json new file mode 100644 index 00000000..a17b81de --- /dev/null +++ b/tests/integration/021_teams/expected_outputs.json @@ -0,0 +1,4 @@ +{ + "team1_name": "team1", + "team2_name": "team2" +} diff --git a/tests/integration/021_teams/main.tf b/tests/integration/021_teams/main.tf new file mode 100644 index 00000000..d85a92ab --- /dev/null +++ b/tests/integration/021_teams/main.tf @@ -0,0 +1,22 @@ +resource "env0_team" "team_resource1" { + name = "team1" +} + +resource "env0_team" "team_resource2" { + name = "team2" +} + +data "env0_teams" "all_teams" {} + +data "env0_team" "teams" { + for_each = toset(data.env0_teams.all_teams.names) + name = each.value +} + +output "team1_name" { + value = var.second_run ? data.env0_team.teams["team1"].name : "" +} + +output "team2_name" { + value = var.second_run ? data.env0_team.teams["team2"].name : "" +} \ No newline at end of file