2025-04-01 10:38:02 +09:00

242 lines
7.2 KiB
Go

package store
import (
"encoding/json"
"fmt"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/services/ngalert/models"
)
func alertRuleToModelsAlertRule(ar alertRule, l log.Logger) (models.AlertRule, error) {
var data []models.AlertQuery
err := json.Unmarshal([]byte(ar.Data), &data)
if err != nil {
return models.AlertRule{}, fmt.Errorf("failed to parse data: %w", err)
}
result := models.AlertRule{
ID: ar.ID,
OrgID: ar.OrgID,
GUID: ar.GUID,
Title: ar.Title,
Condition: ar.Condition,
Data: data,
Updated: ar.Updated,
IntervalSeconds: ar.IntervalSeconds,
Version: ar.Version,
UID: ar.UID,
NamespaceUID: ar.NamespaceUID,
DashboardUID: ar.DashboardUID,
PanelID: ar.PanelID,
RuleGroup: ar.RuleGroup,
RuleGroupIndex: ar.RuleGroupIndex,
For: ar.For,
IsPaused: ar.IsPaused,
}
if ar.UpdatedBy != nil {
result.UpdatedBy = util.Pointer(models.UserUID(*ar.UpdatedBy))
}
if ar.NoDataState != "" {
result.NoDataState, err = models.NoDataStateFromString(ar.NoDataState)
if err != nil {
l.Warn("Unknown NoDataState value, defaulting to NoData", append(result.GetKey().LogContext(), "original", ar.NoDataState)...)
result.NoDataState = models.NoData
}
}
if ar.ExecErrState != "" {
result.ExecErrState, err = models.ErrStateFromString(ar.ExecErrState)
if err != nil {
l.Warn("Unknown ExecErrState value, defaulting to Error", append(result.GetKey().LogContext(), "original", ar.ExecErrState)...)
result.ExecErrState = models.ErrorErrState
}
}
if ar.Record != "" {
var record models.Record
err = json.Unmarshal([]byte(ar.Record), &record)
if err != nil {
return models.AlertRule{}, fmt.Errorf("failed to parse record: %w", err)
}
result.Record = &record
}
if ar.Labels != "" {
err = json.Unmarshal([]byte(ar.Labels), &result.Labels)
if err != nil {
return models.AlertRule{}, fmt.Errorf("failed to parse labels: %w", err)
}
}
if ar.Annotations != "" {
err = json.Unmarshal([]byte(ar.Annotations), &result.Annotations)
if err != nil {
return models.AlertRule{}, fmt.Errorf("failed to parse annotations: %w", err)
}
}
if ar.NotificationSettings != "" {
ns, err := parseNotificationSettings(ar.NotificationSettings)
if err != nil {
return models.AlertRule{}, fmt.Errorf("failed to parse notification settings: %w", err)
}
result.NotificationSettings = ns
}
if ar.Metadata != "" {
err = json.Unmarshal([]byte(ar.Metadata), &result.Metadata)
if err != nil {
return models.AlertRule{}, fmt.Errorf("failed to metadata: %w", err)
}
}
return result, nil
}
func parseNotificationSettings(s string) ([]models.NotificationSettings, error) {
var result []models.NotificationSettings
if err := json.Unmarshal([]byte(s), &result); err != nil {
return nil, err
}
return result, nil
}
func alertRuleFromModelsAlertRule(ar models.AlertRule) (alertRule, error) {
result := alertRule{
ID: ar.ID,
GUID: ar.GUID,
OrgID: ar.OrgID,
Title: ar.Title,
Condition: ar.Condition,
Updated: ar.Updated,
IntervalSeconds: ar.IntervalSeconds,
Version: ar.Version,
UID: ar.UID,
NamespaceUID: ar.NamespaceUID,
DashboardUID: ar.DashboardUID,
PanelID: ar.PanelID,
RuleGroup: ar.RuleGroup,
RuleGroupIndex: ar.RuleGroupIndex,
NoDataState: ar.NoDataState.String(),
ExecErrState: ar.ExecErrState.String(),
For: ar.For,
IsPaused: ar.IsPaused,
}
if ar.UpdatedBy != nil {
result.UpdatedBy = util.Pointer(string(*ar.UpdatedBy))
}
// Serialize complex types to JSON strings
data, err := json.Marshal(ar.Data)
if err != nil {
return alertRule{}, fmt.Errorf("failed to marshal data: %w", err)
}
result.Data = string(data)
if ar.Record != nil {
recordData, err := json.Marshal(ar.Record)
if err != nil {
return alertRule{}, fmt.Errorf("failed to marshal record: %w", err)
}
result.Record = string(recordData)
}
if len(ar.Annotations) > 0 {
annotationsData, err := json.Marshal(ar.Annotations)
if err != nil {
return alertRule{}, fmt.Errorf("failed to marshal annotations: %w", err)
}
result.Annotations = string(annotationsData)
}
if len(ar.Labels) > 0 {
labelsData, err := json.Marshal(ar.Labels)
if err != nil {
return alertRule{}, fmt.Errorf("failed to marshal labels: %w", err)
}
result.Labels = string(labelsData)
}
if len(ar.NotificationSettings) > 0 {
notificationSettingsData, err := json.Marshal(ar.NotificationSettings)
if err != nil {
return alertRule{}, fmt.Errorf("failed to marshal notification settings: %w", err)
}
result.NotificationSettings = string(notificationSettingsData)
}
metadata, err := json.Marshal(ar.Metadata)
if err != nil {
return alertRule{}, fmt.Errorf("failed to metadata: %w", err)
}
result.Metadata = string(metadata)
return result, nil
}
func alertRuleToAlertRuleVersion(rule alertRule) alertRuleVersion {
return alertRuleVersion{
RuleOrgID: rule.OrgID,
RuleGUID: rule.GUID,
RuleUID: rule.UID,
RuleNamespaceUID: rule.NamespaceUID,
RuleGroup: rule.RuleGroup,
RuleGroupIndex: rule.RuleGroupIndex,
ParentVersion: 0,
RestoredFrom: 0,
Version: rule.Version,
Created: rule.Updated, // assuming the Updated time as the creation time
CreatedBy: rule.UpdatedBy,
Title: rule.Title,
Condition: rule.Condition,
Data: rule.Data,
IntervalSeconds: rule.IntervalSeconds,
Record: rule.Record,
NoDataState: rule.NoDataState,
ExecErrState: rule.ExecErrState,
For: rule.For,
Annotations: rule.Annotations,
Labels: rule.Labels,
IsPaused: rule.IsPaused,
NotificationSettings: rule.NotificationSettings,
Metadata: rule.Metadata,
}
}
func alertRuleVersionToAlertRule(version alertRuleVersion) alertRule {
return alertRule{
ID: version.ID,
GUID: version.RuleGUID,
OrgID: version.RuleOrgID,
Title: version.Title,
Condition: version.Condition,
Data: version.Data,
Updated: version.Created,
UpdatedBy: version.CreatedBy,
IntervalSeconds: version.IntervalSeconds,
Version: version.Version,
UID: version.RuleUID,
NamespaceUID: version.RuleNamespaceUID,
// Versions do not store Dashboard\Panel as separate column.
// However, these fields are part of annotations and information in these fields is redundant
DashboardUID: nil,
PanelID: nil,
RuleGroup: version.RuleGroup,
RuleGroupIndex: version.RuleGroupIndex,
Record: version.Record,
NoDataState: version.NoDataState,
ExecErrState: version.ExecErrState,
For: version.For,
Annotations: version.Annotations,
Labels: version.Labels,
IsPaused: version.IsPaused,
NotificationSettings: version.NotificationSettings,
Metadata: version.Metadata,
}
}