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

Add ability to add groups to Inventory Element & Hosts at runtime. #590

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9b1687d
added ability to dynamically add group to hots
kpeterson-sf Sep 22, 2020
a623e1f
remove uneeded refresh
kpeterson-sf Sep 22, 2020
9df9d2d
fixed some linting
kpeterson-sf Sep 22, 2020
dd32bce
fix black formatting issue
kpeterson-sf Sep 22, 2020
c9c1ee7
override the ParentGroup remove
kpeterson-sf Sep 22, 2020
af4e89d
fix deleted host in test
kpeterson-sf Sep 22, 2020
3d2fa93
Merge pull request #1 from kpeterson-sf/feature/dynamic_group
kpeterson-sf Sep 22, 2020
d41aa39
update some PR review changes
kpeterson-sf Oct 5, 2020
7cfbd09
fix some linting
kpeterson-sf Oct 5, 2020
944b02c
added ability to dynamically add group to hots
kpeterson-sf Sep 22, 2020
3671a57
remove uneeded refresh
kpeterson-sf Sep 22, 2020
3e0f1b6
fixed some linting
kpeterson-sf Sep 22, 2020
3c13650
fix black formatting issue
kpeterson-sf Sep 22, 2020
e592df5
override the ParentGroup remove
kpeterson-sf Sep 22, 2020
07bd215
fix deleted host in test
kpeterson-sf Sep 22, 2020
eeabbec
rebased
kpeterson-sf Oct 5, 2020
e36eefd
Merge branch 'develop' into develop
kpeterson-sf Oct 5, 2020
4d033cc
Merge branch 'develop' into feature/dynamic_group
kpeterson-sf Oct 5, 2020
f06d9b0
Merge branch 'develop' of github.com:kpeterson-sf/nornir into feature…
kpeterson-sf Oct 5, 2020
e266a2f
Merge branch 'feature/dynamic_group' of github.com:kpeterson-sf/norni…
kpeterson-sf Oct 5, 2020
2ed49bd
linting
kpeterson-sf Oct 5, 2020
d8e70fc
Merge pull request #2 from kpeterson-sf/feature/dynamic_group
kpeterson-sf Oct 5, 2020
5c5a9d4
removed methods
kpeterson-sf Oct 5, 2020
8db7bb0
Merge branch 'develop' into develop
dbarrosop Dec 21, 2020
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
21 changes: 21 additions & 0 deletions nornir/core/inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,27 @@ def __contains__(self, value: object) -> bool:
else:
return any([value == g for g in self])

def add(self, group: "Group") -> None:
kpeterson-sf marked this conversation as resolved.
Show resolved Hide resolved
"""
Add the ParentGroup. The group will only be appended
if it does not exist.

:param group: Parent Group object to add
:return: None
"""
# only add the group if it doesn't exist
if not self.__contains__(group):
self.append(group)

def remove(self, group: "Group") -> None:
"""
Remove the parent group.

:param group: Group object to remove
:return: None
"""
super().remove(group)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this means the method isn't really necessary as we get the same behaviour without it, right? Or am I missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah don't see any reason it needs to stay there.



class InventoryElement(BaseAttributes):
__slots__ = ("groups", "data", "connection_options")
Expand Down
47 changes: 47 additions & 0 deletions tests/core/test_inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,3 +530,50 @@ def test_get_hosts_dict(self, inv):
assert "group_1" in dev1_groups
assert dev2_paramiko_opts["username"] == "root"
assert "dev3.group_2" in hosts_dict

def test_add_group_to_host_runtime(self):
orig_data = {"var1": "val1"}
data = {"var3": "val3"}
g1 = inventory.Group(name="g1", data=orig_data)
g2 = inventory.Group(name="g2", groups=inventory.ParentGroups([g1]))
g3 = inventory.Group(name="g3", groups=inventory.ParentGroups([g2]), data=data)
h1 = inventory.Host(name="h1", groups=inventory.ParentGroups([g1, g2]))
h2 = inventory.Host(name="h2")
hosts = {"h1": h1, "h2": h2}
groups = {"g1": g1, "g2": g2}
inv = inventory.Inventory(hosts=hosts, groups=groups)

assert "h1" in inv.hosts
assert g3 not in inv.hosts["h1"].groups
assert h1.get("var3", None) is None

h1.groups.add(g3)
assert g3 in h1.groups
assert h1.get("var3", None) == "val3"

def test_remove_group_from_host(self):
data = {"var3": "val3"}
orig_data = {"var1": "val1"}
g1 = inventory.Group(name="g1", data=orig_data)
g2 = inventory.Group(name="g2", groups=inventory.ParentGroups([g1]))
g3 = inventory.Group(name="g3", groups=inventory.ParentGroups([g2]), data=data)
h1 = inventory.Host(name="h1", groups=inventory.ParentGroups([g1, g2, g3]))
h2 = inventory.Host(name="h2")
hosts = {"h1": h1, "h2": h2}
groups = {"g1": g1, "g2": g2}
inv = inventory.Inventory(hosts=hosts, groups=groups)

assert "h1" in inv.hosts
assert g3 in inv.hosts["h1"].groups
assert h1.get("var3") == "val3"

g3.data["var3"] = "newval3"
assert h1.get("var3", None) == "newval3"

h1.groups.remove(g3)
assert g3 not in h1.groups
assert h1.get("var3", None) is None
assert h1.get("var1", None) == "val1"

with pytest.raises(ValueError):
h1.groups.remove(g3)