Skip to content

Commit 8f9fa01

Browse files
committed
fixes issue with finding ip prefixx in NetBox 4.2 and reassignes VRFs to IPs #397
1 parent d7ca5d3 commit 8f9fa01

2 files changed

Lines changed: 70 additions & 23 deletions

File tree

module/netbox/object_classes.py

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,7 @@ def update(self, data=None, read_from_netbox=False, source=None):
14421442

14431443
super().update(data=data, read_from_netbox=read_from_netbox, source=source)
14441444

1445+
14451446
class NBVLANGroup(NetBoxObject):
14461447
name = "VLANGroup"
14471448
api_path = "ipam/vlan-groups"
@@ -1477,8 +1478,9 @@ def resolve_relations(self):
14771478

14781479
if isinstance(o_id, int) and o_type is not None and self.data_model_relation.get(o_type) is not None:
14791480
self.data["scope_id"] = self.inventory.get_by_id(self.data_model_relation.get(o_type), nb_id=o_id)
1480-
elif not isinstance(o_id, NetBoxObject):
1481-
log.debug(f"{self.name} '{self.data.get('name')}' scope type '{o_type}' for '{grab(self, 'data.scope.name')}' is currently not supported")
1481+
elif o_id is not None and not isinstance(o_id, NetBoxObject):
1482+
log.debug(f"{self.name} '{self.data.get('name')}' scope type '{o_type}' for "
1483+
f"'{grab(self, 'data.scope.name')}' is currently not supported")
14821484
self.data["scope_id"] = ""
14831485

14841486
super().resolve_relations()
@@ -1500,16 +1502,16 @@ def matches_site_cluster(self, site=None, cluster=None) -> bool:
15001502
15011503
"""
15021504
if isinstance(site, NBSite):
1503-
if isinstance(self.data["scope_id"], NBSite) and self.data["scope_id"] == site:
1505+
if isinstance(self.data.get("scope_id"), NBSite) and self.data.get("scope_id") == site:
15041506
return True
1505-
if (isinstance(self.data["scope_id"], NBSiteGroup) and
1507+
if (isinstance(self.data.get("scope_id"), NBSiteGroup) and
15061508
self.data["scope_id"] == grab(site, "data.group")):
15071509
return True
15081510

15091511
if isinstance(cluster, NBCluster):
1510-
if isinstance(self.data["scope_id"], NBCluster) and self.data["scope_id"] == cluster:
1512+
if isinstance(self.data.get("scope_id"), NBCluster) and self.data.get("scope_id") == cluster:
15111513
return True
1512-
if (isinstance(self.data["scope_id"], NBClusterGroup) and
1514+
if (isinstance(self.data.get("scope_id"), NBClusterGroup) and
15131515
self.data["scope_id"] == grab(cluster, "data.group")):
15141516
return True
15151517

@@ -1545,19 +1547,29 @@ def __init__(self, *args, **kwargs):
15451547
self.data_model = {
15461548
"prefix": [IPv4Network, IPv6Network],
15471549
"site": NBSite,
1550+
"scope_type": ["dcim.site", "dcim.sitegroup"],
1551+
"scope_id": [NBSite, NBSiteGroup],
15481552
"tenant": NBTenant,
15491553
"vlan": NBVLAN,
15501554
"vrf": NBVRF,
15511555
"description": 200,
15521556
"tags": NBTagList
15531557
}
1558+
# add relation between two attributes
1559+
self.data_model_relation = {
1560+
"dcim.site": NBSite,
1561+
"dcim.sitegroup": NBSiteGroup,
1562+
NBSite: "dcim.site",
1563+
NBSiteGroup: "dcim.sitegroup",
1564+
}
1565+
15541566
super().__init__(*args, **kwargs)
15551567

15561568
def update(self, data=None, read_from_netbox=False, source=None):
15571569

15581570
# prefixes are parsed into ip_networks
15591571
data_prefix = data.get(self.primary_key)
1560-
if data_prefix is not None and not isinstance(data_prefix, (IPv4Network, IPv6Network)):
1572+
if not isinstance(data_prefix, (IPv4Network, IPv6Network)) and data_prefix is not None:
15611573
try:
15621574
data[self.primary_key] = ip_network(data_prefix)
15631575
except ValueError as e:
@@ -1569,6 +1581,47 @@ def update(self, data=None, read_from_netbox=False, source=None):
15691581
if read_from_netbox is False:
15701582
raise ValueError(f"Adding {self.name} by this program is currently not implemented.")
15711583

1584+
def resolve_relations(self):
1585+
1586+
o_id = self.data.get("scope_id")
1587+
o_type = self.data.get("scope_type")
1588+
1589+
if isinstance(o_id, int) and o_type is not None and self.data_model_relation.get(o_type) is not None:
1590+
self.data["scope_id"] = self.inventory.get_by_id(self.data_model_relation.get(o_type), nb_id=o_id)
1591+
elif o_id is not None and not isinstance(o_id, NetBoxObject):
1592+
log.debug(f"{self.name} '{self.data.get('name')}' scope type '{o_type}' for "
1593+
f"'{grab(self, 'data.scope.name')}' is currently not supported")
1594+
self.data["scope_id"] = ""
1595+
1596+
super().resolve_relations()
1597+
1598+
def matches_site(self, site=None) -> bool:
1599+
"""
1600+
tries to figure out if this prefix matches a certain site or site group
1601+
1602+
Parameters
1603+
----------
1604+
site: NBSite
1605+
the site object to match to
1606+
1607+
Returns
1608+
-------
1609+
bool: True if matches one of the params
1610+
1611+
"""
1612+
if isinstance(site, NBSite):
1613+
if isinstance(self.data.get("scope_id"), NBSite) and self.data.get("scope_id") == site:
1614+
return True
1615+
if (isinstance(self.data.get("scope_id"), NBSiteGroup) and
1616+
self.data["scope_id"] == grab(site, "data.group")):
1617+
return True
1618+
1619+
# compatible for NetBox versions < 4.2.0
1620+
if self.data.get("site") == site:
1621+
return True
1622+
1623+
return False
1624+
15721625

15731626
class NBManufacturer(NetBoxObject):
15741627
name = "manufacturer"
@@ -1686,7 +1739,7 @@ def __init__(self, *args, **kwargs):
16861739
"type": NBClusterType,
16871740
"tenant": NBTenant,
16881741
"group": NBClusterGroup,
1689-
"scope_type": ["dcim.site", "dcim.sitegroup", "dcim.location", "dcim.region"],
1742+
"scope_type": ["dcim.site", "dcim.sitegroup"],
16901743
"scope_id": NBSite,
16911744
"tags": NBTagList
16921745
}

module/sources/common/source_base.py

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def return_longest_matching_prefix_for_ip(self, ip_to_match=None, site_name=None
216216

217217
for prefix in self.inventory.get_all_items(NBPrefix):
218218

219-
if grab(prefix, "data.site") != site_object:
219+
if not prefix.matches_site(site_object):
220220
continue
221221

222222
prefix_network = grab(prefix, f"data.{NBPrefix.primary_key}")
@@ -286,7 +286,7 @@ def add_update_interface(self, interface_object, device_object, interface_data,
286286
site_name = device_object_cluster.get_site_name()
287287
elif type(device_object) == NBDevice:
288288
interface_class = NBInterface
289-
site_name = grab(device_object, "data.site.data.name")
289+
site_name = device_object.get_site_name()
290290
elif device_object is None:
291291
log.error(f"No device/VM object submitted to attach interface '{grab(interface_data, 'name')}' to.")
292292
return None
@@ -415,7 +415,7 @@ def add_update_interface(self, interface_object, device_object, interface_data,
415415

416416
# check if IP address is of type IP interface (includes prefix length)
417417
if type(ip_object) in [IPv6Address, IPv4Address]:
418-
log.warning(f"{log_text}. Unable to add IP address to NetBox.")
418+
log.warning(f"{log_text}. Unable to add IP address to NetBox")
419419
continue
420420
else:
421421
log.debug2(log_text)
@@ -426,7 +426,7 @@ def add_update_interface(self, interface_object, device_object, interface_data,
426426
if type(this_prefix) in [IPv4Network, IPv6Network]:
427427
ip_object = ip_interface(f"{ip_object}/{this_prefix.prefixlen}")
428428
else:
429-
log.warning(f"{matching_ip_prefix.name} got wrong format. Unable to add IP to NetBox")
429+
log.warning(f"{matching_ip_prefix.name} got wrong format. Unable to add IP address to NetBox")
430430
continue
431431

432432
# try to find matching IP address object
@@ -563,27 +563,21 @@ def add_update_interface(self, interface_object, device_object, interface_data,
563563
ip_tenant = prefix_tenant
564564
break
565565

566+
if possible_ip_vrf is not None:
567+
nic_ip_data["vrf"] = possible_ip_vrf
568+
if ip_tenant is not None:
569+
nic_ip_data["tenant"] = ip_tenant
570+
566571
if not isinstance(this_ip_object, NBIPAddress):
567572
log.debug(f"No existing {NBIPAddress.name} object found. Creating a new one.")
568573

569-
if possible_ip_vrf is not None:
570-
nic_ip_data["vrf"] = possible_ip_vrf
571-
if ip_tenant is not None:
572-
nic_ip_data["tenant"] = ip_tenant
573-
574574
this_ip_object = self.inventory.add_object(NBIPAddress, data=nic_ip_data, source=self)
575575

576576
# update IP address with additional data if not already present
577577
else:
578578

579579
log.debug2(f"Found existing NetBox {NBIPAddress.name} object: {this_ip_object.get_display_name()}")
580580

581-
if grab(this_ip_object, "data.vrf") is None and possible_ip_vrf is not None:
582-
nic_ip_data["vrf"] = possible_ip_vrf
583-
584-
if grab(this_ip_object, "data.tenant") is None and ip_tenant is not None:
585-
nic_ip_data["tenant"] = ip_tenant
586-
587581
this_ip_object.update(data=nic_ip_data, source=self)
588582

589583
ip_address_objects.append(this_ip_object)

0 commit comments

Comments
 (0)