-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: add env0_projects (plural) data resource (#787)
* Feat: add env0_projects (plural) data resource * added more features * fix typo
- Loading branch information
1 parent
77bc1b6
commit b9c02fd
Showing
7 changed files
with
221 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
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 dataProjects() *schema.Resource { | ||
return &schema.Resource{ | ||
ReadContext: dataProjectsRead, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"include_archived_projects": { | ||
Type: schema.TypeBool, | ||
Description: "set to 'true' to include archived projects (defaults to 'false')", | ||
Optional: true, | ||
Default: false, | ||
}, | ||
"projects": { | ||
Type: schema.TypeList, | ||
Description: "list of projects", | ||
Computed: true, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"name": { | ||
Type: schema.TypeString, | ||
Description: "the name of the project", | ||
Computed: true, | ||
}, | ||
"id": { | ||
Type: schema.TypeString, | ||
Description: "id of the project", | ||
Computed: true, | ||
}, | ||
"is_archived": { | ||
Type: schema.TypeBool, | ||
Description: "'true' if the project is archived", | ||
Computed: true, | ||
}, | ||
"parent_project_id": { | ||
Type: schema.TypeString, | ||
Description: "the parent project id (if one exist)", | ||
Computed: true, | ||
}, | ||
"hierarchy": { | ||
Type: schema.TypeString, | ||
Description: "the project hierarchy (e.g. uuid1|uuid2|...)", | ||
Computed: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func dataProjectsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
apiClient := meta.(client.ApiClientInterface) | ||
|
||
includeArchivedProjects := d.Get("include_archived_projects").(bool) | ||
|
||
projects, err := apiClient.Projects() | ||
if err != nil { | ||
return diag.Errorf("failed to get list of projects: %v", err) | ||
} | ||
|
||
filteredProjects := []client.Project{} | ||
for _, project := range projects { | ||
if includeArchivedProjects || !project.IsArchived { | ||
filteredProjects = append(filteredProjects, project) | ||
} | ||
} | ||
|
||
if err := writeResourceDataSlice(filteredProjects, "projects", d); err != nil { | ||
return diag.Errorf("schema slice resource data serialization failed: %v", err) | ||
} | ||
|
||
d.SetId("projects") | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package env0 | ||
|
||
import ( | ||
"errors" | ||
"regexp" | ||
"testing" | ||
|
||
"github.com/env0/terraform-provider-env0/client" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
) | ||
|
||
func TestProjectsDataSource(t *testing.T) { | ||
project1 := client.Project{ | ||
Id: "id0", | ||
Name: "my-project-1", | ||
ParentProjectId: "p1", | ||
Hierarchy: "adsas|fdsfsd", | ||
} | ||
|
||
project2 := client.Project{ | ||
Id: "id1", | ||
Name: "my-project-2", | ||
} | ||
|
||
project3 := client.Project{ | ||
Id: "id1", | ||
Name: "my-project-2", | ||
IsArchived: true, | ||
} | ||
|
||
projects := []client.Project{project1, project2, project3} | ||
|
||
resourceType := "env0_projects" | ||
resourceName := "test_projects" | ||
accessor := dataSourceAccessor(resourceType, resourceName) | ||
|
||
getValidTestCase := func() resource.TestCase { | ||
return resource.TestCase{ | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: dataSourceConfigCreate(resourceType, resourceName, map[string]interface{}{}), | ||
Check: resource.ComposeAggregateTestCheckFunc( | ||
resource.TestCheckResourceAttr(accessor, "projects.0.id", project1.Id), | ||
resource.TestCheckResourceAttr(accessor, "projects.0.name", project1.Name), | ||
resource.TestCheckResourceAttr(accessor, "projects.0.parent_project_id", project1.ParentProjectId), | ||
resource.TestCheckResourceAttr(accessor, "projects.0.hierarchy", project1.Hierarchy), | ||
resource.TestCheckResourceAttr(accessor, "projects.0.is_archived", "false"), | ||
resource.TestCheckResourceAttr(accessor, "projects.1.id", project2.Id), | ||
resource.TestCheckResourceAttr(accessor, "projects.1.name", project2.Name), | ||
resource.TestCheckResourceAttr(accessor, "projects.1.is_archived", "false"), | ||
resource.TestCheckResourceAttr(accessor, "projects.#", "2"), | ||
), | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
getValidTestCaseWithArchived := func() resource.TestCase { | ||
return resource.TestCase{ | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: dataSourceConfigCreate(resourceType, resourceName, map[string]interface{}{ | ||
"include_archived_projects": "true", | ||
}), | ||
Check: resource.ComposeAggregateTestCheckFunc( | ||
resource.TestCheckResourceAttr(accessor, "projects.0.id", project1.Id), | ||
resource.TestCheckResourceAttr(accessor, "projects.0.name", project1.Name), | ||
resource.TestCheckResourceAttr(accessor, "projects.0.parent_project_id", project1.ParentProjectId), | ||
resource.TestCheckResourceAttr(accessor, "projects.0.hierarchy", project1.Hierarchy), | ||
resource.TestCheckResourceAttr(accessor, "projects.0.is_archived", "false"), | ||
resource.TestCheckResourceAttr(accessor, "projects.1.id", project2.Id), | ||
resource.TestCheckResourceAttr(accessor, "projects.1.name", project2.Name), | ||
resource.TestCheckResourceAttr(accessor, "projects.1.is_archived", "false"), | ||
resource.TestCheckResourceAttr(accessor, "projects.2.id", project2.Id), | ||
resource.TestCheckResourceAttr(accessor, "projects.2.name", project2.Name), | ||
resource.TestCheckResourceAttr(accessor, "projects.2.is_archived", "true"), | ||
resource.TestCheckResourceAttr(accessor, "projects.#", "3"), | ||
), | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
getErrorTestCase := func(expectedError string) resource.TestCase { | ||
return resource.TestCase{ | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: dataSourceConfigCreate(resourceType, resourceName, map[string]interface{}{}), | ||
ExpectError: regexp.MustCompile(expectedError), | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
mockGetProjectsCall := func(returnValue []client.Project) func(mockFunc *client.MockApiClientInterface) { | ||
return func(mock *client.MockApiClientInterface) { | ||
mock.EXPECT().Projects().AnyTimes().Return(returnValue, nil) | ||
} | ||
} | ||
|
||
mockGetProjectsCallFailed := func(err string) func(mockFunc *client.MockApiClientInterface) { | ||
return func(mock *client.MockApiClientInterface) { | ||
mock.EXPECT().Projects().AnyTimes().Return([]client.Project{}, errors.New(err)) | ||
} | ||
} | ||
|
||
t.Run("get all projects", func(t *testing.T) { | ||
runUnitTest(t, | ||
getValidTestCase(), | ||
mockGetProjectsCall(projects), | ||
) | ||
}) | ||
|
||
t.Run("get all projects including archived", func(t *testing.T) { | ||
runUnitTest(t, | ||
getValidTestCaseWithArchived(), | ||
mockGetProjectsCall(projects), | ||
) | ||
}) | ||
|
||
t.Run("Error when API call fails", func(t *testing.T) { | ||
runUnitTest(t, | ||
getErrorTestCase("failed to get list of projects: error"), | ||
mockGetProjectsCallFailed("error"), | ||
) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
data "env0_projects" "list_of_projects" {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters