[python]Dynamic hosts data, using Nornir framework

Introduction

There are many examples that hardcoded username and password into the yaml file, and use InitNornir, best practice and example should not show hardcoded credentials, always use a vault or a database that centrally stores username and password securely, one particular credential storage I am using is Hashicorp vault.

In my opinion, best practice should be observed from the start and not for the sake of simplicity to just show the credentials, storing and retrieval of credentials are tedious but not difficult, if it is difficult then you should do a few times until it becomes a habit.

I am using get_kv2_secret from my own written package – pyvault2 to obtain the stored credential.

Below is the json data stored within the vault.
hv1

How to transform hosts.yaml

I am writing this based on the documentation of Nornir.
I have a yaml file saved in templates subdirectory which looks like this:

---
fw01:
  hostname: ipaddress
  username: username
  password: password
  platform: platform

the ipaddress, username, password, platform are placeholders.

A function to adapt the new configuration has to be created which looks like this:

def change_host_data(host):
    host.username = credential_from_vault["username"]
    host.password = credential_from_vault["password"]
    host.hostname = credential_from_vault["ip"]
    host.platform = "cisco_asa"

To change the values of these keys – username, password, hostname and platform – the code looks like this:

nr = InitNornir(
    inventory={
        "plugin": "nornir.plugins.inventory.simple.SimpleInventory",
        "options": {
            "host_file": "templates/hosts.yaml"
        },
        "transform_function": change_host_data
    }
)

transform_function key takes in the reference of the function change_host_data.
The host_file contains the template path.

The entire code

The entire code:

from nornir import InitNornir
from nornir.plugins.tasks.networking import netmiko_send_command
from nornir.plugins.functions.text import print_result
from pyvault2.vault.hvault2 import get_kv2_secret

"""
The credential_from_vault function can be found here:
https://github.com/sirbowen78/pyvault2/blob/master/vault/hvault2.py
"""
credential_from_vault = get_kv2_secret(mount_path="cisco_asa", path="fw01", find="data")

"""
Reference:
https://nornir.readthedocs.io/en/stable/howto/transforming_inventory_data.html
"""


def change_host_data(host):
    host.username = credential_from_vault["username"]
    host.password = credential_from_vault["password"]
    host.hostname = credential_from_vault["ip"]
    host.platform = "cisco_asa"


nr = InitNornir(
    inventory={
        "plugin": "nornir.plugins.inventory.simple.SimpleInventory",
        "options": {
            "host_file": "templates/hosts.yaml"
        },
        "transform_function": change_host_data
    }
)

cmd = "show int ip brief"
r = nr.run(task=netmiko_send_command,
           command_string=cmd)
print_result(r)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s