diff --git a/go.mod b/go.mod index 63bafca0da7..3e3875c530d 100644 --- a/go.mod +++ b/go.mod @@ -76,7 +76,7 @@ require ( github.com/googleapis/gax-go/v2 v2.14.1 // @grafana/grafana-backend-group github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // @grafana/grafana-app-platform-squad - github.com/grafana/alerting v0.0.0-20250521131632-6e476b0b04c3 // @grafana/alerting-backend + github.com/grafana/alerting v0.0.0-20250602195607-6a7a4878b148 // @grafana/alerting-backend github.com/grafana/authlib v0.0.0-20250515162837-2f4a8263eabb // @grafana/identity-access-team github.com/grafana/authlib/types v0.0.0-20250325095148-d6da9c164a7d // @grafana/identity-access-team github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics diff --git a/go.sum b/go.sum index 20561c1ee3e..be5c962595e 100644 --- a/go.sum +++ b/go.sum @@ -1559,8 +1559,8 @@ github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7Fsg github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= -github.com/grafana/alerting v0.0.0-20250521131632-6e476b0b04c3 h1:QgV6JOePZeVOqIu0yVrjuryctEpVBvlPI04Zq25PV3c= -github.com/grafana/alerting v0.0.0-20250521131632-6e476b0b04c3/go.mod h1:pMfhRxL2LZ3Pm8iy7VcVsb9CLYuBtjFYbf1oxgx7yFA= +github.com/grafana/alerting v0.0.0-20250602195607-6a7a4878b148 h1:Rzl0iMizrm6+5uUYGt7CQ6nf7JnnoP2d37Eph3Tdrw8= +github.com/grafana/alerting v0.0.0-20250602195607-6a7a4878b148/go.mod h1:pMfhRxL2LZ3Pm8iy7VcVsb9CLYuBtjFYbf1oxgx7yFA= github.com/grafana/authlib v0.0.0-20250515162837-2f4a8263eabb h1:oTl2j6/4miQUYmXANp2pBuYCWA5f8NVYFfCWpczpFso= github.com/grafana/authlib v0.0.0-20250515162837-2f4a8263eabb/go.mod h1:PBtQaXwkFu4BAt2aXsR7w8p8NVpdjV5aJYhqRDei9Us= github.com/grafana/authlib/types v0.0.0-20250325095148-d6da9c164a7d h1:34E6btDAhdDOiSEyrMaYaHwnJpM8w9QKzVQZIBzLNmM= diff --git a/go.work.sum b/go.work.sum index 1610e0fbc26..27385fd10c1 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1268,6 +1268,8 @@ github.com/grafana/alerting v0.0.0-20250403153742-418bc7118d05 h1:hMzOzI/S0nkZt0 github.com/grafana/alerting v0.0.0-20250403153742-418bc7118d05/go.mod h1:K3YAJumchx5EEZItGv4D3pCv/Ux796hmoOibP/p/eYk= github.com/grafana/alerting v0.0.0-20250429131604-de176b4a0309 h1:H2p3XKDHnTBGkMXLCgXiqb2dFnHbQ4zPDXOwKK4Ne3Y= github.com/grafana/alerting v0.0.0-20250429131604-de176b4a0309/go.mod h1:pMfhRxL2LZ3Pm8iy7VcVsb9CLYuBtjFYbf1oxgx7yFA= +github.com/grafana/alerting v0.0.0-20250602195607-6a7a4878b148 h1:Rzl0iMizrm6+5uUYGt7CQ6nf7JnnoP2d37Eph3Tdrw8= +github.com/grafana/alerting v0.0.0-20250602195607-6a7a4878b148/go.mod h1:pMfhRxL2LZ3Pm8iy7VcVsb9CLYuBtjFYbf1oxgx7yFA= github.com/grafana/authlib v0.0.0-20250123104008-e99947858901/go.mod h1:/gYfphsNu9v1qYWXxpv1NSvMEMSwvdf8qb8YlgwIRl8= github.com/grafana/authlib/types v0.0.0-20250120144156-d6737a7dc8f5/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM= github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM= diff --git a/pkg/services/ngalert/api/tooling/definitions/alertmanager_validation.go b/pkg/services/ngalert/api/tooling/definitions/alertmanager_validation.go index 0e8c319113b..46f64d096d1 100644 --- a/pkg/services/ngalert/api/tooling/definitions/alertmanager_validation.go +++ b/pkg/services/ngalert/api/tooling/definitions/alertmanager_validation.go @@ -31,18 +31,12 @@ func (t *NotificationTemplate) Validate() error { content = fmt.Sprintf("{{ define \"%s\" }}\n%s\n{{ end }}", t.Name, content) } t.Template = content - - // Validate template contents. We try to stick as close to what will actually happen when the templates are parsed - // by the alertmanager as possible. - tmpl, err := templates.NewTemplate() - if err != nil { - return fmt.Errorf("failed to create template: %w", err) - } - if err := tmpl.Parse(strings.NewReader(t.Template)); err != nil { - return fmt.Errorf("invalid template: %w", err) + def := templates.TemplateDefinition{ + Name: t.Name, + Template: t.Template, + Kind: templates.GrafanaKind, } - - return nil + return def.Validate() } func (mt *MuteTimeInterval) Validate() error { diff --git a/pkg/services/ngalert/notifier/compat.go b/pkg/services/ngalert/notifier/compat.go index 8ba1aaae66c..c7488f3d4e9 100644 --- a/pkg/services/ngalert/notifier/compat.go +++ b/pkg/services/ngalert/notifier/compat.go @@ -139,6 +139,7 @@ func ToTemplateDefinitions(cfg *apimodels.PostableUserConfig) []alertingTemplate out = append(out, alertingTemplates.TemplateDefinition{ Name: name, Template: tmpl, + Kind: alertingTemplates.GrafanaKind, }) } return out diff --git a/pkg/services/ngalert/notifier/email_test.go b/pkg/services/ngalert/notifier/email_test.go index ef2b6159e9b..32606a95c7f 100644 --- a/pkg/services/ngalert/notifier/email_test.go +++ b/pkg/services/ngalert/notifier/email_test.go @@ -3,14 +3,12 @@ package notifier import ( "context" "net/url" - "os" "testing" alertingImages "github.com/grafana/alerting/images" "github.com/grafana/alerting/receivers" alertingEmail "github.com/grafana/alerting/receivers/email" alertingTemplates "github.com/grafana/alerting/templates" - "github.com/prometheus/alertmanager/template" "github.com/prometheus/alertmanager/types" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" @@ -26,7 +24,7 @@ import ( func TestEmailNotifierIntegration(t *testing.T) { ns := createEmailSender(t) - emailTmpl := templateForTests(t) + emailTmpl := alertingTemplates.ForTests(t) externalURL, err := url.Parse("http://localhost/base") require.NoError(t, err) emailTmpl.ExternalURL = externalURL @@ -187,7 +185,7 @@ func TestEmailNotifierIntegration(t *testing.T) { } } -func createSut(t *testing.T, messageTmpl string, subjectTmpl string, emailTmpl *template.Template, ns receivers.EmailSender) *alertingEmail.Notifier { +func createSut(t *testing.T, messageTmpl string, subjectTmpl string, emailTmpl *alertingTemplates.Template, ns receivers.EmailSender) *alertingEmail.Notifier { t.Helper() if subjectTmpl == "" { subjectTmpl = alertingTemplates.DefaultMessageTitleEmbed @@ -235,23 +233,3 @@ func createEmailSender(t *testing.T) *emailSender { return &emailSender{ns: ns} } - -func templateForTests(t *testing.T) *template.Template { - f, err := os.CreateTemp("/tmp", "template") - require.NoError(t, err) - defer func(f *os.File) { - _ = f.Close() - }(f) - - t.Cleanup(func() { - require.NoError(t, os.RemoveAll(f.Name())) - }) - - _, err = f.WriteString(alertingTemplates.TemplateForTestsString) - require.NoError(t, err) - - tmpl, err := template.FromGlobs([]string{f.Name()}) - require.NoError(t, err) - - return tmpl -}