mirror of
https://github.com/prometheus/alertmanager
synced 2024-12-28 17:12:13 +00:00
Code review fixes: copy attributes, truncate all the messages, fix logging, remove api_version
Signed-off-by: Tyler Reid <tyler.reid@grafana.com>
This commit is contained in:
parent
9d37d6cc44
commit
3446b35272
@ -133,7 +133,6 @@ var (
|
||||
NotifierConfig: NotifierConfig{
|
||||
VSendResolved: true,
|
||||
},
|
||||
APIVersion: "sns.default.api_version",
|
||||
Subject: `{{ template "sns.default.subject" . }}`,
|
||||
Message: `{{ template "sns.default.message" . }}`,
|
||||
}
|
||||
@ -608,7 +607,6 @@ type SNSConfig struct {
|
||||
HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"`
|
||||
|
||||
APIUrl string `yaml:"api_url" json:"api_url"`
|
||||
APIVersion string `yaml:"api_version,omitempty" json:"api_version,omitempty"`
|
||||
Sigv4 SigV4Config `yaml:"sigv4" json:"sigv4"`
|
||||
TopicARN string `yaml:"topic_arn,omitempty" json:"topic_arn,omitempty"`
|
||||
PhoneNumber string `yaml:"phone_number,omitempty" json:"phone_number,omitempty"`
|
||||
@ -625,7 +623,7 @@ func (c *SNSConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
if err := unmarshal((*plain)(c)); err != nil {
|
||||
return err
|
||||
}
|
||||
if c.TargetARN == "" && c.TopicARN == "" && c.PhoneNumber == "" {
|
||||
if (c.TargetARN == "") != (c.TopicARN == "") != (c.PhoneNumber == "") {
|
||||
return fmt.Errorf("must provide either a Target ARN, Topic ARN, or Phone Number for SNS config")
|
||||
}
|
||||
if (c.Sigv4.AccessKey == "") != (c.Sigv4.SecretKey == "") {
|
||||
|
@ -699,9 +699,6 @@ value: <tmpl_string>
|
||||
# The SNS API URL i.e. https://sns.us-east-2.amazonaws.com
|
||||
[api_url: <tmpl_string>]
|
||||
|
||||
# The SNS API version i.e.
|
||||
[ api_version: <tmpl_string> | default = sns.default.api_version ]
|
||||
|
||||
# Configures AWS's Signature Verification 4 signing process to sign requests.
|
||||
sigv4:
|
||||
[ <sigv4_config> ]
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/sns"
|
||||
"github.com/go-kit/kit/log"
|
||||
"github.com/go-kit/kit/log/level"
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
"github.com/prometheus/alertmanager/notify"
|
||||
"github.com/prometheus/alertmanager/template"
|
||||
@ -70,6 +71,14 @@ func (n *Notifier) Notify(ctx context.Context, alert ...*types.Alert) (bool, err
|
||||
creds = credentials.NewStaticCredentials(n.conf.Sigv4.AccessKey, string(n.conf.Sigv4.SecretKey), "")
|
||||
}
|
||||
|
||||
attributes := make(map[string]*sns.MessageAttributeValue, len(n.conf.Attributes))
|
||||
if len(n.conf.Attributes) > 0 {
|
||||
for k, v := range n.conf.Attributes {
|
||||
attributes[tmpl(k)] = &sns.MessageAttributeValue{DataType: aws.String("String"), StringValue: aws.String(tmpl(v))}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sess, err := session.NewSessionWithOptions(session.Options{
|
||||
Config: aws.Config{
|
||||
Region: aws.String(n.conf.Sigv4.Region),
|
||||
@ -87,18 +96,13 @@ func (n *Notifier) Notify(ctx context.Context, alert ...*types.Alert) (bool, err
|
||||
sess.Config.Credentials = stscreds.NewCredentials(sess, n.conf.Sigv4.RoleARN)
|
||||
}
|
||||
|
||||
// Max message size for a message in a SNS publish request is 256KB, except for SMS messages where the limit is 1600 characters/runes.
|
||||
messageSize := 256 * 1024
|
||||
client := sns.New(sess, &aws.Config{Credentials: creds})
|
||||
publishInput := &sns.PublishInput{}
|
||||
|
||||
if n.conf.TopicARN != "" {
|
||||
publishInput.SetTopicArn(tmpl(n.conf.TopicARN))
|
||||
messageToSend, isTrunc, err := validateAndTruncateMessage(tmpl(n.conf.Message))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if isTrunc {
|
||||
n.conf.Attributes["truncated"] = "true"
|
||||
}
|
||||
|
||||
if n.isFifo == nil {
|
||||
checkFifo, err := checkTopicFifoAttribute(client, n.conf.TopicARN)
|
||||
@ -120,43 +124,32 @@ func (n *Notifier) Notify(ctx context.Context, alert ...*types.Alert) (bool, err
|
||||
publishInput.SetMessageDeduplicationId(key.Hash())
|
||||
publishInput.SetMessageGroupId(key.Hash())
|
||||
}
|
||||
|
||||
publishInput.SetMessage(messageToSend)
|
||||
}
|
||||
if n.conf.PhoneNumber != "" {
|
||||
publishInput.SetPhoneNumber(tmpl(n.conf.PhoneNumber))
|
||||
// If SMS message is over 1600 chars, SNS will reject the message.
|
||||
_, isTruncated := notify.Truncate(tmpl(n.conf.Message), 1600)
|
||||
if isTruncated {
|
||||
return false, fmt.Errorf("SMS message exeeds length of 1600 charactors")
|
||||
} else {
|
||||
publishInput.SetMessage(tmpl(n.conf.Message))
|
||||
}
|
||||
// If we have an SMS message, we need to truncate to 1600 characters/runes.
|
||||
messageSize = 1600
|
||||
}
|
||||
if n.conf.TargetARN != "" {
|
||||
publishInput.SetTargetArn(tmpl(n.conf.TargetARN))
|
||||
messageToSend, isTrunc, err := validateAndTruncateMessage(tmpl(n.conf.Message))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if isTrunc {
|
||||
n.conf.Attributes["truncated"] = "true"
|
||||
}
|
||||
publishInput.SetMessage(messageToSend)
|
||||
|
||||
}
|
||||
|
||||
if len(n.conf.Attributes) > 0 {
|
||||
attributes := map[string]*sns.MessageAttributeValue{}
|
||||
for k, v := range n.conf.Attributes {
|
||||
attributes[tmpl(k)] = &sns.MessageAttributeValue{DataType: aws.String("String"), StringValue: aws.String(tmpl(v))}
|
||||
}
|
||||
publishInput.SetMessageAttributes(attributes)
|
||||
messageToSend, isTrunc, err := validateAndTruncateMessage(tmpl(n.conf.Message), messageSize)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if isTrunc {
|
||||
attributes[tmpl("truncated")] = &sns.MessageAttributeValue{DataType: aws.String("String"), StringValue: aws.String(tmpl("true"))}
|
||||
}
|
||||
publishInput.SetMessage(messageToSend)
|
||||
|
||||
if n.conf.Subject != "" {
|
||||
publishInput.SetSubject(tmpl(n.conf.Subject))
|
||||
}
|
||||
|
||||
publishInput.SetMessageAttributes(attributes)
|
||||
|
||||
publishOutput, err := client.Publish(publishInput)
|
||||
if err != nil {
|
||||
if e, ok := err.(awserr.RequestFailure); ok {
|
||||
@ -166,10 +159,7 @@ func (n *Notifier) Notify(ctx context.Context, alert ...*types.Alert) (bool, err
|
||||
}
|
||||
}
|
||||
|
||||
err = n.logger.Log(publishOutput.String())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
level.Debug(n.logger).Log("msg", "SNS publish successfully sent", "message_id", publishOutput.MessageId, "sequence number", publishOutput.SequenceNumber)
|
||||
|
||||
return false, nil
|
||||
}
|
||||
@ -180,21 +170,21 @@ func checkTopicFifoAttribute(client *sns.SNS, topicARN string) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
ta := topicAttributes.Attributes["FifoTopic"]
|
||||
if ta != nil && *ta == "true" {
|
||||
if aws.StringValue(ta) == "true" {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func validateAndTruncateMessage(message string) (string, bool, error) {
|
||||
if utf8.ValidString(message) {
|
||||
// if the message is larger than 256KB we have to truncate.
|
||||
if len(message) > 256*1024 {
|
||||
truncated := make([]byte, 256*1024)
|
||||
copy(truncated, message)
|
||||
return string(truncated), true, nil
|
||||
}
|
||||
func validateAndTruncateMessage(message string, sizeInBytes int) (string, bool, error) {
|
||||
if !utf8.ValidString(message) {
|
||||
return "", false, fmt.Errorf("non utf8 encoded message string")
|
||||
}
|
||||
if len(message) <= sizeInBytes {
|
||||
return message, false, nil
|
||||
}
|
||||
return "", false, fmt.Errorf("non utf8 encoded message string")
|
||||
// if the message is larger than our specified size we have to truncate.
|
||||
truncated := make([]byte, sizeInBytes)
|
||||
copy(truncated, message)
|
||||
return string(truncated), true, nil
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ func TestValidateAndTruncateMessage(t *testing.T) {
|
||||
for i := range sBuff {
|
||||
sBuff[i] = byte(33)
|
||||
}
|
||||
truncatedMessage, isTruncated, err := validateAndTruncateMessage(string(sBuff))
|
||||
truncatedMessage, isTruncated, err := validateAndTruncateMessage(string(sBuff), 256*1024)
|
||||
require.True(t, isTruncated)
|
||||
require.NoError(t, err)
|
||||
require.NotEqual(t, sBuff, truncatedMessage)
|
||||
@ -34,12 +34,12 @@ func TestValidateAndTruncateMessage(t *testing.T) {
|
||||
for i := range sBuff {
|
||||
sBuff[i] = byte(33)
|
||||
}
|
||||
truncatedMessage, isTruncated, err = validateAndTruncateMessage(string(sBuff))
|
||||
truncatedMessage, isTruncated, err = validateAndTruncateMessage(string(sBuff), 100)
|
||||
require.False(t, isTruncated)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, string(sBuff), truncatedMessage)
|
||||
|
||||
invalidUtf8String := "\xc3\x28"
|
||||
_, _, err = validateAndTruncateMessage(invalidUtf8String)
|
||||
_, _, err = validateAndTruncateMessage(invalidUtf8String, 100)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user