Skip to content

Commit 3d38bfa

Browse files
authored
feat: Added support for AWS Health events (#170)
1 parent 8da65e5 commit 3d38bfa

File tree

3 files changed

+160
-0
lines changed

3 files changed

+160
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"version": "0",
3+
"id": "121345678-1234-1234-1234-123456789012",
4+
"detail-type": "AWS Health Event",
5+
"source": "aws.health",
6+
"account": "123456789012",
7+
"time": "2016-06-05T06:27:57Z",
8+
"region": "us-west-2",
9+
"resources": [
10+
"i-abcd1111"
11+
],
12+
"detail": {
13+
"eventArn": "arn:aws:health:us-west-2::event/AWS_EC2_INSTANCE_STORE_DRIVE_PERFORMANCE_DEGRADED_90353408594353980",
14+
"service": "EC2",
15+
"eventTypeCode": "AWS_EC2_INSTANCE_STORE_DRIVE_PERFORMANCE_DEGRADED",
16+
"eventTypeCategory": "issue",
17+
"startTime": "Sat, 05 Jun 2016 15:10:09 GMT",
18+
"eventDescription": [
19+
{
20+
"language": "en_US",
21+
"latestDescription": "A description of the event will be provided here"
22+
}
23+
],
24+
"affectedEntities": [
25+
{
26+
"entityValue": "i-abcd1111",
27+
"tags": {
28+
"stage": "prod",
29+
"app": "my-app"
30+
}
31+
}
32+
]
33+
}
34+
}

functions/notify_slack.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,80 @@ def format_guardduty_finding(message: Dict[str, Any], region: str) -> Dict[str,
191191
}
192192

193193

194+
class AwsHealthCategory(Enum):
195+
"""Maps AWS Health eventTypeCategory to Slack message format color
196+
197+
eventTypeCategory
198+
The category code of the event. The possible values are issue,
199+
accountNotification, and scheduledChange.
200+
"""
201+
202+
accountNotification = "#777777"
203+
scheduledChange = "warning"
204+
issue = "danger"
205+
206+
207+
def format_aws_health(message: Dict[str, Any], region: str) -> Dict[str, Any]:
208+
"""
209+
Format AWS Health event into Slack message format
210+
211+
:params message: SNS message body containing AWS Health event
212+
:params region: AWS region where the event originated from
213+
:returns: formatted Slack message payload
214+
"""
215+
216+
aws_health_url = (
217+
f"https://phd.aws.amazon.com/phd/home?region={region}#/dashboard/open-issues"
218+
)
219+
detail = message["detail"]
220+
resources = message.get("resources", "<unknown>")
221+
service = detail.get("service", "<unknown>")
222+
223+
return {
224+
"color": AwsHealthCategory[detail["eventTypeCategory"]].value,
225+
"text": f"New AWS Health Event for {service}",
226+
"fallback": f"New AWS Health Event for {service}",
227+
"fields": [
228+
{"title": "Affected Service", "value": f"`{service}`", "short": True},
229+
{
230+
"title": "Affected Region",
231+
"value": f"`{message.get('region')}`",
232+
"short": True,
233+
},
234+
{
235+
"title": "Code",
236+
"value": f"`{detail.get('eventTypeCode')}`",
237+
"short": False,
238+
},
239+
{
240+
"title": "Event Description",
241+
"value": f"`{detail['eventDescription'][0]['latestDescription']}`",
242+
"short": False,
243+
},
244+
{
245+
"title": "Affected Resources",
246+
"value": f"`{', '.join(resources)}`",
247+
"short": False,
248+
},
249+
{
250+
"title": "Start Time",
251+
"value": f"`{detail.get('startTime', '<unknown>')}`",
252+
"short": True,
253+
},
254+
{
255+
"title": "End Time",
256+
"value": f"`{detail.get('endTime', '<unknown>')}`",
257+
"short": True,
258+
},
259+
{
260+
"title": "Link to Event",
261+
"value": f"{aws_health_url}",
262+
"short": False,
263+
},
264+
],
265+
}
266+
267+
194268
def format_default(
195269
message: Union[str, Dict], subject: Optional[str] = None
196270
) -> Dict[str, Any]:
@@ -265,6 +339,10 @@ def get_slack_message_payload(
265339
)
266340
attachment = notification
267341

342+
elif isinstance(message, Dict) and message.get("detail-type") == "AWS Health Event":
343+
notification = format_aws_health(message=message, region=message["region"])
344+
attachment = notification
345+
268346
elif "attachments" in message or "text" in message:
269347
payload = {**payload, **message}
270348

functions/snapshots/snap_notify_slack_test.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,56 @@
44

55
from snapshottest import Snapshot
66

7+
78
snapshots = Snapshot()
89

10+
snapshots[
11+
"test_event_get_slack_message_payload_snapshots event_aws_health_event.json"
12+
] = [
13+
{
14+
"attachments": [
15+
{
16+
"color": "danger",
17+
"fallback": "New AWS Health Event for EC2",
18+
"fields": [
19+
{"short": True, "title": "Affected Service", "value": "`EC2`"},
20+
{"short": True, "title": "Affected Region", "value": "`us-west-2`"},
21+
{
22+
"short": False,
23+
"title": "Code",
24+
"value": "`AWS_EC2_INSTANCE_STORE_DRIVE_PERFORMANCE_DEGRADED`",
25+
},
26+
{
27+
"short": False,
28+
"title": "Event Description",
29+
"value": "`A description of the event will be provided here`",
30+
},
31+
{
32+
"short": False,
33+
"title": "Affected Resources",
34+
"value": "`i-abcd1111`",
35+
},
36+
{
37+
"short": True,
38+
"title": "Start Time",
39+
"value": "`Sat, 05 Jun 2016 15:10:09 GMT`",
40+
},
41+
{"short": True, "title": "End Time", "value": "`<unknown>`"},
42+
{
43+
"short": False,
44+
"title": "Link to Event",
45+
"value": "https://phd.aws.amazon.com/phd/home?region=us-west-2#/dashboard/open-issues",
46+
},
47+
],
48+
"text": "New AWS Health Event for EC2",
49+
}
50+
],
51+
"channel": "slack_testing_sandbox",
52+
"icon_emoji": ":aws:",
53+
"username": "notify_slack_test",
54+
}
55+
]
56+
957
snapshots[
1058
"test_event_get_slack_message_payload_snapshots event_cloudwatch_alarm.json"
1159
] = [

0 commit comments

Comments
 (0)