Skip to content

Commit

Permalink
feat: supports new notifier_id attribute in alert configuration notif…
Browse files Browse the repository at this point in the history
…ications (#1514)

* fix: alert configuration data source nil pointer with third party notifications

* modify all third party notifications to use fake credentials so acceptance tests are run in CI

* extract dummy keys to common variables

* remove usage of project id env variable in third party alert configuration tests

* feat: supports new notifier_id attribute in alert configuration notifications

* temprary change to use atlas go sdk version with changes

* docs: align documentation of alert config singular data source with plural data source

* fix merge conflict resolution

* update atlas sdk to 0.34.0

* addressing docs PR comments
  • Loading branch information
AgustinBettati committed Oct 13, 2023
1 parent 1100e25 commit 7d38199
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 18 deletions.
2 changes: 2 additions & 0 deletions examples/atlas-alert-configurations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ chmod +x ./import-alerts.sh
terraform apply
```

**NOTE**: Third-party notifications will not contain their respective credentials as these are sensitive attributes. If you wish to perform updates on these notifications without providing the original credentials, the corresponding `notifier_id` attribute must be provided instead.

## Contingency Plans
If unhappy with the resource file or imports, here are some things that can be done:

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ require (
github.com/mwielbut/pointy v1.1.0
github.com/spf13/cast v1.5.1
github.com/zclconf/go-cty v1.14.1
go.mongodb.org/atlas v0.33.0
go.mongodb.org/atlas v0.34.0
go.mongodb.org/atlas-sdk/v20231001001 v20231001001.0.0
go.mongodb.org/realm v0.1.0
golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -721,8 +721,8 @@ github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRK
github.com/zclconf/go-cty-yaml v1.0.2 h1:dNyg4QLTrv2IfJpm7Wtxi55ed5gLGOlPrZ6kMd51hY0=
github.com/zclconf/go-cty-yaml v1.0.2/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0=
go.mongodb.org/atlas v0.12.0/go.mod h1:wVCnHcm/7/IfTjEB6K8K35PLG70yGz8BdkRwX0oK9/M=
go.mongodb.org/atlas v0.33.0 h1:qJhkEuJufh7sVDVHorTF/D7G7naQ1EJAzqf1aV29JWs=
go.mongodb.org/atlas v0.33.0/go.mod h1:L4BKwVx/OeEhOVjCSdgo90KJm4469iv7ZLzQms/EPTg=
go.mongodb.org/atlas v0.34.0 h1:C6pDYjKWbjSZCsNoZpgNO6I5e/jH7OVwoQ0OXcoAFCg=
go.mongodb.org/atlas v0.34.0/go.mod h1:L4BKwVx/OeEhOVjCSdgo90KJm4469iv7ZLzQms/EPTg=
go.mongodb.org/atlas-sdk/v20231001001 v20231001001.0.0 h1:7hl8ap9WzQDcaAO3/FWYdUYee7+taWWpXA4T4bPv6IE=
go.mongodb.org/atlas-sdk/v20231001001 v20231001001.0.0/go.mod h1:2DismEF/fnloT92wjCkA1hpbBGrjQ5fPNAbC48mkRD4=
go.mongodb.org/realm v0.1.0 h1:zJiXyLaZrznQ+Pz947ziSrDKUep39DO4SfA0Fzx8M4M=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ var alertConfigDSSchemaAttributes = map[string]schema.Attribute{
"team_name": schema.StringAttribute{
Computed: true,
},
"notifier_id": schema.StringAttribute{
Computed: true,
},
"type_name": schema.StringAttribute{
Computed: true,
},
Expand Down Expand Up @@ -428,6 +431,10 @@ func convertNotificationToCtyValues(notification *admin.AlertsNotificationRootFo
values["team_name"] = cty.StringVal(*notification.TeamName)
}

if util.IsStringPresent(notification.NotifierId) {
values["notifier_id"] = cty.StringVal(*notification.NotifierId)
}

if util.IsStringPresent(notification.TypeName) {
values["type_name"] = cty.StringVal(*notification.TypeName)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestAccConfigDSAlertConfiguration_basic(t *testing.T) {
testAccCheckMongoDBAtlasAlertConfigurationExists(dataSourceName, alert),
resource.TestCheckResourceAttrSet(dataSourceName, "project_id"),
resource.TestCheckResourceAttr(dataSourceName, "notification.#", "1"),
resource.TestCheckResourceAttrSet(dataSourceName, "notification.0.notifier_id"),
resource.TestCheckResourceAttr(dataSourceName, "matcher.#", "1"),
resource.TestCheckResourceAttr(dataSourceName, "metric_threshold_config.#", "1"),
resource.TestCheckResourceAttr(dataSourceName, "threshold_config.#", "0"),
Expand Down
10 changes: 10 additions & 0 deletions mongodbatlas/fw_resource_mongodbatlas_alert_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ type tfNotificationModel struct {
OpsGenieAPIKey types.String `tfsdk:"ops_genie_api_key"`
TeamID types.String `tfsdk:"team_id"`
TeamName types.String `tfsdk:"team_name"`
NotifierID types.String `tfsdk:"notifier_id"`
TypeName types.String `tfsdk:"type_name"`
ChannelName types.String `tfsdk:"channel_name"`
VictorOpsAPIKey types.String `tfsdk:"victor_ops_api_key"`
Expand Down Expand Up @@ -322,6 +323,10 @@ func (r *AlertConfigurationRS) Schema(ctx context.Context, req resource.SchemaRe
stringplanmodifier.UseStateForUnknown(),
},
},
"notifier_id": schema.StringAttribute{
Computed: true,
Optional: true,
},
"type_name": schema.StringAttribute{
Required: true,
Validators: []validator.String{
Expand Down Expand Up @@ -581,6 +586,7 @@ func newNotificationList(tfNotificationSlice []tfNotificationModel) ([]matlas.No
ServiceKey: value.ServiceKey.ValueString(),
SMSEnabled: value.SMSEnabled.ValueBoolPointer(),
TeamID: value.TeamID.ValueString(),
NotifierID: value.NotifierID.ValueString(),
TypeName: value.TypeName.ValueString(),
Username: value.Username.ValueString(),
VictorOpsAPIKey: value.VictorOpsAPIKey.ValueString(),
Expand Down Expand Up @@ -671,6 +677,7 @@ func newTFNotificationModelList(matlasSlice []matlas.Notification, currStateNoti
TeamID: conversion.StringNullIfEmpty(value.TeamID),
TypeName: conversion.StringNullIfEmpty(value.TypeName),
Username: conversion.StringNullIfEmpty(value.Username),
NotifierID: types.StringValue(value.NotifierID),
EmailEnabled: types.BoolValue(value.EmailEnabled != nil && *value.EmailEnabled),
SMSEnabled: types.BoolValue(value.SMSEnabled != nil && *value.SMSEnabled),
}
Expand Down Expand Up @@ -723,6 +730,7 @@ func newTFNotificationModelList(matlasSlice []matlas.Notification, currStateNoti
newState.Username = conversion.StringNullIfEmpty(value.Username)
}

newState.NotifierID = types.StringValue(value.NotifierID)
newState.IntervalMin = types.Int64Value(int64(value.IntervalMin))
newState.DelayMin = types.Int64Value(int64(*value.DelayMin))
newState.EmailEnabled = types.BoolValue(value.EmailEnabled != nil && *value.EmailEnabled)
Expand Down Expand Up @@ -751,6 +759,7 @@ func newTFNotificationModelListV2(n []admin.AlertsNotificationRootForGroup, curr
MobileNumber: conversion.StringPtrNullIfEmpty(value.MobileNumber),
OpsGenieRegion: conversion.StringPtrNullIfEmpty(value.OpsGenieRegion),
TeamID: conversion.StringPtrNullIfEmpty(value.TeamId),
NotifierID: types.StringPointerValue(value.NotifierId),
TypeName: conversion.StringPtrNullIfEmpty(value.TypeName),
Username: conversion.StringPtrNullIfEmpty(value.Username),
EmailEnabled: types.BoolValue(value.EmailEnabled != nil && *value.EmailEnabled),
Expand Down Expand Up @@ -805,6 +814,7 @@ func newTFNotificationModelListV2(n []admin.AlertsNotificationRootForGroup, curr
newState.Username = conversion.StringPtrNullIfEmpty(value.Username)
}

newState.NotifierID = types.StringPointerValue(value.NotifierId)
newState.IntervalMin = types.Int64PointerValue(util.IntPtrToInt64Ptr(value.IntervalMin))
newState.DelayMin = types.Int64PointerValue(util.IntPtrToInt64Ptr(value.DelayMin))
newState.EmailEnabled = types.BoolValue(value.EmailEnabled != nil && *value.EmailEnabled)
Expand Down
61 changes: 61 additions & 0 deletions mongodbatlas/fw_resource_mongodbatlas_alert_configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,42 @@ func TestAccConfigRSAlertConfiguration_importPagerDuty(t *testing.T) {
})
}

func TestAccConfigRSAlertConfiguration_UpdatePagerDutyWithNotifierId(t *testing.T) {
var (
resourceName = "mongodbatlas_alert_configuration.test"
orgID = os.Getenv("MONGODB_ATLAS_ORG_ID")
projectName = acctest.RandomWithPrefix("test-acc")
serviceKey = dummy32CharKey
notifierID = "651dd9336afac13e1c112222"
alert = &matlas.AlertConfiguration{}
)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheckBasic(t) },
ProtoV6ProviderFactories: testAccProviderV6Factories,
CheckDestroy: testAccCheckMongoDBAtlasAlertConfigurationDestroy,
Steps: []resource.TestStep{
{
Config: testAccMongoDBAtlasAlertConfigurationPagerDutyNotifierIDConfig(orgID, projectName, notifierID, 10, &serviceKey),
Check: resource.ComposeTestCheckFunc(
testAccCheckMongoDBAtlasAlertConfigurationExists(resourceName, alert),
resource.TestCheckResourceAttrSet(resourceName, "project_id"),
resource.TestCheckResourceAttr(resourceName, "notification.0.delay_min", "10"),
resource.TestCheckResourceAttr(resourceName, "notification.0.service_key", serviceKey),
),
},
{
Config: testAccMongoDBAtlasAlertConfigurationPagerDutyNotifierIDConfig(orgID, projectName, notifierID, 15, nil),
Check: resource.ComposeTestCheckFunc(
testAccCheckMongoDBAtlasAlertConfigurationExists(resourceName, alert),
resource.TestCheckResourceAttrSet(resourceName, "project_id"),
resource.TestCheckResourceAttr(resourceName, "notification.0.delay_min", "15"),
),
},
},
})
}

func TestAccConfigRSAlertConfiguration_DataDog(t *testing.T) {
var (
resourceName = "mongodbatlas_alert_configuration.test"
Expand Down Expand Up @@ -850,6 +886,31 @@ resource "mongodbatlas_alert_configuration" "test" {
`, orgID, projectName, serviceKey, enabled)
}

func testAccMongoDBAtlasAlertConfigurationPagerDutyNotifierIDConfig(orgID, projectName, notifierID string, delayMin int, serviceKey *string) string {
var serviceKeyString string
if serviceKey != nil {
serviceKeyString = fmt.Sprintf(`service_key = %q`, *serviceKey)
}
return fmt.Sprintf(`
resource "mongodbatlas_project" "test" {
name = %[2]q
org_id = %[1]q
}
resource "mongodbatlas_alert_configuration" "test" {
project_id = mongodbatlas_project.test.id
event_type = "NO_PRIMARY"
enabled = "true"
notification {
type_name = "PAGER_DUTY"
notifier_id = %[3]q
%[4]s
delay_min = %[5]d
}
}
`, orgID, projectName, notifierID, serviceKeyString, delayMin)
}

func testAccMongoDBAtlasAlertConfigurationOpsGenieConfig(orgID, projectName, apiKey string, enabled bool) string {
return fmt.Sprintf(`
resource "mongodbatlas_project" "test" {
Expand Down
18 changes: 11 additions & 7 deletions website/docs/d/alert_configuration.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,12 @@ In addition to all arguments above, the following attributes are exported:
* `updated` - Timestamp in ISO 8601 date and time format in UTC when this alert configuration was last updated.
* `enabled` - If set to true, the alert configuration is enabled. If enabled is not exported it is set to false.
* `event_type` - The type of event that will trigger an alert.
* `matcher` - Rules to apply when matching an object against this alert configuration. See [matchers](#matchers).
* `metric_threshold_config` - The threshold that causes an alert to be triggered. Required if `event_type_name` : `OUTSIDE_METRIC_THRESHOLD` or `OUTSIDE_SERVERLESS_METRIC_THRESHOLD`. See [metric threshold config](#metric-threshold-config).
* `threshold_config` - Threshold that triggers an alert. Required if `event_type_name` is any value other than `OUTSIDE_METRIC_THRESHOLD` or `OUTSIDE_SERVERLESS_METRIC_THRESHOLD`. See [threshold config](#threshold-config).
* `notifications` - List of notifications to send when an alert condition is detected. See [notifications](#notifications).

-> ***IMPORTANT:*** Event Type has many possible values. All current options at available at https://docs.atlas.mongodb.com/reference/api/alert-configurations-create-config/ Details for both conditional and metric based alerts can be found by selecting the tabs on the [alert config page](https://docs.atlas.mongodb.com/reference/api/alert-configurations-create-config/) and checking the latest eventTypeName options.
-> ***IMPORTANT:*** Event Type has many possible values. Details for both conditional and metric based alerts can be found by selecting the tabs on the [alert config page](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/v2/#tag/Alert-Configurations/operation/createAlertConfiguration) and checking the latest eventTypeName options.

-> **NOTE:** If `event_type` is set to `OUTSIDE_METRIC_THRESHOLD` or `OUTSIDE_SERVERLESS_METRIC_THRESHOLD`, the `metric_threshold_config` field must also be configured.

Expand Down Expand Up @@ -163,12 +167,12 @@ Rules to apply when matching an object against this alert configuration. Only en
- `CONFIG`
- `MONGOS`

### Metric Threshold Config (`metric_threshold_config`)
### Metric Threshold Config
The threshold that causes an alert to be triggered. Required if `event_type_name` : `OUTSIDE_METRIC_THRESHOLD` or `OUTSIDE_SERVERLESS_METRIC_THRESHOLD`.

* `metric_name` - Name of the metric to check. The full list being quite large, please refer to atlas docs [here for general metrics](https://docs.atlas.mongodb.com/reference/alert-host-metrics/#measurement-types) and [here for serverless metrics](https://www.mongodb.com/docs/atlas/reference/api/alert-configurations-create-config/#serverless-measurements)

* `operator` - Operator to apply when checking the current metric value against the threshold value.
* `operator` - The operator to apply when checking the current metric value against the threshold value.
Accepted values are:
- `GREATER_THAN`
- `LESS_THAN`
Expand All @@ -178,8 +182,8 @@ The threshold that causes an alert to be triggered. Required if `event_type_name
Refer to the [MongoDB API Alert Configuration documentation](https://www.mongodb.com/docs/atlas/reference/api/alert-configurations-get-config/#request-body-parameters) for a list of accepted values.
* `mode` - This must be set to AVERAGE. Atlas computes the current metric value as an average.

### Threshold Config (`threshold_config`)
* `operator` - Operator to apply when checking the current metric value against the threshold value.
### Threshold Config
* `operator` - The operator to apply when checking the current metric value against the threshold value.
Accepted values are:
- `GREATER_THAN`
- `LESS_THAN`
Expand All @@ -199,7 +203,7 @@ Notifications to send when an alert condition is detected.
* `email_address` - Email address to which alert notifications are sent. Required for the EMAIL notifications type.
* `email_enabled` - Flag indicating email notifications should be sent. Atlas returns this value if `type_name` is set to `ORG`, `GROUP`, or `USER`.
* `flowdock_api_token` - The Flowdock personal API token. Required for the `FLOWDOCK` notifications type. If the token later becomes invalid, Atlas sends an email to the project owner and eventually removes the token.
* `flow_name` - Flowdock flow name in lower-case letters. Required for the `FLOWDOCK` notifications type
* `flow_name` - Flowdock flow name in lower-case letters. Required for the `FLOWDOCK` notifications type.
* `interval_min` - Number of minutes to wait between successive notifications for unacknowledged alerts that are not resolved. The minimum value is 5.
* `mobile_number` - Mobile number to which alert notifications are sent. Required for the SMS notifications type.
* `ops_genie_api_key` - Opsgenie API Key. Required for the `OPS_GENIE` notifications type. If the key later becomes invalid, Atlas sends an email to the project owner and eventually removes the token.
Expand All @@ -226,13 +230,13 @@ Notifications to send when an alert condition is detected.
- `WEBHOOK`
- `MICROSOFT_TEAMS`

* `notifier_id` - The notifier id is a system-generated unique identifier assigned to each notification method. This is needed when updating third-party notifications without requiring explicit authentication credentials.
* `username` - Name of the Atlas user to which to send notifications. Only a user in the project that owns the alert configuration is allowed here. Required for the `USER` notifications type.
* `victor_ops_api_key` - VictorOps API key. Required for the `VICTOR_OPS` notifications type. If the key later becomes invalid, Atlas sends an email to the project owner and eventually removes the key.
* `victor_ops_routing_key` - VictorOps routing key. Optional for the `VICTOR_OPS` notifications type. If the key later becomes invalid, Atlas sends an email to the project owner and eventually removes the key.
* `webhook_secret` - Authentication secret for the `WEBHOOK` notifications type.
* `webhook_url` - Target URL for the `WEBHOOK` notifications type.
* `microsoft_teams_webhook_url` - Microsoft Teams channel incoming webhook URL. Required for the `MICROSOFT_TEAMS` notifications type.

* `roles` - Atlas role in current Project or Organization. Atlas returns this value if you set `type_name` to `ORG` or `GROUP`.

See detailed information for arguments and attributes: [MongoDB API Alert Configuration](https://docs.atlas.mongodb.com/reference/api/alert-configurations-get-config/)
Loading

0 comments on commit 7d38199

Please sign in to comment.