From d726d6b3e8057b509b050e8dc16db99455b4410b Mon Sep 17 00:00:00 2001 From: David Caro Date: Mon, 6 Mar 2023 14:42:03 +0100 Subject: [PATCH] feat: add default alertmanagers to silence form That will allow setting some default alertmanagers to select when creating a new silence, overriding the current behavior of getting all the ones that are not readonly. Signed-off-by: David Caro --- .../tests/testscript/059_log_full_config_env.txt | 1 + .../tests/testscript/060_log_full_config_file.txt | 1 + .../tests/testscript/065_proxy-with-readonly.txt | 1 + cmd/karma/tests/testscript/066_proxy.txt | 1 + cmd/karma/tests/testscript/067_readonly.txt | 1 + cmd/karma/tests/testscript/070_upper_case_keys.txt | 1 + cmd/karma/tests/testscript/097_proxy_url_config.txt | 1 + cmd/karma/views.go | 1 + cmd/karma/views_test.go | 1 + demo/karma.yaml | 2 ++ docs/CONFIGURATION.md | 13 +++++++++++++ docs/example.yaml | 2 ++ internal/config/config.go | 3 +++ internal/config/config_test.go | 5 +++++ internal/config/models.go | 1 + internal/models/api.go | 3 ++- .../SilenceModal/AlertManagerInput/index.tsx | 13 ++++++++++++- ui/src/Models/APITypes.ts | 1 + ui/src/Stores/AlertStore.ts | 1 + ui/src/__fixtures__/Fetch.ts | 1 + 20 files changed, 52 insertions(+), 2 deletions(-) diff --git a/cmd/karma/tests/testscript/059_log_full_config_env.txt b/cmd/karma/tests/testscript/059_log_full_config_env.txt index e2c29cf2f..35a8bd3e0 100644 --- a/cmd/karma/tests/testscript/059_log_full_config_env.txt +++ b/cmd/karma/tests/testscript/059_log_full_config_env.txt @@ -232,6 +232,7 @@ level=info msg=" labels:" level=info msg=" - job" level=info msg=" - severity" level=info msg=" - region" +level=info msg=" defaultAlertmanagers: []" level=info msg="ui:" level=info msg=" refresh: 10s" level=info msg=" hideFiltersWhenIdle: false" diff --git a/cmd/karma/tests/testscript/060_log_full_config_file.txt b/cmd/karma/tests/testscript/060_log_full_config_file.txt index 196bfb859..18d835f75 100644 --- a/cmd/karma/tests/testscript/060_log_full_config_file.txt +++ b/cmd/karma/tests/testscript/060_log_full_config_file.txt @@ -269,6 +269,7 @@ level=info msg=" labels:" level=info msg=" - job" level=info msg=" - severity" level=info msg=" - region" +level=info msg=" defaultAlertmanagers: []" level=info msg="ui:" level=info msg=" refresh: 10s" level=info msg=" hideFiltersWhenIdle: true" diff --git a/cmd/karma/tests/testscript/065_proxy-with-readonly.txt b/cmd/karma/tests/testscript/065_proxy-with-readonly.txt index 00736e049..4e127bcfa 100644 --- a/cmd/karma/tests/testscript/065_proxy-with-readonly.txt +++ b/cmd/karma/tests/testscript/065_proxy-with-readonly.txt @@ -120,6 +120,7 @@ level=info msg=" rules: []" level=info msg="silenceForm:" level=info msg=" strip:" level=info msg=" labels: []" +level=info msg=" defaultAlertmanagers: []" level=info msg="ui:" level=info msg=" refresh: 30s" level=info msg=" hideFiltersWhenIdle: true" diff --git a/cmd/karma/tests/testscript/066_proxy.txt b/cmd/karma/tests/testscript/066_proxy.txt index 1b67a28e8..06ba98685 100644 --- a/cmd/karma/tests/testscript/066_proxy.txt +++ b/cmd/karma/tests/testscript/066_proxy.txt @@ -120,6 +120,7 @@ level=info msg=" rules: []" level=info msg="silenceForm:" level=info msg=" strip:" level=info msg=" labels: []" +level=info msg=" defaultAlertmanagers: []" level=info msg="ui:" level=info msg=" refresh: 30s" level=info msg=" hideFiltersWhenIdle: true" diff --git a/cmd/karma/tests/testscript/067_readonly.txt b/cmd/karma/tests/testscript/067_readonly.txt index 74a3346f9..82d5deb23 100644 --- a/cmd/karma/tests/testscript/067_readonly.txt +++ b/cmd/karma/tests/testscript/067_readonly.txt @@ -120,6 +120,7 @@ level=info msg=" rules: []" level=info msg="silenceForm:" level=info msg=" strip:" level=info msg=" labels: []" +level=info msg=" defaultAlertmanagers: []" level=info msg="ui:" level=info msg=" refresh: 30s" level=info msg=" hideFiltersWhenIdle: true" diff --git a/cmd/karma/tests/testscript/070_upper_case_keys.txt b/cmd/karma/tests/testscript/070_upper_case_keys.txt index 72f13ca4e..ba40e646d 100644 --- a/cmd/karma/tests/testscript/070_upper_case_keys.txt +++ b/cmd/karma/tests/testscript/070_upper_case_keys.txt @@ -130,6 +130,7 @@ level=info msg=" rules: []" level=info msg="silenceForm:" level=info msg=" strip:" level=info msg=" labels: []" +level=info msg=" defaultAlertmanagers: []" level=info msg="ui:" level=info msg=" refresh: 30s" level=info msg=" hideFiltersWhenIdle: true" diff --git a/cmd/karma/tests/testscript/097_proxy_url_config.txt b/cmd/karma/tests/testscript/097_proxy_url_config.txt index 1a7a714d9..232c01815 100644 --- a/cmd/karma/tests/testscript/097_proxy_url_config.txt +++ b/cmd/karma/tests/testscript/097_proxy_url_config.txt @@ -120,6 +120,7 @@ level=info msg=" rules: []" level=info msg="silenceForm:" level=info msg=" strip:" level=info msg=" labels: []" +level=info msg=" defaultAlertmanagers: []" level=info msg="ui:" level=info msg=" refresh: 30s" level=info msg=" hideFiltersWhenIdle: true" diff --git a/cmd/karma/views.go b/cmd/karma/views.go index ff73e5689..905fb1306 100644 --- a/cmd/karma/views.go +++ b/cmd/karma/views.go @@ -193,6 +193,7 @@ func alerts(w http.ResponseWriter, r *http.Request) { Strip: models.SilenceFormStripSettings{ Labels: config.Config.SilenceForm.Strip.Labels, }, + DefaultAlertmanagers: config.Config.SilenceForm.DefaultAlertmanagers, }, AlertAcknowledgement: models.AlertAcknowledgementSettings{ Enabled: config.Config.AlertAcknowledgement.Enabled, diff --git a/cmd/karma/views_test.go b/cmd/karma/views_test.go index 74e8dbf51..bf12fd5ad 100644 --- a/cmd/karma/views_test.go +++ b/cmd/karma/views_test.go @@ -1124,6 +1124,7 @@ func TestEmptySettings(t *testing.T) { Strip: models.SilenceFormStripSettings{ Labels: []string{}, }, + DefaultAlertmanagers: []string{}, }, AlertAcknowledgement: models.AlertAcknowledgementSettings{ Enabled: false, diff --git a/demo/karma.yaml b/demo/karma.yaml index 447fba0e5..f316412ab 100644 --- a/demo/karma.yaml +++ b/demo/karma.yaml @@ -120,6 +120,8 @@ silenceForm: - job - severity - region + defaultAlertmanagers: + - single ui: refresh: 10s hideFiltersWhenIdle: true diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 8dfa942e2..559ce8ce9 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -1242,6 +1242,19 @@ silenceForm: - job ``` +- `defaultAlertmanagers` - list of Alertmanager names that will be used as + default when creating a new silence. + +Example where alertmanagers `prod1` and `prod2` will be the default ones when +creating a new silence + +```YAML +silenceForm: + defaultAlertmanagers: + - prod1 + - prod2 +``` + ## UI defaults `ui` section allows configuring default values for UI settings controled via the diff --git a/docs/example.yaml b/docs/example.yaml index fe311b6bb..a98fbcb06 100644 --- a/docs/example.yaml +++ b/docs/example.yaml @@ -60,6 +60,8 @@ silenceForm: strip: labels: - job + defaultAlertmanagers: + - local ui: refresh: 30s hideFiltersWhenIdle: true diff --git a/internal/config/config.go b/internal/config/config.go index c7cc2ee10..4536916b4 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -131,6 +131,7 @@ func SetupFlags(f *pflag.FlagSet) { f.Duration("silences.expired", time.Minute*10, "Maximum age of expired silences to show on active alerts") f.StringSlice("silenceform.strip.labels", []string{}, "List of labels to ignore when auto-filling silence form from alerts") + f.StringSlice("silenceform.defaultAlertmanagers", []string{}, "List of Alertmanager names to use as default when creating a new silence") f.String("listen.address", "", "IP/Hostname to listen on") f.Int("listen.port", 8080, "HTTP port to listen on") @@ -236,6 +237,8 @@ func readEnvVariables(k *koanf.Koanf) { return "labels.valueOnly_re" case "SILENCEFORM_STRIP_LABELS": return "silenceForm.strip.labels" + case "SILENCEFORM_DEFAULTALERTMANAGERS": + return "silenceForm.defaultAlertmanagers" case "UI_HIDEFILTERSWHENIDLE": return "ui.hideFiltersWhenIdle" case "UI_COLORTITLEBAR": diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 4c27cd246..03b416cf7 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -149,6 +149,7 @@ silences: silenceForm: strip: labels: [] + defaultAlertmanagers: [] ui: refresh: 30s hideFiltersWhenIdle: true @@ -393,6 +394,7 @@ func TestDefaultConfig(t *testing.T) { expectedConfig.Receivers.Keep = []string{} expectedConfig.Receivers.Strip = []string{} expectedConfig.SilenceForm.Strip.Labels = []string{} + expectedConfig.SilenceForm.DefaultAlertmanagers = []string{} if diff := cmp.Diff(expectedConfig.Annotations, Config.Annotations); diff != "" { t.Errorf("Wrong annotations config returned (-want +got):\n%s", diff) @@ -406,6 +408,9 @@ func TestDefaultConfig(t *testing.T) { if diff := cmp.Diff(expectedConfig.SilenceForm.Strip, Config.SilenceForm.Strip); diff != "" { t.Errorf("Wrong silence form config returned (-want +got):\n%s", diff) } + if diff := cmp.Diff(expectedConfig.SilenceForm.DefaultAlertmanagers, Config.SilenceForm.DefaultAlertmanagers); diff != "" { + t.Errorf("Wrong defaultAlertmanagers form config returned (-want +got):\n%s", diff) + } } func TestValidateConfigMissingFile(t *testing.T) { diff --git a/internal/config/models.go b/internal/config/models.go index 5be8897bc..b1508ee68 100644 --- a/internal/config/models.go +++ b/internal/config/models.go @@ -206,6 +206,7 @@ type configSchema struct { Strip struct { Labels []string } + DefaultAlertmanagers []string `yaml:"defaultAlertmanagers" koanf:"defaultAlertmanagers"` } `yaml:"silenceForm" koanf:"silenceForm"` // nolint: maligned UI struct { diff --git a/internal/models/api.go b/internal/models/api.go index 0d26d2750..97647a2ef 100644 --- a/internal/models/api.go +++ b/internal/models/api.go @@ -402,7 +402,8 @@ type SilenceFormStripSettings struct { } type SilenceFormSettings struct { - Strip SilenceFormStripSettings `json:"strip"` + Strip SilenceFormStripSettings `json:"strip"` + DefaultAlertmanagers []string `json:"defaultAlertmanagers"` } type AlertAcknowledgementSettings struct { diff --git a/ui/src/Components/SilenceModal/AlertManagerInput/index.tsx b/ui/src/Components/SilenceModal/AlertManagerInput/index.tsx index e193f2fd1..c6620be04 100644 --- a/ui/src/Components/SilenceModal/AlertManagerInput/index.tsx +++ b/ui/src/Components/SilenceModal/AlertManagerInput/index.tsx @@ -21,8 +21,19 @@ const AlertManagerInput: FC<{ }> = observer(({ alertStore, silenceFormStore }) => { useEffect(() => { if (silenceFormStore.data.alertmanagers.length === 0) { + // get only the clusters that match the defaults, or all of them if there are no defaults silenceFormStore.data.setAlertmanagers( - AlertmanagerClustersToOption(alertStore.data.clustersWithoutReadOnly) + AlertmanagerClustersToOption( + alertStore.data.clustersWithoutReadOnly + ).filter((am) => { + return ( + alertStore.settings.values.silenceForm.defaultAlertmanagers.some( + (amName) => am.value.includes(amName) + ) || + alertStore.settings.values.silenceForm.defaultAlertmanagers + .length === 0 + ); + }) ); } }, []); // eslint-disable-line react-hooks/exhaustive-deps diff --git a/ui/src/Models/APITypes.ts b/ui/src/Models/APITypes.ts index 951f3a98b..f8dd1f825 100644 --- a/ui/src/Models/APITypes.ts +++ b/ui/src/Models/APITypes.ts @@ -200,6 +200,7 @@ export interface APISettingsT { strip: { labels: string[]; }; + defaultAlertmanagers: string[]; }; alertAcknowledgement: { enabled: boolean; diff --git a/ui/src/Stores/AlertStore.ts b/ui/src/Stores/AlertStore.ts index 5f947647f..55c000611 100644 --- a/ui/src/Stores/AlertStore.ts +++ b/ui/src/Stores/AlertStore.ts @@ -466,6 +466,7 @@ class AlertStore { strip: { labels: [] as string[], }, + defaultAlertmanagers: [] as string[], }, alertAcknowledgement: { enabled: false as boolean, diff --git a/ui/src/__fixtures__/Fetch.ts b/ui/src/__fixtures__/Fetch.ts index e0e274c2e..29dc9bdd8 100644 --- a/ui/src/__fixtures__/Fetch.ts +++ b/ui/src/__fixtures__/Fetch.ts @@ -64,6 +64,7 @@ const EmptyAPIResponse = (): APIAlertsResponseT => ({ strip: { labels: [], }, + defaultAlertmanagers: [], }, alertAcknowledgement: { enabled: false,