commit
aa836c4703
6 changed files with 90 additions and 14 deletions
|
@ -3,6 +3,7 @@ import argparse
|
||||||
from netbox_agent.dell.dell import DellHost
|
from netbox_agent.dell.dell import DellHost
|
||||||
import netbox_agent.dmidecode as dmidecode
|
import netbox_agent.dmidecode as dmidecode
|
||||||
from netbox_agent.hp.hp import HPHost
|
from netbox_agent.hp.hp import HPHost
|
||||||
|
from netbox_agent.logging import logging # NOQA
|
||||||
|
|
||||||
MANUFACTURERS = {
|
MANUFACTURERS = {
|
||||||
'Dell Inc.': DellHost,
|
'Dell Inc.': DellHost,
|
||||||
|
|
|
@ -10,6 +10,8 @@ netbox_instance = pynetbox.api(
|
||||||
token=config['netbox']['token']
|
token=config['netbox']['token']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
LOG_LEVEL = config.get('log_level', 'debug')
|
||||||
|
|
||||||
DATACENTER_LOCATION_DRIVER_FILE = None
|
DATACENTER_LOCATION_DRIVER_FILE = None
|
||||||
DATACENTER_LOCATION = None
|
DATACENTER_LOCATION = None
|
||||||
DATACENTER_LOCATION_REGEX = None
|
DATACENTER_LOCATION_REGEX = None
|
||||||
|
|
|
@ -61,7 +61,7 @@ class Ethtool():
|
||||||
if status != 0:
|
if status != 0:
|
||||||
return {}
|
return {}
|
||||||
r = re.search(r'Identifier.*\((\w+)\)', output)
|
r = re.search(r'Identifier.*\((\w+)\)', output)
|
||||||
if r and r.groups() > 0:
|
if r and len(r.groups()) > 0:
|
||||||
return {'form_factor': r.groups()[0]}
|
return {'form_factor': r.groups()[0]}
|
||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
|
|
11
netbox_agent/logging.py
Normal file
11
netbox_agent/logging.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from netbox_agent.config import LOG_LEVEL
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
|
if LOG_LEVEL == 'debug':
|
||||||
|
logger.setLevel(logging.DEBUG)
|
||||||
|
else:
|
||||||
|
logger.setLevel(logging.INFO)
|
|
@ -1,4 +1,5 @@
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
@ -80,14 +81,18 @@ class Network():
|
||||||
|
|
||||||
def create_netbox_nic(self, device, nic):
|
def create_netbox_nic(self, device, nic):
|
||||||
# TODO: add Optic Vendor, PN and Serial
|
# TODO: add Optic Vendor, PN and Serial
|
||||||
|
type = self.get_netbox_type_for_nic(nic)
|
||||||
|
logging.info('Creating NIC {name} ({mac}) on {device}'.format(
|
||||||
|
name=nic['name'], mac=nic['mac'], device=device.name))
|
||||||
return nb.dcim.interfaces.create(
|
return nb.dcim.interfaces.create(
|
||||||
device=device.id,
|
device=device.id,
|
||||||
name=nic['name'],
|
name=nic['name'],
|
||||||
mac_address=nic['mac'],
|
mac_address=nic['mac'],
|
||||||
type=self.get_netbox_type_for_nic(nic),
|
type=type,
|
||||||
)
|
)
|
||||||
|
|
||||||
def create_netbox_network_cards(self):
|
def create_netbox_network_cards(self):
|
||||||
|
logging.debug('Creating NIC...')
|
||||||
device = self.server.get_netbox_server()
|
device = self.server.get_netbox_server()
|
||||||
for nic in self.nics:
|
for nic in self.nics:
|
||||||
interface = nb.dcim.interfaces.get(
|
interface = nb.dcim.interfaces.get(
|
||||||
|
@ -105,16 +110,22 @@ class Network():
|
||||||
address=ip,
|
address=ip,
|
||||||
)
|
)
|
||||||
if netbox_ip:
|
if netbox_ip:
|
||||||
|
logging.info('Assigning existing IP {ip} to {interface}'.format(
|
||||||
|
ip=ip, interface=new_interface))
|
||||||
netbox_ip.interface = new_interface
|
netbox_ip.interface = new_interface
|
||||||
netbox_ip.save()
|
netbox_ip.save()
|
||||||
else:
|
else:
|
||||||
|
logging.info('Create new IP {ip} on {interface}'.format(
|
||||||
|
ip=ip, interface=new_interface))
|
||||||
netbox_ip = nb.ipam.ip_addresses.create(
|
netbox_ip = nb.ipam.ip_addresses.create(
|
||||||
address=ip,
|
address=ip,
|
||||||
interface=new_interface.id,
|
interface=new_interface.id,
|
||||||
status=1,
|
status=1,
|
||||||
)
|
)
|
||||||
|
logging.debug('Finished creating NIC!')
|
||||||
|
|
||||||
def update_netbox_network_cards(self):
|
def update_netbox_network_cards(self):
|
||||||
|
logging.debug('Updating NIC...')
|
||||||
device = self.server.get_netbox_server()
|
device = self.server.get_netbox_server()
|
||||||
|
|
||||||
# delete IP on netbox that are not known on this server
|
# delete IP on netbox that are not known on this server
|
||||||
|
@ -126,6 +137,8 @@ class Network():
|
||||||
]))
|
]))
|
||||||
for netbox_ip in netbox_ips:
|
for netbox_ip in netbox_ips:
|
||||||
if netbox_ip.address not in all_local_ips:
|
if netbox_ip.address not in all_local_ips:
|
||||||
|
logging.info('Unassigning IP {ip} from {interface}'.format(
|
||||||
|
ip=netbox_ip.address, interface=netbox_ip.interface))
|
||||||
netbox_ip.interface = None
|
netbox_ip.interface = None
|
||||||
netbox_ip.save()
|
netbox_ip.save()
|
||||||
|
|
||||||
|
@ -134,10 +147,17 @@ class Network():
|
||||||
interface = nb.dcim.interfaces.get(
|
interface = nb.dcim.interfaces.get(
|
||||||
mac_address=nic['mac'],
|
mac_address=nic['mac'],
|
||||||
)
|
)
|
||||||
|
if not interface:
|
||||||
|
logging.info('Interface {} not found, creating..'.format(
|
||||||
|
mac_address=nic['mac'])
|
||||||
|
)
|
||||||
|
interface = self.create_netbox_nic(device, nic)
|
||||||
|
|
||||||
nic_update = False
|
nic_update = False
|
||||||
if nic['name'] != interface.name:
|
if nic['name'] != interface.name:
|
||||||
nic_update = True
|
nic_update = True
|
||||||
|
logging.info('Updating interface {interface} name to: {name}'.format(
|
||||||
|
interface=interface, name=nic['name']))
|
||||||
interface.name = nic['name']
|
interface.name = nic['name']
|
||||||
|
|
||||||
if nic['ip']:
|
if nic['ip']:
|
||||||
|
@ -153,9 +173,19 @@ class Network():
|
||||||
interface=interface.id,
|
interface=interface.id,
|
||||||
status=1,
|
status=1,
|
||||||
)
|
)
|
||||||
|
logging.info('Created new IP {ip} on {interface}'.format(
|
||||||
|
ip=ip, interface=interface))
|
||||||
else:
|
else:
|
||||||
if netbox_ip.interface != interface:
|
if netbox_ip.interface.id != interface.id:
|
||||||
|
logging.info(
|
||||||
|
'Detected interface change: old interface is {old_interface} '
|
||||||
|
'(id: {old_id}), new interface is {new_interface} (id: {new_id})'
|
||||||
|
.format(
|
||||||
|
old_interface=netbox_ip.interface, new_interface=interface,
|
||||||
|
old_id=netbox_ip.id, new_id=interface.id
|
||||||
|
))
|
||||||
netbox_ip.interface = interface
|
netbox_ip.interface = interface
|
||||||
netbox_ip.save()
|
netbox_ip.save()
|
||||||
if nic_update:
|
if nic_update:
|
||||||
interface.save()
|
interface.save()
|
||||||
|
logging.debug('Finished updating NIC!')
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
import logging
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
from netbox_agent.config import netbox_instance as nb
|
from netbox_agent.config import netbox_instance as nb
|
||||||
|
|
||||||
import netbox_agent.dmidecode as dmidecode
|
import netbox_agent.dmidecode as dmidecode
|
||||||
from netbox_agent.location import Datacenter, Rack
|
from netbox_agent.location import Datacenter, Rack
|
||||||
from netbox_agent.network import Network
|
from netbox_agent.network import Network
|
||||||
|
@ -81,14 +81,19 @@ class ServerBase():
|
||||||
model=self.get_chassis(),
|
model=self.get_chassis(),
|
||||||
)
|
)
|
||||||
if not device_type:
|
if not device_type:
|
||||||
raise Exception('Chassis "{}" doesn\'t exist'.format(self.get_chassis()))
|
error_msg = 'Chassis "{}" doesn\'t exist'.format(self.get_chassis())
|
||||||
|
logging.error(error_msg)
|
||||||
|
raise Exception(error_msg)
|
||||||
device_role = nb.dcim.device_roles.get(
|
device_role = nb.dcim.device_roles.get(
|
||||||
name='Server Chassis',
|
name='Server Chassis',
|
||||||
)
|
)
|
||||||
|
serial = self.get_chassis_service_tag()
|
||||||
|
logging.info('Creating chassis blade (serial: {serial})'.format(
|
||||||
|
serial=serial))
|
||||||
new_chassis = nb.dcim.devices.create(
|
new_chassis = nb.dcim.devices.create(
|
||||||
name=''.format(),
|
name=''.format(),
|
||||||
device_type=device_type.id,
|
device_type=device_type.id,
|
||||||
serial=self.get_chassis_service_tag(),
|
serial=serial,
|
||||||
device_role=device_role.id,
|
device_role=device_role.id,
|
||||||
site=datacenter.id if datacenter else None,
|
site=datacenter.id if datacenter else None,
|
||||||
)
|
)
|
||||||
|
@ -101,9 +106,15 @@ class ServerBase():
|
||||||
device_type = nb.dcim.device_types.get(
|
device_type = nb.dcim.device_types.get(
|
||||||
model=self.get_product_name(),
|
model=self.get_product_name(),
|
||||||
)
|
)
|
||||||
|
serial = self.get_service_tag()
|
||||||
|
hostname = self.get_hostname()
|
||||||
|
logging.info(
|
||||||
|
'Creating blade (serial: {serial}) {hostname} on chassis {chassis_serial}'.format(
|
||||||
|
serial=serial, hostname=hostname, chassis_serial=chassis.serial
|
||||||
|
))
|
||||||
new_blade = nb.dcim.devices.create(
|
new_blade = nb.dcim.devices.create(
|
||||||
name=self.get_hostname(),
|
name=hostname,
|
||||||
serial=self.get_service_tag(),
|
serial=serial,
|
||||||
device_role=device_role.id,
|
device_role=device_role.id,
|
||||||
device_type=device_type.id,
|
device_type=device_type.id,
|
||||||
parent_device=chassis.id,
|
parent_device=chassis.id,
|
||||||
|
@ -120,9 +131,13 @@ class ServerBase():
|
||||||
)
|
)
|
||||||
if not device_type:
|
if not device_type:
|
||||||
raise Exception('Chassis "{}" doesn\'t exist'.format(self.get_chassis()))
|
raise Exception('Chassis "{}" doesn\'t exist'.format(self.get_chassis()))
|
||||||
|
serial = self.get_service_tag()
|
||||||
|
hostname = self.get_hostname()
|
||||||
|
logging.info('Creating server (serial: {serial}) {hostname}'.format(
|
||||||
|
serial=serial, hostname=hostname))
|
||||||
new_server = nb.dcim.devices.create(
|
new_server = nb.dcim.devices.create(
|
||||||
name=self.get_hostname(),
|
name=hostname,
|
||||||
serial=self.get_service_tag(),
|
serial=serial,
|
||||||
device_role=device_role.id,
|
device_role=device_role.id,
|
||||||
device_type=device_type.id,
|
device_type=device_type.id,
|
||||||
site=datacenter.id if datacenter else None,
|
site=datacenter.id if datacenter else None,
|
||||||
|
@ -133,10 +148,12 @@ class ServerBase():
|
||||||
return nb.dcim.devices.get(serial=self.get_service_tag())
|
return nb.dcim.devices.get(serial=self.get_service_tag())
|
||||||
|
|
||||||
def netbox_create(self):
|
def netbox_create(self):
|
||||||
|
logging.debug('Creating Server..')
|
||||||
datacenter = self.get_netbox_datacenter()
|
datacenter = self.get_netbox_datacenter()
|
||||||
if self.is_blade():
|
if self.is_blade():
|
||||||
# let's find the blade
|
# let's find the blade
|
||||||
blade = nb.dcim.devices.get(serial=self.get_service_tag())
|
serial = self.get_service_tag()
|
||||||
|
blade = nb.dcim.devices.get(serial=serial)
|
||||||
chassis = nb.dcim.devices.get(serial=self.get_chassis_service_tag())
|
chassis = nb.dcim.devices.get(serial=self.get_chassis_service_tag())
|
||||||
# if it doesn't exist, create it
|
# if it doesn't exist, create it
|
||||||
if not blade:
|
if not blade:
|
||||||
|
@ -151,20 +168,24 @@ class ServerBase():
|
||||||
blade = self._netbox_create_blade(chassis, datacenter)
|
blade = self._netbox_create_blade(chassis, datacenter)
|
||||||
|
|
||||||
# Find the slot and update it with our blade
|
# Find the slot and update it with our blade
|
||||||
|
slot = self.get_blade_slot()
|
||||||
device_bays = nb.dcim.device_bays.filter(
|
device_bays = nb.dcim.device_bays.filter(
|
||||||
device_id=chassis.id,
|
device_id=chassis.id,
|
||||||
name='Blade {}'.format(self.get_blade_slot()),
|
name='Blade {}'.format(slot),
|
||||||
)
|
)
|
||||||
if len(device_bays) > 0:
|
if len(device_bays) > 0:
|
||||||
|
logging.info('Updating blade ({serial}) slot on: Blade {slot}'.format(
|
||||||
|
serial=serial, slot=slot))
|
||||||
device_bay = device_bays[0]
|
device_bay = device_bays[0]
|
||||||
device_bay.installed_device = blade
|
device_bay.installed_device = blade
|
||||||
device_bay.save()
|
device_bay.save()
|
||||||
else:
|
else:
|
||||||
server = nb.dcim.devices.get(serial=self.get_service_tag())
|
server = nb.dcim.devices.get(serial=self.get_service_tag())
|
||||||
if not server:
|
if not server:
|
||||||
self._netbox_create_server()
|
self._netbox_create_server(datacenter)
|
||||||
|
|
||||||
self.network.create_netbox_network_cards()
|
self.network.create_netbox_network_cards()
|
||||||
|
logging.debug('Server created!')
|
||||||
|
|
||||||
def netbox_update(self):
|
def netbox_update(self):
|
||||||
"""
|
"""
|
||||||
|
@ -176,6 +197,7 @@ class ServerBase():
|
||||||
* hostname update
|
* hostname update
|
||||||
* new network infos
|
* new network infos
|
||||||
"""
|
"""
|
||||||
|
logging.debug('Updating Server...')
|
||||||
server = nb.dcim.devices.get(serial=self.get_service_tag())
|
server = nb.dcim.devices.get(serial=self.get_service_tag())
|
||||||
if not server:
|
if not server:
|
||||||
raise Exception("The server (Serial: {}) isn't yet registered in Netbox, register"
|
raise Exception("The server (Serial: {}) isn't yet registered in Netbox, register"
|
||||||
|
@ -203,14 +225,23 @@ class ServerBase():
|
||||||
chassis = self._netbox_create_blade_chassis(datacenter)
|
chassis = self._netbox_create_blade_chassis(datacenter)
|
||||||
|
|
||||||
if move_device_bay or device_bay.name != 'Blade {}'.format(self.get_blade_slot()):
|
if move_device_bay or device_bay.name != 'Blade {}'.format(self.get_blade_slot()):
|
||||||
|
logging.info('Device ({serial}) seems to have moved, reseting old slot..'.format(
|
||||||
|
serial=server.serial))
|
||||||
device_bay.installed_device = None
|
device_bay.installed_device = None
|
||||||
device_bay.save()
|
device_bay.save()
|
||||||
|
|
||||||
|
slot = self.get_blade_slot()
|
||||||
# Find the slot and update it with our blade
|
# Find the slot and update it with our blade
|
||||||
device_bays = nb.dcim.device_bays.filter(
|
device_bays = nb.dcim.device_bays.filter(
|
||||||
device_id=chassis.id,
|
device_id=chassis.id,
|
||||||
name='Blade {}'.format(self.get_blade_slot()),
|
name='Blade {}'.format(slot),
|
||||||
)
|
)
|
||||||
if len(device_bays) > 0:
|
if len(device_bays) > 0:
|
||||||
|
logging.info(
|
||||||
|
'Setting device ({serial}) new slot on Blade {slot} '
|
||||||
|
'(Chassis {chassis_serial})..'.format(
|
||||||
|
serial=server.serial, slot=slot, chassis_serial=chassis.serial
|
||||||
|
))
|
||||||
device_bay = device_bays[0]
|
device_bay = device_bays[0]
|
||||||
device_bay.installed_device = server
|
device_bay.installed_device = server
|
||||||
device_bay.save()
|
device_bay.save()
|
||||||
|
@ -224,6 +255,7 @@ class ServerBase():
|
||||||
self.network.update_netbox_network_cards()
|
self.network.update_netbox_network_cards()
|
||||||
if update:
|
if update:
|
||||||
server.save()
|
server.save()
|
||||||
|
logging.debug('Finished updating Server!')
|
||||||
|
|
||||||
def print_debug(self):
|
def print_debug(self):
|
||||||
# FIXME: do something more generic by looping on every get_* methods
|
# FIXME: do something more generic by looping on every get_* methods
|
||||||
|
|
Loading…
Reference in a new issue