diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..457f44d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.analysis.typeCheckingMode": "basic" +} \ No newline at end of file diff --git a/netbox_agent/inventory.py b/netbox_agent/inventory.py index 40e73d4..fa6e8f6 100644 --- a/netbox_agent/inventory.py +++ b/netbox_agent/inventory.py @@ -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']) ) @@ -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, @@ -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, @@ -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'], ) diff --git a/netbox_agent/network.py b/netbox_agent/network.py index 673dfc1..c87fd78 100644 --- a/netbox_agent/network.py +++ b/netbox_agent/network.py @@ -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: @@ -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 @@ -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() @@ -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) diff --git a/netbox_agent/server.py b/netbox_agent/server.py index c755a71..922cacc 100644 --- a/netbox_agent/server.py +++ b/netbox_agent/server.py @@ -517,4 +517,4 @@ def own_drive_expansion_slot(self): """ Indicates if the device hosts a drive expansion bay """ - return False + return False \ No newline at end of file