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:
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
package definitions
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestToModel(t *testing.T) {
|
||||
t.Run("if no rules are provided the rule field should be nil", func(t *testing.T) {
|
||||
ruleGroup := AlertRuleGroup{
|
||||
Title: "123",
|
||||
FolderUID: "123",
|
||||
Interval: 10,
|
||||
}
|
||||
tm, err := ruleGroup.ToModel()
|
||||
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{
|
||||
Title: "123",
|
||||
FolderUID: "123",
|
||||
Interval: 10,
|
||||
Rules: []ProvisionedAlertRule{
|
||||
{
|
||||
UID: "1",
|
||||
},
|
||||
},
|
||||
}
|
||||
tm, err := ruleGroup.ToModel()
|
||||
require.NoError(t, err)
|
||||
require.Len(t, tm.Rules, 1)
|
||||
})
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user