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

AWS Direct Parser #84

Merged
merged 11 commits into from
Sep 28, 2021
2 changes: 2 additions & 0 deletions circuit_maintenance_parser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .provider import (
GenericProvider,
AquaComms,
AWS,
Cogent,
Colt,
EUNetworks,
Expand All @@ -29,6 +30,7 @@
SUPPORTED_PROVIDERS = (
GenericProvider,
AquaComms,
AWS,
Cogent,
Colt,
EUNetworks,
Expand Down
23 changes: 23 additions & 0 deletions circuit_maintenance_parser/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,26 @@ def parser_hook(self, raw: bytes):
def parse_csv(raw: bytes) -> List[Dict]:
"""Custom CSV parsing."""
raise NotImplementedError


class Text(Parser):
"""Text parser."""

_data_types = ["text/plain"]

def parser_hook(self, raw: bytes):
"""Execute parsing."""
result = []
text = self.get_text_hook(raw)
for data in self.parse_text(text):
result.append(data)
return result

@staticmethod
def get_text_hook(raw: bytes) -> str:
"""Can be overwritten by subclasses."""
return raw.decode()

def parse_text(self, text) -> List[Dict]:
"""Custom text parsing."""
raise NotImplementedError
88 changes: 88 additions & 0 deletions circuit_maintenance_parser/parsers/aws.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""AquaComms parser."""
import hashlib
import logging
import quopri
import re

import bs4 # type: ignore

from dateutil import parser

from circuit_maintenance_parser.parser import CircuitImpact, EmailSubjectParser, Impact, Status, Text

# pylint: disable=too-many-nested-blocks, too-many-branches

logger = logging.getLogger(__name__)


class SubjectParserAWS1(EmailSubjectParser):
"""Subject parser for AWS notifications."""

def parse_subject(self, subject):
"""Parse subject.

Example: AWS Direct Connect Planned Maintenance Notification [AWS Account: 00000001]
"""
data = {}
search = re.search(r"\[AWS Account ?I?D?: ([0-9]+)\]", subject)
if search:
data["account"] = search.group(1)
return [data]


class TextParserAWS1(Text):
"""Parse text body of email."""

@staticmethod
def get_text_hook(raw):
"""Modify soup before entering `parse_text`."""
soup = bs4.BeautifulSoup(quopri.decodestring(raw), features="lxml")
return soup.text

def parse_text(self, text):
"""Parse text.

Example:
Hello,

Planned maintenance has been scheduled on an AWS Direct Connect router in A=
Block, New York, NY from Thu, 20 May 2021 08:00:00 GMT to Thu, 20 Ma=
y 2021 14:00:00 GMT for 6 hours. During this maintenance window, your AWS D=
irect Connect services listed below may become unavailable.

aaaaa-00000001
aaaaa-00000002
aaaaa-00000003
aaaaa-00000004
aaaaa-00000005
aaaaa-00000006

This maintenance is scheduled to avoid disrupting redundant connections at =
the same time.
"""
data = {"circuits": []}
impact = Impact.OUTAGE
maintenace_id = ""
status = Status.CONFIRMED
for line in text.splitlines():
if "planned maintenance" in line.lower():
data["summary"] = line
search = re.search(
r"([A-Z][a-z]{2}, [0-9]{1,2} [A-Z][a-z]{2,9} [0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2} [A-Z]{2,3}) to ([A-Z][a-z]{2}, [0-9]{1,2} [A-Z][a-z]{2,9} [0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2} [A-Z]{2,3})",
line,
)
if search:
data["start"] = self.dt2ts(parser.parse(search.group(1)))
data["end"] = self.dt2ts(parser.parse(search.group(2)))
maintenace_id += str(data["start"])
maintenace_id += str(data["end"])
if "may become unavailable" in line.lower():
impact = Impact.OUTAGE
elif "has been cancelled" in line.lower():
status = Status.CANCELLED
elif re.match(r"[a-z]{5}-[a-z0-9]{8}", line):
maintenace_id += line
data["circuits"].append(CircuitImpact(circuit_id=line, impact=impact))
data["maintenance_id"] = hashlib.md5(maintenace_id.encode("utf-8")).hexdigest() # nosec
chadell marked this conversation as resolved.
Show resolved Hide resolved
data["status"] = status
return [data]
10 changes: 10 additions & 0 deletions circuit_maintenance_parser/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from circuit_maintenance_parser.processor import CombinedProcessor, SimpleProcessor, GenericProcessor

from circuit_maintenance_parser.parsers.aquacomms import HtmlParserAquaComms1, SubjectParserAquaComms1
from circuit_maintenance_parser.parsers.aws import SubjectParserAWS1, TextParserAWS1
from circuit_maintenance_parser.parsers.cogent import HtmlParserCogent1
from circuit_maintenance_parser.parsers.colt import ICalParserColt1, CsvParserColt1
from circuit_maintenance_parser.parsers.gtt import HtmlParserGTT1
Expand Down Expand Up @@ -116,6 +117,15 @@ class AquaComms(GenericProvider):
_default_organizer = "[email protected]"


class AWS(GenericProvider):
"""AWS provider custom class."""

_processors: List[GenericProcessor] = [
CombinedProcessor(data_parsers=[EmailDateParser, TextParserAWS1, SubjectParserAWS1]),
]
_default_organizer = "[email protected]"


class Cogent(GenericProvider):
"""Cogent provider custom class."""

Expand Down
52 changes: 52 additions & 0 deletions tests/unit/data/aws/aws1.eml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
Subject: [rCluster Request] [rCloud AWS Notification] AWS Direct Connect
Planned Maintenance Notification [AWS Account: 0000000000001]
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-SM-COMMUNICATION: true
X-SM-COMMUNICATION-TYPE: AWS_DIRECTCONNECT_MAINTENANCE_SCHEDULED
X-SM-DEDUPING-ID: 7cc8bab7-00bb-44e0-a3ec-bdd1a5560b80-EMAIL--1012261942-036424c1a19ca69ca7ea459ebd6823e1
Date: Thu, 6 May 2021 21:52:56 +0000
Feedback-ID: 1.us-east-1.xvKJ2gIiw98/SnInpbS9SQT1XBoAzwrySbDsqgMkBQI=:AmazonSES
X-SES-Outgoing: 2021.05.06-54.240.48.83
X-Original-Sender: [email protected]
X-Original-Authentication-Results: mx.google.com; dkim=pass
[email protected] header.s=szqgv33erturdv5cvz4vtb5qcy53gdkn
header.b=IQc0x0aC; dkim=pass [email protected]
header.s=ug7nbtf4gccmlpwj322ax3p6ow6yfsug header.b=X4gZtDlT; spf=pass
(google.com: domain of 0100017943ab6519-f09ba161-049c-45e4-8ff3-698af4d94f86-000000@amazonses.com
designates 54.240.48.83 as permitted sender) smtp.mailfrom=0100017943ab6519-f09ba161-049c-45e4-8ff3-698af4d94f86-000000@amazonses.com;
dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amazon.com
X-Original-From: "Amazon Web Services, Inc." <[email protected]>
Reply-To: "Amazon Web Services, Inc." <[email protected]>
Precedence: list

Hello,

Planned maintenance has been scheduled on an AWS Direct Connect router in A=
Block, New York, NY from Thu, 20 May 2021 08:00:00 GMT to Thu, 20 Ma=
y 2021 14:00:00 GMT for 6 hours. During this maintenance window, your AWS D=
irect Connect services listed below may become unavailable.

aaaaa-00000001
aaaaa-00000002
aaaaa-00000003
aaaaa-00000004
aaaaa-00000005
aaaaa-00000006

This maintenance is scheduled to avoid disrupting redundant connections at =
the same time.

If you encounter any problems with your connection after the end of this ma=
intenance window, please contact AWS Support[1].

[1] https://aws.amazon.com/support

Sincerely,
Amazon Web Services

Amazon Web Services, Inc. is a subsidiary of Amazon.com, Inc. Amazon.com is=
a registered trademark of Amazon.com, Inc. This message was produced and d=
istributed by Amazon Web Services Inc., 410 Terry Ave. North, Seattle, WA 9=
8109-5210.
41 changes: 41 additions & 0 deletions tests/unit/data/aws/aws1_result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[
{
"account": "0000000000001",
"circuits": [
{
"circuit_id": "aaaaa-00000001",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000002",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000003",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000004",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000005",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000006",
"impact": "OUTAGE"
}
],
"end": 1621519200,
"maintenance_id": "15faf02fcf2e999792668df97828bc76",
"organizer": "[email protected]",
"provider": "aws",
"sequence": 1,
"stamp": 1620337976,
"start": 1621497600,
"status": "CONFIRMED",
"summary": "Planned maintenance has been scheduled on an AWS Direct Connect router in A Block, New York, NY from Thu, 20 May 2021 08:00:00 GMT to Thu, 20 May 2021 14:00:00 GMT for 6 hours. During this maintenance window, your AWS Direct Connect services listed below may become unavailable.",
"uid": "0"
}
]
5 changes: 5 additions & 0 deletions tests/unit/data/aws/aws1_subject_parser_result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
{
"account": "0000000000001"
}
]
35 changes: 35 additions & 0 deletions tests/unit/data/aws/aws1_text_parser_result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[
{
"circuits": [
{
"circuit_id": "aaaaa-00000001",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000002",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000003",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000004",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000005",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000006",
"impact": "OUTAGE"
}
],
"end": 1621519200,
"maintenance_id": "15faf02fcf2e999792668df97828bc76",
"start": 1621497600,
"status": "CONFIRMED",
"summary": "Planned maintenance has been scheduled on an AWS Direct Connect router in A Block, New York, NY from Thu, 20 May 2021 08:00:00 GMT to Thu, 20 May 2021 14:00:00 GMT for 6 hours. During this maintenance window, your AWS Direct Connect services listed below may become unavailable."
}
]
45 changes: 45 additions & 0 deletions tests/unit/data/aws/aws2.eml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
Subject: [rCluster Request] [rCloud AWS Notification] AWS Direct Connect
Planned Maintenance Notification [AWS Account: 0000000000001]
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-SM-COMMUNICATION: true
X-SM-COMMUNICATION-TYPE: AWS_DIRECTCONNECT_MAINTENANCE_SCHEDULED
X-SM-DEDUPING-ID: 7cc8bab7-00bb-44e0-a3ec-bdd1a5560b80-EMAIL--1012261942-036424c1a19ca69ca7ea459ebd6823e1
Date: Thu, 6 May 2021 21:52:56 +0000
Feedback-ID: 1.us-east-1.xvKJ2gIiw98/SnInpbS9SQT1XBoAzwrySbDsqgMkBQI=:AmazonSES
X-SES-Outgoing: 2021.05.06-54.240.48.83
X-Original-Sender: [email protected]
X-Original-Authentication-Results: mx.google.com; dkim=pass
[email protected] header.s=szqgv33erturdv5cvz4vtb5qcy53gdkn
header.b=IQc0x0aC; dkim=pass [email protected]
header.s=ug7nbtf4gccmlpwj322ax3p6ow6yfsug header.b=X4gZtDlT; spf=pass
(google.com: domain of 0100017943ab6519-f09ba161-049c-45e4-8ff3-698af4d94f86-000000@amazonses.com
designates 54.240.48.83 as permitted sender) smtp.mailfrom=0100017943ab6519-f09ba161-049c-45e4-8ff3-698af4d94f86-000000@amazonses.com;
dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=amazon.com
X-Original-From: "Amazon Web Services, Inc." <[email protected]>
Reply-To: "Amazon Web Services, Inc." <[email protected]>
Precedence: list

Hello,

We would like to inform you that the planned maintenance that was scheduled for AWS Direct Connect endpoint in Equinix SG2, Singapore, SGP from Mon, 13 Sep 2021 19:02:00 GMT to Tue, 14 Sep 2021 02:02:00 GMT has been cancelled. Please find below your AWS Direct Connect services that would have been affected by this planned maintenance.

aaaaa-00000001
aaaaa-00000002
aaaaa-00000003
aaaaa-00000004
aaaaa-00000005
aaaaa-00000006

We sincerely regret any inconvenience our planning process may have caused you. If you have any questions regarding the planned work, or if you would like to report a fault or adjust your contact information, please contact AWS Support[1].

[1] https://aws.amazon.com/support

Sincerely,
Amazon Web Services

Amazon Web Services, Inc. is a subsidiary of Amazon.com, Inc. Amazon.com is=
a registered trademark of Amazon.com, Inc. This message was produced and d=
istributed by Amazon Web Services Inc., 410 Terry Ave. North, Seattle, WA 9=
8109-5210.
41 changes: 41 additions & 0 deletions tests/unit/data/aws/aws2_result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[
{
"account": "0000000000001",
"circuits": [
{
"circuit_id": "aaaaa-00000001",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000002",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000003",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000004",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000005",
"impact": "OUTAGE"
},
{
"circuit_id": "aaaaa-00000006",
"impact": "OUTAGE"
}
],
"end": 1631584920,
"maintenance_id": "47876b7d5a5198643a1a9cb7f954487a",
"organizer": "[email protected]",
"provider": "aws",
"sequence": 1,
"stamp": 1620337976,
"start": 1631559720,
"status": "CANCELLED",
"summary": "We would like to inform you that the planned maintenance that was scheduled for AWS Direct Connect endpoint in Equinix SG2, Singapore, SGP from Mon, 13 Sep 2021 19:02:00 GMT to Tue, 14 Sep 2021 02:02:00 GMT has been cancelled. Please find below your AWS Direct Connect services that would have been affected by this planned maintenance.",
"uid": "0"
}
]
5 changes: 5 additions & 0 deletions tests/unit/data/aws/aws2_subject_parser_result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
{
"account": "0000000000001"
}
]
Loading