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

Finish integrations #218

Merged
merged 26 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8d8788d
chore: Improve integrations handling
snaselj Jun 14, 2023
1b3050a
fix: Add changelog.
snaselj Jun 14, 2023
adea05c
fix: Circular import
snaselj Jun 14, 2023
62e1b68
fix: Replace obsolete WEBEX_TEAMS... with WEBEX...
snaselj Jun 14, 2023
0bbbeae
fix: Unittest not to be dependent on creds.example
snaselj Jun 14, 2023
e740506
fix: black
snaselj Jun 14, 2023
dba7323
fix: Extra coma
snaselj Jun 14, 2023
225028e
doc: Admin install ACI
snaselj Jun 19, 2023
8ef287d
docs: Added /aci user commands, improvements
snaselj Jun 20, 2023
2aa6be7
docs: ACI screenshots
snaselj Jun 20, 2023
beda413
chore: Webex cleanup
snaselj Jun 21, 2023
9a9a4df
chore: Add missing empty docs
snaselj Jun 21, 2023
1616ac7
chore: Credits to original contributors
snaselj Jun 21, 2023
b071c02
fix: Better format nautobot subcommands help
snaselj Jun 21, 2023
db845d1
fix: pylint line length
snaselj Jun 21, 2023
38a4631
Merge remote-tracking branch 'origin/develop' into u/snaselj-finish-i…
snaselj Jun 23, 2023
0708160
Merge remote-tracking branch 'origin/develop' into u/snaselj-finish-i…
snaselj Jul 10, 2023
65b06e9
fix: PR comments
snaselj Jul 19, 2023
394ca88
fix: Include glossary to users guide
snaselj Jul 19, 2023
7f7cf9e
chore: Rename arista_cloudvision to arista_cv
snaselj Jul 19, 2023
e370561
chore: Commands, some of install instructions
snaselj Jul 19, 2023
e05bb8e
doc: Grafana and fixes
snaselj Jul 24, 2023
657689a
doc: IPFabric
snaselj Jul 24, 2023
bb9905e
doc: Meraki
snaselj Jul 24, 2023
18b2ccb
doc: Panorama
snaselj Jul 24, 2023
f545665
doc: Dev and fixes
snaselj Jul 24, 2023
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
4 changes: 4 additions & 0 deletions changes/218.changed
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- Added `/clear` command to development Mattermost.
- Improved integration workers loading.
- Sorted App config and environment variables.
- Sorted pyproject configurations.
59 changes: 36 additions & 23 deletions development/creds.example.env
Original file line number Diff line number Diff line change
@@ -1,35 +1,48 @@
# nautobot_chatops
SLACK_API_TOKEN=xoxb-...
SLACK_SIGNING_SECRET=...
# SLACK_SLASH_COMMAND_PREFIX=/
MICROSOFT_APP_ID=...
MICROSOFT_APP_PASSWORD=...
WEBEX_TEAMS_ACCESS_TOKEN=...
WEBEX_TEAMS_SIGNING_SECRET=...
MATTERMOST_API_TOKEN="5qsffxoapt883qfdygbdgf17jy"
POSTGRES_PASSWORD=notverysecurepwd
REDIS_PASSWORD=notverysecurepwd
SECRET_KEY=r8OwDznj!!dci#P9ghmRfdu1Ysxm0AiPeDCQhKE+N_rClfWNj
NAUTOBOT_CREATE_SUPERUSER=true
NAUTOBOT_SUPERUSER_API_TOKEN=0123456789abcdef0123456789abcdef01234567
NAUTOBOT_SUPERUSER_PASSWORD=admin
NAUTOBOT_TOWER_PASSWORD="password"

# Cisco ACI Chatops Plugin Settings
# = Chat Platforms ===================

# - Mattermost -----------------------
MATTERMOST_API_TOKEN="5qsffxoapt883qfdygbdgf17jy"

# - Microsoft Teams ------------------
# MICROSOFT_APP_ID="changeme"
# MICROSOFT_APP_PASSWORD="changeme"

# - Slack ----------------------------
# SLACK_API_TOKEN="xoxb-changeme"
# SLACK_APP_TOKEN="changeme"
# SLACK_SIGNING_SECRET="changeme"

# - Webex ----------------------------
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We went with Webex Teams when it was rebranded. Did Webex Teams become Webex again?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition, I know it doesn't really matter, as Admins can change the nautobot_config.py to whatever they want, it will still cause issues when using an older creds.env for developers expecting WEBEX_TEAMS_ACCESS_TOKEN.

Copy link
Contributor Author

@snaselj snaselj Jun 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expecting the next ChatOps App version to be 2.0, I was taking into account this deprecation: https://github.com/nautobot/nautobot-plugin-chatops/blob/develop/docs/admin/install/webex_setup.md#deprecation-warning

Webex Teams brand doesn't seem to be advertised by Ciso, when using search tools.

The old WEBEX_TEAMS_ACCESS_TOKEN is directly consumed by webexteamssdk library, however WEBEX_ACCESS_TOKEN is read by the App nautobot_config.py, passed to App config, and then passed to the library as arguments. Seems to me a bit better to use environment variables controlled by our App config to allow us some validations.

I would stay with Webex and emphasize this change in the documentation I'm preparing WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can replace all WebEx occurrences with Webex including class names in the code, to be inline with the official Cisco naming, WDYT @smk4664 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this was going out pre 2.0, but we are close to the Nautobot 2.0 release, so I am good with these changes.
As long as we document them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Webex cleaned up:

  • Renamed WebEx => Webex.
  • Simplified reading App config.
    • Added def get_app_config_part(prefix) .
  • Removed webex_teams related deprecation warnings and usage.
  • Added webex_msg_char_limit App config entry.

# WEBEX_ACCESS_TOKEN="changeme"
# WEBEX_SIGNING_SECRET="changeme"

# = ChatOps Integrations =============

# - Cisco ACI ------------------------
# First APIC
APIC_USERNAME_NTCAPIC=admin
APIC_PASSWORD_NTCAPIC=notverysecurepwd
APIC_URI_NTCAPIC=https://aci.demo.networktocode.com
APIC_VERIFY_NTCAPIC=false
# APIC_USERNAME_NTCAPIC=admin
# APIC_PASSWORD_NTCAPIC=notverysecurepwd
# APIC_URI_NTCAPIC=https://aci.demo.networktocode.com
# APIC_VERIFY_NTCAPIC=false
# Second APIC
APIC_USERNAME_LAB=admin
APIC_PASSWORD_LAB=labpassword
APIC_URI_LAB=https://10.100.1.10
APIC_VERIFY_LAB=false
# APIC_USERNAME_LAB=admin
# APIC_PASSWORD_LAB=labpassword
# APIC_URI_LAB=https://10.100.1.10
# APIC_VERIFY_LAB=false
# Repeat for as many as you need...

MERAKI_API_KEY=1234567890
# - Ansible --------------------------
NAUTOBOT_TOWER_PASSWORD="password"

# - Meraki ---------------------------
# MERAKI_API_KEY="1234567890"

PANORAMA_HOST=localhost
PANORAMA_USER=admin
PANORAMA_PASSWORD=admin
# - Panorama -------------------------
# PANORAMA_PASSWORD=admin
32 changes: 32 additions & 0 deletions development/dev.env
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,40 @@ POSTGRES_USER=nautobot
# Needed for Redis should match the values for Nautobot above
REDIS_PASSWORD=notverysecurepwd

# = ChatOps ==========================
NAUTOBOT_CHATOPS_RESTRICT_HELP="False"

# = Chat Platforms ===================

# - Mattermost -----------------------
NAUTOBOT_CHATOPS_ENABLE_MATTERMOST="True"
MATTERMOST_URL="http://mattermost:8065"

# - Microsoft Teams ------------------
NAUTOBOT_CHATOPS_ENABLE_MS_TEAMS="False"

# - Slack ----------------------------
NAUTOBOT_CHATOPS_ENABLE_SLACK="False"
# SLACK_SLASH_COMMAND_PREFIX="/"

# - Webex ----------------------------
NAUTOBOT_CHATOPS_ENABLE_WEBEX="False"

# = ChatOps Integrations =============

# - Cisco ACI ------------------------
NAUTOBOT_CHATOPS_ENABLE_ACI="False"

# - Ansible --------------------------
NAUTOBOT_CHATOPS_ENABLE_ANSIBLE="True"
NAUTOBOT_TOWER_URI="https://awx:8043/"
NAUTOBOT_TOWER_USERNAME="awx"
NAUTOBOT_TOWER_VERIFY_SSL="False"

# - Meraki ---------------------------
NAUTOBOT_CHATOPS_ENABLE_MERAKI="False"

# - Panorama -------------------------
NAUTOBOT_CHATOPS_ENABLE_PANORAMA="False"
# PANORAMA_HOST="changeme"
# PANORAMA_USER="changme"
1 change: 1 addition & 0 deletions development/mattermost/dump.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1590,6 +1590,7 @@ INSERT INTO `Channels` VALUES ('9g8qo5udpp8dzdud8jex1m6kuh',1684146025517,168414
INSERT INTO `Channels` VALUES ('fi1muawz1bybue4gwu95kni4eh',1684139715866,1684139715866,0,'35odngbgr7yw3bf13o8kg85ngh','O','Off-Topic','off-topic','','',1684146863411,0,0,'',NULL,NULL,NULL,0,1684146863411);
INSERT INTO `Commands` VALUES ('yhepukctj7r1jgr8kappi7mb7e','tc1u8wbh53fwxxdkhswbmu9wsa',1685617546901,1685618110521,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','aci','P','','',0,'','','Cisco ACI','Cisco ACI Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/','');
INSERT INTO `Commands` VALUES ('846xisdqmtro9yd3eg8m45co3o','c7udax974iymjkmoyhi1a11cpy',1685089324429,1685089324429,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','ansible','P','','',0,'','','Ansible','Ansible Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/','');
INSERT INTO `Commands` VALUES ('561dqoomjt8ixqc3td9m53i3mh','p7phuwhpaiddjxqf8c1hnw33yh',1686737880192,1686737880192,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','clear','P','','',0,'','','Clear','Clear Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/','');
INSERT INTO `Commands` VALUES ('j5pnszdfcpbt3f6yfs63o5bwhw','t9irqwjni3dozf3yx6tzak7k3w',1685532127072,1685532127072,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','meraki','P','','',0,'','','Cisco Meraki','Cisco Meraki Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/','');
INSERT INTO `Commands` VALUES ('d9irq7zuwt84pr77crnteso6da','rmdpfdjhnpg988e7ujzyom4euh',1684146546769,1684152166227,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','nautobot','P','','',0,'','','Nautobot','Nautobot Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/','');
INSERT INTO `Commands` VALUES ('uooffhygyigtfb4454k9yxm81h','6nf5cmz1ft8bdfykz46cs5pofo',1685702889199,1685702889199,0,'jactwicuqb8bu8pau8mgjydzeo','35odngbgr7yw3bf13o8kg85ngh','panorama','P','','',0,'','','Panorama','Panorama Slash Command','http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/','');
Expand Down
1 change: 1 addition & 0 deletions development/mattermost/nautobot_bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
_COMMAND_TOKENS = {
"aci": "tc1u8wbh53fwxxdkhswbmu9wsa", # nosec
"ansible": "c7udax974iymjkmoyhi1a11cpy", # nosec
"clear": "p7phuwhpaiddjxqf8c1hnw33yh", # nosec
"meraki": "t9irqwjni3dozf3yx6tzak7k3w", # nosec
"nautobot": "rmdpfdjhnpg988e7ujzyom4euh", # nosec
"panorama": "6nf5cmz1ft8bdfykz46cs5pofo", # nosec
Expand Down
50 changes: 29 additions & 21 deletions development/nautobot_config.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
"""Nautobot configuration."""
import json
import os
import sys


from nautobot.core.settings import * # noqa: F401,F403 pylint: disable=wildcard-import,unused-wildcard-import
from nautobot.core.settings_funcs import parse_redis_connection


def _get_bool_env(name: str, default=False):
value = os.getenv(name, str(default))
return bool(json.loads(value.lower()))
from nautobot.core.settings_funcs import is_truthy, parse_redis_connection


ALLOWED_HOSTS = os.getenv("NAUTOBOT_ALLOWED_HOSTS", "").split(" ")
Expand Down Expand Up @@ -133,31 +126,46 @@ def _get_bool_env(name: str, default=False):
# Each key in the dictionary is the name of an installed plugin and its value is a dictionary of settings.
PLUGINS_CONFIG = {
"nautobot_chatops": {
"aci_creds": {x: os.environ[x] for x in os.environ if "APIC" in x},
"enable_mattermost": _get_bool_env("NAUTOBOT_CHATOPS_ENABLE_MATTERMOST"),
"enable_ms_teams": _get_bool_env("NAUTOBOT_CHATOPS_ENABLE_MS_TEAMS"),
"enable_slack": _get_bool_env("NAUTOBOT_CHATOPS_ENABLE_SLACK"),
"enable_webex": _get_bool_env("NAUTOBOT_CHATOPS_ENABLE_WEBEX"),
# = Common settings ==================
"restrict_help": is_truthy(os.getenv("NAUTOBOT_CHATOPS_RESTRICT_HELP")),
# = 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"),
"meraki_dashboard_api_key": os.environ.get("MERAKI_API_KEY"),
# - 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"),
"restrict_help": _get_bool_env("NAUTOBOT_CHATOPS_RESTRICT_HELP"),
# - 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", "/"),
"tower_uri": os.getenv("NAUTOBOT_TOWER_URI"),
"tower_username": os.getenv("NAUTOBOT_TOWER_USERNAME"),
"tower_password": os.getenv("NAUTOBOT_TOWER_PASSWORD"),
"tower_verify_ssl": _get_bool_env("NAUTOBOT_TOWER_VERIFY_SSL", True),
# - WebEx ----------------------------
"enable_webex": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_WEBEX")),
"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},
# - Ansible --------------------------
"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)),
# - Meraki ---------------------------
"enable_meraki": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_MERAKI")),
"meraki_dashboard_api_key": os.environ.get("MERAKI_API_KEY"),
# - Panorama -------------------------
"enable_panorama": is_truthy(os.getenv("NAUTOBOT_CHATOPS_ENABLE_PANORAMA")),
"panorama_host": os.environ.get("PANORAMA_HOST"),
"panorama_user": os.environ.get("PANORAMA_USER"),
"panorama_password": os.environ.get("PANORAMA_PASSWORD"),
"panorama_user": os.environ.get("PANORAMA_USER"),
},
}

METRICS_ENABLED = _get_bool_env("NAUTOBOT_METRICS_ENABLED")
METRICS_ENABLED = is_truthy(os.getenv("NAUTOBOT_METRICS_ENABLED"))
74 changes: 43 additions & 31 deletions nautobot_chatops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
_CONFLICTING_APP_NAMES = [
# App names that conflict with nautobot_chatops
"nautobot_plugin_chatops_aci",
"nautobot_plugin_chatops_ansible",
"nautobot_plugin_chatops_meraki",
"nautobot_plugin_chatops_panorama",
]
Expand Down Expand Up @@ -46,17 +47,29 @@ class NautobotChatOpsConfig(PluginConfig):
base_url = "chatops"
required_settings = []
default_settings = {
"aci_creds": None,
"enable_slack": False,
"enable_ms_teams": False,
"enable_webex": False,
# = ChatOps ==========================
# Should menus, text input fields, etc. be deleted from the chat history after the user makes a selection?
"delete_input_on_submission": False,
"restrict_help": False,
# Session Cache
"session_cache_timeout": 86400,
# Slack-specific settings
"slack_api_token": None, # for example, "xoxb-123456"
"slack_signing_secret": None,
# As requested on https://github.com/nautobot/nautobot-plugin-chatops/issues/114 this setting is used for
# sending all messages as an ephemeral message, meaning only the person interacting with the bot will see the
# responses.
"send_all_messages_private": False,
# = Chat Platforms ===================
# - Mattermost -----------------------
"enable_mattermost": False,
"mattermost_api_token": "",
"mattermost_url": "",
# - Microsoft Teams ------------------
"enable_ms_teams": False,
"microsoft_app_id": "",
"microsoft_app_password": "",
# - Slack ----------------------------
"enable_slack": False,
"slack_api_token": "", # for example, "xoxb-123456"
"slack_signing_secret": "",
"slack_ephemeral_message_size_limit": 3000,
# Any prefix that's prepended to all slash-commands for this bot and should be stripped away
# in order to identify the actual command name to be invoked, eg "/nautobot-"
Expand All @@ -65,30 +78,29 @@ class NautobotChatOpsConfig(PluginConfig):
# where to find Static images. If Django Storages is configured with an External server like S3,
# this can be ignored.
# If neither option is provided, then no static images (like Nautobot Logo) will be shown.
"slack_socket_static_host": None,
# Microsoft-Teams-specific settings
"microsoft_app_id": None,
"microsoft_app_password": None,
# WebEx-specific settings
"webex_token": None,
"webex_signing_secret": None,
"enable_mattermost": False,
# Mattermost-specific settings
"mattermost_api_token": None,
"mattermost_url": None,
# As requested on https://github.com/nautobot/nautobot-plugin-chatops/issues/114 this setting is used for
# sending all messages as an ephemeral message, meaning only the person interacting with the bot will see the
# responses.
"send_all_messages_private": False,
"restrict_help": False,
"meraki_dashboard_api_key": None,
"tower_uri": None,
"tower_username": None,
"tower_password": None,
"tower_verify_ssl": False,
"panorama_host": None,
"panorama_user": None,
"panorama_password": None,
"slack_socket_static_host": "",
# - Webex ----------------------------
"enable_webex": False,
"webex_token": "",
"webex_signing_secret": "",
# = Integrations =====================
# - Cisco ACI ------------------------
"enable_aci": False,
"aci_creds": "",
# - Ansible --------------------------
"enable_ansible": False,
"tower_password": "",
"tower_uri": "",
"tower_username": "",
"tower_verify_ssl": True,
# - Meraki ---------------------------
"enable_meraki": False,
"meraki_dashboard_api_key": "",
# - Panorama -------------------------
"enable_panorama": False,
"panorama_host": "",
"panorama_password": "",
"panorama_user": "",
}

max_version = "1.999"
Expand Down
50 changes: 50 additions & 0 deletions nautobot_chatops/integrations/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""Utility functions for nautobot_chatops integrations."""
from collections.abc import Mapping
from importlib import import_module
from pathlib import Path
from types import ModuleType
from typing import Generator

from django.conf import settings

from nautobot_chatops.utils import logger


def _each_integration() -> Generator[str, None, None]:
"""Return all integrations."""
for path in Path(__file__).parent.iterdir():
if (path / "worker.py").is_file():
yield path.name


ALL_INTEGRATIONS = set(_each_integration())


def _each_enabled_integration() -> Generator[str, None, None]:
"""Return all enabled integrations."""
if not isinstance(settings.PLUGINS_CONFIG, Mapping):
raise TypeError("Django `settings.PLUGINS_CONFIG` must be a Mapping")

config = settings.PLUGINS_CONFIG["nautobot_chatops"]
if not isinstance(config, Mapping):
raise TypeError("nautobot_chatops config must be a Mapping")

for name in ALL_INTEGRATIONS:
if config.get(f"enable_{name}", False):
yield name


ENABLED_INTEGRATIONS = set(_each_enabled_integration())
DISABLED_INTEGRATIONS = ALL_INTEGRATIONS - ENABLED_INTEGRATIONS


def each_enabled_integration_module(module_name: str) -> Generator[ModuleType, None, None]:
"""For each enabled integration, import the module name."""
for name in ENABLED_INTEGRATIONS:
try:
module = import_module(f"nautobot_chatops.integrations.{name}.{module_name}")
except ModuleNotFoundError:
logger.debug("Integration %s does not have a %s module, skipping.", name, module_name)
continue

yield module
8 changes: 7 additions & 1 deletion nautobot_chatops/tests/test_dispatchers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"""Tests for Nautobot dispatcher class implementations."""
from copy import deepcopy
from unittest.mock import patch, MagicMock

from django.conf import settings
from django.test import TestCase
from django.test import TestCase, override_settings
from slack_sdk.errors import SlackApiError

from nautobot_chatops.dispatchers.ms_teams import MSTeamsDispatcher
Expand Down Expand Up @@ -247,6 +248,11 @@ def test_thread_ts_passed_into_slack_client(self):
pass


_PLUGINS_CONFIG = deepcopy(settings.PLUGINS_CONFIG)
_PLUGINS_CONFIG["nautobot_chatops"]["webex_token"] = "changeme"


@override_settings(PLUGINS_CONFIG=_PLUGINS_CONFIG)
class TestWebExDispatcher(TestSlackDispatcher):
"""Test the WebExDispatcher class."""

Expand Down
Loading