Skip to content

Commit

Permalink
bring back SimpleInventory to nornir3.0.0 (#543)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbarrosop authored May 14, 2020
1 parent 255d149 commit 8b482fe
Show file tree
Hide file tree
Showing 10 changed files with 595 additions and 0 deletions.
3 changes: 3 additions & 0 deletions nornir/plugins/inventory/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .simple import SimpleInventory

__all__ = ("SimpleInventory",)
122 changes: 122 additions & 0 deletions nornir/plugins/inventory/simple.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import logging
import pathlib
from typing import Any, Dict, Type

from nornir.core.inventory import (
Inventory,
Group,
Groups,
Host,
Hosts,
Defaults,
ConnectionOptions,
HostOrGroup,
ParentGroups,
)

import ruamel.yaml

logger = logging.getLogger(__name__)


def _get_connection_options(data: Dict[str, Any]) -> Dict[str, ConnectionOptions]:
cp = {}
for cn, c in data.items():
cp[cn] = ConnectionOptions(
hostname=c.get("hostname"),
port=c.get("port"),
username=c.get("username"),
password=c.get("password"),
platform=c.get("platform"),
extras=c.get("extras"),
)
return cp


def _get_defaults(data: Dict[str, Any]) -> Defaults:
return Defaults(
hostname=data.get("hostname"),
port=data.get("port"),
username=data.get("username"),
password=data.get("password"),
platform=data.get("platform"),
data=data.get("data"),
connection_options=_get_connection_options(data.get("connection_options", {})),
)


def _get_inventory_element(
typ: Type[HostOrGroup], data: Dict[str, Any], name: str, defaults: Defaults
) -> HostOrGroup:
return typ(
name=name,
hostname=data.get("hostname"),
port=data.get("port"),
username=data.get("username"),
password=data.get("password"),
platform=data.get("platform"),
data=data.get("data"),
groups=data.get(
"groups"
), # this is a hack, we will convert it later to the correct type
defaults=defaults,
connection_options=_get_connection_options(data.get("connection_options", {})),
)


class SimpleInventory:
def __init__(
self,
host_file: str = "hosts.yaml",
group_file: str = "groups.yaml",
defaults_file: str = "defaults.yaml",
) -> None:
"""
SimpleInventory is an inventory plugin that loads data from YAML files.
The YAML files follow the same structure as the native objects
Args:
host_file: path to file with hosts definition
group_file: path to file with groups definition. If
it doesn't exist it will be skipped
defaults_file: path to file with defaults definition.
If it doesn't exist it will be skipped
"""

self.host_file = pathlib.Path(host_file)
self.group_file = pathlib.Path(group_file)
self.defaults_file = pathlib.Path(defaults_file)

def load(self) -> Inventory:
yml = ruamel.yaml.YAML(typ="safe")

if self.defaults_file.exists():
with open(self.defaults_file, "r") as f:
defaults_dict = yml.load(f)
defaults = _get_defaults(defaults_dict)
else:
defaults = Defaults()

hosts = Hosts()
with open(self.host_file, "r") as f:
hosts_dict = yml.load(f)

for n, h in hosts_dict.items():
hosts[n] = _get_inventory_element(Host, h, n, defaults)

groups = Groups()
if self.group_file.exists():
with open(self.group_file, "r") as f:
groups_dict = yml.load(f)

for n, g in groups_dict.items():
groups[n] = _get_inventory_element(Group, g, n, defaults)

for h in hosts.values():
h.groups = ParentGroups([groups[g] for g in h.groups])

for g in groups.values():
g.groups = ParentGroups([groups[g] for g in g.groups])

return Inventory(hosts=hosts, groups=groups, defaults=defaults)
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ build-backend = "poetry.masonry.api"
"serial" = "nornir.plugins.runners:SerialRunner"
"threaded" = "nornir.plugins.runners:ThreadedRunner"

[tool.poetry.plugins."nornir.plugins.inventory"]
"SimpleInventory" = "nornir.plugins.inventory.simple:SimpleInventory"

[tool.poetry]
name = "nornir"
version = "3.0.0a3"
Expand Down
22 changes: 22 additions & 0 deletions tests/core/test_registered_plugins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from nornir.core.plugins.inventory import InventoryPluginRegister
from nornir.core.plugins.runners import RunnersPluginRegister

from nornir.plugins.inventory import SimpleInventory
from nornir.plugins.runners import SerialRunner, ThreadedRunner


class Test:
def test_registered_runners(self):
RunnersPluginRegister.deregister_all()
RunnersPluginRegister.auto_register()
assert RunnersPluginRegister.available == {
"threaded": ThreadedRunner,
"serial": SerialRunner,
}

def test_registered_inventory(self):
InventoryPluginRegister.deregister_all()
InventoryPluginRegister.auto_register()
assert InventoryPluginRegister.available == {
"SimpleInventory": SimpleInventory,
}
Empty file.
18 changes: 18 additions & 0 deletions tests/plugins/inventory/data/defaults.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
port:
hostname:
username: root
password: docker
platform: linux
data:
my_var: comes_from_defaults
only_default: only_defined_in_default
connection_options:
dummy:
hostname: dummy_from_defaults
port:
username:
password:
platform:
extras:
blah: from_defaults
60 changes: 60 additions & 0 deletions tests/plugins/inventory/data/groups.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
parent_group:
port:
hostname:
username:
password: from_parent_group
platform:
data:
a_var: blah
a_false_var: false
groups: []
connection_options:
dummy:
hostname: dummy_from_parent_group
port:
username:
password:
platform:
extras:
blah: from_group
dummy2:
hostname: dummy2_from_parent_group
port:
username:
password:
platform:
extras:
blah: from_group
group_1:
port:
hostname:
username:
password: from_group1
platform:
data:
my_var: comes_from_group_1
site: site1
groups:
- parent_group
connection_options: {}
group_2:
port:
hostname:
username:
password:
platform:
data:
site: site2
groups: []
connection_options: {}
group_3:
port:
hostname:
username:
password:
platform:
groups: []
data:
site: site2
connection_options: {}
121 changes: 121 additions & 0 deletions tests/plugins/inventory/data/hosts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
dev1.group_1:
port: 65020
hostname: localhost
username:
password: a_password
platform: eos
data:
my_var: comes_from_dev1.group_1
www_server: nginx
role: www
nested_data:
a_dict:
a: 1
b: 2
a_list: [1, 2]
a_string: asdasd
groups:
- group_1
connection_options:
paramiko:
port: 65020
hostname:
username: root
password: docker
platform: linux
extras: {}
dummy:
hostname: dummy_from_host
port:
username:
password:
platform:
extras:
blah: from_host
dev2.group_1:
port: 65021
hostname: localhost
username:
password:
platform: junos
data:
role: db
nested_data:
a_dict:
b: 2
c: 3
a_list: [2, 3]
a_string: qwe
groups:
- group_1
connection_options:
paramiko:
port:
hostname:
username: root
password: docker
platform: linux
extras: {}
dummy2:
hostname:
port:
username: dummy2_from_host
password:
platform:
extras:
dev3.group_2:
port: 65022
hostname: localhost
username:
password:
platform: linux
data:
www_server: apache
role: www
groups:
- group_2
connection_options:
nornir_napalm.napalm:
platform: mock
hostname:
port:
username:
password:
extras: {}
dev4.group_2:
port: 65023
hostname: localhost
username:
password:
platform: linux
data:
my_var: comes_from_dev4.group_2
role: db
groups:
- parent_group
- group_2
connection_options:
paramiko:
port:
hostname: localhost
username: root
password: docker
platform: linux
extras: {}
netmiko:
port:
hostname: localhost
username: root
password: docker
platform: linux
extras: {}
dev5.no_group:
port: 65024
hostname: localhost
username:
password:
platform: linux
data: {}
groups: []
connection_options: {}
13 changes: 13 additions & 0 deletions tests/plugins/inventory/data/netconf_hosts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
netconf1.no_group:
hostname: localhost
username: netconf
password: netconf
port: 65025
connection_options:
netconf:
extras:
allow_agent: False
hostkey_verify: False
look_for_keys: False
ssh_config: null
Loading

0 comments on commit 8b482fe

Please sign in to comment.