mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
120 lines
4.1 KiB
Go
120 lines
4.1 KiB
Go
|
package notifier
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||
|
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||
|
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
||
|
)
|
||
|
|
||
|
type UnknownReceiverError struct {
|
||
|
UID string
|
||
|
}
|
||
|
|
||
|
func (e UnknownReceiverError) Error() string {
|
||
|
return fmt.Sprintf("unknown receiver: %s", e.UID)
|
||
|
}
|
||
|
|
||
|
type AlertmanagerConfigRejectedError struct {
|
||
|
Inner error
|
||
|
}
|
||
|
|
||
|
func (e AlertmanagerConfigRejectedError) Error() string {
|
||
|
return fmt.Sprintf("failed to save and apply Alertmanager configuration: %s", e.Inner.Error())
|
||
|
}
|
||
|
|
||
|
type configurationStore interface {
|
||
|
GetLatestAlertmanagerConfiguration(ctx context.Context, query *models.GetLatestAlertmanagerConfigurationQuery) error
|
||
|
}
|
||
|
|
||
|
func (moa *MultiOrgAlertmanager) GetAlertmanagerConfiguration(ctx context.Context, org int64) (definitions.GettableUserConfig, error) {
|
||
|
query := models.GetLatestAlertmanagerConfigurationQuery{OrgID: org}
|
||
|
err := moa.configStore.GetLatestAlertmanagerConfiguration(ctx, &query)
|
||
|
if err != nil {
|
||
|
return definitions.GettableUserConfig{}, fmt.Errorf("failed to get latest configuration: %w", err)
|
||
|
}
|
||
|
cfg, err := Load([]byte(query.Result.AlertmanagerConfiguration))
|
||
|
if err != nil {
|
||
|
return definitions.GettableUserConfig{}, fmt.Errorf("failed to unmarshal alertmanager configuration: %w", err)
|
||
|
}
|
||
|
|
||
|
result := definitions.GettableUserConfig{
|
||
|
TemplateFiles: cfg.TemplateFiles,
|
||
|
AlertmanagerConfig: definitions.GettableApiAlertingConfig{
|
||
|
Config: cfg.AlertmanagerConfig.Config,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for _, recv := range cfg.AlertmanagerConfig.Receivers {
|
||
|
receivers := make([]*definitions.GettableGrafanaReceiver, 0, len(recv.PostableGrafanaReceivers.GrafanaManagedReceivers))
|
||
|
for _, pr := range recv.PostableGrafanaReceivers.GrafanaManagedReceivers {
|
||
|
secureFields := make(map[string]bool, len(pr.SecureSettings))
|
||
|
for k := range pr.SecureSettings {
|
||
|
decryptedValue, err := moa.Crypto.getDecryptedSecret(pr, k)
|
||
|
if err != nil {
|
||
|
return definitions.GettableUserConfig{}, fmt.Errorf("failed to decrypt stored secure setting: %w", err)
|
||
|
}
|
||
|
if decryptedValue == "" {
|
||
|
continue
|
||
|
}
|
||
|
secureFields[k] = true
|
||
|
}
|
||
|
gr := definitions.GettableGrafanaReceiver{
|
||
|
UID: pr.UID,
|
||
|
Name: pr.Name,
|
||
|
Type: pr.Type,
|
||
|
DisableResolveMessage: pr.DisableResolveMessage,
|
||
|
Settings: pr.Settings,
|
||
|
SecureFields: secureFields,
|
||
|
}
|
||
|
receivers = append(receivers, &gr)
|
||
|
}
|
||
|
gettableApiReceiver := definitions.GettableApiReceiver{
|
||
|
GettableGrafanaReceivers: definitions.GettableGrafanaReceivers{
|
||
|
GrafanaManagedReceivers: receivers,
|
||
|
},
|
||
|
}
|
||
|
gettableApiReceiver.Name = recv.Name
|
||
|
result.AlertmanagerConfig.Receivers = append(result.AlertmanagerConfig.Receivers, &gettableApiReceiver)
|
||
|
}
|
||
|
|
||
|
return result, nil
|
||
|
}
|
||
|
|
||
|
func (moa *MultiOrgAlertmanager) ApplyAlertmanagerConfiguration(ctx context.Context, org int64, config definitions.PostableUserConfig) error {
|
||
|
// Get the last known working configuration
|
||
|
query := models.GetLatestAlertmanagerConfigurationQuery{OrgID: org}
|
||
|
if err := moa.configStore.GetLatestAlertmanagerConfiguration(ctx, &query); err != nil {
|
||
|
// If we don't have a configuration there's nothing for us to know and we should just continue saving the new one
|
||
|
if !errors.Is(err, store.ErrNoAlertmanagerConfiguration) {
|
||
|
return fmt.Errorf("failed to get latest configuration %w", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if err := moa.Crypto.LoadSecureSettings(ctx, org, config.AlertmanagerConfig.Receivers); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if err := config.ProcessConfig(moa.Crypto.Encrypt); err != nil {
|
||
|
return fmt.Errorf("failed to post process Alertmanager configuration: %w", err)
|
||
|
}
|
||
|
|
||
|
am, err := moa.AlertmanagerFor(org)
|
||
|
if err != nil {
|
||
|
// It's okay if the alertmanager isn't ready yet, we're changing its config anyway.
|
||
|
if !errors.Is(err, ErrAlertmanagerNotReady) {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if err := am.SaveAndApplyConfig(ctx, &config); err != nil {
|
||
|
moa.logger.Error("unable to save and apply alertmanager configuration", "err", err)
|
||
|
return AlertmanagerConfigRejectedError{err}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|