1package models
2
3import (
4	"fmt"
5	"time"
6
7	"github.com/grafana/grafana/pkg/components/simplejson"
8)
9
10type AlertStateType string
11type NoDataOption string
12type ExecutionErrorOption string
13
14const (
15	AlertStateNoData   AlertStateType = "no_data"
16	AlertStatePaused   AlertStateType = "paused"
17	AlertStateAlerting AlertStateType = "alerting"
18	AlertStateOK       AlertStateType = "ok"
19	AlertStatePending  AlertStateType = "pending"
20	AlertStateUnknown  AlertStateType = "unknown"
21)
22
23const (
24	NoDataSetOK       NoDataOption = "ok"
25	NoDataSetNoData   NoDataOption = "no_data"
26	NoDataKeepState   NoDataOption = "keep_state"
27	NoDataSetAlerting NoDataOption = "alerting"
28)
29
30const (
31	ExecutionErrorSetAlerting ExecutionErrorOption = "alerting"
32	ExecutionErrorKeepState   ExecutionErrorOption = "keep_state"
33)
34
35var (
36	ErrCannotChangeStateOnPausedAlert = fmt.Errorf("cannot change state on pause alert")
37	ErrRequiresNewState               = fmt.Errorf("update alert state requires a new state")
38)
39
40func (s AlertStateType) IsValid() bool {
41	return s == AlertStateOK ||
42		s == AlertStateNoData ||
43		s == AlertStatePaused ||
44		s == AlertStatePending ||
45		s == AlertStateAlerting ||
46		s == AlertStateUnknown
47}
48
49func (s NoDataOption) IsValid() bool {
50	return s == NoDataSetNoData || s == NoDataSetAlerting || s == NoDataKeepState || s == NoDataSetOK
51}
52
53func (s NoDataOption) ToAlertState() AlertStateType {
54	return AlertStateType(s)
55}
56
57func (s ExecutionErrorOption) IsValid() bool {
58	return s == ExecutionErrorSetAlerting || s == ExecutionErrorKeepState
59}
60
61func (s ExecutionErrorOption) ToAlertState() AlertStateType {
62	return AlertStateType(s)
63}
64
65type Alert struct {
66	Id             int64
67	Version        int64
68	OrgId          int64
69	DashboardId    int64
70	PanelId        int64
71	Name           string
72	Message        string
73	Severity       string // Unused
74	State          AlertStateType
75	Handler        int64 // Unused
76	Silenced       bool
77	ExecutionError string
78	Frequency      int64
79	For            time.Duration
80
81	EvalData     *simplejson.Json
82	NewStateDate time.Time
83	StateChanges int64
84
85	Created time.Time
86	Updated time.Time
87
88	Settings *simplejson.Json
89}
90
91func (a *Alert) ValidToSave() bool {
92	return a.DashboardId != 0 && a.OrgId != 0 && a.PanelId != 0
93}
94
95func (a *Alert) ContainsUpdates(other *Alert) bool {
96	result := false
97	result = result || a.Name != other.Name
98	result = result || a.Message != other.Message
99
100	if a.Settings != nil && other.Settings != nil {
101		json1, err1 := a.Settings.Encode()
102		json2, err2 := other.Settings.Encode()
103
104		if err1 != nil || err2 != nil {
105			return false
106		}
107
108		result = result || string(json1) != string(json2)
109	}
110
111	// don't compare .State! That would be insane.
112	return result
113}
114
115func (a *Alert) GetTagsFromSettings() []*Tag {
116	tags := []*Tag{}
117	if a.Settings != nil {
118		if data, ok := a.Settings.CheckGet("alertRuleTags"); ok {
119			for tagNameString, tagValue := range data.MustMap() {
120				// MustMap() already guarantees the return of a `map[string]interface{}`.
121				// Therefore we only need to verify that tagValue is a String.
122				tagValueString := simplejson.NewFromAny(tagValue).MustString()
123				tags = append(tags, &Tag{Key: tagNameString, Value: tagValueString})
124			}
125		}
126	}
127	return tags
128}
129
130type SaveAlertsCommand struct {
131	DashboardId int64
132	UserId      int64
133	OrgId       int64
134
135	Alerts []*Alert
136}
137
138type PauseAlertCommand struct {
139	OrgId       int64
140	AlertIds    []int64
141	ResultCount int64
142	Paused      bool
143}
144
145type PauseAllAlertCommand struct {
146	ResultCount int64
147	Paused      bool
148}
149
150type SetAlertStateCommand struct {
151	AlertId  int64
152	OrgId    int64
153	State    AlertStateType
154	Error    string
155	EvalData *simplejson.Json
156
157	Result Alert
158}
159
160// Queries
161type GetAlertsQuery struct {
162	OrgId        int64
163	State        []string
164	DashboardIDs []int64
165	PanelId      int64
166	Limit        int64
167	Query        string
168	User         *SignedInUser
169
170	Result []*AlertListItemDTO
171}
172
173type GetAllAlertsQuery struct {
174	Result []*Alert
175}
176
177type GetAlertByIdQuery struct {
178	Id int64
179
180	Result *Alert
181}
182
183type GetAlertStatesForDashboardQuery struct {
184	OrgId       int64
185	DashboardId int64
186
187	Result []*AlertStateInfoDTO
188}
189
190type AlertListItemDTO struct {
191	Id             int64            `json:"id"`
192	DashboardId    int64            `json:"dashboardId"`
193	DashboardUid   string           `json:"dashboardUid"`
194	DashboardSlug  string           `json:"dashboardSlug"`
195	PanelId        int64            `json:"panelId"`
196	Name           string           `json:"name"`
197	State          AlertStateType   `json:"state"`
198	NewStateDate   time.Time        `json:"newStateDate"`
199	EvalDate       time.Time        `json:"evalDate"`
200	EvalData       *simplejson.Json `json:"evalData"`
201	ExecutionError string           `json:"executionError"`
202	Url            string           `json:"url"`
203}
204
205type AlertStateInfoDTO struct {
206	Id           int64          `json:"id"`
207	DashboardId  int64          `json:"dashboardId"`
208	PanelId      int64          `json:"panelId"`
209	State        AlertStateType `json:"state"`
210	NewStateDate time.Time      `json:"newStateDate"`
211}
212