Skip to content

Commit

Permalink
Create a new custom field to define custom provider mapping to the li…
Browse files Browse the repository at this point in the history
…brary parsers
  • Loading branch information
chadell committed Aug 5, 2021
1 parent f66daca commit b65b612
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 15 deletions.
13 changes: 9 additions & 4 deletions nautobot_circuit_maintenance/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from nautobot.extras.plugins import PluginConfig


def custom_field_extension(sender, **kwargs): # pylint: disable=unused-argument
"""Add extended custom field."""
def custom_fields_extension(sender, **kwargs): # pylint: disable=unused-argument
"""Add extended custom fields."""
# pylint: disable=import-outside-toplevel
from django.contrib.contenttypes.models import ContentType
from nautobot.circuits.models import Provider
Expand All @@ -18,7 +18,12 @@ def custom_field_extension(sender, **kwargs): # pylint: disable=unused-argument
{
"name": "emails_circuit_maintenances",
"type": CustomFieldTypeChoices.TYPE_TEXT,
"label": "Emails for Circuit Maintenance plugin",
"label": "Emails for Circuit Maintenance plugin.",
},
{
"name": "provider_parser_circuit_maintenances",
"type": CustomFieldTypeChoices.TYPE_TEXT,
"label": "Provider Parser for Circuit Maintenance plugin.",
},
]:
field, _ = CustomField.objects.get_or_create(name=provider_cf_dict["name"], defaults=provider_cf_dict)
Expand Down Expand Up @@ -66,7 +71,7 @@ class CircuitMaintenanceConfig(PluginConfig):

def ready(self):
super().ready()
post_migrate.connect(custom_field_extension, sender=self)
post_migrate.connect(custom_fields_extension, sender=self)
post_migrate.connect(import_notification_sources, sender=self)


Expand Down
29 changes: 28 additions & 1 deletion nautobot_circuit_maintenance/custom_validators.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""Custom Validators definition."""
from nautobot.circuits.models import Provider
from nautobot.extras.plugins import PluginCustomValidator
from nautobot.extras.models import CustomField

from circuit_maintenance_parser import SUPPORTED_PROVIDER_NAMES


class ProviderEmailValidator(PluginCustomValidator):
Expand All @@ -26,4 +29,28 @@ def clean(self):
)


custom_validators = [ProviderEmailValidator]
class ProviderParserValidator(PluginCustomValidator):
"""Custom validator to validate that Provider's parser exists in the Parser library."""

model = "circuits.provider"

def clean(self):
"""Validate that the Provider's parser exists in the Parser library."""
provider_mapping = (
self.context["object"]
.get_custom_fields()
.get(CustomField.objects.get(name="provider_parser_circuit_maintenances"))
)

if provider_mapping and provider_mapping.lower() not in SUPPORTED_PROVIDER_NAMES:
self.validation_error(
{
"cf_provider_parser_circuit_maintenances": (
f"{provider_mapping} is not one of the supported Providers in the "
f"circuit-maintenance-parser library: {SUPPORTED_PROVIDER_NAMES}."
)
}
)


custom_validators = [ProviderEmailValidator, ProviderParserValidator]
10 changes: 9 additions & 1 deletion nautobot_circuit_maintenance/handle_notifications/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,12 +266,20 @@ def extract_provider_data_types(email_source: str) -> Tuple[str, str, str]:
]
if email_source in sources:
provider_type = provider.slug
# If there is no custom provider mapping defined, we take the provider slug as default mapping
provider_parser_circuit_maintenances = provider.get_custom_fields().get(
CustomField.objects.get(name="provider_parser_circuit_maintenances")
)
if provider_parser_circuit_maintenances:
provider_mapping = provider_parser_circuit_maintenances.lower()
else:
provider_mapping = provider_type
break
else:
return "", "", f"Sender email {email_source} is not registered for any circuit provider."

try:
provider_data_types = get_provider_data_types(provider_type)
provider_data_types = get_provider_data_types(provider_mapping)
except NonexistentParserError:
return (
"",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
<div class="col-sm-8 col-md-9">
<ol class="breadcrumb">
<li><a href="{% url 'plugins:nautobot_circuit_maintenance:rawnotification_list' %}">ParsedNotification</a></li>
<li><a>{{ object.raw_notification.subject }}</a></li>
<li><a>{{ object }}</a></li>
</ol>
</div>
</div>

<h1>{{ object.raw_notification.subject }}</h1>
<h1>{{ object }}</h1>
<div class="pull-right noprint">{% custom_links object %}</div>

{% endblock %}
Expand Down
13 changes: 8 additions & 5 deletions nautobot_circuit_maintenance/tests/test_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,17 +141,20 @@ def test_extract_provider_data_types_no_provider_parser(self):

@parameterized.expand(
[
["ntt", {"text/calendar"}, False],
["telstra", {"text/html", "text/calendar"}, False],
["zayo", {"text/html"}, False],
["unknown", "unknown", True],
["ntt", {"text/calendar"}, "", False],
["ntt", {"text/calendar"}, "eunetworks", False],
["telstra", {"text/html", "text/calendar"}, "", False],
["zayo", {"text/html"}, "", False],
["unknown", "unknown", "", True],
]
)
def test_extract_provider_data_types_ok(self, provider_type, data_types, error_message):
def test_extract_provider_data_types_ok(self, provider_type, data_types, provider_mapping, error_message):
"""Test for extract_provider_data_types."""
email_source = "user@example.com"
provider = Provider.objects.create(name=provider_type, slug=provider_type)
provider.cf["emails_circuit_maintenances"] = email_source
if provider_mapping:
provider.cf["provider_parser_circuit_maintenances"] = provider_mapping
provider.save()

self.assertEqual(
Expand Down
12 changes: 10 additions & 2 deletions nautobot_circuit_maintenance/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,15 +328,23 @@ def setUpTestData(cls):
source = NotificationSource.objects.create(name="whatever 1", slug="whatever-1")

raw_notification = RawNotification.objects.create(
subject="whatever", provider=providers[0], sender="whatever", source=source, raw=b"whatever 1"
subject="whatever subject 1",
provider=providers[0],
sender="whatever sender 1",
source=source,
raw=b"whatever raw 1",
)
circuit_maintenance = CircuitMaintenance.objects.create(
name="UT-TEST-1", start_time="2020-10-04 10:00:00", end_time="2020-10-04 12:00:00"
)
ParsedNotification.objects.create(maintenance=circuit_maintenance, raw_notification=raw_notification, json="{}")

raw_notification_2 = RawNotification.objects.create(
subject="whatever", provider=providers[0], sender="whatever", source=source, raw=b"whatever 2"
subject="whatever subject 2",
provider=providers[0],
sender="whatever sender 2",
source=source,
raw=b"whatever raw 2",
)
circuit_maintenance_2 = CircuitMaintenance.objects.create(
name="UT-TEST-2", start_time="2020-10-04 10:00:00", end_time="2020-10-04 12:00:00"
Expand Down

0 comments on commit b65b612

Please sign in to comment.