From f00b4f8ae14d0657ebf7907a22d8ba03558614bc Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 29 Nov 2023 12:04:01 -0800 Subject: [PATCH 1/4] Remove attribute conflict validation for 'cves' and 'vulnerabilities' Also remove 'Computed' attribute for 'cves'. Practitioners need to set "any" if 'vulnerabilities' is also set to 'any' to avoid state drift. Update documentation for the same. --- docs/resources/ignore_rule.md | 2 +- pkg/xray/resource_xray_ignore_rule.go | 20 +++---- pkg/xray/resource_xray_ignore_rule_test.go | 64 ++++++++++++++-------- 3 files changed, 49 insertions(+), 37 deletions(-) diff --git a/docs/resources/ignore_rule.md b/docs/resources/ignore_rule.md index 1ebae728..03dfe3ed 100644 --- a/docs/resources/ignore_rule.md +++ b/docs/resources/ignore_rule.md @@ -66,7 +66,7 @@ resource "xray_ignore_rule" "ignore-111" { - `artifact` (Block Set) List of specific artifacts to ignore. Omit to apply to all. (see [below for nested schema](#nestedblock--artifact)) - `build` (Block Set) List of specific builds to ignore. Omit to apply to all. (see [below for nested schema](#nestedblock--build)) - `component` (Block Set) List of specific components to ignore. Omit to apply to all. (see [below for nested schema](#nestedblock--component)) -- `cves` (Set of String) List of specific CVEs to ignore. Omit to apply to all. +- `cves` (Set of String) List of specific CVEs to ignore. Omit to apply to all. Should set to 'any' when 'vulnerabilities' is set to 'any'. - `docker_layers` (Set of String) List of Docker layer SHA256 hashes to ignore. Omit to apply to all. - `expiration_date` (String) The Ignore Rule will be active until the expiration date. At that date it will automatically get deleted. The rule with the expiration date less than current day, will error out. - `licenses` (Set of String) List of specific licenses to ignore. Omit to apply to all. diff --git a/pkg/xray/resource_xray_ignore_rule.go b/pkg/xray/resource_xray_ignore_rule.go index 47db8738..44038fe4 100644 --- a/pkg/xray/resource_xray_ignore_rule.go +++ b/pkg/xray/resource_xray_ignore_rule.go @@ -88,7 +88,7 @@ func resourceXrayIgnoreRule() *schema.Resource { Optional: true, ForceNew: true, Description: "List of specific vulnerabilities to ignore. Omit to apply to all.", - ConflictsWith: []string{"cves", "licenses", "operational_risk"}, + ConflictsWith: []string{"licenses", "operational_risk"}, Elem: &schema.Schema{ Type: schema.TypeString, }, @@ -97,9 +97,8 @@ func resourceXrayIgnoreRule() *schema.Resource { Type: schema.TypeSet, Optional: true, ForceNew: true, - Computed: true, // If "vulnerabilities" is set to "any" and "cves" omitted (user can't set a conflicting attribute), the value "any" for "cves" will be returned in the response body from the Xray anyway. To avoid state drift this attribute is "Computed". - Description: "List of specific CVEs to ignore. Omit to apply to all.", - ConflictsWith: []string{"vulnerabilities", "licenses", "operational_risk"}, + Description: "List of specific CVEs to ignore. Omit to apply to all. Should set to 'any' when 'vulnerabilities' is set to 'any'.", + ConflictsWith: []string{"licenses", "operational_risk"}, Elem: &schema.Schema{ Type: schema.TypeString, }, @@ -417,6 +416,7 @@ func resourceXrayIgnoreRule() *schema.Resource { ignoreFilters := IgnoreFilters{} data := &sdk.ResourceData{ResourceData: d} + vulnerabilities := data.GetSet("vulnerabilities") if len(vulnerabilities) > 0 { ignoreFilters.Vulnerabilities = vulnerabilities @@ -462,7 +462,7 @@ func resourceXrayIgnoreRule() *schema.Resource { } var resourceXrayIgnoreRuleRead = func(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - ignoreRule := IgnoreRule{} + var ignoreRule IgnoreRule projectKey := d.Get("project_key").(string) req, err := getRestyRequest(m.(sdk.ProvderMetadata).Client, projectKey) @@ -472,9 +472,7 @@ func resourceXrayIgnoreRule() *schema.Resource { resp, err := req. SetResult(&ignoreRule). - SetPathParams(map[string]string{ - "id": d.Id(), - }). + SetPathParam("id", d.Id()). Get("xray/api/v1/ignore_rules/{id}") if err != nil { if resp != nil && resp.StatusCode() == http.StatusNotFound { @@ -502,7 +500,7 @@ func resourceXrayIgnoreRule() *schema.Resource { Info string `json:"info"` } - response := IgnoreRuleCreateResponse{} + var response IgnoreRuleCreateResponse _, err = req. SetBody(ignoreRule). @@ -538,9 +536,7 @@ func resourceXrayIgnoreRule() *schema.Resource { } resp, err := req. - SetPathParams(map[string]string{ - "id": d.Id(), - }). + SetPathParam("id", d.Id()). Delete("xray/api/v1/ignore_rules/{id}") if err != nil && resp.StatusCode() == http.StatusInternalServerError { d.SetId("") diff --git a/pkg/xray/resource_xray_ignore_rule_test.go b/pkg/xray/resource_xray_ignore_rule_test.go index ec7d58bb..ed9f49f2 100644 --- a/pkg/xray/resource_xray_ignore_rule_test.go +++ b/pkg/xray/resource_xray_ignore_rule_test.go @@ -439,6 +439,7 @@ func TestAccIgnoreRule_docker_layers(t *testing.T) { notes = "fake notes" expiration_date = "{{ .expirationDate }}" vulnerabilities = ["any"] + cves = ["any"] docker_layers = [ "2ae0e4835a9a6e22e35dd0fcce7d7354999476b7dad8698d2d7a77c80bfc647b", @@ -527,6 +528,7 @@ func sourceTestCase(source string, t *testing.T) (*testing.T, resource.TestCase) notes = "fake notes" expiration_date = "{{ .expirationDate }}" vulnerabilities = ["any"] + cves = ["any"] {{ .source }} { name = "fake-name" @@ -573,6 +575,7 @@ func TestAccIgnoreRule_artifact(t *testing.T) { notes = "fake notes" expiration_date = "{{ .expirationDate }}" vulnerabilities = ["any"] + cves = ["any"] artifact { name = "fake-name" @@ -648,36 +651,49 @@ func TestAccIgnoreRule_invalid_artifact_path(t *testing.T) { func TestAccIgnoreRule_with_project_key(t *testing.T) { _, fqrn, name := testutil.MkNames("ignore-rule-", "xray_ignore_rule") expirationDate := time.Now().Add(time.Hour * 48) - projectKey := fmt.Sprintf("testproj%d", testutil.RandSelect(1, 2, 3, 4, 5)) + projectKey := fmt.Sprintf("testproj%d", testutil.RandomInt()) + + config := sdk.ExecuteTemplate( + "TestAccIgnoreRule", + `resource "project" "{{ .projectKey }}" { + key = "{{ .projectKey }}" + display_name = "{{ .projectKey }}" + admin_privileges { + manage_members = true + manage_resources = true + index_resources = true + } + } - config := sdk.ExecuteTemplate("TestAccIgnoreRule", ` resource "xray_ignore_rule" "{{ .name }}" { - notes = "fake notes" - expiration_date = "{{ .expirationDate }}" - vulnerabilities = ["any"] - project_key = "{{ .projectKey }}" + notes = "fake notes" + expiration_date = "{{ .expirationDate }}" + vulnerabilities = ["any"] + cves = ["any"] + project_key = project.{{ .projectKey }}.key - docker_layers = [ - "2ae0e4835a9a6e22e35dd0fcce7d7354999476b7dad8698d2d7a77c80bfc647b", - "a8db0e25d5916e70023114bb2d2497cd85327486bd6e0dc2092b349a1ab3a0a0" - ] - } - `, map[string]interface{}{ - "name": name, - "expirationDate": expirationDate.Format("2006-01-02"), - "projectKey": projectKey, - }) + build { + name = "fake-name" + version = "fake-version" + } + }`, + map[string]interface{}{ + "name": name, + "expirationDate": expirationDate.Format("2006-01-02"), + "projectKey": projectKey, + }, + ) resource.Test(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheck(t) - CreateProject(t, projectKey) - }, + PreCheck: func() { testAccPreCheck(t) }, ProviderFactories: testAccProviders(), - CheckDestroy: verifyDeleted(fqrn, func(id string, request *resty.Request) (*resty.Response, error) { - DeleteProject(t, projectKey) - return testCheckIgnoreRule(id, request) - }), + ExternalProviders: map[string]resource.ExternalProvider{ + "project": { + Source: "registry.terraform.io/jfrog/project", + VersionConstraint: "1.3.4", + }, + }, + CheckDestroy: verifyDeleted(fqrn, testCheckIgnoreRule), Steps: []resource.TestStep{ { Config: config, From 11487d972486a5eb39469169692754e1a732c2b7 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 29 Nov 2023 12:07:09 -0800 Subject: [PATCH 2/4] Update CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18112df4..fc4f80ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.0.4 (November 30, 2023) + +BUG FIXES: + +* resource/xray_ignore_rule: Remove validation against setting attributes `vulnerabilities` and `cves` at the same time. Removed `Computed` attribute for `cves` to avoid state drift and forced replacement. PR: [#151](https://github.com/jfrog/terraform-provider-xray/pull/151) Issue: [#148](https://github.com/jfrog/terraform-provider-xray/issues/148) + ## 2.0.3 (November 17, 2023). Tested on Artifactory 7.71.4 and Xray 3.85.5 BUG FIXES: From f6fe159f07464eea1751f92c6551bda5bbddf374 Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Wed, 29 Nov 2023 13:53:24 -0800 Subject: [PATCH 3/4] Update test with project_key --- pkg/xray/resource_xray_ignore_rule_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/xray/resource_xray_ignore_rule_test.go b/pkg/xray/resource_xray_ignore_rule_test.go index ed9f49f2..1a2986c9 100644 --- a/pkg/xray/resource_xray_ignore_rule_test.go +++ b/pkg/xray/resource_xray_ignore_rule_test.go @@ -672,10 +672,10 @@ func TestAccIgnoreRule_with_project_key(t *testing.T) { cves = ["any"] project_key = project.{{ .projectKey }}.key - build { - name = "fake-name" - version = "fake-version" - } + docker_layers = [ + "2ae0e4835a9a6e22e35dd0fcce7d7354999476b7dad8698d2d7a77c80bfc647b", + "a8db0e25d5916e70023114bb2d2497cd85327486bd6e0dc2092b349a1ab3a0a0" + ] }`, map[string]interface{}{ "name": name, From da9d9f6ffd9d632602fae09e32e2c979504d309a Mon Sep 17 00:00:00 2001 From: JFrog CI Date: Wed, 29 Nov 2023 22:34:02 +0000 Subject: [PATCH 4/4] 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 fc4f80ee..46c46e34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.4 (November 30, 2023) +## 2.0.4 (November 30, 2023). Tested on Artifactory 7.71.5 and Xray 3.86.3 BUG FIXES: