mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Disable legacy alerting for ever (#83651)
* hard disable for legacy alerting * remove alerting section from configuration file * update documentation to not refer to deleted section * remove AlertingEnabled from usage in UA setting parsing
This commit is contained in:
parent
8c7090bc11
commit
7147af6b8e
@ -1200,17 +1200,17 @@ ha_gossip_interval = 200ms
|
||||
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
ha_push_pull_interval = 60s
|
||||
|
||||
# Enable or disable alerting rule execution. The alerting UI remains visible. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# Enable or disable alerting rule execution. The alerting UI remains visible.
|
||||
execute_alerts = true
|
||||
|
||||
# Alert evaluation timeout when fetching data from the datasource. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# Alert evaluation timeout when fetching data from the datasource.
|
||||
# The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
evaluation_timeout = 30s
|
||||
|
||||
# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. The default value is 1.
|
||||
max_attempts = 1
|
||||
|
||||
# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time.
|
||||
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
min_interval = 10s
|
||||
|
||||
@ -1347,45 +1347,6 @@ password =
|
||||
|
||||
sync_interval = 5m
|
||||
|
||||
#################################### Alerting ############################
|
||||
[alerting]
|
||||
# Enable the legacy alerting sub-system and interface. If Unified Alerting is already enabled and you try to go back to legacy alerting, all data that is part of Unified Alerting will be deleted. When this configuration section and flag are not defined, the state is defined at runtime. See the documentation for more details.
|
||||
enabled =
|
||||
|
||||
# Makes it possible to turn off alert execution but alerting UI is visible
|
||||
execute_alerts = true
|
||||
|
||||
# Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
|
||||
error_or_timeout = alerting
|
||||
|
||||
# Default setting for how Grafana handles nodata or null values in alerting. (alerting, no_data, keep_state, ok)
|
||||
nodata_or_nullvalues = no_data
|
||||
|
||||
# Alert notifications can include images, but rendering many images at the same time can overload the server
|
||||
# This limit will protect the server from render overloading and make sure notifications are sent out quickly
|
||||
concurrent_render_limit = 5
|
||||
|
||||
# Default setting for alert calculation timeout. Default value is 30
|
||||
evaluation_timeout_seconds = 30
|
||||
|
||||
# Default setting for alert notification timeout. Default value is 30
|
||||
notification_timeout_seconds = 30
|
||||
|
||||
# Default setting for max attempts to sending alert notifications. Default value is 3
|
||||
max_attempts = 3
|
||||
|
||||
# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend
|
||||
min_interval_seconds = 1
|
||||
|
||||
# Configures for how long alert annotations are stored. Default is 0, which keeps them forever.
|
||||
# This setting should be expressed as an duration. Ex 6h (hours), 10d (days), 2w (weeks), 1M (month).
|
||||
# Deprecated, use [annotations.alerting].max_age instead
|
||||
max_annotation_age =
|
||||
|
||||
# Configures max number of alert annotations that Grafana stores. Default value is 0, which keeps all alert annotations.
|
||||
# Deprecated, use [annotations.alerting].max_annotations_to_keep instead
|
||||
max_annotations_to_keep =
|
||||
|
||||
#################################### Annotations #########################
|
||||
[annotations]
|
||||
# Configures the batch size for the annotation clean-up job. This setting is used for dashboard, API, and alert annotations.
|
||||
|
@ -1116,17 +1116,17 @@
|
||||
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
;ha_push_pull_interval = "60s"
|
||||
|
||||
# Enable or disable alerting rule execution. The alerting UI remains visible. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# Enable or disable alerting rule execution. The alerting UI remains visible.
|
||||
;execute_alerts = true
|
||||
|
||||
# Alert evaluation timeout when fetching data from the datasource. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# Alert evaluation timeout when fetching data from the datasource.
|
||||
# The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
;evaluation_timeout = 30s
|
||||
|
||||
# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. The default value is 1.
|
||||
;max_attempts = 1
|
||||
|
||||
# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence.
|
||||
# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time.
|
||||
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
;min_interval = 10s
|
||||
|
||||
@ -1216,45 +1216,6 @@ max_annotations_to_keep =
|
||||
# Unified Alerting. Should be kept false when not needed as it may cause unintended data-loss if left enabled.
|
||||
;clean_upgrade = false
|
||||
|
||||
#################################### Alerting ############################
|
||||
[alerting]
|
||||
# Disable legacy alerting engine & UI features
|
||||
;enabled = false
|
||||
|
||||
# Makes it possible to turn off alert execution but alerting UI is visible
|
||||
;execute_alerts = true
|
||||
|
||||
# Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
|
||||
;error_or_timeout = alerting
|
||||
|
||||
# Default setting for how Grafana handles nodata or null values in alerting. (alerting, no_data, keep_state, ok)
|
||||
;nodata_or_nullvalues = no_data
|
||||
|
||||
# Alert notifications can include images, but rendering many images at the same time can overload the server
|
||||
# This limit will protect the server from render overloading and make sure notifications are sent out quickly
|
||||
;concurrent_render_limit = 5
|
||||
|
||||
# Default setting for alert calculation timeout. Default value is 30
|
||||
;evaluation_timeout_seconds = 30
|
||||
|
||||
# Default setting for alert notification timeout. Default value is 30
|
||||
;notification_timeout_seconds = 30
|
||||
|
||||
# Default setting for max attempts to sending alert notifications. Default value is 3
|
||||
;max_attempts = 3
|
||||
|
||||
# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend
|
||||
;min_interval_seconds = 1
|
||||
|
||||
# Configures for how long alert annotations are stored. Default is 0, which keeps them forever.
|
||||
# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
|
||||
# Deprecated, use [annotations.alerting].max_age instead
|
||||
;max_annotation_age =
|
||||
|
||||
# Configures max number of alert annotations that Grafana stores. Default value is 0, which keeps all alert annotations.
|
||||
# Deprecated, use [annotations.alerting].max_annotations_to_keep instead
|
||||
;max_annotations_to_keep =
|
||||
|
||||
#################################### Annotations #########################
|
||||
[annotations]
|
||||
# Configures the batch size for the annotation clean-up job. This setting is used for dashboard, API, and alert annotations.
|
||||
|
@ -1608,11 +1608,11 @@ The interval string is a possibly signed sequence of decimal numbers, followed b
|
||||
|
||||
### execute_alerts
|
||||
|
||||
Enable or disable alerting rule execution. The default value is `true`. The alerting UI remains visible. This option has a [legacy version in the alerting section]({{< relref "#execute_alerts-1" >}}) that takes precedence.
|
||||
Enable or disable alerting rule execution. The default value is `true`. The alerting UI remains visible.
|
||||
|
||||
### evaluation_timeout
|
||||
|
||||
Sets the alert evaluation timeout when fetching data from the data source. The default value is `30s`. This option has a [legacy version in the alerting section]({{< relref "#evaluation_timeout_seconds" >}}) that takes precedence.
|
||||
Sets the alert evaluation timeout when fetching data from the data source. The default value is `30s`.
|
||||
|
||||
The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
|
||||
@ -1622,7 +1622,7 @@ Sets a maximum number of times we'll attempt to evaluate an alert rule before gi
|
||||
|
||||
### min_interval
|
||||
|
||||
Sets the minimum interval to enforce between rule evaluations. The default value is `10s` which equals the scheduler interval. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has [a legacy version in the alerting section]({{< relref "#min_interval_seconds" >}}) that takes precedence.
|
||||
Sets the minimum interval to enforce between rule evaluations. The default value is `10s` which equals the scheduler interval. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time.
|
||||
|
||||
The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
|
||||
@ -1690,68 +1690,6 @@ It should be kept false when not needed, as it may cause unintended data loss if
|
||||
|
||||
<hr>
|
||||
|
||||
## [alerting]
|
||||
|
||||
For more information about the legacy dashboard alerting feature in Grafana, refer to [the legacy Grafana alerts](/docs/grafana/v8.5/alerting/old-alerting/).
|
||||
|
||||
### enabled
|
||||
|
||||
Set to `true` to [enable legacy dashboard alerting]({{< relref "#unified_alerting" >}}). The default value is `false`.
|
||||
|
||||
### execute_alerts
|
||||
|
||||
Turns off alert rule execution, but alerting is still visible in the Grafana UI.
|
||||
|
||||
### error_or_timeout
|
||||
|
||||
Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
|
||||
|
||||
### nodata_or_nullvalues
|
||||
|
||||
Defines how Grafana handles nodata or null values in alerting. Options are `alerting`, `no_data`, `keep_state`, and `ok`. Default is `no_data`.
|
||||
|
||||
### concurrent_render_limit
|
||||
|
||||
Alert notifications can include images, but rendering many images at the same time can overload the server.
|
||||
This limit protects the server from render overloading and ensures notifications are sent out quickly. Default value is `5`.
|
||||
|
||||
### evaluation_timeout_seconds
|
||||
|
||||
Sets the alert calculation timeout. Default value is `30`.
|
||||
|
||||
### notification_timeout_seconds
|
||||
|
||||
Sets the alert notification timeout. Default value is `30`.
|
||||
|
||||
### max_attempts
|
||||
|
||||
Sets a maximum limit on attempts to sending alert notifications. Default value is `3`.
|
||||
|
||||
### min_interval_seconds
|
||||
|
||||
Sets the minimum interval between rule evaluations. Default value is `1`.
|
||||
|
||||
> **Note.** This setting has precedence over each individual rule frequency. If a rule frequency is lower than this value, then this value is enforced.
|
||||
|
||||
### max_annotation_age
|
||||
|
||||
{{% admonition type="note" %}}
|
||||
This option is deprecated - See `max_age` option in [unified_alerting.state_history.annotations]({{< relref "#unified_alertingstate_historyannotations" >}}) instead.
|
||||
{{% /admonition %}}
|
||||
|
||||
Configures for how long alert annotations are stored. Default is 0, which keeps them forever.
|
||||
This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
|
||||
|
||||
### max_annotations_to_keep
|
||||
|
||||
{{% admonition type="note" %}}
|
||||
This option is deprecated - See `max_annotations_to_keep` option in [unified_alerting.state_history.annotations]({{< relref "#unified_alertingstate_historyannotations" >}}) instead.
|
||||
{{% /admonition %}}
|
||||
|
||||
Configures max number of alert annotations that Grafana stores. Default value is 0, which keeps all alert annotations.
|
||||
|
||||
<hr>
|
||||
|
||||
## [annotations]
|
||||
|
||||
### cleanupjob_batchsize
|
||||
|
@ -30,7 +30,7 @@ You can also render a PNG by hovering over the panel to display the actions menu
|
||||
|
||||
## Alerting and render limits
|
||||
|
||||
Alert notifications can include images, but rendering many images at the same time can overload the server where the renderer is running. For instructions of how to configure this, see [concurrent_render_limit]({{< relref "../configure-grafana#concurrent_render_limit" >}}).
|
||||
Alert notifications can include images, but rendering many images at the same time can overload the server where the renderer is running. For instructions of how to configure this, see [max_concurrent_screenshots]({{< relref "../configure-grafana#max_concurrent_screenshots" >}}).
|
||||
|
||||
## Install Grafana Image Renderer plugin
|
||||
|
||||
|
@ -715,6 +715,8 @@ func (cfg *Cfg) readAnnotationSettings() error {
|
||||
|
||||
alertingAnnotations := cfg.Raw.Section("unified_alerting.state_history.annotations")
|
||||
if alertingAnnotations.Key("max_age").Value() == "" && section.Key("max_annotations_to_keep").Value() == "" {
|
||||
// Although this section is not documented anymore, we decided to keep it to avoid potential data-loss when user upgrades Grafana and does not change the setting.
|
||||
// TODO delete some time after Grafana 11.
|
||||
alertingSection := cfg.Raw.Section("alerting")
|
||||
cleanup := newAnnotationCleanupSettings(alertingSection, "max_annotation_age")
|
||||
if cleanup.MaxCount > 0 || cleanup.MaxAge > 0 {
|
||||
@ -1743,25 +1745,13 @@ func (cfg *Cfg) readRenderingSettings(iniFile *ini.File) error {
|
||||
}
|
||||
|
||||
func (cfg *Cfg) readAlertingSettings(iniFile *ini.File) error {
|
||||
// This check is kept to prevent users that upgrade to Grafana 11 with the legacy alerting enabled. This should prevent them from accidentally upgrading without migration to Unified Alerting.
|
||||
alerting := iniFile.Section("alerting")
|
||||
enabled, err := alerting.Key("enabled").Bool()
|
||||
cfg.AlertingEnabled = nil
|
||||
if err == nil {
|
||||
cfg.AlertingEnabled = &enabled
|
||||
if err == nil && enabled {
|
||||
cfg.Logger.Error("Option '[alerting].enabled' cannot be true. Legacy Alerting is removed. It is no longer deployed, enhanced, or supported. Delete '[alerting].enabled' and use '[unified_alerting].enabled' to enable Grafana Alerting. For more information, refer to the documentation on upgrading to Grafana Alerting (https://grafana.com/docs/grafana/v10.4/alerting/set-up/migrating-alerts)")
|
||||
return fmt.Errorf("invalid setting [alerting].enabled")
|
||||
}
|
||||
cfg.ExecuteAlerts = alerting.Key("execute_alerts").MustBool(true)
|
||||
cfg.AlertingRenderLimit = alerting.Key("concurrent_render_limit").MustInt(5)
|
||||
|
||||
cfg.AlertingErrorOrTimeout = valueAsString(alerting, "error_or_timeout", "alerting")
|
||||
cfg.AlertingNoDataOrNullValues = valueAsString(alerting, "nodata_or_nullvalues", "no_data")
|
||||
|
||||
evaluationTimeoutSeconds := alerting.Key("evaluation_timeout_seconds").MustInt64(30)
|
||||
cfg.AlertingEvaluationTimeout = time.Second * time.Duration(evaluationTimeoutSeconds)
|
||||
notificationTimeoutSeconds := alerting.Key("notification_timeout_seconds").MustInt64(30)
|
||||
cfg.AlertingNotificationTimeout = time.Second * time.Duration(notificationTimeoutSeconds)
|
||||
cfg.AlertingMaxAttempts = alerting.Key("max_attempts").MustInt(3)
|
||||
cfg.AlertingMinInterval = alerting.Key("min_interval_seconds").MustInt64(1)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ package setting
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
@ -463,356 +462,39 @@ func TestGetCDNPathWithAlphaVersion(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAlertingEnabled(t *testing.T) {
|
||||
anyBoolean := func() bool {
|
||||
return rand.Int63()%2 == 0
|
||||
}
|
||||
t.Run("fail if legacy alerting enabled", func(t *testing.T) {
|
||||
f := ini.Empty()
|
||||
cfg := NewCfg()
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
unifiedAlertingEnabled string
|
||||
legacyAlertingEnabled string
|
||||
featureToggleSet bool
|
||||
isEnterprise bool
|
||||
verifyCfg func(*testing.T, Cfg, *ini.File)
|
||||
}{
|
||||
{
|
||||
desc: "when legacy alerting is enabled and unified is disabled",
|
||||
legacyAlertingEnabled: "true",
|
||||
unifiedAlertingEnabled: "false",
|
||||
isEnterprise: anyBoolean(),
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.Equal(t, *cfg.UnifiedAlerting.Enabled, false)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, *(cfg.AlertingEnabled), true)
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when legacy alerting is disabled and unified is enabled",
|
||||
legacyAlertingEnabled: "false",
|
||||
unifiedAlertingEnabled: "true",
|
||||
isEnterprise: anyBoolean(),
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.Equal(t, *cfg.UnifiedAlerting.Enabled, true)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, *(cfg.AlertingEnabled), false)
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when both alerting are enabled",
|
||||
legacyAlertingEnabled: "true",
|
||||
unifiedAlertingEnabled: "true",
|
||||
isEnterprise: anyBoolean(),
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
require.Error(t, err)
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when legacy alerting is invalid (or not defined) and unified is disabled",
|
||||
legacyAlertingEnabled: "",
|
||||
unifiedAlertingEnabled: "false",
|
||||
isEnterprise: anyBoolean(),
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.Equal(t, *cfg.UnifiedAlerting.Enabled, false)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, *(cfg.AlertingEnabled), true)
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when legacy alerting is invalid (or not defined) and unified is enabled",
|
||||
legacyAlertingEnabled: "",
|
||||
unifiedAlertingEnabled: "true",
|
||||
isEnterprise: anyBoolean(),
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.Equal(t, *cfg.UnifiedAlerting.Enabled, true)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, *(cfg.AlertingEnabled), false)
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when legacy alerting is enabled and unified is not defined [OSS]",
|
||||
legacyAlertingEnabled: "true",
|
||||
unifiedAlertingEnabled: "",
|
||||
isEnterprise: false,
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.Equal(t, true, *cfg.UnifiedAlerting.Enabled)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, false, *(cfg.AlertingEnabled))
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when legacy alerting is enabled and unified is invalid [OSS]",
|
||||
legacyAlertingEnabled: "true",
|
||||
unifiedAlertingEnabled: "invalid",
|
||||
isEnterprise: false,
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
assert.EqualError(t, err, "failed to read unified alerting enabled setting: invalid value invalid, should be either true or false")
|
||||
assert.Nil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, false, *(cfg.AlertingEnabled))
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when legacy alerting is enabled and unified is not defined [Enterprise]",
|
||||
legacyAlertingEnabled: "true",
|
||||
unifiedAlertingEnabled: "",
|
||||
isEnterprise: true,
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.Equal(t, true, *cfg.UnifiedAlerting.Enabled)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, false, *(cfg.AlertingEnabled))
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when legacy alerting is enabled and unified is invalid [Enterprise]",
|
||||
legacyAlertingEnabled: "true",
|
||||
unifiedAlertingEnabled: "invalid",
|
||||
isEnterprise: false,
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
assert.EqualError(t, err, "failed to read unified alerting enabled setting: invalid value invalid, should be either true or false")
|
||||
assert.Nil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, false, *(cfg.AlertingEnabled))
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when legacy alerting is disabled and unified is not defined [OSS]",
|
||||
legacyAlertingEnabled: "false",
|
||||
unifiedAlertingEnabled: "",
|
||||
isEnterprise: false,
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.Equal(t, *cfg.UnifiedAlerting.Enabled, true)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, *(cfg.AlertingEnabled), false)
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when legacy alerting is disabled and unified is invalid [OSS]",
|
||||
legacyAlertingEnabled: "false",
|
||||
unifiedAlertingEnabled: "invalid",
|
||||
isEnterprise: false,
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
assert.EqualError(t, err, "failed to read unified alerting enabled setting: invalid value invalid, should be either true or false")
|
||||
assert.Nil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, false, *(cfg.AlertingEnabled))
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when legacy alerting is disabled and unified is not defined [Enterprise]",
|
||||
legacyAlertingEnabled: "false",
|
||||
unifiedAlertingEnabled: "",
|
||||
isEnterprise: true,
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.Equal(t, *cfg.UnifiedAlerting.Enabled, true)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, *(cfg.AlertingEnabled), false)
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when legacy alerting is disabled and unified is invalid [Enterprise]",
|
||||
legacyAlertingEnabled: "false",
|
||||
unifiedAlertingEnabled: "invalid",
|
||||
isEnterprise: false,
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
assert.EqualError(t, err, "failed to read unified alerting enabled setting: invalid value invalid, should be either true or false")
|
||||
assert.Nil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, false, *(cfg.AlertingEnabled))
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when both are not defined [OSS]",
|
||||
legacyAlertingEnabled: "",
|
||||
unifiedAlertingEnabled: "",
|
||||
isEnterprise: false,
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.True(t, *cfg.UnifiedAlerting.Enabled)
|
||||
assert.Nil(t, cfg.AlertingEnabled)
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when both are not invalid [OSS]",
|
||||
legacyAlertingEnabled: "invalid",
|
||||
unifiedAlertingEnabled: "invalid",
|
||||
isEnterprise: false,
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
assert.EqualError(t, err, "failed to read unified alerting enabled setting: invalid value invalid, should be either true or false")
|
||||
assert.Nil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, false, *(cfg.AlertingEnabled))
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when both are not defined [Enterprise]",
|
||||
legacyAlertingEnabled: "",
|
||||
unifiedAlertingEnabled: "",
|
||||
isEnterprise: true,
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.True(t, *cfg.UnifiedAlerting.Enabled)
|
||||
assert.Nil(t, cfg.AlertingEnabled)
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when both are not invalid [Enterprise]",
|
||||
legacyAlertingEnabled: "invalid",
|
||||
unifiedAlertingEnabled: "invalid",
|
||||
isEnterprise: false,
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
assert.EqualError(t, err, "failed to read unified alerting enabled setting: invalid value invalid, should be either true or false")
|
||||
assert.Nil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, false, *(cfg.AlertingEnabled))
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when both are false",
|
||||
legacyAlertingEnabled: "false",
|
||||
unifiedAlertingEnabled: "false",
|
||||
isEnterprise: anyBoolean(),
|
||||
verifyCfg: func(t *testing.T, cfg Cfg, f *ini.File) {
|
||||
err := cfg.readAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.readFeatureToggles(f)
|
||||
require.NoError(t, err)
|
||||
err = cfg.ReadUnifiedAlertingSettings(f)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, cfg.UnifiedAlerting.Enabled)
|
||||
assert.Equal(t, *cfg.UnifiedAlerting.Enabled, false)
|
||||
assert.NotNil(t, cfg.AlertingEnabled)
|
||||
assert.Equal(t, *(cfg.AlertingEnabled), false)
|
||||
},
|
||||
},
|
||||
}
|
||||
alertingSec, err := f.NewSection("alerting")
|
||||
require.NoError(t, err)
|
||||
_, err = alertingSec.NewKey("enabled", "true")
|
||||
require.NoError(t, err)
|
||||
|
||||
var isEnterpriseOld = IsEnterprise
|
||||
t.Cleanup(func() {
|
||||
IsEnterprise = isEnterpriseOld
|
||||
require.Error(t, cfg.readAlertingSettings(f))
|
||||
})
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
IsEnterprise = tc.isEnterprise
|
||||
t.Run("do nothing if it is disabled", func(t *testing.T) {
|
||||
f := ini.Empty()
|
||||
cfg := NewCfg()
|
||||
|
||||
f := ini.Empty()
|
||||
cfg := NewCfg()
|
||||
unifiedAlertingSec, err := f.NewSection("unified_alerting")
|
||||
require.NoError(t, err)
|
||||
_, err = unifiedAlertingSec.NewKey("enabled", tc.unifiedAlertingEnabled)
|
||||
require.NoError(t, err)
|
||||
alertingSec, err := f.NewSection("alerting")
|
||||
require.NoError(t, err)
|
||||
_, err = alertingSec.NewKey("enabled", "false")
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, cfg.readAlertingSettings(f))
|
||||
})
|
||||
|
||||
alertingSec, err := f.NewSection("alerting")
|
||||
require.NoError(t, err)
|
||||
_, err = alertingSec.NewKey("enabled", tc.legacyAlertingEnabled)
|
||||
require.NoError(t, err)
|
||||
t.Run("do nothing if it invalid", func(t *testing.T) {
|
||||
f := ini.Empty()
|
||||
cfg := NewCfg()
|
||||
|
||||
tc.verifyCfg(t, *cfg, f)
|
||||
})
|
||||
}
|
||||
alertingSec, err := f.NewSection("alerting")
|
||||
require.NoError(t, err)
|
||||
_, err = alertingSec.NewKey("enabled", "test")
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, cfg.readAlertingSettings(f))
|
||||
})
|
||||
}
|
||||
|
||||
func TestRedactedValue(t *testing.T) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package setting
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -46,7 +45,7 @@ const (
|
||||
`
|
||||
evaluatorDefaultEvaluationTimeout = 30 * time.Second
|
||||
schedulerDefaultAdminConfigPollInterval = time.Minute
|
||||
schedulereDefaultExecuteAlerts = true
|
||||
schedulerDefaultExecuteAlerts = true
|
||||
schedulerDefaultMaxAttempts = 1
|
||||
schedulerDefaultLegacyMinInterval = 1
|
||||
screenshotsDefaultCapture = false
|
||||
@ -166,49 +165,13 @@ func (cfg *Cfg) readUnifiedAlertingEnabledSetting(section *ini.Section) (*bool,
|
||||
// At present an invalid value is considered the same as no value. This means that a
|
||||
// spelling mistake in the string "false" could enable unified alerting rather
|
||||
// than disable it. This issue can be found here
|
||||
hasEnabled := section.Key("enabled").Value() != ""
|
||||
if !hasEnabled {
|
||||
// TODO: Remove in Grafana v10
|
||||
if cfg.IsFeatureToggleEnabled("ngalert") {
|
||||
cfg.Logger.Warn("ngalert feature flag is deprecated: use unified alerting enabled setting instead")
|
||||
// feature flag overrides the legacy alerting setting
|
||||
legacyAlerting := false
|
||||
cfg.AlertingEnabled = &legacyAlerting
|
||||
unifiedAlerting := true
|
||||
return &unifiedAlerting, nil
|
||||
}
|
||||
|
||||
// if legacy alerting has not been configured then enable unified alerting
|
||||
if cfg.AlertingEnabled == nil {
|
||||
unifiedAlerting := true
|
||||
return &unifiedAlerting, nil
|
||||
}
|
||||
|
||||
// enable unified alerting and disable legacy alerting
|
||||
legacyAlerting := false
|
||||
cfg.AlertingEnabled = &legacyAlerting
|
||||
unifiedAlerting := true
|
||||
return &unifiedAlerting, nil
|
||||
if section.Key("enabled").Value() == "" {
|
||||
return util.Pointer(true), nil
|
||||
}
|
||||
|
||||
unifiedAlerting, err := section.Key("enabled").Bool()
|
||||
if err != nil {
|
||||
// the value for unified alerting is invalid so disable all alerting
|
||||
legacyAlerting := false
|
||||
cfg.AlertingEnabled = &legacyAlerting
|
||||
return nil, fmt.Errorf("invalid value %s, should be either true or false", section.Key("enabled"))
|
||||
}
|
||||
|
||||
// If both legacy and unified alerting are enabled then return an error
|
||||
if cfg.AlertingEnabled != nil && *(cfg.AlertingEnabled) && unifiedAlerting {
|
||||
return nil, errors.New("legacy and unified alerting cannot both be enabled at the same time, please disable one of them and restart Grafana")
|
||||
}
|
||||
|
||||
if cfg.AlertingEnabled == nil {
|
||||
legacyAlerting := !unifiedAlerting
|
||||
cfg.AlertingEnabled = &legacyAlerting
|
||||
}
|
||||
|
||||
return &unifiedAlerting, nil
|
||||
}
|
||||
|
||||
@ -277,9 +240,9 @@ func (cfg *Cfg) ReadUnifiedAlertingSettings(iniFile *ini.File) error {
|
||||
|
||||
alerting := iniFile.Section("alerting")
|
||||
|
||||
uaExecuteAlerts := ua.Key("execute_alerts").MustBool(schedulereDefaultExecuteAlerts)
|
||||
uaExecuteAlerts := ua.Key("execute_alerts").MustBool(schedulerDefaultExecuteAlerts)
|
||||
if uaExecuteAlerts { // unified option equals the default (true)
|
||||
legacyExecuteAlerts := alerting.Key("execute_alerts").MustBool(schedulereDefaultExecuteAlerts)
|
||||
legacyExecuteAlerts := alerting.Key("execute_alerts").MustBool(schedulerDefaultExecuteAlerts)
|
||||
if !legacyExecuteAlerts {
|
||||
cfg.Logger.Warn("falling back to legacy setting of 'execute_alerts'; please use the configuration option in the `unified_alerting` section if Grafana 8 alerts are enabled.")
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ func TestUnifiedAlertingSettings(t *testing.T) {
|
||||
alertingOptions: map[string]string{
|
||||
"max_attempts": strconv.FormatInt(schedulerDefaultMaxAttempts, 10),
|
||||
"min_interval_seconds": strconv.FormatInt(schedulerDefaultLegacyMinInterval, 10),
|
||||
"execute_alerts": strconv.FormatBool(schedulereDefaultExecuteAlerts),
|
||||
"execute_alerts": strconv.FormatBool(schedulerDefaultExecuteAlerts),
|
||||
"evaluation_timeout_seconds": strconv.FormatInt(int64(evaluatorDefaultEvaluationTimeout.Seconds()), 10),
|
||||
},
|
||||
verifyCfg: func(t *testing.T, cfg Cfg) {
|
||||
@ -111,7 +111,7 @@ func TestUnifiedAlertingSettings(t *testing.T) {
|
||||
unifiedAlertingOptions: map[string]string{
|
||||
"admin_config_poll_interval": "120s",
|
||||
"min_interval": SchedulerBaseInterval.String(),
|
||||
"execute_alerts": strconv.FormatBool(schedulereDefaultExecuteAlerts),
|
||||
"execute_alerts": strconv.FormatBool(schedulerDefaultExecuteAlerts),
|
||||
"evaluation_timeout": evaluatorDefaultEvaluationTimeout.String(),
|
||||
},
|
||||
alertingOptions: map[string]string{
|
||||
@ -148,7 +148,7 @@ func TestUnifiedAlertingSettings(t *testing.T) {
|
||||
require.Equal(t, alertmanagerDefaultConfigPollInterval, cfg.UnifiedAlerting.AdminConfigPollInterval)
|
||||
require.Equal(t, int64(schedulerDefaultMaxAttempts), cfg.UnifiedAlerting.MaxAttempts)
|
||||
require.Equal(t, SchedulerBaseInterval, cfg.UnifiedAlerting.MinInterval)
|
||||
require.Equal(t, schedulereDefaultExecuteAlerts, cfg.UnifiedAlerting.ExecuteAlerts)
|
||||
require.Equal(t, schedulerDefaultExecuteAlerts, cfg.UnifiedAlerting.ExecuteAlerts)
|
||||
require.Equal(t, evaluatorDefaultEvaluationTimeout, cfg.UnifiedAlerting.EvaluationTimeout)
|
||||
require.Equal(t, SchedulerBaseInterval, cfg.UnifiedAlerting.BaseInterval)
|
||||
require.Equal(t, DefaultRuleEvaluationInterval, cfg.UnifiedAlerting.DefaultRuleEvaluationInterval)
|
||||
|
Loading…
Reference in New Issue
Block a user