From 5f848dbd77e836bba4a9130fcef462f456ac5b18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Engebr=C3=A5ten?= Date: Wed, 3 Apr 2024 09:55:34 +0200 Subject: [PATCH 1/8] feat: Added parser for AWS backup messages --- functions/notify_slack.py | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/functions/notify_slack.py b/functions/notify_slack.py index cb75ce73..2b281f73 100644 --- a/functions/notify_slack.py +++ b/functions/notify_slack.py @@ -266,6 +266,80 @@ def format_aws_health(message: Dict[str, Any], region: str) -> Dict[str, Any]: } +def aws_backup_field_parser(message: str) -> Dict[str, Any]: + """ + Parser for AWS Backup event message. It extracts the fields from the message and returns a dictionary. + + :params message: message containing AWS Backup event + :returns: dictionary containing the fields extracted from the message + """ + field_names = ["Recovery point ARN", "Resource ARN", "BackupJob ID", "Backup Job Id", "Backed up Resource ARN", "Status Message"] + + first = None + field_match = None + + for field in field_names: + index = message.find(field) + if index != -1 and (first == None or index < first): + first = index + field_match = field + + if first is not None: + next = None + for field in field_names: + index = message.find(field, first + len(field_match) + 1) + if index != -1 and (next == None or index < next): + next = index + + if next is None: + next = len(message) + + rem_message = message[next:] + fields = aws_backup_field_parser(rem_message) + + text = message[first+len(field_match)+1:next] + while text.startswith(" ") or text.startswith(":"): + text = text[1:] + + fields[field_match] = text + return fields + else: + return {} + + +def format_aws_backup(message: Dict[str, Any]) -> Dict[str, Any]: + """ + Format AWS Backup event into Slack message format + + :params message: SNS message body containing AWS Backup event + :returns: formatted Slack message payload + """ + + fields = [] + attachments = {} + + title = message.split(".")[0] + + + if "failed" in title: + title = title + " ⚠️" + + if "completed" in title: + title = title + " ✅" + + fields.append({"title": title}) + + list_items = aws_backup_field_parser(message) + + for k,v in list_items.items(): + fields.append({"value": k , "short": False}) + fields.append({"value": "```\n" + v +"\n```" , "short": False}) + + attachments["fields"] = fields # type: ignore + + return attachments + + def format_default( message: Union[str, Dict], subject: Optional[str] = None ) -> Dict[str, Any]: @@ -344,6 +418,10 @@ def get_slack_message_payload( notification = format_aws_health(message=message, region=message["region"]) attachment = notification + elif subject == "Notification from AWS Backup": + notification = format_aws_backup(message=message) + attachment = notification + elif "attachments" in message or "text" in message: payload = {**payload, **message} From 46ef15382120559c55a23b747ced737c5bfee369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Engebr=C3=A5ten?= Date: Fri, 5 Apr 2024 11:01:52 +0200 Subject: [PATCH 2/8] chore: Added test for AWS backup --- functions/Pipfile | 2 +- functions/messages/backup.json | 39 +++++++++++++++++++ functions/notify_slack.py | 32 ++++++++------- functions/snapshots/snap_notify_slack_test.py | 37 ++++++++++++++++++ 4 files changed, 96 insertions(+), 14 deletions(-) create mode 100644 functions/messages/backup.json diff --git a/functions/Pipfile b/functions/Pipfile index af8ac944..c701a273 100644 --- a/functions/Pipfile +++ b/functions/Pipfile @@ -18,7 +18,7 @@ radon = "*" snapshottest = "~=0.6" [requires] -python_version = "3.8" +python_version = "3.10" [scripts] test = "python3 -m pytest --cov --cov-report=term" diff --git a/functions/messages/backup.json b/functions/messages/backup.json new file mode 100644 index 00000000..03dfa804 --- /dev/null +++ b/functions/messages/backup.json @@ -0,0 +1,39 @@ +{ + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:...-a3802aa1ed45", + "Sns": { + "Type": "Notification", + "MessageId": "12345678-abcd-123a-def0-abcd1a234567", + "TopicArn": "arn:aws:sns:us-west-1:123456789012:backup-2sqs-sns-topic", + "Subject": "Notification from AWS Backup", + "Message": "An AWS Backup job was completed successfully. Recovery point ARN: arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012d. Resource ARN : arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012e. BackupJob ID : 1b2345b2-f22c-4dab-5eb6-bbc7890ed123", + "Timestamp": "2019-08-02T18:46:02.788Z", + "MessageAttributes": { + "EventType": { + "Type": "String", + "Value": "BACKUP_JOB" + }, + "State": { + "Type": "String", + "Value": "COMPLETED" + }, + "AccountId": { + "Type": "String", + "Value": "123456789012" + }, + "Id": { + "Type": "String", + "Value": "1b2345b2-f22c-4dab-5eb6-bbc7890ed123" + }, + "StartTime": { + "Type": "String", + "Value": "2019-09-02T13:48:52.226Z" + } + } + } + } + ] + } \ No newline at end of file diff --git a/functions/notify_slack.py b/functions/notify_slack.py index 2b281f73..8dbcb5f6 100644 --- a/functions/notify_slack.py +++ b/functions/notify_slack.py @@ -273,11 +273,18 @@ def aws_backup_field_parser(message: str) -> Dict[str, Any]: :params message: message containing AWS Backup event :returns: dictionary containing the fields extracted from the message """ - field_names = ["Recovery point ARN", "Resource ARN", "BackupJob ID", "Backup Job Id", "Backed up Resource ARN", "Status Message"] + field_names = [ + "Recovery point ARN", + "Resource ARN", + "BackupJob ID", + "Backup Job Id", + "Backed up Resource ARN", + "Status Message", + ] first = None field_match = None - + for field in field_names: index = message.find(field) if index != -1 and (first == None or index < first): @@ -293,11 +300,11 @@ def aws_backup_field_parser(message: str) -> Dict[str, Any]: if next is None: next = len(message) - + rem_message = message[next:] fields = aws_backup_field_parser(rem_message) - text = message[first+len(field_match)+1:next] + text = message[first + len(field_match) + 1 : next] while text.startswith(" ") or text.startswith(":"): text = text[1:] @@ -305,7 +312,7 @@ def aws_backup_field_parser(message: str) -> Dict[str, Any]: return fields else: return {} - + def format_aws_backup(message: Dict[str, Any]) -> Dict[str, Any]: """ @@ -317,23 +324,22 @@ def format_aws_backup(message: Dict[str, Any]) -> Dict[str, Any]: fields = [] attachments = {} - + title = message.split(".")[0] - - + if "failed" in title: title = title + " ⚠️" - + if "completed" in title: title = title + " ✅" - + fields.append({"title": title}) list_items = aws_backup_field_parser(message) - for k,v in list_items.items(): - fields.append({"value": k , "short": False}) - fields.append({"value": "```\n" + v +"\n```" , "short": False}) + for k, v in list_items.items(): + fields.append({"value": k, "short": False}) + fields.append({"value": "```\n" + v + "\n```", "short": False}) attachments["fields"] = fields # type: ignore diff --git a/functions/snapshots/snap_notify_slack_test.py b/functions/snapshots/snap_notify_slack_test.py index 7a04a3ef..e7a13664 100644 --- a/functions/snapshots/snap_notify_slack_test.py +++ b/functions/snapshots/snap_notify_slack_test.py @@ -4,6 +4,7 @@ from snapshottest import Snapshot + snapshots = Snapshot() snapshots[ @@ -231,6 +232,42 @@ } ] +snapshots["test_sns_get_slack_message_payload_snapshots message_backup.json"] = [ + { + "attachments": [ + { + "fields": [ + {"title": "An AWS Backup job was completed successfully ✅"}, + {"short": False, "value": "BackupJob ID"}, + { + "short": False, + "value": """``` +1b2345b2-f22c-4dab-5eb6-bbc7890ed123 +```""", + }, + {"short": False, "value": "Resource ARN"}, + { + "short": False, + "value": """``` +arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012e. +```""", + }, + {"short": False, "value": "Recovery point ARN"}, + { + "short": False, + "value": """``` +arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012d. +```""", + }, + ] + } + ], + "channel": "slack_testing_sandbox", + "icon_emoji": ":aws:", + "username": "notify_slack_test", + } +] + snapshots[ "test_sns_get_slack_message_payload_snapshots message_cloudwatch_alarm.json" ] = [ From c952dafc455e4319538cbc5c43fb9fb54e35f277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Engebr=C3=A5ten?= Date: Tue, 16 Apr 2024 08:52:09 +0200 Subject: [PATCH 3/8] chore: Fix code formatting --- functions/notify_slack.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/functions/notify_slack.py b/functions/notify_slack.py index 8dbcb5f6..b6ddd116 100644 --- a/functions/notify_slack.py +++ b/functions/notify_slack.py @@ -287,7 +287,7 @@ def aws_backup_field_parser(message: str) -> Dict[str, Any]: for field in field_names: index = message.find(field) - if index != -1 and (first == None or index < first): + if index != -1 and (first is None or index < first): first = index field_match = field @@ -295,7 +295,7 @@ def aws_backup_field_parser(message: str) -> Dict[str, Any]: next = None for field in field_names: index = message.find(field, first + len(field_match) + 1) - if index != -1 and (next == None or index < next): + if index != -1 and (next is None or index < next): next = index if next is None: @@ -304,7 +304,7 @@ def aws_backup_field_parser(message: str) -> Dict[str, Any]: rem_message = message[next:] fields = aws_backup_field_parser(rem_message) - text = message[first + len(field_match) + 1 : next] + text = message[first + len(field_match) + 1:next] while text.startswith(" ") or text.startswith(":"): text = text[1:] From a75e6083e99e31b834c30f1f78b34e97e4486d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Engebr=C3=A5ten?= Date: Mon, 22 Apr 2024 14:57:01 +0200 Subject: [PATCH 4/8] chore: Fix failing tests --- functions/messages/backup.json | 3 ++- functions/notify_slack.py | 8 ++++---- functions/snapshots/snap_notify_slack_test.py | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/functions/messages/backup.json b/functions/messages/backup.json index 03dfa804..356cd4fa 100644 --- a/functions/messages/backup.json +++ b/functions/messages/backup.json @@ -36,4 +36,5 @@ } } ] - } \ No newline at end of file + } + \ No newline at end of file diff --git a/functions/notify_slack.py b/functions/notify_slack.py index b6ddd116..ceaecd48 100644 --- a/functions/notify_slack.py +++ b/functions/notify_slack.py @@ -283,7 +283,7 @@ def aws_backup_field_parser(message: str) -> Dict[str, Any]: ] first = None - field_match = None + field_match = "" for field in field_names: index = message.find(field) @@ -314,7 +314,7 @@ def aws_backup_field_parser(message: str) -> Dict[str, Any]: return {} -def format_aws_backup(message: Dict[str, Any]) -> Dict[str, Any]: +def format_aws_backup(message: str) -> Dict[str, Any]: """ Format AWS Backup event into Slack message format @@ -322,7 +322,7 @@ def format_aws_backup(message: Dict[str, Any]) -> Dict[str, Any]: :returns: formatted Slack message payload """ - fields = [] + fields : list[Dict[str, Any]] = [] attachments = {} title = message.split(".")[0] @@ -425,7 +425,7 @@ def get_slack_message_payload( attachment = notification elif subject == "Notification from AWS Backup": - notification = format_aws_backup(message=message) + notification = format_aws_backup(message=str(message)) attachment = notification elif "attachments" in message or "text" in message: diff --git a/functions/snapshots/snap_notify_slack_test.py b/functions/snapshots/snap_notify_slack_test.py index e7a13664..a3b9002a 100644 --- a/functions/snapshots/snap_notify_slack_test.py +++ b/functions/snapshots/snap_notify_slack_test.py @@ -249,14 +249,14 @@ { "short": False, "value": """``` -arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012e. +arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012e. ```""", }, {"short": False, "value": "Recovery point ARN"}, { "short": False, "value": """``` -arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012d. +arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012d. ```""", }, ] From 8d5130407a7c5593c6a2c809726ae9af036c262c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Engebr=C3=A5ten?= Date: Wed, 24 Apr 2024 09:12:37 +0200 Subject: [PATCH 5/8] fix: Failing tests --- functions/messages/backup.json | 1 + functions/notify_slack.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/functions/messages/backup.json b/functions/messages/backup.json index 356cd4fa..91346476 100644 --- a/functions/messages/backup.json +++ b/functions/messages/backup.json @@ -37,4 +37,5 @@ } ] } + \ No newline at end of file diff --git a/functions/notify_slack.py b/functions/notify_slack.py index ceaecd48..ade5fb4f 100644 --- a/functions/notify_slack.py +++ b/functions/notify_slack.py @@ -322,7 +322,7 @@ def format_aws_backup(message: str) -> Dict[str, Any]: :returns: formatted Slack message payload """ - fields : list[Dict[str, Any]] = [] + fields:list[Dict[str, Any]] = [] attachments = {} title = message.split(".")[0] From d3dfa5395bcd71d2b67e3f115297ae505afdb19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sondre=20Engebr=C3=A5ten?= Date: Wed, 24 Apr 2024 10:01:02 +0200 Subject: [PATCH 6/8] fix: Add ignore to allow the use of slices --- functions/.flake8 | 1 + 1 file changed, 1 insertion(+) diff --git a/functions/.flake8 b/functions/.flake8 index 76618dc5..4451dfc7 100644 --- a/functions/.flake8 +++ b/functions/.flake8 @@ -1,6 +1,7 @@ [flake8] max-complexity = 10 max-line-length = 120 +extend-ignore = E203,E701 exclude = .pytest_cache __pycache__/ From 616c1c6a053bf69136c7da5b43cbdfe9674b9287 Mon Sep 17 00:00:00 2001 From: Anton Babenko Date: Wed, 24 Apr 2024 12:36:05 +0200 Subject: [PATCH 7/8] Update functions/notify_slack.py --- functions/notify_slack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions/notify_slack.py b/functions/notify_slack.py index ade5fb4f..4fb1fbdc 100644 --- a/functions/notify_slack.py +++ b/functions/notify_slack.py @@ -322,7 +322,7 @@ def format_aws_backup(message: str) -> Dict[str, Any]: :returns: formatted Slack message payload """ - fields:list[Dict[str, Any]] = [] + fields: list[Dict[str, Any]] = [] attachments = {} title = message.split(".")[0] From c6875021fa541298ed2a9b18590757c4591bdd1e Mon Sep 17 00:00:00 2001 From: Bryant Biggs Date: Wed, 24 Apr 2024 08:03:49 -0400 Subject: [PATCH 8/8] fix: Correct parsing and add all available text case payloads --- functions/.flake8 | 1 - functions/messages/backup.json | 142 +++- functions/notify_slack.py | 71 +- functions/snapshots/snap_notify_slack_test.py | 727 +++++++++++------- 4 files changed, 575 insertions(+), 366 deletions(-) diff --git a/functions/.flake8 b/functions/.flake8 index 4451dfc7..76618dc5 100644 --- a/functions/.flake8 +++ b/functions/.flake8 @@ -1,7 +1,6 @@ [flake8] max-complexity = 10 max-line-length = 120 -extend-ignore = E203,E701 exclude = .pytest_cache __pycache__/ diff --git a/functions/messages/backup.json b/functions/messages/backup.json index 91346476..7fe50c24 100644 --- a/functions/messages/backup.json +++ b/functions/messages/backup.json @@ -1,41 +1,109 @@ { - "Records": [ - { - "EventSource": "aws:sns", - "EventVersion": "1.0", - "EventSubscriptionArn": "arn:aws:sns:...-a3802aa1ed45", - "Sns": { - "Type": "Notification", - "MessageId": "12345678-abcd-123a-def0-abcd1a234567", - "TopicArn": "arn:aws:sns:us-west-1:123456789012:backup-2sqs-sns-topic", - "Subject": "Notification from AWS Backup", - "Message": "An AWS Backup job was completed successfully. Recovery point ARN: arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012d. Resource ARN : arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012e. BackupJob ID : 1b2345b2-f22c-4dab-5eb6-bbc7890ed123", - "Timestamp": "2019-08-02T18:46:02.788Z", - "MessageAttributes": { - "EventType": { - "Type": "String", - "Value": "BACKUP_JOB" - }, - "State": { - "Type": "String", - "Value": "COMPLETED" - }, - "AccountId": { - "Type": "String", - "Value": "123456789012" - }, - "Id": { - "Type": "String", - "Value": "1b2345b2-f22c-4dab-5eb6-bbc7890ed123" - }, - "StartTime": { - "Type": "String", - "Value": "2019-09-02T13:48:52.226Z" - } + "Records": [ + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:...-a3802aa1ed45", + "Sns": { + "Type": "Notification", + "MessageId": "12345678-abcd-123a-def0-abcd1a234567", + "TopicArn": "arn:aws:sns:us-west-1:123456789012:backup-2sqs-sns-topic", + "Subject": "Notification from AWS Backup", + "Message": "An AWS Backup job was completed successfully. Recovery point ARN: arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012d. Resource ARN : arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012e. BackupJob ID : 1b2345b2-f22c-4dab-5eb6-bbc7890ed123", + "Timestamp": "2019-08-02T18:46:02.788Z", + "MessageAttributes": { + "EventType": { + "Type": "String", + "Value": "BACKUP_JOB" + }, + "State": { + "Type": "String", + "Value": "COMPLETED" + }, + "AccountId": { + "Type": "String", + "Value": "123456789012" + }, + "Id": { + "Type": "String", + "Value": "1b2345b2-f22c-4dab-5eb6-bbc7890ed123" + }, + "StartTime": { + "Type": "String", + "Value": "2019-09-02T13:48:52.226Z" } } } - ] - } - - \ No newline at end of file + }, + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:...-a3802aa1ed45", + "Sns": { + "Type": "Notification", + "MessageId": "12345678-abcd-123a-def0-abcd1a234567", + "TopicArn": "arn:aws:sns:us-west-1:123456789012:backup-2sqs-sns-topic", + "Subject": "Notification from AWS Backup", + "Message": "An AWS Backup job failed. Resource ARN : arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012e. BackupJob ID : 1b2345b2-f22c-4dab-5eb6-bbc7890ed123", + "Timestamp": "2019-08-02T18:46:02.788Z", + "MessageAttributes": { + "EventType": { + "Type": "String", + "Value": "BACKUP_JOB" + }, + "State": { + "Type": "String", + "Value": "FAILED" + }, + "AccountId": { + "Type": "String", + "Value": "123456789012" + }, + "Id": { + "Type": "String", + "Value": "1b2345b2-f22c-4dab-5eb6-bbc7890ed123" + }, + "StartTime": { + "Type": "String", + "Value": "2019-09-02T13:48:52.226Z" + } + } + } + }, + { + "EventSource": "aws:sns", + "EventVersion": "1.0", + "EventSubscriptionArn": "arn:aws:sns:...-a3802aa1ed45", + "Sns": { + "Type": "Notification", + "MessageId": "12345678-abcd-123a-def0-abcd1a234567", + "TopicArn": "arn:aws:sns:us-west-1:123456789012:backup-2sqs-sns-topic", + "Subject": "Notification from AWS Backup", + "Message": "An AWS Backup job failed to complete in time. Resource ARN : arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012e. BackupJob ID : 1b2345b2-f22c-4dab-5eb6-bbc7890ed123", + "Timestamp": "2019-08-02T18:46:02.788Z", + "MessageAttributes": { + "EventType": { + "Type": "String", + "Value": "BACKUP_JOB" + }, + "State": { + "Type": "String", + "Value": "EXPIRED" + }, + "AccountId": { + "Type": "String", + "Value": "123456789012" + }, + "Id": { + "Type": "String", + "Value": "1b2345b2-f22c-4dab-5eb6-bbc7890ed123" + }, + "StartTime": { + "Type": "String", + "Value": "2019-09-02T13:48:52.226Z" + } + } + } + } + ] +} diff --git a/functions/notify_slack.py b/functions/notify_slack.py index 4fb1fbdc..d7e7c864 100644 --- a/functions/notify_slack.py +++ b/functions/notify_slack.py @@ -11,6 +11,7 @@ import json import logging import os +import re import urllib.parse import urllib.request from enum import Enum @@ -266,52 +267,32 @@ def format_aws_health(message: Dict[str, Any], region: str) -> Dict[str, Any]: } -def aws_backup_field_parser(message: str) -> Dict[str, Any]: +def aws_backup_field_parser(message: str) -> Dict[str, str]: """ Parser for AWS Backup event message. It extracts the fields from the message and returns a dictionary. :params message: message containing AWS Backup event :returns: dictionary containing the fields extracted from the message """ - field_names = [ - "Recovery point ARN", - "Resource ARN", - "BackupJob ID", - "Backup Job Id", - "Backed up Resource ARN", - "Status Message", - ] - - first = None - field_match = "" - - for field in field_names: - index = message.find(field) - if index != -1 and (first is None or index < first): - first = index - field_match = field - - if first is not None: - next = None - for field in field_names: - index = message.find(field, first + len(field_match) + 1) - if index != -1 and (next is None or index < next): - next = index - - if next is None: - next = len(message) - - rem_message = message[next:] - fields = aws_backup_field_parser(rem_message) - - text = message[first + len(field_match) + 1:next] - while text.startswith(" ") or text.startswith(":"): - text = text[1:] - - fields[field_match] = text - return fields - else: - return {} + # Order is somewhat important, working in reverse order of the message payload + # to reduce right most matched values + field_names = { + "BackupJob ID": r"(BackupJob ID : ).*", + "Resource ARN": r"(Resource ARN : ).*[.]", + "Recovery point ARN": r"(Recovery point ARN: ).*[.]", + } + fields = {} + + for fname, freg in field_names.items(): + match = re.search(freg, message) + if match: + value = match.group(0).split(" ")[-1] + fields[fname] = value.removesuffix(".") + + # Remove the matched field from the message + message = message.replace(match.group(0), "") + + return fields def format_aws_backup(message: str) -> Dict[str, Any]: @@ -328,18 +309,18 @@ def format_aws_backup(message: str) -> Dict[str, Any]: title = message.split(".")[0] if "failed" in title: - title = title + " ⚠️" + title = f"⚠️ {title}" if "completed" in title: - title = title + " ✅" + title = f"✅ {title}" fields.append({"title": title}) - list_items = aws_backup_field_parser(message) + backup_fields = aws_backup_field_parser(message) - for k, v in list_items.items(): + for k, v in backup_fields.items(): fields.append({"value": k, "short": False}) - fields.append({"value": "```\n" + v + "\n```", "short": False}) + fields.append({"value": f"`{v}`", "short": False}) attachments["fields"] = fields # type: ignore diff --git a/functions/snapshots/snap_notify_slack_test.py b/functions/snapshots/snap_notify_slack_test.py index a3b9002a..a8ec24cf 100644 --- a/functions/snapshots/snap_notify_slack_test.py +++ b/functions/snapshots/snap_notify_slack_test.py @@ -7,465 +7,626 @@ snapshots = Snapshot() -snapshots[ - "test_event_get_slack_message_payload_snapshots event_aws_health_event.json" -] = [ +snapshots['test_event_get_slack_message_payload_snapshots event_aws_health_event.json'] = [ { - "attachments": [ + 'attachments': [ { - "color": "danger", - "fallback": "New AWS Health Event for EC2", - "fields": [ - {"short": True, "title": "Affected Service", "value": "`EC2`"}, - {"short": True, "title": "Affected Region", "value": "`us-west-2`"}, + 'color': 'danger', + 'fallback': 'New AWS Health Event for EC2', + 'fields': [ { - "short": False, - "title": "Code", - "value": "`AWS_EC2_INSTANCE_STORE_DRIVE_PERFORMANCE_DEGRADED`", + 'short': True, + 'title': 'Affected Service', + 'value': '`EC2`' }, { - "short": False, - "title": "Event Description", - "value": "`A description of the event will be provided here`", + 'short': True, + 'title': 'Affected Region', + 'value': '`us-west-2`' }, { - "short": False, - "title": "Affected Resources", - "value": "`i-abcd1111`", + 'short': False, + 'title': 'Code', + 'value': '`AWS_EC2_INSTANCE_STORE_DRIVE_PERFORMANCE_DEGRADED`' }, { - "short": True, - "title": "Start Time", - "value": "`Sat, 05 Jun 2016 15:10:09 GMT`", + 'short': False, + 'title': 'Event Description', + 'value': '`A description of the event will be provided here`' }, - {"short": True, "title": "End Time", "value": "``"}, { - "short": False, - "title": "Link to Event", - "value": "https://phd.aws.amazon.com/phd/home?region=us-west-2#/dashboard/open-issues", + 'short': False, + 'title': 'Affected Resources', + 'value': '`i-abcd1111`' }, + { + 'short': True, + 'title': 'Start Time', + 'value': '`Sat, 05 Jun 2016 15:10:09 GMT`' + }, + { + 'short': True, + 'title': 'End Time', + 'value': '``' + }, + { + 'short': False, + 'title': 'Link to Event', + 'value': 'https://phd.aws.amazon.com/phd/home?region=us-west-2#/dashboard/open-issues' + } ], - "text": "New AWS Health Event for EC2", + 'text': 'New AWS Health Event for EC2' } ], - "channel": "slack_testing_sandbox", - "icon_emoji": ":aws:", - "username": "notify_slack_test", + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' } ] -snapshots[ - "test_event_get_slack_message_payload_snapshots event_cloudwatch_alarm.json" -] = [ +snapshots['test_event_get_slack_message_payload_snapshots event_cloudwatch_alarm.json'] = [ { - "attachments": [ + 'attachments': [ { - "color": "danger", - "fallback": "Alarm Example triggered", - "fields": [ - {"short": True, "title": "Alarm Name", "value": "`Example`"}, + 'color': 'danger', + 'fallback': 'Alarm Example triggered', + 'fields': [ { - "short": False, - "title": "Alarm Description", - "value": "`Example alarm description.`", + 'short': True, + 'title': 'Alarm Name', + 'value': '`Example`' }, { - "short": False, - "title": "Alarm reason", - "value": "`Threshold Crossed`", + 'short': False, + 'title': 'Alarm Description', + 'value': '`Example alarm description.`' }, - {"short": True, "title": "Old State", "value": "`OK`"}, - {"short": True, "title": "Current State", "value": "`ALARM`"}, { - "short": False, - "title": "Link to Alarm", - "value": "https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#alarm:alarmFilter=ANY;name=Example", + 'short': False, + 'title': 'Alarm reason', + 'value': '`Threshold Crossed`' }, + { + 'short': True, + 'title': 'Old State', + 'value': '`OK`' + }, + { + 'short': True, + 'title': 'Current State', + 'value': '`ALARM`' + }, + { + 'short': False, + 'title': 'Link to Alarm', + 'value': 'https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#alarm:alarmFilter=ANY;name=Example' + } ], - "text": "AWS CloudWatch notification - Example", + 'text': 'AWS CloudWatch notification - Example' } ], - "channel": "slack_testing_sandbox", - "icon_emoji": ":aws:", - "username": "notify_slack_test", + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' } ] -snapshots[ - "test_event_get_slack_message_payload_snapshots event_guardduty_finding_high.json" -] = [ +snapshots['test_event_get_slack_message_payload_snapshots event_guardduty_finding_high.json'] = [ { - "attachments": [ + 'attachments': [ { - "color": "danger", - "fallback": "GuardDuty Finding: SAMPLE Unprotected port on EC2 instance i-123123123 is being probed", - "fields": [ + 'color': 'danger', + 'fallback': 'GuardDuty Finding: SAMPLE Unprotected port on EC2 instance i-123123123 is being probed', + 'fields': [ { - "short": False, - "title": "Description", - "value": "`EC2 instance has an unprotected port which is being probed by a known malicious host.`", + 'short': False, + 'title': 'Description', + 'value': '`EC2 instance has an unprotected port which is being probed by a known malicious host.`' }, { - "short": False, - "title": "Finding Type", - "value": "`Recon:EC2 PortProbeUnprotectedPort`", + 'short': False, + 'title': 'Finding Type', + 'value': '`Recon:EC2 PortProbeUnprotectedPort`' }, { - "short": True, - "title": "First Seen", - "value": "`2020-01-02T01:02:03Z`", + 'short': True, + 'title': 'First Seen', + 'value': '`2020-01-02T01:02:03Z`' }, { - "short": True, - "title": "Last Seen", - "value": "`2020-01-03T01:02:03Z`", + 'short': True, + 'title': 'Last Seen', + 'value': '`2020-01-03T01:02:03Z`' }, - {"short": True, "title": "Severity", "value": "`High`"}, - {"short": True, "title": "Account ID", "value": "`123456789`"}, - {"short": True, "title": "Count", "value": "`1234`"}, { - "short": False, - "title": "Link to Finding", - "value": "https://console.aws.amazon.com/guardduty/home?region=us-east-1#/findings?search=id%3Dsample-id-2", + 'short': True, + 'title': 'Severity', + 'value': '`High`' }, + { + 'short': True, + 'title': 'Account ID', + 'value': '`123456789`' + }, + { + 'short': True, + 'title': 'Count', + 'value': '`1234`' + }, + { + 'short': False, + 'title': 'Link to Finding', + 'value': 'https://console.aws.amazon.com/guardduty/home?region=us-east-1#/findings?search=id%3Dsample-id-2' + } ], - "text": "AWS GuardDuty Finding - SAMPLE Unprotected port on EC2 instance i-123123123 is being probed", + 'text': 'AWS GuardDuty Finding - SAMPLE Unprotected port on EC2 instance i-123123123 is being probed' } ], - "channel": "slack_testing_sandbox", - "icon_emoji": ":aws:", - "username": "notify_slack_test", + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' } ] -snapshots[ - "test_event_get_slack_message_payload_snapshots event_guardduty_finding_low.json" -] = [ +snapshots['test_event_get_slack_message_payload_snapshots event_guardduty_finding_low.json'] = [ { - "attachments": [ + 'attachments': [ { - "color": "#777777", - "fallback": "GuardDuty Finding: SAMPLE Unprotected port on EC2 instance i-123123123 is being probed", - "fields": [ + 'color': '#777777', + 'fallback': 'GuardDuty Finding: SAMPLE Unprotected port on EC2 instance i-123123123 is being probed', + 'fields': [ { - "short": False, - "title": "Description", - "value": "`EC2 instance has an unprotected port which is being probed by a known malicious host.`", + 'short': False, + 'title': 'Description', + 'value': '`EC2 instance has an unprotected port which is being probed by a known malicious host.`' }, { - "short": False, - "title": "Finding Type", - "value": "`Recon:EC2 PortProbeUnprotectedPort`", + 'short': False, + 'title': 'Finding Type', + 'value': '`Recon:EC2 PortProbeUnprotectedPort`' }, { - "short": True, - "title": "First Seen", - "value": "`2020-01-02T01:02:03Z`", + 'short': True, + 'title': 'First Seen', + 'value': '`2020-01-02T01:02:03Z`' }, { - "short": True, - "title": "Last Seen", - "value": "`2020-01-03T01:02:03Z`", + 'short': True, + 'title': 'Last Seen', + 'value': '`2020-01-03T01:02:03Z`' }, - {"short": True, "title": "Severity", "value": "`Low`"}, - {"short": True, "title": "Account ID", "value": "`123456789`"}, - {"short": True, "title": "Count", "value": "`1234`"}, { - "short": False, - "title": "Link to Finding", - "value": "https://console.aws.amazon.com/guardduty/home?region=us-east-1#/findings?search=id%3Dsample-id-2", + 'short': True, + 'title': 'Severity', + 'value': '`Low`' }, + { + 'short': True, + 'title': 'Account ID', + 'value': '`123456789`' + }, + { + 'short': True, + 'title': 'Count', + 'value': '`1234`' + }, + { + 'short': False, + 'title': 'Link to Finding', + 'value': 'https://console.aws.amazon.com/guardduty/home?region=us-east-1#/findings?search=id%3Dsample-id-2' + } ], - "text": "AWS GuardDuty Finding - SAMPLE Unprotected port on EC2 instance i-123123123 is being probed", + 'text': 'AWS GuardDuty Finding - SAMPLE Unprotected port on EC2 instance i-123123123 is being probed' } ], - "channel": "slack_testing_sandbox", - "icon_emoji": ":aws:", - "username": "notify_slack_test", + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' } ] -snapshots[ - "test_event_get_slack_message_payload_snapshots event_guardduty_finding_medium.json" -] = [ +snapshots['test_event_get_slack_message_payload_snapshots event_guardduty_finding_medium.json'] = [ { - "attachments": [ + 'attachments': [ { - "color": "warning", - "fallback": "GuardDuty Finding: SAMPLE Unprotected port on EC2 instance i-123123123 is being probed", - "fields": [ + 'color': 'warning', + 'fallback': 'GuardDuty Finding: SAMPLE Unprotected port on EC2 instance i-123123123 is being probed', + 'fields': [ { - "short": False, - "title": "Description", - "value": "`EC2 instance has an unprotected port which is being probed by a known malicious host.`", + 'short': False, + 'title': 'Description', + 'value': '`EC2 instance has an unprotected port which is being probed by a known malicious host.`' }, { - "short": False, - "title": "Finding Type", - "value": "`Recon:EC2 PortProbeUnprotectedPort`", + 'short': False, + 'title': 'Finding Type', + 'value': '`Recon:EC2 PortProbeUnprotectedPort`' }, { - "short": True, - "title": "First Seen", - "value": "`2020-01-02T01:02:03Z`", + 'short': True, + 'title': 'First Seen', + 'value': '`2020-01-02T01:02:03Z`' }, { - "short": True, - "title": "Last Seen", - "value": "`2020-01-03T01:02:03Z`", + 'short': True, + 'title': 'Last Seen', + 'value': '`2020-01-03T01:02:03Z`' }, - {"short": True, "title": "Severity", "value": "`Medium`"}, - {"short": True, "title": "Account ID", "value": "`123456789`"}, - {"short": True, "title": "Count", "value": "`1234`"}, { - "short": False, - "title": "Link to Finding", - "value": "https://console.aws.amazon.com/guardduty/home?region=us-east-1#/findings?search=id%3Dsample-id-2", + 'short': True, + 'title': 'Severity', + 'value': '`Medium`' }, + { + 'short': True, + 'title': 'Account ID', + 'value': '`123456789`' + }, + { + 'short': True, + 'title': 'Count', + 'value': '`1234`' + }, + { + 'short': False, + 'title': 'Link to Finding', + 'value': 'https://console.aws.amazon.com/guardduty/home?region=us-east-1#/findings?search=id%3Dsample-id-2' + } ], - "text": "AWS GuardDuty Finding - SAMPLE Unprotected port on EC2 instance i-123123123 is being probed", + 'text': 'AWS GuardDuty Finding - SAMPLE Unprotected port on EC2 instance i-123123123 is being probed' } ], - "channel": "slack_testing_sandbox", - "icon_emoji": ":aws:", - "username": "notify_slack_test", + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' } ] -snapshots["test_sns_get_slack_message_payload_snapshots message_backup.json"] = [ +snapshots['test_sns_get_slack_message_payload_snapshots message_backup.json'] = [ { - "attachments": [ + 'attachments': [ { - "fields": [ - {"title": "An AWS Backup job was completed successfully ✅"}, - {"short": False, "value": "BackupJob ID"}, + 'fields': [ + { + 'title': '✅ An AWS Backup job was completed successfully' + }, + { + 'short': False, + 'value': 'BackupJob ID' + }, + { + 'short': False, + 'value': '`1b2345b2-f22c-4dab-5eb6-bbc7890ed123`' + }, { - "short": False, - "value": """``` -1b2345b2-f22c-4dab-5eb6-bbc7890ed123 -```""", + 'short': False, + 'value': 'Resource ARN' }, - {"short": False, "value": "Resource ARN"}, { - "short": False, - "value": """``` -arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012e. -```""", + 'short': False, + 'value': '`arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012e`' }, - {"short": False, "value": "Recovery point ARN"}, { - "short": False, - "value": """``` -arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012d. -```""", + 'short': False, + 'value': 'Recovery point ARN' }, + { + 'short': False, + 'value': '`arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012d`' + } ] } ], - "channel": "slack_testing_sandbox", - "icon_emoji": ":aws:", - "username": "notify_slack_test", + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' + }, + { + 'attachments': [ + { + 'fields': [ + { + 'title': '⚠️ An AWS Backup job failed' + }, + { + 'short': False, + 'value': 'BackupJob ID' + }, + { + 'short': False, + 'value': '`1b2345b2-f22c-4dab-5eb6-bbc7890ed123`' + }, + { + 'short': False, + 'value': 'Resource ARN' + }, + { + 'short': False, + 'value': '`arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012e`' + } + ] + } + ], + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' + }, + { + 'attachments': [ + { + 'fields': [ + { + 'title': '⚠️ An AWS Backup job failed to complete in time' + }, + { + 'short': False, + 'value': 'BackupJob ID' + }, + { + 'short': False, + 'value': '`1b2345b2-f22c-4dab-5eb6-bbc7890ed123`' + }, + { + 'short': False, + 'value': 'Resource ARN' + }, + { + 'short': False, + 'value': '`arn:aws:ec2:us-west-1:123456789012:volume/vol-012f345df6789012e`' + } + ] + } + ], + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' } ] -snapshots[ - "test_sns_get_slack_message_payload_snapshots message_cloudwatch_alarm.json" -] = [ +snapshots['test_sns_get_slack_message_payload_snapshots message_cloudwatch_alarm.json'] = [ { - "attachments": [ + 'attachments': [ { - "color": "good", - "fallback": "Alarm DBMigrationRequired triggered", - "fields": [ + 'color': 'good', + 'fallback': 'Alarm DBMigrationRequired triggered', + 'fields': [ + { + 'short': True, + 'title': 'Alarm Name', + 'value': '`DBMigrationRequired`' + }, { - "short": True, - "title": "Alarm Name", - "value": "`DBMigrationRequired`", + 'short': False, + 'title': 'Alarm Description', + 'value': '`App is reporting "A JPA error occurred(Unable to build EntityManagerFactory)"`' }, { - "short": False, - "title": "Alarm Description", - "value": '`App is reporting "A JPA error occurred(Unable to build EntityManagerFactory)"`', + 'short': False, + 'title': 'Alarm reason', + 'value': '`Threshold Crossed: 1 datapoint [1.0 (12/02/19 15:44:00)] was not less than the threshold (1.0).`' }, { - "short": False, - "title": "Alarm reason", - "value": "`Threshold Crossed: 1 datapoint [1.0 (12/02/19 15:44:00)] was not less than the threshold (1.0).`", + 'short': True, + 'title': 'Old State', + 'value': '`ALARM`' }, - {"short": True, "title": "Old State", "value": "`ALARM`"}, - {"short": True, "title": "Current State", "value": "`OK`"}, { - "short": False, - "title": "Link to Alarm", - "value": "https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#alarm:alarmFilter=ANY;name=DBMigrationRequired", + 'short': True, + 'title': 'Current State', + 'value': '`OK`' }, + { + 'short': False, + 'title': 'Link to Alarm', + 'value': 'https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#alarm:alarmFilter=ANY;name=DBMigrationRequired' + } ], - "text": "AWS CloudWatch notification - DBMigrationRequired", + 'text': 'AWS CloudWatch notification - DBMigrationRequired' } ], - "channel": "slack_testing_sandbox", - "icon_emoji": ":aws:", - "username": "notify_slack_test", + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' } ] -snapshots[ - "test_sns_get_slack_message_payload_snapshots message_dms_notification.json" -] = [ +snapshots['test_sns_get_slack_message_payload_snapshots message_dms_notification.json'] = [ { - "attachments": [ + 'attachments': [ { - "fallback": "A new message", - "fields": [ + 'fallback': 'A new message', + 'fields': [ { - "short": True, - "title": "Event Source", - "value": "`replication-task`", + 'short': True, + 'title': 'Event Source', + 'value': '`replication-task`' }, { - "short": True, - "title": "Event Time", - "value": "`2019-02-12 15:45:24.091`", + 'short': True, + 'title': 'Event Time', + 'value': '`2019-02-12 15:45:24.091`' }, { - "short": False, - "title": "Identifier Link", - "value": "`https://console.aws.amazon.com/dms/home?region=us-east-1#tasks:ids=hello-world`", + 'short': False, + 'title': 'Identifier Link', + 'value': '`https://console.aws.amazon.com/dms/home?region=us-east-1#tasks:ids=hello-world`' }, - {"short": True, "title": "SourceId", "value": "`hello-world`"}, { - "short": False, - "title": "Event ID", - "value": "`http://docs.aws.amazon.com/dms/latest/userguide/CHAP_Events.html#DMS-EVENT-0079 `", + 'short': True, + 'title': 'SourceId', + 'value': '`hello-world`' }, { - "short": False, - "title": "Event Message", - "value": "`Replication task has stopped.`", + 'short': False, + 'title': 'Event ID', + 'value': '`http://docs.aws.amazon.com/dms/latest/userguide/CHAP_Events.html#DMS-EVENT-0079 `' }, + { + 'short': False, + 'title': 'Event Message', + 'value': '`Replication task has stopped.`' + } + ], + 'mrkdwn_in': [ + 'value' ], - "mrkdwn_in": ["value"], - "text": "AWS notification", - "title": "DMS Notification Message", + 'text': 'AWS notification', + 'title': 'DMS Notification Message' } ], - "channel": "slack_testing_sandbox", - "icon_emoji": ":aws:", - "username": "notify_slack_test", + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' } ] -snapshots[ - "test_sns_get_slack_message_payload_snapshots message_glue_notification.json" -] = [ +snapshots['test_sns_get_slack_message_payload_snapshots message_glue_notification.json'] = [ { - "attachments": [ + 'attachments': [ { - "fallback": "A new message", - "fields": [ - {"short": True, "title": "version", "value": "`0`"}, + 'fallback': 'A new message', + 'fields': [ + { + 'short': True, + 'title': 'version', + 'value': '`0`' + }, + { + 'short': False, + 'title': 'id', + 'value': '`ad3c3da1-148c-d5da-9a6a-79f1bc9a8a2e`' + }, + { + 'short': True, + 'title': 'detail-type', + 'value': '`Glue Job State Change`' + }, { - "short": False, - "title": "id", - "value": "`ad3c3da1-148c-d5da-9a6a-79f1bc9a8a2e`", + 'short': True, + 'title': 'source', + 'value': '`aws.glue`' }, { - "short": True, - "title": "detail-type", - "value": "`Glue Job State Change`", + 'short': True, + 'title': 'account', + 'value': '`000000000000`' }, - {"short": True, "title": "source", "value": "`aws.glue`"}, - {"short": True, "title": "account", "value": "`000000000000`"}, - {"short": True, "title": "time", "value": "`2021-06-18T12:34:06Z`"}, - {"short": True, "title": "region", "value": "`us-east-2`"}, - {"short": True, "title": "resources", "value": "`[]`"}, { - "short": False, - "title": "detail", - "value": '`{"jobName": "test_job", "severity": "ERROR", "state": "FAILED", "jobRunId": "jr_ca2144d747b45ad412d3c66a1b6934b6b27aa252be9a21a95c54dfaa224a1925", "message": "SystemExit: 1"}`', + 'short': True, + 'title': 'time', + 'value': '`2021-06-18T12:34:06Z`' }, + { + 'short': True, + 'title': 'region', + 'value': '`us-east-2`' + }, + { + 'short': True, + 'title': 'resources', + 'value': '`[]`' + }, + { + 'short': False, + 'title': 'detail', + 'value': '`{"jobName": "test_job", "severity": "ERROR", "state": "FAILED", "jobRunId": "jr_ca2144d747b45ad412d3c66a1b6934b6b27aa252be9a21a95c54dfaa224a1925", "message": "SystemExit: 1"}`' + } ], - "mrkdwn_in": ["value"], - "text": "AWS notification", - "title": "Message", + 'mrkdwn_in': [ + 'value' + ], + 'text': 'AWS notification', + 'title': 'Message' } ], - "channel": "slack_testing_sandbox", - "icon_emoji": ":aws:", - "username": "notify_slack_test", + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' } ] -snapshots[ - "test_sns_get_slack_message_payload_snapshots message_guardduty_finding.json" -] = [ +snapshots['test_sns_get_slack_message_payload_snapshots message_guardduty_finding.json'] = [ { - "attachments": [ + 'attachments': [ { - "color": "danger", - "fallback": "GuardDuty Finding: SAMPLE Unprotected port on EC2 instance i-123123123 is being probed", - "fields": [ + 'color': 'danger', + 'fallback': 'GuardDuty Finding: SAMPLE Unprotected port on EC2 instance i-123123123 is being probed', + 'fields': [ + { + 'short': False, + 'title': 'Description', + 'value': '`EC2 instance has an unprotected port which is being probed by a known malicious host.`' + }, { - "short": False, - "title": "Description", - "value": "`EC2 instance has an unprotected port which is being probed by a known malicious host.`", + 'short': False, + 'title': 'Finding Type', + 'value': '`Recon:EC2 PortProbeUnprotectedPort`' }, { - "short": False, - "title": "Finding Type", - "value": "`Recon:EC2 PortProbeUnprotectedPort`", + 'short': True, + 'title': 'First Seen', + 'value': '`2020-01-02T01:02:03Z`' }, { - "short": True, - "title": "First Seen", - "value": "`2020-01-02T01:02:03Z`", + 'short': True, + 'title': 'Last Seen', + 'value': '`2020-01-03T01:02:03Z`' }, { - "short": True, - "title": "Last Seen", - "value": "`2020-01-03T01:02:03Z`", + 'short': True, + 'title': 'Severity', + 'value': '`High`' }, - {"short": True, "title": "Severity", "value": "`High`"}, - {"short": True, "title": "Account ID", "value": "`123456789`"}, - {"short": True, "title": "Count", "value": "`1234`"}, { - "short": False, - "title": "Link to Finding", - "value": "https://console.amazonaws-us-gov.com/guardduty/home?region=us-gov-east-1#/findings?search=id%3Dsample-id-2", + 'short': True, + 'title': 'Account ID', + 'value': '`123456789`' }, + { + 'short': True, + 'title': 'Count', + 'value': '`1234`' + }, + { + 'short': False, + 'title': 'Link to Finding', + 'value': 'https://console.amazonaws-us-gov.com/guardduty/home?region=us-gov-east-1#/findings?search=id%3Dsample-id-2' + } ], - "text": "AWS GuardDuty Finding - SAMPLE Unprotected port on EC2 instance i-123123123 is being probed", + 'text': 'AWS GuardDuty Finding - SAMPLE Unprotected port on EC2 instance i-123123123 is being probed' } ], - "channel": "slack_testing_sandbox", - "icon_emoji": ":aws:", - "username": "notify_slack_test", + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' } ] -snapshots["test_sns_get_slack_message_payload_snapshots message_text_message.json"] = [ +snapshots['test_sns_get_slack_message_payload_snapshots message_text_message.json'] = [ { - "attachments": [ + 'attachments': [ { - "fallback": "A new message", - "fields": [ + 'fallback': 'A new message', + 'fields': [ { - "short": False, - "value": """This + 'short': False, + 'value': '''This is a typical multi-line message from SNS! -Have a ~good~ amazing day! :)""", +Have a ~good~ amazing day! :)''' } ], - "mrkdwn_in": ["value"], - "text": "AWS notification", - "title": "All Fine", + 'mrkdwn_in': [ + 'value' + ], + 'text': 'AWS notification', + 'title': 'All Fine' } ], - "channel": "slack_testing_sandbox", - "icon_emoji": ":aws:", - "username": "notify_slack_test", + 'channel': 'slack_testing_sandbox', + 'icon_emoji': ':aws:', + 'username': 'notify_slack_test' } ]