Skip to content

Commit 60bb038

Browse files
authored
Add NetBox 4.3 to CI matrix (#1417)
1 parent 41a6aaa commit 60bb038

File tree

116 files changed

+22292
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+22292
-4
lines changed

.github/workflows/main.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ jobs:
6666
strategy:
6767
fail-fast: false
6868
matrix:
69-
include:
70-
- VERSION: "v4.0"
71-
NETBOX_DOCKER_VERSION: 2.9.1
69+
include:
7270
- VERSION: "v4.1"
7371
NETBOX_DOCKER_VERSION: 3.0.1
7472
- VERSION: "v4.2"
75-
NETBOX_DOCKER_VERSION: 3.1.0
73+
NETBOX_DOCKER_VERSION: 3.2.1
74+
- VERSION: "v4.3"
75+
NETBOX_DOCKER_VERSION: 3.3.0
7676

7777
steps:
7878

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
runme_config
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# https://docs.ansible.com/ansible/devel/dev_guide/testing/sanity/integration-aliases.html
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#!/usr/bin/env python
2+
3+
# Inspired by community.aws collection script_inventory_ec2 test
4+
# https://github.com/ansible-collections/community.aws/blob/master/tests/integration/targets/script_inventory_ec2/inventory_diff.py
5+
6+
from __future__ import absolute_import, division, print_function
7+
8+
__metaclass__ = type
9+
10+
import argparse
11+
import json
12+
import sys
13+
from operator import itemgetter
14+
15+
from deepdiff import DeepDiff
16+
17+
# NetBox includes "created" and "last_updated" times on objects. These end up in the interfaces objects that are included verbatim from the NetBox API.
18+
# "url" may be different if local tests use a different host/port
19+
# Remove these from files saved in git as test data
20+
KEYS_REMOVE = frozenset(["created", "last_updated", "url"])
21+
22+
# Ignore these when performing diffs as they will be different for each test run
23+
# (Was previously keys specific to NetBox 2.6)
24+
KEYS_IGNORE = frozenset()
25+
26+
# Rack Groups became hierarchical in NetBox 2.8. Don't bother comparing against test data in NetBox 2.7
27+
KEYS_IGNORE_27 = frozenset(
28+
[
29+
"rack_groups", # host var
30+
"rack_group_parent_rack_group", # group, group_names_raw = False
31+
"parent_rack_group", # group, group_names_raw = True
32+
]
33+
)
34+
35+
36+
# Assume the object will not be recursive, as it originally came from JSON
37+
def remove_keys(obj, keys):
38+
if isinstance(obj, dict):
39+
keys_to_remove = keys.intersection(obj.keys())
40+
for key in keys_to_remove:
41+
del obj[key]
42+
43+
for key, value in obj.items():
44+
remove_keys(value, keys)
45+
46+
elif isinstance(obj, list):
47+
# Iterate over temporary copy, as we may remove items
48+
for item in obj[:]:
49+
if isinstance(item, str) and item in keys:
50+
# List contains a string that we want to remove
51+
# eg. a group name in list of groups
52+
obj.remove(item)
53+
remove_keys(item, keys)
54+
55+
56+
def sort_hostvar_arrays(obj):
57+
meta = obj.get("_meta")
58+
if not meta:
59+
return
60+
61+
hostvars = meta.get("hostvars")
62+
if not hostvars:
63+
return
64+
65+
for _, host in hostvars.items(): # pylint: disable=disallowed-name
66+
if interfaces := host.get("interfaces"):
67+
host["interfaces"] = sorted(interfaces, key=itemgetter("id"))
68+
69+
if services := host.get("services"):
70+
host["services"] = sorted(services, key=itemgetter("id"))
71+
72+
73+
def read_json(filename):
74+
with open(filename, "r", encoding="utf-8") as file:
75+
return json.loads(file.read())
76+
77+
78+
def write_json(filename, data):
79+
with open(filename, "w", encoding="utf-8") as file:
80+
json.dump(data, file, indent=4)
81+
82+
83+
def main():
84+
parser = argparse.ArgumentParser(description="Diff Ansible inventory JSON output")
85+
parser.add_argument(
86+
"filename_a",
87+
metavar="ORIGINAL.json",
88+
type=str,
89+
help="Original json to test against",
90+
)
91+
parser.add_argument(
92+
"filename_b",
93+
metavar="NEW.json",
94+
type=str,
95+
help="Newly generated json to compare against original",
96+
)
97+
parser.add_argument(
98+
"--write",
99+
action="store_true",
100+
help=(
101+
"When comparing files, various keys are removed. "
102+
"This option will not compare the files, and instead writes ORIGINAL.json to NEW.json after removing these keys. "
103+
"This is used to clean the test json files before saving to the git repo. "
104+
"For example, this removes dates. "
105+
),
106+
)
107+
parser.add_argument(
108+
"--netbox-version",
109+
metavar="VERSION",
110+
type=str,
111+
help=(
112+
"Apply comparison specific to NetBox version. "
113+
"For example, rack_groups arrays will only contain a single item in v2.7, so are ignored in the comparison."
114+
),
115+
)
116+
117+
args = parser.parse_args()
118+
119+
data_a = read_json(args.filename_a)
120+
121+
if args.write:
122+
# When writing test data, only remove "remove_keys" that will change on every git commit.
123+
# This makes diffs more easily readable to ensure changes to test data look correct.
124+
remove_keys(data_a, KEYS_REMOVE)
125+
sort_hostvar_arrays(data_a)
126+
write_json(args.filename_b, data_a)
127+
128+
else:
129+
data_b = read_json(args.filename_b)
130+
131+
# Ignore keys that we don't want to diff, in addition to the ones removed that change on every commit
132+
keys = KEYS_REMOVE.union(KEYS_IGNORE)
133+
remove_keys(data_a, keys)
134+
remove_keys(data_b, keys)
135+
136+
sort_hostvar_arrays(data_a)
137+
sort_hostvar_arrays(data_b)
138+
139+
# Perform the diff
140+
result = DeepDiff(data_a, data_b, ignore_order=True)
141+
142+
if result:
143+
# Dictionary is not empty - print differences
144+
print(json.dumps(result, sort_keys=True, indent=4))
145+
sys.exit(1)
146+
else:
147+
# Success, no differences
148+
sys.exit(0)
149+
150+
151+
if __name__ == "__main__":
152+
main()

0 commit comments

Comments
 (0)