Skip to content

Commit 32213ba

Browse files
authored
fix(vuln-rule-bundle): replace TypeList with TypeSet to ignore ordering (#674)
The API does not keep the order for rule bundle rules. This change ensures that there won't be undesired updates for resources that should not change, because the API will not return the rules always in the same order.
1 parent cd126c2 commit 32213ba

File tree

2 files changed

+89
-81
lines changed

2 files changed

+89
-81
lines changed

sysdig/resource_sysdig_secure_vulnerability_rule_bundle.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func resourceSysdigSecureVulnerabilityRuleBundle() *schema.Resource {
9898
},
9999

100100
"rule": {
101-
Type: schema.TypeList,
101+
Type: schema.TypeSet,
102102
Required: true,
103103
MinItems: 1,
104104
Description: "Rules for this bundle",
@@ -606,7 +606,7 @@ func vulnerabilityRuleBundleFromResourceData(d *schema.ResourceData) (v2.Vulnera
606606
return &idAsInt
607607
}
608608

609-
rules, err := vulnerabilityRulesFromList(d.Get("rule").([]any))
609+
rules, err := vulnerabilityRulesFromList(d.Get("rule").(*schema.Set).List())
610610
if err != nil {
611611
return v2.VulnerabilityRuleBundle{}, err
612612
}
@@ -621,7 +621,10 @@ func vulnerabilityRuleBundleFromResourceData(d *schema.ResourceData) (v2.Vulnera
621621
}
622622

623623
func vulnerabilityRulesFromList(list []any) ([]v2.VulnerabilityRule, error) {
624-
var out []v2.VulnerabilityRule
624+
if len(list) == 0 {
625+
return nil, fmt.Errorf("empty rule detected, you need to specify one")
626+
}
627+
out := []v2.VulnerabilityRule{}
625628

626629
for _, ruleRaw := range list {
627630
if ruleRaw == nil {

sysdig/resource_sysdig_secure_vulnerability_rule_bundle_test.go

Lines changed: 83 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,22 @@ func TestAccVulnerabilityRuleBundle(t *testing.T) {
7676
),
7777
},
7878
{
79-
Config: fullVulnerabilityRuleBundleConfig_ImageLabel(random()),
79+
Config: singleRuleConfig_label_must_not_exist(random()),
8080
Check: resource.ComposeTestCheckFunc(
8181
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.0.image_label.0.label_must_not_exist", "forbidden-label"),
82-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.1.image_label.0.label_must_exist", "another-required-label"),
83-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.2.image_label.0.label_must_exist_and_contain_value.0.required_label", "required-label"),
84-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.2.image_label.0.label_must_exist_and_contain_value.0.required_value", "required-value"),
82+
),
83+
},
84+
{
85+
Config: singleRuleConfig_label_must_exist(random()),
86+
Check: resource.ComposeTestCheckFunc(
87+
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.0.image_label.0.label_must_exist", "another-required-label"),
88+
),
89+
},
90+
{
91+
Config: singleRuleConfig_label_must_exist_and_contain_value(random()),
92+
Check: resource.ComposeTestCheckFunc(
93+
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.0.image_label.0.label_must_exist_and_contain_value.0.required_label", "required-label"),
94+
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.0.image_label.0.label_must_exist_and_contain_value.0.required_value", "required-value"),
8595
),
8696
},
8797
{
@@ -103,29 +113,6 @@ func TestAccVulnerabilityRuleBundle(t *testing.T) {
103113
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.0.severities_and_threats.0.epss_percentile_at_least_percentage", "90"),
104114
),
105115
},
106-
{
107-
Config: fullVulnerabilityRuleBundleConfig_AllTypes(random()),
108-
Check: resource.ComposeTestCheckFunc(
109-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.0.image_label.0.label_must_not_exist", "forbidden-label"),
110-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.1.image_label.0.label_must_exist", "another-required-label"),
111-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.2.image_label.0.label_must_exist_and_contain_value.0.required_label", "required-label"),
112-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.2.image_label.0.label_must_exist_and_contain_value.0.required_value", "required-value"),
113-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.severity_at_least", "high"),
114-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.disclosure_older_than_days", "90"),
115-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.package_type", "os"),
116-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.in_use", "true"),
117-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.fix_available_since_days", "30"),
118-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.public_exploit_available_since_days", "15"),
119-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.exploit_no_admin_privileges", "true"),
120-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.exploit_no_user_interaction", "true"),
121-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.exploit_network_attack_vector", "true"),
122-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.cisa_kev_in_ransomware_campaign", "true"),
123-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.cisa_kev_available_since_days", "10"),
124-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.cisa_kev_due_date_in_days", "21"),
125-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.epss_score_at_least_percentage", "80"),
126-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.3.severities_and_threats.0.epss_percentile_at_least_percentage", "90"),
127-
),
128-
},
129116
{
130117
Config: variantVulnerabilityRuleBundleConfig_SeverityEquals(random()),
131118
Check: resource.ComposeTestCheckFunc(
@@ -157,6 +144,9 @@ func TestAccVulnerabilityRuleBundle(t *testing.T) {
157144
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_rule_bundle.sample", "rule.0.severities_and_threats.0.fix_available", "true"),
158145
),
159146
},
147+
{
148+
Config: fullVulnerabilityRuleBundleConfig_AllTypes(random()),
149+
},
160150
{
161151
ResourceName: "sysdig_secure_vulnerability_rule_bundle.sample",
162152
ImportState: true,
@@ -224,82 +214,39 @@ resource "sysdig_secure_vulnerability_rule_bundle" "sample" {
224214
`, suffix)
225215
}
226216

227-
func fullVulnerabilityRuleBundleConfig_ImageLabel(suffix string) string {
217+
func singleRuleConfig_label_must_not_exist(suffix string) string {
228218
return fmt.Sprintf(`
229219
resource "sysdig_secure_vulnerability_rule_bundle" "sample" {
230220
name = "TERRAFORM TEST %s"
231-
description = "Full bundle with image_label rules"
232-
221+
description = "rule with label_must_not_exist"
233222
rule {
234223
image_label {
235224
label_must_not_exist = "forbidden-label"
236225
}
237226
}
238-
239-
rule {
240-
image_label {
241-
label_must_exist = "another-required-label"
242-
}
243-
}
244-
245-
rule {
246-
image_label {
247-
label_must_exist_and_contain_value {
248-
required_label = "required-label"
249-
required_value = "required-value"
250-
}
251-
}
252-
}
253227
}
254228
`, suffix)
255229
}
256230

257-
func fullVulnerabilityRuleBundleConfig_Severities(suffix string) string {
231+
func singleRuleConfig_label_must_exist(suffix string) string {
258232
return fmt.Sprintf(`
259233
resource "sysdig_secure_vulnerability_rule_bundle" "sample" {
260234
name = "TERRAFORM TEST %s"
261-
description = "Full bundle with severities_and_threats rules"
262-
235+
description = "rule with label_must_exist"
263236
rule {
264-
severities_and_threats {
265-
severity_at_least = "high"
266-
disclosure_older_than_days = 90
267-
package_type = "os"
268-
in_use = true
269-
fix_available_since_days = 30
270-
public_exploit_available_since_days = 15
271-
exploit_no_admin_privileges = true
272-
exploit_no_user_interaction = true
273-
exploit_network_attack_vector = true
274-
cisa_kev_in_ransomware_campaign = true
275-
cisa_kev_available_since_days = 10
276-
cisa_kev_due_date_in_days = 21
277-
epss_score_at_least_percentage = 80
278-
epss_percentile_at_least_percentage = 90
237+
image_label {
238+
label_must_exist = "another-required-label"
279239
}
280240
}
281241
}
282242
`, suffix)
283243
}
284244

285-
func fullVulnerabilityRuleBundleConfig_AllTypes(suffix string) string {
245+
func singleRuleConfig_label_must_exist_and_contain_value(suffix string) string {
286246
return fmt.Sprintf(`
287247
resource "sysdig_secure_vulnerability_rule_bundle" "sample" {
288248
name = "TERRAFORM TEST %s"
289-
description = "Full bundle with all rule types"
290-
291-
rule {
292-
image_label {
293-
label_must_not_exist = "forbidden-label"
294-
}
295-
}
296-
297-
rule {
298-
image_label {
299-
label_must_exist = "another-required-label"
300-
}
301-
}
302-
249+
description = "rule with label_must_exist_and_contain_value"
303250
rule {
304251
image_label {
305252
label_must_exist_and_contain_value {
@@ -308,6 +255,15 @@ resource "sysdig_secure_vulnerability_rule_bundle" "sample" {
308255
}
309256
}
310257
}
258+
}
259+
`, suffix)
260+
}
261+
262+
func fullVulnerabilityRuleBundleConfig_Severities(suffix string) string {
263+
return fmt.Sprintf(`
264+
resource "sysdig_secure_vulnerability_rule_bundle" "sample" {
265+
name = "TERRAFORM TEST %s"
266+
description = "Full bundle with severities_and_threats rules"
311267
312268
rule {
313269
severities_and_threats {
@@ -485,3 +441,52 @@ resource "sysdig_secure_vulnerability_rule_bundle" "sample" {
485441
}
486442
`, suffix)
487443
}
444+
445+
func fullVulnerabilityRuleBundleConfig_AllTypes(suffix string) string {
446+
return fmt.Sprintf(`
447+
resource "sysdig_secure_vulnerability_rule_bundle" "sample" {
448+
name = "TERRAFORM TEST %s"
449+
description = "Full bundle with all rule types"
450+
451+
rule {
452+
image_label {
453+
label_must_not_exist = "forbidden-label"
454+
}
455+
}
456+
457+
rule {
458+
image_label {
459+
label_must_exist = "another-required-label"
460+
}
461+
}
462+
463+
rule {
464+
image_label {
465+
label_must_exist_and_contain_value {
466+
required_label = "required-label"
467+
required_value = "required-value"
468+
}
469+
}
470+
}
471+
472+
rule {
473+
severities_and_threats {
474+
severity_at_least = "high"
475+
disclosure_older_than_days = 90
476+
package_type = "os"
477+
in_use = true
478+
fix_available_since_days = 30
479+
public_exploit_available_since_days = 15
480+
exploit_no_admin_privileges = true
481+
exploit_no_user_interaction = true
482+
exploit_network_attack_vector = true
483+
cisa_kev_in_ransomware_campaign = true
484+
cisa_kev_available_since_days = 10
485+
cisa_kev_due_date_in_days = 21
486+
epss_score_at_least_percentage = 80
487+
epss_percentile_at_least_percentage = 90
488+
}
489+
}
490+
}
491+
`, suffix)
492+
}

0 commit comments

Comments
 (0)