diff --git a/changes/223.fixed b/changes/223.fixed deleted file mode 100644 index 69579552..00000000 --- a/changes/223.fixed +++ /dev/null @@ -1 +0,0 @@ -Fixed App initialization when `[grafana]` extra is not installed. diff --git a/docs/admin/release_notes/version_2.0.md b/docs/admin/release_notes/version_2.0.md index 377c9670..10c7f6ea 100644 --- a/docs/admin/release_notes/version_2.0.md +++ b/docs/admin/release_notes/version_2.0.md @@ -2,6 +2,19 @@ # v2.0 Release Notes +## [v2.0.3 (2023-09-22)](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v2.0.3) + +### Added + +- [#227](https://github.com/nautobot/nautobot-plugin-chatops/issues/227) - Added some tests for VLAN chatops. + +### Fixed + +- [#227](https://github.com/nautobot/nautobot-plugin-chatops/issues/227) - Fixed parameters that should be set to None if they have not been defined yet by default. +- [#239](https://github.com/nautobot/nautobot-plugin-chatops/issues/239) - Updated IP Fabric Logo. +- [#241](https://github.com/nautobot/nautobot-plugin-chatops/issues/241) - Remove Grafana Navigation and urls if disabled. +- [#253](https://github.com/nautobot/nautobot-plugin-chatops/issues/253) - Sorted the ICMP types from IP Fabric diagrams package. + ## [v2.0.2 (2023-08-11)](https://github.com/nautobot/nautobot-plugin-chatops/releases/tag/v2.0.2) ### Changed diff --git a/nautobot_chatops/integrations/grafana/api/urls.py b/nautobot_chatops/integrations/grafana/api/urls.py index 0a25eb18..c6b4e88f 100644 --- a/nautobot_chatops/integrations/grafana/api/urls.py +++ b/nautobot_chatops/integrations/grafana/api/urls.py @@ -1,16 +1,16 @@ """Django urlpatterns declaration for nautobot_chatops.integrations.grafana plugin.""" -# from django.urls import path +from django.conf import settings from nautobot.core.api import OrderedDefaultRouter from nautobot_chatops.integrations.grafana.api.views.generic import NautobotPluginChatopsGrafanaRootView urlpatterns = [] +if settings.PLUGINS_CONFIG["nautobot_chatops"]["enable_grafana"]: + router = OrderedDefaultRouter() + router.APIRootView = NautobotPluginChatopsGrafanaRootView -router = OrderedDefaultRouter() -router.APIRootView = NautobotPluginChatopsGrafanaRootView + app_name = "nautobot_chatops.grafana-api" -app_name = "nautobot_chatops.grafana-api" - -urlpatterns += router.urls + urlpatterns += router.urls diff --git a/nautobot_chatops/integrations/ipfabric/worker.py b/nautobot_chatops/integrations/ipfabric/worker.py index 89544646..9f4ab94f 100644 --- a/nautobot_chatops/integrations/ipfabric/worker.py +++ b/nautobot_chatops/integrations/ipfabric/worker.py @@ -564,7 +564,7 @@ def pathlookup_icmp(dispatcher, src_ip, dst_ip, icmp_type): # pylint: disable=t """Path simulation diagram lookup between source and target IP address.""" sub_cmd = "pathlookup-icmp" icmp_type = icmp_type.upper() if isinstance(icmp_type, str) else icmp_type - icmp_types = [(icmp_type_name.upper(), icmp_type_name) for icmp_type_name in icmp.__all__] + icmp_types = sorted([(icmp_type_name.upper(), icmp_type_name) for icmp_type_name in icmp.__all__]) # identical to dialog_list in end-to-end-path; consolidate dialog_list if maintaining both cmds dialog_list = [ diff --git a/nautobot_chatops/navigation.py b/nautobot_chatops/navigation.py index bb4f2480..27c28a7e 100644 --- a/nautobot_chatops/navigation.py +++ b/nautobot_chatops/navigation.py @@ -1,9 +1,13 @@ """Plugin additions to the Nautobot navigation menu.""" +from django.conf import settings from nautobot.extras.plugins import PluginMenuItem, PluginMenuButton from nautobot.utilities.choices import ButtonColorChoices -from .integrations.grafana.navigation import menu_items as grafana_menu_items +if settings.PLUGINS_CONFIG["nautobot_chatops"]["enable_grafana"]: + from .integrations.grafana.navigation import menu_items as grafana_menu_items +else: + grafana_menu_items = () menu_items = ( PluginMenuItem( diff --git a/nautobot_chatops/static/ipfabric/IP_Fabric_logo_small.jpg b/nautobot_chatops/static/ipfabric/IP_Fabric_logo_small.jpg deleted file mode 100644 index c69ad84f..00000000 Binary files a/nautobot_chatops/static/ipfabric/IP_Fabric_logo_small.jpg and /dev/null differ diff --git a/nautobot_chatops/static/ipfabric/ipfabric_logo.png b/nautobot_chatops/static/ipfabric/ipfabric_logo.png index 568f3f3f..256074d6 100644 Binary files a/nautobot_chatops/static/ipfabric/ipfabric_logo.png and b/nautobot_chatops/static/ipfabric/ipfabric_logo.png differ diff --git a/nautobot_chatops/tests/workers/test_nautobot.py b/nautobot_chatops/tests/workers/test_nautobot.py new file mode 100644 index 00000000..a6c7db59 --- /dev/null +++ b/nautobot_chatops/tests/workers/test_nautobot.py @@ -0,0 +1,56 @@ +"""Tests for the /nautobot chatops commands.""" +from unittest.mock import MagicMock + +from django.test import TestCase +from nautobot.dcim.models import Site +from nautobot.ipam.models import VLAN +from nautobot.extras.models import Status +from nautobot_chatops.choices import CommandStatusChoices + +from nautobot_chatops.dispatchers import Dispatcher +from nautobot_chatops.workers.nautobot import get_vlans + + +class IpamTestCase(TestCase): + """Tests related to IPAM ChatOps commands.""" + + def setUp(self): + """Per-test-case setup function.""" + self.active_status = Status.objects.get(name="Active") + self.site = Site.objects.create(name="site-1", status=self.active_status) + self.vlans, _ = VLAN.objects.get_or_create(vid=1, name="vlan-1", status=self.active_status, site=self.site) + + # Mock the dispatcher + self.dispatcher = MagicMock(Dispatcher) + + def test_get_vlans_initial_prompt(self): + """Test get VLANs initial command.""" + self.assertFalse(get_vlans(self.dispatcher)) + self.dispatcher.send_error.assert_not_called() + self.dispatcher.prompt_from_menu.assert_called_with( + "nautobot get-vlans", + "select a vlan filter", + [ + ("VLAN ID", "id"), + ("Group", "group"), + ("Name", "name"), + ("Role", "role"), + ("Site", "site"), + ("Status", "status"), + ("Tenant", "tenant"), + ("All (no filter)", "all"), + ], + ) + + def test_get_vlans_filter_type_sent_filter_name(self): + """Test get VLANs with filter type Name selected.""" + self.assertFalse(get_vlans(self.dispatcher, "name")) + self.dispatcher.send_error.assert_not_called() + self.dispatcher.prompt_from_menu.assert_called_with( + "nautobot get-vlans name", "select a vlan name", [("vlan-1", "vlan-1")], offset=0 + ) + + def test_get_vlans_filter_type_sent_filter_all(self): + """Test get VLANs with filter type All selected.""" + self.assertEqual(get_vlans(self.dispatcher, "all"), CommandStatusChoices.STATUS_SUCCEEDED) + self.dispatcher.send_error.assert_not_called() diff --git a/nautobot_chatops/urls.py b/nautobot_chatops/urls.py index b84f4774..17b06bf6 100644 --- a/nautobot_chatops/urls.py +++ b/nautobot_chatops/urls.py @@ -1,6 +1,7 @@ """Django urlpatterns declaration for nautobot_chatops plugin.""" import logging +from django.conf import settings from django.urls import path from nautobot.extras.views import ObjectChangeLogView @@ -18,15 +19,19 @@ AccessGrantBulkDeleteView, ) -try: - from nautobot_chatops.integrations.grafana.urls import urlpatterns as grafana_urlpatterns -# pylint: disable-next=broad-except -except Exception: +if settings.PLUGINS_CONFIG["nautobot_chatops"]["enable_grafana"]: + try: + from nautobot_chatops.integrations.grafana.urls import urlpatterns as grafana_urlpatterns + # pylint: disable-next=broad-except + except Exception: + grafana_urlpatterns = [] + logger = logging.getLogger(__name__) + logger.warning("Grafana ChatOps integration is not available.", exc_info=True) +else: grafana_urlpatterns = [] logger = logging.getLogger(__name__) logger.warning("Grafana ChatOps integration is not available.", exc_info=True) - urlpatterns = [ path("", NautobotHomeView.as_view(), name="home"), path("access/", AccessGrantListView.as_view(), name="accessgrant_list"), diff --git a/nautobot_chatops/workers/nautobot.py b/nautobot_chatops/workers/nautobot.py index 747a3be1..642d457a 100644 --- a/nautobot_chatops/workers/nautobot.py +++ b/nautobot_chatops/workers/nautobot.py @@ -160,7 +160,7 @@ def examine_termination_endpoints(circuit): # pylint: disable=too-many-statements @subcommand_of("nautobot") -def get_vlans(dispatcher, filter_type, filter_value_1): +def get_vlans(dispatcher, filter_type=None, filter_value_1=None): """Return a filtered list of VLANs based on filter type and/or `filter_value_1`.""" # pylint: disable=no-else-return if not filter_type: diff --git a/poetry.lock b/poetry.lock index 42dd0c79..f5ea902a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4725,4 +4725,4 @@ panorama = ["defusedxml", "ipaddr", "netmiko", "netutils", "pan-os-python"] [metadata] lock-version = "2.0" python-versions = "^3.8.0" -content-hash = "18d99944fa290289afe8d2725fb0b3453789d259395f119d53c6644a0f95592b" +content-hash = "de96ece1039708aa0171ed405f07380bddc81cf495b83fb39311e6119680f3a6" diff --git a/pyproject.toml b/pyproject.toml index 0cd34045..6a0b080c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nautobot-chatops" -version = "2.0.2" +version = "2.0.3" description = "A plugin providing chatbot capabilities for Nautobot" authors = ["Network to Code, LLC "] readme = "README.md" @@ -44,7 +44,7 @@ ipfabric-diagrams = { version = "~6.0.2", optional = true } isodate = { version = "^0.6.1", optional = true } meraki = { version = "^1.7.2", optional = true } nautobot = "^1.5.4" -nautobot-capacity-metrics = "*" +nautobot-capacity-metrics = "^2.0.0" netmiko = { version = "^3.4.0", optional = true } netutils = { version = "^1.1.0", optional = true } pan-os-python = { version = "^1.3.0", optional = true }