Skip to content

Commit b1b746c

Browse files
committed
Inventory tests: Sort interfaces and services when comparing json
Netbox 2.6 seems to return these in a different order than 2.7 and 2.8. Order shouldn't be important.
1 parent bc58f55 commit b1b746c

File tree

3 files changed

+68
-38
lines changed

3 files changed

+68
-38
lines changed

tests/integration/targets/inventory/compare_inventory_json.py

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import argparse
1313
from jsondiff import diff
1414
from typing import Iterable
15+
from operator import itemgetter
1516

1617
# Netbox includes "created" and "last_updated" times on objects. These end up in the interfaces objects that are included verbatim from the Netbox API.
1718
# "url" may be different if local tests use a different host/port
@@ -40,16 +41,42 @@ def remove_keys(obj, keys):
4041

4142

4243
def remove_specifics(obj):
43-
try:
44-
# Netbox 2.6 doesn't output "tags" for services
45-
# I don't just want to ignore the "tags" key everywhere, as it's a host var that users care about
46-
hostvars = obj["_meta"]["hostvars"]
47-
for host in hostvars:
48-
services = host["services"]
49-
for item in services:
50-
item.pop("tags", None)
51-
except Exception:
52-
pass
44+
# Netbox 2.6 doesn't output "tags" for services
45+
# I don't just want to ignore the "tags" key everywhere, as it's a host var that users care about
46+
meta = obj.get("_meta")
47+
if not meta:
48+
return
49+
50+
hostvars = meta.get("hostvars")
51+
if not hostvars:
52+
return
53+
54+
for hostname, host in hostvars.items():
55+
services = host.get("services")
56+
if not services:
57+
continue
58+
59+
for item in services:
60+
item.pop("tags", None)
61+
62+
63+
def sort_hostvar_arrays(obj):
64+
meta = obj.get("_meta")
65+
if not meta:
66+
return
67+
68+
hostvars = meta.get("hostvars")
69+
if not hostvars:
70+
return
71+
72+
for hostname, host in hostvars.items():
73+
interfaces = host.get("interfaces")
74+
if interfaces:
75+
host["interfaces"] = sorted(interfaces, key=itemgetter("id"))
76+
77+
services = host.get("services")
78+
if services:
79+
host["services"] = sorted(services, key=itemgetter("id"))
5380

5481

5582
def read_json(filename):
@@ -94,6 +121,7 @@ def main():
94121
# When writing test data, only remove "remove_keys" that will change on every git commit.
95122
# This makes diffs more easily readable to ensure changes to test data look correct.
96123
remove_keys(data_a, KEYS_REMOVE)
124+
sort_hostvar_arrays(data_a)
97125
write_json(args.filename_b, data_a)
98126

99127
else:
@@ -104,6 +132,8 @@ def main():
104132
remove_keys(data_b, KEYS_REMOVE.union(KEYS_IGNORE))
105133
remove_specifics(data_a)
106134
remove_specifics(data_b)
135+
sort_hostvar_arrays(data_a)
136+
sort_hostvar_arrays(data_b)
107137

108138
# Perform the diff
109139
# syntax='symmetric' will produce output that prints both the before and after as "$insert" and "$delete"

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

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,23 @@
4747
"count_ipaddresses": 1,
4848
"description": "",
4949
"device": {
50-
"display_name": "Test Nexus Child One",
51-
"id": 5,
52-
"name": "Test Nexus Child One"
50+
"display_name": "Test Nexus One",
51+
"id": 4,
52+
"name": "Test Nexus One"
5353
},
5454
"enabled": true,
55-
"id": 2,
55+
"id": 1,
5656
"ip_addresses": [
5757
{
58-
"address": "172.16.180.12/24",
58+
"address": "172.16.180.11/24",
5959
"custom_fields": {},
6060
"description": "",
6161
"dns_name": "",
6262
"family": {
6363
"label": "IPv4",
6464
"value": 4
6565
},
66-
"id": 4,
66+
"id": 3,
6767
"nat_inside": null,
6868
"nat_outside": null,
6969
"role": null,
@@ -82,7 +82,7 @@
8282
"mgmt_only": false,
8383
"mode": null,
8484
"mtu": null,
85-
"name": "Ethernet2/1",
85+
"name": "Ethernet1/1",
8686
"tagged_vlans": [],
8787
"tags": [],
8888
"type": {
@@ -100,23 +100,23 @@
100100
"count_ipaddresses": 1,
101101
"description": "",
102102
"device": {
103-
"display_name": "Test Nexus One",
104-
"id": 4,
105-
"name": "Test Nexus One"
103+
"display_name": "Test Nexus Child One",
104+
"id": 5,
105+
"name": "Test Nexus Child One"
106106
},
107107
"enabled": true,
108-
"id": 1,
108+
"id": 2,
109109
"ip_addresses": [
110110
{
111-
"address": "172.16.180.11/24",
111+
"address": "172.16.180.12/24",
112112
"custom_fields": {},
113113
"description": "",
114114
"dns_name": "",
115115
"family": {
116116
"label": "IPv4",
117117
"value": 4
118118
},
119-
"id": 3,
119+
"id": 4,
120120
"nat_inside": null,
121121
"nat_outside": null,
122122
"role": null,
@@ -135,7 +135,7 @@
135135
"mgmt_only": false,
136136
"mode": null,
137137
"mtu": null,
138-
"name": "Ethernet1/1",
138+
"name": "Ethernet2/1",
139139
"tagged_vlans": [],
140140
"tags": [],
141141
"type": {

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

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,23 @@
2828
"count_ipaddresses": 1,
2929
"description": "",
3030
"device": {
31-
"display_name": "Test Nexus Child One",
32-
"id": 5,
33-
"name": "Test Nexus Child One"
31+
"display_name": "Test Nexus One",
32+
"id": 4,
33+
"name": "Test Nexus One"
3434
},
3535
"enabled": true,
36-
"id": 2,
36+
"id": 1,
3737
"ip_addresses": [
3838
{
39-
"address": "172.16.180.12/24",
39+
"address": "172.16.180.11/24",
4040
"custom_fields": {},
4141
"description": "",
4242
"dns_name": "",
4343
"family": {
4444
"label": "IPv4",
4545
"value": 4
4646
},
47-
"id": 4,
47+
"id": 3,
4848
"nat_inside": null,
4949
"nat_outside": null,
5050
"role": null,
@@ -63,7 +63,7 @@
6363
"mgmt_only": false,
6464
"mode": null,
6565
"mtu": null,
66-
"name": "Ethernet2/1",
66+
"name": "Ethernet1/1",
6767
"tagged_vlans": [],
6868
"tags": [],
6969
"type": {
@@ -81,23 +81,23 @@
8181
"count_ipaddresses": 1,
8282
"description": "",
8383
"device": {
84-
"display_name": "Test Nexus One",
85-
"id": 4,
86-
"name": "Test Nexus One"
84+
"display_name": "Test Nexus Child One",
85+
"id": 5,
86+
"name": "Test Nexus Child One"
8787
},
8888
"enabled": true,
89-
"id": 1,
89+
"id": 2,
9090
"ip_addresses": [
9191
{
92-
"address": "172.16.180.11/24",
92+
"address": "172.16.180.12/24",
9393
"custom_fields": {},
9494
"description": "",
9595
"dns_name": "",
9696
"family": {
9797
"label": "IPv4",
9898
"value": 4
9999
},
100-
"id": 3,
100+
"id": 4,
101101
"nat_inside": null,
102102
"nat_outside": null,
103103
"role": null,
@@ -116,7 +116,7 @@
116116
"mgmt_only": false,
117117
"mode": null,
118118
"mtu": null,
119-
"name": "Ethernet1/1",
119+
"name": "Ethernet2/1",
120120
"tagged_vlans": [],
121121
"tags": [],
122122
"type": {

0 commit comments

Comments
 (0)