Alerting: Remove usages of ReceiverType (#111508)

* remove usages of ReceiverType
This commit is contained in:
Yuri Tseretyan
2025-09-25 16:09:54 -04:00
committed by GitHub
parent 217990ded9
commit 24c10b4fb9
9 changed files with 93 additions and 149 deletions
@@ -206,8 +206,10 @@ func (f *AlertmanagerApiHandler) handleRoutePostAlertingConfig(ctx *contextmodel
if err != nil {
return errorToResponse(err)
}
if !body.AlertmanagerConfig.ReceiverType().Can(apimodels.AlertmanagerReceiverType) {
return errorToResponse(backendTypeDoesNotMatchPayloadTypeError(apimodels.AlertmanagerBackend, body.AlertmanagerConfig.ReceiverType().String()))
for _, p := range body.AlertmanagerConfig.Receivers {
if p.HasGrafanaIntegrations() {
return errorToResponse(backendTypeDoesNotMatchPayloadTypeError(apimodels.AlertmanagerBackend, apimodels.GrafanaBackend.String()))
}
}
return s.RoutePostAlertingConfig(ctx, body)
}
@@ -267,7 +267,6 @@ type (
ObjectMatchers = definition.ObjectMatchers
PostableApiReceiver = definition.PostableApiReceiver
PostableGrafanaReceivers = definition.PostableGrafanaReceivers
ReceiverType = definition.ReceiverType
)
type MergeResult definition.MergeResult
@@ -295,9 +294,6 @@ func (m MergeResult) LogContext() []any {
}
const (
GrafanaReceiverType = definition.GrafanaReceiverType
AlertmanagerReceiverType = definition.AlertmanagerReceiverType
errInvalidExtraConfigurationMsg = "Invalid Alertmanager configuration: {{.Public.Error}}"
)
@@ -870,12 +866,8 @@ func (c *PostableUserConfig) validate() error {
func (c *PostableUserConfig) GetGrafanaReceiverMap() map[string]*PostableGrafanaReceiver {
UIDs := make(map[string]*PostableGrafanaReceiver)
for _, r := range c.AlertmanagerConfig.Receivers {
switch r.Type() {
case GrafanaReceiverType:
for _, gr := range r.GrafanaManagedReceivers {
UIDs[gr.UID] = gr
}
default:
for _, gr := range r.GrafanaManagedReceivers {
UIDs[gr.UID] = gr
}
}
return UIDs
@@ -975,12 +967,8 @@ func (c *GettableUserConfig) MarshalJSON() ([]byte, error) {
func (c *GettableUserConfig) GetGrafanaReceiverMap() map[string]*GettableGrafanaReceiver {
UIDs := make(map[string]*GettableGrafanaReceiver)
for _, r := range c.AlertmanagerConfig.Receivers {
switch r.Type() {
case GrafanaReceiverType:
for _, gr := range r.GrafanaManagedReceivers {
UIDs[gr.UID] = gr
}
default:
for _, gr := range r.GrafanaManagedReceivers {
UIDs[gr.UID] = gr
}
}
return UIDs
@@ -1097,47 +1085,7 @@ type GettableApiReceiver struct {
func (r *GettableApiReceiver) UnmarshalJSON(b []byte) error {
type plain GettableApiReceiver
if err := json.Unmarshal(b, (*plain)(r)); err != nil {
return err
}
hasGrafanaReceivers := len(r.GrafanaManagedReceivers) > 0
if hasGrafanaReceivers {
if len(r.EmailConfigs) > 0 {
return fmt.Errorf("cannot have both Alertmanager EmailConfigs & Grafana receivers together")
}
if len(r.PagerdutyConfigs) > 0 {
return fmt.Errorf("cannot have both Alertmanager PagerdutyConfigs & Grafana receivers together")
}
if len(r.SlackConfigs) > 0 {
return fmt.Errorf("cannot have both Alertmanager SlackConfigs & Grafana receivers together")
}
if len(r.WebhookConfigs) > 0 {
return fmt.Errorf("cannot have both Alertmanager WebhookConfigs & Grafana receivers together")
}
if len(r.OpsGenieConfigs) > 0 {
return fmt.Errorf("cannot have both Alertmanager OpsGenieConfigs & Grafana receivers together")
}
if len(r.WechatConfigs) > 0 {
return fmt.Errorf("cannot have both Alertmanager WechatConfigs & Grafana receivers together")
}
if len(r.PushoverConfigs) > 0 {
return fmt.Errorf("cannot have both Alertmanager PushoverConfigs & Grafana receivers together")
}
if len(r.VictorOpsConfigs) > 0 {
return fmt.Errorf("cannot have both Alertmanager VictorOpsConfigs & Grafana receivers together")
}
}
return nil
}
func (r *GettableApiReceiver) Type() ReceiverType {
if len(r.GrafanaManagedReceivers) > 0 {
return GrafanaReceiverType
}
return AlertmanagerReceiverType
return json.Unmarshal(b, (*plain)(r))
}
func (r *GettableApiReceiver) GetName() string {
@@ -452,26 +452,22 @@ func assignReceiverConfigsUIDs(c []*definitions.PostableApiReceiver) error {
seenUIDs := make(map[string]struct{})
// encrypt secure settings for storing them in DB
for _, r := range c {
switch r.Type() {
case definitions.GrafanaReceiverType:
for _, gr := range r.GrafanaManagedReceivers {
if gr.UID == "" {
retries := 5
for i := 0; i < retries; i++ {
gen := util.GenerateShortUID()
_, ok := seenUIDs[gen]
if !ok {
gr.UID = gen
break
}
}
if gr.UID == "" {
return fmt.Errorf("all %d attempts to generate UID for receiver have failed; please retry", retries)
for _, gr := range r.GrafanaManagedReceivers {
if gr.UID == "" {
retries := 5
for i := 0; i < retries; i++ {
gen := util.GenerateShortUID()
_, ok := seenUIDs[gen]
if !ok {
gr.UID = gen
break
}
}
seenUIDs[gr.UID] = struct{}{}
if gr.UID == "" {
return fmt.Errorf("all %d attempts to generate UID for receiver have failed; please retry", retries)
}
}
default:
seenUIDs[gr.UID] = struct{}{}
}
}
return nil
+61 -65
View File
@@ -87,81 +87,77 @@ func EncryptReceiverConfigSettings(c []*definitions.PostableApiReceiver, encrypt
func encryptReceiverConfigs(c []*definitions.PostableApiReceiver, encrypt definitions.EncryptFn, encryptExisting bool) error {
// encrypt secure settings for storing them in DB
for _, r := range c {
switch r.Type() {
case definitions.GrafanaReceiverType:
for _, gr := range r.GrafanaManagedReceivers {
if encryptExisting {
for k, v := range gr.SecureSettings {
encryptedData, err := encrypt(context.Background(), []byte(v))
for _, gr := range r.GrafanaManagedReceivers {
if encryptExisting {
for k, v := range gr.SecureSettings {
encryptedData, err := encrypt(context.Background(), []byte(v))
if err != nil {
return fmt.Errorf("failed to encrypt secure settings: %w", err)
}
gr.SecureSettings[k] = base64.StdEncoding.EncodeToString(encryptedData)
}
}
if len(gr.Settings) > 0 {
// We need to parse the settings to check for secret keys. If we find any, we encrypt them and
// store them in SecureSettings. This can happen from incorrect configuration or when an integration
// definition is updated to make a field secure.
settings := make(map[string]any)
if err := json.Unmarshal(gr.Settings, &settings); err != nil {
return fmt.Errorf("integration '%s' of receiver '%s' has settings that cannot be parsed as JSON: %w", gr.Type, gr.Name, err)
}
secretKeys, err := channels_config.GetSecretKeysForContactPointType(gr.Type, channels_config.V1)
if err != nil {
return fmt.Errorf("failed to get secret keys for contact point type %s: %w", gr.Type, err)
}
secureSettings := gr.SecureSettings
if secureSettings == nil {
secureSettings = make(map[string]string)
}
settingsChanged := false
secureSettingsChanged := false
for _, secretKey := range secretKeys {
settingsValue, ok := settings[secretKey]
if !ok {
continue
}
// Secrets should not be stored in settings regardless.
delete(settings, secretKey)
settingsChanged = true
// If the secret is already encrypted, we don't need to encrypt it again.
if _, ok := secureSettings[secretKey]; ok {
continue
}
if strVal, isString := settingsValue.(string); isString {
encrypted, err := encrypt(context.Background(), []byte(strVal))
if err != nil {
return fmt.Errorf("failed to encrypt secure settings: %w", err)
}
gr.SecureSettings[k] = base64.StdEncoding.EncodeToString(encryptedData)
secureSettings[secretKey] = base64.StdEncoding.EncodeToString(encrypted)
secureSettingsChanged = true
}
}
if len(gr.Settings) > 0 {
// We need to parse the settings to check for secret keys. If we find any, we encrypt them and
// store them in SecureSettings. This can happen from incorrect configuration or when an integration
// definition is updated to make a field secure.
settings := make(map[string]any)
if err := json.Unmarshal(gr.Settings, &settings); err != nil {
return fmt.Errorf("integration '%s' of receiver '%s' has settings that cannot be parsed as JSON: %w", gr.Type, gr.Name, err)
}
secretKeys, err := channels_config.GetSecretKeysForContactPointType(gr.Type, channels_config.V1)
// Defensive checks to limit the risk of unintentional edge case changes in this legacy API.
if settingsChanged {
// If we removed any secret keys from settings, we need to save the updated settings.
jsonBytes, err := json.Marshal(settings)
if err != nil {
return fmt.Errorf("failed to get secret keys for contact point type %s: %w", gr.Type, err)
}
secureSettings := gr.SecureSettings
if secureSettings == nil {
secureSettings = make(map[string]string)
}
settingsChanged := false
secureSettingsChanged := false
for _, secretKey := range secretKeys {
settingsValue, ok := settings[secretKey]
if !ok {
continue
}
// Secrets should not be stored in settings regardless.
delete(settings, secretKey)
settingsChanged = true
// If the secret is already encrypted, we don't need to encrypt it again.
if _, ok := secureSettings[secretKey]; ok {
continue
}
if strVal, isString := settingsValue.(string); isString {
encrypted, err := encrypt(context.Background(), []byte(strVal))
if err != nil {
return fmt.Errorf("failed to encrypt secure settings: %w", err)
}
secureSettings[secretKey] = base64.StdEncoding.EncodeToString(encrypted)
secureSettingsChanged = true
}
}
// Defensive checks to limit the risk of unintentional edge case changes in this legacy API.
if settingsChanged {
// If we removed any secret keys from settings, we need to save the updated settings.
jsonBytes, err := json.Marshal(settings)
if err != nil {
return err
}
gr.Settings = jsonBytes
}
if secureSettingsChanged {
// If we added any secure settings, we need to save the updated secure settings.
gr.SecureSettings = secureSettings
return err
}
gr.Settings = jsonBytes
}
if secureSettingsChanged {
// If we added any secure settings, we need to save the updated secure settings.
gr.SecureSettings = secureSettings
}
}
default:
}
}
return nil