|
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