Skip to content

Commit

Permalink
use email sender from alerting repository
Browse files Browse the repository at this point in the history
  • Loading branch information
santihernandezc committed Jun 18, 2024
1 parent 289e425 commit a5d6198
Show file tree
Hide file tree
Showing 8 changed files with 1,416 additions and 110 deletions.
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ require (

require (
cloud.google.com/go/storage v1.40.0
github.com/Masterminds/sprig/v3 v3.2.1
github.com/alecthomas/chroma/v2 v2.12.0
github.com/alecthomas/kingpin/v2 v2.4.0
github.com/aws/aws-sdk-go v1.53.16
Expand All @@ -64,7 +63,7 @@ require (
github.com/google/go-github/v57 v57.0.0
github.com/google/uuid v1.6.0
github.com/grafana-tools/sdk v0.0.0-20220919052116-6562121319fc
github.com/grafana/alerting v0.0.0-20240607182251-835aff588914
github.com/grafana/alerting v0.0.0-20240618145205-cdfc0e849e0b
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/hashicorp/vault/api v1.10.0
Expand All @@ -87,7 +86,6 @@ require (
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f
google.golang.org/api v0.183.0
google.golang.org/protobuf v1.34.1
gopkg.in/mail.v2 v2.3.1
sigs.k8s.io/kustomize/kyaml v0.16.0
)

Expand All @@ -100,6 +98,7 @@ require (
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.1.1 // indirect
github.com/Masterminds/sprig/v3 v3.2.1 // indirect
github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 // indirect
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
Expand Down Expand Up @@ -130,6 +129,7 @@ require (
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/mail.v2 v2.3.1 // indirect
gopkg.in/telebot.v3 v3.2.1 // indirect
k8s.io/apimachinery v0.29.3 // indirect
k8s.io/client-go v0.29.3 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -513,8 +513,8 @@ github.com/gosimple/slug v1.1.1 h1:fRu/digW+NMwBIP+RmviTK97Ho/bEj/C9swrCspN3D4=
github.com/gosimple/slug v1.1.1/go.mod h1:ER78kgg1Mv0NQGlXiDe57DpCyfbNywXXZ9mIorhxAf0=
github.com/grafana-tools/sdk v0.0.0-20220919052116-6562121319fc h1:PXZQA2WCxe85Tnn+WEvr8fDpfwibmEPgfgFEaC87G24=
github.com/grafana-tools/sdk v0.0.0-20220919052116-6562121319fc/go.mod h1:AHHlOEv1+GGQ3ktHMlhuTUwo3zljV3QJbC0+8o2kn+4=
github.com/grafana/alerting v0.0.0-20240607182251-835aff588914 h1:WXLbSnnomltxdNcE20CI8RD8quZ/L0YpXP0WK+0S1BU=
github.com/grafana/alerting v0.0.0-20240607182251-835aff588914/go.mod h1:U7Ta3K4T7jVgqGSYuPsfuPKHFiL2GbCZSHa3nHjmCos=
github.com/grafana/alerting v0.0.0-20240618145205-cdfc0e849e0b h1:M86NakDlsYjYqEp/1kR54mhTjxYXTa59vl2pWhgi3f4=
github.com/grafana/alerting v0.0.0-20240618145205-cdfc0e849e0b/go.mod h1:my6It91EE/AanRkHj3hVjglp3mhuFNxSptm1etLSKHg=
github.com/grafana/dskit v0.0.0-20240611171734-87c7e9e7a4fe h1:PpBnljz9oYSp05pCcQl27n69cL9fNeFH+wkG/ga6oGs=
github.com/grafana/dskit v0.0.0-20240611171734-87c7e9e7a4fe/go.mod h1:HvSf3uf8Ps2vPpzHeAFyZTdUcbVr+Rxpq1xcx7J/muc=
github.com/grafana/e2e v0.1.2-0.20240118170847-db90b84177fc h1:BW+LjKJDz0So5LI8UZfW5neWeKpSkWqhmGjQFzcFfLM=
Expand Down
94 changes: 19 additions & 75 deletions pkg/alertmanager/alertmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
package alertmanager

import (
"bytes"
"context"
"crypto/md5"
"encoding/binary"
"encoding/json"
"fmt"
htmlTemplate "html/template"
"net/http"
"net/url"
"path"
Expand All @@ -21,14 +19,14 @@ import (
"sync"
"time"

"github.com/Masterminds/sprig/v3"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
"github.com/grafana/alerting/definition"
"github.com/grafana/alerting/images"
alertingNotify "github.com/grafana/alerting/notify"
"github.com/grafana/alerting/notify/nfstatus"
alertingReceivers "github.com/grafana/alerting/receivers"
alertingTemplates "github.com/grafana/alerting/templates"
"github.com/grafana/dskit/flagext"
"github.com/pkg/errors"
"github.com/prometheus/alertmanager/api"
Expand Down Expand Up @@ -317,19 +315,6 @@ func New(cfg *Config, reg *prometheus.Registry) (*Alertmanager, error) {

am.dispatcherMetrics = dispatch.NewDispatcherMetrics(true, am.registry)

mailTemplates = htmlTemplate.New("name")
mailTemplates.Funcs(htmlTemplate.FuncMap{
"Subject": subjectTemplateFunc,
"HiddenSubject": hiddenSubjectTemplateFunc,
"__dangerouslyInjectHTML": __dangerouslyInjectHTML,
})
mailTemplates.Funcs(sprig.FuncMap())
if _, err := mailTemplates.ParseFiles("./templates/ng_alert_notification.html"); err != nil {
return nil, err
}

fmt.Println("Parsed:", mailTemplates.Templates())

//TODO: From this point onward, the alertmanager _might_ receive requests - we need to make sure we've settled and are ready.
return am, nil
}
Expand Down Expand Up @@ -389,6 +374,10 @@ func (am *Alertmanager) ApplyConfig(userID string, conf *definition.PostableApiA
}
tmpl.ExternalURL = am.cfg.ExternalURL

if err := tmpl.Parse(strings.NewReader(alertingTemplates.DefaultTemplateString)); err != nil {
return err
}

cfg := definition.GrafanaToUpstreamConfig(conf)
am.api.Update(&cfg, func(_ model.LabelSet) {})

Expand Down Expand Up @@ -547,27 +536,22 @@ func buildIntegrationsMap(gCfg *config.GlobalConfig, externalURL string, nc []*d

func buildGrafanaReceiverIntegrations(gCfg *config.GlobalConfig, externalURL string, rcv *definition.PostableApiReceiver, tmpl *template.Template, logger log.Logger) ([]*nfstatus.Integration, error) {
loggerFactory := newLoggerFactory(logger)
smtpCfg := SmtpConfig{
AuthPassword: string(gCfg.SMTPAuthPassword),
AuthUser: gCfg.SMTPAuthUsername,
CertFile: gCfg.HTTPConfig.TLSConfig.CertFile,
ContentTypes: []string{}, // (?)
EhloIdentity: gCfg.SMTPHello,
ExternalURL: externalURL,
FromAddress: gCfg.SMTPFrom,
FromName: "Grafana",
Host: gCfg.SMTPSmarthost.String(),
KeyFile: gCfg.HTTPConfig.TLSConfig.KeyFile,
SkipVerify: !gCfg.SMTPRequireTLS,
StartTLSPolicy: "", // (?)
StaticHeaders: map[string]string{}, // (?)
emailCfg := alertingReceivers.EmailSenderConfig{
AuthPassword: string(gCfg.SMTPAuthPassword),
AuthUser: gCfg.SMTPAuthUsername,
CertFile: gCfg.HTTPConfig.TLSConfig.CertFile,
EhloIdentity: gCfg.SMTPHello,
ExternalURL: externalURL,
FromAddress: gCfg.SMTPFrom,
FromName: "Grafana",
Host: gCfg.SMTPSmarthost.String(),
KeyFile: gCfg.HTTPConfig.TLSConfig.KeyFile,
SkipVerify: !gCfg.SMTPRequireTLS,
StaticHeaders: map[string]string{}, // (?)
}

whFn := func(n alertingReceivers.Metadata) (alertingReceivers.WebhookSender, error) {
return NewSender(logger, smtpCfg), nil
}
emailFn := func(n alertingReceivers.Metadata) (alertingReceivers.EmailSender, error) {
return NewSender(logger, smtpCfg), nil
return NewSender(logger), nil
}

// The decrypt functions and the context are used to decrypt the configuration.
Expand All @@ -583,7 +567,7 @@ func buildGrafanaReceiverIntegrations(gCfg *config.GlobalConfig, externalURL str
&images.UnavailableProvider{}, // TODO: include images in notifications
loggerFactory,
whFn,
emailFn,
alertingReceivers.NewEmailSenderFactory(emailCfg),
1, // orgID is always 1.
version.Version,
)
Expand Down Expand Up @@ -860,43 +844,3 @@ func alertSize(alert model.Alert) int {
size += len(alert.GeneratorURL)
return size
}

// hiddenSubjectTemplateFunc sets the subject template (value) on the map represented by `.Subject.` (obj) so that it can be compiled and executed later.
// It returns a blank string, so there will be no resulting value left in place of the template.
func hiddenSubjectTemplateFunc(obj map[string]any, value string) string {
obj["value"] = value
return ""
}

// subjectTemplateFunc does the same thing has hiddenSubjectTemplateFunc, but in addition it executes and returns the subject template using the data represented in `.TemplateData` (data)
// This results in the template being replaced by the subject string.
func subjectTemplateFunc(obj map[string]any, data map[string]any, value string) string {
obj["value"] = value

titleTmpl, err := htmlTemplate.New("title").Parse(value)
if err != nil {
return ""
}

var buf bytes.Buffer
err = titleTmpl.ExecuteTemplate(&buf, "title", data)
if err != nil {
return ""
}

subj := buf.String()
// Since we have already executed the template, save it to subject data so we don't have to do it again later on
obj["executed_template"] = subj
return subj
}

// __dangerouslyInjectHTML allows marking areas of am email template as HTML safe, this will _not_ sanitize the string and will allow HTML snippets to be rendered verbatim.
// Use with absolute care as this _could_ allow for XSS attacks when used in an insecure context.
//
// It's safe to ignore gosec warning G203 when calling this function in an HTML template because we assume anyone who has write access
// to the email templates folder is an administrator.
//
// nolint:gosec
func __dangerouslyInjectHTML(s string) htmlTemplate.HTML {
return htmlTemplate.HTML(s)
}
7 changes: 3 additions & 4 deletions pkg/alertmanager/sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ type Sender struct {
smtp SmtpConfig
}

func NewSender(log log.Logger, cfg SmtpConfig) *Sender {
func NewSender(log log.Logger) *Sender {
netTransport := &http.Transport{
TLSClientConfig: &tls.Config{
Renegotiation: tls.RenegotiateFreelyAsClient,
Expand All @@ -67,9 +67,8 @@ func NewSender(log log.Logger, cfg SmtpConfig) *Sender {
Transport: netTransport,
}
return &Sender{
c: c,
log: log,
smtp: cfg,
c: c,
log: log,
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/alertmanager/sender_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestSendWebhook(t *testing.T) {
got = r
w.WriteHeader(http.StatusOK)
}))
s := NewSender(alertingLogging.FakeLogger{}, SmtpConfig{})
s := NewSender(alertingLogging.FakeLogger{})

// The method should be either POST or PUT.
cmd := alertingReceivers.SendWebhookSettings{
Expand Down
Loading

0 comments on commit a5d6198

Please sign in to comment.