From 5083e958ec092385bf2a27c9a0222df9cf1e4cb9 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Tue, 26 Sep 2023 14:00:55 -0700 Subject: [PATCH 1/3] Remove default values from op_risk_custom criteria So they will be default to Golang default value (0) which in combination of 'omitempty', will mean they are not sent to API if not specify in HCL. This will allow the attribute/setting to be unset. --- GNUmakefile | 2 +- docs/resources/operational_risk_policy.md | 2 +- pkg/xray/policies.go | 12 +- .../resource_xray_operational_risk_policy.go | 7 +- ...ource_xray_operational_risk_policy_test.go | 124 ++++++++++++++++++ 5 files changed, 133 insertions(+), 14 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 5b43c018..1e905c93 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -27,7 +27,7 @@ install: clean build terraform init clean: - rm -fR dist terraform.d/ .terraform terraform.tfstate* terraform.d/ .terraform.lock.hcl + rm -fR dist terraform.d/ .terraform terraform.tfstate* .terraform.lock.hcl release: @git tag ${NEXT_VERSION} && git push --mirror diff --git a/docs/resources/operational_risk_policy.md b/docs/resources/operational_risk_policy.md index 6ddf081e..2872fbdb 100644 --- a/docs/resources/operational_risk_policy.md +++ b/docs/resources/operational_risk_policy.md @@ -150,7 +150,7 @@ Optional: Optional: - `op_risk_custom` (Block List, Max: 1) Custom Condition (see [below for nested schema](#nestedblock--rule--criteria--op_risk_custom)) -- `op_risk_min_risk` (String) The minimum operational risk that will be impacted by the policy. +- `op_risk_min_risk` (String) The minimum operational risk that will be impacted by the policy: High, Medium, Low ### Nested Schema for `rule.criteria.op_risk_custom` diff --git a/pkg/xray/policies.go b/pkg/xray/policies.go index 643b9437..52c5afd7 100644 --- a/pkg/xray/policies.go +++ b/pkg/xray/policies.go @@ -187,12 +187,12 @@ type PolicyExposures struct { type OperationalRiskCriteria struct { UseAndCondition bool `json:"use_and_condition"` IsEOL bool `json:"is_eol"` - ReleaseDateGreaterThanMonths int `json:"release_date_greater_than_months"` - NewerVersionsGreaterThan int `json:"newer_versions_greater_than"` - ReleaseCadencePerYearLessThan int `json:"release_cadence_per_year_less_than"` - CommitsLessThan int `json:"commits_less_than"` - CommittersLessThan int `json:"committers_less_than"` - Risk string `json:"risk"` + ReleaseDateGreaterThanMonths int `json:"release_date_greater_than_months,omitempty"` + NewerVersionsGreaterThan int `json:"newer_versions_greater_than,omitempty"` + ReleaseCadencePerYearLessThan int `json:"release_cadence_per_year_less_than,omitempty"` + CommitsLessThan int `json:"commits_less_than,omitempty"` + CommittersLessThan int `json:"committers_less_than,omitempty"` + Risk string `json:"risk,omitempty"` } type PolicyRuleCriteria struct { diff --git a/pkg/xray/resource_xray_operational_risk_policy.go b/pkg/xray/resource_xray_operational_risk_policy.go index b7a829dd..890cc8ae 100644 --- a/pkg/xray/resource_xray_operational_risk_policy.go +++ b/pkg/xray/resource_xray_operational_risk_policy.go @@ -38,7 +38,7 @@ func resourceXrayOperationalRiskPolicy() *schema.Resource { "op_risk_min_risk": { Type: schema.TypeString, Optional: true, - Description: "The minimum operational risk that will be impacted by the policy.", + Description: "The minimum operational risk that will be impacted by the policy: High, Medium, Low", ValidateDiagFunc: validator.StringInSlice(true, "High", "Medium", "Low"), }, "op_risk_custom": { @@ -62,35 +62,30 @@ func resourceXrayOperationalRiskPolicy() *schema.Resource { "release_date_greater_than_months": { Type: schema.TypeInt, Optional: true, - Default: 6, Description: "Release age greater than (in months): 6, 12, 18, 24, 30, or 36", ValidateDiagFunc: validation.ToDiagFunc(validation.IntInSlice([]int{6, 12, 18, 24, 30, 36})), }, "newer_versions_greater_than": { Type: schema.TypeInt, Optional: true, - Default: 1, Description: "Number of releases since greater than: 1, 2, 3, 4, or 5", ValidateDiagFunc: validation.ToDiagFunc(validation.IntInSlice([]int{1, 2, 3, 4, 5})), }, "release_cadence_per_year_less_than": { Type: schema.TypeInt, Optional: true, - Default: 1, Description: "Release cadence less than per year: 1, 2, 3, 4, or 5", ValidateDiagFunc: validation.ToDiagFunc(validation.IntInSlice([]int{1, 2, 3, 4, 5})), }, "commits_less_than": { Type: schema.TypeInt, Optional: true, - Default: 10, Description: "Number of commits less than per year: 10, 25, 50, or 100", ValidateDiagFunc: validation.ToDiagFunc(validation.IntInSlice([]int{10, 25, 50, 100})), }, "committers_less_than": { Type: schema.TypeInt, Optional: true, - Default: 1, Description: "Number of committers less than per year: 1, 2, 3, 4, or 5", ValidateDiagFunc: validation.ToDiagFunc(validation.IntInSlice([]int{1, 2, 3, 4, 5})), }, diff --git a/pkg/xray/resource_xray_operational_risk_policy_test.go b/pkg/xray/resource_xray_operational_risk_policy_test.go index f6ff41f8..4a8e6b52 100644 --- a/pkg/xray/resource_xray_operational_risk_policy_test.go +++ b/pkg/xray/resource_xray_operational_risk_policy_test.go @@ -202,6 +202,35 @@ func TestAccOperationalRiskPolicy_customCriteria(t *testing.T) { testData["op_risk_custom_committers_less_than"] = testutil.RandSelect("1", "2", "3", "4", "5").(string) testData["op_risk_custom_risk"] = testutil.RandSelect("high", "medium", "low").(string) + const opertionalRiskPolicyCustomUnset = `resource "xray_operational_risk_policy" "{{ .resource_name }}" { + name = "{{ .policy_name }}" + description = "{{ .policy_description }}" + type = "operational_risk" + rule { + name = "{{ .rule_name }}" + priority = 1 + criteria { + op_risk_custom { + use_and_condition = {{ .op_risk_custom_use_and_condition }} + is_eol = {{ .op_risk_custom_is_eol }} + risk = "{{ .op_risk_custom_risk }}" + } + } + actions { + block_release_bundle_distribution = {{ .block_release_bundle_distribution }} + fail_build = {{ .fail_build }} + notify_watch_recipients = {{ .notify_watch_recipients }} + notify_deployer = {{ .notify_deployer }} + create_ticket_enabled = {{ .create_ticket_enabled }} + build_failure_grace_period_in_days = {{ .grace_period_days }} + block_download { + unscanned = {{ .block_unscanned }} + active = {{ .block_active }} + } + } + } + }` + resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, CheckDestroy: verifyDeleted(fqrn, testCheckPolicy), @@ -221,6 +250,20 @@ func TestAccOperationalRiskPolicy_customCriteria(t *testing.T) { resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.risk", testData["op_risk_custom_risk"]), ), }, + { + Config: sdk.ExecuteTemplate(fqrn, opertionalRiskPolicyCustomUnset, testData), + Check: resource.ComposeTestCheckFunc( + verifyOpertionalRiskPolicy(fqrn, testData), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.use_and_condition", testData["op_risk_custom_use_and_condition"]), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.is_eol", testData["op_risk_custom_is_eol"]), + resource.TestCheckNoResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.release_date_greater_than_months"), + resource.TestCheckNoResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.newer_versions_greater_than"), + resource.TestCheckNoResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.release_cadence_per_year_less_than"), + resource.TestCheckNoResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.commits_less_than"), + resource.TestCheckNoResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.committers_less_than"), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.risk", testData["op_risk_custom_risk"]), + ), + }, { ResourceName: fqrn, ImportState: true, @@ -230,6 +273,87 @@ func TestAccOperationalRiskPolicy_customCriteria(t *testing.T) { }) } +func TestAccOperationalRiskPolicy_customCriteria_migration(t *testing.T) { + _, fqrn, resourceName := testutil.MkNames("policy-", "xray_operational_risk_policy") + + const opertionalRiskPolicyCustom = `resource "xray_operational_risk_policy" "{{ .resource_name }}" { + name = "{{ .policy_name }}" + description = "{{ .policy_description }}" + type = "operational_risk" + rule { + name = "{{ .rule_name }}" + priority = 1 + criteria { + op_risk_custom { + use_and_condition = {{ .op_risk_custom_use_and_condition }} + is_eol = {{ .op_risk_custom_is_eol }} + risk = "{{ .op_risk_custom_risk }}" + } + } + actions { + block_release_bundle_distribution = {{ .block_release_bundle_distribution }} + fail_build = {{ .fail_build }} + notify_watch_recipients = {{ .notify_watch_recipients }} + notify_deployer = {{ .notify_deployer }} + create_ticket_enabled = {{ .create_ticket_enabled }} + build_failure_grace_period_in_days = {{ .grace_period_days }} + block_download { + unscanned = {{ .block_unscanned }} + active = {{ .block_active }} + } + } + } + }` + + testData := sdk.MergeMaps(testDataOperationalRisk) + testData["resource_name"] = resourceName + testData["op_risk_custom_use_and_condition"] = "true" + testData["op_risk_custom_is_eol"] = "false" + testData["op_risk_custom_risk"] = testutil.RandSelect("high", "medium", "low").(string) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + CheckDestroy: verifyDeleted(fqrn, testCheckPolicy), + Steps: []resource.TestStep{ + { + ExternalProviders: map[string]resource.ExternalProvider{ + "xray": { + VersionConstraint: "1.18.0", + Source: "registry.terraform.io/jfrog/xray", + }, + }, + Config: sdk.ExecuteTemplate(fqrn, opertionalRiskPolicyCustom, testData), + Check: resource.ComposeTestCheckFunc( + verifyOpertionalRiskPolicy(fqrn, testData), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.use_and_condition", testData["op_risk_custom_use_and_condition"]), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.is_eol", testData["op_risk_custom_is_eol"]), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.release_date_greater_than_months", "6"), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.newer_versions_greater_than", "1"), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.release_cadence_per_year_less_than", "1"), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.commits_less_than", "10"), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.committers_less_than", "1"), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.risk", testData["op_risk_custom_risk"]), + ), + }, + { + ProviderFactories: testAccProviders(), + Config: sdk.ExecuteTemplate(fqrn, opertionalRiskPolicyCustom, testData), + Check: resource.ComposeTestCheckFunc( + verifyOpertionalRiskPolicy(fqrn, testData), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.use_and_condition", testData["op_risk_custom_use_and_condition"]), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.is_eol", testData["op_risk_custom_is_eol"]), + resource.TestCheckNoResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.release_date_greater_than_months"), + resource.TestCheckNoResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.newer_versions_greater_than"), + resource.TestCheckNoResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.release_cadence_per_year_less_than"), + resource.TestCheckNoResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.commits_less_than"), + resource.TestCheckNoResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.committers_less_than"), + resource.TestCheckResourceAttr(fqrn, "rule.0.criteria.0.op_risk_custom.0.risk", testData["op_risk_custom_risk"]), + ), + }, + }, + }) +} + func verifyOpertionalRiskPolicy(fqrn string, testData map[string]string) resource.TestCheckFunc { return resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(fqrn, "name", testData["policy_name"]), From 52c399a0882cf71f3e79648ff9c9d37f740fefc2 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Tue, 26 Sep 2023 14:13:55 -0700 Subject: [PATCH 2/3] Update CHANGELOG --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 493caeb3..f560c76b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 2.0.0 (September 27, 2023) + + BREAKING CHANGES: + + * resource/xray_operational_risk_policy: remove default values for attributes `op_risk_custom.release_date_greater_than_months`, `op_risk_custom.newer_versions_greater_than`, `op_risk_custom.release_cadence_per_year_less_than`, `op_risk_custom.commits_less_than`, and `op_risk_custom.committers_less_than`. They are now require to be defined explicitly if you wish to set any values. There may be state drifts for this policy resource as the provide code can't distinguish between default values vs configuration values so it can't automatically upgrade the TF state. + +PR: [#140](https://github.com/jfrog/terraform-provider-xray/pull/140) +Issue: [#138](https://github.com/jfrog/terraform-provider-xray/issues/138) + ## 1.18.0 (September 26, 2023). Tested on Artifactory 7.68.11 and Xray 3.82.11 FEATURES: From 7a71d69878b1bf500442c09a49432a723a90f93e Mon Sep 17 00:00:00 2001 From: JFrog CI Date: Tue, 26 Sep 2023 21:52:09 +0000 Subject: [PATCH 3/3] JFrog Pipelines - Add Artifactory and Xray versions to CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f560c76b..16a58265 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.0 (September 27, 2023) +## 2.0.0 (September 27, 2023). Tested on Artifactory 7.68.11 and Xray 3.82.11 BREAKING CHANGES: