From 512147084e918e655e5d52dc37832940c062e5d4 Mon Sep 17 00:00:00 2001 From: andvit Date: Wed, 11 Feb 2026 12:59:34 +0200 Subject: [PATCH 1/5] Adding subject parser for Google, improving status and no-end-date parsing --- circuit_maintenance_parser/parsers/google.py | 46 +++++- circuit_maintenance_parser/provider.py | 4 +- ...t.json => google1_html_parser_result.json} | 5 +- .../data/google/google2_scheduled_subject | 1 + ...ogle2_scheduled_subject_parser_result.json | 7 + .../data/google/google3_completed_subject | 1 + ...ogle3_completed_subject_parser_result.json | 7 + .../unit/data/google/google4_canceled_subject | 1 + ...oogle4_canceled_subject_parser_result.json | 7 + .../{google2.eml => google5_scheduled.eml} | 0 ...ult.json => google5_scheduled_result.json} | 2 +- tests/unit/data/google/google6_completed.eml | 152 +++++++++++++++++ .../data/google/google6_completed_result.json | 25 +++ tests/unit/data/google/google7_canceled.eml | 153 +++++++++++++++++ .../data/google/google7_canceled_result.json | 25 +++ .../google/google8_scheduled_no_end_time.eml | 155 ++++++++++++++++++ .../google8_scheduled_no_end_time_result.json | 25 +++ .../google/google9_completed_no_end_time.eml | 146 +++++++++++++++++ .../google9_completed_no_end_time_result.json | 25 +++ tests/unit/test_e2e.py | 40 ++++- tests/unit/test_parsers.py | 19 ++- 21 files changed, 829 insertions(+), 17 deletions(-) rename tests/unit/data/google/{google1_parser_result.json => google1_html_parser_result.json} (62%) create mode 100644 tests/unit/data/google/google2_scheduled_subject create mode 100644 tests/unit/data/google/google2_scheduled_subject_parser_result.json create mode 100644 tests/unit/data/google/google3_completed_subject create mode 100644 tests/unit/data/google/google3_completed_subject_parser_result.json create mode 100644 tests/unit/data/google/google4_canceled_subject create mode 100644 tests/unit/data/google/google4_canceled_subject_parser_result.json rename tests/unit/data/google/{google2.eml => google5_scheduled.eml} (100%) rename tests/unit/data/google/{google2_result.json => google5_scheduled_result.json} (84%) create mode 100644 tests/unit/data/google/google6_completed.eml create mode 100644 tests/unit/data/google/google6_completed_result.json create mode 100644 tests/unit/data/google/google7_canceled.eml create mode 100644 tests/unit/data/google/google7_canceled_result.json create mode 100644 tests/unit/data/google/google8_scheduled_no_end_time.eml create mode 100644 tests/unit/data/google/google8_scheduled_no_end_time_result.json create mode 100644 tests/unit/data/google/google9_completed_no_end_time.eml create mode 100644 tests/unit/data/google/google9_completed_no_end_time_result.json diff --git a/circuit_maintenance_parser/parsers/google.py b/circuit_maintenance_parser/parsers/google.py index 5f926de7..31b14b01 100644 --- a/circuit_maintenance_parser/parsers/google.py +++ b/circuit_maintenance_parser/parsers/google.py @@ -4,7 +4,7 @@ import re from datetime import datetime -from circuit_maintenance_parser.parser import CircuitImpact, Html, Impact, Status +from circuit_maintenance_parser.parser import CircuitImpact, EmailSubjectParser, Html, Impact, Status # pylint: disable=too-many-nested-blocks, too-many-branches @@ -18,7 +18,7 @@ def parse_html(self, soup): """Execute parsing.""" data = {} data["circuits"] = [] - data["status"] = Status.CONFIRMED + end_time_explicit = False for span in soup.find_all("span"): if span.string is None: @@ -29,6 +29,7 @@ def parse_html(self, soup): elif span.string.strip() == "End Time:": dt_str = span.next_sibling.string.strip() data["end"] = self.dt2ts(datetime.strptime(dt_str, "%Y-%m-%d %H:%M:%S %z UTC")) + end_time_explicit = True elif span.string.strip() == "Peer ASN:": data["account"] = span.parent.next_sibling.string.strip() elif span.string.strip() == "Google Neighbor Address(es):": @@ -37,9 +38,42 @@ def parse_html(self, soup): cid = googleaddr + "-" + span.parent.next_sibling.string.strip() data["circuits"].append(CircuitImpact(circuit_id=cid, impact=Impact.OUTAGE)) - summary = list(soup.find("div").find("div").strings)[-1].strip() - match = re.search(r" - Reference (.*)$", summary) - data["summary"] = summary - data["maintenance_id"] = match[1] + # Google sometimes send notifications without End Time specificed + if not end_time_explicit and data["start"]: + # Since start and end times cannot be equal, manufacturing end date by adding 1hr to start date + end_time_delta = 3600 + data["end"] = data["start"] + end_time_delta + + return [data] + + +class SubjectParserGoogle1(EmailSubjectParser): + """Subject Parser for Google notifications.""" + + def parse_subject(self, subject): + """Parse the subject line.""" + data = {} + + # Example subject format - "[Scheduled] Google Planned Network Maintenance Notification - Reference PCR/123456" + # Group 1: Status (e.g., Scheduled, Completed, Canceled) + # Group 2: Maintenance ID (e.g., PCR/123456) + match = re.search(r"(\[\S+\]).*Reference\s+(\S+)", subject, re.IGNORECASE | re.DOTALL) + match_2 = re.search(r"\[\S+\]\s+(.*)", subject, re.IGNORECASE | re.DOTALL) + + if match: + status_str = match.group(1).upper() + data["maintenance_id"] = match.group(2).strip() + if "COMPLETED" in status_str: + data["status"] = Status.COMPLETED + # To handle both Cancelled and Canceled spelling options just in case + elif "CANCEL" in status_str: + data["status"] = Status.CANCELLED + elif "SCHEDULED" in status_str: + data["status"] = Status.CONFIRMED + # If unable to match, we fallback to default confirmed + else: + data["status"] = Status.CONFIRMED + if match_2: + data["summary"] = match_2.group(1) return [data] diff --git a/circuit_maintenance_parser/provider.py b/circuit_maintenance_parser/provider.py index 8be9519b..367924e6 100644 --- a/circuit_maintenance_parser/provider.py +++ b/circuit_maintenance_parser/provider.py @@ -24,7 +24,7 @@ from circuit_maintenance_parser.parsers.crowncastle import HtmlParserCrownCastle1 from circuit_maintenance_parser.parsers.equinix import HtmlParserEquinix, SubjectParserEquinix from circuit_maintenance_parser.parsers.globalcloudxchange import HtmlParserGcx1, SubjectParserGcx1 -from circuit_maintenance_parser.parsers.google import HtmlParserGoogle1 +from circuit_maintenance_parser.parsers.google import HtmlParserGoogle1, SubjectParserGoogle1 from circuit_maintenance_parser.parsers.gtt import HtmlParserGTT1 from circuit_maintenance_parser.parsers.hgc import HtmlParserHGC1, HtmlParserHGC2, SubjectParserHGC1 from circuit_maintenance_parser.parsers.lumen import HtmlParserLumen1 @@ -364,7 +364,7 @@ class Google(GenericProvider): _processors: List[GenericProcessor] = PrivateAttr( [ - CombinedProcessor(data_parsers=[EmailDateParser, HtmlParserGoogle1]), + CombinedProcessor(data_parsers=[EmailDateParser, HtmlParserGoogle1, SubjectParserGoogle1]), ] ) _default_organizer = PrivateAttr("noc-noreply@google.com") diff --git a/tests/unit/data/google/google1_parser_result.json b/tests/unit/data/google/google1_html_parser_result.json similarity index 62% rename from tests/unit/data/google/google1_parser_result.json rename to tests/unit/data/google/google1_html_parser_result.json index a7d84b51..b2f84d89 100644 --- a/tests/unit/data/google/google1_parser_result.json +++ b/tests/unit/data/google/google1_html_parser_result.json @@ -12,9 +12,6 @@ } ], "end": 1701839100, - "maintenance_id": "PCR/123456", - "start": 1701809700, - "status": "CONFIRMED", - "summary": "Network Maintenance Notification - Reference PCR/123456" + "start": 1701809700 } ] diff --git a/tests/unit/data/google/google2_scheduled_subject b/tests/unit/data/google/google2_scheduled_subject new file mode 100644 index 00000000..16f38e2f --- /dev/null +++ b/tests/unit/data/google/google2_scheduled_subject @@ -0,0 +1 @@ +[Scheduled] Google Planned Network Maintenance Notification - Reference PCR/123456 diff --git a/tests/unit/data/google/google2_scheduled_subject_parser_result.json b/tests/unit/data/google/google2_scheduled_subject_parser_result.json new file mode 100644 index 00000000..ed6be593 --- /dev/null +++ b/tests/unit/data/google/google2_scheduled_subject_parser_result.json @@ -0,0 +1,7 @@ +[ + { + "maintenance_id": "PCR/123456", + "status": "CONFIRMED", + "summary": "Google Planned Network Maintenance Notification - Reference PCR/123456" + } +] diff --git a/tests/unit/data/google/google3_completed_subject b/tests/unit/data/google/google3_completed_subject new file mode 100644 index 00000000..29cda390 --- /dev/null +++ b/tests/unit/data/google/google3_completed_subject @@ -0,0 +1 @@ +[Completed] Google Planned Network Maintenance Notification - Reference PCR/123456 diff --git a/tests/unit/data/google/google3_completed_subject_parser_result.json b/tests/unit/data/google/google3_completed_subject_parser_result.json new file mode 100644 index 00000000..79198bc2 --- /dev/null +++ b/tests/unit/data/google/google3_completed_subject_parser_result.json @@ -0,0 +1,7 @@ +[ + { + "maintenance_id": "PCR/123456", + "status": "COMPLETED", + "summary": "Google Planned Network Maintenance Notification - Reference PCR/123456" + } +] diff --git a/tests/unit/data/google/google4_canceled_subject b/tests/unit/data/google/google4_canceled_subject new file mode 100644 index 00000000..767640d3 --- /dev/null +++ b/tests/unit/data/google/google4_canceled_subject @@ -0,0 +1 @@ +[Canceled] Google Planned Network Maintenance Notification - Reference PCR/123456 diff --git a/tests/unit/data/google/google4_canceled_subject_parser_result.json b/tests/unit/data/google/google4_canceled_subject_parser_result.json new file mode 100644 index 00000000..0be2b267 --- /dev/null +++ b/tests/unit/data/google/google4_canceled_subject_parser_result.json @@ -0,0 +1,7 @@ +[ + { + "maintenance_id": "PCR/123456", + "status": "CANCELLED", + "summary": "Google Planned Network Maintenance Notification - Reference PCR/123456" + } +] diff --git a/tests/unit/data/google/google2.eml b/tests/unit/data/google/google5_scheduled.eml similarity index 100% rename from tests/unit/data/google/google2.eml rename to tests/unit/data/google/google5_scheduled.eml diff --git a/tests/unit/data/google/google2_result.json b/tests/unit/data/google/google5_scheduled_result.json similarity index 84% rename from tests/unit/data/google/google2_result.json rename to tests/unit/data/google/google5_scheduled_result.json index ce194ea5..898346eb 100644 --- a/tests/unit/data/google/google2_result.json +++ b/tests/unit/data/google/google5_scheduled_result.json @@ -19,7 +19,7 @@ "stamp": 1701823205, "start": 1701809700, "status": "CONFIRMED", - "summary": "Network Maintenance Notification - Reference PCR/123456", + "summary": "Google Planned Network Maintenance Notification - Reference PCR/123456", "uid": "0" } ] diff --git a/tests/unit/data/google/google6_completed.eml b/tests/unit/data/google/google6_completed.eml new file mode 100644 index 00000000..0cb088c5 --- /dev/null +++ b/tests/unit/data/google/google6_completed.eml @@ -0,0 +1,152 @@ +Date: Tue, 15 Jul 2025 13:09:19 +0000 +Subject: [Completed] Google Planned Network Maintenance Notification - + Reference PCR/123456 +From: Google NOC +To: sample@example.net +Content-Type: multipart/alternative; boundary="000000000000ecbeea0639f77b7f" + +--000000000000ecbeea0639f77b7f +Content-Type: text/plain; charset="UTF-8"; format=flowed; delsp=yes + +Google Network Maintenance Notification - Reference PCR/123456 - Completed + + +This message was sent to: [sample@example.net] +These addresses were selected from the Google ISP Portal. You can update +your preferences by navigating to "Configuration > Contacts" and adjusting +Email Subscriptions for each user. You can find additional details about +Contacts here. + + +Details: +Start Time: 2025-07-15 03:55:00 +0000 UTC +End Time: 2025-07-15 14:05:00 +0000 UTC +Duration: 10h10m0s + + +Google ASN: 15169 Peer ASN: 65001 + +Google Neighbor Address(es): 2001:db8::1 Peer Neighbor +Address(es): 2001:db8:: + +Google Neighbor Address(es): 192.0.2.1 Peer Neighbor Address(es): +192.0.2.0 + + +Please note that the maintenance is completed, Google systems will +automatically re-route traffic back. + +Questions about this event can be sent to noc@google.com. + +Thank you for peering with Google! + + + +PRIVILEGE AND CONFIDENTIALITY NOTICE: The information in this e-mail +communication and any attached documents may be privileged, confidential or +otherwise protected from disclosure and is intended only for the use of the +designated recipient(s). If the reader is neither the intended recipient +nor an employee or agent thereof who is responsible for delivering it to +the intended recipient, you are hereby notified that any review, +dissemination, distribution, copying or other use of this communication is +strictly prohibited. If you have received this communication in error, +please immediately notify us by return e-mail and promptly delete the +original electronic e-mail communication and any attached documentation. +Receipt by anyone other than the intended recipient is not a waiver of any +attorney-client or work-product privilege. + + +--000000000000ecbeea0639f77b7f +Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + + +
+
Google Network Maintenance No= +tification - Reference PCR/123456 - Completed

+ =20 +
+ This message was sent to: [sample@example.net] + These addresses were selected from the Google ISP Portal. You can update your preferences by navigating t= +o "Configuration > Contacts" and adjusting Email Subscriptions for each use= +r. You can find additional details about Contacts here<= +/a>. +
+ +
+
+ =20 + Details:
+ Start Time: 2025-07-15 03:55:00= + +0000 UTC
+ End Time: 2025-07-15 14:05:00 &= +#43;0000 UTC
+ Duration: 10h10m0s
+ + + + + + =20 + + + + + =20 + + + + + =20 +
Google ASN:151= +69Peer ASN:65001= +
Google Neighbor Address(es):2001:db8::1Peer Neighbor Address(es):2001:db8::
Google Neighbor Address(es):192.0.2.1Peer Neighbor Address(es):192.0.2.0
+ +

+ Please note that the maintenance is completed, Google systems will automa= +tically re-route traffic back. +

+

+ Questions about this event can be sent to noc@google.com. +

+

+ Thank you for peering with Google!
+

+
+
+
+ PRIVILEGE AND CONFIDENTIALITY NOTICE: The information in this + e-mail communication and any attached documents may be privileged, + confidential or otherwise protected from disclosure and is intended onl= +y + for the use of the designated recipient(s). If the reader is neither th= +e + intended recipient nor an employee or agent thereof who is responsible + for delivering it to the intended recipient, you are hereby notified + that any review, dissemination, distribution, copying or other use of + this communication is strictly prohibited. If you have received this + communication in error, please immediately notify us by return e-mail + and promptly delete the original electronic e-mail communication and + any attached documentation. Receipt by anyone other than the intended + recipient is not a waiver of any attorney-client or work-product + privilege. +
+
+ +--000000000000ecbeea0639f77b7f-- diff --git a/tests/unit/data/google/google6_completed_result.json b/tests/unit/data/google/google6_completed_result.json new file mode 100644 index 00000000..06acd43c --- /dev/null +++ b/tests/unit/data/google/google6_completed_result.json @@ -0,0 +1,25 @@ +[ + { + "account": "65001", + "circuits": [ + { + "circuit_id": "2001:db8::1-2001:db8::", + "impact": "OUTAGE" + }, + { + "circuit_id": "192.0.2.1-192.0.2.0", + "impact": "OUTAGE" + } + ], + "end": 1752588300, + "maintenance_id": "PCR/123456", + "organizer": "noc-noreply@google.com", + "provider": "google", + "sequence": 1, + "stamp": 1752584959, + "start": 1752551700, + "status": "COMPLETED", + "summary": "Google Planned Network Maintenance Notification - Reference PCR/123456", + "uid": "0" + } +] diff --git a/tests/unit/data/google/google7_canceled.eml b/tests/unit/data/google/google7_canceled.eml new file mode 100644 index 00000000..b5d417c7 --- /dev/null +++ b/tests/unit/data/google/google7_canceled.eml @@ -0,0 +1,153 @@ +Date: Tue, 15 Jul 2025 20:33:59 +0000 +Subject: [Canceled] Google Planned Network Maintenance Notification - + Reference PCR/123456 +From: Google NOC +To: sample@example.net +Content-Type: multipart/alternative; boundary="0000000000003723370639fdb2e2" + +--0000000000003723370639fdb2e2 +Content-Type: text/plain; charset="UTF-8"; format=flowed; delsp=yes + +Google Network Maintenance Notification - Reference PCR/123456 - Canceled + + +This message was sent to: [sample@example.net] +These addresses were selected from the Google ISP Portal. You can update +your preferences by navigating to "Configuration > Contacts" and adjusting +Email Subscriptions for each user. You can find additional details about +Contacts here. + + +Details: +Start Time: 2025-07-16 03:55:00 +0000 UTC +End Time: 2025-07-16 14:05:00 +0000 UTC +Duration: 10h10m0s + + +Google ASN: 15169 Peer ASN: 65001 + +Google Neighbor Address(es): 2001:db8::1 Peer Neighbor +Address(es): 2001:db8:: + +Google Neighbor Address(es): 192.0.2.1 Peer Neighbor Address(es): +192.0.2.0 + + +Please note that the scheduled maintenance activity is canceled. If new +maintenance is scheduled we will notify you again. + +Questions about this event can be sent to noc@google.com. + +Thank you for peering with Google! + + + +PRIVILEGE AND CONFIDENTIALITY NOTICE: The information in this e-mail +communication and any attached documents may be privileged, confidential or +otherwise protected from disclosure and is intended only for the use of the +designated recipient(s). If the reader is neither the intended recipient +nor an employee or agent thereof who is responsible for delivering it to +the intended recipient, you are hereby notified that any review, +dissemination, distribution, copying or other use of this communication is +strictly prohibited. If you have received this communication in error, +please immediately notify us by return e-mail and promptly delete the +original electronic e-mail communication and any attached documentation. +Receipt by anyone other than the intended recipient is not a waiver of any +attorney-client or work-product privilege. + + +--0000000000003723370639fdb2e2 +Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + + +
+
Google Network Maintenance No= +tification - Reference PCR/123456 - Canceled

+
+ =20 +
+ This message was sent to: [sample@example.net] + These addresses were selected from the Google ISP Portal. You can update your preferences by navigating t= +o "Configuration > Contacts" and adjusting Email Subscriptions for each use= +r. You can find additional details about Contacts here<= +/a>. +
+ +
+
+ =20 + Details:
+ Start Time: 2025-07-16 03:55:00= + +0000 UTC
+ End Time: 2025-07-16 14:05:00 &= +#43;0000 UTC
+ Duration: 10h10m0s
+ + + + + + =20 + + + + + =20 + + + + + =20 +
Google ASN:151= +69Peer ASN:65001= +
Google Neighbor Address(es):2001:db8::1Peer Neighbor Address(es):2001:db8::
Google Neighbor Address(es):192.0.2.1Peer Neighbor Address(es):192.0.2.0
+ +

+ Please note that the scheduled maintenance activity is canceled. If new m= +aintenance is scheduled we will notify you again. +

+

+ Questions about this event can be sent to noc@google.com. +

+

+ Thank you for peering with Google!
+

+
+
+
+ PRIVILEGE AND CONFIDENTIALITY NOTICE: The information in this + e-mail communication and any attached documents may be privileged, + confidential or otherwise protected from disclosure and is intended onl= +y + for the use of the designated recipient(s). If the reader is neither th= +e + intended recipient nor an employee or agent thereof who is responsible + for delivering it to the intended recipient, you are hereby notified + that any review, dissemination, distribution, copying or other use of + this communication is strictly prohibited. If you have received this + communication in error, please immediately notify us by return e-mail + and promptly delete the original electronic e-mail communication and + any attached documentation. Receipt by anyone other than the intended + recipient is not a waiver of any attorney-client or work-product + privilege. +
+
+ +--0000000000003723370639fdb2e2-- diff --git a/tests/unit/data/google/google7_canceled_result.json b/tests/unit/data/google/google7_canceled_result.json new file mode 100644 index 00000000..791ae337 --- /dev/null +++ b/tests/unit/data/google/google7_canceled_result.json @@ -0,0 +1,25 @@ +[ + { + "account": "65001", + "circuits": [ + { + "circuit_id": "2001:db8::1-2001:db8::", + "impact": "OUTAGE" + }, + { + "circuit_id": "192.0.2.1-192.0.2.0", + "impact": "OUTAGE" + } + ], + "end": 1752674700, + "maintenance_id": "PCR/123456", + "organizer": "noc-noreply@google.com", + "provider": "google", + "sequence": 1, + "stamp": 1752611639, + "start": 1752638100, + "status": "CANCELLED", + "summary": "Google Planned Network Maintenance Notification - Reference PCR/123456", + "uid": "0" + } +] diff --git a/tests/unit/data/google/google8_scheduled_no_end_time.eml b/tests/unit/data/google/google8_scheduled_no_end_time.eml new file mode 100644 index 00000000..78d3d651 --- /dev/null +++ b/tests/unit/data/google/google8_scheduled_no_end_time.eml @@ -0,0 +1,155 @@ +Date: Sat, 22 Nov 2025 17:13:40 +0000 +Subject: [Scheduled] Google Planned Network Maintenance Notification - + Reference PCR/123456 +From: Google NOC +To: sample@example.net +Content-Type: multipart/alternative; boundary="00000000000035449b0644320d95" + +--00000000000035449b0644320d95 +Content-Type: text/plain; charset="UTF-8"; format=flowed; delsp=yes + +Google Network Maintenance Notification - Reference PCR/123456 + + +This message was sent to: [sample@example.net] +These addresses were selected from the Google ISP Portal. You can update +your preferences by navigating to "Configuration > Contacts" and adjusting +Email Subscriptions for each user. You can find additional details about +Contacts here. + + +Details: +Start Time: 2025-11-22 18:36:00 +0000 UTC + + +Google ASN: 15169 Peer ASN: 65001 + +Google Neighbor Address(es): 2001:db8::1 Peer Neighbor +Address(es): 2001:db8:: + +Google Neighbor Address(es): 192.0.2.1 Peer Neighbor Address(es): +192.0.2.0 + + +Google systems will automatically re-route the traffic away from the +peering link(s) under maintenance. + +Depending on the nature of the work, your BGP session with Google may stay +up through the maintenance window. Traffic may shift to alternate sessions +with Google and/or your upstream provider(s). + +Questions about this event can be sent to noc@google.com. + +Thank you for peering with Google! + + + +PRIVILEGE AND CONFIDENTIALITY NOTICE: The information in this e-mail +communication and any attached documents may be privileged, confidential or +otherwise protected from disclosure and is intended only for the use of the +designated recipient(s). If the reader is neither the intended recipient +nor an employee or agent thereof who is responsible for delivering it to +the intended recipient, you are hereby notified that any review, +dissemination, distribution, copying or other use of this communication is +strictly prohibited. If you have received this communication in error, +please immediately notify us by return e-mail and promptly delete the +original electronic e-mail communication and any attached documentation. +Receipt by anyone other than the intended recipient is not a waiver of any +attorney-client or work-product privilege. + + +--00000000000035449b0644320d95 +Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + + +
+
Google Network Maintenance No= +tification - Reference PCR/123456
+
+ =20 +
+ This message was sent to: [sample@example.net]
+ These addresses were selected from the
Google ISP Portal. You can update your preferences by navigating t= +o "Configuration > Contacts" and adjusting Email Subscriptions for each use= +r. You can find additional details about Contacts here<= +/a>. +
+ +
+
+ =20 + Details:
+ Start Time: 2025-11-22 18:36:00= + +0000 UTC
+ + + + + + =20 + + + + + =20 + + + + + =20 +
Google ASN:151= +69Peer ASN:65001= +
Google Neighbor Address(es):2001:db8::1Peer Neighbor Address(es):2001:db8::
Google Neighbor Address(es):192.0.2.1Peer Neighbor Address(es):192.0.2.0
+ +

+ Google systems will automatically re-route the traffic away from the peer= +ing link(s) under maintenance. +

+

+ Depending on the nature of the work, your BGP session with Google may sta= +y up through the maintenance window. Traffic may shift to alternate session= +s with Google and/or your upstream provider(s). +

+

+ Questions about this event can be sent to noc@google.com. +

+

+ Thank you for peering with Google!
+

+
+
+
+ PRIVILEGE AND CONFIDENTIALITY NOTICE: The information in this + e-mail communication and any attached documents may be privileged, + confidential or otherwise protected from disclosure and is intended onl= +y + for the use of the designated recipient(s). If the reader is neither th= +e + intended recipient nor an employee or agent thereof who is responsible + for delivering it to the intended recipient, you are hereby notified + that any review, dissemination, distribution, copying or other use of + this communication is strictly prohibited. If you have received this + communication in error, please immediately notify us by return e-mail + and promptly delete the original electronic e-mail communication and + any attached documentation. Receipt by anyone other than the intended + recipient is not a waiver of any attorney-client or work-product + privilege. +
+
+ +--00000000000035449b0644320d95-- diff --git a/tests/unit/data/google/google8_scheduled_no_end_time_result.json b/tests/unit/data/google/google8_scheduled_no_end_time_result.json new file mode 100644 index 00000000..2cbab514 --- /dev/null +++ b/tests/unit/data/google/google8_scheduled_no_end_time_result.json @@ -0,0 +1,25 @@ +[ + { + "account": "65001", + "circuits": [ + { + "circuit_id": "2001:db8::1-2001:db8::", + "impact": "OUTAGE" + }, + { + "circuit_id": "192.0.2.1-192.0.2.0", + "impact": "OUTAGE" + } + ], + "end": 1763840160, + "maintenance_id": "PCR/123456", + "organizer": "noc-noreply@google.com", + "provider": "google", + "sequence": 1, + "stamp": 1763831620, + "start": 1763836560, + "status": "CONFIRMED", + "summary": "Google Planned Network Maintenance Notification - Reference PCR/123456", + "uid": "0" + } +] diff --git a/tests/unit/data/google/google9_completed_no_end_time.eml b/tests/unit/data/google/google9_completed_no_end_time.eml new file mode 100644 index 00000000..90368fa4 --- /dev/null +++ b/tests/unit/data/google/google9_completed_no_end_time.eml @@ -0,0 +1,146 @@ +Date: Sat, 22 Nov 2025 20:26:49 +0000 +Subject: [Completed] Google Planned Network Maintenance Notification - + Reference PCR/123456 +From: Google NOC +To: sample@example.net +Content-Type: multipart/alternative; boundary="000000000000eee422064434bfbd" + +--000000000000eee422064434bfbd +Content-Type: text/plain; charset="UTF-8"; format=flowed; delsp=yes + +Google Network Maintenance Notification - Reference PCR/123456 - Completed + + +This message was sent to: [sample@example.net] +These addresses were selected from the Google ISP Portal. You can update +your preferences by navigating to "Configuration > Contacts" and adjusting +Email Subscriptions for each user. You can find additional details about +Contacts here. + + +Details: +Start Time: 2025-11-22 18:36:00 +0000 UTC + + +Google ASN: 15169 Peer ASN: 65001 + +Google Neighbor Address(es): 2001:db8::1 Peer Neighbor Address(es): +2001:db8:: + +Google Neighbor Address(es): 192.0.2.1 Peer Neighbor Address(es): +192.0.2.0 + + +Please note that the maintenance is completed, Google systems will +automatically re-route traffic back. + +Questions about this event can be sent to noc@google.com. + +Thank you for peering with Google! + + + +PRIVILEGE AND CONFIDENTIALITY NOTICE: The information in this e-mail +communication and any attached documents may be privileged, confidential or +otherwise protected from disclosure and is intended only for the use of the +designated recipient(s). If the reader is neither the intended recipient +nor an employee or agent thereof who is responsible for delivering it to +the intended recipient, you are hereby notified that any review, +dissemination, distribution, copying or other use of this communication is +strictly prohibited. If you have received this communication in error, +please immediately notify us by return e-mail and promptly delete the +original electronic e-mail communication and any attached documentation. +Receipt by anyone other than the intended recipient is not a waiver of any +attorney-client or work-product privilege. + + +--000000000000eee422064434bfbd +Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: quoted-printable + + +
+
Google Network Maintenance No= +tification - Reference PCR/123456 - Completed

+ =20 +
+ This message was sent to: [sample@example.net]
+ These addresses were selected from the
Google ISP Portal. You can update your preferences by navigating t= +o "Configuration > Contacts" and adjusting Email Subscriptions for each use= +r. You can find additional details about Contacts here<= +/a>. +
+ +
+
+ =20 + Details:
+ Start Time: 2025-11-22 18:36:00= + +0000 UTC
+ + + + + + =20 + + + + + =20 + + + + + =20 +
Google ASN:151= +69Peer ASN:65001= +
Google Neighbor Address(es):2001:db8::1Peer Neighbor Address(es):2001:db8::
Google Neighbor Address(es):192.0.2.1Peer Neighbor Address(es):192.0.2.0
+ +

+ Please note that the maintenance is completed, Google systems will automa= +tically re-route traffic back. +

+

+ Questions about this event can be sent to noc@google.com. +

+

+ Thank you for peering with Google!
+

+
+
+
+ PRIVILEGE AND CONFIDENTIALITY NOTICE: The information in this + e-mail communication and any attached documents may be privileged, + confidential or otherwise protected from disclosure and is intended onl= +y + for the use of the designated recipient(s). If the reader is neither th= +e + intended recipient nor an employee or agent thereof who is responsible + for delivering it to the intended recipient, you are hereby notified + that any review, dissemination, distribution, copying or other use of + this communication is strictly prohibited. If you have received this + communication in error, please immediately notify us by return e-mail + and promptly delete the original electronic e-mail communication and + any attached documentation. Receipt by anyone other than the intended + recipient is not a waiver of any attorney-client or work-product + privilege. +
+
+ +--000000000000eee422064434bfbd-- diff --git a/tests/unit/data/google/google9_completed_no_end_time_result.json b/tests/unit/data/google/google9_completed_no_end_time_result.json new file mode 100644 index 00000000..9c4e9b09 --- /dev/null +++ b/tests/unit/data/google/google9_completed_no_end_time_result.json @@ -0,0 +1,25 @@ +[ + { + "account": "65001", + "circuits": [ + { + "circuit_id": "2001:db8::1-2001:db8::", + "impact": "OUTAGE" + }, + { + "circuit_id": "192.0.2.1-192.0.2.0", + "impact": "OUTAGE" + } + ], + "end": 1763840160, + "maintenance_id": "PCR/123456", + "organizer": "noc-noreply@google.com", + "provider": "google", + "sequence": 1, + "stamp": 1763843209, + "start": 1763836560, + "status": "COMPLETED", + "summary": "Google Planned Network Maintenance Notification - Reference PCR/123456", + "uid": "0" + } +] diff --git a/tests/unit/test_e2e.py b/tests/unit/test_e2e.py index 135ebd51..e8930493 100644 --- a/tests/unit/test_e2e.py +++ b/tests/unit/test_e2e.py @@ -507,10 +507,46 @@ ( Google, [ - ("email", Path(dir_path, "data", "google", "google2.eml")), + ("email", Path(dir_path, "data", "google", "google5_scheduled.eml")), ], [ - Path(dir_path, "data", "google", "google2_result.json"), + Path(dir_path, "data", "google", "google5_scheduled_result.json"), + ], + ), + ( + Google, + [ + ("email", Path(dir_path, "data", "google", "google6_completed.eml")), + ], + [ + Path(dir_path, "data", "google", "google6_completed_result.json"), + ], + ), + ( + Google, + [ + ("email", Path(dir_path, "data", "google", "google7_canceled.eml")), + ], + [ + Path(dir_path, "data", "google", "google7_canceled_result.json"), + ], + ), + ( + Google, + [ + ("email", Path(dir_path, "data", "google", "google8_scheduled_no_end_time.eml")), + ], + [ + Path(dir_path, "data", "google", "google8_scheduled_no_end_time_result.json"), + ], + ), + ( + Google, + [ + ("email", Path(dir_path, "data", "google", "google9_completed_no_end_time.eml")), + ], + [ + Path(dir_path, "data", "google", "google9_completed_no_end_time_result.json"), ], ), # Lumen diff --git a/tests/unit/test_parsers.py b/tests/unit/test_parsers.py index 6f6353d2..fc7d839b 100644 --- a/tests/unit/test_parsers.py +++ b/tests/unit/test_parsers.py @@ -18,7 +18,7 @@ from circuit_maintenance_parser.parsers.crowncastle import HtmlParserCrownCastle1 from circuit_maintenance_parser.parsers.equinix import HtmlParserEquinix, SubjectParserEquinix from circuit_maintenance_parser.parsers.globalcloudxchange import HtmlParserGcx1, SubjectParserGcx1 -from circuit_maintenance_parser.parsers.google import HtmlParserGoogle1 +from circuit_maintenance_parser.parsers.google import HtmlParserGoogle1, SubjectParserGoogle1 from circuit_maintenance_parser.parsers.gtt import HtmlParserGTT1 from circuit_maintenance_parser.parsers.hgc import HtmlParserHGC1, HtmlParserHGC2 from circuit_maintenance_parser.parsers.lumen import HtmlParserLumen1 @@ -385,7 +385,22 @@ def default(self, o): ( HtmlParserGoogle1, Path(dir_path, "data", "google", "google1.html"), - Path(dir_path, "data", "google", "google1_parser_result.json"), + Path(dir_path, "data", "google", "google1_html_parser_result.json"), + ), + ( + SubjectParserGoogle1, + Path(dir_path, "data", "google", "google2_scheduled_subject"), + Path(dir_path, "data", "google", "google2_scheduled_subject_parser_result.json"), + ), + ( + SubjectParserGoogle1, + Path(dir_path, "data", "google", "google3_completed_subject"), + Path(dir_path, "data", "google", "google3_completed_subject_parser_result.json"), + ), + ( + SubjectParserGoogle1, + Path(dir_path, "data", "google", "google4_canceled_subject"), + Path(dir_path, "data", "google", "google4_canceled_subject_parser_result.json"), ), # GTT ( From 3bb17facc18601a753f119e74bf4a34717bacfbd Mon Sep 17 00:00:00 2001 From: andvit Date: Wed, 11 Feb 2026 22:01:20 +0200 Subject: [PATCH 2/5] Added changelog fragment --- changes/374.feature.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes/374.feature.rst diff --git a/changes/374.feature.rst b/changes/374.feature.rst new file mode 100644 index 00000000..66aa5dfe --- /dev/null +++ b/changes/374.feature.rst @@ -0,0 +1 @@ +Added Google subject parser with support for multiple status types and notifications without end times From 38d926899daf33a63f033299a28b7960bd9bb994 Mon Sep 17 00:00:00 2001 From: andvit Date: Wed, 11 Feb 2026 22:02:37 +0200 Subject: [PATCH 3/5] Fixing changelog fragment PR num --- changes/375.feature.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes/375.feature.rst diff --git a/changes/375.feature.rst b/changes/375.feature.rst new file mode 100644 index 00000000..66aa5dfe --- /dev/null +++ b/changes/375.feature.rst @@ -0,0 +1 @@ +Added Google subject parser with support for multiple status types and notifications without end times From 5ff26ce16d3d0ccac96a1ee2f8d948cd1a2017cf Mon Sep 17 00:00:00 2001 From: andvit Date: Wed, 11 Feb 2026 22:05:18 +0200 Subject: [PATCH 4/5] Removing incorrectly named changelog fragment --- changes/374.feature.rst | 1 - 1 file changed, 1 deletion(-) delete mode 100644 changes/374.feature.rst diff --git a/changes/374.feature.rst b/changes/374.feature.rst deleted file mode 100644 index 66aa5dfe..00000000 --- a/changes/374.feature.rst +++ /dev/null @@ -1 +0,0 @@ -Added Google subject parser with support for multiple status types and notifications without end times From bebb52ef28899ffbc359433fb55aca786aa1d97d Mon Sep 17 00:00:00 2001 From: andvit Date: Wed, 11 Feb 2026 22:13:46 +0200 Subject: [PATCH 5/5] Fixing changelog fragment name --- changes/{375.feature.rst => 375.added} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changes/{375.feature.rst => 375.added} (100%) diff --git a/changes/375.feature.rst b/changes/375.added similarity index 100% rename from changes/375.feature.rst rename to changes/375.added