Skip to content

Commit

Permalink
Feat: data resource for Custom Flow (#746)
Browse files Browse the repository at this point in the history
* Feat: data resource for Custom Flow

* added new files

* fix test

* fix test

* fix test

* fix test

* fix test
  • Loading branch information
TomerHeber committed Nov 22, 2023
1 parent 8a13e9e commit ac3c341
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 2 deletions.
55 changes: 55 additions & 0 deletions env0/data_custom_flow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
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 dataCustomFlow() *schema.Resource {
return &schema.Resource{
ReadContext: dataCustomFlowRead,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Description: "The name of the custom flow",
Optional: true,
ExactlyOneOf: []string{"name", "id"},
},
"id": {
Type: schema.TypeString,
Description: "ID of the custom flow",
Optional: true,
ExactlyOneOf: []string{"name", "id"},
},
},
}
}

func dataCustomFlowRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var err error
var customFlow *client.CustomFlow

id, ok := d.GetOk("id")
if ok {
customFlow, err = meta.(client.ApiClientInterface).CustomFlow(id.(string))
if err != nil {
return diag.Errorf("failed to get custom flow by id: %v", err)
}
} else {
name := d.Get("name")
customFlow, err = getCustomFlowByName(name.(string), meta)
if err != nil {
return diag.Errorf("failed to get custom flow by name: %v", err)
}
}

if err := writeResourceData(customFlow, d); err != nil {
return diag.Errorf("schema resource data serialization failed: %v", err)
}

return nil
}
100 changes: 100 additions & 0 deletions env0/data_custom_flow_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package env0

import (
"regexp"
"testing"

"github.com/env0/terraform-provider-env0/client"
"github.com/env0/terraform-provider-env0/client/http"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestCustomFlowDataSource(t *testing.T) {
customFlow := client.CustomFlow{
Id: "id0",
Name: "name0",
Repository: "rep1",
Path: "path",
}

otherCustomFlow := client.CustomFlow{
Id: "id1",
Name: "name1",
Repository: "rep2",
Path: "path",
}

customFlowFieldsByName := map[string]interface{}{"name": customFlow.Name}
customFlowFieldsById := map[string]interface{}{"id": customFlow.Id}

resourceType := "env0_custom_flow"
resourceName := "test_custom_flow"
accessor := dataSourceAccessor(resourceType, resourceName)

getValidTestCase := func(input map[string]interface{}) resource.TestCase {
return resource.TestCase{
Steps: []resource.TestStep{
{
Config: dataSourceConfigCreate(resourceType, resourceName, input),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(accessor, "id", customFlow.Id),
resource.TestCheckResourceAttr(accessor, "name", customFlow.Name),
),
},
},
}
}

getErrorTestCase := func(input map[string]interface{}, expectedError string) resource.TestCase {
return resource.TestCase{
Steps: []resource.TestStep{
{
Config: dataSourceConfigCreate(resourceType, resourceName, input),
ExpectError: regexp.MustCompile(expectedError),
},
},
}
}

mockListCustomFlowsCall := func(returnValue []client.CustomFlow) func(mockFunc *client.MockApiClientInterface) {
return func(mock *client.MockApiClientInterface) {
mock.EXPECT().CustomFlows(customFlow.Name).AnyTimes().Return(returnValue, nil)
}
}

mockCustomFlowCall := func(returnValue *client.CustomFlow) func(mockFunc *client.MockApiClientInterface) {
return func(mock *client.MockApiClientInterface) {
mock.EXPECT().CustomFlow(customFlow.Id).AnyTimes().Return(returnValue, nil)
}
}

t.Run("By ID", func(t *testing.T) {
runUnitTest(t,
getValidTestCase(customFlowFieldsById),
mockCustomFlowCall(&customFlow),
)
})

t.Run("By Name", func(t *testing.T) {
runUnitTest(t,
getValidTestCase(customFlowFieldsByName),
mockListCustomFlowsCall([]client.CustomFlow{customFlow}),
)
})

t.Run("Throw error when by name and more than one custom flow exists", func(t *testing.T) {
runUnitTest(t,
getErrorTestCase(customFlowFieldsByName, "found multiple custom flows with name"),
mockListCustomFlowsCall([]client.CustomFlow{customFlow, otherCustomFlow, customFlow}),
)
})

t.Run("Throw error when by id and no custom flow found with that id", func(t *testing.T) {
runUnitTest(t,
getErrorTestCase(customFlowFieldsById, "failed to get custom flow by id"),
func(mock *client.MockApiClientInterface) {
mock.EXPECT().CustomFlow(customFlow.Id).Times(1).Return(nil, http.NewMockFailedResponseError(404))
},
)
})
}
1 change: 1 addition & 0 deletions env0/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ func Provider(version string) plugin.ProviderFunc {
"env0_custom_roles": dataCustomRoles(),
"env0_gpg_key": dataGpgKey(),
"env0_provider": dataProvider(),
"env0_custom_flow": dataCustomFlow(),
},
ResourcesMap: map[string]*schema.Resource{
"env0_project": resourceProject(),
Expand Down
2 changes: 1 addition & 1 deletion env0/resource_custom_flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func getCustomFlowByName(name string, meta interface{}) (*client.CustomFlow, err
}

if len(customFlows) > 1 {
return nil, fmt.Errorf("found multiple custom flows with name: %s. Use id instead or make sure custom flow names are unique %v", name, customFlows)
return nil, fmt.Errorf("found multiple custom flows with name '%s'. Use id instead or make sure custom flow names are unique %v", name, customFlows)
}

return &customFlows[0], nil
Expand Down
6 changes: 5 additions & 1 deletion tests/integration/027_custom_flow/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ resource "env0_custom_flow" "test" {
path = "custom-flows/opa.yaml"
}

data "env0_custom_flow" "test111" {
name = env0_custom_flow.test.name
}

resource "env0_custom_flow_assignment" "assignment" {
scope_id = env0_project.project.id
template_id = env0_custom_flow.test.id
template_id = var.second_run ? data.env0_custom_flow.test111.id : env0_custom_flow.test.id
}

0 comments on commit ac3c341

Please sign in to comment.