Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bring back SimpleInventory to nornir3.0.0 #543

Merged
merged 3 commits into from
May 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file should be safe to remove from the PR.

Loading