Alerting: Update default route groupBy to [grafana_folder, alertname] (#50052)

* Alerting: Update default route groupBy to [grafana_folder, alertname]

Default group by for new routes and migrations is now [grafana_folder, alertname]
pull/52061/head
Matthew Jacobson 3 years ago committed by GitHub
parent 32c2b62dc7
commit 434e94ef2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      pkg/services/ngalert/provisioning/notification_policies_test.go
  2. 4
      pkg/services/sqlstore/migrations/ualert/channel.go
  3. 9
      pkg/services/sqlstore/migrations/ualert/channel_test.go
  4. 13
      pkg/services/sqlstore/migrations/ualert/migration_test.go
  5. 3
      pkg/setting/setting_unified_alerting.go
  6. 3
      pkg/tests/api/alerting/api_alertmanager_test.go
  7. 3
      pkg/tests/api/alerting/testing.go
  8. 3
      public/app/features/alerting/unified/AmRoutes.test.tsx
  9. 3
      public/app/features/alerting/unified/components/amroutes/AmRootRouteForm.tsx
  10. 3
      public/app/features/alerting/unified/components/amroutes/AmRoutesExpandedForm.tsx
  11. 12
      public/app/features/alerting/unified/utils/amroutes.ts

@ -223,7 +223,7 @@ func TestNotificationPolicyService(t *testing.T) {
require.NoError(t, err)
require.Equal(t, "grafana-default-email", tree.Receiver)
require.Nil(t, tree.Routes)
require.Nil(t, tree.GroupBy)
require.Equal(t, []model.LabelName{models.FolderTitleLabel, model.AlertNameLabel}, tree.GroupBy)
})
}

@ -7,8 +7,10 @@ import (
"fmt"
"github.com/prometheus/alertmanager/pkg/labels"
"github.com/prometheus/common/model"
"github.com/grafana/grafana/pkg/components/simplejson"
ngModels "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/util"
)
@ -231,6 +233,7 @@ func (m *migration) createDefaultRouteAndReceiver(defaultChannels []*notificatio
defaultRoute := &Route{
Receiver: defaultReceiverName,
Routes: make([]*Route, 0),
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel}, // To keep parity with pre-migration notifications.
}
return defaultReceiver, defaultRoute, nil
@ -442,6 +445,7 @@ type Route struct {
Matchers Matchers `yaml:"matchers,omitempty" json:"matchers,omitempty"`
Routes []*Route `yaml:"routes,omitempty" json:"routes,omitempty"`
Continue bool `yaml:"continue,omitempty" json:"continue,omitempty"`
GroupByStr []string `yaml:"group_by,omitempty" json:"group_by,omitempty"`
}
type Matchers labels.Matchers

@ -3,9 +3,11 @@ package ualert
import (
"testing"
"github.com/prometheus/common/model"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/simplejson"
ngModels "github.com/grafana/grafana/pkg/services/ngalert/models"
)
func TestFilterReceiversForAlert(t *testing.T) {
@ -148,6 +150,7 @@ func TestCreateRoute(t *testing.T) {
Matchers: Matchers{{Type: 0, Name: "rule_uid", Value: "r_uid1"}},
Routes: nil,
Continue: false,
GroupByStr: nil,
},
},
{
@ -166,15 +169,18 @@ func TestCreateRoute(t *testing.T) {
Matchers: Matchers{{Type: 0, Name: "rule_uid", Value: "r_uid1"}},
Routes: nil,
Continue: true,
GroupByStr: nil,
},
{
Receiver: "recv2",
Matchers: Matchers{{Type: 0, Name: "rule_uid", Value: "r_uid1"}},
Routes: nil,
Continue: true,
GroupByStr: nil,
},
},
Continue: false,
GroupByStr: nil,
},
},
}
@ -296,6 +302,7 @@ func TestCreateDefaultRouteAndReceiver(t *testing.T) {
expRoute: &Route{
Receiver: "autogen-contact-point-default",
Routes: make([]*Route, 0),
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
},
},
{
@ -308,6 +315,7 @@ func TestCreateDefaultRouteAndReceiver(t *testing.T) {
expRoute: &Route{
Receiver: "autogen-contact-point-default",
Routes: make([]*Route, 0),
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
},
},
{
@ -317,6 +325,7 @@ func TestCreateDefaultRouteAndReceiver(t *testing.T) {
expRoute: &Route{
Receiver: "name1",
Routes: make([]*Route, 0),
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
},
},
}

@ -9,12 +9,14 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/prometheus/alertmanager/pkg/labels"
"github.com/prometheus/common/model"
"github.com/stretchr/testify/require"
"xorm.io/xorm"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
ngModels "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/sqlstore/migrations"
"github.com/grafana/grafana/pkg/services/sqlstore/migrations/ualert"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
@ -157,6 +159,7 @@ func TestDashAlertMigration(t *testing.T) {
AlertmanagerConfig: ualert.PostableApiAlertingConfig{
Route: &ualert.Route{
Receiver: "autogen-contact-point-default",
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
Routes: []*ualert.Route{
{Receiver: "notifier1", Matchers: createAlertNameMatchers("alert1")}, // These Matchers are temporary and will be replaced below with generated rule_uid.
{Matchers: createAlertNameMatchers("alert2"), Routes: []*ualert.Route{
@ -178,6 +181,7 @@ func TestDashAlertMigration(t *testing.T) {
AlertmanagerConfig: ualert.PostableApiAlertingConfig{
Route: &ualert.Route{
Receiver: "notifier6",
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
Routes: []*ualert.Route{
{Matchers: createAlertNameMatchers("alert4"), Routes: []*ualert.Route{
{Receiver: "notifier4", Matchers: createAlertNameMatchers("alert4"), Continue: true},
@ -210,6 +214,7 @@ func TestDashAlertMigration(t *testing.T) {
AlertmanagerConfig: ualert.PostableApiAlertingConfig{
Route: &ualert.Route{
Receiver: "autogen-contact-point-default",
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
},
Receivers: []*ualert.PostableApiReceiver{
{Name: "notifier1", GrafanaManagedReceivers: []*ualert.PostableGrafanaReceiver{{Name: "notifier1", Type: "email"}}},
@ -230,6 +235,7 @@ func TestDashAlertMigration(t *testing.T) {
AlertmanagerConfig: ualert.PostableApiAlertingConfig{
Route: &ualert.Route{
Receiver: "notifier1",
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
},
Receivers: []*ualert.PostableApiReceiver{
{Name: "notifier1", GrafanaManagedReceivers: []*ualert.PostableGrafanaReceiver{{Name: "notifier1", Type: "email"}}},
@ -250,6 +256,7 @@ func TestDashAlertMigration(t *testing.T) {
AlertmanagerConfig: ualert.PostableApiAlertingConfig{
Route: &ualert.Route{
Receiver: "autogen-contact-point-default",
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
},
Receivers: []*ualert.PostableApiReceiver{
{Name: "notifier1", GrafanaManagedReceivers: []*ualert.PostableGrafanaReceiver{{Name: "notifier1", Type: "email"}}},
@ -273,6 +280,7 @@ func TestDashAlertMigration(t *testing.T) {
AlertmanagerConfig: ualert.PostableApiAlertingConfig{
Route: &ualert.Route{
Receiver: "autogen-contact-point-default",
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
},
Receivers: []*ualert.PostableApiReceiver{
{Name: "notifier1", GrafanaManagedReceivers: []*ualert.PostableGrafanaReceiver{{Name: "notifier1", Type: "email"}}},
@ -298,6 +306,7 @@ func TestDashAlertMigration(t *testing.T) {
AlertmanagerConfig: ualert.PostableApiAlertingConfig{
Route: &ualert.Route{
Receiver: "autogen-contact-point-default",
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
},
Receivers: []*ualert.PostableApiReceiver{
{Name: "notifier1", GrafanaManagedReceivers: []*ualert.PostableGrafanaReceiver{{Name: "notifier1", Type: "email"}}},
@ -323,6 +332,7 @@ func TestDashAlertMigration(t *testing.T) {
AlertmanagerConfig: ualert.PostableApiAlertingConfig{
Route: &ualert.Route{
Receiver: "autogen-contact-point-default",
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
Routes: []*ualert.Route{
{Receiver: "notifier1", Matchers: createAlertNameMatchers("alert1")},
{Matchers: createAlertNameMatchers("alert2"), Routes: []*ualert.Route{
@ -351,6 +361,7 @@ func TestDashAlertMigration(t *testing.T) {
AlertmanagerConfig: ualert.PostableApiAlertingConfig{
Route: &ualert.Route{
Receiver: "autogen-contact-point-default",
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
},
Receivers: []*ualert.PostableApiReceiver{
{Name: "notifier1", GrafanaManagedReceivers: []*ualert.PostableGrafanaReceiver{{Name: "notifier1", Type: "email"}}},
@ -373,6 +384,7 @@ func TestDashAlertMigration(t *testing.T) {
AlertmanagerConfig: ualert.PostableApiAlertingConfig{
Route: &ualert.Route{
Receiver: "autogen-contact-point-default",
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
},
Receivers: []*ualert.PostableApiReceiver{
{Name: "notifier1", GrafanaManagedReceivers: []*ualert.PostableGrafanaReceiver{{Name: "notifier1", Type: "email"}}},
@ -396,6 +408,7 @@ func TestDashAlertMigration(t *testing.T) {
AlertmanagerConfig: ualert.PostableApiAlertingConfig{
Route: &ualert.Route{
Receiver: "autogen-contact-point-default",
GroupByStr: []string{ngModels.FolderTitleLabel, model.AlertNameLabel},
Routes: []*ualert.Route{
{Receiver: "notifier1", Matchers: createAlertNameMatchers("alert1")},
},

@ -26,7 +26,8 @@ const (
alertmanagerDefaultConfiguration = `{
"alertmanager_config": {
"route": {
"receiver": "grafana-default-email"
"receiver": "grafana-default-email",
"group_by": ["grafana_folder", "alertname"]
},
"receivers": [{
"name": "grafana-default-email",

@ -1832,7 +1832,8 @@ func TestAlertmanagerStatus(t *testing.T) {
},
"config": {
"route": {
"receiver": "grafana-default-email"
"receiver": "grafana-default-email",
"group_by": ["grafana_folder", "alertname"]
},
"templates": null,
"receivers": [{

@ -25,7 +25,8 @@ const defaultAlertmanagerConfigJSON = `
"template_files": null,
"alertmanager_config": {
"route": {
"receiver": "grafana-default-email"
"receiver": "grafana-default-email",
"group_by": ["grafana_folder", "alertname"]
},
"templates": null,
"receivers": [{

@ -21,6 +21,7 @@ import { AccessControlAction } from 'app/types';
import AmRoutes from './AmRoutes';
import { fetchAlertManagerConfig, fetchStatus, updateAlertManagerConfig } from './api/alertmanager';
import { mockDataSource, MockDataSourceSrv, someCloudAlertManagerConfig, someCloudAlertManagerStatus } from './mocks';
import { defaultGroupBy } from './utils/amroutes';
import { getAllDataSources } from './utils/config';
import { ALERTMANAGER_NAME_QUERY_KEY } from './utils/constants';
import { DataSourceType, GRAFANA_RULES_SOURCE_NAME } from './utils/datasource';
@ -363,7 +364,7 @@ describe('AmRoutes', () => {
receivers: [{ name: 'default' }],
route: {
continue: false,
group_by: ['severity', 'namespace'],
group_by: defaultGroupBy.concat(['severity', 'namespace']),
receiver: 'default',
routes: [],
mute_time_intervals: [],

@ -10,6 +10,7 @@ import {
optionalPositiveInteger,
stringToSelectableValue,
stringsToSelectableValues,
commonGroupByOptions,
} from '../../utils/amroutes';
import { makeAMLink } from '../../utils/misc';
import { timeOptions } from '../../utils/time';
@ -86,7 +87,7 @@ export const AmRootRouteForm: FC<AmRootRouteFormProps> = ({
setValue('groupBy', [...field.value, opt]);
}}
onChange={(value) => onChange(mapMultiSelectValueToStrings(value))}
options={groupByOptions}
options={[...commonGroupByOptions, groupByOptions]}
/>
)}
control={control}

@ -29,6 +29,7 @@ import {
optionalPositiveInteger,
stringToSelectableValue,
stringsToSelectableValues,
commonGroupByOptions,
} from '../../utils/amroutes';
import { timeOptions } from '../../utils/time';
@ -179,7 +180,7 @@ export const AmRoutesExpandedForm: FC<AmRoutesExpandedFormProps> = ({ onCancel,
setValue('groupBy', [...field.value, opt]);
}}
onChange={(value) => onChange(mapMultiSelectValueToStrings(value))}
options={groupByOptions}
options={[...commonGroupByOptions, groupByOptions]}
/>
)}
control={control}

@ -59,10 +59,20 @@ export const emptyArrayFieldMatcher: MatcherFieldValue = {
operator: MatcherOperator.equal,
};
// Default route group_by labels for newly created routes.
export const defaultGroupBy = ['grafana_folder', 'alertname'];
// Common route group_by options for multiselect drop-down
export const commonGroupByOptions = [
{ label: 'grafana_folder', value: 'grafana_folder' },
{ label: 'alertname', value: 'alertname' },
{ label: 'Disable (...)', value: '...' },
];
export const emptyRoute: FormAmRoute = {
id: '',
overrideGrouping: false,
groupBy: [],
groupBy: defaultGroupBy,
object_matchers: [],
routes: [],
continue: false,

Loading…
Cancel
Save