Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a receiver for Amazon SNS #173

Merged
merged 3 commits into from
May 30, 2024

Conversation

robbierolin
Copy link
Contributor

@robbierolin robbierolin commented Mar 20, 2024

This PR adds a receiver that will send notifications to Amazon SNS. Fixes #172

I have a corresponding change in the grafana code locally to add this receiver to the available channels that can be selected for contact points. I am guessing the process is to PR that one after this change gets merged.

Here are some example screenshots

Screenshot 2024-03-20 at 5 35 49 PM

I tested by subscribing my email to the sns topic. And verifying that I receive the emails when I send test requests.

Screenshot 2024-03-20 at 5 36 51 PM

Let me know if there's any other changes I should add or testing I should show.

Comment on lines 25 to 34
Topic string `json:"topic,omitempty" yaml:"topic,omitempty"`
AuthProvider string `json:"authProvider,omitempty" yaml:"authProvider,omitempty"`
Subject string `json:"subject,omitempty" yaml:"subject,omitempty"`
Body string `json:"body,omitempty" yaml:"body,omitempty"`
MessageFormat string `json:"messageFormat,omitempty" yaml:"messageFormat,omitempty"`
Credentials string `json:"credentials,omitempty" yaml:"credentials,omitempty"`
AccessKey string `json:"accessKey,omitempty" yaml:"accessKey,omitempty"`
SecretKey string `json:"secretKey,omitempty" yaml:"secretKey,omitempty"`
AssumeRoleARN string `json:"assumeRoleARN,omitempty" yaml:"assumeRoleARN,omitempty"`
ExternalID string `json:"externalId,omitempty" yaml:"externalId,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, thank you so much for opening the PR!

I have not reviewed it yet but the first thing that catches my eye is the config. We're trying to maintain as little drift as possible with integration in the upstream. Please make sure that json\yaml fields match the upstream integration
https://github.com/prometheus/alertmanager/blob/f82574a3763c21ca9bf2ada7baf69bd09e01d977/config/notifiers.go#L731-L744

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for sharing, I will look at that. I think I will need to use this SubformOptions to provide the complex types like sigv4.SigV4Config?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I updated the config to match the upstream and pulled in some of the functionality from there too, like message deduplication and truncation.

Also I noticed that the Grafana channel config UIs doesn't seem to support ShowWhen or secure fields for subforms. I can try to address that in my PR to grafana.

@robbierolin robbierolin force-pushed the add-sns-receiver branch 2 times, most recently from 726c586 to 5984351 Compare March 21, 2024 00:58
@yuri-tceretian yuri-tceretian added the enhancement New feature or request label Mar 21, 2024
@JohnnyQQQQ
Copy link
Member

@robbierolin could you rebase your PR please and @yuri-tceretian could you give it a final review?

@robbierolin
Copy link
Contributor Author

Yup, should be good now.

Copy link
Contributor

@yuri-tceretian yuri-tceretian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the logic pretty much matches already merged in vanilla Alertmanager. The code LGTM but I think it needs some more tests.

settings.Sigv4.AccessKey = decryptFn("accessKey", settings.Sigv4.AccessKey)
settings.Sigv4.SecretKey = decryptFn("secretKey", settings.Sigv4.SecretKey)
at = awsds.AuthTypeKeys
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a validation here to check for situations when either of keys is not specified. Currently, it silently falls back to default authentication type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, will do.

expectedMessage: "message",
expectedAuthType: awsds.AuthTypeSharedCreds.String(),
},
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add tests for invalid configurations like

settings: `{
				"topic_arn": "arn:aws:sns:region:0123456789:SNSTopicName",
				"sigv4": {
					"secret_key": "secret-key"
				}
			}`,

and

settings: `{
"topic_arn": "arn:aws:sns:region:0123456789:SNSTopicName",
"sigv4": {
"access-key": "access-key"
}
}`,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

settings.APIUrl = fmt.Sprintf("https://sns.%s.amazonaws.com", settings.Sigv4.Region)
}

at := awsds.AuthTypeDefault
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I understand correctly that in the case when auth type is "default", the credentials will be taken from a file ~/.aws/credentials or env vars?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That setting comes from here - https://github.com/grafana/grafana-aws-sdk/blob/main/pkg/awsds/settings.go#L16
The behaviour should be to use the default credential provider chain which looks for creds in multiple places. It's explained more here - https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials

return message, false, nil
}
// If the message is larger than our specified size we have to truncate.
truncated := make([]byte, maxMessageSizeInBytes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a standard way for truncating messages notify.TruncateInBytes. However, this matches the logic in the vanilla Alertmanager. So, I think this is fine.

"github.com/grafana/alerting/templates"
)

func TestCreatePublishInput(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs some more tests for truncation of messages

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

@yuri-tceretian
Copy link
Contributor

CI fails due to linter

golangci-lint run

receivers/sns/sns.go:6: File is not `goimports`-ed (goimports)

	"github.com/prometheus/alertmanager/notify"

receivers/sns/config_test.go:4: File is not `goimports`-ed (goimports)

	"encoding/json"

Copy link
Contributor

@yuri-tceretian yuri-tceretian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Add Amazon SNS as receiver
3 participants