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

Fix constance being accessed before database is ready and other fixes #341

Merged
merged 9 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/341.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added a "grafana disabled" view in case a user clicks on a grafana nav menu item when the grafana integration is disabled.
4 changes: 4 additions & 0 deletions changes/341.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fixed django-constance not being upgradable due to this app accessing the database before migrations could run.
Removed conditional logic for adding grafana navigation menu items.
Fixed Nautobot v2.3 incompatibility caused by saved views not being able to determine the models' table classes.
Added exception handling for cases where diffsync is not installed, since it's marked as optional.
1 change: 1 addition & 0 deletions changes/341.housekeeping
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed dev environment nautobot_config.py to fall back to constance if environment variable is not used.
glennmatthews marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions changes/341.removed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Removed all grafana integration API files since there we no API views provided by grafana integration.
38 changes: 26 additions & 12 deletions development/nautobot_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,36 +146,29 @@
# | `session_cache_timeout` | Controls session cache | No | `86400` |
# = Chat Platforms ===================
# - Mattermost -----------------------
"enable_mattermost": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_MATTERMOST")),
"mattermost_api_token": os.environ.get("MATTERMOST_API_TOKEN"),
"mattermost_url": os.environ.get("MATTERMOST_URL"),
# - Microsoft Teams ------------------
"enable_ms_teams": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_MS_TEAMS")),
"microsoft_app_id": os.environ.get("MICROSOFT_APP_ID"),
"microsoft_app_password": os.environ.get("MICROSOFT_APP_PASSWORD"),
# - Slack ----------------------------
"enable_slack": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_SLACK")),
"slack_api_token": os.environ.get("SLACK_API_TOKEN"),
"slack_app_token": os.environ.get("SLACK_APP_TOKEN"),
"slack_signing_secret": os.environ.get("SLACK_SIGNING_SECRET"),
"slack_slash_command_prefix": os.environ.get("SLACK_SLASH_COMMAND_PREFIX", "/"),
# - Cisco Webex ----------------------
"enable_webex": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_WEBEX")),
"webex_msg_char_limit": int(os.getenv("WEBEX_MSG_CHAR_LIMIT", "7439")),
"webex_signing_secret": os.environ.get("WEBEX_SIGNING_SECRET"),
"webex_token": os.environ.get("WEBEX_ACCESS_TOKEN"),
# = Integrations =====================
# - Cisco ACI ------------------------
"enable_aci": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_ACI")),
"aci_creds": {x: os.environ[x] for x in os.environ if "APIC" in x},
# - AWX / Ansible Tower --------------
"enable_ansible": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_ANSIBLE")),
"tower_password": os.getenv("NAUTOBOT_TOWER_PASSWORD"),
"tower_uri": os.getenv("NAUTOBOT_TOWER_URI"),
"tower_username": os.getenv("NAUTOBOT_TOWER_USERNAME"),
"tower_verify_ssl": is_truthy(os.getenv("NAUTOBOT_TOWER_VERIFY_SSL", "true")),
# - Arista CloudVision ---------------
"enable_aristacv": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_ARISTACV")),
"aristacv_cvaas_url": os.environ.get("ARISTACV_CVAAS_URL"),
"aristacv_cvaas_token": os.environ.get("ARISTACV_CVAAS_TOKEN"),
"aristacv_cvp_host": os.environ.get("ARISTACV_CVP_HOST"),
Expand All @@ -184,7 +177,6 @@
"aristacv_cvp_username": os.environ.get("ARISTACV_CVP_USERNAME"),
"aristacv_on_prem": is_truthy(os.environ.get("ARISTACV_ON_PREM")),
# - Grafana --------------------------
"enable_grafana": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_GRAFANA")),
"grafana_url": os.environ.get("GRAFANA_URL", ""),
"grafana_api_key": os.environ.get("GRAFANA_API_KEY", ""),
"grafana_default_width": 0,
Expand All @@ -194,26 +186,48 @@
"grafana_org_id": 1,
"grafana_default_tz": "America/Denver",
# - IPFabric --------------------------
"enable_ipfabric": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_IPFABRIC")),
"ipfabric_api_token": os.environ.get("IPFABRIC_API_TOKEN"),
"ipfabric_host": os.environ.get("IPFABRIC_HOST"),
"ipfabric_timeout": os.environ.get("IPFABRIC_TIMEOUT", 15),
"ipfabric_verify": is_truthy(os.environ.get("IPFABRIC_VERIFY", True)),
# - Cisco Meraki ---------------------
"enable_meraki": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_MERAKI")),
"meraki_dashboard_api_key": os.environ.get("MERAKI_API_KEY"),
# - Palo Alto Panorama ---------------
"enable_panorama": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_PANORAMA")),
"panorama_host": os.environ.get("PANORAMA_HOST"),
"panorama_password": os.environ.get("PANORAMA_PASSWORD"),
"panorama_user": os.environ.get("PANORAMA_USER"),
# - Cisco NSO ------------------------
"enable_nso": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_NSO")),
"nso_url": os.environ.get("NSO_URL"),
"nso_username": os.environ.get("NSO_USERNAME"),
"nso_password": os.environ.get("NSO_PASSWORD"),
"nso_request_timeout": os.environ.get("NSO_REQUEST_TIMEOUT", 60),
},
}
if os.getenv("NAUTOBOT_CHATOPS_ENABLE_MATTERMOST", "") != "":
PLUGINS_CONFIG["nautobot_chatops"]["enable_mattermost"] = (
is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_MATTERMOST")),
)
if os.getenv("NAUTOBOT_CHATOPS_ENABLE_MS_TEAMS", "") != "":
PLUGINS_CONFIG["nautobot_chatops"]["enable_ms_teams"] = is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_MS_TEAMS"))
if os.getenv("NAUTOBOT_CHATOPS_ENABLE_SLACK", "") != "":
PLUGINS_CONFIG["nautobot_chatops"]["enable_slack"] = is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_SLACK"))
if os.getenv("NAUTOBOT_CHATOPS_ENABLE_WEBEX", "") != "":
PLUGINS_CONFIG["nautobot_chatops"]["enable_webex"] = is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_WEBEX"))
if os.getenv("NAUTOBOT_CHATOPS_ENABLE_ACI", "") != "":
PLUGINS_CONFIG["nautobot_chatops"]["enable_aci"] = is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_ACI"))
if os.getenv("NAUTOBOT_CHATOPS_ENABLE_ANSIBLE", "") != "":
PLUGINS_CONFIG["nautobot_chatops"]["enable_ansible"] = is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_ANSIBLE"))
if os.getenv("NAUTOBOT_CHATOPS_ENABLE_ARISTACV", "") != "":
PLUGINS_CONFIG["nautobot_chatops"]["enable_aristacv"] = is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_ARISTACV"))
if os.getenv("NAUTOBOT_CHATOPS_ENABLE_GRAFANA", "") != "":
PLUGINS_CONFIG["nautobot_chatops"]["enable_grafana"] = is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_GRAFANA"))
if os.getenv("NAUTOBOT_CHATOPS_ENABLE_IPFABRIC", "") != "":
PLUGINS_CONFIG["nautobot_chatops"]["enable_ipfabric"] = is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_IPFABRIC"))
if os.getenv("NAUTOBOT_CHATOPS_ENABLE_MERAKI", "") != "":
PLUGINS_CONFIG["nautobot_chatops"]["enable_meraki"] = is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_MERAKI"))
if os.getenv("NAUTOBOT_CHATOPS_ENABLE_PANORAMA", "") != "":
PLUGINS_CONFIG["nautobot_chatops"]["enable_panorama"] = is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_PANORAMA"))
if os.getenv("NAUTOBOT_CHATOPS_ENABLE_NSO", "") != "":
PLUGINS_CONFIG["nautobot_chatops"]["enable_nso"] = is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_NSO"))

METRICS_ENABLED = is_truthy(os.getenv("NAUTOBOT_METRICS_ENABLED"))
47 changes: 12 additions & 35 deletions nautobot_chatops/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

import logging

from django.urls import include, path
from django.urls import path
from nautobot.apps.api import OrderedDefaultRouter
from nautobot.apps.config import get_app_settings_or_config

from nautobot_chatops.api.views.generic import (
AccessGrantViewSet,
Expand All @@ -13,44 +12,24 @@
NautobotChatopsRootView,
)
from nautobot_chatops.api.views.lookup import AccessLookupView, UserEmailLookupView
from nautobot_chatops.api.views.mattermost import MattermostInteractionView, MattermostSlashCommandView
from nautobot_chatops.api.views.ms_teams import MSTeamsMessagesView
from nautobot_chatops.api.views.slack import SlackEventAPIView, SlackInteractionView, SlackSlashCommandView
from nautobot_chatops.api.views.webex import WebexView

logger = logging.getLogger(__name__)
urlpatterns = [
path("lookup/", AccessLookupView.as_view(), name="access_lookup"),
path("email-lookup/", UserEmailLookupView.as_view(), name="email_lookup"),
path("slack/slash_command/", SlackSlashCommandView.as_view(), name="slack_slash_command"),
path("slack/interaction/", SlackInteractionView.as_view(), name="slack_interaction"),
path("slack/event/", SlackEventAPIView.as_view(), name="slack_event"),
path("ms_teams/messages/", MSTeamsMessagesView.as_view(), name="ms_teams_messages"),
path("webex/", WebexView.as_view(), name="webex"),
path("mattermost/slash_command/", MattermostSlashCommandView.as_view(), name="mattermost_slash_command"),
path("mattermost/interaction/", MattermostInteractionView.as_view(), name="mattermost_interaction"),
]

if get_app_settings_or_config("nautobot_chatops", "enable_slack"):
from nautobot_chatops.api.views.slack import SlackEventAPIView, SlackInteractionView, SlackSlashCommandView

urlpatterns += [
path("slack/slash_command/", SlackSlashCommandView.as_view(), name="slack_slash_command"),
path("slack/interaction/", SlackInteractionView.as_view(), name="slack_interaction"),
path("slack/event/", SlackEventAPIView.as_view(), name="slack_event"),
]

if get_app_settings_or_config("nautobot_chatops", "enable_ms_teams"):
from nautobot_chatops.api.views.ms_teams import MSTeamsMessagesView

urlpatterns += [
path("ms_teams/messages/", MSTeamsMessagesView.as_view(), name="ms_teams_messages"),
]

if get_app_settings_or_config("nautobot_chatops", "enable_webex"):
from nautobot_chatops.api.views.webex import WebexView

urlpatterns += [
path("webex/", WebexView.as_view(), name="webex"),
]

if get_app_settings_or_config("nautobot_chatops", "enable_mattermost"):
from nautobot_chatops.api.views.mattermost import MattermostInteractionView, MattermostSlashCommandView

urlpatterns += [
path("mattermost/slash_command/", MattermostSlashCommandView.as_view(), name="mattermost_slash_command"),
path("mattermost/interaction/", MattermostInteractionView.as_view(), name="mattermost_interaction"),
]

router = OrderedDefaultRouter()
router.APIRootView = NautobotChatopsRootView
router.register("commandtoken", CommandTokenViewSet)
Expand All @@ -60,5 +39,3 @@
app_name = "nautobot_chatops-api"

urlpatterns += router.urls

urlpatterns += [path("grafana/", include("nautobot_chatops.integrations.grafana.api.urls"))]
11 changes: 9 additions & 2 deletions nautobot_chatops/api/views/mattermost.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from nautobot_chatops.metrics import signature_error_cntr
from nautobot_chatops.models import CommandToken
from nautobot_chatops.utils import check_and_enqueue_command
from nautobot_chatops.views import SettingsControlledViewMixin
from nautobot_chatops.workers import commands_help, get_commands_registry, parse_command_string

# pylint: disable=logging-fstring-interpolation
Expand Down Expand Up @@ -67,8 +68,14 @@ def verify_signature(request):
return True, "Signature is valid"


class MattermostView(SettingsControlledViewMixin, View):
"""Base class for Mattermost views."""

enable_view_setting = "enable_mattermost"


@method_decorator(csrf_exempt, name="dispatch")
class MattermostSlashCommandView(View):
class MattermostSlashCommandView(MattermostView):
"""Handle notifications from a Mattermost /command."""

http_method_names = ["post"]
Expand Down Expand Up @@ -117,7 +124,7 @@ def post(self, request, *args, **kwargs):


@method_decorator(csrf_exempt, name="dispatch")
class MattermostInteractionView(View):
class MattermostInteractionView(MattermostView):
"""Handle notifications resulting from a Mattermost interactive block."""

http_method_names = ["post"]
Expand Down
4 changes: 3 additions & 1 deletion nautobot_chatops/api/views/ms_teams.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from nautobot_chatops.dispatchers.ms_teams import MSTeamsDispatcher
from nautobot_chatops.utils import check_and_enqueue_command
from nautobot_chatops.views import SettingsControlledViewMixin
from nautobot_chatops.workers import commands_help, get_commands_registry, parse_command_string

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -113,9 +114,10 @@ def verify_jwt_token(request_headers, request_json):


@method_decorator(csrf_exempt, name="dispatch")
class MSTeamsMessagesView(View):
class MSTeamsMessagesView(SettingsControlledViewMixin, View):
"""Handle notifications from a Microsoft Teams bot."""

enable_view_setting = "enable_ms_teams"
http_method_names = ["post"]

# pylint: disable=too-many-locals,too-many-branches,too-many-statements
Expand Down
13 changes: 10 additions & 3 deletions nautobot_chatops/api/views/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from nautobot_chatops.dispatchers.slack import SlackDispatcher
from nautobot_chatops.metrics import signature_error_cntr
from nautobot_chatops.utils import check_and_enqueue_command
from nautobot_chatops.views import SettingsControlledViewMixin
from nautobot_chatops.workers import commands_help, get_commands_registry, parse_command_string

# pylint: disable=logging-fstring-interpolation
Expand Down Expand Up @@ -65,8 +66,14 @@ def verify_signature(request):
return True, "Signature is valid"


class SlackView(SettingsControlledViewMixin, View):
"""Base class for Slack views."""

enable_view_setting = "enable_slack"


@method_decorator(csrf_exempt, name="dispatch")
class SlackSlashCommandView(View):
class SlackSlashCommandView(SlackView):
"""Handle notifications from a Slack /command."""

http_method_names = ["post"]
Expand Down Expand Up @@ -115,7 +122,7 @@ def post(self, request, *args, **kwargs):


@method_decorator(csrf_exempt, name="dispatch")
class SlackInteractionView(View):
class SlackInteractionView(SlackView):
"""Handle notifications resulting from a Slack interactive block or modal."""

http_method_names = ["post"]
Expand Down Expand Up @@ -276,7 +283,7 @@ def post(self, request, *args, **kwargs):


@method_decorator(csrf_exempt, name="dispatch")
class SlackEventAPIView(View):
class SlackEventAPIView(SlackView):
"""Handle notifications resulting from a mention of the Slack app."""

http_method_names = ["post"]
Expand Down
4 changes: 3 additions & 1 deletion nautobot_chatops/api/views/webex.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from nautobot_chatops.dispatchers.webex import WEBEX_CONFIG, WebexDispatcher
from nautobot_chatops.utils import check_and_enqueue_command
from nautobot_chatops.views import SettingsControlledViewMixin
from nautobot_chatops.workers import commands_help, get_commands_registry, parse_command_string

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -76,9 +77,10 @@ def verify_signature(request):


@method_decorator(csrf_exempt, name="dispatch")
class WebexView(View):
class WebexView(SettingsControlledViewMixin, View):
"""Handle all supported inbound notifications from Webex."""

enable_view_setting = "enable_webex"
http_method_names = ["post"]

# pylint: disable=too-many-locals,too-many-return-statements,too-many-branches
Expand Down
1 change: 0 additions & 1 deletion nautobot_chatops/integrations/grafana/api/__init__.py

This file was deleted.

15 changes: 0 additions & 15 deletions nautobot_chatops/integrations/grafana/api/urls.py

This file was deleted.

5 changes: 0 additions & 5 deletions nautobot_chatops/integrations/grafana/api/views/__init__.py

This file was deleted.

11 changes: 0 additions & 11 deletions nautobot_chatops/integrations/grafana/api/views/generic.py

This file was deleted.

Loading