Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sysdig/internal/client/v2/sysdig.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type SysdigSecure interface {
PolicyInterface
RuleInterface
VulnerabilityPolicyClient
VulnerabilityRuleBundleClient
}

func (sr *SysdigRequest) Request(ctx context.Context, method string, url string, payload io.Reader) (*http.Response, error) {
Expand Down
116 changes: 116 additions & 0 deletions sysdig/internal/client/v2/vulnerability_rule_bundle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package v2

import (
"context"
"errors"
"fmt"
"net/http"
"strconv"
)

const (
vulnerabilityRuleBundlesPath = "%s/secure/vulnerability/v1/bundles"
vulnerabilityRuleBundlePath = "%s/secure/vulnerability/v1/bundles/%s"
)

type VulnerabilityRuleBundleClient interface {
CreateVulnerabilityRuleBundle(ctx context.Context, vulnerabilityRuleBundle VulnerabilityRuleBundle) (VulnerabilityRuleBundle, error)
GetVulnerabilityRuleBundleByID(ctx context.Context, vulnerabilityRuleBundleID string) (VulnerabilityRuleBundle, error)
UpdateVulnerabilityRuleBundle(ctx context.Context, vulnerabilityRuleBundle VulnerabilityRuleBundle) (VulnerabilityRuleBundle, error)
DeleteVulnerabilityRuleBundleByID(ctx context.Context, vulnerabilityRuleBundleID string) error
}

func (c *Client) CreateVulnerabilityRuleBundle(ctx context.Context, vulnerabilityRuleBundle VulnerabilityRuleBundle) (ruleBundle VulnerabilityRuleBundle, err error) {
payload, err := Marshal(vulnerabilityRuleBundle)
if err != nil {
return VulnerabilityRuleBundle{}, err
}

response, err := c.requester.Request(ctx, http.MethodPost, c.vulnerabilityRuleBundlesURL(), payload)
if err != nil {
return VulnerabilityRuleBundle{}, err
}
defer func() {
if dErr := response.Body.Close(); dErr != nil {
err = fmt.Errorf("unable to close response body: %w", dErr)
}
}()

if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated {
return VulnerabilityRuleBundle{}, c.ErrorFromResponse(response)
}

return Unmarshal[VulnerabilityRuleBundle](response.Body)
}

func (c *Client) GetVulnerabilityRuleBundleByID(ctx context.Context, vulnerabilityRuleBundleID string) (ruleBundle VulnerabilityRuleBundle, err error) {
response, err := c.requester.Request(ctx, http.MethodGet, c.vulnerabilityRuleBundleURL(vulnerabilityRuleBundleID), nil)
if err != nil {
return VulnerabilityRuleBundle{}, err
}
defer func() {
if dErr := response.Body.Close(); dErr != nil {
err = fmt.Errorf("unable to close response body: %w", dErr)
}
}()

if response.StatusCode != http.StatusOK {
return VulnerabilityRuleBundle{}, c.ErrorFromResponse(response)
}

return Unmarshal[VulnerabilityRuleBundle](response.Body)
}

func (c *Client) UpdateVulnerabilityRuleBundle(ctx context.Context, vulnerabilityRuleBundle VulnerabilityRuleBundle) (ruleBundle VulnerabilityRuleBundle, err error) {
if vulnerabilityRuleBundle.ID == nil {
return VulnerabilityRuleBundle{}, errors.New("rule bundle id was null")
}

payload, err := Marshal(vulnerabilityRuleBundle)
if err != nil {
return VulnerabilityRuleBundle{}, err
}

idAsStr := strconv.Itoa(int(*vulnerabilityRuleBundle.ID))
response, err := c.requester.Request(ctx, http.MethodPut, c.vulnerabilityRuleBundleURL(idAsStr), payload)
if err != nil {
return VulnerabilityRuleBundle{}, err
}
defer func() {
if dErr := response.Body.Close(); dErr != nil {
err = fmt.Errorf("unable to close response body: %w", dErr)
}
}()

if response.StatusCode != http.StatusOK {
return VulnerabilityRuleBundle{}, c.ErrorFromResponse(response)
}

return Unmarshal[VulnerabilityRuleBundle](response.Body)
}

func (c *Client) DeleteVulnerabilityRuleBundleByID(ctx context.Context, vulnerabilityRuleBundleID string) (err error) {
response, err := c.requester.Request(ctx, http.MethodDelete, c.vulnerabilityRuleBundleURL(vulnerabilityRuleBundleID), nil)
if err != nil {
return err
}
defer func() {
if dErr := response.Body.Close(); dErr != nil {
err = fmt.Errorf("unable to close response body: %w", dErr)
}
}()

if response.StatusCode != http.StatusNoContent && response.StatusCode != http.StatusOK {
return c.ErrorFromResponse(response)
}

return err
}

func (c *Client) vulnerabilityRuleBundlesURL() string {
return fmt.Sprintf(vulnerabilityRuleBundlesPath, c.config.url)
}

func (c *Client) vulnerabilityRuleBundleURL(vulnerabilityRuleBundleID string) string {
return fmt.Sprintf(vulnerabilityRuleBundlePath, c.config.url, vulnerabilityRuleBundleID)
}
59 changes: 59 additions & 0 deletions sysdig/internal/client/v2/vulnerability_rule_bundle_model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package v2

type VulnerabilityRuleBundle struct {
ID *int `json:"id,omitempty"`
Name string `json:"name"`
Identifier *string `json:"identifier,omitempty"`
Description *string `json:"description,omitempty"`
Rules []VulnerabilityRule `json:"rules"`
}

type VulnerabilityRule struct {
ID *string `json:"ruleId,omitempty"`
Type VulnerabilityRuleType `json:"ruleType"`
Predicates []VulnerabilityRulePredicate `json:"predicates"`
}

type VulnerabilityRulePredicate struct {
Type string `json:"type"`
Extra *VulnerabilityRulePredicateExtra `json:"extra,omitempty"`
}

type VulnerabilityRulePredicateExtra struct {
Level *Level `json:"level,omitempty"`
Age *int `json:"age,omitempty"`
VulnIDS []string `json:"vulnIds,omitempty"`
Value *string `json:"value,omitempty"`
Packages []Package `json:"packages,omitempty"`
Key *string `json:"key,omitempty"`
User *string `json:"user,omitempty"`
PkgType *string `json:"pkgType,omitempty"`
}

type Package struct {
Name string `json:"name"`
Version string `json:"version"`
}

type Level string

const (
Critical Level = "critical"
High Level = "high"
Medium Level = "medium"
)

type VulnerabilityRuleType string

const (
VulnerabilityRuleTypeImageConfigCreationDate VulnerabilityRuleType = "imageConfigCreationDate"
VulnerabilityRuleTypeImageConfigDefaultUser VulnerabilityRuleType = "imageConfigDefaultUser"
VulnerabilityRuleTypeImageConfigEnvVariable VulnerabilityRuleType = "imageConfigEnvVariable"
VulnerabilityRuleTypeImageConfigInstructionIsPkgManager VulnerabilityRuleType = "imageConfigInstructionIsPkgManager"
VulnerabilityRuleTypeImageConfigInstructionNotRecommended VulnerabilityRuleType = "imageConfigInstructionNotRecommended"
VulnerabilityRuleTypeImageConfigLabel VulnerabilityRuleType = "imageConfigLabel"
VulnerabilityRuleTypeImageConfigSensitiveInformationAndSecrets VulnerabilityRuleType = "imageConfigSensitiveInformationAndSecrets"
VulnerabilityRuleTypePkgDenyList VulnerabilityRuleType = "pkgDenyList"
VulnerabilityRuleTypeVulnDenyList VulnerabilityRuleType = "vulnDenyList"
VulnerabilityRuleTypeVulnSeverityAndThreats VulnerabilityRuleType = "vulnSeverityAndThreats"
)
1 change: 1 addition & 0 deletions sysdig/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ func (p *SysdigProvider) Provider() *schema.Provider {
"sysdig_secure_team": resourceSysdigSecureTeam(),
"sysdig_secure_vulnerability_accept_risk": resourceSysdigSecureVulnerabilityAcceptRisk(),
"sysdig_secure_vulnerability_policy": resourceSysdigSecureVulnerabilityPolicy(),
"sysdig_secure_vulnerability_rule_bundle": resourceSysdigSecureVulnerabilityRuleBundle(),
"sysdig_secure_zone": resourceSysdigSecureZone(),
},
DataSourcesMap: map[string]*schema.Resource{
Expand Down
15 changes: 12 additions & 3 deletions sysdig/resource_sysdig_secure_vulnerability_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestAccVulnerabilityPolicy(t *testing.T) {
{
Config: vulnerabilityPolicyConfig(random()),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_policy.sample", "bundles.#", "1"),
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_policy.sample", "bundles.#", "2"),
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_policy.sample", "bundles.0", "1"),
resource.TestCheckResourceAttr("sysdig_secure_vulnerability_policy.sample", "stages.#", "3"),
),
Expand All @@ -57,11 +57,20 @@ resource "sysdig_secure_vulnerability_policy" "sample" {

func vulnerabilityPolicyConfig(suffix string) string {
return fmt.Sprintf(`
resource "sysdig_secure_vulnerability_rule_bundle" "sample" {
name = "TERRAFORM TEST %s"
rule {
image_label {
label_must_exist = "required-label"
}
}
}

resource "sysdig_secure_vulnerability_policy" "sample" {
name = "TERRAFORM TEST %s"
description = "Acceptance test for bundles as ordered list %s"

bundles = [ "1" ]
bundles = [ "1", sysdig_secure_vulnerability_rule_bundle.sample.id ]

stages {
name = "pipeline"
Expand All @@ -82,5 +91,5 @@ resource "sysdig_secure_vulnerability_policy" "sample" {
}
}
}
`, suffix, suffix)
`, suffix, suffix, suffix)
}
Loading
Loading