nautobot / nautobot-app-circuit-maintenance Goto Github PK
View Code? Open in Web Editor NEWCircuit Maintenance App for Nautobot
Home Page: https://docs.nautobot.com/projects/circuit-maintenance/en/latest/
License: Apache License 2.0
Circuit Maintenance App for Nautobot
Home Page: https://docs.nautobot.com/projects/circuit-maintenance/en/latest/
License: Apache License 2.0
Extract email from mailbox with attachments (attachment is encoded in UTF-16).
Notification retrieval failed with unhandled Exception.
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/nautobot_circuit_maintenance/handle_notifications/sources.py", line 610, in get_notifications
raw_notifications = source.receive_notifications(job_logger, since_date)
File "/usr/local/lib/python3.8/site-packages/nautobot_circuit_maintenance/handle_notifications/sources.py", line 389, in receive_notifications
raw_notification = self.fetch_email(job_logger, msg_id)
File "/usr/local/lib/python3.8/site-packages/nautobot_circuit_maintenance/handle_notifications/sources.py", line 339, in fetch_email
return self.process_email(job_logger, email_message)
File "/usr/local/lib/python3.8/site-packages/nautobot_circuit_maintenance/handle_notifications/sources.py", line 288, in process_email
raw_payload=email_message.as_bytes(),
File "/usr/local/lib/python3.8/email/message.py", line 178, in as_bytes
g.flatten(self, unixfrom=unixfrom)
File "/usr/local/lib/python3.8/email/generator.py", line 116, in flatten
self._write(msg)
File "/usr/local/lib/python3.8/email/generator.py", line 181, in _write
self._dispatch(msg)
File "/usr/local/lib/python3.8/email/generator.py", line 218, in _dispatch
meth(msg)
File "/usr/local/lib/python3.8/email/generator.py", line 276, in _handle_multipart
g.flatten(part, unixfrom=False, linesep=self._NL)
File "/usr/local/lib/python3.8/email/generator.py", line 116, in flatten
self._write(msg)
File "/usr/local/lib/python3.8/email/generator.py", line 181, in _write
self._dispatch(msg)
File "/usr/local/lib/python3.8/email/generator.py", line 218, in _dispatch
meth(msg)
File "/usr/local/lib/python3.8/email/generator.py", line 436, in _handle_text
super(BytesGenerator,self)._handle_text(msg)
File "/usr/local/lib/python3.8/email/generator.py", line 253, in _handle_text
self._write_lines(payload)
File "/usr/local/lib/python3.8/email/generator.py", line 155, in _write_lines
self.write(line)
File "/usr/local/lib/python3.8/email/generator.py", line 410, in write
self._fp.write(s.encode('ascii', 'surrogateescape'))
UnicodeEncodeError: 'ascii' codec can't encode character '\u2019' in position 916: ordinal not in range(128)
RawNotification
arguments should be more generic and not so related to email
sources.
For instance:
NotifiicationSources
won't have so it should be optionalNotificationSource
that was usedThis proposal is to emit a Django Signal from Circuit Maintenance plugin when one of the Circuit Maintenances scheduled, in a valid state (CONFIRMED) is going to START (with a configurable time in advance in case some automation should have to interact with the network) and when the event passed the END time.
This new feature could leverage on the new Celery task queue, that every X time is checking for the state of the Circuit Maintenances and sends the proper signals.
With this feature, other Django components could be passively listening to Circuit Maintenance events and perform actions, such as changing Circuit state or sending IM messages automatically.
By default, first time you run the Notifications Job, it doesn't limit the SINCE
, so it would retrieve all the emails related to the FROM
option.
Be able to customize the number of days it looks back the first time, to not overwhelm the first run.
Instead of using simple text from Choices to show the status of a Circuit Maintenance leverage on custom statuses
This would improve user experience while keeping same text functionalities.
In the add notifications form I am prompted for a Url with no description and source type is either gmail or unknown. A minimal description of the Url field and some documentation around configuring other email sources would be very beneficial.
The documentation should provide examples for configuring a POP3 or an IMAP mail server at a minimum.
Documentation refers to URL but nothing further
The plugin should work well with MYSQL DB
Tests are not in place so it's not clear if it works as expected.
Similar implementation: nautobot/nautobot-app-device-lifecycle-mgmt#33
What purpose does the RawNotification._raw_md5
field serve? I don't see where it's actually being used for anything, and its unique=True
constraint means that trying to create RawNotifications with the same raw
body text (e.g from duplicate emails) results in an exception:
duplicate key value violates unique constraint "nautobot_circuit_mainten__raw_md5_4f063303_uniq" DETAIL: Key (_raw_md5)=(d41d8cd98f00b204e9800998ecf8427e) already exists.
Add support for X-Connect in addition to Circuit. Currently X-Connect ID can be stored under a CircuitTermination.
At a minimum we should be able to match a maintenance notification to a X-Connect ID in addition to a Circuit ID.
Not sure if more changes are required
Some X-Connect can be affected by maintenance as well, like the Metro-Connect from Equinix.
Circuit maintenance job to run to completion
django.db.utils.IntegrityError: duplicate key value violates unique constraint "nautobot_circuit_mainten_maintenance_id_title_f955987f_uniq"
DETAIL: Key (maintenance_id, title)=(646c824b-d576-4e4c-ba19-19eb307e8d1c, Nonexistent circuit ID _) already exists.
_
is being referenced twice:Either we should remove the uniqueness constraint that requires that each Note on a CircuitMaintenance must have a unique title
, or else we need to explicitly detect and handle the case where a duplicate note would be created and avoid this exception.
The GMail API integration needs to support pagination to handle the case where a large number of emails (more than the 100 returned by default) need to be processed.
In this particular case, I discovered this issue because the job was failing for multiple days due to #140; eventually the message that was causing the job to fail fell out of the first 100 results and so the job started passing again because the bad message was no longer being returned in the first 100 results. Unfortunately this means that numerous other older emails also never got processed.
More generally, any email inbox with a large number of providers sending notifications could easily exceed 100 new messages arriving in a given 24-hour period.
The reference time to get notifications should be the last one that we got raw_notifications. Because now the date
is matching the STAMP
or the DATE
of the email, this causes that a wrong STAMP, maybe in the future, will avoid retrieving notifications
since
will be in the futureWhen validating a notification source using the test_authentication
method on the CLI, if a session already exists the return method for the test will always be True - Login OK
Ignore session data when testing the notification source. It may be required to change attributes in the source during initial setup and source validation.
Running test_authentication()
will always return True after initial attempt as the session data causes a conditional check in the logic to avoid subsequent connection attempts.
from nautobot_circuit_maintenance.handle_notifications.sources import Source
test_authentication
from nautobot_circuit_maintenance.handle_notifications.sources import Source
>>> source = Source.init(name="TEST IMAP")
>>> source.test_authentication()
(False, 'LOGIN failed.')
>>> source.test_authentication()
(True, 'Test OK')
Mapping Nautobot Providers to circuit-maintenance-provider Provider classes based on the Nautobot Provider slug
is inflexible as it relies on enforcing that the Nautobot Provider slug
be exactly equal to the circuit-maintenance-provider Provider class __name__
. In practice this may not always be the case, and it's not always going to be feasible to change the existing slug
in Nautobot to resolve this.
I have a Nautobot deployment with circuits defined for provider CenturyLink
(former name of the provider now called Lumen). Without changing the slug
of this provider, or creating a new Lumen
provider and remapping all of the circuits to this new provider, I have no way to make emails from Lumen be handled by the Lumen parser provider because the plugin is looking for a parser called centurylink
.
When Nautobot implements a scheduler (nautobot/nautobot#275), Circuit Maintenance should enable a scheduling to retrieve notifications automatically.
This will enable a continuous operation of the plugin without operation interaction.
By default, all the ParsedNotifications
related to a CircuitMaintenance
are listed in the detailed view. But sometimes, notifications are kind of duplicated, just changing few words, but not changing the parsed information, so we should summarize all the ParsedNotificaitons
that contain the same data in a continuous sequence.
Clean up the relevant information related to a CircuitMaintenance
On deleting a Provider, circuit-maintenance records should not be auto-deleted, although any references to that Provider should be nulled out.
Deleting a Provider deletes all of its associated RawNotifications and ParsedNotifications, although CircuitMaintenances remain present since they are linked to Circuits rather than Providers.
This happened in a user environment where, due to provider mergers and name changes, we had multiple Provider records that actually referred to the same company. After migrating all relevant Circuits to the correct single, consolidated, Provider record, I deleted the old Provider which no longer had any associated Circuits. To my surprise, this also deleted a slew of older RawNotifications and ParsedNotifications as they were associated to the old Provider still. The result is that I still have valid CircuitMaintenance records (since the Circuits were not deleted and are now associated to the new provider) but no longer any references to the parsed data that originated these records.
I would have preferred for the old RawNotification and ParsedNotification records to remain available, presumably with null provider
references, rather than being deleted.
Job to run to completion successfully
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/nautobot_circuit_maintenance/handle_notifications/handler.py", line 166, in create_or_update_circuit_maintenance
circuit_maintenance_entry = CircuitMaintenance.objects.get(name=maintenance_id)
File "/usr/local/lib/python3.7/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/cacheops/query.py", line 353, in get
return qs._no_monkey.get(qs, *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 431, in get
self.model._meta.object_name
nautobot_circuit_maintenance.models.CircuitMaintenance.DoesNotExist: CircuitMaintenance matching query does not exist.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.7/site-packages/newrelic/hooks/database_psycopg2.py", line 65, in execute
**kwargs)
File "/usr/local/lib/python3.7/site-packages/newrelic/hooks/database_dbapi2.py", line 38, in execute
*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django_prometheus/db/common.py", line 71, in execute
return super().execute(*args, **kwargs)
psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "nautobot_circuit_mainten_maintenance_id_circuit_i_01065132_uniq"
DETAIL: Key (maintenance_id, circuit_id)=(408ed18b-9110-4c6c-9ac9-71b10555a06d, d87635fa-fca9-5130-9578-acbb0dc1bb74) already exists.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/nautobot_circuit_maintenance/handle_notifications/handler.py", line 280, in process_raw_notification
logger, parser_maintenance, raw_entry, provider
File "/usr/local/lib/python3.7/site-packages/nautobot_circuit_maintenance/handle_notifications/handler.py", line 187, in create_or_update_circuit_maintenance
circuit_maintenance_entry = create_circuit_maintenance(logger, maintenance_id, parser_maintenance, provider)
File "/usr/local/lib/python3.7/site-packages/nautobot_circuit_maintenance/handle_notifications/handler.py", line 48, in create_circuit_maintenance
impact=circuit.impact,
File "/usr/local/lib/python3.7/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 447, in create
obj.save(force_insert=True, using=self.db)
File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 754, in save
force_update=force_update, update_fields=update_fields)
File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 792, in save_base
force_update, using, update_fields,
File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 895, in _save_table
results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 935, in _do_insert
using=using, raw=raw,
File "/usr/local/lib/python3.7/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 1254, in _insert
return query.get_compiler(using=using).execute_sql(returning_fields)
File "/usr/local/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1397, in execute_sql
cursor.execute(sql, params)
File "/usr/local/lib/python3.7/site-packages/cacheops/transaction.py", line 93, in execute
result = self._no_monkey.execute(self, sql, params)
File "/usr/local/lib/python3.7/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/usr/local/lib/python3.7/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/usr/local/lib/python3.7/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.7/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/usr/local/lib/python3.7/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.7/site-packages/newrelic/hooks/database_psycopg2.py", line 65, in execute
**kwargs)
File "/usr/local/lib/python3.7/site-packages/newrelic/hooks/database_dbapi2.py", line 38, in execute
*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django_prometheus/db/common.py", line 71, in execute
return super().execute(*args, **kwargs)
django.db.utils.IntegrityError: duplicate key value violates unique constraint "nautobot_circuit_mainten_maintenance_id_circuit_i_01065132_uniq"
DETAIL: Key (maintenance_id, circuit_id)=(408ed18b-9110-4c6c-9ac9-71b10555a06d, d87635fa-fca9-5130-9578-acbb0dc1bb74) already exists.
Similar to #140, except that in this case an existent circuit is referenced multiple times in the same notification email:
Presumably the fix will be similar - change CircuitImpact.objects.create()
to CircuitImpact.objects.get_or_create()
as appropriate.
Circuit ID and object link is displayed along with the Circuit Impact. Maintenance should also be linked in the displayed name.
job
to retrieve emails./circuit-maintenance/impact/<id>/
.Make the usage of "Emails for Circuit Maintenance plugin" Custom Field for Provider optional
So far, when using CM you need to define a custom email to filter with the FROM
and classify them to each provider, assuming that this info is not always properly available from the notification and to narrow done the search.
Even this is still an interesting behaviour in terms of optimization and identification, it could be more relaxed so it could be an optional argument that if not present would behave as:
circuit-maintenance-parser
it could use the generic
method and try to take the info from the notification if possible, or maybe add some extra metadata, such as the source email address (and match against provider well know addresses) or API urls.NotificationSource
it's only matching one provider, maybe we could assume that all the notifications are coming from this provider (thinking on a future API integration with an API endpoint), even this could be problematic with other types of integrations based on email boxes.Use Celery instead of RQ: https://nautobot.readthedocs.io/en/latest/installation/services/#migrating-to-celery-from-rq
In the GMail integration, it would be very useful to tag processed emails with one or more categories after processing them, e.g. "parsed" and "parse_failed" perhaps.
This makes it easier for the developer or user to filter the service inbox to see which messages were processed, skipped, and/or failed parsing for troubleshooting and data accuracy checking.
All Relationships associated with the CircuitMaintenance object should be visible in the CircuitMaintenance detail view.
User defined Relationships are not visible in the detail view page but they are visible in the edit view
In the CircuitMaintenance detail view, raw notifications associated with a CircuitMaintenance should be listed based on their notification timestamp.
Raw notifications are listed based on their created/updated timestamp, not the notification timestamp.
Note that all four notifications show times of 9/20 at 2:48 or 2:49 PM as that's the time that the parser job was run and processed these notifications. Clicking through to each individual notification is necessary in order to show its true notification timestamp:
When using source_header
different from From
it is not possible to filter emails, so you get emails that maybe are completely unrelated to the plugin, adding some noise.
Maybe, adding an extra configuration option, such as source_header_from_emails
that can contain a list of the "senders", this could limit all these issues that are unrelated.
Limit the noise from emails that are not related to the plugin work.
Like the end_date
or start_date
the stamp_date
could give information about the reception date of the notification.
Update graph_ql extra_feature for models after nautobot/nautobot#399 is fixed
In the common case where a RawNotification's raw
data is actually a human-readable string, it would be nice to render it as such, instead of as a raw byte-string. I.e., it currently appears like:
but it would be nicer to render the text, for example as:
Provide alerting panel to enable rules to act when:
Provide IM integration
We should be able to get the basic info from an original email when stored in the rawnotification.raw
field. This data is truncated by default to 500 characters
This truncation means missing basic email headers information, so we should look for a value (8192?) that consistently give enough information in the headers to locate the notification in the email source box.
All custom fields associated with the CircuitMaintenance object should be visible in the CircuitMaintenance detail view.
Custom fields are not visible in the detail view page but they are visible in the edit view
From the detail view of a circuit i should be able to visualize the upcoming maintenances and directly navigate to them by following a link.
The list of upcoming maintenances is represented in the detail view of a circuit on the left but there is no link to the corresponding object so it's not possible to navigate to it
Offer an optional flag in the plugin config in order to change the default behaviour of change the state of an email notification retrieved to SEEN.
In some use case, it would be desirable that the automation processes do not change the SEEN status of an email.
Add Gmail API as a supported Notification Source, supporting OAuth authentication.
See: https://www.geeksforgeeks.org/how-to-read-emails-from-gmail-using-gmail-api-in-python/
Because of the OAuth nature, the "Application", the Plugin, will require:
Offer an alternative to IMAP Notification Source
Since Notes are change-logged records, the detail view for a given Note should provide a tab linking to said changelog.
I guess it's also missing from the NotificationSource and ParsedNotification/RawNotification views, but since those are not user-editable models, I think it's less important for those (arguably they don't need change-logging at all).
No tab in the Note detail view.
Running the job should pick up all emails that arrived since the last time the job was run
Because the since
filtering is date-based (not date-time based), any emails that arrived during the same day as the last job run will be skipped over, even though they haven't been processed yet.
Circuit maintenance job to run to completion and successfully process notifications, including those that have already been processed.
I'm not sure. Even after deleting all pre-existing RawNotification records, I'm encountering this issue, but it does not appear that I actually have two duplicate emails (same exact datestamp, subject, and provider) in my inbox, so I don't understand how we're even triggering this condition.
I do have multiple emails from the same provider with the same subject line, but they have different Date:
stamps on them.
Leverage on prometheus_client
to expose key performance metrics for the plugin.
Track the performance of the plugin.
When changing the NotificationSource
config between Nautobot restarts nothing wrong should happen, just update as defined.
When changing the configr from PLUGINS_CONFIG
DB errors are raised:
nautobot_1 | nautobot_circuit_maintenance.models.DoesNotExist: NotificationSource matching query does not exist.
nautobot_1 |
nautobot_1 | During handling of the above exception, another exception occurred:
nautobot_1 |
nautobot_1 | Traceback (most recent call last):
nautobot_1 | File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
nautobot_1 | return self.cursor.execute(sql, params)
nautobot_1 | psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "nautobot_circuit_maintenance_notificationsource_name_key"
nautobot_1 | DETAIL: Key (name)=(my imap source) already exists.
by default, all Providers will be added as related Providers for NotificationSources which parent class is EmailSource, as it's the usual use-case, where all the notifications are received in one email box.
Obviously, if the Provider don't have an email configured, it will be skipped from the loop.
This simplifies the usability of the plugin with this assumption.
RawNotifications to be associated to the correct CircuitMaintenance records
RawNotifications are associated to the wrong CircuitMaintenance records. It looks like something isn't getting carried over or initialized properly as we see a series of consecutive RawNotifications (for different maintenance IDs) being associated to the same CircuitMaintenance instead of different ones as expected.
All custom fields associated with the RawNotification object should be visible in the RawNotification detail view.
Custom fields are not visible in the detail view page
As and when this plugin is used with an ever-growing set of providers sending maintenance notifications, it becomes increasingly likely that two different providers will send maintenance notifications that happen to use the same maintenance ID number/string. (Consider the case of two providers each sending their very first maintenance notification, and both choosing to identify it as maintenance id "00000001"). Because we use the maintenance_id
as the globally-unique name
of the CircuitMaintenance
model instances, these two disparate sets of maintenance notifications would inadvertently be merged into a single CircuitMaintenance
instance named 000000001
, which is almost certainly undesirable.
To avoid collision between providers in this fashion, we should probably include the notification provider
value in addition to the maintenance_id
in constructing the CircuitMaintenance name
.
Googele Fiber uses circuit IP addresses to identify their circuits rather than the ID.
After a conversation with Christian, he has suggested we add a feature that if a circuit ID is an IP address, do a lookup in Nautobot and retrieve the ID. This logic should only be in the plugin and not the parser.
Providers that use a circuits IP as a ID.
The following is the list of errors, which need to be fixed to pass the yamllint step:
INVOKE_NAUTOBOT_CIRCUIT_MAINTENANCE_LOCAL=True invoke yamllint
./nautobot_circuit_maintenance/fixtures/source_gmail_api.yaml
2:10 error string value is not quoted with double quotes (quoted-strings)
3:7 error string value is not quoted with double quotes (quoted-strings)
8:36 error string value is not quoted with double quotes (quoted-strings)
9:11 error string value is not quoted with double quotes (quoted-strings)
10:11 error string value is not quoted with double quotes (quoted-strings)
17:10 error string value is not quoted with double quotes (quoted-strings)
18:7 error string value is not quoted with double quotes (quoted-strings)
23:11 error string value is not quoted with double quotes (quoted-strings)
24:11 error string value is not quoted with double quotes (quoted-strings)
26:10 error string value is not quoted with double quotes (quoted-strings)
27:7 error string value is not quoted with double quotes (quoted-strings)
34:15 error string value is not quoted with double quotes (quoted-strings)
35:11 error string value is not quoted with double quotes (quoted-strings)
41:10 error string value is not quoted with double quotes (quoted-strings)
42:7 error string value is not quoted with double quotes (quoted-strings)
49:15 error string value is not quoted with double quotes (quoted-strings)
50:11 error string value is not quoted with double quotes (quoted-strings)
56:10 error string value is not quoted with double quotes (quoted-strings)
57:7 error string value is not quoted with double quotes (quoted-strings)
65:9 error string value is not quoted with double quotes (quoted-strings)
66:10 error string value is not quoted with double quotes (quoted-strings)
67:7 error string value is not quoted with double quotes (quoted-strings)
75:9 error string value is not quoted with double quotes (quoted-strings)
./nautobot_circuit_maintenance/fixtures/handle_notifications_job.yaml
2:10 error string value is not quoted with double quotes (quoted-strings)
3:7 error string value is not quoted with double quotes (quoted-strings)
8:36 error string value is not quoted with double quotes (quoted-strings)
9:11 error string value is not quoted with double quotes (quoted-strings)
10:11 error string value is not quoted with double quotes (quoted-strings)
17:10 error string value is not quoted with double quotes (quoted-strings)
18:7 error string value is not quoted with double quotes (quoted-strings)
23:36 error string value is not quoted with double quotes (quoted-strings)
24:11 error string value is not quoted with double quotes (quoted-strings)
25:11 error string value is not quoted with double quotes (quoted-strings)
32:10 error string value is not quoted with double quotes (quoted-strings)
33:7 error string value is not quoted with double quotes (quoted-strings)
38:36 error string value is not quoted with double quotes (quoted-strings)
39:11 error string value is not quoted with double quotes (quoted-strings)
40:11 error string value is not quoted with double quotes (quoted-strings)
47:10 error string value is not quoted with double quotes (quoted-strings)
48:7 error string value is not quoted with double quotes (quoted-strings)
53:11 error string value is not quoted with double quotes (quoted-strings)
54:11 error string value is not quoted with double quotes (quoted-strings)
56:10 error string value is not quoted with double quotes (quoted-strings)
57:7 error string value is not quoted with double quotes (quoted-strings)
64:15 error string value is not quoted with double quotes (quoted-strings)
65:11 error string value is not quoted with double quotes (quoted-strings)
71:10 error string value is not quoted with double quotes (quoted-strings)
72:7 error string value is not quoted with double quotes (quoted-strings)
79:15 error string value is not quoted with double quotes (quoted-strings)
80:11 error string value is not quoted with double quotes (quoted-strings)
86:10 error string value is not quoted with double quotes (quoted-strings)
87:7 error string value is not quoted with double quotes (quoted-strings)
95:9 error string value is not quoted with double quotes (quoted-strings)
96:10 error string value is not quoted with double quotes (quoted-strings)
97:7 error string value is not quoted with double quotes (quoted-strings)
105:9 error string value is not quoted with double quotes (quoted-strings)
./nautobot_circuit_maintenance/fixtures/source_imap.yaml
2:10 error string value is not quoted with double quotes (quoted-strings)
3:7 error string value is not quoted with double quotes (quoted-strings)
8:36 error string value is not quoted with double quotes (quoted-strings)
9:11 error string value is not quoted with double quotes (quoted-strings)
10:11 error string value is not quoted with double quotes (quoted-strings)
17:10 error string value is not quoted with double quotes (quoted-strings)
18:7 error string value is not quoted with double quotes (quoted-strings)
23:11 error string value is not quoted with double quotes (quoted-strings)
24:11 error string value is not quoted with double quotes (quoted-strings)
26:10 error string value is not quoted with double quotes (quoted-strings)
27:7 error string value is not quoted with double quotes (quoted-strings)
34:15 error string value is not quoted with double quotes (quoted-strings)
35:11 error string value is not quoted with double quotes (quoted-strings)
41:10 error string value is not quoted with double quotes (quoted-strings)
42:7 error string value is not quoted with double quotes (quoted-strings)
49:15 error string value is not quoted with double quotes (quoted-strings)
50:11 error string value is not quoted with double quotes (quoted-strings)
56:10 error string value is not quoted with double quotes (quoted-strings)
57:7 error string value is not quoted with double quotes (quoted-strings)
65:9 error string value is not quoted with double quotes (quoted-strings)
./development/docker-compose.requirements.yml
11:5 warning comment not indented like content (comments-indentation)
17:14 warning too few spaces before comment (comments)
22:5 warning comment not indented like content (comments-indentation)
./development/docker-compose.base.yml
29:17 error string value is not quoted with double quotes (quoted-strings)
30:16 error string value is not quoted with double quotes (quoted-strings)
31:21 error string value is not quoted with double quotes (quoted-strings)
36:5 error duplication of key "healthcheck" in mapping (key-duplicates)
41:17 error string value is not quoted with double quotes (quoted-strings)
42:16 error string value is not quoted with double quotes (quoted-strings)
43:21 error string value is not quoted with double quotes (quoted-strings)
47:9 error string value is not quoted with double quotes (quoted-strings)
48:9 error string value is not quoted with double quotes (quoted-strings)
51:14 warning too few spaces before comment (comments)
52:68 warning too few spaces before comment (comments)
./.github/workflows/ci.yml
3:1 warning truthy value should be one of [false, true] (truth)
It would be very useful to integrate with the capacity metrics plugin to expose the maintenance status of a circuit as a metric.
The goal is to expose a metric that will reflect the maintenance status of each circuit, something similar to Admin Status and Oper status for interfaces
1
circuit is operational2
circuit is in maintenance mode# Circuit operational
circuit_maintenance_status{"circuit": "XXXXX", provider="ntt", circuit_type="peering", site='XX"} 1.0
# Circuit in maintenance mode
circuit_maintenance_status{"circuit": "YYYYYY", provider="ntt", circuit_type="peering", site='YY"} 2.0
This is something we are already doing with (few) other plugins, here is an example for the chatops plugin
https://github.com/nautobot/nautobot-plugin-chatops/blob/develop/nautobot_chatops/__init__.py#L59
I can think of 2 main use cases for this feature:
There should be a test coverage for handling notifications where there is a Custom mapping to the parser library, and verify that the whole processing is correct.
Provide a Reporting feature in order to get data about:
per circuit/per provider
This data could be available via UI, API, metrics or PDF report
Emails to be processed in chronological order
Emails are processed in reverse chronological order - newest first, oldest last. This has the consequence that the terminal state of any CircuitMaintenance that has multiple emails will be that of the oldest update, instead of the newest update as it should be.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.