Skip to content

CLOUDP-57842: Update alert configs, Atlas #70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions e2e/atlas_alertconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,55 @@ func TestAtlasAlertConfig(t *testing.T) {
}
})

t.Run("Update", func(t *testing.T) {
cmd := exec.Command(cliPath,
atlasEntity,
alertsEntity,
configEntity,
"update",
alertID,
"--event",
eventTypeName,
"--notificationType",
group,
"--notificationIntervalMin",
strconv.Itoa(intervalMin),
"--notificationDelayMin",
strconv.Itoa(delayMin),
"--notificationSmsEnabled=true",
"--notificationEmailEnabled=true")
cmd.Env = os.Environ()
resp, err := cmd.CombinedOutput()

if err != nil {
t.Fatalf("unexpected error: %v, resp: %v", err, string(resp))
}

alert := mongodbatlas.AlertConfiguration{}
err = json.Unmarshal(resp, &alert)

if err != nil {
t.Fatalf("unexpected error: %v, resp: %v", err, string(resp))
}

if *alert.Enabled {
t.Errorf("got=%#v\nwant=%#v\n", true, false)
}

if len(alert.Notifications) != 1 {
t.Errorf("got=%#v\nwant=%#v\n", len(alert.Notifications), 1)
}

if !*alert.Notifications[0].SMSEnabled {
t.Errorf("got=%#v\nwant=%#v\n", false, true)
}

if !*alert.Notifications[0].EmailEnabled {
t.Errorf("got=%#v\nwant=%#v\n", false, true)
}

})

t.Run("Delete", func(t *testing.T) {
cmd := exec.Command(cliPath, atlasEntity, alertsEntity, configEntity, "delete", alertID, "--force")
cmd.Env = os.Environ()
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/atlas_alerts.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func AtlasAlertsBuilder() *cobra.Command {
Short: "Manage alerts for your project.",
}

cmd.AddCommand(AtlasAlertConfigsBuilder())
cmd.AddCommand(AtlasAlertsConfigBuilder())
cmd.AddCommand(AtlasAlertsDescribeBuilder())
cmd.AddCommand(AtlasAlertsListBuilder())
cmd.AddCommand(AtlasAlertsAcknowledgeBuilder())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@ import (
"github.com/spf13/cobra"
)

func AtlasAlertConfigsBuilder() *cobra.Command {
func AtlasAlertsConfigBuilder() *cobra.Command {
cmd := &cobra.Command{
Use: "configs",
Aliases: []string{"config"},
Short: "Manage alerts configuration for your project.",
Long: "The configs command provides access to your alerts configurations. You can create, edit, and delete alert configurations.",
}

cmd.AddCommand(AtlasAlertConfigCreateBuilder())
cmd.AddCommand(AtlasAlertsConfigCreateBuilder())
cmd.AddCommand(AtlasAlertConfigListBuilder())
cmd.AddCommand(AtlasAlertConfigDeleteBuilder())
cmd.AddCommand(AtlasAlertConfigsFieldsBuilder())
cmd.AddCommand(AtlasAlertsConfigUpdateBuilder())

return cmd
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
package cli

import (
"strings"

atlas "github.com/mongodb/go-client-mongodb-atlas/mongodbatlas"
"github.com/mongodb/mongocli/internal/flags"
"github.com/mongodb/mongocli/internal/json"
"github.com/mongodb/mongocli/internal/store"
Expand All @@ -39,39 +36,13 @@ const (
user = "USER"
)

type atlasAlertConfigCreateOpts struct {
type atlasAlertsConfigCreateOpts struct {
*globalOpts
event string
matcherFieldName string
matcherOperator string
matcherValue string
metricThresholdMetricName string
metricThresholdOperator string
metricThresholdUnits string
metricThresholdMode string
notificationToken string // notificationsApiToken, notificationsFlowdockApiToken
notificationChannelName string
apiKey string // notificationsDatadogApiKey, notificationsOpsGenieApiKey, notificationsVictorOpsApiKey
notificationEmailAddress string
notificationFlowName string
notificationMobileNumber string
notificationRegion string // notificationsOpsGenieRegion, notificationsDatadogRegion
notificationOrgName string
notificationServiceKey string
notificationTeamID string
notificationType string
notificationUsername string
notificationVictorOpsRoutingKey string
notificationDelayMin int
notificationIntervalMin int
notificationSmsEnabled bool
enabled bool
notificationEmailEnabled bool
metricThresholdThreshold float64
store store.AlertConfigurationCreator
*atlasAlertsConfigOpts
store store.AlertConfigurationCreator
}

func (opts *atlasAlertConfigCreateOpts) init() error {
func (opts *atlasAlertsConfigCreateOpts) init() error {
if opts.ProjectID() == "" {
return errMissingProjectID
}
Expand All @@ -81,8 +52,8 @@ func (opts *atlasAlertConfigCreateOpts) init() error {
return err
}

func (opts *atlasAlertConfigCreateOpts) Run() error {
alert := opts.buildAlertConfiguration()
func (opts *atlasAlertsConfigCreateOpts) Run() error {
alert := opts.newAlertConfiguration(opts.ProjectID())
result, err := opts.store.CreateAlertConfiguration(alert)

if err != nil {
Expand All @@ -92,102 +63,14 @@ func (opts *atlasAlertConfigCreateOpts) Run() error {
return json.PrettyPrint(result)
}

func (opts *atlasAlertConfigCreateOpts) buildAlertConfiguration() *atlas.AlertConfiguration {

out := new(atlas.AlertConfiguration)

out.GroupID = opts.ProjectID()
out.EventTypeName = strings.ToUpper(opts.event)
out.Enabled = &opts.enabled

if opts.matcherFieldName != "" {
out.Matchers = []atlas.Matcher{*newMatcher(opts)}
}

if opts.metricThresholdMetricName != "" {
out.MetricThreshold = newMetricThreshold(opts)
}

out.Notifications = []atlas.Notification{*newNotification(opts)}

return out
}

func newNotification(opts *atlasAlertConfigCreateOpts) *atlas.Notification {

out := new(atlas.Notification)
out.TypeName = strings.ToUpper(opts.notificationType)
out.DelayMin = &opts.notificationDelayMin
out.IntervalMin = opts.notificationIntervalMin
out.TeamID = opts.notificationTeamID
out.Username = opts.notificationUsername

switch out.TypeName {

case victor:
out.VictorOpsAPIKey = opts.apiKey
out.VictorOpsRoutingKey = opts.notificationVictorOpsRoutingKey

case slack:
out.VictorOpsAPIKey = opts.apiKey
out.VictorOpsRoutingKey = opts.notificationVictorOpsRoutingKey
out.APIToken = opts.notificationToken

case datadog:
out.DatadogAPIKey = opts.apiKey
out.DatadogRegion = strings.ToUpper(opts.notificationRegion)

case email:
out.EmailAddress = opts.notificationEmailAddress

case flowdock:
out.FlowdockAPIToken = opts.notificationToken
out.FlowName = opts.notificationFlowName
out.OrgName = opts.notificationOrgName

case sms:
out.MobileNumber = opts.notificationMobileNumber

case group, user, org:
out.SMSEnabled = &opts.notificationSmsEnabled
out.EmailEnabled = &opts.notificationEmailEnabled

case ops:
out.OpsGenieAPIKey = opts.apiKey
out.OpsGenieRegion = opts.notificationRegion

case pager:
out.ServiceKey = opts.notificationServiceKey

}

return out
}

func newMetricThreshold(opts *atlasAlertConfigCreateOpts) *atlas.MetricThreshold {
return &atlas.MetricThreshold{
MetricName: strings.ToUpper(opts.metricThresholdMetricName),
Operator: strings.ToUpper(opts.metricThresholdOperator),
Threshold: opts.metricThresholdThreshold,
Units: strings.ToUpper(opts.metricThresholdUnits),
Mode: strings.ToUpper(opts.metricThresholdMode),
}
}

func newMatcher(opts *atlasAlertConfigCreateOpts) *atlas.Matcher {
return &atlas.Matcher{
FieldName: strings.ToUpper(opts.matcherFieldName),
Operator: strings.ToUpper(opts.matcherOperator),
Value: strings.ToUpper(opts.matcherValue),
}
}

// mongocli atlas alerts config(s) create -event event --enabled [--matcherField fieldName --matcherOperator operator --matcherValue value]
// mongocli atlas alerts config(s) create [--event event] [--enabled enabled][--matcherField fieldName --matcherOperator operator --matcherValue value]
// [--notificationType type --notificationDelayMin min --notificationEmailEnabled --notificationSmsEnabled --notificationUsername username --notificationTeamID id
// --notificationEmailAddress email --notificationMobileNumber number --notificationChannelName channel --notificationApiToken --notificationRegion region] [--projectId projectId]
func AtlasAlertConfigCreateBuilder() *cobra.Command {
opts := &atlasAlertConfigCreateOpts{
globalOpts: newGlobalOpts(),
// [--notificationEmailAddress email --notificationMobileNumber number --notificationChannelName channel --notificationApiToken --notificationRegion region]
// [--projectId projectId]
func AtlasAlertsConfigCreateBuilder() *cobra.Command {
opts := &atlasAlertsConfigCreateOpts{
globalOpts: newGlobalOpts(),
atlasAlertsConfigOpts: newAtlasAlertsConfigOpts(),
}
cmd := &cobra.Command{
Use: "create",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,35 @@ import (
"github.com/mongodb/mongocli/internal/mocks"
)

func TestAtlasAlertConfigCreate_Run(t *testing.T) {
func TestAtlasAlertsConfigCreate_Run(t *testing.T) {
ctrl := gomock.NewController(t)
mockStore := mocks.NewMockAlertConfigurationCreator(ctrl)

defer ctrl.Finish()

expected := fixtures.AlertConfig()

createOpts := &atlasAlertConfigCreateOpts{
globalOpts: newGlobalOpts(),
event: "OUTSIDE_METRIC_THRESHOLD",
enabled: true,
matcherFieldName: "HOSTNAME_AND_PORT",
matcherOperator: "EQUALS",
matcherValue: "mongo.example.com:27017",
metricThresholdMetricName: "ASSERT_REGULAR",
metricThresholdOperator: "LESS_THAN",
metricThresholdThreshold: 99,
metricThresholdUnits: "RAW",
metricThresholdMode: "RAW",
notificationDelayMin: 0,
notificationIntervalMin: 5,
notificationMobileNumber: "2343454567",
notificationType: "sms",
store: mockStore,
}
createOpts := &atlasAlertsConfigCreateOpts{
globalOpts: newGlobalOpts(),
atlasAlertsConfigOpts: &atlasAlertsConfigOpts{
event: "OUTSIDE_METRIC_THRESHOLD",
enabled: true,
matcherFieldName: "HOSTNAME_AND_PORT",
matcherOperator: "EQUALS",
matcherValue: "mongo.example.com:27017",
metricThresholdMetricName: "ASSERT_REGULAR",
metricThresholdOperator: "LESS_THAN",
metricThresholdThreshold: 99,
metricThresholdUnits: "RAW",
metricThresholdMode: "RAW",
notificationDelayMin: 0,
notificationIntervalMin: 5,
notificationMobileNumber: "2343454567",
notificationType: "sms",
},
store: mockStore}

alert := createOpts.buildAlertConfiguration()
alert := createOpts.newAlertConfiguration(createOpts.ProjectID())
mockStore.
EXPECT().
CreateAlertConfiguration(alert).
Expand Down
Loading