Skip to content

Commit

Permalink
bump to 0.16.1, fix for salt-nornir netbox pillar and added couple fi…
Browse files Browse the repository at this point in the history
…els for retrieved connections data
  • Loading branch information
dmulyalin committed Oct 20, 2022
1 parent 684bb72 commit 454aec4
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 145 deletions.
20 changes: 16 additions & 4 deletions docker-compose.rocky.py39.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ services:
- type: bind
source: .
target: /tmp/salt_nornir/

salt-minion-nrp1:
container_name: salt-minion-nrp1
hostname: 'salt-minion-nrp1'
Expand Down Expand Up @@ -62,7 +62,11 @@ services:
- type: bind
source: .
target: /tmp/salt_nornir/

# bind TTP Templates package for development
- type: bind
source: ../TTP_templates/ttp_templates
target: /usr/local/lib/python3.9/site-packages/ttp_templates/

salt-minion-nrp2:
container_name: salt-minion-nrp2
hostname: 'salt-minion-nrp2'
Expand Down Expand Up @@ -93,7 +97,11 @@ services:
- type: bind
source: .
target: /tmp/salt_nornir/

# bind TTP Templates package for development
- type: bind
source: ../TTP_templates/ttp_templates
target: /usr/local/lib/python3.9/site-packages/ttp_templates/

salt-minion-nrp3:
container_name: salt-minion-nrp3
hostname: 'salt-minion-nrp3'
Expand Down Expand Up @@ -124,7 +132,11 @@ services:
- type: bind
source: .
target: /tmp/salt_nornir/

# bind TTP Templates package for development
- type: bind
source: ../TTP_templates/ttp_templates
target: /usr/local/lib/python3.9/site-packages/ttp_templates/

ceos1:
container_name: ceos1
hostname: 'ceos1'
Expand Down
280 changes: 145 additions & 135 deletions poetry.lock

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "salt_nornir"
version = "0.16.0"
version = "0.16.1"
description = "Salt-Nornir Proxy Minion SaltStack Modules"
authors = ["Denis Mulyalin <[email protected]>"]
maintainers = ["Denis Mulyalin <[email protected]>"]
Expand Down Expand Up @@ -180,6 +180,9 @@ dataprocessor = [
"xmltodict",
"lxml"
]
netbox = [
"pynetbox"
]

[tool.poetry.plugins."salt.loader"]
"module_dirs" = "salt_nornir.loader:module_dirs"
Expand Down
30 changes: 26 additions & 4 deletions salt_nornir/modules/nornir_proxy_execution_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,7 @@ def task(task):
model_exec_nr_do_action,
model_exec_nr_snmp,
)
from salt_nornir.netbox_utils import netbox_tasks

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -2637,8 +2638,8 @@ def nornir_fun(fun, *args, **kwargs):
* ``kill`` - executes immediate shutdown of Nornir Proxy Minion process and child processes
* ``shutdown`` - gracefully shutdowns Nornir Proxy Minion process and child processes
* ``inventory`` - interact with Nornir Process inventory data, using ``InventoryFun`` function,
by default, for ``read_host, read, read_inventory, list_hosts`` operations any Nornir worker
can respond, for other, non-read operations targets all Nornir workers
by default, for ``read_host, read, read_inventory, list_hosts, list_hosts_platforms`` operations any
Nornir worker can respond, for other, non-read operations targets all Nornir workers
* ``stats`` - returns statistics about Nornir proxy process, accepts ``stat`` argument of stat
name to return
* ``version`` - returns a report of Nornir related packages installed versions
Expand Down Expand Up @@ -2696,7 +2697,13 @@ def nornir_fun(fun, *args, **kwargs):
if fun == "inventory":
kwargs.setdefault("call", args[0] if args else "read_inventory")
# make sure by default targets all workers for non read operations
if kwargs["call"] not in ["read_host", "read", "read_inventory", "list_hosts"]:
if kwargs["call"] not in [
"read_host",
"read",
"read_inventory",
"list_hosts",
"list_hosts_platforms",
]:
kwargs.setdefault("worker", "all")
return task(plugin="inventory", **kwargs)
elif fun == "stats":
Expand Down Expand Up @@ -3024,7 +3031,22 @@ def netbox(*args, **kwargs):
salt nrp1 nr.netbox sync_from FB="ceos1"
salt nrp1 nr.netbox task="sync_to" FB="ceos1" via=prod
"""
kwargs["task_name"] = args[0] if args else kwargs.pop("task")
task_name = args[0] if args else kwargs.pop("task")
kwargs["task_name"] = task_name
if task_name in netbox_tasks:
ret = []
# get a list of tasks to execute
tasks_list = netbox_tasks[task_name]["tasks"](
hosts=nornir_fun("inventory", "list_hosts_platforms")
)
# execute tasks to retrieve data from hosts
for task_data in tasks_list:
ret.append(
globals()[task_data["fun"]](
*task_data.get("args", []), **task_data.get("kwargs", {})
)
)
return ret
return __proxy__["nornir.execute_job"](
task_fun="nornir_salt.plugins.tasks.netbox_tasks",
kwargs=kwargs,
Expand Down
74 changes: 74 additions & 0 deletions salt_nornir/netbox_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""
Netbox Utils
============
Collection of functions for Salt-Nornir to interact with Netbox.
"""
import logging
import json
import requests

log = logging.getLogger(__name__)

try:
import pynetbox

HAS_PYNETBOX = True
except ImportError:
HAS_PYNETBOX = False


def get_load_config_tasks(hosts: dict):
"""
Function to produce a list of tasks to collect output from devices
for load_config function.
:param data: dictionary with Nornir Inventory data of hosts to produce tasks for
"""
ret = []
platforms_added = set()
for host_name, platform in hosts.items():
task_kwargs = {}
if platform in platforms_added:
continue
elif platform in ["cisco_xr", "iosxr"]:
template = "ttp://misc/Netbox/parse_cisco_xr_config.txt"
elif platform in ["juniper_junos", "junos", "juniper"]:
template = "ttp://misc/Netbox/parse_juniper_junos_config.txt"
elif platform in ["arista_eos", "eos"]:
template = "ttp://misc/Netbox/parse_arista_eos_config.txt"
task_kwargs["enable"] = True
else:
log.info(
f"netbox_utils:get_load_config_tasks unsupported "
f"platform '{platform}', host name '{host_name}'"
)
continue
ret.append(
{
"fun": "cli",
"kwargs": {
**task_kwargs,
"FL": [h for h, p in hosts.items() if p == platform],
"run_ttp": template,
"ttp_structure": "dictionary",
},
}
)
platforms_added.add(platform)

return ret


def load_config(data: dict):
"""
Function to parse devices confgiuration and load it into Netbox device
confguration context.
"""
pass


# dispatch dictionary of Netbox tasks exposed for calling
netbox_tasks = {"load_config": {"fun": load_config, "tasks": get_load_config_tasks}}
7 changes: 6 additions & 1 deletion salt_nornir/pillar/salt_nornir_netbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,7 @@ def _host_add_interfaces(device, host, params):
intf_dict[intf.pop("name")] = intf
# save data into Nornir host's inventory
dk = host_add_interfaces if isinstance(host_add_interfaces, str) else "interfaces"
host.setdefault("data", {})
host["data"][dk] = intf_dict


Expand Down Expand Up @@ -1016,6 +1017,7 @@ def _host_add_connections(device, host, params):
cables_dict = {}
while cables:
cable = cables.pop()
# extract CableTerminationType items
terminations = cable.pop("terminations")
local_interface_index = None
# map interface ID to interface data
Expand All @@ -1037,20 +1039,23 @@ def _host_add_connections(device, host, params):
f"salt_nornir_netbox '{device['name']}' device, failed to find local "
f"interface for connection '{cable}', terminations '{terminations}'"
)

# extract interface termiantion
local_interface = terminations.pop(local_interface_index)
remote_interface = terminations.pop()

cables_dict[local_interface["interface"]["name"]] = {
**cable,
"remote_device": remote_interface["_device"]["name"],
"remote_interface": remote_interface["interface"]["name"],
"termination_type": local_interface["termination_type"]["model"],
"remote_termination_type": remote_interface["termination_type"]["model"],
}

# save data into Nornir host's inventory
dk = (
host_add_connections if isinstance(host_add_connections, str) else "connections"
)
host.setdefault("data", {})
host["data"][dk] = cables_dict


Expand Down
1 change: 1 addition & 0 deletions test/ceos1.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ username nornir privilege 15 secret sha512 $6$EkriX8oB5g3Midq4$ErOpqzIWT7FxiW1Ik
interface Ethernet1
no switchport
ip address 10.0.1.4/24
mtu 9200
!
interface Loopback1
ip address 1.1.1.1/24
Expand Down
1 change: 1 addition & 0 deletions test/ceos2.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ username nornir privilege 15 secret sha512 $6$EkriX8oB5g3Midq4$ErOpqzIWT7FxiW1Ik
interface Ethernet1
no switchport
ip address 10.0.1.5/24
mtu 9200
!
interface Loopback100
description MGMT Range xYz
Expand Down

0 comments on commit 454aec4

Please sign in to comment.