Skip to content

Commit

Permalink
Feat: add auto approve field to sub environment configuration (#871)
Browse files Browse the repository at this point in the history
* Feat: add auto approve field to sub environment configuration

* remove unrelated change

* fix test

* fix approve_plan issue
  • Loading branch information
TomerHeber authored Jul 8, 2024
1 parent b250785 commit 0de03f8
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 33 deletions.
1 change: 1 addition & 0 deletions client/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type SubEnvironment struct {
Revision string `json:"revision,omitempty"`
Workspace string `json:"workspaceName,omitempty"`
ConfigurationChanges ConfigurationChanges `json:"configurationChanges"`
UserRequiresApproval bool `json:"userRequiresApproval"`
}

type DeployRequest struct {
Expand Down
2 changes: 1 addition & 1 deletion client/remote_state_access_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

var _ = Describe("RemoteStateAccess", func() {
environmentId := "environmnet_id"
environmentId := "environment_id"

remoteStateAccess := RemoteStateAccessConfiguration{
EnvironmentId: environmentId,
Expand Down
2 changes: 1 addition & 1 deletion client/user_environment_assignment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"go.uber.org/mock/gomock"
)

var _ = Describe("User Envrionment Assignment", func() {
var _ = Describe("User Environment Assignment", func() {
environmentId := "environmentId"
userId := "userId"

Expand Down
2 changes: 1 addition & 1 deletion env0/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func configureProvider(version string, p *schema.Provider) schema.ConfigureConte
AddRetryAfterErrorCondition().
AddRetryCondition(func(r *resty.Response, err error) bool {
if r == nil {
// No response. Possiblly a networking issue (E.g. DNS lookup failure).
// No response. Possibly a networking issue (E.g. DNS lookup failure).
tflog.SubsystemWarn(subCtx, "env0_api_client", "No response, retrying request")
return true
}
Expand Down
35 changes: 22 additions & 13 deletions env0/resource_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ import (
)

type SubEnvironment struct {
Id string
Alias string
Revision string
Workflow string
Workspace string
Configuration client.ConfigurationChanges `tfschema:"-"`
Id string
Alias string
Revision string
Workflow string
Workspace string
Configuration client.ConfigurationChanges `tfschema:"-"`
ApprovePlanAutomatically bool
}

func getSubEnvironments(d *schema.ResourceData) ([]SubEnvironment, error) {
Expand Down Expand Up @@ -290,7 +291,7 @@ func resourceEnvironment() *schema.Resource {
},
"sub_environment_configuration": {
Type: schema.TypeList,
Description: "the subenvironments for a workflow enviornment. Template type must be 'workflow'. Must match the configuration as defined in 'env0.workflow.yml'",
Description: "the subenvironments for a workflow environment. Template type must be 'workflow'. Must match the configuration as defined in 'env0.workflow.yml'",
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -320,6 +321,12 @@ func resourceEnvironment() *schema.Resource {
Optional: true,
Elem: configurationSchema,
},
"approve_plan_automatically": {
Type: schema.TypeBool,
Description: "when 'true' (default) plans are approved automatically, otherwise ('false') deployment require manual approval",
Optional: true,
Default: true,
},
},
},
},
Expand Down Expand Up @@ -408,16 +415,16 @@ func setEnvironmentSchema(ctx context.Context, d *schema.ResourceData, environme
var newSubEnvironments []interface{}

for i, iSubEnvironment := range iSubEnvironments.([]interface{}) {
subEnviornment := iSubEnvironment.(map[string]interface{})
subEnvironment := iSubEnvironment.(map[string]interface{})

alias := d.Get(fmt.Sprintf("sub_environment_configuration.%d.alias", i)).(string)

workkflowSubEnvironment, ok := environment.LatestDeploymentLog.WorkflowFile.Environments[alias]
if ok {
subEnviornment["id"] = workkflowSubEnvironment.EnvironmentId
subEnvironment["id"] = workkflowSubEnvironment.EnvironmentId
}

newSubEnvironments = append(newSubEnvironments, subEnviornment)
newSubEnvironments = append(newSubEnvironments, subEnvironment)
}

d.Set("sub_environment_configuration", newSubEnvironments)
Expand Down Expand Up @@ -789,6 +796,7 @@ func deploy(d *schema.ResourceData, apiClient client.ApiClientInterface) diag.Di
Revision: subEnvironment.Revision,
Workspace: subEnvironment.Workspace,
ConfigurationChanges: configurationChanges,
UserRequiresApproval: !subEnvironment.ApprovePlanAutomatically,
}
}
}
Expand Down Expand Up @@ -952,6 +960,7 @@ func getCreatePayload(d *schema.ResourceData, apiClient client.ApiClientInterfac
Revision: subEnvironment.Revision,
ConfigurationChanges: subEnvironment.Configuration,
Workspace: subEnvironment.Workspace,
UserRequiresApproval: !subEnvironment.ApprovePlanAutomatically,
}
}
}
Expand Down Expand Up @@ -1111,9 +1120,9 @@ func getDeployPayload(d *schema.ResourceData, apiClient client.ApiClientInterfac
}
}

if userRequiresApproval, ok := d.GetOk("requires_approval"); ok {
userRequiresApproval := userRequiresApproval.(bool)
payload.UserRequiresApproval = &userRequiresApproval
//lint:ignore SA1019 reason: https://github.com/hashicorp/terraform-plugin-sdk/issues/817
if val, exists := d.GetOkExists("approve_plan_automatically"); exists {
payload.UserRequiresApproval = boolPtr(!val.(bool))
}

return payload, nil
Expand Down
7 changes: 6 additions & 1 deletion env0/resource_environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,8 @@ func TestUnitEnvironmentResource(t *testing.T) {
ProjectId: environment.ProjectId,

DeployRequest: &client.DeployRequest{
BlueprintId: templateId,
BlueprintId: templateId,
UserRequiresApproval: boolPtr(false),
},
IsRemoteBackend: environment.IsRemoteBackend,
RequiresApproval: environment.RequiresApproval,
Expand Down Expand Up @@ -2554,6 +2555,7 @@ func TestUnitEnvironmentWithSubEnvironment(t *testing.T) {
}

updatedSubEnvironment := subEnvironment
updatedSubEnvironment.ApprovePlanAutomatically = false
updatedSubEnvironment.Configuration = append(updatedSubEnvironment.Configuration, client.ConfigurationVariable{
Name: "name2",
Value: "value2",
Expand Down Expand Up @@ -2638,6 +2640,7 @@ func TestUnitEnvironmentWithSubEnvironment(t *testing.T) {
Revision: subEnvironment.Revision,
Workspace: updatedSubEnvironment.Workspace,
ConfigurationChanges: updatedSubEnvironment.Configuration,
UserRequiresApproval: true,
},
},
}
Expand Down Expand Up @@ -2700,6 +2703,7 @@ func TestUnitEnvironmentWithSubEnvironment(t *testing.T) {
alias = "%s"
revision = "%s"
workspace = "%s"
approve_plan_automatically = false
configuration {
name = "%s"
value = "%s"
Expand Down Expand Up @@ -2731,6 +2735,7 @@ func TestUnitEnvironmentWithSubEnvironment(t *testing.T) {
resource.TestCheckResourceAttr(accessor, "sub_environment_configuration.0.alias", updatedSubEnvironment.Alias),
resource.TestCheckResourceAttr(accessor, "sub_environment_configuration.0.revision", updatedSubEnvironment.Revision),
resource.TestCheckResourceAttr(accessor, "sub_environment_configuration.0.workspace", updatedSubEnvironment.Workspace),
resource.TestCheckResourceAttr(accessor, "sub_environment_configuration.0.approve_plan_automatically", "false"),
resource.TestCheckResourceAttr(accessor, "sub_environment_configuration.0.configuration.0.name", updatedSubEnvironment.Configuration[0].Name),
resource.TestCheckResourceAttr(accessor, "sub_environment_configuration.0.configuration.0.value", updatedSubEnvironment.Configuration[0].Value),
resource.TestCheckResourceAttr(accessor, "sub_environment_configuration.0.configuration.1.name", updatedSubEnvironment.Configuration[1].Name),
Expand Down
4 changes: 2 additions & 2 deletions env0/resource_project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func TestUnitProjectResourceDestroyWithEnvironments(t *testing.T) {
Name: "name1",
}

t.Run("Success With Force Destory", func(t *testing.T) {
t.Run("Success With Force Destroy", func(t *testing.T) {
testCase := resource.TestCase{
Steps: []resource.TestStep{
{
Expand Down Expand Up @@ -199,7 +199,7 @@ func TestUnitProjectResourceDestroyWithEnvironments(t *testing.T) {
})
})

t.Run("Failure Without Force Destory", func(t *testing.T) {
t.Run("Failure Without Force Destroy", func(t *testing.T) {
testCase := resource.TestCase{
Steps: []resource.TestStep{
{
Expand Down
6 changes: 3 additions & 3 deletions env0/resource_variable_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ var variableSetVariableSchema *schema.Resource = &schema.Resource{
},
"is_sensitive": {
Type: schema.TypeBool,
Description: "is the value sensitive (defaults to 'false'). Note: 'dropdown' value format cannot be senstive.",
Description: "is the value sensitive (defaults to 'false'). Note: 'dropdown' value format cannot be sensitive.",
Optional: true,
Default: false,
},
Expand Down Expand Up @@ -293,15 +293,15 @@ type mergedVariables struct {
func mergeVariables(schema []client.ConfigurationVariable, api []client.ConfigurationVariable) *mergedVariables {
var res mergedVariables

// To avoid false drifts, keep the order of the 'currentVariables' list similiar to the schema as much as possible.
// To avoid false drifts, keep the order of the 'currentVariables' list similar to the schema as much as possible.
for _, svariable := range schema {
found := false

for _, avariable := range api {
if svariable.Name == avariable.Name && *svariable.Type == *avariable.Type {
found = true
if avariable.IsSensitive != nil && *avariable.IsSensitive {
// Senstive - to avoid drift use the value from the schema
// Sensitive - to avoid drift use the value from the schema
avariable.Value = svariable.Value
}
res.currentVariables = append(res.currentVariables, avariable)
Expand Down
21 changes: 12 additions & 9 deletions env0/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,16 @@ func TestWriteResourceDataOmitEmpty(t *testing.T) {
func TestReadSubEnvironment(t *testing.T) {
expectedSubEnvironments := []SubEnvironment{
{
Id: "id1",
Alias: "alias1",
Revision: "revision1",
Id: "id1",
Alias: "alias1",
Revision: "revision1",
ApprovePlanAutomatically: true,
},
{
Id: "id2",
Alias: "alias2",
Revision: "revision2",
Id: "id2",
Alias: "alias2",
Revision: "revision2",
ApprovePlanAutomatically: false,
Configuration: client.ConfigurationChanges{
{
Name: "name1",
Expand Down Expand Up @@ -388,9 +390,10 @@ func TestReadSubEnvironment(t *testing.T) {
"revision": expectedSubEnvironments[0].Revision,
},
map[string]interface{}{
"id": expectedSubEnvironments[1].Id,
"alias": expectedSubEnvironments[1].Alias,
"revision": expectedSubEnvironments[1].Revision,
"id": expectedSubEnvironments[1].Id,
"alias": expectedSubEnvironments[1].Alias,
"revision": expectedSubEnvironments[1].Revision,
"approve_plan_automatically": expectedSubEnvironments[1].ApprovePlanAutomatically,
"configuration": []interface{}{
map[string]interface{}{
"name": expectedSubEnvironments[1].Configuration[0].Name,
Expand Down
5 changes: 3 additions & 2 deletions tests/integration/012_environment/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,9 @@ resource "env0_environment" "workflow-environment" {
variable_sets = var.second_run ? [env0_variable_set.variable_set2.id] : [env0_variable_set.variable_set1.id]

sub_environment_configuration {
alias = "rootService1"
revision = "master"
alias = "rootService1"
revision = "master"
approve_plan_automatically = var.second_run ? true : false
configuration {
name = "sub_env1_var1"
value = "hello"
Expand Down

0 comments on commit 0de03f8

Please sign in to comment.