Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Truncate Serials Over 50 characters in inventory.py #291

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"python.analysis.typeCheckingMode": "basic"
}
8 changes: 4 additions & 4 deletions netbox_agent/inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def create_netbox_interface(self, iface):
discovered=True,
tags=[{'name': INVENTORY_TAG['interface']['name']}],
name="{}".format(iface['product']),
serial='{}'.format(iface['serial']),
serial='{}'.format(iface['serial'][:50]),
description='{} {}'.format(iface['description'], iface['name'])
)

Expand Down Expand Up @@ -256,7 +256,7 @@ def create_netbox_raid_card(self, raid_card):
)

name = raid_card.get_product_name()
serial = raid_card.get_serial_number()
serial = raid_card.get_serial_number()[:50]
nb_raid_card = nb.dcim.inventory_items.create(
device=self.device_id,
discovered=True,
Expand Down Expand Up @@ -371,7 +371,7 @@ def create_netbox_disk(self, disk):
desc = disk.get('description')
name = '{} ({})'.format(disk['Model'], disk['Size'])
description = disk['Type']
sn = disk.get('SN', 'unknown')
sn = disk.get('SN', 'unknown')[:50]

parms = {
'device': self.device_id,
Expand Down Expand Up @@ -455,7 +455,7 @@ def create_netbox_memory(self, memory):
tags=[{'name': INVENTORY_TAG['memory']['name']}],
name=name,
part_id=memory['product'],
serial=memory['serial'],
serial=memory['serial'][:50],
description=memory['description'],
)

Expand Down
204 changes: 111 additions & 93 deletions netbox_agent/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ def scan(self):
logging.debug('Ignore interface {interface}'.format(interface=interface))
continue

# Skip if the interface is ib0
if interface in ('ib0', 'ib1'):
logging.debug('Skipping ib interface')
continue

ip_addr = netifaces.ifaddresses(interface).get(netifaces.AF_INET, [])
ip6_addr = netifaces.ifaddresses(interface).get(netifaces.AF_INET6, [])
if config.network.ignore_ips:
Expand Down Expand Up @@ -314,87 +319,98 @@ def create_netbox_nic(self, nic, mgmt=False):
return interface

def create_or_update_netbox_ip_on_interface(self, ip, interface):
'''
Two behaviors:
- Anycast IP
* If IP exists and is in Anycast, create a new Anycast one
* If IP exists and isn't assigned, take it
* If server is decomissioned, then free IP will be taken

- Normal IP (can be associated only once)
* If IP doesn't exist, create it
* If IP exists and isn't assigned, take it
* If IP exists and interface is wrong, change interface
'''
netbox_ips = nb.ipam.ip_addresses.filter(
address=ip,
)
if not netbox_ips:
logging.info('Create new IP {ip} on {interface}'.format(
ip=ip, interface=interface))
query_params = {
'address': ip,
'status': "active",
'assigned_object_type': self.assigned_object_type,
'assigned_object_id': interface.id
}
'''
Two behaviors:
- Anycast IP
* If IP exists and is in Anycast, create a new Anycast one
* If IP exists and isn't assigned, take it
* If server is decomissioned, then free IP will be taken

- Normal IP (can be associated only once)
* If IP doesn't exist, create it
* If IP exists and isn't assigned, take it
* If IP exists and interface is wrong, change interface
'''
netbox_ip = None
# Check if the IP is not 0.0.0.0/0
if ip != '0.0.0.0/0':
netbox_ips = nb.ipam.ip_addresses.filter(
address=ip,
)
if not netbox_ips:
logging.info('Create new IP {ip} on {interface}'.format(
ip=ip, interface=interface))
query_params = {
'address': ip,
'status': "active",
'assigned_object_type': self.assigned_object_type,
'assigned_object_id': interface.id
}
netbox_ip = nb.ipam.ip_addresses.create(
**query_params
)
return netbox_ip
else:
# IP already exists, log a warning and return None
logging.warning('IP {ip} already exists in NetBox'.format(ip=ip))
return None
else:
# Log that this IP is not being added due to being 0.0.0.0/0
logging.info('Skipping IP {ip} on {interface} as it is 0.0.0.0/0'.format(
ip=ip, interface=interface))

netbox_ip = nb.ipam.ip_addresses.create(
**query_params
)
return netbox_ip

netbox_ip = list(netbox_ips)[0]
# If IP exists in anycast
if netbox_ip.role and netbox_ip.role.label == 'Anycast':
logging.debug('IP {} is Anycast..'.format(ip))
unassigned_anycast_ip = [x for x in netbox_ips if x.interface is None]
assigned_anycast_ip = [x for x in netbox_ips if
x.interface and x.interface.id == interface.id]
# Check if netbox_ip is not None before accessing its properties
if netbox_ip is not None:
# Proceed with further processing only if netbox_ip is created
if netbox_ip.role and netbox_ip.role.label == 'Anycast':
logging.debug('IP {} is Anycast..'.format(ip))
unassigned_anycast_ip = [x for x in netbox_ips if x.interface is None]
assigned_anycast_ip = [x for x in netbox_ips if
x.interface and x.interface.id == interface.id]
# use the first available anycast ip
if len(unassigned_anycast_ip):
logging.info('Assigning existing Anycast IP {} to interface'.format(ip))
netbox_ip = unassigned_anycast_ip[0]
netbox_ip.interface = interface
netbox_ip.save()
if len(unassigned_anycast_ip):
logging.info('Assigning existing Anycast IP {} to interface'.format(ip))
netbox_ip = unassigned_anycast_ip[0]
netbox_ip.interface = interface
netbox_ip.save()
# or if everything is assigned to other servers
elif not len(assigned_anycast_ip):
logging.info('Creating Anycast IP {} and assigning it to interface'.format(ip))
query_params = {
"address": ip,
"status": "active",
"role": self.ipam_choices['ip-address:role']['Anycast'],
"tenant": self.tenant.id if self.tenant else None,
"assigned_object_type": self.assigned_object_type,
"assigned_object_id": interface.id
}
netbox_ip = nb.ipam.ip_addresses.create(**query_params)
return netbox_ip
else:
ip_interface = getattr(netbox_ip, 'interface', None)
assigned_object = getattr(netbox_ip, 'assigned_object', None)
if not ip_interface or not assigned_object:
logging.info('Assigning existing IP {ip} to {interface}'.format(
elif not len(assigned_anycast_ip):
logging.info('Creating Anycast IP {} and assigning it to interface'.format(ip))
query_params = {
"address": ip,
"status": "active",
"role": self.ipam_choices['ip-address:role']['Anycast'],
"tenant": self.tenant.id if self.tenant else None,
"assigned_object_type": self.assigned_object_type,
"assigned_object_id": interface.id
}
netbox_ip = nb.ipam.ip_addresses.create(**query_params)
return netbox_ip
else:
ip_interface = getattr(netbox_ip, 'interface', None)
assigned_object = getattr(netbox_ip, 'assigned_object', None)
if not ip_interface or not assigned_object:
logging.info('Assigning existing IP {ip} to {interface}'.format(
ip=ip, interface=interface))
elif (ip_interface and ip_interface.id != interface.id) or \
(assigned_object and assigned_object_id != interface.id):

old_interface = getattr(netbox_ip, "assigned_object", "n/a")
logging.info(
'Detected interface change for ip {ip}: old interface is '
'{old_interface} (id: {old_id}), new interface is {new_interface} '
' (id: {new_id})'
.format(
old_interface=old_interface, new_interface=interface,
old_id=netbox_ip.id, new_id=interface.id, ip=netbox_ip.address
))
else:
return netbox_ip

netbox_ip.assigned_object_type = self.assigned_object_type
netbox_ip.assigned_object_id = interface.id
netbox_ip.save()

elif (ip_interface and ip_interface.id != interface.id) or \
(assigned_object and assigned_object.id != interface.id):

old_interface = getattr(netbox_ip, "assigned_object", "n/a")
logging.info(
'Detected interface change for ip {ip}: old interface is '
'{old_interface} (id: {old_id}), new interface is {new_interface} '
' (id: {new_id})'
.format(
old_interface=old_interface, new_interface=interface,
old_id=netbox_ip.id, new_id=interface.id, ip=netbox_ip.address
))
else:
return netbox_ip
netbox_ip.assigned_object_type = self.assigned_object_type
netbox_ip.assigned_object_id = interface.id
netbox_ip.save()
def create_or_update_netbox_network_cards(self):
if config.update_all is None or config.update_network is None:
return None
Expand Down Expand Up @@ -495,7 +511,7 @@ def create_or_update_netbox_network_cards(self):

class ServerNetwork(Network):
def __init__(self, server, *args, **kwargs):
super(ServerNetwork, self).__init__(server, args, kwargs)
super(ServerNetwork, self).__init__(server, *args, **kwargs)

if config.network.ipmi:
self.ipmi = self.get_ipmi()
Expand Down Expand Up @@ -524,22 +540,24 @@ def connect_interface_to_switch(self, switch_ip, switch_interface, nb_server_int
nb_mgmt_ip = nb.ipam.ip_addresses.get(
address=switch_ip,
)
if not nb_mgmt_ip:
logging.error('Switch IP {} cannot be found in Netbox'.format(switch_ip))
return nb_server_interface

try:
nb_switch = nb_mgmt_ip.assigned_object.device
logging.info('Found a switch in Netbox based on LLDP infos: {} (id: {})'.format(
switch_ip,
nb_switch.id
))
except KeyError:
logging.error(
'Switch IP {} is found but not associated to a Netbox Switch Device'.format(
switch_ip

# Add the check here
if nb_mgmt_ip is not None:
try:
nb_switch = nb_mgmt_ip.assigned_object.device
logging.info('Found a switch in Netbox based on LLDP infos: {} (id: {})'.format(
switch_ip,
nb_switch.id
))
except KeyError:
logging.error(
'Switch IP {} is found but not associated to a Netbox Switch Device'.format(
switch_ip
)
)
)
return nb_server_interface
else:
logging.error('No NetBox IP found for switch IP {}'.format(switch_ip))
return nb_server_interface

switch_interface = self.lldp.get_switch_port(nb_server_interface.name)
Expand Down
2 changes: 1 addition & 1 deletion netbox_agent/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -517,4 +517,4 @@ def own_drive_expansion_slot(self):
"""
Indicates if the device hosts a drive expansion bay
"""
return False
return False