add datacenter location awareness with pseudo-driver (cmd and file)
This commit is contained in:
parent
396c4b5d10
commit
8b8cd68ff2
7 changed files with 84 additions and 18 deletions
9
netbox_agent.yaml.example
Normal file
9
netbox_agent.yaml.example
Normal 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
15
netbox_agent/config.py
Normal 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']
|
20
netbox_agent/datacenter.py
Normal file
20
netbox_agent/datacenter.py
Normal 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)
|
0
netbox_agent/drivers/__init__.py
Normal file
0
netbox_agent/drivers/__init__.py
Normal file
11
netbox_agent/drivers/datacenter_cmd.py
Normal file
11
netbox_agent/drivers/datacenter_cmd.py
Normal 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
|
9
netbox_agent/drivers/datacenter_file.py
Normal file
9
netbox_agent/drivers/datacenter_file.py
Normal 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
|
|
@ -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()
|
||||||
|
|
Loading…
Add table
Reference in a new issue