aabouzaid / netbox-as-ansible-inventory

Ansible dynamic inventory script for Netbox.
GNU General Public License v3.0
174 stars 54 forks source link

Add support for grouping by tags #35

Open tjdavis3 opened 6 years ago

tjdavis3 commented 6 years ago

Since netbox 2.4+ adds tags to devices it would be helpful to have the inventory group by tags. This would allow tagging of servers by application / service which could then be used in ansible. Currently adding tags to the general group_by renders an error since the value inside the device is a list.

FragmentedPacket commented 6 years ago

I'm going to look into this within the next few weeks and attempt to implement it

rthomson commented 6 years ago

It's not well tested or PR quality yet, but this small change to netbox.py implements grouping by tag:

diff --git a/netbox.py b/netbox.py
index e7fea3f..962a98a 100755
--- a/netbox.py
+++ b/netbox.py
@@ -249,6 +249,11 @@ class NetboxAsInventory(object):
                 inventory_dict.setdefault("no_group", [server_name])
             else:
                 inventory_dict["no_group"].append(server_name)
+
+        group_tags = host_data.get("tags")
+        for tag in group_tags:
+            inventory_dict = self.add_host_to_group(server_name, tag, inventory_dict)
+
         return inventory_dict

     def get_host_vars(self, host_data, host_vars):
sol1-matt commented 6 years ago

I pulled the latest version for netbox.py (095cfb162fff9eeb7fc4aadfaf015d472f2484ba) and found the same problem, unfortunalty I didn't find this issue first.

an example of the the data returned is

        "device_role": {
            "id": 6,
            "url": "http://netbox.hq.sol1.net/api/dcim/device-roles/6/",
            "name": "Firewall",
            "slug": "firewall"
        },
       "tags": ["foo", "bar"],

what netbox.py add_host_to_inventory sees

('group: ', 'device_role', ', group_value: ', u'Firewall', ', is list: ', False)
('group: ', 'tags', ', group_value: ', [u'foo', u'bar'], ', is list: ', True)

My solution is little more generic, it splits any group_values that is a list into individual groups

index 04ca2fa..34fd93f 100755
--- a/inventory/netbox.py
+++ b/inventory/netbox.py
@@ -255,7 +255,11 @@ class NetboxAsInventory(object):
                             group_value = self._get_value_by_path(data_dict, [group, key_name])

                             if group_value:
-                                inventory_dict = self.add_host_to_group(server_name, group_value, inventory_dict)
+                                if isinstance(group_value, list):
+                                       for list_group in group_value:
+                                               inventory_dict = self.add_host_to_group(server_name, list_group, inventory_dict)
+                                else:
+                                       inventory_dict = self.add_host_to_group(server_name, group_value, inventory_dict)
                             # If any groups defined in "group_by" section, but host is not part of that group, it will go to catch-all group.
                             else:
                                 self._put_host_to_ungrouped(inventory_dict, server_name)