Transforming Inventory Data¶
Imagine your data looks like:
[1]:
%cat transforming_inventory_data/inventory/hosts.yaml
---
rtr00:
data:
user: automation_user
rtr01:
data:
user: automation_user
And we want to do two things:
- Map
user
tousername
- Prompt the user for the password and add it
You can easily do that using a transform_function. For instance:
Modifying hosts’ data¶
You can modify inventory data (regardless of the plugin you are using) on the fly easily by passing a transform_function
like this:
[2]:
from nornir import InitNornir
import pprint
def adapt_host_data(host):
# This function receives a Host object for manipulation
host.username = host["user"]
nr = InitNornir(
inventory={
"plugin": "nornir.plugins.inventory.simple.SimpleInventory",
"options": {
"host_file": "transforming_inventory_data/inventory/hosts.yaml",
"group_file": "transforming_inventory_data/inventory/groups.yaml",
},
"transform_function": adapt_host_data,
},
)
for name, host in nr.inventory.hosts.items():
print(f"{name}.username: {host.username}")
rtr00.username: automation_user
rtr01.username: automation_user
Specifying the transform function in the configuration¶
You can also specify the transform function in the configuration. In order for that to work the function must be importable. For instance:
[3]:
%cat transforming_inventory_data/helpers.py
def adapt_host_data(host):
# This function receives a Host object for manipulation
host.username = host["user"]
Now let’s verify we can, indeed, import the function:
[4]:
from transforming_inventory_data.helpers import adapt_host_data
adapt_host_data
[4]:
<function transforming_inventory_data.helpers.adapt_host_data(host)>
Now the only thing left to do is put the import path as the transform_function
configuration option:
[5]:
%cat transforming_inventory_data/config.yaml
---
inventory:
plugin: nornir.plugins.inventory.simple.SimpleInventory
options:
host_file: "transforming_inventory_data/inventory/hosts.yaml"
group_file: "transforming_inventory_data/inventory/groups.yaml"
transform_function: "transforming_inventory_data.helpers.adapt_host_data"
And then we won’t need to specify it when calling InitNornir
:
[6]:
from nornir import InitNornir
import pprint
nr = InitNornir(
config_file="transforming_inventory_data/config.yaml",
)
for name, host in nr.inventory.hosts.items():
print(f"{name}.username: {host.username}")
rtr00.username: automation_user
rtr01.username: automation_user
Setting a default password¶
You might be in a situation where you may want to prompt the user for some information, for instance, a password. You can leverage the defaults
for something like this (although you could just put in under the hosts themselves or the groups). Let’s see an example:
[7]:
from nornir import InitNornir
# let's pretend we used raw_input or something like that
# password = raw_input("Please, enter password: ")
password = "a_secret_password"
nr = InitNornir(
config_file="transforming_inventory_data/config.yaml",
)
print("Before setting password: ", nr.inventory.hosts["rtr00"].password)
nr.inventory.defaults.password = password
print("After setting password: ", nr.inventory.hosts["rtr00"].password)
print("After setting password: ", nr.inventory.defaults.password)
Before setting password: None
After setting password: a_secret_password
After setting password: a_secret_password
For more information on how inheritance works check the tutorial section inheritance model
Passing options to the transform function¶
You can also pass options to the transform function, like in this example:
[8]:
from nornir import InitNornir
def adapt_host_data(host, password, something_else):
host.data["password"] = password
options = {
"password": "a_secret_password",
"something_else": "unused"
}
nr = InitNornir(
inventory={
"plugin": "nornir.plugins.inventory.simple.SimpleInventory",
"options": {
"host_file": "transforming_inventory_data/inventory/hosts.yaml",
"group_file": "transforming_inventory_data/inventory/groups.yaml",
},
"transform_function": adapt_host_data,
"transform_function_options": options,
}
)
for name, host in nr.inventory.hosts.items():
print(f"{name}.password: {host.password}")
rtr00.password: None
rtr01.password: None
Using ConnectionOptions¶
ConnectionOptions
to be able to connect to your devices.The following example shows how to correctly do so in the helpers.py
:
[9]:
from nornir.core.inventory import ConnectionOptions
def adapt_host_data(host):
# This function receives a Host object for manipulation
host.username = host["user"]
host.password = host["password"]
host.connection_options["napalm"] = ConnectionOptions(
extras={
"optional_args": {
"secret":host.password
}
}
)
You can also specify them as a default
for your entire inventory in this manner:
[10]:
from nornir.core.inventory import ConnectionOptions
nr.inventory.defaults.connection_options = ConnectionOptions(extras={"optional_args":{"secret":"my_secret"}})