diff --git a/netbox_agent/cli.py b/netbox_agent/cli.py index 85b5497..0d8c0f9 100644 --- a/netbox_agent/cli.py +++ b/netbox_agent/cli.py @@ -1,12 +1,12 @@ import netbox_agent.dmidecode as dmidecode from netbox_agent.config import config from netbox_agent.logging import logging # NOQA -from netbox_agent.virtualmachine import VirtualMachine from netbox_agent.vendors.dell import DellHost from netbox_agent.vendors.generic import GenericHost from netbox_agent.vendors.hp import HPHost from netbox_agent.vendors.qct import QCTHost from netbox_agent.vendors.supermicro import SupermicroHost +from netbox_agent.virtualmachine import VirtualMachine MANUFACTURERS = { 'Dell Inc.': DellHost, diff --git a/netbox_agent/ipmi.py b/netbox_agent/ipmi.py index 9281ec8..10ccb8c 100644 --- a/netbox_agent/ipmi.py +++ b/netbox_agent/ipmi.py @@ -1,6 +1,8 @@ import logging import subprocess +from netaddr import IPNetwork + class IPMI(): """ @@ -40,11 +42,27 @@ class IPMI(): logging.error('Cannot get ipmi info: {}'.format(self.output)) def parse(self): - ret = {} + _ipmi = {} if self.ret != 0: - return ret + return _ipmi + for line in self.output.splitlines(): key = line.split(':')[0].strip() + if key not in ['802.1q VLAN ID', 'IP Address', 'Subnet Mask', 'MAC Address']: + continue value = ':'.join(line.split(':')[1:]).strip() - ret[key] = value + _ipmi[key] = value + + ret = {} + ret['name'] = 'IPMI' + ret['bonding'] = False + ret['mac'] = _ipmi['MAC Address'] + ret['vlan'] = int(_ipmi['802.1q VLAN ID']) \ + if _ipmi['802.1q VLAN ID'] != 'Disabled' else None + ip = _ipmi['IP Address'] + netmask = _ipmi['Subnet Mask'] + address = str(IPNetwork('{}/{}'.format(ip, netmask))) + + ret['ip'] = [address] + ret['ipmi'] = True return ret diff --git a/netbox_agent/misc.py b/netbox_agent/misc.py index 0e59956..cc1873c 100644 --- a/netbox_agent/misc.py +++ b/netbox_agent/misc.py @@ -1,15 +1,6 @@ -import os -import re -import netifaces -from netaddr import IPAddress, IPNetwork -from shutil import which import socket - - -from netbox_agent.ethtool import Ethtool -from netbox_agent.ipmi import IPMI -from netbox_agent.lldp import LLDP -from netbox_agent.logging import logging # NOQA +import subprocess +from shutil import which def is_tool(name): diff --git a/netbox_agent/network.py b/netbox_agent/network.py index eec8093..b988ee4 100644 --- a/netbox_agent/network.py +++ b/netbox_agent/network.py @@ -4,7 +4,7 @@ import re from itertools import chain import netifaces -from netaddr import IPAddress, IPNetwork +from netaddr import IPAddress from netbox_agent.config import config from netbox_agent.config import netbox_instance as nb @@ -18,7 +18,12 @@ class Network(object): self.nics = [] self.lldp = LLDP() if config.network.lldp else None - self.scan() + self.nics = self.scan() + self.ipmi = None + if self.get_network_type() == 'server': + self.ipmi = self.get_ipmi() + if self.ipmi: + self.nics.append(self.ipmi) self.dcim_choices = {} dcim_c = nb.dcim.choices() @@ -59,6 +64,7 @@ class Network(object): return interface def scan(self): + nics = [] for interface in os.listdir('/sys/class/net/'): # ignore if it's not a link (ie: bonding_masters etc) if not os.path.islink('/sys/class/net/{}'.format(interface)): @@ -122,7 +128,8 @@ class Network(object): 'bonding': bonding, 'bonding_slaves': bonding_slaves, } - self.nics.append(nic) + nics.append(nic) + return nics def _set_bonding_interfaces(self): bonding_nics = (x for x in self.nics if x['bonding']) @@ -201,9 +208,10 @@ class Network(object): # if it's a vlan interface elif vlan_id and ( interface.mode is None or - interface.mode.value != self.dcim_choices['interface:mode']['Access'] or - len(interface.tagged_vlans) != 1 or - interface.tagged_vlans[0].vid != vlan_id): + type(interface.mode) is not int and ( + interface.mode.value == self.dcim_choices['interface:mode']['Access'] or + len(interface.tagged_vlans) != 1 or + interface.tagged_vlans[0].vid != vlan_id)): logging.info('Resetting tagged VLAN(s) on interface {interface}'.format( interface=interface)) update = True @@ -345,7 +353,10 @@ class Network(object): interface = self.get_netbox_network_card(nic) # if network doesn't exist we create it if not interface: - new_interface = self.create_netbox_nic(nic) + new_interface = self.create_netbox_nic( + nic, + mgmt=True if 'ipmi' in nic.keys() else False + ) if nic['ip']: # for each ip, we try to find it # assign the device's interface to it @@ -353,8 +364,6 @@ class Network(object): for ip in nic['ip']: self.create_or_update_netbox_ip_on_interface(ip, new_interface) self._set_bonding_interfaces() - if self.get_network_type() == 'server': - self.create_or_update_ipmi() logging.debug('Finished creating NIC!') def update_netbox_network_cards(self): @@ -405,11 +414,11 @@ class Network(object): ret, interface = self.reset_vlan_on_interface(nic, interface) nic_update += ret - type = self.get_netbox_type_for_nic(nic) + _type = self.get_netbox_type_for_nic(nic) if not interface.type or \ - type != interface.type.value: + _type != interface.type.value: logging.info('Interface type is wrong, resetting') - interface.type = type + interface.type = _type nic_update += 1 if hasattr(interface, 'lag') and interface.lag is not None: @@ -439,18 +448,17 @@ class Network(object): interface.save() self._set_bonding_interfaces() - if self.get_network_type() == 'server': - self.create_or_update_ipmi() logging.debug('Finished updating NIC!') class ServerNetwork(Network): def __init__(self, server, *args, **kwargs): - super(VirtualNetwork, self).__init__(server, args, kwargs) + super(ServerNetwork, self).__init__(server, args, kwargs) self.server = server self.device = self.server.get_netbox_server() self.nb_net = nb.dcim - self.custom_arg = {'device_id': self.device.id} + self.custom_arg = {'device': self.device.id} + self.custom_arg_id = {'device_id': self.device.id} def get_network_type(self): return 'server' @@ -466,42 +474,6 @@ class ServerNetwork(Network): mac=mac ) - def create_or_update_ipmi(self): - ipmi = self.get_ipmi() - mac = ipmi['MAC Address'] - ip = ipmi['IP Address'] - netmask = ipmi['Subnet Mask'] - vlan = int(ipmi['802.1q VLAN ID']) if ipmi['802.1q VLAN ID'] != 'Disabled' else None - address = str(IPNetwork('{}/{}'.format(ip, netmask))) - - interface = self.nb_net.interfaces.get( - device_id=self.device.id, - mgmt_only=True, - ) - nic = { - 'name': 'IPMI', - 'mac': mac, - 'vlan': vlan, - 'ip': [address], - } - if interface is None: - interface = self.create_netbox_nic(nic, mgmt=True) - self.create_or_update_netbox_ip_on_interface(address, interface) - else: - # let the user chose the name of mgmt ? - # guess it with manufacturer (IDRAC, ILO, ...) ? - update = False - self.create_or_update_netbox_ip_on_interface(address, interface) - update, interface = self.reset_vlan_on_interface(nic, interface) - if mac.upper() != interface.mac_address: - logging.info('IPMI mac changed from {old_mac} to {new_mac}'.format( - old_mac=interface.mac_address, new_mac=mac.upper())) - interface.mac_address = mac - update = True - if update: - interface.save() - return interface - def connect_interface_to_switch(self, switch_ip, switch_interface, nb_server_interface): logging.info('Interface {} is not connected to switch, trying to connect..'.format( nb_server_interface.name @@ -606,7 +578,6 @@ class ServerNetwork(Network): return update, nb_server_interface - class VirtualNetwork(Network): def __init__(self, server, *args, **kwargs): super(VirtualNetwork, self).__init__(server, args, kwargs) diff --git a/netbox_agent/server.py b/netbox_agent/server.py index f3c737a..459dbe4 100644 --- a/netbox_agent/server.py +++ b/netbox_agent/server.py @@ -8,7 +8,7 @@ from netbox_agent.config import config from netbox_agent.config import netbox_instance as nb from netbox_agent.inventory import Inventory from netbox_agent.location import Datacenter, Rack -from netbox_agent.network import Network +from netbox_agent.network import ServerNetwork from netbox_agent.power import PowerSupply diff --git a/netbox_agent/virtualmachine.py b/netbox_agent/virtualmachine.py index 882f2bb..f6daaac 100644 --- a/netbox_agent/virtualmachine.py +++ b/netbox_agent/virtualmachine.py @@ -5,6 +5,7 @@ from netbox_agent.logging import logging # NOQA from netbox_agent.misc import get_hostname from netbox_agent.network import VirtualNetwork + class VirtualMachine(object): def __init__(self, dmi=None): if dmi: @@ -23,7 +24,7 @@ class VirtualMachine(object): def get_netbox_cluster(self, name): cluster = nb.virtualization.clusters.get( name=name, - ) + ) return cluster def netbox_create(self, config): @@ -37,9 +38,9 @@ class VirtualMachine(object): vm = nb.virtualization.virtual_machines.create( name=hostname, cluster=cluster.id, - vcpu=0, - memory=0, - ) + vcpu=0, # FIXME + memory=0, # FIXME + ) self.network = VirtualNetwork(server=self) self.network.update_netbox_network_cards() else: