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 <dcaro@wikimedia.org>
This commit is contained in:
David Caro
2023-03-08 10:55:35 +00:00
committed by Łukasz Mierzwa
parent 203c3102f3
commit f1006314c0
20 changed files with 52 additions and 2 deletions
@@ -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"
@@ -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"
@@ -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"
+1
View File
@@ -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"
@@ -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"
@@ -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"
@@ -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"
+1
View File
@@ -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,
+1
View File
@@ -1124,6 +1124,7 @@ func TestEmptySettings(t *testing.T) {
Strip: models.SilenceFormStripSettings{
Labels: []string{},
},
DefaultAlertmanagers: []string{},
},
AlertAcknowledgement: models.AlertAcknowledgementSettings{
Enabled: false,
+2
View File
@@ -120,6 +120,8 @@ silenceForm:
- job
- severity
- region
defaultAlertmanagers:
- single
ui:
refresh: 10s
hideFiltersWhenIdle: true
+13
View File
@@ -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
+2
View File
@@ -60,6 +60,8 @@ silenceForm:
strip:
labels:
- job
defaultAlertmanagers:
- local
ui:
refresh: 30s
hideFiltersWhenIdle: true
+3
View File
@@ -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":
+5
View File
@@ -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) {
+1
View File
@@ -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 {
+2 -1
View File
@@ -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 {
@@ -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
+1
View File
@@ -200,6 +200,7 @@ export interface APISettingsT {
strip: {
labels: string[];
};
defaultAlertmanagers: string[];
};
alertAcknowledgement: {
enabled: boolean;
+1
View File
@@ -466,6 +466,7 @@ class AlertStore {
strip: {
labels: [] as string[],
},
defaultAlertmanagers: [] as string[],
},
alertAcknowledgement: {
enabled: false as boolean,
+1
View File
@@ -64,6 +64,7 @@ const EmptyAPIResponse = (): APIAlertsResponseT => ({
strip: {
labels: [],
},
defaultAlertmanagers: [],
},
alertAcknowledgement: {
enabled: false,