Skip to content

Commit 2082fa9

Browse files
authored
feat: Add sysdig_secure_vulnerability_rule_bundle resource (#663)
* feat: add first initial vulnerability rule bundle resource * feat: add label_must_not_exist rule bundle * feat: add label_must_exist_and_contain_value image label rule * refactor: rename fields * refactor: replace iter with a simpler for loop * feat: make the list of rules keep order * ci: add more verifications to validate the resource * ci: add a sysdig_secure_vulnerability_rule_bundle reference to sysdig_secure_vulnerability_policy test * chore: add description to the fields in resource * docs: add documentation for secure_vulnerability_rule_bundle * fix(docs): add required line by tfproviderdocs lint
1 parent 2de87b4 commit 2082fa9

8 files changed

+796
-3
lines changed

sysdig/internal/client/v2/sysdig.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ type SysdigSecure interface {
5555
PolicyInterface
5656
RuleInterface
5757
VulnerabilityPolicyClient
58+
VulnerabilityRuleBundleClient
5859
}
5960

6061
func (sr *SysdigRequest) Request(ctx context.Context, method string, url string, payload io.Reader) (*http.Response, error) {
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package v2
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"net/http"
8+
"strconv"
9+
)
10+
11+
const (
12+
vulnerabilityRuleBundlesPath = "%s/secure/vulnerability/v1/bundles"
13+
vulnerabilityRuleBundlePath = "%s/secure/vulnerability/v1/bundles/%s"
14+
)
15+
16+
type VulnerabilityRuleBundleClient interface {
17+
CreateVulnerabilityRuleBundle(ctx context.Context, vulnerabilityRuleBundle VulnerabilityRuleBundle) (VulnerabilityRuleBundle, error)
18+
GetVulnerabilityRuleBundleByID(ctx context.Context, vulnerabilityRuleBundleID string) (VulnerabilityRuleBundle, error)
19+
UpdateVulnerabilityRuleBundle(ctx context.Context, vulnerabilityRuleBundle VulnerabilityRuleBundle) (VulnerabilityRuleBundle, error)
20+
DeleteVulnerabilityRuleBundleByID(ctx context.Context, vulnerabilityRuleBundleID string) error
21+
}
22+
23+
func (c *Client) CreateVulnerabilityRuleBundle(ctx context.Context, vulnerabilityRuleBundle VulnerabilityRuleBundle) (ruleBundle VulnerabilityRuleBundle, err error) {
24+
payload, err := Marshal(vulnerabilityRuleBundle)
25+
if err != nil {
26+
return VulnerabilityRuleBundle{}, err
27+
}
28+
29+
response, err := c.requester.Request(ctx, http.MethodPost, c.vulnerabilityRuleBundlesURL(), payload)
30+
if err != nil {
31+
return VulnerabilityRuleBundle{}, err
32+
}
33+
defer func() {
34+
if dErr := response.Body.Close(); dErr != nil {
35+
err = fmt.Errorf("unable to close response body: %w", dErr)
36+
}
37+
}()
38+
39+
if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated {
40+
return VulnerabilityRuleBundle{}, c.ErrorFromResponse(response)
41+
}
42+
43+
return Unmarshal[VulnerabilityRuleBundle](response.Body)
44+
}
45+
46+
func (c *Client) GetVulnerabilityRuleBundleByID(ctx context.Context, vulnerabilityRuleBundleID string) (ruleBundle VulnerabilityRuleBundle, err error) {
47+
response, err := c.requester.Request(ctx, http.MethodGet, c.vulnerabilityRuleBundleURL(vulnerabilityRuleBundleID), nil)
48+
if err != nil {
49+
return VulnerabilityRuleBundle{}, err
50+
}
51+
defer func() {
52+
if dErr := response.Body.Close(); dErr != nil {
53+
err = fmt.Errorf("unable to close response body: %w", dErr)
54+
}
55+
}()
56+
57+
if response.StatusCode != http.StatusOK {
58+
return VulnerabilityRuleBundle{}, c.ErrorFromResponse(response)
59+
}
60+
61+
return Unmarshal[VulnerabilityRuleBundle](response.Body)
62+
}
63+
64+
func (c *Client) UpdateVulnerabilityRuleBundle(ctx context.Context, vulnerabilityRuleBundle VulnerabilityRuleBundle) (ruleBundle VulnerabilityRuleBundle, err error) {
65+
if vulnerabilityRuleBundle.ID == nil {
66+
return VulnerabilityRuleBundle{}, errors.New("rule bundle id was null")
67+
}
68+
69+
payload, err := Marshal(vulnerabilityRuleBundle)
70+
if err != nil {
71+
return VulnerabilityRuleBundle{}, err
72+
}
73+
74+
idAsStr := strconv.Itoa(int(*vulnerabilityRuleBundle.ID))
75+
response, err := c.requester.Request(ctx, http.MethodPut, c.vulnerabilityRuleBundleURL(idAsStr), payload)
76+
if err != nil {
77+
return VulnerabilityRuleBundle{}, err
78+
}
79+
defer func() {
80+
if dErr := response.Body.Close(); dErr != nil {
81+
err = fmt.Errorf("unable to close response body: %w", dErr)
82+
}
83+
}()
84+
85+
if response.StatusCode != http.StatusOK {
86+
return VulnerabilityRuleBundle{}, c.ErrorFromResponse(response)
87+
}
88+
89+
return Unmarshal[VulnerabilityRuleBundle](response.Body)
90+
}
91+
92+
func (c *Client) DeleteVulnerabilityRuleBundleByID(ctx context.Context, vulnerabilityRuleBundleID string) (err error) {
93+
response, err := c.requester.Request(ctx, http.MethodDelete, c.vulnerabilityRuleBundleURL(vulnerabilityRuleBundleID), nil)
94+
if err != nil {
95+
return err
96+
}
97+
defer func() {
98+
if dErr := response.Body.Close(); dErr != nil {
99+
err = fmt.Errorf("unable to close response body: %w", dErr)
100+
}
101+
}()
102+
103+
if response.StatusCode != http.StatusNoContent && response.StatusCode != http.StatusOK {
104+
return c.ErrorFromResponse(response)
105+
}
106+
107+
return err
108+
}
109+
110+
func (c *Client) vulnerabilityRuleBundlesURL() string {
111+
return fmt.Sprintf(vulnerabilityRuleBundlesPath, c.config.url)
112+
}
113+
114+
func (c *Client) vulnerabilityRuleBundleURL(vulnerabilityRuleBundleID string) string {
115+
return fmt.Sprintf(vulnerabilityRuleBundlePath, c.config.url, vulnerabilityRuleBundleID)
116+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package v2
2+
3+
type VulnerabilityRuleBundle struct {
4+
ID *int `json:"id,omitempty"`
5+
Name string `json:"name"`
6+
Identifier *string `json:"identifier,omitempty"`
7+
Description *string `json:"description,omitempty"`
8+
Rules []VulnerabilityRule `json:"rules"`
9+
}
10+
11+
type VulnerabilityRule struct {
12+
ID *string `json:"ruleId,omitempty"`
13+
Type VulnerabilityRuleType `json:"ruleType"`
14+
Predicates []VulnerabilityRulePredicate `json:"predicates"`
15+
}
16+
17+
type VulnerabilityRulePredicate struct {
18+
Type string `json:"type"`
19+
Extra *VulnerabilityRulePredicateExtra `json:"extra,omitempty"`
20+
}
21+
22+
type VulnerabilityRulePredicateExtra struct {
23+
Level *Level `json:"level,omitempty"`
24+
Age *int `json:"age,omitempty"`
25+
VulnIDS []string `json:"vulnIds,omitempty"`
26+
Value *string `json:"value,omitempty"`
27+
Packages []Package `json:"packages,omitempty"`
28+
Key *string `json:"key,omitempty"`
29+
User *string `json:"user,omitempty"`
30+
PkgType *string `json:"pkgType,omitempty"`
31+
}
32+
33+
type Package struct {
34+
Name string `json:"name"`
35+
Version string `json:"version"`
36+
}
37+
38+
type Level string
39+
40+
const (
41+
Critical Level = "critical"
42+
High Level = "high"
43+
Medium Level = "medium"
44+
)
45+
46+
type VulnerabilityRuleType string
47+
48+
const (
49+
VulnerabilityRuleTypeImageConfigCreationDate VulnerabilityRuleType = "imageConfigCreationDate"
50+
VulnerabilityRuleTypeImageConfigDefaultUser VulnerabilityRuleType = "imageConfigDefaultUser"
51+
VulnerabilityRuleTypeImageConfigEnvVariable VulnerabilityRuleType = "imageConfigEnvVariable"
52+
VulnerabilityRuleTypeImageConfigInstructionIsPkgManager VulnerabilityRuleType = "imageConfigInstructionIsPkgManager"
53+
VulnerabilityRuleTypeImageConfigInstructionNotRecommended VulnerabilityRuleType = "imageConfigInstructionNotRecommended"
54+
VulnerabilityRuleTypeImageConfigLabel VulnerabilityRuleType = "imageConfigLabel"
55+
VulnerabilityRuleTypeImageConfigSensitiveInformationAndSecrets VulnerabilityRuleType = "imageConfigSensitiveInformationAndSecrets"
56+
VulnerabilityRuleTypePkgDenyList VulnerabilityRuleType = "pkgDenyList"
57+
VulnerabilityRuleTypeVulnDenyList VulnerabilityRuleType = "vulnDenyList"
58+
VulnerabilityRuleTypeVulnSeverityAndThreats VulnerabilityRuleType = "vulnSeverityAndThreats"
59+
)

sysdig/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ func (p *SysdigProvider) Provider() *schema.Provider {
200200
"sysdig_secure_team": resourceSysdigSecureTeam(),
201201
"sysdig_secure_vulnerability_accept_risk": resourceSysdigSecureVulnerabilityAcceptRisk(),
202202
"sysdig_secure_vulnerability_policy": resourceSysdigSecureVulnerabilityPolicy(),
203+
"sysdig_secure_vulnerability_rule_bundle": resourceSysdigSecureVulnerabilityRuleBundle(),
203204
"sysdig_secure_zone": resourceSysdigSecureZone(),
204205
},
205206
DataSourcesMap: map[string]*schema.Resource{

sysdig/resource_sysdig_secure_vulnerability_policy_test.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func TestAccVulnerabilityPolicy(t *testing.T) {
3232
{
3333
Config: vulnerabilityPolicyConfig(random()),
3434
Check: resource.ComposeTestCheckFunc(
35-
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_policy.sample", "bundles.#", "1"),
35+
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_policy.sample", "bundles.#", "2"),
3636
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_policy.sample", "bundles.0", "1"),
3737
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_policy.sample", "stages.#", "3"),
3838
),
@@ -57,11 +57,20 @@ resource "sysdig_secure_vulnerability_policy" "sample" {
5757

5858
func vulnerabilityPolicyConfig(suffix string) string {
5959
return fmt.Sprintf(`
60+
resource "sysdig_secure_vulnerability_rule_bundle" "sample" {
61+
name = "TERRAFORM TEST %s"
62+
rule {
63+
image_label {
64+
label_must_exist = "required-label"
65+
}
66+
}
67+
}
68+
6069
resource "sysdig_secure_vulnerability_policy" "sample" {
6170
name = "TERRAFORM TEST %s"
6271
description = "Acceptance test for bundles as ordered list %s"
6372
64-
bundles = [ "1" ]
73+
bundles = [ "1", sysdig_secure_vulnerability_rule_bundle.sample.id ]
6574
6675
stages {
6776
name = "pipeline"
@@ -82,5 +91,5 @@ resource "sysdig_secure_vulnerability_policy" "sample" {
8291
}
8392
}
8493
}
85-
`, suffix, suffix)
94+
`, suffix, suffix, suffix)
8695
}

0 commit comments

Comments
 (0)