diff --git a/docs/resources/alertprofile.md b/docs/resources/alertprofile.md index a5ad1090..52cc9723 100644 --- a/docs/resources/alertprofile.md +++ b/docs/resources/alertprofile.md @@ -151,60 +151,67 @@ resource "prismacloudcompute_alertprofile" "test" { ### Required -- `alert_profile_config` (Block List, Min: 1, Max: 1) Alert Profile configuration, the values depend on the alert profile type (see [below for nested schema](#nestedblock--alert_profile_config)) -- `alert_profile_type` (String) Alert Profile type. Valid values are : `webhook` - `name` (String) Alert Profile name ### Optional -- `alert_triggers` (Block List, Max: 1) Policy configuration. (see [below for nested schema](#nestedblock--alert_triggers)) - `enable_immediate_vulnerabilities_alerts` (Boolean) Enable immediate vulnerabilities alerts -- `enabled` (Boolean) Enabled +- `policy` (Block List, Max: 1) Policy configuration. Configure triggers for alerts. (see [below for nested schema](#nestedblock--policy)) +- `slack` (Block List, Max: 1) Alert Profile configuration, the values depend on the alert profile type (see [below for nested schema](#nestedblock--slack)) +- `webhook` (Block List, Max: 1) Alert Profile configuration, the values depend on the alert profile type (see [below for nested schema](#nestedblock--webhook)) ### Read-Only - `id` (String) Alert Profile ID - `owner` (String) Owner - -### Nested Schema for `alert_profile_config` + +### Nested Schema for `policy` Optional: -- `credential_id` (String) Credential ID -- `custom_ca` (String) Custom CA Cert -- `custom_json` (String) Custom JSON payload -- `prisma_cloud_integration_id` (String) ID of the Prisma Cloud Integration -- `webhook_url` (String) Webhook URL +- `admission` (Block List, Max: 1) Admission audits (see [below for nested schema](#nestedblock--policy--admission)) +- `agentless_app_firewall` (Block List, Max: 1) WAAS Firewall (Agentless) (see [below for nested schema](#nestedblock--policy--agentless_app_firewall)) +- `app_embedded_app_firewall` (Block List, Max: 1) WAAS Firewall (App-Embedded Defender) (see [below for nested schema](#nestedblock--policy--app_embedded_app_firewall)) +- `app_embedded_runtime` (Block List, Max: 1) App-Embedded Defender runtime (see [below for nested schema](#nestedblock--policy--app_embedded_runtime)) +- `cloud_discovery` (Block List, Max: 1) Cloud discovery (see [below for nested schema](#nestedblock--policy--cloud_discovery)) +- `code_repo_vulnerability` (Block List, Max: 1) Code repository vulnerabilities (see [below for nested schema](#nestedblock--policy--code_repo_vulnerability)) +- `container_app_firewall` (Block List, Max: 1) WAAS Firewall (container) (see [below for nested schema](#nestedblock--policy--container_app_firewall)) +- `container_compliance` (Block List, Max: 1) (see [below for nested schema](#nestedblock--policy--container_compliance)) +- `container_compliance_scan` (Block List, Max: 1) Container and image compliance (see [below for nested schema](#nestedblock--policy--container_compliance_scan)) +- `container_runtime` (Block List, Max: 1) Container runtime (see [below for nested schema](#nestedblock--policy--container_runtime)) +- `container_vulnerability` (Block List, Max: 1) Deployed image vulnerabilities (see [below for nested schema](#nestedblock--policy--container_vulnerability)) +- `defender` (Block List, Max: 1) Defender health (see [below for nested schema](#nestedblock--policy--defender)) +- `host_app_firewall` (Block List, Max: 1) WAAS Firewall (host) (see [below for nested schema](#nestedblock--policy--host_app_firewall)) +- `host_compliance` (Block List, Max: 1) (see [below for nested schema](#nestedblock--policy--host_compliance)) +- `host_compliance_scan` (Block List, Max: 1) Host compliance (see [below for nested schema](#nestedblock--policy--host_compliance_scan)) +- `host_runtime` (Block List, Max: 1) Host runtime (see [below for nested schema](#nestedblock--policy--host_runtime)) +- `host_vulnerability` (Block List, Max: 1) Host vulnerabilities (see [below for nested schema](#nestedblock--policy--host_vulnerability)) +- `incident` (Block List, Max: 1) Incidents (see [below for nested schema](#nestedblock--policy--incident)) +- `kubernetes_audit` (Block List, Max: 1) Kubernetes audits (see [below for nested schema](#nestedblock--policy--kubernetes_audit)) +- `network_firewall` (Block List, Max: 1) Cloud Native Network Segmentation (CNNS) (see [below for nested schema](#nestedblock--policy--network_firewall)) +- `registry_vulnerability` (Block List, Max: 1) Registry image vulnerabilities (see [below for nested schema](#nestedblock--policy--registry_vulnerability)) +- `serverless_app_firewall` (Block List, Max: 1) WAAS Firewall (serverless) (see [below for nested schema](#nestedblock--policy--serverless_app_firewall)) +- `serverless_runtime` (Block List, Max: 1) Serverless runtime (see [below for nested schema](#nestedblock--policy--serverless_runtime)) +- `vm_compliance` (Block List, Max: 1) VM images compliance (see [below for nested schema](#nestedblock--policy--vm_compliance)) +- `vm_vulnerability` (Block List, Max: 1) VM images vulnerabilities (see [below for nested schema](#nestedblock--policy--vm_vulnerability)) +- `waas_health` (Block List, Max: 1) WAAS health (see [below for nested schema](#nestedblock--policy--waas_health)) + + +### Nested Schema for `policy.admission` +Required: - -### Nested Schema for `alert_triggers` +- `all_rules` (Boolean) +- `enabled` (Boolean) Optional: -- `access` (Block List, Max: 1) Access (Docker) (see [below for nested schema](#nestedblock--alert_triggers--access)) -- `admission` (Block List, Max: 1) Admission audits (see [below for nested schema](#nestedblock--alert_triggers--admission)) -- `app_embedded_defender_runtime` (Block List, Max: 1) App-Embedded Defender runtime (see [below for nested schema](#nestedblock--alert_triggers--app_embedded_defender_runtime)) -- `cloud_native_network_firewall` (Block List, Max: 1) Cloud Native Network Firewall (CNNF) (see [below for nested schema](#nestedblock--alert_triggers--cloud_native_network_firewall)) -- `container_and_image_compliance` (Block List, Max: 1) Container and image compliance (see [below for nested schema](#nestedblock--alert_triggers--container_and_image_compliance)) -- `container_runtime` (Block List, Max: 1) Container runtime (see [below for nested schema](#nestedblock--alert_triggers--container_runtime)) -- `defender_health` (Block List, Max: 1) Defender health (see [below for nested schema](#nestedblock--alert_triggers--defender_health)) -- `host_compliance` (Block List, Max: 1) Host compliance (see [below for nested schema](#nestedblock--alert_triggers--host_compliance)) -- `host_runtime` (Block List, Max: 1) Host runtime (see [below for nested schema](#nestedblock--alert_triggers--host_runtime)) -- `host_vulnerabilities` (Block List, Max: 1) Host vulnerabilities (see [below for nested schema](#nestedblock--alert_triggers--host_vulnerabilities)) -- `image_vulnerabilities` (Block List, Max: 1) Image vulnerabilities (registry and deployed) (see [below for nested schema](#nestedblock--alert_triggers--image_vulnerabilities)) -- `incidents` (Block List, Max: 1) incidents (see [below for nested schema](#nestedblock--alert_triggers--incidents)) -- `kubernetes_audits` (Block List, Max: 1) Kubernetes audits (see [below for nested schema](#nestedblock--alert_triggers--kubernetes_audits)) -- `serverless_runtime` (Block List, Max: 1) Serverless runtime (see [below for nested schema](#nestedblock--alert_triggers--serverless_runtime)) -- `waas_firewall_app_embedded_defender` (Block List, Max: 1) WAAS Firewall (App-Embedded Defender) (see [below for nested schema](#nestedblock--alert_triggers--waas_firewall_app_embedded_defender)) -- `waas_firewall_container` (Block List, Max: 1) WAAS Firewall (container) (see [below for nested schema](#nestedblock--alert_triggers--waas_firewall_container)) -- `waas_firewall_host` (Block List, Max: 1) WAAS Firewall (host) (see [below for nested schema](#nestedblock--alert_triggers--waas_firewall_host)) -- `waas_firewall_serverless` (Block List, Max: 1) WAAS Firewall (serverless) (see [below for nested schema](#nestedblock--alert_triggers--waas_firewall_serverless)) -- `waas_health` (Block List, Max: 1) WAAS health (see [below for nested schema](#nestedblock--alert_triggers--waas_health)) - - -### Nested Schema for `alert_triggers.access` +- `rules` (List of String) + + + +### Nested Schema for `policy.agentless_app_firewall` Required: @@ -216,8 +223,8 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.admission` + +### Nested Schema for `policy.app_embedded_app_firewall` Required: @@ -229,8 +236,8 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.app_embedded_defender_runtime` + +### Nested Schema for `policy.app_embedded_runtime` Required: @@ -242,16 +249,21 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.cloud_native_network_firewall` + +### Nested Schema for `policy.cloud_discovery` Required: +- `all_rules` (Boolean) - `enabled` (Boolean) +Optional: + +- `rules` (List of String) + - -### Nested Schema for `alert_triggers.container_and_image_compliance` + +### Nested Schema for `policy.code_repo_vulnerability` Required: @@ -263,8 +275,8 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.container_runtime` + +### Nested Schema for `policy.container_app_firewall` Required: @@ -276,16 +288,21 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.defender_health` + +### Nested Schema for `policy.container_compliance` Required: +- `all_rules` (Boolean) - `enabled` (Boolean) +Optional: - -### Nested Schema for `alert_triggers.host_compliance` +- `rules` (List of String) + + + +### Nested Schema for `policy.container_compliance_scan` Required: @@ -297,8 +314,8 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.host_runtime` + +### Nested Schema for `policy.container_runtime` Required: @@ -310,8 +327,8 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.host_vulnerabilities` + +### Nested Schema for `policy.container_vulnerability` Required: @@ -323,8 +340,8 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.image_vulnerabilities` + +### Nested Schema for `policy.defender` Required: @@ -336,16 +353,21 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.incidents` + +### Nested Schema for `policy.host_app_firewall` Required: +- `all_rules` (Boolean) - `enabled` (Boolean) +Optional: + +- `rules` (List of String) + - -### Nested Schema for `alert_triggers.kubernetes_audits` + +### Nested Schema for `policy.host_compliance` Required: @@ -357,8 +379,8 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.serverless_runtime` + +### Nested Schema for `policy.host_compliance_scan` Required: @@ -370,8 +392,8 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.waas_firewall_app_embedded_defender` + +### Nested Schema for `policy.host_runtime` Required: @@ -383,8 +405,8 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.waas_firewall_container` + +### Nested Schema for `policy.host_vulnerability` Required: @@ -396,8 +418,8 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.waas_firewall_host` + +### Nested Schema for `policy.incident` Required: @@ -409,8 +431,8 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.waas_firewall_serverless` + +### Nested Schema for `policy.kubernetes_audit` Required: @@ -422,11 +444,112 @@ Optional: - `rules` (List of String) - -### Nested Schema for `alert_triggers.waas_health` + +### Nested Schema for `policy.network_firewall` Required: +- `all_rules` (Boolean) - `enabled` (Boolean) +Optional: + +- `rules` (List of String) + + + +### Nested Schema for `policy.registry_vulnerability` + +Required: + +- `all_rules` (Boolean) +- `enabled` (Boolean) + +Optional: + +- `rules` (List of String) + + + +### Nested Schema for `policy.serverless_app_firewall` + +Required: + +- `all_rules` (Boolean) +- `enabled` (Boolean) + +Optional: + +- `rules` (List of String) + + + +### Nested Schema for `policy.serverless_runtime` + +Required: +- `all_rules` (Boolean) +- `enabled` (Boolean) + +Optional: + +- `rules` (List of String) + + + +### Nested Schema for `policy.vm_compliance` + +Required: + +- `all_rules` (Boolean) +- `enabled` (Boolean) + +Optional: + +- `rules` (List of String) + + + +### Nested Schema for `policy.vm_vulnerability` + +Required: + +- `all_rules` (Boolean) +- `enabled` (Boolean) + +Optional: + +- `rules` (List of String) + + + +### Nested Schema for `policy.waas_health` + +Required: + +- `all_rules` (Boolean) +- `enabled` (Boolean) + +Optional: + +- `rules` (List of String) + + + + +### Nested Schema for `slack` + +Optional: + +- `webhook_url` (String) Webhook URL + + + +### Nested Schema for `webhook` + +Optional: + +- `credential_id` (String) Credential ID +- `custom_ca` (String) Custom CA Cert +- `custom_json` (String) Custom JSON payload +- `url` (String) Webhook URL diff --git a/internal/api/alertprofile/alertprofile.go b/internal/api/alertprofile/alertprofile.go index c08ed0d9..63a7b6fb 100755 --- a/internal/api/alertprofile/alertprofile.go +++ b/internal/api/alertprofile/alertprofile.go @@ -18,11 +18,6 @@ const AlertprofilesEndpoint = "api/v1/alert-profiles" // Ssl string `json:"ssl"` // } -// type Slack struct { -// Enabled bool `json:"enabled"` -// WebhookUrl string `json:"webhookUrl"` -// } - // type Jira struct { // Enabled bool `json:"enabled"` // BaseUrl string `json:"baseUrl"` @@ -55,6 +50,11 @@ const AlertprofilesEndpoint = "api/v1/alert-profiles" // } // Alert profiles types +type Slack struct { + Enabled bool `json:"enabled"` + WebhookUrl string `json:"webhookUrl"` +} + type Webhook struct { Enabled bool `json:"enabled"` CredentialId string `json:"credentialId,omitempty"` @@ -287,6 +287,7 @@ type AlertProfile struct { Name string `json:"name"` VulnerabilityImmediateAlertsEnabled bool `json:"vulnerabilityImmediateAlertsEnabled,omitempty"` Owner string `json:"owner,omitempty"` + Slack Slack `json:"slack,omitempty"` Webhook Webhook `json:"webhook,omitempty"` Policy Policy `json:"policy,omitempty"` } diff --git a/internal/convert/alertprofile.go b/internal/convert/alertprofile.go index 8c7896de..52b4681c 100644 --- a/internal/convert/alertprofile.go +++ b/internal/convert/alertprofile.go @@ -7,7 +7,6 @@ import ( // Converts Alertprofile policy object to schema policy func AlertProfilePoliciesToSchema(d *alertprofile.Policy) interface{} { - alertTriggerPolicies := make(map[string]interface{}) if d.Admission.Enabled { @@ -275,7 +274,6 @@ func AlertProfilePoliciesToSchema(d *alertprofile.Policy) interface{} { // Converts a alertprofile schema to a alertprofile object for SDK compatibility. func SchemaToAlertprofile(d *schema.ResourceData) (alertprofile.AlertProfile, error) { - parsedAlertProfile := alertprofile.AlertProfile{} if val, ok := d.GetOk("name"); ok { @@ -291,16 +289,20 @@ func SchemaToAlertprofile(d *schema.ResourceData) (alertprofile.AlertProfile, er } if wc, ok := d.GetOk("webhook"); ok { + parsedAlertProfile.Webhook.Enabled = true for _, val := range wc.([]interface{}) { parsedAlertProfile.Webhook.Url = val.(map[string]interface{})["url"].(string) parsedAlertProfile.Webhook.CredentialId = val.(map[string]interface{})["credential_id"].(string) parsedAlertProfile.Webhook.CaCert = val.(map[string]interface{})["custom_ca"].(string) parsedAlertProfile.Webhook.Json = val.(map[string]interface{})["custom_json"].(string) } + } else if slack, ok := d.GetOk("slack"); ok { + parsedAlertProfile.Slack.Enabled = true + for _, val := range slack.([]interface{}) { + parsedAlertProfile.Slack.WebhookUrl = val.(map[string]interface{})["webhook_url"].(string) + } } - parsedAlertProfile.Webhook.Enabled = true // Currently only supporting webhook alert profiles - if alertTriggers, ok := d.GetOk("policy"); ok { for _, alertTrigger := range alertTriggers.([]interface{}) { for _, cv := range alertTrigger.(map[string]interface{})["admission"].([]interface{}) { diff --git a/internal/provider/resource_alertprofile.go b/internal/provider/resource_alertprofile.go index 0ca36e78..31950e7c 100644 --- a/internal/provider/resource_alertprofile.go +++ b/internal/provider/resource_alertprofile.go @@ -43,6 +43,22 @@ func resourceAlertprofile() *schema.Resource { Computed: true, Description: "Owner", }, + "slack": { + Type: schema.TypeList, + Optional: true, + MinItems: 1, + MaxItems: 1, + Description: "Alert Profile configuration, the values depend on the alert profile type", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "webhook_url": { + Type: schema.TypeString, + Optional: true, + Description: "Webhook URL", + }, + }, + }, + }, "webhook": { Type: schema.TypeList, Optional: true, @@ -827,10 +843,16 @@ func readAlertprofile(ctx context.Context, d *schema.ResourceData, meta interfac config["credential_id"] = retrievedAlertProfile.Webhook.CredentialId config["custom_ca"] = retrievedAlertProfile.Webhook.CaCert config["custom_json"] = retrievedAlertProfile.Webhook.Json + if err = d.Set("webhook", []interface{}{config}); err != nil { + log.Printf("[WARN] Error setting 'webhook' for %s: %s", d.Id(), err) + } } - if err = d.Set("webhook", []interface{}{config}); err != nil { - log.Printf("[WARN] Error setting 'webhook' for %s: %s", d.Id(), err) + if retrievedAlertProfile.Slack.Enabled { + config["webhook_url"] = retrievedAlertProfile.Slack.WebhookUrl + if err = d.Set("slack", []interface{}{config}); err != nil { + log.Printf("[WARN] Error setting 'slack' for %s: %s", d.Id(), err) + } } alertTriggerPolicies := convert.AlertProfilePoliciesToSchema(&retrievedAlertProfile.Policy) diff --git a/internal/provider/resource_alertprofile_test.go b/internal/provider/resource_alertprofile_test.go index 2eca6755..f2faf3b1 100644 --- a/internal/provider/resource_alertprofile_test.go +++ b/internal/provider/resource_alertprofile_test.go @@ -14,7 +14,8 @@ import ( func TestAccAlertProfileWebhook(t *testing.T) { var o alertprofile.AlertProfile - name := fmt.Sprintf("test-%s", acctest.RandString(6)) + nameWebhook := fmt.Sprintf("test-%s", acctest.RandString(6)) + nameSlack := fmt.Sprintf("test-%s", acctest.RandString(6)) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -22,10 +23,17 @@ func TestAccAlertProfileWebhook(t *testing.T) { CheckDestroy: testAccCheckAlertProfileDestroy, Steps: []resource.TestStep{ { - Config: testAccAlertProfileConfig(name), + Config: testAccAlertProfileWebhookConfig(nameWebhook), Check: resource.ComposeTestCheckFunc( - testAccCheckAlertProfileExists("prismacloudcompute_alertprofile.test", &o), - testAccCheckAlertProfileWebhookAttributes(&o, name), + testAccCheckAlertProfileExists("prismacloudcompute_alertprofile.test_webhook", &o), + testAccCheckAlertProfileWebhookAttributes(&o, nameWebhook), + ), + }, + { + Config: testAccAlertProfileSlackConfig(nameSlack), + Check: resource.ComposeTestCheckFunc( + testAccCheckAlertProfileExists("prismacloudcompute_alertprofile.test_slack", &o), + testAccCheckAlertProfileWebhookAttributes(&o, nameSlack), ), }, }, @@ -89,9 +97,132 @@ func testAccCheckAlertProfileDestroy(s *terraform.State) error { return nil } -func testAccAlertProfileConfig(name string) string { +func testAccAlertProfileSlackConfig(name string) string { + return fmt.Sprintf(` + resource "prismacloudcompute_alertprofile" "test_slack" { + name = "%s" + enable_immediate_vulnerabilities_alerts = false + + slack { + webhook_url = "https://webhook.url" + } + + policy { + admission { + enabled = true + all_rules = true + rules = [] + } + + agentless_app_firewall { + enabled = true + all_rules = true + rules = [] + } + + app_embedded_app_firewall { + enabled = true + all_rules = true + rules = [] + } + + app_embedded_runtime { + enabled = true + all_rules = true + rules = [] + } + + container_app_firewall { + enabled = true + all_rules = true + rules = [] + } + + container_compliance_scan { + enabled = true + all_rules = true + rules = [] + } + + container_vulnerability { + enabled = true + all_rules = true + rules = [] + } + + defender { + enabled = true + all_rules = true + rules = [] + } + + host_app_firewall { + enabled = true + all_rules = true + rules = [] + } + + host_compliance_scan { + enabled = true + all_rules = true + rules = [] + } + + host_runtime { + enabled = true + all_rules = true + rules = [] + } + + incident { + enabled = true + all_rules = true + rules = [] + } + + kubernetes_audit { + enabled = true + all_rules = true + rules = [] + } + + network_firewall { + enabled = true + all_rules = true + rules = [] + } + + registry_vulnerability { + enabled = true + all_rules = true + rules = [] + } + + serverless_app_firewall { + enabled = true + all_rules = true + rules = [] + } + + serverless_runtime { + enabled = true + all_rules = true + rules = [] + } + + waas_health { + enabled = true + all_rules = true + rules = [] + } + } + } + `, name) +} + +func testAccAlertProfileWebhookConfig(name string) string { return fmt.Sprintf(` - resource "prismacloudcompute_alertprofile" "test" { + resource "prismacloudcompute_alertprofile" "test_webhook" { name = "%s" enable_immediate_vulnerabilities_alerts = false @@ -174,12 +305,6 @@ func testAccAlertProfileConfig(name string) string { rules = [] } - docker { - enabled = true - all_rules = true - rules = [] - } - host_app_firewall { enabled = true all_rules = true