Skip to content

Commit 8755d30

Browse files
committed
fix(secure): validate mutual exclusivity of image_label sub-blocks
Combining multiple sub-blocks in a single image_label block caused silent state drift because the read path only reads Predicates[0]. This converts the silent data-loss bug into a clear validation error.
1 parent c0a2f8e commit 8755d30

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

sysdig/resource_sysdig_secure_vulnerability_rule_bundle.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,31 @@ func validateSeveritiesAndThreatsRule(ruleBody map[string]any) error {
766766
return nil
767767
}
768768

769+
func validateImageLabelRule(ruleBody map[string]any) error {
770+
count := 0
771+
if val, ok := ruleBody["label_must_exist"]; ok && val.(string) != "" {
772+
count++
773+
}
774+
if val, ok := ruleBody["label_must_not_exist"]; ok && val.(string) != "" {
775+
count++
776+
}
777+
if val, ok := ruleBody["label_must_exist_and_contain_value"]; ok && len(val.([]any)) > 0 {
778+
count++
779+
}
780+
if val, ok := ruleBody["label_with_value_and_required_labels"]; ok && len(val.([]any)) > 0 {
781+
count++
782+
}
783+
if count > 1 {
784+
return errors.New("only one image label predicate can be set per image_label block")
785+
}
786+
return nil
787+
}
788+
769789
func vulnerabilityRuleImageConfigLabelFromMap(ruleBody map[string]any) (v2.VulnerabilityRule, error) {
790+
if err := validateImageLabelRule(ruleBody); err != nil {
791+
return v2.VulnerabilityRule{}, err
792+
}
793+
770794
rule := v2.VulnerabilityRule{
771795
ID: new(ruleBody["id"].(string)),
772796
Type: v2.VulnerabilityRuleTypeImageConfigLabel,

sysdig/resource_sysdig_secure_vulnerability_rule_bundle_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ func TestAccVulnerabilityRuleBundle(t *testing.T) {
6363
Config: errorVulnerabilityRuleBundleConfig_ExploitConflict(random()),
6464
ExpectError: regexp.MustCompile("`public_exploit_available` and `public_exploit_available_since_days` are mutually exclusive"),
6565
},
66+
{
67+
Config: errorVulnerabilityRuleBundleConfig_ImageLabelConflict(random()),
68+
ExpectError: regexp.MustCompile("only one image label predicate can be set"),
69+
},
6670
{
6771
Config: minimalVulnerabilityRuleBundleConfig_ImageLabel(random()),
6872
Check: resource.ComposeTestCheckFunc(
@@ -428,6 +432,24 @@ resource "sysdig_secure_vulnerability_rule_bundle" "sample" {
428432
`, suffix)
429433
}
430434

435+
func errorVulnerabilityRuleBundleConfig_ImageLabelConflict(suffix string) string {
436+
return fmt.Sprintf(`
437+
resource "sysdig_secure_vulnerability_rule_bundle" "sample" {
438+
name = "TERRAFORM TEST %s"
439+
rule {
440+
image_label {
441+
label_must_exist = "required-label"
442+
label_with_value_and_required_labels {
443+
target_label = "Vendor"
444+
target_value = "BNPP"
445+
required_labels = ["Team", "Org"]
446+
}
447+
}
448+
}
449+
}
450+
`, suffix)
451+
}
452+
431453
func variantVulnerabilityRuleBundleConfig_DisclosureDate(suffix string) string {
432454
return fmt.Sprintf(`
433455
resource "sysdig_secure_vulnerability_rule_bundle" "sample" {

0 commit comments

Comments
 (0)