diff --git a/CODEOWNERS b/CODEOWNERS index 3689431b..39e9276b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -12,3 +12,11 @@ # policies/rules *secure*policy* @jacklongsd @kmvachhani @ben-m-lucas @ombellare @miguelgordo @ivanlysiuk-sysdig + +# internal components +/sysdig/internal/client/v2/client.go @filiptubic @mbarbieri @draraksysdig +/sysdig/internal/client/v2/config.go @filiptubic @mbarbieri @draraksysdig +/sysdig/internal/client/v2/ibm.go @filiptubic @mbarbieri @draraksysdig +/main.go @filiptubic @mbarbieri @draraksysdig +/.goreleaser.yml @filiptubic @mbarbieri @draraksysdig +/.github/ @filiptubic @mbarbieri @draraksysdig diff --git a/go.mod b/go.mod index d0e210bd..16f93183 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,10 @@ require ( github.com/falcosecurity/kilt/runtimes/cloudformation v0.0.0-20230606123839-2e4c434d5d88 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/go-retryablehttp v0.7.4 + github.com/hashicorp/terraform-plugin-log v0.8.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1 github.com/jmespath/go-jmespath v0.4.0 + github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.29.1 github.com/spf13/cast v1.5.1 github.com/stretchr/testify v1.8.4 @@ -45,7 +47,6 @@ require ( github.com/hashicorp/terraform-exec v0.18.1 // indirect github.com/hashicorp/terraform-json v0.16.0 // indirect github.com/hashicorp/terraform-plugin-go v0.14.3 // indirect - github.com/hashicorp/terraform-plugin-log v0.8.0 // indirect github.com/hashicorp/terraform-registry-address v0.1.0 // indirect github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect @@ -61,7 +62,6 @@ require ( github.com/oklog/run v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc2 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/vbatts/tar-split v0.11.2 // indirect diff --git a/go.sum b/go.sum index 54369694..3d9525aa 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,6 @@ github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPa github.com/docker/docker v20.10.24+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= -github.com/draios/protorepo/cloudauth/go v0.0.0-20230901163632-fcbfe0cb84e0 h1:LKBglxJ55sl7NuP5IrC/SD89ZQFwN8ejh8XGJ0dj5P0= -github.com/draios/protorepo/cloudauth/go v0.0.0-20230901163632-fcbfe0cb84e0/go.mod h1:JmBZh3AOhz4gg83qMw9p2QDCIiLSH9YCyyvDVClIynU= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/falcosecurity/kilt/pkg v0.0.0-20230111165949-b36cdd622de1 h1:7JOAJwPA4FEtowSP133pgicOu+nOfo0wGuXapXKhafk= diff --git a/main.go b/main.go index 5f99a780..1aa58811 100644 --- a/main.go +++ b/main.go @@ -7,5 +7,9 @@ import ( ) func main() { - plugin.Serve(&plugin.ServeOpts{ProviderFunc: sysdig.Provider}) + sysdigClient := sysdig.NewSysdigClients() + defer sysdigClient.Close() + + provider := &sysdig.SysdigProvider{SysdigClient: sysdigClient} + plugin.Serve(&plugin.ServeOpts{ProviderFunc: provider.Provider}) } diff --git a/sysdig/internal/client/v2/config.go b/sysdig/internal/client/v2/config.go index 3aca897e..e2ef1898 100644 --- a/sysdig/internal/client/v2/config.go +++ b/sysdig/internal/client/v2/config.go @@ -1,16 +1,17 @@ package v2 type config struct { - url string - token string - insecure bool - extraHeaders map[string]string - ibmInstanceID string - ibmAPIKey string - ibmIamURL string - sysdigTeamName string - sysdigTeamID *int - product string + url string + token string + insecure bool + extraHeaders map[string]string + ibmInstanceID string + ibmAPIKey string + ibmIamURL string + sysdigTeamName string + sysdigTeamID *int + product string + secureSkipPolicyV2Msg bool } type Product string @@ -95,3 +96,9 @@ func configure(opts ...ClientOption) *config { } return cfg } + +func WithSkipPolicyV2Msg(skipPolicyV2Msg bool) ClientOption { + return func(c *config) { + c.secureSkipPolicyV2Msg = skipPolicyV2Msg + } +} diff --git a/sysdig/internal/client/v2/list.go b/sysdig/internal/client/v2/list.go index 440d53c1..ced87d3b 100644 --- a/sysdig/internal/client/v2/list.go +++ b/sysdig/internal/client/v2/list.go @@ -7,10 +7,10 @@ import ( ) const ( - CreateListPath = "%s/api/secure/falco/lists" + CreateListPath = "%s/api/secure/falco/lists?skipPolicyV2Msg=%t" GetListPath = "%s/api/secure/falco/lists/%d" - UpdateListPath = "%s/api/secure/falco/lists/%d" - DeleteListPath = "%s/api/secure/falco/lists/%d" + UpdateListPath = "%s/api/secure/falco/lists/%d?skipPolicyV2Msg=%t" + DeleteListPath = "%s/api/secure/falco/lists/%d?skipPolicyV2Msg=%t" ) type ListInterface interface { @@ -97,7 +97,7 @@ func (client *Client) DeleteList(ctx context.Context, id int) error { } func (client *Client) CreateListURL() string { - return fmt.Sprintf(CreateListPath, client.config.url) + return fmt.Sprintf(CreateListPath, client.config.url, client.config.secureSkipPolicyV2Msg) } func (client *Client) GetListURL(id int) string { @@ -105,9 +105,9 @@ func (client *Client) GetListURL(id int) string { } func (client *Client) UpdateListURL(id int) string { - return fmt.Sprintf(UpdateListPath, client.config.url, id) + return fmt.Sprintf(UpdateListPath, client.config.url, id, client.config.secureSkipPolicyV2Msg) } func (client *Client) DeleteListURL(id int) string { - return fmt.Sprintf(DeleteListPath, client.config.url, id) + return fmt.Sprintf(DeleteListPath, client.config.url, id, client.config.secureSkipPolicyV2Msg) } diff --git a/sysdig/internal/client/v2/macros.go b/sysdig/internal/client/v2/macros.go index 6f0f7350..8283af5b 100644 --- a/sysdig/internal/client/v2/macros.go +++ b/sysdig/internal/client/v2/macros.go @@ -7,10 +7,10 @@ import ( ) const ( - CreateMacroPath = "%s/api/secure/falco/macros" + CreateMacroPath = "%s/api/secure/falco/macros?skipPolicyV2Msg=%t" GetMacroByIDPath = "%s/api/secure/falco/macros/%d" - UpdateMacroPath = "%s/api/secure/falco/macros/%d" - DeleteMacroPath = "%s/api/secure/falco/macros/%d" + UpdateMacroPath = "%s/api/secure/falco/macros/%d?skipPolicyV2Msg=%t" + DeleteMacroPath = "%s/api/secure/falco/macros/%d?skipPolicyV2Msg=%t" ) type MacroInterface interface { @@ -96,7 +96,7 @@ func (client *Client) DeleteMacro(ctx context.Context, id int) error { } func (client *Client) CreateMacroURL() string { - return fmt.Sprintf(CreateMacroPath, client.config.url) + return fmt.Sprintf(CreateMacroPath, client.config.url, client.config.secureSkipPolicyV2Msg) } func (client *Client) GetMacroByIDURL(id int) string { @@ -104,9 +104,9 @@ func (client *Client) GetMacroByIDURL(id int) string { } func (client *Client) UpdateMacroURL(id int) string { - return fmt.Sprintf(UpdateMacroPath, client.config.url, id) + return fmt.Sprintf(UpdateMacroPath, client.config.url, id, client.config.secureSkipPolicyV2Msg) } func (client *Client) DeleteMacroURL(id int) string { - return fmt.Sprintf(DeleteMacroPath, client.config.url, id) + return fmt.Sprintf(DeleteMacroPath, client.config.url, id, client.config.secureSkipPolicyV2Msg) } diff --git a/sysdig/internal/client/v2/model.go b/sysdig/internal/client/v2/model.go index 8d38c65a..6cb28b6c 100644 --- a/sysdig/internal/client/v2/model.go +++ b/sysdig/internal/client/v2/model.go @@ -606,8 +606,9 @@ type AlertV2ConfigMetric struct { type AlertV2Metric struct { AlertV2Common - DurationSec int `json:"durationSec"` - Config AlertV2ConfigMetric `json:"config"` + DurationSec int `json:"durationSec"` + Config AlertV2ConfigMetric `json:"config"` + UnreportedAlertNotificationsRetentionSec *int `json:"unreportedAlertNotificationsRetentionSec"` } type alertV2MetricWrapper struct { @@ -628,8 +629,9 @@ type AlertV2ConfigDowntime struct { type AlertV2Downtime struct { AlertV2Common - DurationSec int `json:"durationSec"` - Config AlertV2ConfigDowntime `json:"config"` + DurationSec int `json:"durationSec"` + Config AlertV2ConfigDowntime `json:"config"` + UnreportedAlertNotificationsRetentionSec *int `json:"unreportedAlertNotificationsRetentionSec"` } type alertV2DowntimeWrapper struct { @@ -665,8 +667,9 @@ type AlertV2ConfigFormBasedPrometheus struct { type AlertV2FormBasedPrometheus struct { AlertV2Common - DurationSec int `json:"durationSec"` // not really used but the api wants it set to 0 in POST/PUT - Config AlertV2ConfigFormBasedPrometheus `json:"config"` + DurationSec int `json:"durationSec"` // not really used but the api wants it set to 0 in POST/PUT + Config AlertV2ConfigFormBasedPrometheus `json:"config"` + UnreportedAlertNotificationsRetentionSec *int `json:"unreportedAlertNotificationsRetentionSec"` } type alertV2FormBasedPrometheusWrapper struct { @@ -675,8 +678,9 @@ type alertV2FormBasedPrometheusWrapper struct { type AlertV2Change struct { AlertV2Common - DurationSec int `json:"durationSec"` // not really used but the api wants it set to 0 in POST/PUT - Config AlertV2ConfigChange `json:"config"` + DurationSec int `json:"durationSec"` // not really used but the api wants it set to 0 in POST/PUT + Config AlertV2ConfigChange `json:"config"` + UnreportedAlertNotificationsRetentionSec *int `json:"unreportedAlertNotificationsRetentionSec"` } type alertV2ChangeWrapper struct { diff --git a/sysdig/internal/client/v2/policies.go b/sysdig/internal/client/v2/policies.go index c685258d..f0ad1fe4 100644 --- a/sysdig/internal/client/v2/policies.go +++ b/sysdig/internal/client/v2/policies.go @@ -4,14 +4,17 @@ import ( "context" "fmt" "net/http" + + "github.com/pkg/errors" ) const ( - CreatePolicyPath = "%s/api/v2/policies" - DeletePolicyPath = "%s/api/v2/policies/%d" - UpdatePolicyPath = "%s/api/v2/policies/%d" - GetPolicyPath = "%s/api/v2/policies/%d" - GetPoliciesPath = "%s/api/v2/policies" + CreatePolicyPath = "%s/api/v2/policies?skipPolicyV2Msg=%t" + DeletePolicyPath = "%s/api/v2/policies/%d?skipPolicyV2Msg=%t" + UpdatePolicyPath = "%s/api/v2/policies/%d?skipPolicyV2Msg=%t" + GetPolicyPath = "%s/api/v2/policies/%d" + GetPoliciesPath = "%s/api/v2/policies" + SendPoliciesToAgentsPath = "%s/api/v2/policies/actions?action=forwardPolicyV2Msg" ) type PolicyInterface interface { @@ -21,6 +24,7 @@ type PolicyInterface interface { UpdatePolicy(ctx context.Context, policy Policy) (Policy, error) GetPolicyByID(ctx context.Context, policyID int) (Policy, int, error) GetPolicies(ctx context.Context) ([]Policy, int, error) + SendPoliciesToAgents(ctx context.Context) error } func (client *Client) CreatePolicy(ctx context.Context, policy Policy) (Policy, error) { @@ -113,16 +117,32 @@ func (client *Client) GetPolicies(ctx context.Context) ([]Policy, int, error) { return policies, http.StatusOK, nil } +func (client *Client) SendPoliciesToAgents(ctx context.Context) error { + if client.config.secureSkipPolicyV2Msg { + // We only need to send policies if we've been configured to skip sending them during updates + response, err := client.requester.Request(ctx, http.MethodPost, client.SendPoliciesToAgentsURL(), nil) + if err != nil { + return err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + return errors.Errorf("Unexpected response when sending policies to agents: %s", response.Status) + } + } + return nil +} + func (client *Client) CreatePolicyURL() string { - return fmt.Sprintf(CreatePolicyPath, client.config.url) + return fmt.Sprintf(CreatePolicyPath, client.config.url, client.config.secureSkipPolicyV2Msg) } func (client *Client) DeletePolicyURL(policyID int) string { - return fmt.Sprintf(DeletePolicyPath, client.config.url, policyID) + return fmt.Sprintf(DeletePolicyPath, client.config.url, policyID, client.config.secureSkipPolicyV2Msg) } func (client *Client) UpdatePolicyURL(policyID int) string { - return fmt.Sprintf(UpdatePolicyPath, client.config.url, policyID) + return fmt.Sprintf(UpdatePolicyPath, client.config.url, policyID, client.config.secureSkipPolicyV2Msg) } func (client *Client) GetPolicyURL(policyID int) string { @@ -132,3 +152,7 @@ func (client *Client) GetPolicyURL(policyID int) string { func (client *Client) GetPoliciesURL() string { return fmt.Sprintf(GetPoliciesPath, client.config.url) } + +func (client *Client) SendPoliciesToAgentsURL() string { + return fmt.Sprintf(SendPoliciesToAgentsPath, client.config.url) +} diff --git a/sysdig/internal/client/v2/rules.go b/sysdig/internal/client/v2/rules.go index 6b07c3ac..b151fd5d 100644 --- a/sysdig/internal/client/v2/rules.go +++ b/sysdig/internal/client/v2/rules.go @@ -8,17 +8,17 @@ import ( ) const ( - CreateRulePath = "%s/api/secure/rules" + CreateRulePath = "%s/api/secure/rules?skipPolicyV2Msg=%t" GetRuleByIDPath = "%s/api/secure/rules/%d" - UpdateRulePath = "%s/api/secure/rules/%d" - DeleteURLPath = "%s/api/secure/rules/%d" + UpdateRulePath = "%s/api/secure/rules/%d?skipPolicyV2Msg=%t" + DeleteURLPath = "%s/api/secure/rules/%d?skipPolicyV2Msg=%t" GetRuleGroupPath = "%s/api/secure/rules/groups?name=%s&type=%s" ) type RuleInterface interface { Base CreateRule(ctx context.Context, rule Rule) (Rule, error) - GetRuleByID(ctx context.Context, ruleID int) (Rule, error) + GetRuleByID(ctx context.Context, ruleID int) (Rule, int, error) UpdateRule(ctx context.Context, rule Rule) (Rule, error) DeleteRule(ctx context.Context, ruleID int) error GetRuleGroup(ctx context.Context, ruleName string, ruleType string) ([]Rule, error) @@ -43,18 +43,19 @@ func (client *Client) CreateRule(ctx context.Context, rule Rule) (Rule, error) { return Unmarshal[Rule](response.Body) } -func (client *Client) GetRuleByID(ctx context.Context, ruleID int) (Rule, error) { +func (client *Client) GetRuleByID(ctx context.Context, ruleID int) (Rule, int, error) { response, err := client.requester.Request(ctx, http.MethodGet, client.GetRuleByIDURL(ruleID), nil) if err != nil { - return Rule{}, err + return Rule{}, 0, err } defer response.Body.Close() if response.StatusCode != http.StatusOK { - return Rule{}, client.ErrorFromResponse(response) + return Rule{}, response.StatusCode, client.ErrorFromResponse(response) } - return Unmarshal[Rule](response.Body) + rule, err := Unmarshal[Rule](response.Body) + return rule, 0, err } func (client *Client) UpdateRule(ctx context.Context, rule Rule) (Rule, error) { @@ -106,7 +107,7 @@ func (client *Client) GetRuleGroup(ctx context.Context, ruleName string, ruleTyp } func (client *Client) CreateRuleURL() string { - return fmt.Sprintf(CreateRulePath, client.config.url) + return fmt.Sprintf(CreateRulePath, client.config.url, client.config.secureSkipPolicyV2Msg) } func (client *Client) GetRuleByIDURL(ruleID int) string { @@ -114,11 +115,11 @@ func (client *Client) GetRuleByIDURL(ruleID int) string { } func (client *Client) UpdateRuleURL(ruleID int) string { - return fmt.Sprintf(UpdateRulePath, client.config.url, ruleID) + return fmt.Sprintf(UpdateRulePath, client.config.url, ruleID, client.config.secureSkipPolicyV2Msg) } func (client *Client) DeleteRuleURL(ruleID int) string { - return fmt.Sprintf(DeleteURLPath, client.config.url, ruleID) + return fmt.Sprintf(DeleteURLPath, client.config.url, ruleID, client.config.secureSkipPolicyV2Msg) } func (client *Client) GetRuleGroupURL(ruleName string, ruleType string) string { diff --git a/sysdig/provider.go b/sysdig/provider.go index c0c69bef..336ab8c3 100644 --- a/sysdig/provider.go +++ b/sysdig/provider.go @@ -7,9 +7,25 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) +type SysdigProvider struct { + SysdigClient SysdigClients +} + +// Used by tests to get the provider func Provider() *schema.Provider { + sysdigClient := NewSysdigClients() + provider := &SysdigProvider{SysdigClient: sysdigClient} + return provider.Provider() +} + +func (p *SysdigProvider) Provider() *schema.Provider { return &schema.Provider{ Schema: map[string]*schema.Schema{ + "sysdig_secure_skip_policyv2msg": { + Type: schema.TypeBool, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("SYSDIG_SECURE_SKIP_POLICYV2MSG", true), + }, "sysdig_secure_api_token": { Type: schema.TypeString, Optional: true, @@ -216,11 +232,11 @@ func Provider() *schema.Provider { "sysdig_monitor_notification_channel_ibm_function": dataSourceSysdigMonitorNotificationChannelIBMFunction(), "sysdig_monitor_custom_role_permissions": dataSourceSysdigMonitorCustomRolePermissions(), }, - ConfigureContextFunc: providerConfigure, + ConfigureContextFunc: p.providerConfigure, } } -func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { - sysdigClient := &sysdigClients{d: d} - return sysdigClient, nil +func (p *SysdigProvider) providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { + p.SysdigClient.Configure(ctx, d) + return p.SysdigClient, nil } diff --git a/sysdig/resource_sysdig_monitor_alert_v2_change.go b/sysdig/resource_sysdig_monitor_alert_v2_change.go index bc68cb0c..80de0833 100644 --- a/sysdig/resource_sysdig_monitor_alert_v2_change.go +++ b/sysdig/resource_sysdig_monitor_alert_v2_change.go @@ -127,6 +127,11 @@ func resourceSysdigMonitorAlertV2Change() *schema.Resource { Type: schema.TypeInt, Required: true, }, + "unreported_alert_notifications_retention_seconds": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(60), + }, })), CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error { @@ -299,10 +304,17 @@ func buildAlertV2ChangeStruct(d *schema.ResourceData) (*v2.AlertV2Change, error) // LongerRangeSec config.LongerRangeSec = d.Get("longer_time_range_seconds").(int) + var unreportedAlertNotificationsRetentionSec *int + if unreportedAlertNotificationsRetentionSecInterface, ok := d.GetOk("unreported_alert_notifications_retention_seconds"); ok { + u := unreportedAlertNotificationsRetentionSecInterface.(int) + unreportedAlertNotificationsRetentionSec = &u + } + alert := &v2.AlertV2Change{ - AlertV2Common: *alertV2Common, - DurationSec: 0, - Config: config, + AlertV2Common: *alertV2Common, + DurationSec: 0, + Config: config, + UnreportedAlertNotificationsRetentionSec: unreportedAlertNotificationsRetentionSec, } return alert, nil } @@ -336,5 +348,11 @@ func updateAlertV2ChangeState(d *schema.ResourceData, alert *v2.AlertV2Change) e _ = d.Set("longer_time_range_seconds", alert.Config.LongerRangeSec) + if alert.UnreportedAlertNotificationsRetentionSec != nil { + _ = d.Set("unreported_alert_notifications_retention_seconds", *alert.UnreportedAlertNotificationsRetentionSec) + } else { + _ = d.Set("unreported_alert_notifications_retention_seconds", nil) + } + return nil } diff --git a/sysdig/resource_sysdig_monitor_alert_v2_change_test.go b/sysdig/resource_sysdig_monitor_alert_v2_change_test.go index b470d031..59b11fcd 100644 --- a/sysdig/resource_sysdig_monitor_alert_v2_change_test.go +++ b/sysdig/resource_sysdig_monitor_alert_v2_change_test.go @@ -54,6 +54,9 @@ func TestAccAlertV2Change(t *testing.T) { { Config: alertV2ChangeWithEnabled(rText()), }, + { + Config: alertV2ChangeWithUnreportedAlertNotificationsRetentionSec(rText()), + }, { Config: alertV2ChangeWithWarningThreshold(rText()), }, @@ -295,6 +298,22 @@ resource "sysdig_monitor_alert_v2_change" "sample" { `, name) } +func alertV2ChangeWithUnreportedAlertNotificationsRetentionSec(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_alert_v2_change" "sample" { + name = "TERRAFORM TEST - CHANGE %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + shorter_time_range_seconds = 300 + longer_time_range_seconds = 3600 + unreported_alert_notifications_retention_seconds = 60 * 60 * 24 * 30 +} +`, name) +} + func alertV2ChangeWithWarningThreshold(name string) string { return fmt.Sprintf(` resource "sysdig_monitor_notification_channel_email" "nc_email1" { diff --git a/sysdig/resource_sysdig_monitor_alert_v2_downtime.go b/sysdig/resource_sysdig_monitor_alert_v2_downtime.go index 2fa74a75..94366300 100644 --- a/sysdig/resource_sysdig_monitor_alert_v2_downtime.go +++ b/sysdig/resource_sysdig_monitor_alert_v2_downtime.go @@ -46,6 +46,11 @@ func resourceSysdigMonitorAlertV2Downtime() *schema.Resource { Required: true, ValidateFunc: validation.StringInSlice([]string{"sysdig_container_up", "sysdig_program_up", "sysdig_host_up"}, true), }, + "unreported_alert_notifications_retention_seconds": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(60), + }, })), } } @@ -172,10 +177,17 @@ func buildAlertV2DowntimeStruct(d *schema.ResourceData) *v2.AlertV2Downtime { config.NoDataBehaviour = "DO_NOTHING" + var unreportedAlertNotificationsRetentionSec *int + if unreportedAlertNotificationsRetentionSecInterface, ok := d.GetOk("unreported_alert_notifications_retention_seconds"); ok { + u := unreportedAlertNotificationsRetentionSecInterface.(int) + unreportedAlertNotificationsRetentionSec = &u + } + alert := &v2.AlertV2Downtime{ - AlertV2Common: *alertV2Common, - DurationSec: minutesToSeconds(d.Get("trigger_after_minutes").(int)), - Config: config, + AlertV2Common: *alertV2Common, + DurationSec: minutesToSeconds(d.Get("trigger_after_minutes").(int)), + Config: config, + UnreportedAlertNotificationsRetentionSec: unreportedAlertNotificationsRetentionSec, } return alert } @@ -197,5 +209,11 @@ func updateAlertV2DowntimeState(d *schema.ResourceData, alert *v2.AlertV2Downtim _ = d.Set("metric", alert.Config.Metric.ID) + if alert.UnreportedAlertNotificationsRetentionSec != nil { + _ = d.Set("unreported_alert_notifications_retention_seconds", *alert.UnreportedAlertNotificationsRetentionSec) + } else { + _ = d.Set("unreported_alert_notifications_retention_seconds", nil) + } + return nil } diff --git a/sysdig/resource_sysdig_monitor_alert_v2_downtime_test.go b/sysdig/resource_sysdig_monitor_alert_v2_downtime_test.go index 13c6a3bc..9f35854a 100644 --- a/sysdig/resource_sysdig_monitor_alert_v2_downtime_test.go +++ b/sysdig/resource_sysdig_monitor_alert_v2_downtime_test.go @@ -27,6 +27,9 @@ func TestAccAlertV2Downtime(t *testing.T) { { Config: alertV2DowntimeWithName(rText()), }, + { + Config: alertV2DowntimeWithWithUnreportedAlertNotificationsRetentionSec(rText()), + }, { Config: alertV2DowntimeWithGroupBy(rText()), }, @@ -60,6 +63,28 @@ resource "sysdig_monitor_alert_v2_downtime" "sample" { `, name) } +func alertV2DowntimeWithWithUnreportedAlertNotificationsRetentionSec(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_alert_v2_downtime" "sample" { + + name = "TERRAFORM TEST - DOWNTIMEV2 %s" + metric = "sysdig_container_up" + threshold = 75 + + scope { + label = "kube_cluster_name" + operator = "in" + values = ["thom-cluster1", "demo-env-prom"] + } + + trigger_after_minutes = 15 + unreported_alert_notifications_retention_seconds = 60 * 60 * 24 * 30 + +} + +`, name) +} + func alertV2DowntimeWithGroupBy(name string) string { return fmt.Sprintf(` resource "sysdig_monitor_alert_v2_downtime" "sample" { diff --git a/sysdig/resource_sysdig_monitor_alert_v2_form_based_prometheus.go b/sysdig/resource_sysdig_monitor_alert_v2_form_based_prometheus.go index 908f7c8c..135ab002 100644 --- a/sysdig/resource_sysdig_monitor_alert_v2_form_based_prometheus.go +++ b/sysdig/resource_sysdig_monitor_alert_v2_form_based_prometheus.go @@ -57,6 +57,11 @@ func resourceSysdigMonitorAlertV2FormBasedPrometheus() *schema.Resource { Default: "DO_NOTHING", ValidateFunc: validation.StringInSlice([]string{"DO_NOTHING", "TRIGGER"}, false), }, + "unreported_alert_notifications_retention_seconds": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(60), + }, })), } } @@ -193,10 +198,17 @@ func buildAlertV2FormBasedPrometheusStruct(d *schema.ResourceData) (*v2.AlertV2F config.NoDataBehaviour = d.Get("no_data_behaviour").(string) + var unreportedAlertNotificationsRetentionSec *int + if unreportedAlertNotificationsRetentionSecInterface, ok := d.GetOk("unreported_alert_notifications_retention_seconds"); ok { + u := unreportedAlertNotificationsRetentionSecInterface.(int) + unreportedAlertNotificationsRetentionSec = &u + } + alert := &v2.AlertV2FormBasedPrometheus{ - AlertV2Common: *alertV2Common, - DurationSec: 0, - Config: config, + AlertV2Common: *alertV2Common, + DurationSec: 0, + Config: config, + UnreportedAlertNotificationsRetentionSec: unreportedAlertNotificationsRetentionSec, } return alert, nil } @@ -224,5 +236,11 @@ func updateAlertV2FormBasedPrometheusState(d *schema.ResourceData, alert *v2.Ale _ = d.Set("no_data_behaviour", alert.Config.NoDataBehaviour) + if alert.UnreportedAlertNotificationsRetentionSec != nil { + _ = d.Set("unreported_alert_notifications_retention_seconds", *alert.UnreportedAlertNotificationsRetentionSec) + } else { + _ = d.Set("unreported_alert_notifications_retention_seconds", nil) + } + return nil } diff --git a/sysdig/resource_sysdig_monitor_alert_v2_metric.go b/sysdig/resource_sysdig_monitor_alert_v2_metric.go index 4b976c3d..03a3f40f 100644 --- a/sysdig/resource_sysdig_monitor_alert_v2_metric.go +++ b/sysdig/resource_sysdig_monitor_alert_v2_metric.go @@ -71,6 +71,11 @@ func resourceSysdigMonitorAlertV2Metric() *schema.Resource { Default: "DO_NOTHING", ValidateFunc: validation.StringInSlice([]string{"DO_NOTHING", "TRIGGER"}, false), }, + "unreported_alert_notifications_retention_seconds": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntAtLeast(60), + }, })), } } @@ -214,10 +219,17 @@ func buildAlertV2MetricStruct(d *schema.ResourceData) (*v2.AlertV2Metric, error) config.NoDataBehaviour = d.Get("no_data_behaviour").(string) + var unreportedAlertNotificationsRetentionSec *int + if unreportedAlertNotificationsRetentionSecInterface, ok := d.GetOk("unreported_alert_notifications_retention_seconds"); ok { + u := unreportedAlertNotificationsRetentionSecInterface.(int) + unreportedAlertNotificationsRetentionSec = &u + } + alert := &v2.AlertV2Metric{ - AlertV2Common: *alertV2Common, - DurationSec: minutesToSeconds(d.Get("trigger_after_minutes").(int)), - Config: config, + AlertV2Common: *alertV2Common, + DurationSec: minutesToSeconds(d.Get("trigger_after_minutes").(int)), + Config: config, + UnreportedAlertNotificationsRetentionSec: unreportedAlertNotificationsRetentionSec, } return alert, nil } @@ -251,5 +263,11 @@ func updateAlertV2MetricState(d *schema.ResourceData, alert *v2.AlertV2Metric) e _ = d.Set("no_data_behaviour", alert.Config.NoDataBehaviour) + if alert.UnreportedAlertNotificationsRetentionSec != nil { + _ = d.Set("unreported_alert_notifications_retention_seconds", *alert.UnreportedAlertNotificationsRetentionSec) + } else { + _ = d.Set("unreported_alert_notifications_retention_seconds", nil) + } + return nil } diff --git a/sysdig/resource_sysdig_monitor_alert_v2_metric_test.go b/sysdig/resource_sysdig_monitor_alert_v2_metric_test.go index 7471d7af..d2e4e6ce 100644 --- a/sysdig/resource_sysdig_monitor_alert_v2_metric_test.go +++ b/sysdig/resource_sysdig_monitor_alert_v2_metric_test.go @@ -60,6 +60,9 @@ func TestAccAlertV2Metric(t *testing.T) { { Config: alertV2MetricWithEnabled(rText()), }, + { + Config: alertV2MetricWithUnreportedAlertNotificationsRetentionSec(rText()), + }, { Config: alertV2MetricWithWarningThreshold(rText()), }, @@ -344,6 +347,22 @@ resource "sysdig_monitor_alert_v2_metric" "sample" { `, name) } +func alertV2MetricWithUnreportedAlertNotificationsRetentionSec(name string) string { + return fmt.Sprintf(` +resource "sysdig_monitor_alert_v2_metric" "sample" { + + name = "TERRAFORM TEST - METRICV2 %s" + metric = "sysdig_container_cpu_used_percent" + group_aggregation = "avg" + time_aggregation = "avg" + operator = ">=" + threshold = 50 + trigger_after_minutes = 15 + unreported_alert_notifications_retention_seconds = 60 * 60 * 24 * 30 +} +`, name) +} + func alertV2MetricWithWarningThreshold(name string) string { return fmt.Sprintf(` resource "sysdig_monitor_notification_channel_email" "nc_email1" { diff --git a/sysdig/resource_sysdig_secure_custom_policy.go b/sysdig/resource_sysdig_secure_custom_policy.go index a112f7de..44beeae5 100644 --- a/sysdig/resource_sysdig_secure_custom_policy.go +++ b/sysdig/resource_sysdig_secure_custom_policy.go @@ -72,7 +72,8 @@ func resourceSysdigSecureCustomPolicy() *schema.Resource { } func resourceSysdigCustomPolicyCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecurePolicyClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecurePolicyClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -82,6 +83,7 @@ func resourceSysdigCustomPolicyCreate(ctx context.Context, d *schema.ResourceDat if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) customPolicyToResourceData(&policy, d) @@ -140,8 +142,9 @@ func resourceSysdigCustomPolicyRead(ctx context.Context, d *schema.ResourceData, id, _ := strconv.Atoi(d.Id()) policy, statusCode, err := client.GetPolicyByID(ctx, id) if err != nil { - d.SetId("") if statusCode == http.StatusNotFound { + d.SetId("") + } else { return diag.FromErr(err) } } @@ -152,7 +155,8 @@ func resourceSysdigCustomPolicyRead(ctx context.Context, d *schema.ResourceData, } func resourceSysdigCustomPolicyDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecurePolicyClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecurePolicyClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -163,12 +167,14 @@ func resourceSysdigCustomPolicyDelete(ctx context.Context, d *schema.ResourceDat if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) return nil } func resourceSysdigCustomPolicyUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecurePolicyClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecurePolicyClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -183,6 +189,8 @@ func resourceSysdigCustomPolicyUpdate(ctx context.Context, d *schema.ResourceDat if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) + return nil } diff --git a/sysdig/resource_sysdig_secure_list.go b/sysdig/resource_sysdig_secure_list.go index 9c27e0ae..6e4be74e 100644 --- a/sysdig/resource_sysdig_secure_list.go +++ b/sysdig/resource_sysdig_secure_list.go @@ -62,7 +62,8 @@ func getSecureListClient(c SysdigClients) (v2.ListInterface, error) { } func resourceSysdigListCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureListClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureListClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -72,6 +73,7 @@ func resourceSysdigListCreate(ctx context.Context, d *schema.ResourceData, meta if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) d.SetId(strconv.Itoa(list.ID)) _ = d.Set("version", list.Version) @@ -80,7 +82,8 @@ func resourceSysdigListCreate(ctx context.Context, d *schema.ResourceData, meta } func resourceSysdigListUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureListClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureListClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -95,6 +98,8 @@ func resourceSysdigListUpdate(ctx context.Context, d *schema.ResourceData, meta if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) + return nil } @@ -119,7 +124,8 @@ func resourceSysdigListRead(ctx context.Context, d *schema.ResourceData, meta in } func resourceSysdigListDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureListClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureListClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -130,6 +136,8 @@ func resourceSysdigListDelete(ctx context.Context, d *schema.ResourceData, meta if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) + return nil } diff --git a/sysdig/resource_sysdig_secure_macro.go b/sysdig/resource_sysdig_secure_macro.go index 08528772..03940fa5 100644 --- a/sysdig/resource_sysdig_secure_macro.go +++ b/sysdig/resource_sysdig_secure_macro.go @@ -62,7 +62,8 @@ func getSecureMacroClient(c SysdigClients) (v2.MacroInterface, error) { } func resourceSysdigMacroCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureMacroClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureMacroClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -72,6 +73,7 @@ func resourceSysdigMacroCreate(ctx context.Context, d *schema.ResourceData, meta if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) d.SetId(strconv.Itoa(macro.ID)) _ = d.Set("version", macro.Version) @@ -80,7 +82,8 @@ func resourceSysdigMacroCreate(ctx context.Context, d *schema.ResourceData, meta } func resourceSysdigMacroUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureMacroClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureMacroClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -95,6 +98,8 @@ func resourceSysdigMacroUpdate(ctx context.Context, d *schema.ResourceData, meta if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) + return nil } @@ -122,7 +127,8 @@ func resourceSysdigMacroRead(ctx context.Context, d *schema.ResourceData, meta i } func resourceSysdigMacroDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureMacroClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureMacroClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -133,6 +139,8 @@ func resourceSysdigMacroDelete(ctx context.Context, d *schema.ResourceData, meta if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) + return nil } diff --git a/sysdig/resource_sysdig_secure_managed_policy.go b/sysdig/resource_sysdig_secure_managed_policy.go index 38b03397..5f583061 100644 --- a/sysdig/resource_sysdig_secure_managed_policy.go +++ b/sysdig/resource_sysdig_secure_managed_policy.go @@ -46,7 +46,8 @@ func resourceSysdigSecureManagedPolicy() *schema.Resource { } func resourceSysdigManagedPolicyCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecurePolicyClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecurePolicyClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -65,6 +66,7 @@ func resourceSysdigManagedPolicyCreate(ctx context.Context, d *schema.ResourceDa if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) managedPolicyToResourceData(&updatedPolicy, d) @@ -111,8 +113,9 @@ func resourceSysdigManagedPolicyRead(ctx context.Context, d *schema.ResourceData id, _ := strconv.Atoi(d.Id()) policy, statusCode, err := client.GetPolicyByID(ctx, id) if err != nil { - d.SetId("") if statusCode == http.StatusNotFound { + d.SetId("") + } else { return diag.FromErr(err) } } @@ -123,7 +126,8 @@ func resourceSysdigManagedPolicyRead(ctx context.Context, d *schema.ResourceData } func resourceSysdigManagedPolicyDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecurePolicyClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecurePolicyClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -133,8 +137,9 @@ func resourceSysdigManagedPolicyDelete(ctx context.Context, d *schema.ResourceDa // Reset everything back to default values for managed policy policy, statusCode, err := client.GetPolicyByID(ctx, id) if err != nil { - d.SetId("") if statusCode == http.StatusNotFound { + d.SetId("") + } else { return diag.FromErr(err) } } @@ -153,12 +158,14 @@ func resourceSysdigManagedPolicyDelete(ctx context.Context, d *schema.ResourceDa if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) return nil } func resourceSysdigManagedPolicyUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecurePolicyClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecurePolicyClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -167,8 +174,9 @@ func resourceSysdigManagedPolicyUpdate(ctx context.Context, d *schema.ResourceDa policy, statusCode, err := client.GetPolicyByID(ctx, id) if err != nil { - d.SetId("") if statusCode == http.StatusNotFound { + d.SetId("") + } else { return diag.FromErr(err) } } @@ -179,6 +187,8 @@ func resourceSysdigManagedPolicyUpdate(ctx context.Context, d *schema.ResourceDa if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) + return nil } diff --git a/sysdig/resource_sysdig_secure_managed_ruleset.go b/sysdig/resource_sysdig_secure_managed_ruleset.go index a791c7fc..0625f824 100644 --- a/sysdig/resource_sysdig_secure_managed_ruleset.go +++ b/sysdig/resource_sysdig_secure_managed_ruleset.go @@ -77,7 +77,8 @@ func resourceSysdigSecureManagedRuleset() *schema.Resource { } func resourceSysdigManagedRulesetCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecurePolicyClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecurePolicyClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -101,6 +102,7 @@ func resourceSysdigManagedRulesetCreate(ctx context.Context, d *schema.ResourceD if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) managedRulesetToResourceData(&createdPolicy, d) @@ -148,8 +150,9 @@ func resourceSysdigManagedRulesetRead(ctx context.Context, d *schema.ResourceDat id, _ := strconv.Atoi(d.Id()) policy, statusCode, err := client.GetPolicyByID(ctx, id) if err != nil { - d.SetId("") if statusCode == http.StatusNotFound { + d.SetId("") + } else { return diag.FromErr(err) } } @@ -160,7 +163,8 @@ func resourceSysdigManagedRulesetRead(ctx context.Context, d *schema.ResourceDat } func resourceSysdigManagedRulesetDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecurePolicyClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecurePolicyClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -171,12 +175,14 @@ func resourceSysdigManagedRulesetDelete(ctx context.Context, d *schema.ResourceD if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) return nil } func resourceSysdigManagedRulesetUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecurePolicyClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecurePolicyClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -185,8 +191,9 @@ func resourceSysdigManagedRulesetUpdate(ctx context.Context, d *schema.ResourceD policy, statusCode, err := client.GetPolicyByID(ctx, id) if err != nil { - d.SetId("") if statusCode == http.StatusNotFound { + d.SetId("") + } else { return diag.FromErr(err) } } @@ -197,6 +204,8 @@ func resourceSysdigManagedRulesetUpdate(ctx context.Context, d *schema.ResourceD if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) + return nil } diff --git a/sysdig/resource_sysdig_secure_policy.go b/sysdig/resource_sysdig_secure_policy.go index e9e5fc67..377b1ff7 100644 --- a/sysdig/resource_sysdig_secure_policy.go +++ b/sysdig/resource_sysdig_secure_policy.go @@ -2,13 +2,16 @@ package sysdig import ( "context" + "fmt" "net/http" "strconv" "strings" + "sync" "time" v2 "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2" + "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -150,7 +153,8 @@ func getSecurePolicyClient(c SysdigClients) (v2.PolicyInterface, error) { } func resourceSysdigPolicyCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecurePolicyClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecurePolicyClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -160,6 +164,7 @@ func resourceSysdigPolicyCreate(ctx context.Context, d *schema.ResourceData, met if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) policyToResourceData(&policy, d) @@ -290,8 +295,9 @@ func resourceSysdigPolicyRead(ctx context.Context, d *schema.ResourceData, meta id, _ := strconv.Atoi(d.Id()) policy, statusCode, err := client.GetPolicyByID(ctx, id) if err != nil { - d.SetId("") if statusCode == http.StatusNotFound { + d.SetId("") + } else { return diag.FromErr(err) } } @@ -302,7 +308,8 @@ func resourceSysdigPolicyRead(ctx context.Context, d *schema.ResourceData, meta } func resourceSysdigPolicyDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecurePolicyClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecurePolicyClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -313,12 +320,14 @@ func resourceSysdigPolicyDelete(ctx context.Context, d *schema.ResourceData, met if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) return nil } func resourceSysdigPolicyUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecurePolicyClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecurePolicyClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -333,5 +342,31 @@ func resourceSysdigPolicyUpdate(ctx context.Context, d *schema.ResourceData, met if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) + return nil } + +var sendPoliciesToAgentsOnce sync.Once + +func sendPoliciesToAgents(ctx context.Context, clients SysdigClients) error { + var err error + sendPoliciesToAgentsOnce.Do(func() { + tflog.Info(ctx, "Sending policies to agents") + var client v2.PolicyInterface + client, err = getSecurePolicyClient(clients) + if err != nil { + return + } + + // When running as a cleanup hook, the terraform context is in a cancelled state. + // Using a background context with a deadline will allow us to complete this request. + backgroundCtx, cancel := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second)) + defer cancel() + err = client.SendPoliciesToAgents(backgroundCtx) + }) + if err != nil { + tflog.Error(ctx, fmt.Sprintf("Error in sendPoliciesToAgents: %s", err.Error())) + } + return err +} diff --git a/sysdig/resource_sysdig_secure_rule_container.go b/sysdig/resource_sysdig_secure_rule_container.go index d1d36691..69322019 100644 --- a/sysdig/resource_sysdig_secure_rule_container.go +++ b/sysdig/resource_sysdig_secure_rule_container.go @@ -2,6 +2,7 @@ package sysdig import ( "context" + "net/http" "strconv" "time" @@ -49,7 +50,8 @@ func resourceSysdigSecureRuleContainer() *schema.Resource { } func resourceSysdigRuleContainerCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -60,6 +62,7 @@ func resourceSysdigRuleContainerCreate(ctx context.Context, d *schema.ResourceDa if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) d.SetId(strconv.Itoa(rule.ID)) _ = d.Set("version", rule.Version) @@ -79,9 +82,14 @@ func resourceSysdigRuleContainerRead(ctx context.Context, d *schema.ResourceData return diag.FromErr(err) } - rule, err := client.GetRuleByID(ctx, id) + rule, statusCode, err := client.GetRuleByID(ctx, id) + if err != nil { - d.SetId("") + if statusCode == http.StatusNotFound { + d.SetId("") + } else { + return diag.FromErr(err) + } } if rule.Details.Containers == nil { @@ -96,7 +104,8 @@ func resourceSysdigRuleContainerRead(ctx context.Context, d *schema.ResourceData } func resourceSysdigRuleContainerUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -110,12 +119,14 @@ func resourceSysdigRuleContainerUpdate(ctx context.Context, d *schema.ResourceDa if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) return nil } func resourceSysdigRuleContainerDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -129,6 +140,8 @@ func resourceSysdigRuleContainerDelete(ctx context.Context, d *schema.ResourceDa if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) + return nil } diff --git a/sysdig/resource_sysdig_secure_rule_falco.go b/sysdig/resource_sysdig_secure_rule_falco.go index 117eaef8..2999437b 100644 --- a/sysdig/resource_sysdig_secure_rule_falco.go +++ b/sysdig/resource_sysdig_secure_rule_falco.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "net/http" "strconv" "strings" "time" @@ -100,7 +101,8 @@ func resourceSysdigSecureRuleFalco() *schema.Resource { } func resourceSysdigRuleFalcoCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -114,6 +116,7 @@ func resourceSysdigRuleFalcoCreate(ctx context.Context, d *schema.ResourceData, if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) d.SetId(strconv.Itoa(rule.ID)) _ = d.Set("version", rule.Version) @@ -133,9 +136,13 @@ func resourceSysdigRuleFalcoRead(ctx context.Context, d *schema.ResourceData, me return diag.FromErr(err) } - rule, err := client.GetRuleByID(ctx, id) + rule, statusCode, err := client.GetRuleByID(ctx, id) if err != nil { - d.SetId("") + if statusCode == http.StatusNotFound { + d.SetId("") + } else { + return diag.FromErr(err) + } } if rule.Details.Append != nil && !(*(rule.Details.Append)) { @@ -212,7 +219,8 @@ func fieldOrCompsToStringSlice(fields any) ([]string, error) { } func resourceSysdigRuleFalcoUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -229,12 +237,14 @@ func resourceSysdigRuleFalcoUpdate(ctx context.Context, d *schema.ResourceData, if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) return nil } func resourceSysdigRuleFalcoDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -248,6 +258,8 @@ func resourceSysdigRuleFalcoDelete(ctx context.Context, d *schema.ResourceData, if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) + return nil } diff --git a/sysdig/resource_sysdig_secure_rule_filesystem.go b/sysdig/resource_sysdig_secure_rule_filesystem.go index 5314fb14..9044b91b 100644 --- a/sysdig/resource_sysdig_secure_rule_filesystem.go +++ b/sysdig/resource_sysdig_secure_rule_filesystem.go @@ -2,6 +2,7 @@ package sysdig import ( "context" + "net/http" "strconv" "time" @@ -77,7 +78,8 @@ func resourceSysdigSecureRuleFilesystem() *schema.Resource { } func resourceSysdigRuleFilesystemCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -91,6 +93,7 @@ func resourceSysdigRuleFilesystemCreate(ctx context.Context, d *schema.ResourceD if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) d.SetId(strconv.Itoa(rule.ID)) _ = d.Set("version", rule.Version) @@ -110,9 +113,13 @@ func resourceSysdigRuleFilesystemRead(ctx context.Context, d *schema.ResourceDat return diag.FromErr(err) } - rule, err := client.GetRuleByID(ctx, id) + rule, statusCode, err := client.GetRuleByID(ctx, id) if err != nil { - d.SetId("") + if statusCode == http.StatusNotFound { + d.SetId("") + } else { + return diag.FromErr(err) + } } updateResourceDataForRule(d, rule) @@ -142,7 +149,8 @@ func resourceSysdigRuleFilesystemRead(ctx context.Context, d *schema.ResourceDat } func resourceSysdigRuleFilesystemUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -159,12 +167,14 @@ func resourceSysdigRuleFilesystemUpdate(ctx context.Context, d *schema.ResourceD if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) return nil } func resourceSysdigRuleFilesystemDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -178,6 +188,7 @@ func resourceSysdigRuleFilesystemDelete(ctx context.Context, d *schema.ResourceD if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) return nil } diff --git a/sysdig/resource_sysdig_secure_rule_network.go b/sysdig/resource_sysdig_secure_rule_network.go index f701fc3c..8987637d 100644 --- a/sysdig/resource_sysdig_secure_rule_network.go +++ b/sysdig/resource_sysdig_secure_rule_network.go @@ -2,6 +2,7 @@ package sysdig import ( "context" + "net/http" "strconv" "time" @@ -85,7 +86,8 @@ func resourceSysdigSecureRuleNetwork() *schema.Resource { } func resourceSysdigRuleNetworkCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -99,6 +101,7 @@ func resourceSysdigRuleNetworkCreate(ctx context.Context, d *schema.ResourceData if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) d.SetId(strconv.Itoa(rule.ID)) _ = d.Set("version", rule.Version) @@ -118,9 +121,14 @@ func resourceSysdigRuleNetworkRead(ctx context.Context, d *schema.ResourceData, return diag.FromErr(err) } - rule, err := client.GetRuleByID(ctx, id) + rule, statusCode, err := client.GetRuleByID(ctx, id) + if err != nil { - d.SetId("") + if statusCode == http.StatusNotFound { + d.SetId("") + } else { + return diag.FromErr(err) + } } updateResourceDataForRule(d, rule) @@ -168,7 +176,8 @@ func resourceSysdigRuleNetworkRead(ctx context.Context, d *schema.ResourceData, } func resourceSysdigRuleNetworkUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -185,12 +194,14 @@ func resourceSysdigRuleNetworkUpdate(ctx context.Context, d *schema.ResourceData if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) return nil } func resourceSysdigRuleNetworkDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -204,6 +215,7 @@ func resourceSysdigRuleNetworkDelete(ctx context.Context, d *schema.ResourceData if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) return nil } diff --git a/sysdig/resource_sysdig_secure_rule_process.go b/sysdig/resource_sysdig_secure_rule_process.go index 7836ab38..2573ea59 100644 --- a/sysdig/resource_sysdig_secure_rule_process.go +++ b/sysdig/resource_sysdig_secure_rule_process.go @@ -2,6 +2,7 @@ package sysdig import ( "context" + "net/http" "strconv" "time" @@ -49,7 +50,8 @@ func resourceSysdigSecureRuleProcess() *schema.Resource { } func resourceSysdigRuleProcessCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -60,6 +62,7 @@ func resourceSysdigRuleProcessCreate(ctx context.Context, d *schema.ResourceData if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) d.SetId(strconv.Itoa(rule.ID)) _ = d.Set("version", rule.Version) @@ -79,9 +82,14 @@ func resourceSysdigRuleProcessRead(ctx context.Context, d *schema.ResourceData, return diag.FromErr(err) } - rule, err := client.GetRuleByID(ctx, id) + rule, statusCode, err := client.GetRuleByID(ctx, id) + if err != nil { - d.SetId("") + if statusCode == http.StatusNotFound { + d.SetId("") + } else { + return diag.FromErr(err) + } } if rule.Details.Processes == nil { @@ -96,7 +104,8 @@ func resourceSysdigRuleProcessRead(ctx context.Context, d *schema.ResourceData, } func resourceSysdigRuleProcessUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -110,12 +119,14 @@ func resourceSysdigRuleProcessUpdate(ctx context.Context, d *schema.ResourceData if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) return nil } func resourceSysdigRuleProcessDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -129,6 +140,8 @@ func resourceSysdigRuleProcessDelete(ctx context.Context, d *schema.ResourceData if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) + return nil } diff --git a/sysdig/resource_sysdig_secure_rule_syscall.go b/sysdig/resource_sysdig_secure_rule_syscall.go index b4794697..ad7facf8 100644 --- a/sysdig/resource_sysdig_secure_rule_syscall.go +++ b/sysdig/resource_sysdig_secure_rule_syscall.go @@ -2,6 +2,7 @@ package sysdig import ( "context" + "net/http" "strconv" "time" @@ -48,7 +49,8 @@ func resourceSysdigSecureRuleSyscall() *schema.Resource { } func resourceSysdigRuleSyscallCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -59,6 +61,7 @@ func resourceSysdigRuleSyscallCreate(ctx context.Context, d *schema.ResourceData if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) d.SetId(strconv.Itoa(rule.ID)) _ = d.Set("version", rule.Version) @@ -78,9 +81,14 @@ func resourceSysdigRuleSyscallRead(ctx context.Context, d *schema.ResourceData, return diag.FromErr(err) } - rule, err := client.GetRuleByID(ctx, id) + rule, statusCode, err := client.GetRuleByID(ctx, id) + if err != nil { - d.SetId("") + if statusCode == http.StatusNotFound { + d.SetId("") + } else { + return diag.FromErr(err) + } } if rule.Details.Syscalls == nil { @@ -95,7 +103,8 @@ func resourceSysdigRuleSyscallRead(ctx context.Context, d *schema.ResourceData, } func resourceSysdigRuleSyscallUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -109,12 +118,14 @@ func resourceSysdigRuleSyscallUpdate(ctx context.Context, d *schema.ResourceData if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) return nil } func resourceSysdigRuleSyscallDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - client, err := getSecureRuleClient(meta.(SysdigClients)) + sysdigClients := meta.(SysdigClients) + client, err := getSecureRuleClient(sysdigClients) if err != nil { return diag.FromErr(err) } @@ -128,6 +139,8 @@ func resourceSysdigRuleSyscallDelete(ctx context.Context, d *schema.ResourceData if err != nil { return diag.FromErr(err) } + sysdigClients.AddCleanupHook(sendPoliciesToAgents) + return nil } diff --git a/sysdig/resource_sysdig_team_service_account.go b/sysdig/resource_sysdig_team_service_account.go index 17df8d5b..4e27af6b 100644 --- a/sysdig/resource_sysdig_team_service_account.go +++ b/sysdig/resource_sysdig_team_service_account.go @@ -35,19 +35,23 @@ func resourceSysdigTeamServiceAccount() *schema.Resource { Type: schema.TypeString, Optional: true, Default: "ROLE_TEAM_READ", + ForceNew: true, }, SchemaExpirationDateKey: { Type: schema.TypeInt, Required: true, + ForceNew: true, }, SchemaTeamIDKey: { Type: schema.TypeInt, Required: true, + ForceNew: true, }, SchemaSystemRoleKey: { Type: schema.TypeString, Optional: true, Default: "ROLE_SERVICE_ACCOUNT", + ForceNew: true, }, SchemaCreatedDateKey: { Type: schema.TypeInt, @@ -105,6 +109,10 @@ func resourceSysdigTeamServiceAccountCreate(ctx context.Context, d *schema.Resou } d.SetId(strconv.Itoa(teamServiceAccount.ID)) + err = d.Set(SchemaApiKeyKey, teamServiceAccount.ApiKey) + if err != nil { + return diag.FromErr(err) + } resourceSysdigTeamServiceAccountRead(ctx, d, m) @@ -190,10 +198,6 @@ func teamServiceAccountToResourceData(teamServiceAccount *v2.TeamServiceAccount, if err != nil { return err } - err = d.Set(SchemaApiKeyKey, teamServiceAccount.ApiKey) - if err != nil { - return err - } return nil } diff --git a/sysdig/resource_sysdig_team_service_account_test.go b/sysdig/resource_sysdig_team_service_account_test.go index aec39f07..ce790082 100644 --- a/sysdig/resource_sysdig_team_service_account_test.go +++ b/sysdig/resource_sysdig_team_service_account_test.go @@ -37,6 +37,33 @@ func TestAccTeamServiceAccount(t *testing.T) { "role", "ROLE_TEAM_READ", ), + resource.TestCheckResourceAttrSet("sysdig_team_service_account.service-account-monitor", + "api_key", + ), + resource.TestCheckResourceAttr("sysdig_team_service_account.service-account-monitor", + "expiration_date", + "4070908800", + ), + ), + }, + { + Config: teamServiceAccountMonitorTeamNewExpirationDate(monitorsvc), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("sysdig_team_service_account.service-account-monitor", + "name", + monitorsvc, + ), + resource.TestCheckResourceAttr("sysdig_team_service_account.service-account-monitor", + "role", + "ROLE_TEAM_READ", + ), + resource.TestCheckResourceAttrSet("sysdig_team_service_account.service-account-monitor", + "api_key", + ), + resource.TestCheckResourceAttr("sysdig_team_service_account.service-account-monitor", + "expiration_date", + "4070995200", + ), ), }, { @@ -50,6 +77,9 @@ func TestAccTeamServiceAccount(t *testing.T) { "role", "ROLE_TEAM_READ", ), + resource.TestCheckResourceAttrSet("sysdig_team_service_account.service-account-secure", + "api_key", + ), ), }, }, @@ -78,6 +108,28 @@ resource "sysdig_team_service_account" "service-account-monitor" { `, name, name) } +func teamServiceAccountMonitorTeamNewExpirationDate(name string) string { + return fmt.Sprintf(` +resource "time_static" "example" { + rfc3339 = "2099-01-02T00:00:00Z" +} + +resource "sysdig_monitor_team" "sample" { + name = "monitor-sample-%s" + + entrypoint { + type = "Explore" + } +} + +resource "sysdig_team_service_account" "service-account-monitor" { + name = "%s" + expiration_date = time_static.example.unix + team_id = sysdig_monitor_team.sample.id +} +`, name, name) +} + func teamServiceAccountSecureTeam(name string) string { return fmt.Sprintf(` resource "time_static" "example" { diff --git a/sysdig/sysdig_clients.go b/sysdig/sysdig_clients.go index 39722b8a..51aa8acb 100644 --- a/sysdig/sysdig_clients.go +++ b/sysdig/sysdig_clients.go @@ -1,8 +1,10 @@ package sysdig import ( + "context" "errors" "fmt" + "io" "sync" v2 "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2" @@ -11,10 +13,14 @@ import ( ) type SysdigClients interface { + io.Closer GetClientType() ClientType GetSecureEndpoint() (string, error) GetSecureApiToken() (string, error) + Configure(context.Context, *schema.ResourceData) + AddCleanupHook(func(context.Context, SysdigClients) error) + // v2 sysdigMonitorClientV2() (v2.SysdigMonitor, error) sysdigSecureClientV2() (v2.SysdigSecure, error) @@ -24,6 +30,10 @@ type SysdigClients interface { sysdigCommonClientV2() (v2.SysdigCommon, error) } +func NewSysdigClients() SysdigClients { + return &sysdigClients{} +} + //go:generate stringer -type ClientType type ClientType int @@ -35,10 +45,13 @@ const ( ) type sysdigClients struct { + ctx context.Context d *schema.ResourceData mu sync.Mutex commonMu sync.Mutex + cleanupHooks []func(context.Context, SysdigClients) error + // v2 monitorClientV2 v2.SysdigMonitor secureClientV2 v2.SysdigSecure @@ -59,6 +72,11 @@ type sysdigVariables struct { token string } +type sysdigSecureVariables struct { + *sysdigVariables + skipPolicyV2Msg bool +} + type ibmVariables struct { *globalVariables iamURL string @@ -90,7 +108,7 @@ func getSysdigMonitorVariables(data *schema.ResourceData) (*sysdigVariables, err }, nil } -func getSysdigSecureVariables(data *schema.ResourceData) (*sysdigVariables, error) { +func getSysdigSecureVariables(data *schema.ResourceData) (*sysdigSecureVariables, error) { var ok bool var apiURL, token interface{} @@ -102,13 +120,21 @@ func getSysdigSecureVariables(data *schema.ResourceData) (*sysdigVariables, erro return nil, errors.New("missing sysdig secure token") } - return &sysdigVariables{ - globalVariables: &globalVariables{ - apiURL: apiURL.(string), - insecure: data.Get("sysdig_secure_insecure_tls").(bool), - extraHeaders: getExtraHeaders(data), + skipPolicyV2Msg := false + if skipPolicyV2MsgValue, ok := data.GetOk("sysdig_secure_skip_policyv2msg"); ok { + skipPolicyV2Msg = skipPolicyV2MsgValue.(bool) + } + + return &sysdigSecureVariables{ + sysdigVariables: &sysdigVariables{ + globalVariables: &globalVariables{ + apiURL: apiURL.(string), + insecure: data.Get("sysdig_secure_insecure_tls").(bool), + extraHeaders: getExtraHeaders(data), + }, + token: token.(string), }, - token: token.(string), + skipPolicyV2Msg: skipPolicyV2Msg, }, nil } @@ -160,6 +186,26 @@ func getIBMSecureVariables(data *schema.ResourceData) (*ibmVariables, error) { return getIBMVariables("secure", data) } +func (c *sysdigClients) Configure(ctx context.Context, d *schema.ResourceData) { + c.ctx = ctx + c.d = d +} + +func (c *sysdigClients) AddCleanupHook(cleanupHook func(context.Context, SysdigClients) error) { + c.mu.Lock() + c.cleanupHooks = append(c.cleanupHooks, cleanupHook) + c.mu.Unlock() +} + +func (c *sysdigClients) Close() error { + for _, cleanup := range c.cleanupHooks { + if err := cleanup(c.ctx, c); err != nil { + return err + } + } + return nil +} + func (c *sysdigClients) GetSecureEndpoint() (string, error) { endpoint := c.d.Get("sysdig_secure_url").(string) if endpoint == "" { @@ -217,6 +263,7 @@ func (c *sysdigClients) sysdigSecureClientV2() (v2.SysdigSecure, error) { v2.WithURL(vars.apiURL), v2.WithInsecure(vars.insecure), v2.WithExtraHeaders(vars.extraHeaders), + v2.WithSkipPolicyV2Msg(vars.skipPolicyV2Msg), ) return c.secureClientV2, nil diff --git a/website/docs/r/custom_role.md b/website/docs/r/custom_role.md index ba941835..542b2793 100644 --- a/website/docs/r/custom_role.md +++ b/website/docs/r/custom_role.md @@ -47,7 +47,7 @@ Permissions block is required and supports: Permissions can have dependencies and dependee. Since the dependencies graph can be hard to determine manually were introduced -[`sysdig_secure_custom_role_permissions`](../d/secure_custom_role_permissions.md) and [`sysdig_monitor_custom_role_permissions`](../d/monitor_custom_role_permissions.md) +[`sysdig_secure_custom_role_permissions`](../data-sources/secure_custom_role_permissions.md) and [`sysdig_monitor_custom_role_permissions`](../data-sources/monitor_custom_role_permissions.md) Please check the relative documentation to see how to use them. diff --git a/website/docs/r/monitor_alert_v2_change.md b/website/docs/r/monitor_alert_v2_change.md index 5c40d243..0f75f80b 100644 --- a/website/docs/r/monitor_alert_v2_change.md +++ b/website/docs/r/monitor_alert_v2_change.md @@ -104,6 +104,7 @@ By defining this field, the user can add link to notifications. * `warning_threshold` - (Optional) Warning threshold used together with `op` to trigger the alert if crossed. Must be a number that triggers the alert before reaching the main `threshold`. * `shorter_time_range_seconds` - (Required) Time range for which data is compared to a longer, previous period. Can be one of `300` (5 minutes), `600` (10 minutes), `3600` (1 hour), `14400` (4 hours), `86400` (1 day). * `longer_time_range_seconds` - (Required) Time range for which data will be used as baseline for comparisons with data in the time range defined in `shorter_time_range_seconds`. Possible values depend on `shorter_time_range_seconds`: for a shorter time range of 5 minutes, longer time range can be 1, 2 or 3 hours, for a shorter time range or 10 minutes, it can be from 1 to 8 hours, for a shorter time range or one hour, it can be from 4 to 24 hours, for a shorter time range of 4 hours, it can be from 1 to 7 days, for a shorter time range of one day, it can only be 7 days. +* `unreported_alert_notifications_retention_seconds` - (Optional) Period after which any alerts triggered for entities (such as containers or hosts) that are no longer reporting data will be automatically marked as 'deactivated'. By default there is no deactivation. ### `scope` diff --git a/website/docs/r/monitor_alert_v2_downtime.md b/website/docs/r/monitor_alert_v2_downtime.md index c568eb26..1ac54968 100644 --- a/website/docs/r/monitor_alert_v2_downtime.md +++ b/website/docs/r/monitor_alert_v2_downtime.md @@ -96,6 +96,7 @@ Enables the creation of a capture file of the syscalls during the event. * `group_by` - (Optional) List of segments to trigger a separate alert on. Example: `["kube_cluster_name", "kube_pod_name"]`. * `metric` - (Required) Metric the alert will act upon. Can be: `sysdig_container_up`, `sysdig_program_up`, `sysdig_host_up`. * `threshold` - (Required) Below of this percentage of downtime the alert will be triggered. Defaults to 100. +* `unreported_alert_notifications_retention_seconds` - (Optional) Period after which any alerts triggered for entities (such as containers or hosts) that are no longer reporting data will be automatically marked as 'deactivated'. By default there is no deactivation. ### `scope` diff --git a/website/docs/r/monitor_alert_v2_form_based_prometheus.md b/website/docs/r/monitor_alert_v2_form_based_prometheus.md index 0ec783b0..f849f2ca 100644 --- a/website/docs/r/monitor_alert_v2_form_based_prometheus.md +++ b/website/docs/r/monitor_alert_v2_form_based_prometheus.md @@ -78,6 +78,7 @@ By defining this field, the user can add link to notifications. * `threshold` - (Required) Threshold used together with `op` to trigger the alert if crossed. * `warning_threshold` - (Optional) Warning threshold used together with `op` to trigger the alert if crossed. Must be a number that triggers the alert before reaching the main `threshold`. * `no_data_behaviour` - (Optional) behaviour in case of missing data. Can be `DO_NOTHING`, i.e. ignore, or `TRIGGER`, i.e. notify on main threshold. Default: `DO_NOTHING`. +* `unreported_alert_notifications_retention_seconds` - (Optional) Period after which any alerts triggered for entities (such as containers or hosts) that are no longer reporting data will be automatically marked as 'deactivated'. By default there is no deactivation. ## Attributes Reference diff --git a/website/docs/r/monitor_alert_v2_metric.md b/website/docs/r/monitor_alert_v2_metric.md index 6bf1eea1..c4c16ab5 100644 --- a/website/docs/r/monitor_alert_v2_metric.md +++ b/website/docs/r/monitor_alert_v2_metric.md @@ -113,6 +113,7 @@ Enables the creation of a capture file of the syscalls during the event. * `threshold` - (Required) Threshold used together with `op` to trigger the alert if crossed. * `warning_threshold` - (Optional) Warning threshold used together with `op` to trigger the alert if crossed. Must be a number that triggers the alert before reaching the main `threshold`. * `no_data_behaviour` - (Optional) behaviour in case of missing data. Can be `DO_NOTHING`, i.e. ignore, or `TRIGGER`, i.e. notify on main threshold. Default: `DO_NOTHING`. +* `unreported_alert_notifications_retention_seconds` - (Optional) Period after which any alerts triggered for entities (such as containers or hosts) that are no longer reporting data will be automatically marked as 'deactivated'. By default there is no deactivation. ### `scope` diff --git a/website/docs/r/team_service_account.md b/website/docs/r/team_service_account.md index bed4c835..48fdb522 100644 --- a/website/docs/r/team_service_account.md +++ b/website/docs/r/team_service_account.md @@ -31,7 +31,7 @@ resource "sysdig_team_service_account" "service-account" { name = "read only" role = "ROLE_TEAM_READ" expiration_date = time_static.example.unix - team_id = sysdig_monitor_teamt.sample.id + team_id = sysdig_monitor_team.devops.id } ``` @@ -64,4 +64,3 @@ Sysdig team service account can be imported using the ID, e.g. ``` $ terraform import sysdig_team_service_account.my_team_service_account 10 ``` -