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

Define CloudWatch Alarm Payload structure #296

Merged
merged 11 commits into from Jul 21, 2020
56 changes: 56 additions & 0 deletions events/sns.go
Expand Up @@ -30,3 +30,59 @@ type SNSEntity struct {
UnsubscribeURL string `json:"UnsubscribeUrl"`
Subject string `json:"Subject"`
}

type CloudWatchAlarmSnsPayload struct {
AlarmName string `json:"AlarmName"`
AlarmDescription string `json:"AlarmDescription"`
AWSAccountId string `json:"AWSAccountId"`
bmoffatt marked this conversation as resolved.
Show resolved Hide resolved
NewStateValue string `json:"NewStateValue"`
NewStateReason string `json:"NewStateReason"`
StateChangeTime string `json:"StateChangeTime"`
Region string `json:"Region"`
AlarmArn string `json:"AlarmArn"`
bmoffatt marked this conversation as resolved.
Show resolved Hide resolved
OldStateValue string `json:"OldStateValue"`
Trigger CloudWatchAlarmTrigger `json:"Trigger"`
}

type CloudWatchAlarmTrigger struct {
Period int64 `json:"Period"`
EvaluationPeriods int64 `json:"EvaluationPeriods"`
ComparisonOperator string `json:"ComparisonOperator"`
Threshold float64 `json:"Threshold"`
TreatMissingData string `json:"TreatMissingData"`
EvaluateLowSampleCountPercentile string `json:"EvaluateLowSampleCountPercentile"`
Metrics []*CloudWatchMetricDataQuery `json:"Metrics,omitempty"`
MetricName string `json:"MetricName,omitempty"`
Namespace string `json:"Namespace,omitempty"`
StatisticType string `json:"StatisticType,omitempty"`
Statistic string `json:"Statistic,omitempty"`
Unit string `json:"Unit,omitempty"`
Dimensions []*CloudWatchDimension `json:"Dimensions,omitempty"`
}

type CloudWatchMetricDataQuery struct {
Expression *string `json:"Expression,omitempty"`
Id *string `json:"Id"`
Label *string `json:"Label,omitempty"`
MetricStat *CloudWatchMetricStat `json:"MetricStat,omitempty"`
Period *int64 `json:"Period,omitempty"`
ReturnData *bool `json:"ReturnData,omitempty"`
}

type CloudWatchMetricStat struct {
Metric *CloudWatchMetric `json:"Metric"`
Period *int64 `json:"Period"`
Stat *string `json:"Stat"`
Unit *string `json:"Unit,omitempty"`
}

type CloudWatchMetric struct {
Dimensions []*CloudWatchDimension `json:"Dimensions,omitempty"`
MetricName *string `json:"MetricName,omitempty"`
Namespace *string `json:"Namespace,omitempty"`
}

type CloudWatchDimension struct {
Name *string `json:"name"`
Value *string `json:"value"`
}
29 changes: 29 additions & 0 deletions events/sns_test.go
Expand Up @@ -33,3 +33,32 @@ func TestSnsEventMarshaling(t *testing.T) {
func TestSnsMarshalingMalformedJson(t *testing.T) {
test.TestMalformedJson(t, SNSEvent{})
}

func TestCloudWatchAlarmSnsPayloadMarshaling(t *testing.T) {
// 1. read JSON from file
inputJson := test.ReadJSONFromFile(t, "./testdata/cloudwatch-alarm-sns-payload-single-metric.json")

// 2. de-serialize into Go object
var inputEvent SNSEvent
if err := json.Unmarshal(inputJson, &inputEvent); err != nil {
t.Errorf("could not unmarshal event. details: %v", err)
}

// 3.retrieve message from the Go object
var message = inputEvent.Records[0].SNS.Message

// 4. de-serialize message into Go object
var inputCloudWatchPayload CloudWatchAlarmSnsPayload
if err := json.Unmarshal([]byte(message), &inputCloudWatchPayload); err != nil {
t.Errorf("could not unmarshal event. details: %v", err)
}

// 5. serialize message to JSON
outputJson, err := json.Marshal(inputCloudWatchPayload)
if err != nil {
t.Errorf("could not marshal event. details: %v", err)
}

// 4. check result
assert.JSONEq(t, string(message), string(outputJson))
}
22 changes: 22 additions & 0 deletions events/testdata/cloudwatch-alarm-sns-payload-multiple-metrics.json
@@ -0,0 +1,22 @@
{
"Records": [
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
"Sns": {
"Type": "Notification",
"MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
"TopicArn": "arn:aws:sns:EXAMPLE",
"Subject": "TestInvoke",
"Message": "{\"AlarmName\":\"EXAMPLE\",\"AlarmDescription\":\"EXAMPLE\",\"AWSAccountId\":\"EXAMPLE\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 out of the last 1 datapoints [1234.0 (06/03/15 17:43:27)] was greater than the threshold (0.0) (minimum 1 datapoint for OK -> ALARM transition).\",\"StateChangeTime\":\"2015-06-03T17:43:27.123+0000\",\"Region\":\"EXAMPLE\",\"AlarmArn\":\"arn:aws:cloudwatch:REGION:ACCOUNT_NUMBER:alarm:EXAMPLE\",\"OldStateValue\":\"INSUFFICIENT_DATA\",\"Trigger\":{\"Period\":60,\"EvaluationPeriods\":1,\"ComparisonOperator\":\"GreaterThanThreshold\",\"Threshold\":0.0,\"TreatMissingData\":\"- TreatMissingData: missing\",\"EvaluateLowSampleCountPercentile\":\"\",\"Metrics\":[{\"Expression\":\"m1*1\",\"Id\":\"e1\",\"Label\":\"Expression1\",\"ReturnData\":true},{\"Id\":\"m1\",\"MetricStat\":{\"Metric\":{\"Dimensions\":[{\"value\":\"TestInstance\",\"name\":\"InstanceId\"}],\"MetricName\":\"NetworkOut\",\"Namespace\":\"AWS/EC2\"},\"Period\":60,\"Stat\":\"Average\"},\"ReturnData\":false}]}}",
"Timestamp": "2015-06-03T17:43:27.123Z",
"SignatureVersion": "1",
"Signature": "EXAMPLE",
"SigningCertUrl": "EXAMPLE",
"UnsubscribeUrl": "EXAMPLE",
"MessageAttributes": {}
}
}
]
}
22 changes: 22 additions & 0 deletions events/testdata/cloudwatch-alarm-sns-payload-single-metric.json
@@ -0,0 +1,22 @@
{
"Records": [
{
"EventSource": "aws:sns",
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:us-east-2: 594917905844:Default_CloudWatch_Alarms_Topic_Test: 872f5b40-db58-4161-94af-4fbc7f613012",
bmoffatt marked this conversation as resolved.
Show resolved Hide resolved
"Sns": {
"Type": "Notification",
"MessageId": "48c234a8-0bf8-56aa-82bd-63fcf9fc8cdc",
"TopicArn": "arn:aws:sns:us-east-2: 594917905844:Default_CloudWatch_Alarms_Topic_Test",
"Subject": "ALARM: \"test-alarm\" in US East (Ohio)",
"Message": "{\"AlarmName\": \"EXAMPLE\",\"AlarmDescription\": \"EXAMPLE\",\"AWSAccountId\": \"123456789012\",\"NewStateValue\": \"ALARM\",\"NewStateReason\": \"Threshold Crossed: 1 out of the last 1 datapoints [1234.0 (06/03/15 17:43:27)] was greater than the threshold (0.0) (minimum 1 datapoint for OK -> ALARM transition).\",\"StateChangeTime\": \"2015-06-03T17:43:27.123+0000\",\"Region\": \"EXAMPLE\",\"AlarmArn\": \"arn:aws:cloudwatch:REGION:ACCOUNT_NUMBER:alarm:EXAMPLE\",\"OldStateValue\": \"INSUFFICIENT_DATA\",\"Trigger\": {\"MetricName\": \"NetworkOut\",\"Namespace\": \"AWS/EC2\",\"StatisticType\": \"Statistic\",\"Statistic\": \"AVERAGE\",\"Unit\": \"Bytes\",\"Dimensions\": [{\"value\": \"TestInstance\",\"name\": \"InstanceId\"}],\"Period\": 60,\"EvaluationPeriods\": 1,\"ComparisonOperator\": \"GreaterThanThreshold\",\"Threshold\": 0.0,\"TreatMissingData\": \"- TreatMissingData: missing\",\"EvaluateLowSampleCountPercentile\": \"\"}}",
"Timestamp": "2015-06-03T17:43:27.123Z",
"SignatureVersion": "1",
"Signature": "RENXziJT8pGBhsGjpAOCAnoJ97DxibakoUk/hv71cxGUM2bSROtYAzCb1UNSvWsfonFXH4tf+aJsjKEkoDRCgnbft9rjohgW52L6GXEGpL0mgdoBF08EzRrLk/xCqoOvMzTP1W0gM2hiwyCmLmQvUw21gCU8RYZrk2LvFQ91sdXqneRcifrRBEyk92SZ60JHjMatnxWHFXOe71Ca8aPou0Qu1V76Sn1/J6hYq5tujMWohWBkPnqWXOvLPRJsrh6HnvVYhfBVUiE2QIEg3G9++0+fQoGHExAfrleK/1afmDNBhh27d3TKFRSOG78wF/NG2HeyYgg4ocQ6F6VwchPRew==",
"SigningCertUrl": "https: //sns.us-east-2.amazonaws.com/SimpleNotificationService-a86cb10b4e1f29c941702d737128f7b6.pem",
"UnsubscribeUrl": "https: //sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:594917905844:Default_CloudWatch_Alarms_Topic_Test:872f5b40-db58-4161-94af-4fbc7f613012",
"MessageAttributes": {}
}
}
]
}
3 changes: 2 additions & 1 deletion go.mod
Expand Up @@ -3,6 +3,7 @@ module github.com/aws/aws-lambda-go
go 1.12

require (
github.com/stretchr/testify v1.4.0
github.com/aws/aws-sdk-go v1.31.12
bmoffatt marked this conversation as resolved.
Show resolved Hide resolved
github.com/stretchr/testify v1.5.1
github.com/urfave/cli/v2 v2.1.1
)
12 changes: 12 additions & 0 deletions go.sum
@@ -1,8 +1,14 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/aws/aws-sdk-go v1.31.12 h1:SxRRGyhlCagI0DYkhOg+FgdXGXzRTE3vEX/gsgFaiKQ=
github.com/aws/aws-sdk-go v1.31.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
Expand All @@ -12,8 +18,14 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k=
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
Expand Down