mirror of
https://github.com/grafana/grafana.git
synced 2025-02-10 23:55:47 -06:00
Alerting: Add file provisioning for text templates (#52952)
This commit is contained in:
parent
3d39594d75
commit
8fc8d00167
@ -29,6 +29,9 @@ const (
|
||||
testFileCorrectProperties_mt = "./testdata/mute_times/correct-properties"
|
||||
testFileCorrectPropertiesWithOrg_mt = "./testdata/mute_times/correct-properties-with-org"
|
||||
testFileMultipleMts = "./testdata/mute_times/multiple-mute-times"
|
||||
testFileCorrectProperties_t = "./testdata/templates/correct-properties"
|
||||
testFileCorrectPropertiesWithOrg_t = "./testdata/templates/correct-properties-with-org"
|
||||
testFileMultipleTs = "./testdata/templates/multiple-templates"
|
||||
)
|
||||
|
||||
func TestConfigReader(t *testing.T) {
|
||||
@ -138,4 +141,20 @@ func TestConfigReader(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, file[0].MuteTimes, 2)
|
||||
})
|
||||
t.Run("a template file with correct properties and specific org should not error", func(t *testing.T) {
|
||||
_, err := configReader.readConfig(ctx, testFileCorrectProperties_t)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
t.Run("a template file with correct properties and specific org should not error", func(t *testing.T) {
|
||||
file, err := configReader.readConfig(ctx, testFileCorrectPropertiesWithOrg_t)
|
||||
require.NoError(t, err)
|
||||
t.Run("when an organization is set it should not overwrite it with the default of 1", func(t *testing.T) {
|
||||
require.Equal(t, int64(1337), file[0].Templates[0].OrgID)
|
||||
})
|
||||
})
|
||||
t.Run("the config reader should be able to read a file with multiple mute times", func(t *testing.T) {
|
||||
file, err := configReader.readConfig(ctx, testFileMultipleTs)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, file[0].Templates, 2)
|
||||
})
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ type ProvisionerConfig struct {
|
||||
ContactPointService provisioning.ContactPointService
|
||||
NotificiationPolicyService provisioning.NotificationPolicyService
|
||||
MuteTimingService provisioning.MuteTimingService
|
||||
TemplateService provisioning.TemplateService
|
||||
}
|
||||
|
||||
func Provision(ctx context.Context, cfg ProvisionerConfig) error {
|
||||
@ -47,6 +48,11 @@ func Provision(ctx context.Context, cfg ProvisionerConfig) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("mute times: %w", err)
|
||||
}
|
||||
ttProvsioner := NewTextTemplateProvisioner(logger, cfg.TemplateService)
|
||||
err = ttProvsioner.Provision(ctx, files)
|
||||
if err != nil {
|
||||
return fmt.Errorf("text templates: %w", err)
|
||||
}
|
||||
npProvisioner := NewNotificationPolicyProvisoner(logger, cfg.NotificiationPolicyService)
|
||||
err = npProvisioner.Provision(ctx, files)
|
||||
if err != nil {
|
||||
@ -64,6 +70,10 @@ func Provision(ctx context.Context, cfg ProvisionerConfig) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("mute times: %w", err)
|
||||
}
|
||||
err = ttProvsioner.Unprovision(ctx, files)
|
||||
if err != nil {
|
||||
return fmt.Errorf("text templates: %w", err)
|
||||
}
|
||||
logger.Info("finished to provision alerting")
|
||||
return nil
|
||||
}
|
||||
|
@ -0,0 +1,5 @@
|
||||
apiVersion: 1
|
||||
templates:
|
||||
- orgId: 1337
|
||||
name: my_first_template
|
||||
template: "test"
|
4
pkg/services/provisioning/alerting/testdata/templates/correct-properties/mute_times.yml
vendored
Normal file
4
pkg/services/provisioning/alerting/testdata/templates/correct-properties/mute_times.yml
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
apiVersion: 1
|
||||
templates:
|
||||
- name: my_first_template
|
||||
template: "test"
|
7
pkg/services/provisioning/alerting/testdata/templates/multiple-templates/mute_times.yml
vendored
Normal file
7
pkg/services/provisioning/alerting/testdata/templates/multiple-templates/mute_times.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
apiVersion: 1
|
||||
templates:
|
||||
- orgId: 1337
|
||||
name: my_first_template
|
||||
template: "test"
|
||||
- name: my_second_template
|
||||
template: "test"
|
54
pkg/services/provisioning/alerting/text_templates.go
Normal file
54
pkg/services/provisioning/alerting/text_templates.go
Normal file
@ -0,0 +1,54 @@
|
||||
package alerting
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
|
||||
)
|
||||
|
||||
type TextTemplateProvisioner interface {
|
||||
Provision(ctx context.Context, files []*AlertingFile) error
|
||||
Unprovision(ctx context.Context, files []*AlertingFile) error
|
||||
}
|
||||
|
||||
type defaultTextTemplateProvisioner struct {
|
||||
logger log.Logger
|
||||
templateService provisioning.TemplateService
|
||||
}
|
||||
|
||||
func NewTextTemplateProvisioner(logger log.Logger,
|
||||
templateService provisioning.TemplateService) TextTemplateProvisioner {
|
||||
return &defaultTextTemplateProvisioner{
|
||||
logger: logger,
|
||||
templateService: templateService,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *defaultTextTemplateProvisioner) Provision(ctx context.Context,
|
||||
files []*AlertingFile) error {
|
||||
for _, file := range files {
|
||||
for _, template := range file.Templates {
|
||||
template.Data.Provenance = models.ProvenanceFile
|
||||
_, err := c.templateService.SetTemplate(ctx, template.OrgID, template.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *defaultTextTemplateProvisioner) Unprovision(ctx context.Context,
|
||||
files []*AlertingFile) error {
|
||||
for _, file := range files {
|
||||
for _, deleteTemplate := range file.DeleteTemplates {
|
||||
err := c.templateService.DeleteTemplate(ctx, deleteTemplate.OrgID, deleteTemplate.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
55
pkg/services/provisioning/alerting/text_templates_types.go
Normal file
55
pkg/services/provisioning/alerting/text_templates_types.go
Normal file
@ -0,0 +1,55 @@
|
||||
package alerting
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/values"
|
||||
)
|
||||
|
||||
type TemplateV1 struct {
|
||||
OrgID values.Int64Value `json:"orgId" yaml:"orgId"`
|
||||
Template definitions.MessageTemplate `json:",inline" yaml:",inline"`
|
||||
}
|
||||
|
||||
func (v1 *TemplateV1) mapToModel() Template {
|
||||
orgID := v1.OrgID.Value()
|
||||
if orgID < 1 {
|
||||
orgID = 1
|
||||
}
|
||||
return Template{
|
||||
Data: v1.Template,
|
||||
OrgID: orgID,
|
||||
}
|
||||
}
|
||||
|
||||
type Template struct {
|
||||
OrgID int64
|
||||
Data definitions.MessageTemplate
|
||||
}
|
||||
|
||||
type DeleteTemplateV1 struct {
|
||||
OrgID values.Int64Value `json:"orgId" yaml:"orgId"`
|
||||
Name values.StringValue `json:"name" yaml:"name"`
|
||||
}
|
||||
|
||||
func (v1 *DeleteTemplateV1) mapToModel() (DeleteTemplate, error) {
|
||||
name := strings.TrimSpace(v1.Name.Value())
|
||||
if name == "" {
|
||||
return DeleteTemplate{}, errors.New("delete template missing name")
|
||||
}
|
||||
orgID := v1.OrgID.Value()
|
||||
if orgID < 1 {
|
||||
orgID = 1
|
||||
}
|
||||
return DeleteTemplate{
|
||||
Name: name,
|
||||
OrgID: orgID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type DeleteTemplate struct {
|
||||
OrgID int64
|
||||
Name string
|
||||
}
|
@ -23,6 +23,8 @@ type AlertingFile struct {
|
||||
ResetPolicies []OrgID
|
||||
MuteTimes []MuteTime
|
||||
DeleteMuteTimes []DeleteMuteTime
|
||||
Templates []Template
|
||||
DeleteTemplates []DeleteTemplate
|
||||
}
|
||||
|
||||
type AlertingFileV1 struct {
|
||||
@ -36,6 +38,8 @@ type AlertingFileV1 struct {
|
||||
ResetPolicies []values.Int64Value `json:"resetPolicies" yaml:"resetPolicies"`
|
||||
MuteTimes []MuteTimeV1 `json:"muteTimes" yaml:"muteTimes"`
|
||||
DeleteMuteTimes []DeleteMuteTimeV1 `json:"deleteMuteTimes" yaml:"deleteMuteTimes"`
|
||||
Templates []TemplateV1 `json:"templates" yaml:"templates"`
|
||||
DeleteTemplates []DeleteTemplateV1 `json:"deleteTemplates" yaml:"deleteTemplates"`
|
||||
}
|
||||
|
||||
func (fileV1 *AlertingFileV1) MapToModel() (AlertingFile, error) {
|
||||
@ -51,9 +55,26 @@ func (fileV1 *AlertingFileV1) MapToModel() (AlertingFile, error) {
|
||||
if err := fileV1.mapMuteTimes(&alertingFile); err != nil {
|
||||
return AlertingFile{}, fmt.Errorf("failure parsing mute times: %w", err)
|
||||
}
|
||||
if err := fileV1.mapTemplates(&alertingFile); err != nil {
|
||||
return AlertingFile{}, fmt.Errorf("failure parsing templates: %w", err)
|
||||
}
|
||||
return alertingFile, nil
|
||||
}
|
||||
|
||||
func (fileV1 *AlertingFileV1) mapTemplates(alertingFile *AlertingFile) error {
|
||||
for _, ttV1 := range fileV1.Templates {
|
||||
alertingFile.Templates = append(alertingFile.Templates, ttV1.mapToModel())
|
||||
}
|
||||
for _, deleteV1 := range fileV1.DeleteTemplates {
|
||||
delReq, err := deleteV1.mapToModel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
alertingFile.DeleteTemplates = append(alertingFile.DeleteTemplates, delReq)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fileV1 *AlertingFileV1) mapMuteTimes(alertingFile *AlertingFile) error {
|
||||
for _, mtV1 := range fileV1.MuteTimes {
|
||||
alertingFile.MuteTimes = append(alertingFile.MuteTimes, mtV1.mapToModel())
|
||||
|
@ -275,6 +275,7 @@ func (ps *ProvisioningServiceImpl) ProvisionAlerting(ctx context.Context) error
|
||||
notificationPolicyService := provisioning.NewNotificationPolicyService(&st,
|
||||
st, ps.SQLStore, ps.Cfg.UnifiedAlerting, ps.log)
|
||||
mutetimingsService := provisioning.NewMuteTimingService(&st, st, &st, ps.log)
|
||||
templateService := provisioning.NewTemplateService(&st, st, &st, ps.log)
|
||||
cfg := prov_alerting.ProvisionerConfig{
|
||||
Path: alertingPath,
|
||||
RuleService: *ruleService,
|
||||
@ -283,6 +284,7 @@ func (ps *ProvisioningServiceImpl) ProvisionAlerting(ctx context.Context) error
|
||||
ContactPointService: *contactPointService,
|
||||
NotificiationPolicyService: *notificationPolicyService,
|
||||
MuteTimingService: *mutetimingsService,
|
||||
TemplateService: *templateService,
|
||||
}
|
||||
return ps.provisionAlerting(ctx, cfg)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user