Skip to content

Commit

Permalink
NETCONF prototype (#416)
Browse files Browse the repository at this point in the history
* prototype

* progress

* progress
  • Loading branch information
dbarrosop committed Sep 6, 2019
1 parent 444113a commit 5b17fa6
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 5 deletions.
6 changes: 6 additions & 0 deletions docs/plugins/connections/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,9 @@ Paramiko

.. automodule:: nornir.plugins.connections.paramiko
:members:

Netconf
-------

.. automodule:: nornir.plugins.connections.netconf
:members:
2 changes: 2 additions & 0 deletions nornir/init_nornir.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
from nornir.core.deserializer.configuration import Config
from nornir.core.state import GlobalState
from nornir.plugins.connections.napalm import Napalm
from nornir.plugins.connections.netconf import Netconf
from nornir.plugins.connections.netmiko import Netmiko
from nornir.plugins.connections.paramiko import Paramiko


def register_default_connection_plugins() -> None:
Connections.register("napalm", Napalm)
Connections.register("netconf", Netconf)
Connections.register("netmiko", Netmiko)
Connections.register("paramiko", Paramiko)

Expand Down
122 changes: 122 additions & 0 deletions nornir/plugins/connections/netconf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
from typing import Any, Dict, Optional

from ncclient import manager

from nornir.core.configuration import Config
from nornir.core.connections import ConnectionPlugin


class Netconf(ConnectionPlugin):
"""
This plugin connects to the device via NETCONF using ncclient library.
Inventory:
extras: See
`here <https://ncclient.readthedocs.io/en/latest/transport.html#ncclient.transport.SSHSession.connect>`_
Example on how to configure a device to use netconfig without using an ssh agent and without verifying the keys::
---
nc_device:
hostname: 192.168.16.20
username: admin
password: admin
port: 2022
connection_options:
netconf:
extras:
allow_agent: False
hostkey_verify: False
Then it can be used like::
>>> from nornir import InitNornir
>>> from nornir.core.task import Result, Task
>>>
>>> nr = InitNornir(
>>> inventory={
>>> "options": {
>>> "hosts": {
>>> "rtr00": {
>>> "hostname": "localhost",
>>> "username": "admin",
>>> "password": "admin",
>>> "port": 65030,
>>> "platform": "whatever",
>>> "connection_options": {
>>> "netconf": {"extras": {"hostkey_verify": False}}
>>> },
>>> }
>>> }
>>> }
>>> }
>>>)
>>>
>>>
>>> def netconf_code(task: Task) -> Result:
>>> manager = task.host.get_connection("netconf", task.nornir.config)
>>>
>>> # get running config and system state
>>> print(manager.get())
>>>
>>> # get only hostname
>>> print(manager.get(filter=("xpath", "/sys:system/sys:hostname")))
>>>
>>> # get candidate config
>>> print(manager.get_config("candidate"))
>>>
>>> # lock
>>> print(manager.lock("candidate"))
>>>
>>> # edit configuration
>>> res = manager.edit_config(
>>> "candidate",
>>> "<sys:system><sys:hostname>asd</sys:hostname></sys:system>",
>>> default_operation="merge",
>>> )
>>> print(res)
>>>
>>> print(manager.commit())
>>>
>>> # unlock
>>> print(manager.unlock("candidate"))
>>>
>>> return Result(result="ok", host=task.host)
>>>
>>>
>>> nr.run(task=netconf_code)
""" # noqa

def open(
self,
hostname: Optional[str],
username: Optional[str],
password: Optional[str],
port: Optional[int],
platform: Optional[str],
extras: Optional[Dict[str, Any]] = None,
configuration: Optional[Config] = None,
) -> None:
extras = extras or {}

parameters: Dict[str, Any] = {
"host": hostname,
"username": username,
"password": password,
"port": port,
}

if "ssh_config" not in extras:
try:
parameters["ssh_config"] = configuration.ssh.config_file # type: ignore
except AttributeError:
pass

parameters.update(extras)
parameters["ssh_config"] = None

connection = manager.connect_ssh(**parameters)
self.connection = connection

def close(self) -> None:
self.connection.close_session()
10 changes: 5 additions & 5 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ jupyter = { version = "^1", optional = true }
nbsphinx = { version = "^0.4", optional = true }
pygments = { version = "^2", optional = true }
sphinx-issues = { version = "^1.2", optional = true }
junos-eznc = "^2.2"
ncclient = "^0.6.6"

[tool.poetry.dev-dependencies]
decorator = "*"
Expand Down

0 comments on commit 5b17fa6

Please sign in to comment.