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

Add NSO integration #288

Merged
merged 23 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ac21062
Add NSO integration - initial commit
romanukes Oct 27, 2023
bbb47c4
Apply Black formatting
romanukes Dec 21, 2023
6581a97
Update NSO migration
romanukes Jan 4, 2024
73ddac8
Move NSO tests
romanukes Jan 4, 2024
d21cb93
Apply formatting
romanukes Jan 4, 2024
9f449ec
Make NSO integration compatible with Nautobot 2.0
romanukes Jan 4, 2024
6ed4759
Add NSO integration urls and navigation
romanukes Jan 4, 2024
db018a0
Add nso integration documentation
romanukes Jan 5, 2024
ed502fd
Add nso integration docs
romanukes Jan 5, 2024
e53bdee
Add responses dev dependency
romanukes Jan 5, 2024
3ebe8f2
Fix pylint warning
romanukes Jan 5, 2024
2d2912d
Update NSO documentation
romanukes Mar 4, 2024
651da37
Update poetry.lock
romanukes Mar 4, 2024
346a8d5
Add NSO integration commandfilter.html template
romanukes Mar 4, 2024
fbdceab
NSO integration - fix formatting
romanukes Mar 4, 2024
853147f
NSO integration - rename CommandFilter to NSOCommandFilter
romanukes Mar 4, 2024
0fbb291
NSO integration - Add newsfragment
romanukes Mar 5, 2024
04b6a99
NSO integration - Remove NSOCommandFilter model and run_commands command
romanukes Mar 14, 2024
32e0da7
NSO integration - Update documentation
romanukes Mar 15, 2024
7e2def7
NSO integration - Add NSO to mattermost dump.sql
romanukes Mar 15, 2024
87b2e4e
Merge remote-tracking branch 'origin/develop' into nso_integration
romanukes Mar 15, 2024
6ff064f
NSO integration - Add NSO and responses to pyproject.toml
romanukes Mar 18, 2024
347a1fa
NSO integration - Update poetry.lock
romanukes Mar 18, 2024
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/288.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added Cisco NSO integration
6 changes: 5 additions & 1 deletion development/creds.example.env
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,15 @@ NAUTOBOT_TOWER_PASSWORD="admin"
# - Grafana --------------------------
# GRAFANA_API_KEY="changeme"

# - IPFabric ---------------------
# - IPFabric -------------------------
# IPFABRIC_API_TOKEN="changeme"

# - Cisco Meraki ---------------------
# MERAKI_API_KEY="changeme"

# - Palo Alto Panorama ---------------
# PANORAMA_PASSWORD="changeme"

# - Cisco NSO ------------------------
# NSO_USERNAME="changeme"
# NSO_PASSWORD="changeme"
6 changes: 6 additions & 0 deletions development/development.env
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,9 @@ NAUTOBOT_CHATOPS_ENABLE_MERAKI="False"
NAUTOBOT_CHATOPS_ENABLE_PANORAMA="False"
PANORAMA_HOST="https://panorama.example.com"
PANORAMA_USER="admin"

# - Cisco NSO ------------------------
NAUTOBOT_CHATOPS_ENABLE_NSO="False"
# NSO_URL="https://nso.example.com"
# NSO_USERNAME="admin"
# NSO_PASSWORD="admin"
1 change: 1 addition & 0 deletions development/mattermost/dump.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1612,6 +1612,7 @@ INSERT INTO public.commands VALUES ('urmj87oqbbynir8nzc33by1f4c', '3wxwh3m8mjrzx
INSERT INTO public.commands VALUES ('mw51fho6ojd3fxqmrgfkt9xykw', 'ppm316za33ritm3xgpobcmmgre', 1698322479271, 1698322479271, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'ipfabric', 'P', '', '', false, '', '', 'IP Fabric', 'IP Fabric Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', '');
INSERT INTO public.commands VALUES ('11cwjihduffn3ceybits6n5zty', '11ix54hycjr4dmxcgw4d77qc4w', 1698322532951, 1698322532951, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'meraki', 'P', '', '', false, '', '', 'Cisco Meraki', 'Cisco Meraki Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', '');
INSERT INTO public.commands VALUES ('p43ko8rim3r89d78yexbg3fiww', 'fh1kbk45xtgm8r48jzr39ru1ww', 1698322585580, 1698322585580, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'panorama', 'P', '', '', false, '', '', 'Panorama', 'Panorama Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', '');
INSERT INTO public.commands VALUES ('qbxb8a33cimdw77hyxjeuyg80i', 'j9bcga71hl4lreaczecen7i5dz', 1698322527456, 1698322527456, 0, '5md7bsji6pbijpxitu8bwezaqy', 'rkpuunm3rp8fffhzkjxw63usyc', 'nso', 'P', '', '', false, '', '', 'Cisco NSO', 'Cisco NSO Slash Command', 'http://nautobot:8080/api/plugins/chatops/mattermost/slash_command/', '');


--
Expand Down
3 changes: 2 additions & 1 deletion development/mattermost/nautobot_bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"meraki": "11ix54hycjr4dmxcgw4d77qc4w", # nosec
"nautobot": "ncygprhkt3rrxr4rkytcaa7c9c", # nosec
"panorama": "fh1kbk45xtgm8r48jzr39ru1ww", # nosec
"nso": "j9bcga71hl4lreaczecen7i5dz", # nosec
}

for command, token in _COMMAND_TOKENS.items():
Expand All @@ -48,7 +49,7 @@
with contextlib.suppress(ObjectDoesNotExist):
admin = User.objects.get(name="admin")
ChatOpsAccountLink.objects.update_or_create(
user_id="jactwicuqb8bu8pau8mgjydzeo",
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To match the Mattermost SQL dump. Mattermost integration didn't work without this change

user_id="w7uyhzuo7fnfueen6og9cxmn9h",
platform=PlatformChoices.MATTERMOST,
defaults={"nautobot_user": admin},
)
6 changes: 6 additions & 0 deletions development/nautobot_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@
"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),
},
}

Expand Down
1 change: 1 addition & 0 deletions docs/admin/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,5 @@ Set up integrations using the specific guides:
- [Grafana](./integrations/grafana.md)
- [IPFabric](./integrations/ipfabric.md)
- [Cisco Meraki](./integrations/meraki.md)
- [Cisco NSO](./integrations/nso.md)
- [Palo Alto Panorama](./integrations/panorama.md)
56 changes: 56 additions & 0 deletions docs/admin/integrations/nso.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Cisco NSO Integration Setup

This guide will walk you through steps to set up Cisco NSO integration with the `nautobot_chatops` App.

## Prerequisites

Before configuring the integration, please ensure the following:

- `nautobot-chatops` App was installed.
```shell
pip install nautobot-chatops
```
- `nautobot-chatops` App is set up with at least one [enabled chat platform](../install.md#chat-platforms-configuration) and [tested](./../install.md#test-your-chatbot).
- [Cisco NSO](https://developer.cisco.com/docs/nso-guides-6.2/#!installation/installation) application installed and configured.

## Command Setup

Create a top-level command named `nso` in your enabled chat platform. For detailed instructions related to your specific chat platform, refer to the [platform specific set up](../install.md#chat-platforms-configuration).

## Configuration

You must define the following values in your `nautobot_config.py` file:

| Configuration Setting | Mandatory? | Default | Notes | Available on Admin Config |
| --------------------- | ---------- | ------- | ----- | ------------------------- |
| `enable_nso` | **Yes** | False | Enable Cisco NSO integration. | Yes |
| `nso_url` | **Yes** | | Base url that the Cisco NSO application is hosted at. | No |
| `nso_username` | **Yes** | | Cisco NSO username. | No |
| `nso_password` | **Yes** | | Cisco NSO password. | No |
| `nso_request_timeout` | | 60 | Timeout of the API request to Cisco NSO. | No |

Below is an example snippet from `development/nautobot_config.py` that demonstrates how to enable and configure Cisco NSO integration:

```python
PLUGINS = ["nautobot_chatops"]

PLUGINS_CONFIG = {
"nautobot_chatops": {
...
"enable_nso": True,
"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),
}
}
```

## Computed Fields

Optionally, a computed field might be created to display NSO status on a device details page. Please note, that it might delay the page load depending on NSO response time.

![Add a new computed field](../../images/nso-07.png)
![Computed fields list](../../images/nso-08.png)
![Device details 1](../../images/nso-09.png)
![Device details 2](../../images/nso-10.png)
Binary file added docs/images/nso-01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/nso-02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/nso-03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/nso-04.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/nso-05.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/nso-06.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/nso-07.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/nso-08.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/nso-09.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/nso-10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/user/app_getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,5 @@ The `nautobot-chatops` package includes multiple integrations. Each integration
- [Grafana](./integrations/grafana.md)
- [IPFabric](./integrations/ipfabric.md)
- [Cisco Meraki](./integrations/meraki.md)
- [Cisco NSO](./integrations/nso.md)
- [Palo Alto Panorama](./integrations/panorama.md)
30 changes: 30 additions & 0 deletions docs/user/integrations/nso.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Cisco NSO Chat Commands

## `/nso` Command

Interact with Cisco NSO by utilizing the following sub-commands:

| Command | Arguments | Description |
| ----------------- | ---------------------------------- | --------------------------------------|
| `ping` | `[device-name]` | Ping a device. |
| `connect` | `[device-name]` | Check device connection with NSO. |
| `check-sync` | `[device-name]` `[compare-config]` | Check sync between current device config and stored in NSO. |
| `run-command-set` | `[device-name]` `[commands]` | Run predefined set of commands on a device. |

!!! note
All sub-commands are intended to be used with the `/nso` prefix.

## Screenshots

![Commands list](../../images/nso-01.png)

![Ping command](../../images/nso-02.png)

![Check-sync command](../../images/nso-03.png)

![Check-sync command, compare config](../../images/nso-04.png)

![Run remote commands](../../images/nso-05.png)

![Run remote commands result](../../images/nso-06.png)

2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ nav:
- "user/integrations/ipfabric.md"
- "user/integrations/meraki.md"
- "user/integrations/panorama.md"
- "user/integrations/nso.md"
- Administrator Guide:
- Install and Configure: "admin/install.md"
- Platforms:
Expand All @@ -130,6 +131,7 @@ nav:
- "admin/integrations/ipfabric.md"
- "admin/integrations/meraki.md"
- "admin/integrations/panorama.md"
- "admin/integrations/nso.md"
- Upgrade: "admin/upgrade.md"
- Uninstall: "admin/uninstall.md"
- Compatibility Matrix: "admin/compatibility_matrix.md"
Expand Down
8 changes: 7 additions & 1 deletion nautobot_chatops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class NautobotChatOpsConfig(NautobotAppConfig):
"grafana_default_timespan": "",
"grafana_org_id": 1,
"grafana_default_tz": "",
# - IPFabric ---------------------
# - IPFabric -------------------------
"ipfabric_api_token": "",
"ipfabric_host": "",
"ipfabric_timeout": "",
Expand All @@ -116,6 +116,11 @@ class NautobotChatOpsConfig(NautobotAppConfig):
"panorama_host": "",
"panorama_password": "",
"panorama_user": "",
# - Cisco NSO ------------------------
"nso_url": "",
"nso_username": "",
"nso_password": "",
"nso_request_timeout": "",
}
constance_config = {
"fallback_chatops_user": ConstanceConfigItem(default="chatbot", help_text="Enable Mattermost Chat Platform."),
Expand All @@ -142,6 +147,7 @@ class NautobotChatOpsConfig(NautobotAppConfig):
"enable_panorama": ConstanceConfigItem(
default=False, help_text="Enable Panorama Integration.", field_type=bool
),
"enable_nso": ConstanceConfigItem(default=False, help_text="Enable NSO Integration.", field_type=bool),
}

caching_config = {}
Expand Down
1 change: 1 addition & 0 deletions nautobot_chatops/integrations/nso/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Nautobot ChatOps NSO Integration."""
17 changes: 17 additions & 0 deletions nautobot_chatops/integrations/nso/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Custom Exceptions for the nautobot_chatops.integrations.nso plugin."""


class CommunicationError(Exception):
"""Error communicating with NSO."""


class DeviceNotFound(Exception):
"""Device not found in NSO."""


class DeviceNotSupported(Exception):
"""Device not supported in NSO."""


class DeviceLocked(Exception):
"""Device not reachable in NSO."""
14 changes: 14 additions & 0 deletions nautobot_chatops/integrations/nso/jinja_filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Custom filters for nautobot_chatops.integrations.nso."""
from django_jinja import library
from nautobot_chatops.integrations.nso.nso import NSOClient


@library.filter
def get_nso_sync_status(device_name):
"""Pull NSO sync status for specified device."""
nso = NSOClient()
try:
response = nso.sync_status(device_name)
return response
except Exception: # pylint: disable=W0703
return "N/A"
Loading