mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: decouple api models from domain\dto models: separate Provenance status + converters (#63594)
* move conversions of domain models to api models and reverse from definition package to api package
This commit is contained in:
parent
dc01e1ee6a
commit
f561e71de8
@ -34,7 +34,7 @@ func checkRoutes(currentConfig apimodels.GettableUserConfig, newConfig apimodels
|
||||
reporter := cmputil.DiffReporter{}
|
||||
options := []cmp.Option{cmp.Reporter(&reporter), cmpopts.EquateEmpty(), cmpopts.IgnoreUnexported(labels.Matcher{})}
|
||||
routesEqual := cmp.Equal(currentConfig.AlertmanagerConfig.Route, newConfig.AlertmanagerConfig.Route, options...)
|
||||
if !routesEqual && currentConfig.AlertmanagerConfig.Route.Provenance != ngmodels.ProvenanceNone {
|
||||
if !routesEqual && currentConfig.AlertmanagerConfig.Route.Provenance != apimodels.Provenance(ngmodels.ProvenanceNone) {
|
||||
return fmt.Errorf("policies were provisioned and cannot be changed through the UI")
|
||||
}
|
||||
return nil
|
||||
@ -44,7 +44,7 @@ func checkTemplates(currentConfig apimodels.GettableUserConfig, newConfig apimod
|
||||
for name, template := range currentConfig.TemplateFiles {
|
||||
provenance := ngmodels.ProvenanceNone
|
||||
if prov, present := currentConfig.TemplateFileProvenances[name]; present {
|
||||
provenance = prov
|
||||
provenance = ngmodels.Provenance(prov)
|
||||
}
|
||||
if provenance == ngmodels.ProvenanceNone {
|
||||
continue // we are only interested in non none
|
||||
@ -76,7 +76,7 @@ func checkContactPoints(currReceivers []*apimodels.GettableApiReceiver, newRecei
|
||||
}
|
||||
for _, existingReceiver := range currReceivers {
|
||||
for _, contactPoint := range existingReceiver.GrafanaManagedReceivers {
|
||||
if contactPoint.Provenance == ngmodels.ProvenanceNone {
|
||||
if contactPoint.Provenance == apimodels.Provenance(ngmodels.ProvenanceNone) {
|
||||
continue // we are only interested in non none
|
||||
}
|
||||
postedContactPoint, present := newCPs[contactPoint.UID]
|
||||
@ -133,7 +133,7 @@ func checkMuteTimes(currentConfig apimodels.GettableUserConfig, newConfig apimod
|
||||
for _, muteTime := range currentConfig.AlertmanagerConfig.MuteTimeIntervals {
|
||||
provenance := ngmodels.ProvenanceNone
|
||||
if prov, present := currentConfig.AlertmanagerConfig.MuteTimeProvenances[muteTime.Name]; present {
|
||||
provenance = prov
|
||||
provenance = ngmodels.Provenance(prov)
|
||||
}
|
||||
if provenance == ngmodels.ProvenanceNone {
|
||||
continue // we are only interested in non none
|
||||
|
@ -65,7 +65,7 @@ func gettableRoute(t *testing.T, provenance models.Provenance) definitions.Getta
|
||||
AlertmanagerConfig: definitions.GettableApiAlertingConfig{
|
||||
Config: definitions.Config{
|
||||
Route: &definitions.Route{
|
||||
Provenance: provenance,
|
||||
Provenance: definitions.Provenance(provenance),
|
||||
Continue: true,
|
||||
GroupBy: []model.LabelName{
|
||||
"...",
|
||||
@ -100,7 +100,7 @@ func postableRoute(t *testing.T, provenace models.Provenance) definitions.Postab
|
||||
AlertmanagerConfig: definitions.PostableApiAlertingConfig{
|
||||
Config: definitions.Config{
|
||||
Route: &definitions.Route{
|
||||
Provenance: provenace,
|
||||
Provenance: definitions.Provenance(provenace),
|
||||
Continue: true,
|
||||
GroupBy: []model.LabelName{
|
||||
"...",
|
||||
@ -199,8 +199,8 @@ func gettableTemplates(t *testing.T, name string, provenance models.Provenance)
|
||||
TemplateFiles: map[string]string{
|
||||
name: "some-template",
|
||||
},
|
||||
TemplateFileProvenances: map[string]models.Provenance{
|
||||
name: provenance,
|
||||
TemplateFileProvenances: map[string]definitions.Provenance{
|
||||
name: definitions.Provenance(provenance),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -315,7 +315,7 @@ func defaultGettableReceiver(t *testing.T, uid string, provenance models.Provena
|
||||
Name: "yeah",
|
||||
Type: "slack",
|
||||
DisableResolveMessage: true,
|
||||
Provenance: provenance,
|
||||
Provenance: definitions.Provenance(provenance),
|
||||
SecureFields: map[string]bool{
|
||||
"url": true,
|
||||
},
|
||||
@ -368,8 +368,8 @@ func TestCheckMuteTimes(t *testing.T) {
|
||||
TimeIntervals: defaultInterval(t),
|
||||
},
|
||||
},
|
||||
map[string]models.Provenance{
|
||||
"test-1": models.ProvenanceNone,
|
||||
map[string]definitions.Provenance{
|
||||
"test-1": definitions.Provenance(models.ProvenanceNone),
|
||||
}),
|
||||
newConfig: postableMuteIntervals(t,
|
||||
[]amConfig.MuteTimeInterval{
|
||||
@ -393,8 +393,8 @@ func TestCheckMuteTimes(t *testing.T) {
|
||||
TimeIntervals: defaultInterval(t),
|
||||
},
|
||||
},
|
||||
map[string]models.Provenance{
|
||||
"test-1": models.ProvenanceNone,
|
||||
map[string]definitions.Provenance{
|
||||
"test-1": definitions.Provenance(models.ProvenanceNone),
|
||||
}),
|
||||
newConfig: postableMuteIntervals(t, []amConfig.MuteTimeInterval{}),
|
||||
},
|
||||
@ -412,8 +412,8 @@ func TestCheckMuteTimes(t *testing.T) {
|
||||
TimeIntervals: defaultInterval(t),
|
||||
},
|
||||
},
|
||||
map[string]models.Provenance{
|
||||
"test-1": models.ProvenanceAPI,
|
||||
map[string]definitions.Provenance{
|
||||
"test-1": definitions.Provenance(models.ProvenanceAPI),
|
||||
}),
|
||||
newConfig: postableMuteIntervals(t, []amConfig.MuteTimeInterval{
|
||||
{
|
||||
@ -432,8 +432,8 @@ func TestCheckMuteTimes(t *testing.T) {
|
||||
TimeIntervals: defaultInterval(t),
|
||||
},
|
||||
},
|
||||
map[string]models.Provenance{
|
||||
"test-1": models.ProvenanceNone,
|
||||
map[string]definitions.Provenance{
|
||||
"test-1": definitions.Provenance(models.ProvenanceNone),
|
||||
}),
|
||||
newConfig: postableMuteIntervals(t,
|
||||
[]amConfig.MuteTimeInterval{
|
||||
@ -457,8 +457,8 @@ func TestCheckMuteTimes(t *testing.T) {
|
||||
TimeIntervals: defaultInterval(t),
|
||||
},
|
||||
},
|
||||
map[string]models.Provenance{
|
||||
"test-1": models.ProvenanceNone,
|
||||
map[string]definitions.Provenance{
|
||||
"test-1": definitions.Provenance(models.ProvenanceNone),
|
||||
}),
|
||||
newConfig: postableMuteIntervals(t,
|
||||
[]amConfig.MuteTimeInterval{
|
||||
@ -487,8 +487,8 @@ func TestCheckMuteTimes(t *testing.T) {
|
||||
TimeIntervals: defaultInterval(t),
|
||||
},
|
||||
},
|
||||
map[string]models.Provenance{
|
||||
"test-1": models.ProvenanceAPI,
|
||||
map[string]definitions.Provenance{
|
||||
"test-1": definitions.Provenance(models.ProvenanceAPI),
|
||||
}),
|
||||
newConfig: postableMuteIntervals(t,
|
||||
[]amConfig.MuteTimeInterval{
|
||||
@ -520,7 +520,7 @@ func TestCheckMuteTimes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func gettableMuteIntervals(t *testing.T, muteTimeIntervals []amConfig.MuteTimeInterval, provenances map[string]models.Provenance) definitions.GettableUserConfig {
|
||||
func gettableMuteIntervals(t *testing.T, muteTimeIntervals []amConfig.MuteTimeInterval, provenances map[string]definitions.Provenance) definitions.GettableUserConfig {
|
||||
return definitions.GettableUserConfig{
|
||||
AlertmanagerConfig: definitions.GettableApiAlertingConfig{
|
||||
MuteTimeProvenances: provenances,
|
||||
|
@ -223,7 +223,7 @@ func TestAlertmanagerConfig(t *testing.T) {
|
||||
response := sut.RouteGetAlertingConfig(rc)
|
||||
|
||||
body := asGettableUserConfig(t, response)
|
||||
require.Equal(t, ngmodels.ProvenanceNone, body.AlertmanagerConfig.Route.Provenance)
|
||||
require.Equal(t, apimodels.Provenance(ngmodels.ProvenanceNone), body.AlertmanagerConfig.Route.Provenance)
|
||||
})
|
||||
t.Run("contact point from GET config has no provenance", func(t *testing.T) {
|
||||
sut := createSut(t, nil)
|
||||
@ -232,7 +232,7 @@ func TestAlertmanagerConfig(t *testing.T) {
|
||||
response := sut.RouteGetAlertingConfig(rc)
|
||||
|
||||
body := asGettableUserConfig(t, response)
|
||||
require.Equal(t, ngmodels.ProvenanceNone, body.AlertmanagerConfig.Receivers[0].GrafanaManagedReceivers[0].Provenance)
|
||||
require.Equal(t, apimodels.Provenance(ngmodels.ProvenanceNone), body.AlertmanagerConfig.Receivers[0].GrafanaManagedReceivers[0].Provenance)
|
||||
})
|
||||
t.Run("templates from GET config have no provenance", func(t *testing.T) {
|
||||
sut := createSut(t, nil)
|
||||
@ -254,7 +254,7 @@ func TestAlertmanagerConfig(t *testing.T) {
|
||||
response := sut.RouteGetAlertingConfig(rc)
|
||||
|
||||
body := asGettableUserConfig(t, response)
|
||||
require.Equal(t, ngmodels.ProvenanceAPI, body.AlertmanagerConfig.Route.Provenance)
|
||||
require.Equal(t, apimodels.Provenance(ngmodels.ProvenanceAPI), body.AlertmanagerConfig.Route.Provenance)
|
||||
})
|
||||
t.Run("contact point from GET config has expected provenance", func(t *testing.T) {
|
||||
sut := createSut(t, nil)
|
||||
@ -274,7 +274,7 @@ func TestAlertmanagerConfig(t *testing.T) {
|
||||
response = sut.RouteGetAlertingConfig(rc)
|
||||
body = asGettableUserConfig(t, response)
|
||||
|
||||
require.Equal(t, ngmodels.ProvenanceAPI, body.AlertmanagerConfig.Receivers[0].GrafanaManagedReceivers[0].Provenance)
|
||||
require.Equal(t, apimodels.Provenance(ngmodels.ProvenanceAPI), body.AlertmanagerConfig.Receivers[0].GrafanaManagedReceivers[0].Provenance)
|
||||
})
|
||||
t.Run("templates from GET config have expected provenance", func(t *testing.T) {
|
||||
sut := createSut(t, nil)
|
||||
@ -286,7 +286,7 @@ func TestAlertmanagerConfig(t *testing.T) {
|
||||
body := asGettableUserConfig(t, response)
|
||||
require.NotNil(t, body.TemplateFileProvenances)
|
||||
require.Len(t, body.TemplateFileProvenances, 1)
|
||||
require.Equal(t, ngmodels.ProvenanceAPI, body.TemplateFileProvenances["a"])
|
||||
require.Equal(t, apimodels.Provenance(ngmodels.ProvenanceAPI), body.TemplateFileProvenances["a"])
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ func (srv *ProvisioningSrv) RoutePutTemplate(c *contextmodel.ReqContext, body de
|
||||
tmpl := definitions.NotificationTemplate{
|
||||
Name: name,
|
||||
Template: body.Template,
|
||||
Provenance: alerting_models.ProvenanceAPI,
|
||||
Provenance: definitions.Provenance(alerting_models.ProvenanceAPI),
|
||||
}
|
||||
modified, err := srv.templates.SetTemplate(c.Req.Context(), c.OrgID, tmpl)
|
||||
if err != nil {
|
||||
@ -219,7 +219,7 @@ func (srv *ProvisioningSrv) RouteGetMuteTimings(c *contextmodel.ReqContext) resp
|
||||
}
|
||||
|
||||
func (srv *ProvisioningSrv) RoutePostMuteTiming(c *contextmodel.ReqContext, mt definitions.MuteTimeInterval) response.Response {
|
||||
mt.Provenance = alerting_models.ProvenanceAPI
|
||||
mt.Provenance = definitions.Provenance(alerting_models.ProvenanceAPI)
|
||||
created, err := srv.muteTimings.CreateMuteTiming(c.Req.Context(), mt, c.OrgID)
|
||||
if err != nil {
|
||||
if errors.Is(err, provisioning.ErrValidation) {
|
||||
@ -232,7 +232,7 @@ func (srv *ProvisioningSrv) RoutePostMuteTiming(c *contextmodel.ReqContext, mt d
|
||||
|
||||
func (srv *ProvisioningSrv) RoutePutMuteTiming(c *contextmodel.ReqContext, mt definitions.MuteTimeInterval, name string) response.Response {
|
||||
mt.Name = name
|
||||
mt.Provenance = alerting_models.ProvenanceAPI
|
||||
mt.Provenance = definitions.Provenance(alerting_models.ProvenanceAPI)
|
||||
updated, err := srv.muteTimings.UpdateMuteTiming(c.Req.Context(), mt, c.OrgID)
|
||||
if err != nil {
|
||||
if errors.Is(err, provisioning.ErrValidation) {
|
||||
@ -259,7 +259,7 @@ func (srv *ProvisioningSrv) RouteGetAlertRules(c *contextmodel.ReqContext) respo
|
||||
if err != nil {
|
||||
return ErrResp(http.StatusInternalServerError, err, "")
|
||||
}
|
||||
return response.JSON(http.StatusOK, definitions.NewAlertRules(rules))
|
||||
return response.JSON(http.StatusOK, ProvisionedAlertRuleFromAlertRules(rules))
|
||||
}
|
||||
|
||||
func (srv *ProvisioningSrv) RouteRouteGetAlertRule(c *contextmodel.ReqContext, UID string) response.Response {
|
||||
@ -267,11 +267,11 @@ func (srv *ProvisioningSrv) RouteRouteGetAlertRule(c *contextmodel.ReqContext, U
|
||||
if err != nil {
|
||||
return ErrResp(http.StatusInternalServerError, err, "")
|
||||
}
|
||||
return response.JSON(http.StatusOK, definitions.NewAlertRule(rule, provenace))
|
||||
return response.JSON(http.StatusOK, ProvisionedAlertRuleFromAlertRule(rule, provenace))
|
||||
}
|
||||
|
||||
func (srv *ProvisioningSrv) RoutePostAlertRule(c *contextmodel.ReqContext, ar definitions.ProvisionedAlertRule) response.Response {
|
||||
upstreamModel, err := ar.UpstreamModel()
|
||||
upstreamModel, err := AlertRuleFromProvisionedAlertRule(ar)
|
||||
upstreamModel.OrgID = c.OrgID
|
||||
if err != nil {
|
||||
return ErrResp(http.StatusBadRequest, err, "")
|
||||
@ -291,12 +291,12 @@ func (srv *ProvisioningSrv) RoutePostAlertRule(c *contextmodel.ReqContext, ar de
|
||||
return ErrResp(http.StatusInternalServerError, err, "")
|
||||
}
|
||||
|
||||
resp := definitions.NewAlertRule(createdAlertRule, provenance)
|
||||
resp := ProvisionedAlertRuleFromAlertRule(createdAlertRule, provenance)
|
||||
return response.JSON(http.StatusCreated, resp)
|
||||
}
|
||||
|
||||
func (srv *ProvisioningSrv) RoutePutAlertRule(c *contextmodel.ReqContext, ar definitions.ProvisionedAlertRule, UID string) response.Response {
|
||||
updated, err := ar.UpstreamModel()
|
||||
updated, err := AlertRuleFromProvisionedAlertRule(ar)
|
||||
if err != nil {
|
||||
ErrResp(http.StatusBadRequest, err, "")
|
||||
}
|
||||
@ -317,7 +317,7 @@ func (srv *ProvisioningSrv) RoutePutAlertRule(c *contextmodel.ReqContext, ar def
|
||||
return ErrResp(http.StatusInternalServerError, err, "")
|
||||
}
|
||||
|
||||
resp := definitions.NewAlertRule(updatedAlertRule, provenance)
|
||||
resp := ProvisionedAlertRuleFromAlertRule(updatedAlertRule, provenance)
|
||||
return response.JSON(http.StatusOK, resp)
|
||||
}
|
||||
|
||||
@ -337,7 +337,7 @@ func (srv *ProvisioningSrv) RouteGetAlertRuleGroup(c *contextmodel.ReqContext, f
|
||||
}
|
||||
return ErrResp(http.StatusInternalServerError, err, "")
|
||||
}
|
||||
return response.JSON(http.StatusOK, definitions.NewAlertRuleGroupFromModel(g))
|
||||
return response.JSON(http.StatusOK, AlertRuleGroupToApi(g))
|
||||
}
|
||||
|
||||
// RouteGetAlertRulesExport retrieves all alert rules in a format compatible with file provisioning.
|
||||
@ -403,7 +403,7 @@ func (srv *ProvisioningSrv) RouteGetAlertRuleExport(c *contextmodel.ReqContext,
|
||||
func (srv *ProvisioningSrv) RoutePutAlertRuleGroup(c *contextmodel.ReqContext, ag definitions.AlertRuleGroup, folderUID string, group string) response.Response {
|
||||
ag.FolderUID = folderUID
|
||||
ag.Title = group
|
||||
groupModel, err := ag.ToModel()
|
||||
groupModel, err := AlertRuleGroupFromApi(ag)
|
||||
if err != nil {
|
||||
ErrResp(http.StatusBadRequest, err, "")
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ func TestProvisioningApi(t *testing.T) {
|
||||
require.Equal(t, 201, response.Status())
|
||||
created := deserializeRule(t, response.Body())
|
||||
require.Equal(t, int64(3), created.OrgID)
|
||||
require.Equal(t, models.ProvenanceNone, created.Provenance)
|
||||
require.Equal(t, definitions.Provenance(models.ProvenanceNone), created.Provenance)
|
||||
})
|
||||
|
||||
t.Run("PUT sets expected fields with no provenance", func(t *testing.T) {
|
||||
@ -293,7 +293,7 @@ func TestProvisioningApi(t *testing.T) {
|
||||
require.Equal(t, 200, response.Status())
|
||||
created := deserializeRule(t, response.Body())
|
||||
require.Equal(t, int64(3), created.OrgID)
|
||||
require.Equal(t, models.ProvenanceNone, created.Provenance)
|
||||
require.Equal(t, definitions.Provenance(models.ProvenanceNone), created.Provenance)
|
||||
})
|
||||
})
|
||||
|
||||
@ -921,7 +921,7 @@ func (f *fakeNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID
|
||||
return definitions.Route{}, store.ErrNoAlertmanagerConfiguration
|
||||
}
|
||||
result := f.tree
|
||||
result.Provenance = f.prov
|
||||
result.Provenance = definitions.Provenance(f.prov)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
@ -481,7 +481,7 @@ func toGettableExtendedRuleNode(r ngmodels.AlertRule, namespaceID int64, provena
|
||||
RuleGroup: r.RuleGroup,
|
||||
NoDataState: apimodels.NoDataState(r.NoDataState),
|
||||
ExecErrState: apimodels.ExecutionErrorState(r.ExecErrState),
|
||||
Provenance: provenance,
|
||||
Provenance: apimodels.Provenance(provenance),
|
||||
IsPaused: r.IsPaused,
|
||||
},
|
||||
}
|
||||
|
@ -367,10 +367,10 @@ func TestRouteGetNamespaceRulesConfig(t *testing.T) {
|
||||
for _, group := range groups {
|
||||
for _, actualRule := range group.Rules {
|
||||
if actualRule.GrafanaManagedAlert.UID == expectedRules[0].UID {
|
||||
require.Equal(t, models.ProvenanceAPI, actualRule.GrafanaManagedAlert.Provenance)
|
||||
require.Equal(t, apimodels.Provenance(models.ProvenanceAPI), actualRule.GrafanaManagedAlert.Provenance)
|
||||
found = true
|
||||
} else {
|
||||
require.Equal(t, models.ProvenanceNone, actualRule.GrafanaManagedAlert.Provenance)
|
||||
require.Equal(t, apimodels.Provenance(models.ProvenanceNone), actualRule.GrafanaManagedAlert.Provenance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
91
pkg/services/ngalert/api/compat.go
Normal file
91
pkg/services/ngalert/api/compat.go
Normal file
@ -0,0 +1,91 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/common/model"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
)
|
||||
|
||||
// AlertRuleFromProvisionedAlertRule converts definitions.ProvisionedAlertRule to models.AlertRule
|
||||
func AlertRuleFromProvisionedAlertRule(a definitions.ProvisionedAlertRule) (models.AlertRule, error) {
|
||||
return models.AlertRule{
|
||||
ID: a.ID,
|
||||
UID: a.UID,
|
||||
OrgID: a.OrgID,
|
||||
NamespaceUID: a.FolderUID,
|
||||
RuleGroup: a.RuleGroup,
|
||||
Title: a.Title,
|
||||
Condition: a.Condition,
|
||||
Data: a.Data,
|
||||
Updated: a.Updated,
|
||||
NoDataState: a.NoDataState,
|
||||
ExecErrState: a.ExecErrState,
|
||||
For: time.Duration(a.For),
|
||||
Annotations: a.Annotations,
|
||||
Labels: a.Labels,
|
||||
IsPaused: a.IsPaused,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ProvisionedAlertRuleFromAlertRule converts models.AlertRule to definitions.ProvisionedAlertRule and sets provided provenance status
|
||||
func ProvisionedAlertRuleFromAlertRule(rule models.AlertRule, provenance models.Provenance) definitions.ProvisionedAlertRule {
|
||||
return definitions.ProvisionedAlertRule{
|
||||
ID: rule.ID,
|
||||
UID: rule.UID,
|
||||
OrgID: rule.OrgID,
|
||||
FolderUID: rule.NamespaceUID,
|
||||
RuleGroup: rule.RuleGroup,
|
||||
Title: rule.Title,
|
||||
For: model.Duration(rule.For),
|
||||
Condition: rule.Condition,
|
||||
Data: rule.Data,
|
||||
Updated: rule.Updated,
|
||||
NoDataState: rule.NoDataState,
|
||||
ExecErrState: rule.ExecErrState,
|
||||
Annotations: rule.Annotations,
|
||||
Labels: rule.Labels,
|
||||
Provenance: definitions.Provenance(provenance), // TODO validate enum conversion?
|
||||
IsPaused: rule.IsPaused,
|
||||
}
|
||||
}
|
||||
|
||||
// ProvisionedAlertRuleFromAlertRules converts a collection of models.AlertRule to definitions.ProvisionedAlertRules with provenance status models.ProvenanceNone
|
||||
func ProvisionedAlertRuleFromAlertRules(rules []*models.AlertRule) definitions.ProvisionedAlertRules {
|
||||
result := make([]definitions.ProvisionedAlertRule, 0, len(rules))
|
||||
for _, r := range rules {
|
||||
result = append(result, ProvisionedAlertRuleFromAlertRule(*r, models.ProvenanceNone))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func AlertRuleGroupFromApi(a definitions.AlertRuleGroup) (models.AlertRuleGroup, error) {
|
||||
ruleGroup := models.AlertRuleGroup{
|
||||
Title: a.Title,
|
||||
FolderUID: a.FolderUID,
|
||||
Interval: a.Interval,
|
||||
}
|
||||
for i := range a.Rules {
|
||||
converted, err := AlertRuleFromProvisionedAlertRule(a.Rules[i])
|
||||
if err != nil {
|
||||
return models.AlertRuleGroup{}, err
|
||||
}
|
||||
ruleGroup.Rules = append(ruleGroup.Rules, converted)
|
||||
}
|
||||
return ruleGroup, nil
|
||||
}
|
||||
|
||||
func AlertRuleGroupToApi(d models.AlertRuleGroup) definitions.AlertRuleGroup {
|
||||
rules := make([]definitions.ProvisionedAlertRule, 0, len(d.Rules))
|
||||
for i := range d.Rules {
|
||||
rules = append(rules, ProvisionedAlertRuleFromAlertRule(d.Rules[i], d.Provenance))
|
||||
}
|
||||
return definitions.AlertRuleGroup{
|
||||
Title: d.Title,
|
||||
FolderUID: d.FolderUID,
|
||||
Interval: d.Interval,
|
||||
Rules: rules,
|
||||
}
|
||||
}
|
@ -1,34 +1,36 @@
|
||||
package definitions
|
||||
package api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
)
|
||||
|
||||
func TestToModel(t *testing.T) {
|
||||
t.Run("if no rules are provided the rule field should be nil", func(t *testing.T) {
|
||||
ruleGroup := AlertRuleGroup{
|
||||
ruleGroup := definitions.AlertRuleGroup{
|
||||
Title: "123",
|
||||
FolderUID: "123",
|
||||
Interval: 10,
|
||||
}
|
||||
tm, err := ruleGroup.ToModel()
|
||||
tm, err := AlertRuleGroupFromApi(ruleGroup)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, tm.Rules)
|
||||
})
|
||||
t.Run("if rules are provided the rule field should be not nil", func(t *testing.T) {
|
||||
ruleGroup := AlertRuleGroup{
|
||||
ruleGroup := definitions.AlertRuleGroup{
|
||||
Title: "123",
|
||||
FolderUID: "123",
|
||||
Interval: 10,
|
||||
Rules: []ProvisionedAlertRule{
|
||||
Rules: []definitions.ProvisionedAlertRule{
|
||||
{
|
||||
UID: "1",
|
||||
},
|
||||
},
|
||||
}
|
||||
tm, err := ruleGroup.ToModel()
|
||||
tm, err := AlertRuleGroupFromApi(ruleGroup)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, tm.Rules, 1)
|
||||
})
|
@ -17,7 +17,6 @@ import (
|
||||
"github.com/prometheus/common/model"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
"github.com/grafana/grafana/pkg/services/secrets"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
@ -567,11 +566,13 @@ func (c *PostableUserConfig) UnmarshalYAML(value *yaml.Node) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Provenance string
|
||||
|
||||
// swagger:model
|
||||
type GettableUserConfig struct {
|
||||
TemplateFiles map[string]string `yaml:"template_files" json:"template_files"`
|
||||
TemplateFileProvenances map[string]models.Provenance `yaml:"template_file_provenances,omitempty" json:"template_file_provenances,omitempty"`
|
||||
AlertmanagerConfig GettableApiAlertingConfig `yaml:"alertmanager_config" json:"alertmanager_config"`
|
||||
TemplateFiles map[string]string `yaml:"template_files" json:"template_files"`
|
||||
TemplateFileProvenances map[string]Provenance `yaml:"template_file_provenances,omitempty" json:"template_file_provenances,omitempty"`
|
||||
AlertmanagerConfig GettableApiAlertingConfig `yaml:"alertmanager_config" json:"alertmanager_config"`
|
||||
|
||||
// amSimple stores a map[string]interface of the decoded alertmanager config.
|
||||
// This enables circumventing the underlying alertmanager secret type
|
||||
@ -635,7 +636,7 @@ func (c *GettableUserConfig) GetGrafanaReceiverMap() map[string]*GettableGrafana
|
||||
|
||||
type GettableApiAlertingConfig struct {
|
||||
Config `yaml:",inline"`
|
||||
MuteTimeProvenances map[string]models.Provenance `yaml:"muteTimeProvenances,omitempty" json:"muteTimeProvenances,omitempty"`
|
||||
MuteTimeProvenances map[string]Provenance `yaml:"muteTimeProvenances,omitempty" json:"muteTimeProvenances,omitempty"`
|
||||
// Override with our superset receiver type
|
||||
Receivers []*GettableApiReceiver `yaml:"receivers,omitempty" json:"receivers,omitempty"`
|
||||
}
|
||||
@ -722,7 +723,7 @@ type Route struct {
|
||||
GroupInterval *model.Duration `yaml:"group_interval,omitempty" json:"group_interval,omitempty"`
|
||||
RepeatInterval *model.Duration `yaml:"repeat_interval,omitempty" json:"repeat_interval,omitempty"`
|
||||
|
||||
Provenance models.Provenance `yaml:"provenance,omitempty" json:"provenance,omitempty"`
|
||||
Provenance Provenance `yaml:"provenance,omitempty" json:"provenance,omitempty"`
|
||||
}
|
||||
|
||||
// UnmarshalYAML implements the yaml.Unmarshaler interface for Route. This is a copy of alertmanager's upstream except it removes validation on the label key.
|
||||
@ -1006,13 +1007,13 @@ func (r RawMessage) MarshalYAML() (interface{}, error) {
|
||||
}
|
||||
|
||||
type GettableGrafanaReceiver struct {
|
||||
UID string `json:"uid"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
DisableResolveMessage bool `json:"disableResolveMessage"`
|
||||
Settings RawMessage `json:"settings,omitempty"`
|
||||
SecureFields map[string]bool `json:"secureFields"`
|
||||
Provenance models.Provenance `json:"provenance,omitempty"`
|
||||
UID string `json:"uid"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
DisableResolveMessage bool `json:"disableResolveMessage"`
|
||||
Settings RawMessage `json:"settings,omitempty"`
|
||||
SecureFields map[string]bool `json:"secureFields"`
|
||||
Provenance Provenance `json:"provenance,omitempty"`
|
||||
}
|
||||
|
||||
type PostableGrafanaReceiver struct {
|
||||
|
@ -393,6 +393,6 @@ type GettableGrafanaRule struct {
|
||||
RuleGroup string `json:"rule_group" yaml:"rule_group"`
|
||||
NoDataState NoDataState `json:"no_data_state" yaml:"no_data_state"`
|
||||
ExecErrState ExecutionErrorState `json:"exec_err_state" yaml:"exec_err_state"`
|
||||
Provenance models.Provenance `json:"provenance,omitempty" yaml:"provenance,omitempty"`
|
||||
Provenance Provenance `json:"provenance,omitempty" yaml:"provenance,omitempty"`
|
||||
IsPaused bool `json:"is_paused" yaml:"is_paused"`
|
||||
}
|
||||
|
@ -133,60 +133,11 @@ type ProvisionedAlertRule struct {
|
||||
// example: {"team": "sre-team-1"}
|
||||
Labels map[string]string `json:"labels,omitempty"`
|
||||
// readonly: true
|
||||
Provenance models.Provenance `json:"provenance,omitempty"`
|
||||
Provenance Provenance `json:"provenance,omitempty"`
|
||||
// example: false
|
||||
IsPaused bool `json:"isPaused"`
|
||||
}
|
||||
|
||||
func (a *ProvisionedAlertRule) UpstreamModel() (models.AlertRule, error) {
|
||||
return models.AlertRule{
|
||||
ID: a.ID,
|
||||
UID: a.UID,
|
||||
OrgID: a.OrgID,
|
||||
NamespaceUID: a.FolderUID,
|
||||
RuleGroup: a.RuleGroup,
|
||||
Title: a.Title,
|
||||
Condition: a.Condition,
|
||||
Data: a.Data,
|
||||
Updated: a.Updated,
|
||||
NoDataState: a.NoDataState,
|
||||
ExecErrState: a.ExecErrState,
|
||||
For: time.Duration(a.For),
|
||||
Annotations: a.Annotations,
|
||||
Labels: a.Labels,
|
||||
IsPaused: a.IsPaused,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewAlertRule(rule models.AlertRule, provenance models.Provenance) ProvisionedAlertRule {
|
||||
return ProvisionedAlertRule{
|
||||
ID: rule.ID,
|
||||
UID: rule.UID,
|
||||
OrgID: rule.OrgID,
|
||||
FolderUID: rule.NamespaceUID,
|
||||
RuleGroup: rule.RuleGroup,
|
||||
Title: rule.Title,
|
||||
For: model.Duration(rule.For),
|
||||
Condition: rule.Condition,
|
||||
Data: rule.Data,
|
||||
Updated: rule.Updated,
|
||||
NoDataState: rule.NoDataState,
|
||||
ExecErrState: rule.ExecErrState,
|
||||
Annotations: rule.Annotations,
|
||||
Labels: rule.Labels,
|
||||
Provenance: provenance,
|
||||
IsPaused: rule.IsPaused,
|
||||
}
|
||||
}
|
||||
|
||||
func NewAlertRules(rules []*models.AlertRule) ProvisionedAlertRules {
|
||||
result := make([]ProvisionedAlertRule, 0, len(rules))
|
||||
for _, r := range rules {
|
||||
result = append(result, NewAlertRule(*r, models.ProvenanceNone))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// swagger:route GET /api/v1/provisioning/folder/{FolderUID}/rule-groups/{Group} provisioning stable RouteGetAlertRuleGroup
|
||||
//
|
||||
// Get a rule group.
|
||||
@ -268,32 +219,3 @@ type AlertRuleGroup struct {
|
||||
// AlertingFileExport is the full provisioned file export.
|
||||
// swagger:model
|
||||
type AlertingFileExport = file.AlertingFileExport
|
||||
|
||||
func (a *AlertRuleGroup) ToModel() (models.AlertRuleGroup, error) {
|
||||
ruleGroup := models.AlertRuleGroup{
|
||||
Title: a.Title,
|
||||
FolderUID: a.FolderUID,
|
||||
Interval: a.Interval,
|
||||
}
|
||||
for i := range a.Rules {
|
||||
converted, err := a.Rules[i].UpstreamModel()
|
||||
if err != nil {
|
||||
return models.AlertRuleGroup{}, err
|
||||
}
|
||||
ruleGroup.Rules = append(ruleGroup.Rules, converted)
|
||||
}
|
||||
return ruleGroup, nil
|
||||
}
|
||||
|
||||
func NewAlertRuleGroupFromModel(d models.AlertRuleGroup) AlertRuleGroup {
|
||||
rules := make([]ProvisionedAlertRule, 0, len(d.Rules))
|
||||
for i := range d.Rules {
|
||||
rules = append(rules, NewAlertRule(d.Rules[i], d.Provenance))
|
||||
}
|
||||
return AlertRuleGroup{
|
||||
Title: d.Title,
|
||||
FolderUID: d.FolderUID,
|
||||
Interval: d.Interval,
|
||||
Rules: rules,
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,6 @@ package definitions
|
||||
|
||||
import (
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
)
|
||||
|
||||
// swagger:route GET /api/v1/provisioning/mute-timings provisioning stable RouteGetMuteTimings
|
||||
@ -71,7 +69,7 @@ type MuteTimingPayload struct {
|
||||
// swagger:model
|
||||
type MuteTimeInterval struct {
|
||||
config.MuteTimeInterval `json:",inline" yaml:",inline"`
|
||||
Provenance models.Provenance `json:"provenance,omitempty"`
|
||||
Provenance Provenance `json:"provenance,omitempty"`
|
||||
}
|
||||
|
||||
func (mt *MuteTimeInterval) ResourceType() string {
|
||||
|
@ -1,9 +1,5 @@
|
||||
package definitions
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
)
|
||||
|
||||
// swagger:route GET /api/v1/provisioning/templates provisioning stable RouteGetTemplates
|
||||
//
|
||||
// Get all notification templates.
|
||||
@ -47,9 +43,9 @@ type RouteGetTemplateParam struct {
|
||||
|
||||
// swagger:model
|
||||
type NotificationTemplate struct {
|
||||
Name string `json:"name"`
|
||||
Template string `json:"template"`
|
||||
Provenance models.Provenance `json:"provenance,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Template string `json:"template"`
|
||||
Provenance Provenance `json:"provenance,omitempty"`
|
||||
}
|
||||
|
||||
// swagger:model
|
||||
|
@ -129,7 +129,7 @@ func (moa *MultiOrgAlertmanager) mergeProvenance(ctx context.Context, config def
|
||||
if err != nil {
|
||||
return definitions.GettableUserConfig{}, err
|
||||
}
|
||||
config.AlertmanagerConfig.Route.Provenance = provenance
|
||||
config.AlertmanagerConfig.Route.Provenance = definitions.Provenance(provenance)
|
||||
}
|
||||
|
||||
cp := definitions.EmbeddedContactPoint{}
|
||||
@ -140,7 +140,7 @@ func (moa *MultiOrgAlertmanager) mergeProvenance(ctx context.Context, config def
|
||||
for _, receiver := range config.AlertmanagerConfig.Receivers {
|
||||
for _, contactPoint := range receiver.GrafanaManagedReceivers {
|
||||
if provenance, exists := cpProvs[contactPoint.UID]; exists {
|
||||
contactPoint.Provenance = provenance
|
||||
contactPoint.Provenance = definitions.Provenance(provenance)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -150,14 +150,20 @@ func (moa *MultiOrgAlertmanager) mergeProvenance(ctx context.Context, config def
|
||||
if err != nil {
|
||||
return definitions.GettableUserConfig{}, nil
|
||||
}
|
||||
config.TemplateFileProvenances = tmplProvs
|
||||
config.TemplateFileProvenances = make(map[string]definitions.Provenance, len(tmplProvs))
|
||||
for key, provenance := range tmplProvs {
|
||||
config.TemplateFileProvenances[key] = definitions.Provenance(provenance)
|
||||
}
|
||||
|
||||
mt := definitions.MuteTimeInterval{}
|
||||
mtProvs, err := moa.ProvStore.GetProvenances(ctx, org, mt.ResourceType())
|
||||
if err != nil {
|
||||
return definitions.GettableUserConfig{}, nil
|
||||
}
|
||||
config.AlertmanagerConfig.MuteTimeProvenances = mtProvs
|
||||
config.AlertmanagerConfig.MuteTimeProvenances = make(map[string]definitions.Provenance, len(mtProvs))
|
||||
for key, provenance := range mtProvs {
|
||||
config.AlertmanagerConfig.MuteTimeProvenances[key] = definitions.Provenance(provenance)
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ func (svc *MuteTimingService) CreateMuteTiming(ctx context.Context, mt definitio
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = svc.prov.SetProvenance(ctx, &mt, orgID, mt.Provenance)
|
||||
err = svc.prov.SetProvenance(ctx, &mt, orgID, models.Provenance(mt.Provenance))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -137,7 +137,7 @@ func (svc *MuteTimingService) UpdateMuteTiming(ctx context.Context, mt definitio
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = svc.prov.SetProvenance(ctx, &mt, orgID, mt.Provenance)
|
||||
err = svc.prov.SetProvenance(ctx, &mt, orgID, models.Provenance(mt.Provenance))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ func (nps *NotificationPolicyService) GetPolicyTree(ctx context.Context, orgID i
|
||||
}
|
||||
|
||||
result := *cfg.AlertmanagerConfig.Route
|
||||
result.Provenance = provenance
|
||||
result.Provenance = definitions.Provenance(provenance)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ func TestNotificationPolicyService(t *testing.T) {
|
||||
tree, err := sut.GetPolicyTree(context.Background(), 1)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, models.ProvenanceNone, tree.Provenance)
|
||||
require.Equal(t, models.ProvenanceNone, models.Provenance(tree.Provenance))
|
||||
})
|
||||
|
||||
t.Run("service returns upgraded provenance value", func(t *testing.T) {
|
||||
@ -158,7 +158,7 @@ func TestNotificationPolicyService(t *testing.T) {
|
||||
|
||||
updated, err := sut.GetPolicyTree(context.Background(), 1)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, models.ProvenanceAPI, updated.Provenance)
|
||||
require.Equal(t, models.ProvenanceAPI, models.Provenance(updated.Provenance))
|
||||
})
|
||||
|
||||
t.Run("service respects concurrency token when updating", func(t *testing.T) {
|
||||
|
@ -70,7 +70,7 @@ func (t *TemplateService) SetTemplate(ctx context.Context, orgID int64, tmpl def
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = t.prov.SetProvenance(ctx, &tmpl, orgID, tmpl.Provenance)
|
||||
err = t.prov.SetProvenance(ctx, &tmpl, orgID, models.Provenance(tmpl.Provenance))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ func (c *defaultMuteTimesProvisioner) Provision(ctx context.Context,
|
||||
cache[muteTiming.OrgID][interval.Name] = interval
|
||||
}
|
||||
}
|
||||
muteTiming.MuteTime.Provenance = models.ProvenanceFile
|
||||
muteTiming.MuteTime.Provenance = definitions.Provenance(models.ProvenanceFile)
|
||||
if _, exists := cache[muteTiming.OrgID][muteTiming.MuteTime.Name]; exists {
|
||||
_, err := c.muteTimingService.UpdateMuteTiming(ctx, muteTiming.MuteTime, muteTiming.OrgID)
|
||||
if err != nil {
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"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/provisioning"
|
||||
)
|
||||
@ -30,7 +31,7 @@ func (c *defaultTextTemplateProvisioner) Provision(ctx context.Context,
|
||||
files []*AlertingFile) error {
|
||||
for _, file := range files {
|
||||
for _, template := range file.Templates {
|
||||
template.Data.Provenance = models.ProvenanceFile
|
||||
template.Data.Provenance = definitions.Provenance(models.ProvenanceFile)
|
||||
_, err := c.templateService.SetTemplate(ctx, template.OrgID, template.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
|
Loading…
Reference in New Issue
Block a user