diff --git a/.github/workflows/ci-provider-docs.yaml b/.github/workflows/ci-provider-docs.yaml index 3207cc12f..f495061d3 100644 --- a/.github/workflows/ci-provider-docs.yaml +++ b/.github/workflows/ci-provider-docs.yaml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/cache@v4 continue-on-error: true id: cache-terraform-plugin-dir timeout-minutes: 2 @@ -34,12 +34,12 @@ jobs: run: | echo "GOCACHE=$(go env GOCACHE)" >> $GITHUB_ENV - if: steps.cache-terraform-plugin-dir.outputs.cache-hit != 'true' || steps.cache-terraform-plugin-dir.outcome == 'failure' - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ${{ env.GOCACHE }} key: ${{ runner.os }}-GOCACHE-${{ hashFiles('go.sum') }}-${{ hashFiles('sysdig/**') }} - if: steps.cache-terraform-plugin-dir.outputs.cache-hit != 'true' || steps.cache-terraform-plugin-dir.outcome == 'failure' - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }} @@ -53,7 +53,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/cache@v2 + - uses: actions/cache@v4 continue-on-error: true id: cache-terraform-providers-schema timeout-minutes: 2 @@ -61,7 +61,7 @@ jobs: path: terraform-providers-schema key: ${{ runner.os }}-terraform-providers-schema-${{ hashFiles('go.sum') }}-${{ hashFiles('sysdig/**') }} - if: steps.cache-terraform-providers-schema.outputs.cache-hit != 'true' || steps.cache-terraform-providers-schema.outcome == 'failure' - uses: actions/cache@v2 + uses: actions/cache@v4 timeout-minutes: 2 with: path: terraform-plugin-dir @@ -97,14 +97,14 @@ jobs: go-version: ${{ env.GO_VERSION }} check-latest: true cache: true - - uses: actions/cache@v2 + - uses: actions/cache@v4 continue-on-error: true timeout-minutes: 2 with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }} - run: cd /tmp && go install github.com/bflad/tfproviderdocs@latest - - uses: actions/cache@v2 + - uses: actions/cache@v4 timeout-minutes: 2 with: path: terraform-providers-schema diff --git a/sysdig/data_source_sysdig_secure_rule_stateful.go b/sysdig/data_source_sysdig_secure_rule_stateful.go new file mode 100644 index 000000000..c12cae705 --- /dev/null +++ b/sysdig/data_source_sysdig_secure_rule_stateful.go @@ -0,0 +1,141 @@ +package sysdig + +import ( + "context" + "encoding/json" + "errors" + "strconv" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceSysdigSecureRuleStateful() *schema.Resource { + timeout := 1 * time.Minute + + return &schema.Resource{ + ReadContext: dataSourceSysdigRuleStatefulRead, + + Timeouts: &schema.ResourceTimeout{ + Read: schema.DefaultTimeout(timeout), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + "source": { + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validateDiagFunc(validateStatefulRuleSource), + }, + "ruletype": { + Type: schema.TypeString, + Computed: true, + }, + "append": { + Type: schema.TypeBool, + Computed: true, + }, + "exceptions": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "values": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceSysdigRuleStatefulRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client, err := getSecureRuleClient(meta.(SysdigClients)) + if err != nil { + return diag.FromErr(err) + } + + nameObj, ok := d.GetOk("name") + if !ok { + return diag.FromErr(errors.New("name is required")) + } + + name := nameObj.(string) + + sourceObj, ok := d.GetOk("source") + if !ok { + return diag.FromErr(errors.New("source is required")) + } + + source := sourceObj.(string) + + rules, err := client.GetStatefulRuleGroup(ctx, name, source) + if err != nil { + return diag.FromErr(err) + } + + ruleIndexObj, ok := d.GetOk("index") + ruleIndex := 0 + if ok { + ruleIndex, ok = ruleIndexObj.(int) + if !ok { + return diag.FromErr(errors.New("index must be an integer")) + } + } + + rule := rules[ruleIndex] + + if len(rules) == 0 { + d.SetId("") + } else { + d.SetId(strconv.Itoa(rule.ID)) + } + + _ = d.Set("name", rule.Name) + _ = d.Set("source", source) + + if rule.Details.Append != nil { + _ = d.Set("append", *rule.Details.Append) + } + + exceptions := make([]any, 0, len(rule.Details.Exceptions)) + for _, exception := range rule.Details.Exceptions { + if exception == nil { + return diag.Errorf("exception is nil") + } + valuesData, err := json.Marshal(exception.Values) + if err != nil { + return diag.Errorf("error marshalling exception values '%+v': %s", exception.Values, err) + } + + exceptions = append(exceptions, map[string]any{ + "name": exception.Name, + "values": string(valuesData), + }) + } + + if err := d.Set("exceptions", exceptions); err != nil { + return diag.FromErr(err) + } + + return nil +} diff --git a/sysdig/data_source_sysdig_secure_rule_stateful_count.go b/sysdig/data_source_sysdig_secure_rule_stateful_count.go new file mode 100644 index 000000000..9a731dc3b --- /dev/null +++ b/sysdig/data_source_sysdig_secure_rule_stateful_count.go @@ -0,0 +1,58 @@ +package sysdig + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceSysdigSecureRuleStatefulCount() *schema.Resource { + timeout := 1 * time.Minute + + return &schema.Resource{ + ReadContext: dataSourceSysdigRuleStatefulCountRead, + + Timeouts: &schema.ResourceTimeout{ + Read: schema.DefaultTimeout(timeout), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + }, + "source": { + Type: schema.TypeString, + Required: true, + ValidateDiagFunc: validateDiagFunc(validateStatefulRuleSource), + }, + "rule_count": { + Type: schema.TypeInt, + Computed: true, + }, + }, + } +} + +func dataSourceSysdigRuleStatefulCountRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client, err := getSecureRuleClient(meta.(SysdigClients)) + if err != nil { + return diag.FromErr(err) + } + + ruleName := d.Get("name").(string) + ruleType := d.Get("source").(string) + rules, err := client.GetStatefulRuleGroup(ctx, ruleName, ruleType) + if err != nil { + return diag.FromErr(err) + } + + d.SetId(fmt.Sprintf("count__%s__%s", ruleName, ruleType)) + _ = d.Set("name", ruleName) + _ = d.Set("rule_count", len(rules)) + + return nil +} diff --git a/sysdig/data_source_sysdig_secure_rule_stateful_count_test.go b/sysdig/data_source_sysdig_secure_rule_stateful_count_test.go new file mode 100644 index 000000000..0a7c3c918 --- /dev/null +++ b/sysdig/data_source_sysdig_secure_rule_stateful_count_test.go @@ -0,0 +1,56 @@ +//go:build tf_acc_sysdig || tf_acc_sysdig_secure || tf_acc_policies || tf_acc_onprem_secure + +package sysdig_test + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/draios/terraform-provider-sysdig/sysdig" +) + +func TestAccRuleStatefulCountDataSource(t *testing.T) { + + if strings.HasSuffix(os.Getenv("SYSDIG_SECURE_URL"), "ibm.com") { + t.Skip("Skipping stateful tests for IBM Cloud") + return + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + if v := os.Getenv("SYSDIG_SECURE_API_TOKEN"); v == "" { + t.Fatal("SYSDIG_SECURE_API_TOKEN must be set for acceptance tests") + } + }, + ProviderFactories: map[string]func() (*schema.Provider, error){ + "sysdig": func() (*schema.Provider, error) { + return sysdig.Provider(), nil + }, + }, + Steps: []resource.TestStep{ + { + Config: ruleStatefulCountDataSource(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.sysdig_secure_rule_stateful_count.data_stateful_rule_append", "rule_count", "2"), + ), + }, + }, + }) +} + +func ruleStatefulCountDataSource() string { + return fmt.Sprintf(` +%s + +data "sysdig_secure_rule_stateful_count" "data_stateful_rule_append" { + name = "API Gateway Enumeration Detected" + source = "awscloudtrail_stateful" + depends_on = [ sysdig_secure_rule_stateful.stateful_rule_append ] +} +`, ruleStatefulAppend()) +} diff --git a/sysdig/data_source_sysdig_secure_rule_stateful_test.go b/sysdig/data_source_sysdig_secure_rule_stateful_test.go new file mode 100644 index 000000000..41278e098 --- /dev/null +++ b/sysdig/data_source_sysdig_secure_rule_stateful_test.go @@ -0,0 +1,53 @@ +//go:build tf_acc_sysdig || tf_acc_sysdig_secure || tf_acc_policies || tf_acc_onprem_secure + +package sysdig_test + +import ( + "fmt" + "os" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/draios/terraform-provider-sysdig/sysdig" +) + +func TestAccRuleStatefulDataSource(t *testing.T) { + + if strings.HasSuffix(os.Getenv("SYSDIG_SECURE_URL"), "ibm.com") { + t.Skip("Skipping stateful tests for IBM Cloud") + return + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + if v := os.Getenv("SYSDIG_SECURE_API_TOKEN"); v == "" { + t.Fatal("SYSDIG_SECURE_API_TOKEN must be set for acceptance tests") + } + }, + ProviderFactories: map[string]func() (*schema.Provider, error){ + "sysdig": func() (*schema.Provider, error) { + return sysdig.Provider(), nil + }, + }, + Steps: []resource.TestStep{ + { + Config: ruleStatefulDataSource(), + }, + }, + }) +} + +func ruleStatefulDataSource() string { + return fmt.Sprintf(` +%s + +data "sysdig_secure_rule_stateful" "data_stateful_rule_append" { + name = "API Gateway Enumeration Detected" + source = "awscloudtrail_stateful" + depends_on = [ sysdig_secure_rule_stateful.stateful_rule_append ] +} +`, ruleStatefulAppend()) +} diff --git a/sysdig/provider.go b/sysdig/provider.go index 1562c240f..11de1d1cd 100644 --- a/sysdig/provider.go +++ b/sysdig/provider.go @@ -234,6 +234,8 @@ func (p *SysdigProvider) Provider() *schema.Provider { "sysdig_secure_rule_syscall": dataSourceSysdigSecureRuleSyscall(), "sysdig_secure_posture_policies": dataSourceSysdigSecurePosturePolicies(), "sysdig_secure_custom_role_permissions": dataSourceSysdigSecureCustomRolePermissions(), + "sysdig_secure_rule_stateful": dataSourceSysdigSecureRuleStateful(), + "sysdig_secure_rule_stateful_count": dataSourceSysdigSecureRuleStatefulCount(), "sysdig_current_user": dataSourceSysdigCurrentUser(), "sysdig_user": dataSourceSysdigUser(), diff --git a/website/docs/d/secure_rule_stateful.md b/website/docs/d/secure_rule_stateful.md index bb74ed85e..aa51ba1b0 100644 --- a/website/docs/d/secure_rule_stateful.md +++ b/website/docs/d/secure_rule_stateful.md @@ -44,4 +44,3 @@ Supported fields for exceptions: * `name` - The name of the existing exception definition. * `values` - Contains tuples of values. Each item in the tuple should align 1-1 with the corresponding field and comparison operator. - diff --git a/website/docs/d/secure_rule_stateful_count.md b/website/docs/d/secure_rule_stateful_count.md new file mode 100644 index 000000000..ce927b357 --- /dev/null +++ b/website/docs/d/secure_rule_stateful_count.md @@ -0,0 +1,33 @@ +--- +subcategory: "Sysdig Secure" +layout: "sysdig" +page_title: "Sysdig: sysdig_secure_rule_stateful_count" +description: |- + Retrieves the count of rules (including appends) for a named stateful rule. +--- + +# Data Source: sysdig_secure_rule_stateful_count + +Retrieves the count of rules (including appends) for a named stateful rule. + +-> **Note:** Sysdig Terraform Provider is under rapid development at this point. If you experience any issue or discrepancy while using it, please make sure you have the latest version. If the issue persists, or you have a Feature Request to support an additional set of resources, please open a [new issue](https://github.com/sysdiglabs/terraform-provider-sysdig/issues/new) in the GitHub repository. + +## Example Usage + +```terraform +data "sysdig_secure_rule_stateful_count" "example" { + name = "API Gateway Enumeration Detected" + source = "awscloudtrail_stateful" +} +``` + +## Argument Reference + +* `name` - (Required) The name of the Secure stateful rule to retrieve. +* `source` - (Required) The source of the Secure stateful rule to retrieve. + +## Attributes Reference + +In addition to the argument above, the following attributes are exported: + +* `rule_count` - The number of rules (including appends).