Alerting: Remove alertingSimplifiedRouting feature toggle (#104980)

Co-authored-by: Gilles De Mey <gilles.de.mey@gmail.com>
pull/104116/merge
Sonia Aguilar 2 weeks ago committed by GitHub
parent 7345ba35a1
commit 0ceea29787
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 119
      docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md
  2. 5
      packages/grafana-data/src/types/featureToggles.gen.ts
  3. 8
      pkg/services/featuremgmt/registry.go
  4. 1
      pkg/services/featuremgmt/toggles_gen.csv
  5. 4
      pkg/services/featuremgmt/toggles_gen.go
  6. 5
      pkg/services/featuremgmt/toggles_gen.json
  7. 2
      pkg/services/ngalert/api/api_alertmanager_test.go
  8. 2
      pkg/services/ngalert/api/api_ruler.go
  9. 7
      pkg/services/ngalert/ngalert.go
  10. 13
      pkg/services/ngalert/notifier/alertmanager.go
  11. 3
      pkg/services/ngalert/notifier/alertmanager_config.go
  12. 2
      pkg/tests/api/alerting/api_ruler_test.go
  13. 5
      public/app/features/alerting/unified/components/contact-points/utils.ts
  14. 27
      public/app/features/alerting/unified/components/notification-policies/Policy.test.tsx
  15. 12
      public/app/features/alerting/unified/components/notification-policies/Policy.tsx
  16. 6
      public/app/features/alerting/unified/components/rule-editor/NotificationsStep.tsx
  17. 2
      public/app/features/alerting/unified/components/rule-editor/alert-rule-form/simplifiedRouting/SimplifiedRuleEditor.test.tsx
  18. 5
      public/app/features/alerting/unified/components/rules/Filter/RulesFilter.v1.tsx
  19. 16
      public/app/features/alerting/unified/rule-editor/formDefaults.test.ts
  20. 7
      public/app/features/alerting/unified/rule-editor/formDefaults.ts

@ -21,66 +21,65 @@ For more information about feature release stages, refer to [Release life cycle
Most [generally available](https://grafana.com/docs/release-life-cycle/#general-availability) features are enabled by default. You can disable these feature by setting the feature flag to "false" in the configuration.
| Feature toggle name | Description | Enabled by default |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| `disableEnvelopeEncryption` | Disable envelope encryption (emergency only) | |
| `publicDashboardsScene` | Enables public dashboard rendering using scenes | Yes |
| `featureHighlights` | Highlight Grafana Enterprise features | |
| `correlations` | Correlations page | Yes |
| `cloudWatchCrossAccountQuerying` | Enables cross-account querying in CloudWatch datasources | Yes |
| `nestedFolders` | Enable folder nesting | Yes |
| `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes |
| `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals | Yes |
| `influxdbBackendMigration` | Query InfluxDB InfluxQL without the proxy | Yes |
| `dataplaneFrontendFallback` | Support dataplane contract field name change for transformations and field name matchers where the name is different | Yes |
| `unifiedRequestLog` | Writes error logs to the request logger | Yes |
| `pluginsDetailsRightPanel` | Enables right panel for the plugins details page | Yes |
| `recordedQueriesMulti` | Enables writing multiple items from a single query within Recorded Queries | Yes |
| `logsExploreTableVisualisation` | A table visualisation for logs in Explore | Yes |
| `transformationsRedesign` | Enables the transformations redesign | Yes |
| `awsAsyncQueryCaching` | Enable caching for async queries for Redshift and Athena. Requires that the datasource has caching and async query support enabled | Yes |
| `angularDeprecationUI` | Display Angular warnings in dashboards and panels | Yes |
| `dashgpt` | Enable AI powered features in dashboards | Yes |
| `externalCorePlugins` | Allow core plugins to be loaded as external | Yes |
| `panelMonitoring` | Enables panel monitoring through logs and measurements | Yes |
| `formatString` | Enable format string transformer | Yes |
| `kubernetesClientDashboardsFolders` | Route the folder and dashboard service requests to k8s | Yes |
| `lokiStructuredMetadata` | Enables the loki data source to request structured metadata from the Loki server | Yes |
| `addFieldFromCalculationStatFunctions` | Add cumulative and window functions to the add field from calculation transformation | Yes |
| `annotationPermissionUpdate` | Change the way annotation permissions work by scoping them to folders and dashboards. | Yes |
| `dashboardSceneForViewers` | Enables dashboard rendering using Scenes for viewer roles | Yes |
| `dashboardSceneSolo` | Enables rendering dashboards using scenes for solo panels | Yes |
| `dashboardScene` | Enables dashboard rendering using scenes for all roles | Yes |
| `ssoSettingsApi` | Enables the SSO settings API and the OAuth configuration UIs in Grafana | Yes |
| `logsInfiniteScrolling` | Enables infinite scrolling for the Logs panel in Explore and Dashboards | Yes |
| `alertingSimplifiedRouting` | Enables users to easily configure alert notifications by specifying a contact point directly when editing or creating an alert rule | Yes |
| `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected | Yes |
| `lokiQueryHints` | Enables query hints for Loki | Yes |
| `alertingQueryOptimization` | Optimizes eligible queries in order to reduce load on datasources | |
| `onPremToCloudMigrations` | Enable the Grafana Migration Assistant, which helps you easily migrate various on-prem resources to your Grafana Cloud stack. | Yes |
| `groupToNestedTableTransformation` | Enables the group to nested table transformation | Yes |
| `newPDFRendering` | New implementation for the dashboard-to-PDF rendering | Yes |
| `tlsMemcached` | Use TLS-enabled memcached in the enterprise caching feature | Yes |
| `ssoSettingsSAML` | Use the new SSO Settings API to configure the SAML connector | Yes |
| `cloudWatchNewLabelParsing` | Updates CloudWatch label parsing to be more accurate | Yes |
| `newDashboardSharingComponent` | Enables the new sharing drawer design | Yes |
| `pluginProxyPreserveTrailingSlash` | Preserve plugin proxy trailing slash. | |
| `azureMonitorPrometheusExemplars` | Allows configuration of Azure Monitor as a data source that can provide Prometheus exemplars | Yes |
| `pinNavItems` | Enables pinning of nav items | Yes |
| `failWrongDSUID` | Throws an error if a data source has an invalid UIDs | Yes |
| `cloudWatchRoundUpEndTime` | Round up end time for metric queries to the next minute to avoid missing data | Yes |
| `newFiltersUI` | Enables new combobox style UI for the Ad hoc filters variable in scenes architecture | Yes |
| `alertingQueryAndExpressionsStepMode` | Enables step mode for alerting queries and expressions | Yes |
| `useSessionStorageForRedirection` | Use session storage for handling the redirection after login | Yes |
| `pluginsSriChecks` | Enables SRI checks for plugin assets | |
| `azureMonitorDisableLogLimit` | Disables the log limit restriction for Azure Monitor when true. The limit is enabled by default. | |
| `preinstallAutoUpdate` | Enables automatic updates for pre-installed plugins | Yes |
| `reportingUseRawTimeRange` | Uses the original report or dashboard time range instead of making an absolute transformation | Yes |
| `alertingUIOptimizeReducer` | Enables removing the reducer from the alerting UI when creating a new alert rule and using instant query | Yes |
| `azureMonitorEnableUserAuth` | Enables user auth for Azure Monitor datasource only | Yes |
| `alertingNotificationsStepMode` | Enables simplified step mode in the notifications section | Yes |
| `lokiLabelNamesQueryApi` | Defaults to using the Loki `/labels` API instead of `/series` | Yes |
| `unifiedNavbars` | Enables unified navbars | |
| Feature toggle name | Description | Enabled by default |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| `disableEnvelopeEncryption` | Disable envelope encryption (emergency only) | |
| `publicDashboardsScene` | Enables public dashboard rendering using scenes | Yes |
| `featureHighlights` | Highlight Grafana Enterprise features | |
| `correlations` | Correlations page | Yes |
| `cloudWatchCrossAccountQuerying` | Enables cross-account querying in CloudWatch datasources | Yes |
| `nestedFolders` | Enable folder nesting | Yes |
| `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes |
| `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals | Yes |
| `influxdbBackendMigration` | Query InfluxDB InfluxQL without the proxy | Yes |
| `dataplaneFrontendFallback` | Support dataplane contract field name change for transformations and field name matchers where the name is different | Yes |
| `unifiedRequestLog` | Writes error logs to the request logger | Yes |
| `pluginsDetailsRightPanel` | Enables right panel for the plugins details page | Yes |
| `recordedQueriesMulti` | Enables writing multiple items from a single query within Recorded Queries | Yes |
| `logsExploreTableVisualisation` | A table visualisation for logs in Explore | Yes |
| `transformationsRedesign` | Enables the transformations redesign | Yes |
| `awsAsyncQueryCaching` | Enable caching for async queries for Redshift and Athena. Requires that the datasource has caching and async query support enabled | Yes |
| `angularDeprecationUI` | Display Angular warnings in dashboards and panels | Yes |
| `dashgpt` | Enable AI powered features in dashboards | Yes |
| `externalCorePlugins` | Allow core plugins to be loaded as external | Yes |
| `panelMonitoring` | Enables panel monitoring through logs and measurements | Yes |
| `formatString` | Enable format string transformer | Yes |
| `kubernetesClientDashboardsFolders` | Route the folder and dashboard service requests to k8s | Yes |
| `lokiStructuredMetadata` | Enables the loki data source to request structured metadata from the Loki server | Yes |
| `addFieldFromCalculationStatFunctions` | Add cumulative and window functions to the add field from calculation transformation | Yes |
| `annotationPermissionUpdate` | Change the way annotation permissions work by scoping them to folders and dashboards. | Yes |
| `dashboardSceneForViewers` | Enables dashboard rendering using Scenes for viewer roles | Yes |
| `dashboardSceneSolo` | Enables rendering dashboards using scenes for solo panels | Yes |
| `dashboardScene` | Enables dashboard rendering using scenes for all roles | Yes |
| `ssoSettingsApi` | Enables the SSO settings API and the OAuth configuration UIs in Grafana | Yes |
| `logsInfiniteScrolling` | Enables infinite scrolling for the Logs panel in Explore and Dashboards | Yes |
| `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected | Yes |
| `lokiQueryHints` | Enables query hints for Loki | Yes |
| `alertingQueryOptimization` | Optimizes eligible queries in order to reduce load on datasources | |
| `onPremToCloudMigrations` | Enable the Grafana Migration Assistant, which helps you easily migrate various on-prem resources to your Grafana Cloud stack. | Yes |
| `groupToNestedTableTransformation` | Enables the group to nested table transformation | Yes |
| `newPDFRendering` | New implementation for the dashboard-to-PDF rendering | Yes |
| `tlsMemcached` | Use TLS-enabled memcached in the enterprise caching feature | Yes |
| `ssoSettingsSAML` | Use the new SSO Settings API to configure the SAML connector | Yes |
| `cloudWatchNewLabelParsing` | Updates CloudWatch label parsing to be more accurate | Yes |
| `newDashboardSharingComponent` | Enables the new sharing drawer design | Yes |
| `pluginProxyPreserveTrailingSlash` | Preserve plugin proxy trailing slash. | |
| `azureMonitorPrometheusExemplars` | Allows configuration of Azure Monitor as a data source that can provide Prometheus exemplars | Yes |
| `pinNavItems` | Enables pinning of nav items | Yes |
| `failWrongDSUID` | Throws an error if a data source has an invalid UIDs | Yes |
| `cloudWatchRoundUpEndTime` | Round up end time for metric queries to the next minute to avoid missing data | Yes |
| `newFiltersUI` | Enables new combobox style UI for the Ad hoc filters variable in scenes architecture | Yes |
| `alertingQueryAndExpressionsStepMode` | Enables step mode for alerting queries and expressions | Yes |
| `useSessionStorageForRedirection` | Use session storage for handling the redirection after login | Yes |
| `pluginsSriChecks` | Enables SRI checks for plugin assets | |
| `azureMonitorDisableLogLimit` | Disables the log limit restriction for Azure Monitor when true. The limit is enabled by default. | |
| `preinstallAutoUpdate` | Enables automatic updates for pre-installed plugins | Yes |
| `reportingUseRawTimeRange` | Uses the original report or dashboard time range instead of making an absolute transformation | Yes |
| `alertingUIOptimizeReducer` | Enables removing the reducer from the alerting UI when creating a new alert rule and using instant query | Yes |
| `azureMonitorEnableUserAuth` | Enables user auth for Azure Monitor datasource only | Yes |
| `alertingNotificationsStepMode` | Enables simplified step mode in the notifications section | Yes |
| `lokiLabelNamesQueryApi` | Defaults to using the Loki `/labels` API instead of `/series` | Yes |
| `unifiedNavbars` | Enables unified navbars | |
## Public preview feature toggles

@ -429,11 +429,6 @@ export interface FeatureToggles {
*/
logsInfiniteScrolling?: boolean;
/**
* Enables users to easily configure alert notifications by specifying a contact point directly when editing or creating an alert rule
* @default true
*/
alertingSimplifiedRouting?: boolean;
/**
* Enable filtering menu displayed when text of a log line is selected
* @default true
*/

@ -713,14 +713,6 @@ var (
FrontendOnly: true,
Owner: grafanaObservabilityLogsSquad,
},
{
Name: "alertingSimplifiedRouting",
Description: "Enables users to easily configure alert notifications by specifying a contact point directly when editing or creating an alert rule",
Stage: FeatureStageGeneralAvailability,
FrontendOnly: false,
Owner: grafanaAlertingSquad,
Expression: "true", // enabled by default
},
{
Name: "logRowsPopoverMenu",
Description: "Enable filtering menu displayed when text of a log line is selected",

@ -94,7 +94,6 @@ pdfTables,preview,@grafana/sharing-squad,false,false,false
ssoSettingsApi,GA,@grafana/identity-access-team,false,false,false
canvasPanelPanZoom,preview,@grafana/dataviz-squad,false,false,true
logsInfiniteScrolling,GA,@grafana/observability-logs,false,false,true
alertingSimplifiedRouting,GA,@grafana/alerting-squad,false,false,false
logRowsPopoverMenu,GA,@grafana/observability-logs,false,false,true
pluginsSkipHostEnvVars,experimental,@grafana/plugins-platform-backend,false,false,false
tableSharedCrosshair,experimental,@grafana/dataviz-squad,false,false,true

1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
94 ssoSettingsApi GA @grafana/identity-access-team false false false
95 canvasPanelPanZoom preview @grafana/dataviz-squad false false true
96 logsInfiniteScrolling GA @grafana/observability-logs false false true
alertingSimplifiedRouting GA @grafana/alerting-squad false false false
97 logRowsPopoverMenu GA @grafana/observability-logs false false true
98 pluginsSkipHostEnvVars experimental @grafana/plugins-platform-backend false false false
99 tableSharedCrosshair experimental @grafana/dataviz-squad false false true

@ -387,10 +387,6 @@ const (
// Enables infinite scrolling for the Logs panel in Explore and Dashboards
FlagLogsInfiniteScrolling = "logsInfiniteScrolling"
// FlagAlertingSimplifiedRouting
// Enables users to easily configure alert notifications by specifying a contact point directly when editing or creating an alert rule
FlagAlertingSimplifiedRouting = "alertingSimplifiedRouting"
// FlagLogRowsPopoverMenu
// Enable filtering menu displayed when text of a log line is selected
FlagLogRowsPopoverMenu = "logRowsPopoverMenu"

@ -356,8 +356,9 @@
{
"metadata": {
"name": "alertingSimplifiedRouting",
"resourceVersion": "1743693517832",
"creationTimestamp": "2023-11-10T13:14:39Z"
"resourceVersion": "1745491786560",
"creationTimestamp": "2023-11-10T13:14:39Z",
"deletionTimestamp": "2025-05-06T07:23:50Z"
},
"spec": {
"description": "Enables users to easily configure alert notifications by specifying a contact point directly when editing or creating an alert rule",

@ -610,7 +610,7 @@ func createMultiOrgAlertmanager(t *testing.T, configs map[int64]*ngmodels.AlertC
ngfakes.NewFakeReceiverPermissionsService(),
log.New("testlogger"),
secretsService,
featuremgmt.WithManager(featuremgmt.FlagAlertingSimplifiedRouting),
featuremgmt.WithManager(),
)
require.NoError(t, err)
err = mam.LoadAndSyncAlertmanagersForOrgs(context.Background())

@ -582,7 +582,7 @@ func (srv RulerSrv) updateAlertRulesInGroup(c *contextmodel.ReqContext, groupKey
return ErrResp(http.StatusInternalServerError, err, "failed to update rule group")
}
if srv.featureManager.IsEnabled(c.Req.Context(), featuremgmt.FlagAlertingSimplifiedRouting) && dbConfig != nil {
if dbConfig != nil {
// This isn't strictly necessary since the alertmanager config is periodically synced.
err := srv.amRefresher.ApplyConfig(c.Req.Context(), groupKey.OrgID, dbConfig)
if err != nil {

@ -189,11 +189,8 @@ func (ng *AlertNG) init() error {
remotePrimary := ng.FeatureToggles.IsEnabled(initCtx, featuremgmt.FlagAlertmanagerRemotePrimary)
remoteSecondary := ng.FeatureToggles.IsEnabled(initCtx, featuremgmt.FlagAlertmanagerRemoteSecondary)
if remoteOnly || remotePrimary || remoteSecondary {
autogenFn := remote.NoopAutogenFn
if ng.FeatureToggles.IsEnabled(initCtx, featuremgmt.FlagAlertingSimplifiedRouting) {
autogenFn = func(ctx context.Context, logger log.Logger, orgID int64, cfg *definitions.PostableApiAlertingConfig, skipInvalid bool) error {
return notifier.AddAutogenConfig(ctx, logger, ng.store, orgID, cfg, skipInvalid)
}
autogenFn := func(ctx context.Context, logger log.Logger, orgID int64, cfg *definitions.PostableApiAlertingConfig, skipInvalid bool) error {
return notifier.AddAutogenConfig(ctx, logger, ng.store, orgID, cfg, skipInvalid)
}
switch {

@ -60,8 +60,6 @@ type alertmanager struct {
decryptFn alertingNotify.GetDecryptedValueFn
orgID int64
withAutogen bool
}
// maintenanceOptions represent the options for components that need maintenance on a frequency within the Alertmanager.
@ -152,9 +150,6 @@ func NewAlertmanager(ctx context.Context, orgID int64, cfg *setting.Cfg, store A
decryptFn: decryptFn,
stateStore: stateStore,
logger: l,
// TODO: Preferably, logic around autogen would be outside of the specific alertmanager implementation so that remote alertmanager will get it for free.
withAutogen: featureToggles.IsEnabled(ctx, featuremgmt.FlagAlertingSimplifiedRouting),
}
return am, nil
@ -322,11 +317,9 @@ func (am *alertmanager) aggregateInhibitMatchers(rules []config.InhibitRule, amu
// It returns a boolean indicating whether the user config was changed and an error.
// It is not safe to call concurrently.
func (am *alertmanager) applyConfig(ctx context.Context, cfg *apimodels.PostableUserConfig, skipInvalid bool) (bool, error) {
if am.withAutogen {
err := AddAutogenConfig(ctx, am.logger, am.Store, am.orgID, &cfg.AlertmanagerConfig, skipInvalid)
if err != nil {
return false, err
}
err := AddAutogenConfig(ctx, am.logger, am.Store, am.orgID, &cfg.AlertmanagerConfig, skipInvalid)
if err != nil {
return false, err
}
// First, let's make sure this config is not already loaded

@ -11,7 +11,6 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"github.com/grafana/grafana/pkg/apimachinery/errutil"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/notifier/legacy_storage"
@ -122,7 +121,7 @@ func (moa *MultiOrgAlertmanager) GetAlertmanagerConfiguration(ctx context.Contex
return definitions.GettableUserConfig{}, err
}
if moa.featureManager.IsEnabled(ctx, featuremgmt.FlagAlertingSimplifiedRouting) && withAutogen {
if withAutogen {
// We validate the notification settings in a similar way to when we POST.
// Otherwise, broken settings (e.g. a receiver that doesn't exist) will cause the config returned here to be
// different than the config currently in-use.

@ -4371,7 +4371,7 @@ func TestIntegrationRuleNotificationSettings(t *testing.T) {
DisableAnonymous: true,
AppModeProduction: true,
NGAlertSchedulerBaseInterval: 1 * time.Second,
EnableFeatureToggles: []string{featuremgmt.FlagConfigurableSchedulerTick, featuremgmt.FlagAlertingSimplifiedRouting},
EnableFeatureToggles: []string{featuremgmt.FlagConfigurableSchedulerTick},
})
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, p)

@ -1,7 +1,6 @@
import { difference, groupBy, take, trim, upperFirst } from 'lodash';
import { ReactNode } from 'react';
import { config } from '@grafana/runtime';
import { t } from 'app/core/internationalization';
import { canAdminEntity, shouldUseK8sApi } from 'app/features/alerting/unified/utils/k8s/utils';
import {
@ -174,10 +173,6 @@ function getContactPointIdentifier(contactPoint: Receiver): string {
}
export function isAutoGeneratedPolicy(route: Route) {
const simplifiedRoutingToggleEnabled = config.featureToggles.alertingSimplifiedRouting ?? false;
if (!simplifiedRoutingToggleEnabled) {
return false;
}
if (!route.object_matchers) {
return false;
}

@ -4,7 +4,6 @@ import { first, noop } from 'lodash';
import { Route, Routes } from 'react-router-dom-v5-compat';
import { render } from 'test/test-utils';
import { config } from '@grafana/runtime';
import { contextSrv } from 'app/core/core';
import {
AlertmanagerGroup,
@ -23,7 +22,7 @@ import {
AUTOGENERATED_ROOT_LABEL_NAME,
Policy,
TimingOptionsMeta,
isAutoGeneratedRootAndSimplifiedEnabled,
isAutoGeneratedRoot,
useCreateDropdownMenuActions,
} from './Policy';
@ -385,40 +384,28 @@ const mockRoutes: RouteWithID = {
repeat_interval: '4h',
};
describe('isAutoGeneratedRootAndSimplifiedEnabled', () => {
it('returns false when simplified routing is not enabled', () => {
const route: RouteWithID = {
id: '1',
object_matchers: [['label', MatcherOperator.equal, 'true']],
};
config.featureToggles.alertingSimplifiedRouting = false;
expect(isAutoGeneratedRootAndSimplifiedEnabled(route)).toBe(false);
});
describe('isAutoGeneratedRoot', () => {
it('returns false when object_matchers is not defined', () => {
const route: RouteWithID = {
id: '1',
};
config.featureToggles.alertingSimplifiedRouting = true;
expect(isAutoGeneratedRootAndSimplifiedEnabled(route)).toBe(false);
expect(isAutoGeneratedRoot(route)).toBe(false);
});
it('returns true when object_matchers contains AUTOGENERATED_ROOT_LABEL_NAME, and simplified routing is enabled', () => {
it('returns true when object_matchers contains AUTOGENERATED_ROOT_LABEL_NAME', () => {
const route: RouteWithID = {
id: '1',
object_matchers: [[AUTOGENERATED_ROOT_LABEL_NAME, MatcherOperator.equal, 'true']],
};
config.featureToggles.alertingSimplifiedRouting = true;
expect(isAutoGeneratedRootAndSimplifiedEnabled(route)).toBe(true);
expect(isAutoGeneratedRoot(route)).toBe(true);
});
it('returns false when object_matchers does not contain AUTOGENERATED_ROOT_LABEL_NAME, and simplified routing is enabled', () => {
it('returns false when object_matchers does not contain AUTOGENERATED_ROOT_LABEL_NAME', () => {
const route: RouteWithID = {
id: '1',
object_matchers: [['label', MatcherOperator.equal, 'true']],
};
config.featureToggles.alertingSimplifiedRouting = true;
expect(isAutoGeneratedRootAndSimplifiedEnabled(route)).toBe(false);
expect(isAutoGeneratedRoot(route)).toBe(false);
});
});

@ -6,7 +6,6 @@ import { FC, Fragment, ReactNode, useState } from 'react';
import { useToggle } from 'react-use';
import { GrafanaTheme2 } from '@grafana/data';
import { config } from '@grafana/runtime';
import {
Badge,
Button,
@ -157,7 +156,7 @@ const Policy = (props: PolicyComponentProps) => {
);
// we collapse the auto-generated policies by default
const isAutogeneratedPolicyRoot = isAutoGeneratedRootAndSimplifiedEnabled(currentRoute);
const isAutogeneratedPolicyRoot = isAutoGeneratedRoot(currentRoute);
const [showPolicyChildren, togglePolicyChildren] = useToggle(isAutogeneratedPolicyRoot ? false : true);
const groupBy = currentRoute.group_by;
@ -349,7 +348,7 @@ const Policy = (props: PolicyComponentProps) => {
{pageOfChildren.map((child) => {
const childInheritedProperties = getInheritedProperties(currentRoute, child, inheritedProperties);
// This child is autogenerated if it's the autogenerated root or if it's a child of an autogenerated policy.
const isThisChildAutoGenerated = isAutoGeneratedRootAndSimplifiedEnabled(child) || isAutoGenerated;
const isThisChildAutoGenerated = isAutoGeneratedRoot(child) || isAutoGenerated;
/* pass the "readOnly" prop from the parent, because for any child policy , if its parent it's not editable,
then the child policy should not be editable either */
const isThisChildReadOnly = readOnly || provisioned || isAutoGenerated;
@ -602,11 +601,7 @@ export const useCreateDropdownMenuActions = (
export const AUTOGENERATED_ROOT_LABEL_NAME = '__grafana_autogenerated__';
export function isAutoGeneratedRootAndSimplifiedEnabled(route: RouteWithID) {
const simplifiedRoutingToggleEnabled = config.featureToggles.alertingSimplifiedRouting ?? false;
if (!simplifiedRoutingToggleEnabled) {
return false;
}
export function isAutoGeneratedRoot(route: RouteWithID) {
if (!route.object_matchers) {
return false;
}
@ -619,7 +614,6 @@ export function isAutoGeneratedRootAndSimplifiedEnabled(route: RouteWithID) {
);
}) ?? false
);
// return simplifiedRoutingToggleEnabled && route.receiver === 'contact_point_5';
}
const ProvisionedTooltip = (children: ReactNode) => (

@ -47,13 +47,11 @@ export const NotificationsStep = ({ alertUid }: NotificationsStepProps) => {
const dataSourceName = watch('dataSourceName') ?? GRAFANA_RULES_SOURCE_NAME;
const isGrafanaManaged = isGrafanaManagedRuleByType(type);
const simplifiedRoutingToggleEnabled = config.featureToggles.alertingSimplifiedRouting ?? false;
const simplifiedModeInNotificationsStepEnabled = config.featureToggles.alertingNotificationsStepMode ?? false;
const shouldRenderpreview = type === RuleFormType.grafana;
const hasInternalAlertmanagerEnabled = useHasInternalAlertmanagerEnabled();
const shouldAllowSimplifiedRouting =
type === RuleFormType.grafana && simplifiedRoutingToggleEnabled && hasInternalAlertmanagerEnabled;
const shouldAllowSimplifiedRouting = type === RuleFormType.grafana && hasInternalAlertmanagerEnabled;
function onCloseLabelsEditor(labelsToUpdate?: KBObjectArray) {
if (labelsToUpdate) {
@ -146,7 +144,6 @@ export const NotificationsStep = ({ alertUid }: NotificationsStepProps) => {
/**
* Preconditions:
* - simplified routing is enabled
* - the alert rule is a grafana rule
*
* This component will render the switch between the select contact point routing and the notification policy routing.
@ -191,7 +188,6 @@ function ManualAndAutomaticRouting({ alertUid }: { alertUid?: string }) {
/**
* Preconditions:
* - simplified routing is enabled
* - simple mode for notifications step is enabled
* - the alert rule is a grafana rule
*

@ -59,8 +59,6 @@ const selectContactPoint = async (user: UserEvent, contactPointName: string) =>
setupMswServer();
describe('Can create a new grafana managed alert using simplified routing', () => {
testWithFeatureToggles(['alertingSimplifiedRouting']);
beforeEach(() => {
window.localStorage.clear();
setupDataSources(dataSources.default, dataSources.am);

@ -3,7 +3,6 @@ import { useEffect, useRef, useState } from 'react';
import { useForm } from 'react-hook-form';
import { DataSourceInstanceSettings, GrafanaTheme2, SelectableValue } from '@grafana/data';
import { config } from '@grafana/runtime';
import { Button, Field, Icon, Input, Label, RadioButtonGroup, Stack, Tooltip, useStyles2 } from '@grafana/ui';
import { DashboardPicker } from 'app/core/components/Select/DashboardPicker';
import { contextSrv } from 'app/core/core';
@ -41,9 +40,7 @@ const RuleHealthOptions: SelectableValue[] = [
];
// Contact point selector is not supported in Alerting ListView V2 yet
const canRenderContactPointSelector =
contextSrv.hasPermission(AccessControlAction.AlertingReceiversRead) &&
config.featureToggles.alertingSimplifiedRouting;
const canRenderContactPointSelector = contextSrv.hasPermission(AccessControlAction.AlertingReceiversRead);
interface RulesFilerProps {
onClear?: () => void;

@ -1,5 +1,3 @@
import { config } from '@grafana/runtime';
import { mockAlertQuery, mockDataSource, mockReduceExpression, mockThresholdExpression } from '../mocks';
import { testWithFeatureToggles } from '../test/test-utils';
import { RuleFormType } from '../types/rule-form';
@ -177,24 +175,16 @@ describe('getDefaultManualRouting', () => {
window.localStorage.clear();
});
it('returns false if the feature toggle is not enabled', () => {
config.featureToggles.alertingSimplifiedRouting = false;
expect(getDefautManualRouting()).toBe(false);
});
it('returns true if the feature toggle is enabled and localStorage is not set', () => {
config.featureToggles.alertingSimplifiedRouting = true;
it('returns true if localStorage is not set', () => {
expect(getDefautManualRouting()).toBe(true);
});
it('returns false if the feature toggle is enabled and localStorage is set to "false"', () => {
config.featureToggles.alertingSimplifiedRouting = true;
it('returns false if localStorage is set to "false"', () => {
localStorage.setItem(MANUAL_ROUTING_KEY, 'false');
expect(getDefautManualRouting()).toBe(false);
});
it('returns true if the feature toggle is enabled and localStorage is set to any value other than "false"', () => {
config.featureToggles.alertingSimplifiedRouting = true;
it('returns true if localStorage is set to any value other than "false"', () => {
localStorage.setItem(MANUAL_ROUTING_KEY, 'true');
expect(getDefautManualRouting()).toBe(true);
localStorage.removeItem(MANUAL_ROUTING_KEY);

@ -81,12 +81,7 @@ export const getDefaultFormValues = (): RuleFormValues => {
};
export const getDefautManualRouting = () => {
// first check if feature toggle for simplified routing is enabled
const simplifiedRoutingToggleEnabled = config.featureToggles.alertingSimplifiedRouting ?? false;
if (!simplifiedRoutingToggleEnabled) {
return false;
}
//then, check in local storage if the user has enabled simplified routing
// check in local storage
// if it's not set, we'll default to true
const manualRouting = localStorage.getItem(MANUAL_ROUTING_KEY);
return manualRouting !== 'false';

Loading…
Cancel
Save