add datacenter location awareness with pseudo-driver (cmd and file)

This commit is contained in:
Solvik Blum 2019-08-04 01:11:53 +02:00
parent 396c4b5d10
commit 8b8cd68ff2
No known key found for this signature in database
GPG key ID: CC12B3DC262B6C47
7 changed files with 84 additions and 18 deletions

View file

@ -0,0 +1,9 @@
netbox:
url: 'http://netbox.internal.company.com'
token: supersecrettoken
datacenter_location:
driver: file:/etc/qualification
regex: "datacenter: (?P<datacenter>[A-Za-z0-9]+)"
# driver: 'cmd:lldpctl'
# regex = 'SysName: .*\.(?P<datacenter>[A-Za-z0-9]+)'

15
netbox_agent/config.py Normal file
View file

@ -0,0 +1,15 @@
import pynetbox
import yaml
with open('/etc/netbox_agent.yaml', 'r') as ymlfile:
# FIXME: validate configuration file
config = yaml.load(ymlfile)
netbox_instance = pynetbox.api(
url=config['netbox']['url'],
token=config['netbox']['token']
)
DATACENTER_LOCATION = config['datacenter_location']['driver']
DATACENTER_LOCATION_REGEX = config['datacenter_location']['regex']

View file

@ -0,0 +1,20 @@
import importlib
from netbox_agent.config import DATACENTER_LOCATION, \
DATACENTER_LOCATION_REGEX
class Datacenter():
"""
"""
def __init__(self, *args, **kwargs):
self.driver = DATACENTER_LOCATION.split(':')[0]
self.driver_value = DATACENTER_LOCATION.split(':')[1]
try:
self.driver = importlib.import_module('netbox_agent.drivers.datacenter_' + self.driver)
except ImportError:
raise ImportError("Driver {} doesn't exists".format(self.driver))
def get(self):
return getattr(self.driver, 'get')(self.driver_value, DATACENTER_LOCATION_REGEX)

View file

View file

@ -0,0 +1,11 @@
import re
import subprocess
def get(value, regex):
output = subprocess.getoutput(value)
r = re.search(regex, output)
if r:
result = r.group('datacenter')
return result
return None

View file

@ -0,0 +1,9 @@
import re
def get(value, regex):
for line in open(value, 'r'):
r = re.search(regex, line)
if r:
return r.group('datacenter')
return None

View file

@ -3,6 +3,7 @@ import re
import socket import socket
from netbox_agent.config import netbox_instance as nb from netbox_agent.config import netbox_instance as nb
from netbox_agent.datacenter import Datacenter
import netbox_agent.dmidecode as dmidecode import netbox_agent.dmidecode as dmidecode
# Regex to match base interface name # Regex to match base interface name
@ -21,6 +22,16 @@ class ServerBase():
self.network_cards = [] self.network_cards = []
def get_datacenter(self):
dc = Datacenter()
return dc.get().upper()
def get_netbox_datacenter(self):
datacenter = nb.dcim.sites.get(
name=self.get_datacenter()
)
return datacenter
def get_product_name(self): def get_product_name(self):
""" """
Return the Chassis Name from dmidecode info Return the Chassis Name from dmidecode info
@ -66,7 +77,7 @@ class ServerBase():
nics.append(nic) nics.append(nic)
return nics return nics
def _netbox_create_blade_chassis(self): def _netbox_create_blade_chassis(self, datacenter):
device_type = nb.dcim.device_types.get( device_type = nb.dcim.device_types.get(
model=self.get_chassis(), model=self.get_chassis(),
) )
@ -75,39 +86,33 @@ class ServerBase():
device_role = nb.dcim.device_roles.get( device_role = nb.dcim.device_roles.get(
name='Server Chassis', name='Server Chassis',
) )
datacenter = nb.dcim.sites.get(
name='DC3', # FIXME: datacenter support
)
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=self.get_chassis_service_tag(),
device_role=device_role.id, device_role=device_role.id,
site=datacenter.id, site=datacenter.id if datacenter else None,
) )
return new_chassis return new_chassis
def _netbox_create_blade(self, chassis): def _netbox_create_blade(self, chassis, datacenter):
device_role = nb.dcim.device_roles.get( device_role = nb.dcim.device_roles.get(
name='Blade', name='Blade',
) )
device_type = nb.dcim.device_types.get( device_type = nb.dcim.device_types.get(
model=self.get_product_name(), model=self.get_product_name(),
) )
datacenter = nb.dcim.sites.get(
name='DC3', # FIXME: datacenter support
)
new_blade = nb.dcim.devices.create( new_blade = nb.dcim.devices.create(
name='{}'.format(socket.gethostname()), name='{}'.format(socket.gethostname()),
serial=self.get_service_tag(), serial=self.get_service_tag(),
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,
site=datacenter.id, site=datacenter.id if datacenter else None,
) )
return new_blade return new_blade
def _netbox_create_server(self): def _netbox_create_server(self, datacenter):
device_role = nb.dcim.device_roles.get( device_role = nb.dcim.device_roles.get(
name='Server', name='Server',
) )
@ -116,19 +121,17 @@ 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()))
datacenter = nb.dcim.sites.get(
name='DC3' # FIXME: datacenter support
)
new_server = nb.dcim.devices.create( new_server = nb.dcim.devices.create(
name='{}'.format(socket.gethostname()), name='{}'.format(socket.gethostname()),
serial=self.get_service_tag(), serial=self.get_service_tag(),
device_role=device_role.id, device_role=device_role.id,
device_type=device_type.id, device_type=device_type.id,
site=datacenter.id, site=datacenter.id if datacenter else None,
) )
return new_server return new_server
def netbox_create(self): def netbox_create(self):
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()) blade = nb.dcim.devices.get(serial=self.get_service_tag())
@ -138,9 +141,9 @@ class ServerBase():
# check if the chassis exist before # check if the chassis exist before
# if it doesn't exist, create it # if it doesn't exist, create it
if not chassis: if not chassis:
chassis = self._netbox_create_blade_chassis() chassis = self._netbox_create_blade_chassis(datacenter)
blade = self._netbox_create_blade(chassis) 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
device_bays = nb.dcim.device_bays.filter( device_bays = nb.dcim.device_bays.filter(
@ -152,7 +155,6 @@ class ServerBase():
device_bay.installed_device = blade device_bay.installed_device = blade
device_bay.save() device_bay.save()
else: else:
# FIXME : handle pizza box
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()