I have a few Cisco routers which are on IOS, I have never used NAPALM before, I use netmiko most often for cisco devices, Napalm itself is based on netmiko, I napalm has a get_facts
method that gather the information of cisco ios router, this is very convenient as compared with netmiko, netmiko is more suitable for people who knows cisco commands.
Simple example in napalm:
from napalm import get_network_driver from getpass import getpass hostname = input("IP address of router: ") username = input(f"Username of {hostname}: ") password = getpass(f"Password of {hostname}") secret = getpass(f"Enable password of {hostname}: ") driver = get_network_driver("ios") router_info = { "hostname": hostname, "username": username, "password": password, "optional_args": { "secret": secret } } with driver(**router_info) as router: print(router.get_facts())
The result of get_facts is like this:
{'uptime': 3360, 'vendor': 'Cisco', 'os_version': 'IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.6(2)T, RELEASE SOFTWARE (fc2)', 'serial_number': '9C2EDRJ9TA7MC7I08Z312', 'model': 'IOSv', 'hostname': 'R1', 'fqdn': 'R1.cyruslab.local', 'interface_list': ['GigabitEthernet0/0', 'GigabitEthernet0/1', 'GigabitEthernet0/2', 'GigabitEthernet0/3']}
Complex code with Nornir:
from nornir import InitNornir from nornir.plugins.tasks.networking import napalm_get from nornir.plugins.functions.text import print_result from getpass import getpass from tempfile import NamedTemporaryFile import yaml from os import unlink """Get router information from user input""" host = input("Hostname of router: ") hostname = input("IP address of router: ") username = input(f"Username of {hostname}: ") password = getpass(f"Password of {hostname}: ") secret = getpass(f"Enable password of {hostname}: ") """ See hosts.yaml examples here: https://github.com/cldeluna/nornir-config/blob/master/hosts.yaml """ router_config = { host: { "hostname": hostname, "username": username, "password": password, "platform": "ios", "port": 22, "connection_options": { "napalm": { "extras": { "optional_args": { "secret": secret } } } } } } """ As this is a demo, I did not permanently save a hosts.yaml file, hence I am writing to a temporary file. delete=False is to maintain the temp file after NamedTemporaryFile is closed. NamedTemporaryFile is not only write the yaml format into temp file, also to get the temp file name, so that InitNornir's inventory can open the host_file. """ with NamedTemporaryFile(delete=False) as temp: temp.write(yaml.safe_dump(router_config).encode('utf-8')) tmp_name = temp.name with InitNornir(inventory={ "plugin": "nornir.plugins.inventory.simple.SimpleInventory", "options": { "host_file": tmp_name } }) as nr: result = nr.run(task=napalm_get, getters=["facts"]) """unlink is to delete the temp file.""" unlink(tmp_name) """Display the result in stdout""" print_result(result)
The result looks like this:
I would recommend using netmiko either directly or indirectly with Nornir as long as you are handling with Cisco IOS, or Cisco ASA, it is easier and depend lesser on the API of Napalm, Napalm itself uses netmiko, and in order to get getter["facts"]
with Nornir.napalm_get
you need to supply secret password in the yaml file, however if you are using netmiko in nornir this is not required.
For more examples on the yaml file examples look here.
Example yaml host file for two connection options of one host:
r1.cyruslab.local: hostname: 192.168.100.101 username: username password: password platform: ios port: 22 connection_options: netmiko: extras: device_type: cisco_ios connection_options: napalm: extras: optional_args: secret: secret