Alerting: Validate extra configuration with PostableApiAlertingConfig (#108706)

This commit is contained in:
Alexander Akhmetov
2025-07-28 10:09:26 +02:00
committed by GitHub
parent f4b4d8ec95
commit 4ad80cec1a
3 changed files with 127 additions and 4 deletions
@@ -745,12 +745,14 @@ func (c ExtraConfiguration) Validate() error {
}
}
// Alertmanager configuration is validated during YAML unmarshalling.
am := config.Config{}
err := yaml.Unmarshal([]byte(c.AlertmanagerConfig), &am)
cfg, err := c.GetAlertmanagerConfig()
if err != nil {
return errInvalidExtraConfiguration(fmt.Errorf("failed to parse alertmanager config: %w", err))
}
err = cfg.Validate()
if err != nil {
return errInvalidExtraConfiguration(fmt.Errorf("invalid alertmanager config: %w", err))
}
return nil
}
@@ -403,3 +403,93 @@ func TestPostableUserConfig_GetMergedTemplateDefinitions(t *testing.T) {
})
}
}
func TestExtraConfiguration_Validate(t *testing.T) {
testCases := []struct {
name string
config ExtraConfiguration
expectedError string
}{
{
name: "valid configuration",
config: ExtraConfiguration{
Identifier: "test-config",
MergeMatchers: config.Matchers{{Type: labels.MatchEqual, Name: "env", Value: "prod"}},
AlertmanagerConfig: `route:
receiver: default
receivers:
- name: default`,
},
},
{
name: "empty identifier",
config: ExtraConfiguration{
Identifier: "",
MergeMatchers: config.Matchers{{Type: labels.MatchEqual, Name: "env", Value: "prod"}},
AlertmanagerConfig: `route: {receiver: default}`,
},
expectedError: "identifier is required",
},
{
name: "invalid matcher type",
config: ExtraConfiguration{
Identifier: "test-config",
MergeMatchers: config.Matchers{{Type: labels.MatchNotEqual, Name: "env", Value: "prod"}},
AlertmanagerConfig: `route:
receiver: default
receivers:
- name: default`,
},
expectedError: "only matchers with type equal are supported",
},
{
name: "invalid YAML alertmanager config",
config: ExtraConfiguration{
Identifier: "test-config",
MergeMatchers: config.Matchers{{Type: labels.MatchEqual, Name: "env", Value: "prod"}},
AlertmanagerConfig: `invalid: yaml: content: [`,
},
expectedError: "failed to parse alertmanager config",
},
{
name: "missing route in alertmanager config",
config: ExtraConfiguration{
Identifier: "test-config",
MergeMatchers: config.Matchers{{Type: labels.MatchEqual, Name: "env", Value: "prod"}},
AlertmanagerConfig: `receivers:
- name: default`,
},
expectedError: "no routes provided",
},
{
name: "missing receivers in alertmanager config",
config: ExtraConfiguration{
Identifier: "test-config",
MergeMatchers: config.Matchers{{Type: labels.MatchEqual, Name: "env", Value: "prod"}},
AlertmanagerConfig: `route:
receiver: default`,
},
expectedError: "undefined receiver",
},
{
name: "empty alertmanager config",
config: ExtraConfiguration{
Identifier: "test-config",
MergeMatchers: config.Matchers{{Type: labels.MatchEqual, Name: "env", Value: "prod"}},
AlertmanagerConfig: "",
},
expectedError: "failed to parse alertmanager config",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := tc.config.Validate()
if tc.expectedError == "" {
require.NoError(t, err)
} else {
require.ErrorContains(t, err, tc.expectedError)
}
})
}
}