Skip to content

Commit

Permalink
Merge pull request #288 from romanukes/nso_integration
Browse files Browse the repository at this point in the history
Add NSO integration
  • Loading branch information
smk4664 authored Mar 19, 2024
2 parents c3e97da + 347a1fa commit 43bb10c
Show file tree
Hide file tree
Showing 40 changed files with 1,205 additions and 4 deletions.
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",
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

0 comments on commit 43bb10c

Please sign in to comment.