Skip to content

Commit fa8e54b

Browse files
Inventory: add group_by options for cluster, cluster_type, and cluster_group (#188) (#191)
1 parent 414280c commit fa8e54b

File tree

10 files changed

+244
-34
lines changed

10 files changed

+244
-34
lines changed

hacking/update_test_inventories.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ set -e
1313
export ANSIBLE_COLLECTIONS_PATHS=.
1414
export OUTPUT_INVENTORY_JSON=tests/integration/targets/inventory/files
1515

16+
# Remove local cache
17+
rm -rf /tmp/inventory_netbox/
18+
1619
# Clean and install the built collection
1720
./hacking/local-test.sh
1821

plugins/inventory/nb_inventory.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@
8989
- platforms
9090
- platform
9191
- region
92+
- cluster
93+
- cluster_type
94+
- cluster_group
9295
default: []
9396
group_names_raw:
9497
description: Will not add the group_by choice name to the group names
@@ -497,6 +500,9 @@ def group_extractors(self):
497500
"interfaces": self.extract_interfaces,
498501
"custom_fields": self.extract_custom_fields,
499502
"region": self.extract_regions,
503+
"cluster": self.extract_cluster,
504+
"cluster_group": self.extract_cluster_group,
505+
"cluster_type": self.extract_cluster_type,
500506
}
501507
else:
502508
return {
@@ -516,6 +522,9 @@ def group_extractors(self):
516522
"interfaces": self.extract_interfaces,
517523
"custom_fields": self.extract_custom_fields,
518524
"region": self.extract_regions,
525+
"cluster": self.extract_cluster,
526+
"cluster_group": self.extract_cluster_group,
527+
"cluster_type": self.extract_cluster_type,
519528
}
520529

521530
def _pluralize(self, extracted_value):
@@ -719,6 +728,25 @@ def extract_regions(self, host):
719728

720729
return regions
721730

731+
def extract_cluster(self, host):
732+
try:
733+
# cluster does not have a slug
734+
return host["cluster"]["name"]
735+
except Exception:
736+
return
737+
738+
def extract_cluster_group(self, host):
739+
try:
740+
return self.clusters_group_lookup[host["cluster"]["id"]]
741+
except Exception:
742+
return
743+
744+
def extract_cluster_type(self, host):
745+
try:
746+
return self.clusters_type_lookup[host["cluster"]["id"]]
747+
except Exception:
748+
return
749+
722750
def refresh_platforms_lookup(self):
723751
url = self.api_endpoint + "/api/dcim/platforms/?limit=0"
724752
platforms = self.get_resource_list(api_url=url)
@@ -791,6 +819,32 @@ def refresh_manufacturers_lookup(self):
791819
(manufacturer["id"], manufacturer["slug"]) for manufacturer in manufacturers
792820
)
793821

822+
def refresh_clusters_lookup(self):
823+
url = self.api_endpoint + "/api/virtualization/clusters/?limit=0"
824+
clusters = self.get_resource_list(api_url=url)
825+
826+
def get_cluster_type(cluster):
827+
# Will fail if cluster does not have a type (required property so should always be true)
828+
try:
829+
return (cluster["id"], cluster["type"]["slug"])
830+
except Exception:
831+
return (cluster["id"], None)
832+
833+
def get_cluster_group(cluster):
834+
# Will fail if cluster does not have a group (group is optional)
835+
try:
836+
return (cluster["id"], cluster["group"]["slug"])
837+
except Exception:
838+
return (cluster["id"], None)
839+
840+
self.clusters_type_lookup = dict(
841+
filter(lambda x: x is not None, map(get_cluster_type, clusters))
842+
)
843+
844+
self.clusters_group_lookup = dict(
845+
filter(lambda x: x is not None, map(get_cluster_group, clusters))
846+
)
847+
794848
@property
795849
def lookup_processes(self):
796850
return [
@@ -802,6 +856,7 @@ def lookup_processes(self):
802856
self.refresh_platforms_lookup,
803857
self.refresh_device_types_lookup,
804858
self.refresh_manufacturers_lookup,
859+
self.refresh_clusters_lookup,
805860
]
806861

807862
def refresh_lookups(self):

tests/integration/netbox-deploy.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@
247247
## Create Cluster Group
248248
cluster_groups = [{"name": "Test Cluster Group", "slug": "test-cluster-group"}]
249249
created_cluster_groups = nb.virtualization.cluster_groups.create(cluster_groups)
250+
test_cluster_group = nb.virtualization.cluster_groups.get(slug="test-cluster-group")
250251

251252
## Create Cluster Type
252253
cluster_types = [{"name": "Test Cluster Type", "slug": "test-cluster-type"}]
@@ -255,18 +256,25 @@
255256

256257
## Create Cluster
257258
clusters = [
258-
{"name": "Test Cluster", "type": test_cluster_type.id, "site": test_site.id}
259+
{
260+
"name": "Test Cluster",
261+
"type": test_cluster_type.id,
262+
"group": test_cluster_group.id,
263+
"site": test_site.id,
264+
},
265+
{"name": "Test Cluster 2", "type": test_cluster_type.id,},
259266
]
260267
created_clusters = nb.virtualization.clusters.create(clusters)
261268
test_cluster = nb.virtualization.clusters.get(name="Test Cluster")
269+
test_cluster2 = nb.virtualization.clusters.get(name="Test Cluster 2")
262270

263271
## Create Virtual Machine
264272
virtual_machines = [
265273
{"name": "test100-vm", "cluster": test_cluster.id},
266274
{"name": "test101-vm", "cluster": test_cluster.id},
267275
{"name": "test102-vm", "cluster": test_cluster.id},
268276
{"name": "test103-vm", "cluster": test_cluster.id},
269-
{"name": "test104-vm", "cluster": test_cluster.id},
277+
{"name": "test104-vm", "cluster": test_cluster2.id},
270278
]
271279
created_virtual_machines = nb.virtualization.virtual_machines.create(virtual_machines)
272280
test100_vm = nb.virtualization.virtual_machines.get(name="test100-vm")

tests/integration/targets/inventory/files/test-inventory-legacy.json

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@
105105
"tags": []
106106
},
107107
"test100-vm": {
108+
"cluster": "Test Cluster",
109+
"cluster_group": "test-cluster-group",
110+
"cluster_type": "test-cluster-type",
108111
"custom_fields": {},
109112
"regions": [
110113
"test-region",
@@ -116,6 +119,9 @@
116119
"tags": []
117120
},
118121
"test101-vm": {
122+
"cluster": "Test Cluster",
123+
"cluster_group": "test-cluster-group",
124+
"cluster_type": "test-cluster-type",
119125
"custom_fields": {},
120126
"regions": [
121127
"test-region",
@@ -127,6 +133,9 @@
127133
"tags": []
128134
},
129135
"test102-vm": {
136+
"cluster": "Test Cluster",
137+
"cluster_group": "test-cluster-group",
138+
"cluster_type": "test-cluster-type",
130139
"custom_fields": {},
131140
"regions": [
132141
"test-region",
@@ -138,6 +147,9 @@
138147
"tags": []
139148
},
140149
"test103-vm": {
150+
"cluster": "Test Cluster",
151+
"cluster_group": "test-cluster-group",
152+
"cluster_type": "test-cluster-type",
141153
"custom_fields": {},
142154
"regions": [
143155
"test-region",
@@ -149,14 +161,10 @@
149161
"tags": []
150162
},
151163
"test104-vm": {
164+
"cluster": "Test Cluster 2",
165+
"cluster_type": "test-cluster-type",
152166
"custom_fields": {},
153-
"regions": [
154-
"test-region",
155-
"parent-region"
156-
],
157-
"sites": [
158-
"test-site"
159-
],
167+
"regions": [],
160168
"tags": []
161169
}
162170
}

tests/integration/targets/inventory/files/test-inventory-options.json

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
{
2+
"Test_Cluster": {
3+
"hosts": [
4+
"test100-vm",
5+
"test101-vm",
6+
"test102-vm",
7+
"test103-vm"
8+
]
9+
},
10+
"Test_Cluster_2": {
11+
"hosts": [
12+
"test104-vm"
13+
]
14+
},
215
"Test_Rack": {
316
"hosts": [
417
"R1-Device"
@@ -71,6 +84,9 @@
7184
"tags": []
7285
},
7386
"test100-vm": {
87+
"cluster": "Test Cluster",
88+
"cluster_group": "test-cluster-group",
89+
"cluster_type": "test-cluster-type",
7490
"custom_fields": {},
7591
"regions": [
7692
"test-region",
@@ -80,6 +96,9 @@
8096
"tags": []
8197
},
8298
"test101-vm": {
99+
"cluster": "Test Cluster",
100+
"cluster_group": "test-cluster-group",
101+
"cluster_type": "test-cluster-type",
83102
"custom_fields": {},
84103
"regions": [
85104
"test-region",
@@ -89,6 +108,9 @@
89108
"tags": []
90109
},
91110
"test102-vm": {
111+
"cluster": "Test Cluster",
112+
"cluster_group": "test-cluster-group",
113+
"cluster_type": "test-cluster-type",
92114
"custom_fields": {},
93115
"regions": [
94116
"test-region",
@@ -98,6 +120,9 @@
98120
"tags": []
99121
},
100122
"test103-vm": {
123+
"cluster": "Test Cluster",
124+
"cluster_group": "test-cluster-group",
125+
"cluster_type": "test-cluster-type",
101126
"custom_fields": {},
102127
"regions": [
103128
"test-region",
@@ -107,18 +132,18 @@
107132
"tags": []
108133
},
109134
"test104-vm": {
135+
"cluster": "Test Cluster 2",
136+
"cluster_type": "test-cluster-type",
110137
"custom_fields": {},
111-
"regions": [
112-
"test-region",
113-
"parent-region"
114-
],
115-
"site": "test-site",
138+
"regions": [],
116139
"tags": []
117140
}
118141
}
119142
},
120143
"all": {
121144
"children": [
145+
"Test_Cluster",
146+
"Test_Cluster_2",
122147
"Test_Rack",
123148
"cisco",
124149
"cisco_test",
@@ -128,6 +153,8 @@
128153
"nexus_parent",
129154
"other_region",
130155
"parent_region",
156+
"test_cluster_group",
157+
"test_cluster_type",
131158
"test_site2",
132159
"ungrouped"
133160
]
@@ -179,6 +206,23 @@
179206
"test_region"
180207
]
181208
},
209+
"test_cluster_group": {
210+
"hosts": [
211+
"test100-vm",
212+
"test101-vm",
213+
"test102-vm",
214+
"test103-vm"
215+
]
216+
},
217+
"test_cluster_type": {
218+
"hosts": [
219+
"test100-vm",
220+
"test101-vm",
221+
"test102-vm",
222+
"test103-vm",
223+
"test104-vm"
224+
]
225+
},
182226
"test_region": {
183227
"children": [
184228
"test_site"
@@ -193,8 +237,7 @@
193237
"test100-vm",
194238
"test101-vm",
195239
"test102-vm",
196-
"test103-vm",
197-
"test104-vm"
240+
"test103-vm"
198241
]
199242
},
200243
"test_site2": {

tests/integration/targets/inventory/files/test-inventory-options.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ group_by:
2626
- manufacturer
2727
- platform
2828
- region
29+
- cluster
30+
- cluster_group
31+
- cluster_type
2932

3033
query_filters:
3134

0 commit comments

Comments
 (0)