diff --git a/CHANGELOG.md b/CHANGELOG.md index 18112df4..46c46e34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.0.4 (November 30, 2023). Tested on Artifactory 7.71.5 and Xray 3.86.3 + +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: 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..1a2986c9 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 }}" - - docker_layers = [ - "2ae0e4835a9a6e22e35dd0fcce7d7354999476b7dad8698d2d7a77c80bfc647b", - "a8db0e25d5916e70023114bb2d2497cd85327486bd6e0dc2092b349a1ab3a0a0" - ] - } - `, map[string]interface{}{ - "name": name, - "expirationDate": expirationDate.Format("2006-01-02"), - "projectKey": 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, + }, + ) 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,