|
51 | 51 | "interfaces",
|
52 | 52 | "interface_templates",
|
53 | 53 | "inventory_items",
|
| 54 | + "locations", |
54 | 55 | "manufacturers",
|
55 | 56 | "platforms",
|
56 | 57 | "power_feeds",
|
|
66 | 67 | "rear_port_templates",
|
67 | 68 | "regions",
|
68 | 69 | "sites",
|
| 70 | + "site_groups", |
69 | 71 | "virtual_chassis",
|
70 | 72 | ],
|
71 | 73 | extras=["tags"],
|
|
101 | 103 | group="slug",
|
102 | 104 | installed_device="name",
|
103 | 105 | import_targets="name",
|
| 106 | + location="slug", |
104 | 107 | manufacturer="slug",
|
105 | 108 | nat_inside="address",
|
106 | 109 | nat_outside="address",
|
|
125 | 128 | route_targets="name",
|
126 | 129 | slug="slug",
|
127 | 130 | site="slug",
|
| 131 | + site_group="slug", |
128 | 132 | tenant="slug",
|
129 | 133 | tenant_group="slug",
|
130 | 134 | time_zone="timezone",
|
|
166 | 170 | "interface_template": "interface_templates",
|
167 | 171 | "ip_addresses": "ip_addresses",
|
168 | 172 | "ipaddresses": "ip_addresses",
|
| 173 | + "location": "locations", |
169 | 174 | "lag": "interfaces",
|
170 | 175 | "manufacturer": "manufacturers",
|
171 | 176 | "master": "devices",
|
|
190 | 195 | "rear_port_template": "rear_port_templates",
|
191 | 196 | "rir": "rirs",
|
192 | 197 | "route_targets": "route_targets",
|
| 198 | + # Just a placeholder as scope can be several different types including sites. |
| 199 | + "scope": "sites", |
193 | 200 | "services": "services",
|
194 | 201 | "site": "sites",
|
| 202 | + "site_group": "site_groups", |
195 | 203 | "tags": "tags",
|
196 | 204 | "tagged_vlans": "vlans",
|
197 | 205 | "tenant": "tenants",
|
|
232 | 240 | "interface_templates": "interface_template",
|
233 | 241 | "inventory_items": "inventory_item",
|
234 | 242 | "ip_addresses": "ip_address",
|
| 243 | + "locations": "location", |
235 | 244 | "manufacturers": "manufacturer",
|
236 | 245 | "platforms": "platform",
|
237 | 246 | "power_feeds": "power_feed",
|
|
253 | 262 | "route_targets": "route_target",
|
254 | 263 | "services": "services",
|
255 | 264 | "sites": "site",
|
| 265 | + "site_groups": "site_group", |
256 | 266 | "tags": "tags",
|
257 | 267 | "tenants": "tenant",
|
258 | 268 | "tenant_groups": "tenant_group",
|
|
300 | 310 | "ip_addresses": set(["address", "vrf", "device", "interface", "assigned_object"]),
|
301 | 311 | "ipaddresses": set(["address", "vrf", "device", "interface", "assigned_object"]),
|
302 | 312 | "lag": set(["name"]),
|
| 313 | + "location": set(["slug"]), |
303 | 314 | "manufacturer": set(["slug"]),
|
304 | 315 | "master": set(["name"]),
|
305 | 316 | "nat_inside": set(["vrf", "address"]),
|
|
337 | 348 | "virtual_chassis": set(["name", "master"]),
|
338 | 349 | "virtual_machine": set(["name", "cluster"]),
|
339 | 350 | "vlan": set(["group", "name", "site", "tenant", "vid", "vlan_group"]),
|
340 |
| - "vlan_group": set(["slug", "site"]), |
| 351 | + "vlan_group": set(["slug", "site", "scope"]), |
341 | 352 | "vrf": set(["name", "tenant"]),
|
342 | 353 | }
|
343 | 354 |
|
|
351 | 362 | "rir",
|
352 | 363 | "vrf",
|
353 | 364 | "site",
|
| 365 | + "scope", |
354 | 366 | "tenant",
|
355 | 367 | "type",
|
356 | 368 | "virtual_machine",
|
|
390 | 402 | # This is used to map non-clashing keys to Netbox API compliant keys to prevent bad logic in code for similar keys but different modules
|
391 | 403 | CONVERT_KEYS = {
|
392 | 404 | "assigned_object": "assigned_object_id",
|
| 405 | + "scope": "scope_id", |
393 | 406 | "circuit_type": "type",
|
394 | 407 | "cluster_type": "type",
|
395 | 408 | "cluster_group": "group",
|
|
417 | 430 | "device_roles",
|
418 | 431 | "device_types",
|
419 | 432 | "ipam_roles",
|
| 433 | + "locations", |
420 | 434 | "rack_groups",
|
421 | 435 | "rack_roles",
|
422 | 436 | "regions",
|
423 | 437 | "rirs",
|
424 | 438 | "roles",
|
425 | 439 | "sites",
|
| 440 | + "site_groups", |
426 | 441 | "tags",
|
427 | 442 | "tenants",
|
428 | 443 | "tenant_groups",
|
|
432 | 447 | "vlan_groups",
|
433 | 448 | }
|
434 | 449 |
|
| 450 | +SCOPE_TO_ENDPOINT = { |
| 451 | + "dcim.location": "locations", |
| 452 | + "dcim.rack": "racks", |
| 453 | + "dcim.region": "regions", |
| 454 | + "dcim.site": "sites", |
| 455 | + "dcim.sitegroup": "site_groups", |
| 456 | + "virtualization.cluster": "clusters", |
| 457 | + "virtualization.clustergroup": "cluster_groups", |
| 458 | +} |
| 459 | + |
435 | 460 | NETBOX_ARG_SPEC = dict(
|
436 | 461 | netbox_url=dict(type="str", required=True),
|
437 | 462 | netbox_token=dict(type="str", required=True, no_log=True),
|
@@ -609,8 +634,8 @@ def _convert_identical_keys(self, data):
|
609 | 634 | if self.endpoint == "power_panels" and key == "rack_group":
|
610 | 635 | temp_dict[key] = data[key]
|
611 | 636 | elif key in CONVERT_KEYS:
|
612 |
| - # This will keep the original key for assigned_object, but also convert to assigned_object_id |
613 |
| - if key == "assigned_object": |
| 637 | + # This will keep the original key for keys in list, but also convert it. |
| 638 | + if key in ("assigned_object", "scope"): |
614 | 639 | temp_dict[key] = data[key]
|
615 | 640 | new_key = CONVERT_KEYS[key]
|
616 | 641 | temp_dict[new_key] = data[key]
|
@@ -672,6 +697,8 @@ def _build_query_params(
|
672 | 697 | parent = module_data["termination_a_type"]
|
673 | 698 | elif parent == "termination_b" and module_data.get("termination_b_type"):
|
674 | 699 | parent = module_data["termination_b_type"]
|
| 700 | + elif parent == "scope": |
| 701 | + parent = ENDPOINT_NAME_MAPPING[SCOPE_TO_ENDPOINT[module_data["scope_type"]]] |
675 | 702 |
|
676 | 703 | query_dict = dict()
|
677 | 704 | if user_query_params:
|
@@ -862,6 +889,9 @@ def _find_ids(self, data, user_query_params):
|
862 | 889 | endpoint = CONVERT_TO_ID[data.get("termination_b_type")]
|
863 | 890 | elif k == "assigned_object":
|
864 | 891 | endpoint = "interfaces"
|
| 892 | + elif k == "scope": |
| 893 | + # Determine endpoint name for scope ID resolution |
| 894 | + endpoint = SCOPE_TO_ENDPOINT[data["scope_type"]] |
865 | 895 | else:
|
866 | 896 | endpoint = CONVERT_TO_ID[k]
|
867 | 897 | search = v
|
@@ -911,6 +941,12 @@ def _find_ids(self, data, user_query_params):
|
911 | 941 | query_params = self._build_query_params(
|
912 | 942 | k, data, user_query_params
|
913 | 943 | )
|
| 944 | + elif k == "scope": |
| 945 | + query_params = { |
| 946 | + QUERY_TYPES.get( |
| 947 | + ENDPOINT_NAME_MAPPING[endpoint], "q" |
| 948 | + ): search |
| 949 | + } |
914 | 950 | else:
|
915 | 951 | query_params = {QUERY_TYPES.get(k, "q"): search}
|
916 | 952 | query_id = self._nb_endpoint_get(nb_endpoint, query_params, k)
|
@@ -960,7 +996,13 @@ def _normalize_data(self, data):
|
960 | 996 | if sub_data_type == "slug":
|
961 | 997 | data[k][subk] = self._to_slug(subv)
|
962 | 998 | else:
|
963 |
| - data_type = QUERY_TYPES.get(k, "q") |
| 999 | + if k == "scope": |
| 1000 | + data_type = QUERY_TYPES.get( |
| 1001 | + ENDPOINT_NAME_MAPPING[SCOPE_TO_ENDPOINT[data["scope_type"]]], |
| 1002 | + "q", |
| 1003 | + ) |
| 1004 | + else: |
| 1005 | + data_type = QUERY_TYPES.get(k, "q") |
964 | 1006 | if data_type == "slug":
|
965 | 1007 | data[k] = self._to_slug(v)
|
966 | 1008 | elif data_type == "timezone":
|
|
0 commit comments