From c070c4c2907459ae022dd314e712d65f660b0c7f Mon Sep 17 00:00:00 2001 From: GiliFaroEnv0 Date: Tue, 23 Nov 2021 14:26:35 +0200 Subject: [PATCH 1/5] feat: Add ability to set default CD and PR plan by project policy --- client/model.go | 74 ++++++++++++++++------------ docs/data-sources/project_policy.md | 2 + docs/resources/project_policy.md | 2 + env0/data_project_policy.go | 10 ++++ env0/data_project_policy_test.go | 20 +++++--- env0/resource_project_policy.go | 20 ++++++++ env0/resource_project_policy_test.go | 4 ++ 7 files changed, 92 insertions(+), 40 deletions(-) diff --git a/client/model.go b/client/model.go index d3e58759..e277b7d4 100644 --- a/client/model.go +++ b/client/model.go @@ -243,48 +243,58 @@ type TeamProjectAssignment struct { } type Policy struct { - Id string `json:"id"` - ProjectId string `json:"projectId"` - NumberOfEnvironments int `json:"numberOfEnvironments"` - NumberOfEnvironmentsTotal int `json:"numberOfEnvironmentsTotal"` - RequiresApprovalDefault bool `json:"requiresApprovalDefault"` - IncludeCostEstimation bool `json:"includeCostEstimation"` - SkipApplyWhenPlanIsEmpty bool `json:"skipApplyWhenPlanIsEmpty"` - DisableDestroyEnvironments bool `json:"disableDestroyEnvironments"` - SkipRedundantDeployments bool `json:"skipRedundantDeployments"` - UpdatedBy string `json:"updatedBy"` + Id string `json:"id"` + ProjectId string `json:"projectId"` + NumberOfEnvironments int `json:"numberOfEnvironments"` + NumberOfEnvironmentsTotal int `json:"numberOfEnvironmentsTotal"` + RequiresApprovalDefault bool `json:"requiresApprovalDefault"` + IncludeCostEstimation bool `json:"includeCostEstimation"` + SkipApplyWhenPlanIsEmpty bool `json:"skipApplyWhenPlanIsEmpty"` + DisableDestroyEnvironments bool `json:"disableDestroyEnvironments"` + SkipRedundantDeployments bool `json:"skipRedundantDeployments"` + UpdatedBy string `json:"updatedBy"` + RunPullRequestPlanDefault bool `json:"runPullRequestPlanDefault"` + ContinuousDeploymentDefault bool `json:"continuousDeploymentDefault"` } type PolicyUpdatePayload struct { - ProjectId string `json:"projectId"` - NumberOfEnvironments int `json:"numberOfEnvironments"` - NumberOfEnvironmentsTotal int `json:"numberOfEnvironmentsTotal"` - RequiresApprovalDefault bool `json:"requiresApprovalDefault"` - IncludeCostEstimation bool `json:"includeCostEstimation"` - SkipApplyWhenPlanIsEmpty bool `json:"skipApplyWhenPlanIsEmpty"` - DisableDestroyEnvironments bool `json:"disableDestroyEnvironments"` - SkipRedundantDeployments bool `json:"skipRedundantDeployments"` + Id string `json:"id"` + ProjectId string `json:"projectId"` + NumberOfEnvironments int `json:"numberOfEnvironments"` + NumberOfEnvironmentsTotal int `json:"numberOfEnvironmentsTotal"` + RequiresApprovalDefault bool `json:"requiresApprovalDefault"` + IncludeCostEstimation bool `json:"includeCostEstimation"` + SkipApplyWhenPlanIsEmpty bool `json:"skipApplyWhenPlanIsEmpty"` + DisableDestroyEnvironments bool `json:"disableDestroyEnvironments"` + SkipRedundantDeployments bool `json:"skipRedundantDeployments"` + UpdatedBy string `json:"updatedBy"` + RunPullRequestPlanDefault bool `json:"runPullRequestPlanDefault"` + ContinuousDeploymentDefault bool `json:"continuousDeploymentDefault"` } func (p PolicyUpdatePayload) MarshalJSON() ([]byte, error) { type serial struct { - ProjectId string `json:"projectId"` - NumberOfEnvironments *int `json:"numberOfEnvironments"` - NumberOfEnvironmentsTotal *int `json:"numberOfEnvironmentsTotal"` - RequiresApprovalDefault bool `json:"requiresApprovalDefault"` - IncludeCostEstimation bool `json:"includeCostEstimation"` - SkipApplyWhenPlanIsEmpty bool `json:"skipApplyWhenPlanIsEmpty"` - DisableDestroyEnvironments bool `json:"disableDestroyEnvironments"` - SkipRedundantDeployments bool `json:"skipRedundantDeployments"` + ProjectId string `json:"projectId"` + NumberOfEnvironments *int `json:"numberOfEnvironments"` + NumberOfEnvironmentsTotal *int `json:"numberOfEnvironmentsTotal"` + RequiresApprovalDefault bool `json:"requiresApprovalDefault"` + IncludeCostEstimation bool `json:"includeCostEstimation"` + SkipApplyWhenPlanIsEmpty bool `json:"skipApplyWhenPlanIsEmpty"` + DisableDestroyEnvironments bool `json:"disableDestroyEnvironments"` + SkipRedundantDeployments bool `json:"skipRedundantDeployments"` + RunPullRequestPlanDefault bool `json:"runPullRequestPlanDefault"` + ContinuousDeploymentDefault bool `json:"continuousDeploymentDefault"` } s := serial{ - ProjectId: p.ProjectId, - RequiresApprovalDefault: p.RequiresApprovalDefault, - IncludeCostEstimation: p.IncludeCostEstimation, - SkipApplyWhenPlanIsEmpty: p.SkipApplyWhenPlanIsEmpty, - DisableDestroyEnvironments: p.DisableDestroyEnvironments, - SkipRedundantDeployments: p.SkipRedundantDeployments, + ProjectId: p.ProjectId, + RequiresApprovalDefault: p.RequiresApprovalDefault, + IncludeCostEstimation: p.IncludeCostEstimation, + SkipApplyWhenPlanIsEmpty: p.SkipApplyWhenPlanIsEmpty, + DisableDestroyEnvironments: p.DisableDestroyEnvironments, + SkipRedundantDeployments: p.SkipRedundantDeployments, + RunPullRequestPlanDefault: p.RunPullRequestPlanDefault, + ContinuousDeploymentDefault: p.ContinuousDeploymentDefault, } if p.NumberOfEnvironments != 0 { diff --git a/docs/data-sources/project_policy.md b/docs/data-sources/project_policy.md index 0bf50533..661da5be 100644 --- a/docs/data-sources/project_policy.md +++ b/docs/data-sources/project_policy.md @@ -21,12 +21,14 @@ description: |- ### Read-Only +- **continuous_deployment_default** (Boolean) Redeploy on every push to the git branch default value - **disable_destroy_environments** (Boolean) Disallow destroying environment in the project - **id** (String) id of the policy - **include_cost_estimation** (Boolean) Enable cost estimation for the project - **number_of_environments** (Number) Max number of environments a single user can have in this project, 0 indicates no limit - **number_of_environments_total** (Number) Max number of environments in this project, 0 indicates no limit - **requires_approval_default** (Boolean) Requires approval default value when creating a new environment in the project +- **run_pull_request_plan_default** (Boolean) Run Terraform Plan on Pull Requests for new environments targeting their branch default value - **skip_apply_when_plan_is_empty** (Boolean) Skip apply when plan has no changes - **skip_redundant_deployments** (Boolean) Automatically skip queued deployments when a newer deployment is triggered - **updated_by** (String) updated by diff --git a/docs/resources/project_policy.md b/docs/resources/project_policy.md index fe58c62f..90ca2d4e 100644 --- a/docs/resources/project_policy.md +++ b/docs/resources/project_policy.md @@ -38,11 +38,13 @@ resource "env0_project_policy" "example" { ### Optional +- **continuous_deployment_default** (Boolean) Redeploy on every push to the git branch default value - **disable_destroy_environments** (Boolean) Disallow destroying environment in the project - **include_cost_estimation** (Boolean) Enable cost estimation for the project - **number_of_environments** (Number) Max number of environments a single user can have in this project, 0 indicates no limit - **number_of_environments_total** (Number) Max number of environments in this project, 0 indicates no limit - **requires_approval_default** (Boolean) Requires approval default value when creating a new environment in the project +- **run_pull_request_plan_default** (Boolean) Run Terraform Plan on Pull Requests for new environments targeting their branch default value - **skip_apply_when_plan_is_empty** (Boolean) Skip apply when plan has no changes - **skip_redundant_deployments** (Boolean) Automatically skip queued deployments when a newer deployment is triggered diff --git a/env0/data_project_policy.go b/env0/data_project_policy.go index cbd312f3..e8ec2247 100644 --- a/env0/data_project_policy.go +++ b/env0/data_project_policy.go @@ -63,6 +63,16 @@ func dataPolicy() *schema.Resource { Description: "updated by", Computed: true, }, + "run_pull_request_plan_default": { + Type: schema.TypeBool, + Description: "Run Terraform Plan on Pull Requests for new environments targeting their branch default value", + Computed: true, + }, + "continuous_deployment_default": { + Type: schema.TypeBool, + Description: "Redeploy on every push to the git branch default value", + Computed: true, + }, }, } } diff --git a/env0/data_project_policy_test.go b/env0/data_project_policy_test.go index 6fea720e..0fc4919e 100644 --- a/env0/data_project_policy_test.go +++ b/env0/data_project_policy_test.go @@ -10,14 +10,16 @@ import ( func TestPolicyDataSource(t *testing.T) { policy := client.Policy{ - Id: "id0", - ProjectId: "project0", - NumberOfEnvironments: 1, - NumberOfEnvironmentsTotal: 2, - RequiresApprovalDefault: true, - IncludeCostEstimation: true, - SkipApplyWhenPlanIsEmpty: true, - DisableDestroyEnvironments: true, + Id: "id0", + ProjectId: "project0", + NumberOfEnvironments: 1, + NumberOfEnvironmentsTotal: 2, + RequiresApprovalDefault: true, + IncludeCostEstimation: true, + SkipApplyWhenPlanIsEmpty: true, + DisableDestroyEnvironments: true, + ContinuousDeploymentDefault: true, + RunPullRequestPlanDefault: false, } resourceType := "env0_project_policy" @@ -40,6 +42,8 @@ func TestPolicyDataSource(t *testing.T) { resource.TestCheckResourceAttr(accessor, "include_cost_estimation", strconv.FormatBool(policy.IncludeCostEstimation)), resource.TestCheckResourceAttr(accessor, "skip_apply_when_plan_is_empty", strconv.FormatBool(policy.SkipApplyWhenPlanIsEmpty)), resource.TestCheckResourceAttr(accessor, "disable_destroy_environments", strconv.FormatBool(policy.DisableDestroyEnvironments)), + resource.TestCheckResourceAttr(accessor, "run_pull_request_plan_default", strconv.FormatBool(policy.RunPullRequestPlanDefault)), + resource.TestCheckResourceAttr(accessor, "continuous_deployment_default", strconv.FormatBool(policy.ContinuousDeploymentDefault)), ), }, }, diff --git a/env0/resource_project_policy.go b/env0/resource_project_policy.go index 2025f8dd..5ac4e013 100644 --- a/env0/resource_project_policy.go +++ b/env0/resource_project_policy.go @@ -93,6 +93,18 @@ func resourcePolicy() *schema.Resource { Description: "updated by", Computed: true, }, + "run_pull_request_plan_default": { + Type: schema.TypeBool, + Description: "Run Terraform Plan on Pull Requests for new environments targeting their branch default value", + Optional: true, + Default: false, + }, + "continuous_deployment_default": { + Type: schema.TypeBool, + Description: "Redeploy on every push to the git branch default value", + Optional: true, + Default: false, + }, }, } } @@ -108,6 +120,8 @@ func setPolicySchema(d *schema.ResourceData, policy client.Policy) { d.Set("disable_destroy_environments", policy.DisableDestroyEnvironments) d.Set("skip_redundant_deployments", policy.SkipRedundantDeployments) d.Set("updated_by", policy.UpdatedBy) + d.Set("run_pull_request_plan_default", policy.RunPullRequestPlanDefault) + d.Set("continuous_deployment_default" , policy.ContinuousDeploymentDefault) } func resourcePolicyCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -166,6 +180,12 @@ func resourcePolicyUpdate(ctx context.Context, d *schema.ResourceData, meta inte if skipRedundantDeployments, ok := d.GetOk("skip_redundant_deployments"); ok { payload.SkipRedundantDeployments = skipRedundantDeployments.(bool) } + if runPullRequestPlanDefault, ok := d.GetOk("run_pull_request_plan_default"); ok { + payload.RunPullRequestPlanDefault = runPullRequestPlanDefault.(bool) + } + if continuousDeploymentDefault, ok := d.GetOk("continuous_deployment_default"); ok { + payload.ContinuousDeploymentDefault = continuousDeploymentDefault.(bool) + } _, err := apiClient.PolicyUpdate(payload) if err != nil { diff --git a/env0/resource_project_policy_test.go b/env0/resource_project_policy_test.go index 1d1979d5..bb6cacdb 100644 --- a/env0/resource_project_policy_test.go +++ b/env0/resource_project_policy_test.go @@ -57,6 +57,8 @@ func TestUnitPolicyResource(t *testing.T) { "skip_apply_when_plan_is_empty": policy.SkipApplyWhenPlanIsEmpty, "disable_destroy_environments": policy.DisableDestroyEnvironments, "skip_redundant_deployments": policy.SkipRedundantDeployments, + "run_pull_request_plan_default": policy.RunPullRequestPlanDefault, + "continuous_deployment_default": policy.ContinuousDeploymentDefault, }), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(accessor, "project_id", policy.ProjectId), @@ -67,6 +69,8 @@ func TestUnitPolicyResource(t *testing.T) { resource.TestCheckResourceAttr(accessor, "skip_apply_when_plan_is_empty", strconv.FormatBool(policy.SkipApplyWhenPlanIsEmpty)), resource.TestCheckResourceAttr(accessor, "disable_destroy_environments", strconv.FormatBool(policy.DisableDestroyEnvironments)), resource.TestCheckResourceAttr(accessor, "skip_redundant_deployments", strconv.FormatBool(policy.SkipRedundantDeployments)), + resource.TestCheckResourceAttr(accessor, "run_pull_request_plan_default", strconv.FormatBool(policy.RunPullRequestPlanDefault)), + resource.TestCheckResourceAttr(accessor, "continuous_deployment_default", strconv.FormatBool(policy.ContinuousDeploymentDefault)), ), }, { From a03f4a587149dac7ef7991caae22cb24ce533460 Mon Sep 17 00:00:00 2001 From: GiliFaroEnv0 Date: Tue, 23 Nov 2021 16:21:33 +0200 Subject: [PATCH 2/5] fix go fmt --- env0/resource_project_policy.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/env0/resource_project_policy.go b/env0/resource_project_policy.go index 5ac4e013..bfe5fb3f 100644 --- a/env0/resource_project_policy.go +++ b/env0/resource_project_policy.go @@ -94,17 +94,17 @@ func resourcePolicy() *schema.Resource { Computed: true, }, "run_pull_request_plan_default": { - Type: schema.TypeBool, - Description: "Run Terraform Plan on Pull Requests for new environments targeting their branch default value", - Optional: true, - Default: false, - }, - "continuous_deployment_default": { - Type: schema.TypeBool, - Description: "Redeploy on every push to the git branch default value", - Optional: true, - Default: false, - }, + Type: schema.TypeBool, + Description: "Run Terraform Plan on Pull Requests for new environments targeting their branch default value", + Optional: true, + Default: false, + }, + "continuous_deployment_default": { + Type: schema.TypeBool, + Description: "Redeploy on every push to the git branch default value", + Optional: true, + Default: false, + }, }, } } @@ -121,7 +121,7 @@ func setPolicySchema(d *schema.ResourceData, policy client.Policy) { d.Set("skip_redundant_deployments", policy.SkipRedundantDeployments) d.Set("updated_by", policy.UpdatedBy) d.Set("run_pull_request_plan_default", policy.RunPullRequestPlanDefault) - d.Set("continuous_deployment_default" , policy.ContinuousDeploymentDefault) + d.Set("continuous_deployment_default", policy.ContinuousDeploymentDefault) } func resourcePolicyCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { From 485d952db9ad33f6af7c279d97455bf0b0912b2c Mon Sep 17 00:00:00 2001 From: GiliFaroEnv0 Date: Tue, 23 Nov 2021 17:00:46 +0200 Subject: [PATCH 3/5] remove default values --- env0/resource_project_policy.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/env0/resource_project_policy.go b/env0/resource_project_policy.go index bfe5fb3f..414ec96f 100644 --- a/env0/resource_project_policy.go +++ b/env0/resource_project_policy.go @@ -66,7 +66,6 @@ func resourcePolicy() *schema.Resource { Type: schema.TypeBool, Description: "Requires approval default value when creating a new environment in the project", Optional: true, - Default: true, }, "include_cost_estimation": { Type: schema.TypeBool, @@ -97,13 +96,11 @@ func resourcePolicy() *schema.Resource { Type: schema.TypeBool, Description: "Run Terraform Plan on Pull Requests for new environments targeting their branch default value", Optional: true, - Default: false, }, "continuous_deployment_default": { Type: schema.TypeBool, Description: "Redeploy on every push to the git branch default value", Optional: true, - Default: false, }, }, } From 50ae45c0e3104a4cf8bedef74180d51aaf93023d Mon Sep 17 00:00:00 2001 From: GiliFaroEnv0 Date: Tue, 23 Nov 2021 17:02:35 +0200 Subject: [PATCH 4/5] remove id from update request --- client/model.go | 1 - 1 file changed, 1 deletion(-) diff --git a/client/model.go b/client/model.go index e277b7d4..352411be 100644 --- a/client/model.go +++ b/client/model.go @@ -258,7 +258,6 @@ type Policy struct { } type PolicyUpdatePayload struct { - Id string `json:"id"` ProjectId string `json:"projectId"` NumberOfEnvironments int `json:"numberOfEnvironments"` NumberOfEnvironmentsTotal int `json:"numberOfEnvironmentsTotal"` From 5e1b64d65dbfb68b74b36fe6fae93fc49e076432 Mon Sep 17 00:00:00 2001 From: GiliFaroEnv0 Date: Tue, 23 Nov 2021 17:03:20 +0200 Subject: [PATCH 5/5] remove updatedby from update request --- client/model.go | 1 - 1 file changed, 1 deletion(-) diff --git a/client/model.go b/client/model.go index 352411be..1bd375c7 100644 --- a/client/model.go +++ b/client/model.go @@ -266,7 +266,6 @@ type PolicyUpdatePayload struct { SkipApplyWhenPlanIsEmpty bool `json:"skipApplyWhenPlanIsEmpty"` DisableDestroyEnvironments bool `json:"disableDestroyEnvironments"` SkipRedundantDeployments bool `json:"skipRedundantDeployments"` - UpdatedBy string `json:"updatedBy"` RunPullRequestPlanDefault bool `json:"runPullRequestPlanDefault"` ContinuousDeploymentDefault bool `json:"continuousDeploymentDefault"` }