The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/services/cloudmigration/cloudmigrationimpl/snapshot_mgmt_alerts.go

237 lines
8.8 KiB

package cloudmigrationimpl
import (
"context"
"fmt"
"time"
"github.com/prometheus/alertmanager/config"
"github.com/prometheus/common/model"
"github.com/grafana/grafana/pkg/components/simplejson"
ngalertapi "github.com/grafana/grafana/pkg/services/ngalert/api/compat"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
type muteTimeInterval struct {
UID string `json:"uid"`
// There is a lot of custom (de)serialization logic from Alertmanager,
// and this is the same type used by the underlying API, hence we can use the type as-is.
config.MuteTimeInterval `json:",inline"`
}
func (s *Service) getAlertMuteTimings(ctx context.Context, signedInUser *user.SignedInUser) ([]muteTimeInterval, error) {
muteTimings, err := s.ngAlert.Api.MuteTimings.GetMuteTimings(ctx, signedInUser.OrgID)
if err != nil {
return nil, fmt.Errorf("fetching ngalert mute timings: %w", err)
}
muteTimeIntervals := make([]muteTimeInterval, 0, len(muteTimings))
for _, muteTiming := range muteTimings {
muteTimeIntervals = append(muteTimeIntervals, muteTimeInterval{
UID: muteTiming.UID,
MuteTimeInterval: config.MuteTimeInterval{
Name: muteTiming.Name,
TimeIntervals: muteTiming.TimeIntervals,
},
})
}
return muteTimeIntervals, nil
}
type notificationTemplate struct {
UID string `json:"uid"`
Name string `json:"name"`
Template string `json:"template"`
}
func (s *Service) getNotificationTemplates(ctx context.Context, signedInUser *user.SignedInUser) ([]notificationTemplate, error) {
templates, err := s.ngAlert.Api.Templates.GetTemplates(ctx, signedInUser.OrgID)
if err != nil {
return nil, fmt.Errorf("fetching ngalert notification templates: %w", err)
}
notificationTemplates := make([]notificationTemplate, 0, len(templates))
for _, template := range templates {
notificationTemplates = append(notificationTemplates, notificationTemplate{
UID: template.UID,
Name: template.Name,
Template: template.Template,
})
}
return notificationTemplates, nil
}
type contactPoint struct {
Settings *simplejson.Json `json:"settings"`
UID string `json:"uid"`
Name string `json:"name"`
Type string `json:"type"`
DisableResolveMessage bool `json:"disableResolveMessage"`
}
func (s *Service) getContactPoints(ctx context.Context, signedInUser *user.SignedInUser) ([]contactPoint, error) {
query := provisioning.ContactPointQuery{
OrgID: signedInUser.GetOrgID(),
Decrypt: true, // needed to recreate the settings in the target instance.
}
embeddedContactPoints, err := s.ngAlert.Api.ContactPointService.GetContactPoints(ctx, query, signedInUser)
if err != nil {
return nil, fmt.Errorf("fetching ngalert contact points: %w", err)
}
contactPoints := make([]contactPoint, 0, len(embeddedContactPoints))
for _, embeddedContactPoint := range embeddedContactPoints {
contactPoints = append(contactPoints, contactPoint{
UID: embeddedContactPoint.UID,
Name: embeddedContactPoint.Name,
Type: embeddedContactPoint.Type,
Settings: embeddedContactPoint.Settings,
DisableResolveMessage: embeddedContactPoint.DisableResolveMessage,
})
}
return contactPoints, nil
}
type notificationPolicy struct {
Name string
Routes definitions.Route
}
func (s *Service) getNotificationPolicies(ctx context.Context, signedInUser *user.SignedInUser) (notificationPolicy, error) {
policyTree, _, err := s.ngAlert.Api.Policies.GetPolicyTree(ctx, signedInUser.GetOrgID())
if err != nil {
return notificationPolicy{}, fmt.Errorf("fetching ngalert notification policy tree: %w", err)
}
return notificationPolicy{
Name: "Notification Policy Tree",
Routes: policyTree,
}, nil
}
type alertRule struct {
Updated time.Time `json:"updated,omitempty"`
Annotations map[string]string `json:"annotations,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
Record *definitions.Record `json:"record"`
NotificationSettings *definitions.AlertRuleNotificationSettings `json:"notification_settings"`
FolderUID string `json:"folderUID"`
RuleGroup string `json:"ruleGroup"`
NoDataState string `json:"noDataState"`
Condition string `json:"condition"`
UID string `json:"uid"`
Title string `json:"title"`
ExecErrState string `json:"execErrState"`
Data []definitions.AlertQuery `json:"data"`
For model.Duration `json:"for"`
OrgID int64 `json:"orgID"`
IsPaused bool `json:"isPaused"`
}
func (s *Service) getAlertRules(ctx context.Context, signedInUser *user.SignedInUser) ([]alertRule, error) {
alertRules, _, err := s.ngAlert.Api.AlertRules.GetAlertRules(ctx, signedInUser)
if err != nil {
return nil, fmt.Errorf("fetching alert rules: %w", err)
}
settingAlertRulesPaused := s.cfg.CloudMigration.AlertRulesState == setting.GMSAlertRulesPaused
provisionedAlertRules := make([]alertRule, 0, len(alertRules))
for _, rule := range alertRules {
isPaused := rule.IsPaused
if settingAlertRulesPaused {
isPaused = true
}
provisionedAlertRules = append(provisionedAlertRules, alertRule{
UID: rule.UID,
OrgID: rule.OrgID,
FolderUID: rule.NamespaceUID,
RuleGroup: rule.RuleGroup,
Title: rule.Title,
For: model.Duration(rule.For),
Condition: rule.Condition,
Data: ngalertapi.ApiAlertQueriesFromAlertQueries(rule.Data),
Updated: rule.Updated,
NoDataState: rule.NoDataState.String(),
ExecErrState: rule.ExecErrState.String(),
Annotations: rule.Annotations,
Labels: rule.Labels,
IsPaused: isPaused,
NotificationSettings: ngalertapi.AlertRuleNotificationSettingsFromNotificationSettings(rule.NotificationSettings),
Record: ngalertapi.ApiRecordFromModelRecord(rule.Record),
})
}
return provisionedAlertRules, nil
}
type alertRuleGroup struct {
Title string `json:"title"`
FolderUID string `json:"folderUid"`
Interval int64 `json:"interval"`
Rules []alertRule `json:"rules"`
}
func (s *Service) getAlertRuleGroups(ctx context.Context, signedInUser *user.SignedInUser) ([]alertRuleGroup, error) {
alertRuleGroupsWithFolder, err := s.ngAlert.Api.AlertRules.GetAlertGroupsWithFolderFullpath(ctx, signedInUser, nil)
if err != nil {
return nil, fmt.Errorf("fetching alert rule groups with folders: %w", err)
}
settingAlertRulesPaused := s.cfg.CloudMigration.AlertRulesState == setting.GMSAlertRulesPaused
alertRuleGroups := make([]alertRuleGroup, 0, len(alertRuleGroupsWithFolder))
for _, ruleGroup := range alertRuleGroupsWithFolder {
provisionedAlertRules := make([]alertRule, 0, len(ruleGroup.Rules))
for _, rule := range ruleGroup.Rules {
isPaused := rule.IsPaused
if settingAlertRulesPaused {
isPaused = true
}
provisionedAlertRules = append(provisionedAlertRules, alertRule{
UID: rule.UID,
OrgID: rule.OrgID,
FolderUID: rule.NamespaceUID,
RuleGroup: rule.RuleGroup,
Title: rule.Title,
For: model.Duration(rule.For),
Condition: rule.Condition,
Data: ngalertapi.ApiAlertQueriesFromAlertQueries(rule.Data),
Updated: rule.Updated,
NoDataState: rule.NoDataState.String(),
ExecErrState: rule.ExecErrState.String(),
Annotations: rule.Annotations,
Labels: rule.Labels,
IsPaused: isPaused,
NotificationSettings: ngalertapi.AlertRuleNotificationSettingsFromNotificationSettings(rule.NotificationSettings),
Record: ngalertapi.ApiRecordFromModelRecord(rule.Record),
})
}
alertRuleGroups = append(alertRuleGroups, alertRuleGroup{
Title: ruleGroup.Title,
FolderUID: ruleGroup.FolderUID,
Interval: ruleGroup.Interval,
Rules: provisionedAlertRules,
})
}
return alertRuleGroups, nil
}