Merge branch 'master' into feature/rack_awareness
This commit is contained in:
commit
18e29638e7
3 changed files with 122 additions and 11 deletions
|
@ -18,14 +18,18 @@ def run(args):
|
||||||
server.print_debug()
|
server.print_debug()
|
||||||
if args.register:
|
if args.register:
|
||||||
server.netbox_create()
|
server.netbox_create()
|
||||||
|
if args.update:
|
||||||
|
server.netbox_update()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description='Netbox agent command line')
|
parser = argparse.ArgumentParser(description='Netbox agent command line')
|
||||||
parser.add_argument('--register', action='store_true',
|
parser.add_argument('-r', '--register', action='store_true',
|
||||||
help='Register server in Netbox')
|
help='Register server in Netbox')
|
||||||
parser.add_argument('--debug', action='store_true',
|
parser.add_argument('-u', '--update', action='store_true',
|
||||||
|
help='Update server in Netbox')
|
||||||
|
parser.add_argument('-d', '--debug', action='store_true',
|
||||||
help='Print debug informations')
|
help='Print debug informations')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from itertools import chain
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
@ -86,7 +87,7 @@ class Network():
|
||||||
type=self.get_netbox_type_for_nic(nic),
|
type=self.get_netbox_type_for_nic(nic),
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_netbox_network_cards(self):
|
def create_netbox_network_cards(self):
|
||||||
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(
|
||||||
|
@ -112,9 +113,49 @@ class Network():
|
||||||
interface=new_interface.id,
|
interface=new_interface.id,
|
||||||
status=1,
|
status=1,
|
||||||
)
|
)
|
||||||
# or we check if it needs update
|
|
||||||
|
def update_netbox_network_cards(self):
|
||||||
|
device = self.server.get_netbox_server()
|
||||||
|
|
||||||
|
# delete IP on netbox that are not known on this server
|
||||||
|
netbox_ips = nb.ipam.ip_addresses.filter(
|
||||||
|
device=device
|
||||||
|
)
|
||||||
|
all_local_ips = list(chain.from_iterable([
|
||||||
|
x['ip'] for x in self.nics if x['ip'] is not None
|
||||||
|
]))
|
||||||
|
for netbox_ip in netbox_ips:
|
||||||
|
if netbox_ip.address not in all_local_ips:
|
||||||
|
netbox_ip.interface = None
|
||||||
|
netbox_ip.save()
|
||||||
|
|
||||||
|
# update each nic
|
||||||
|
for nic in self.nics:
|
||||||
|
interface = nb.dcim.interfaces.get(
|
||||||
|
mac_address=nic['mac'],
|
||||||
|
)
|
||||||
|
|
||||||
|
nic_update = False
|
||||||
|
if nic['name'] != interface.name:
|
||||||
|
nic_update = True
|
||||||
|
interface.name = nic['name']
|
||||||
|
|
||||||
|
if nic['ip']:
|
||||||
|
# sync local IPs
|
||||||
|
for ip in nic['ip']:
|
||||||
|
netbox_ip = nb.ipam.ip_addresses.get(
|
||||||
|
address=ip,
|
||||||
|
)
|
||||||
|
if not netbox_ip:
|
||||||
|
# create netbbox_ip on device
|
||||||
|
netbox_ip = nb.ipam.ip_addresses.create(
|
||||||
|
address=ip,
|
||||||
|
interface=interface.id,
|
||||||
|
status=1,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# FIXME: implement update
|
if netbox_ip.device != device:
|
||||||
# update name or ip
|
netbox_ip.device = device
|
||||||
# see https://github.com/Solvik/netbox_agent/issues/9
|
netbox_ip.save()
|
||||||
pass
|
if nic_update:
|
||||||
|
interface.save()
|
||||||
|
|
|
@ -2,6 +2,7 @@ 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
|
||||||
|
@ -51,6 +52,9 @@ class ServerBase():
|
||||||
"""
|
"""
|
||||||
return self.system[0]['Serial Number']
|
return self.system[0]['Serial Number']
|
||||||
|
|
||||||
|
def get_hostname(self):
|
||||||
|
return '{}'.format(socket.gethostname())
|
||||||
|
|
||||||
def is_blade(self):
|
def is_blade(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@ -98,7 +102,7 @@ class ServerBase():
|
||||||
model=self.get_product_name(),
|
model=self.get_product_name(),
|
||||||
)
|
)
|
||||||
new_blade = nb.dcim.devices.create(
|
new_blade = nb.dcim.devices.create(
|
||||||
name='{}'.format(socket.gethostname()),
|
name=self.get_hostname(),
|
||||||
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,
|
||||||
|
@ -117,7 +121,7 @@ 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()))
|
||||||
new_server = nb.dcim.devices.create(
|
new_server = nb.dcim.devices.create(
|
||||||
name='{}'.format(socket.gethostname()),
|
name=self.get_hostname(),
|
||||||
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,
|
||||||
|
@ -138,6 +142,9 @@ class ServerBase():
|
||||||
if not blade:
|
if not blade:
|
||||||
# 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
|
||||||
|
chassis = nb.dcim.devices.get(
|
||||||
|
serial=self.get_chassis_service_tag()
|
||||||
|
)
|
||||||
if not chassis:
|
if not chassis:
|
||||||
chassis = self._netbox_create_blade_chassis(datacenter)
|
chassis = self._netbox_create_blade_chassis(datacenter)
|
||||||
|
|
||||||
|
@ -157,7 +164,66 @@ class ServerBase():
|
||||||
if not server:
|
if not server:
|
||||||
self._netbox_create_server()
|
self._netbox_create_server()
|
||||||
|
|
||||||
|
self.network.create_netbox_network_cards()
|
||||||
|
|
||||||
|
def netbox_update(self):
|
||||||
|
"""
|
||||||
|
Netbox method to update info about our server/blade
|
||||||
|
|
||||||
|
Handle:
|
||||||
|
* new chasis for a blade
|
||||||
|
* new slot for a bblade
|
||||||
|
* hostname update
|
||||||
|
* new network infos
|
||||||
|
"""
|
||||||
|
server = nb.dcim.devices.get(serial=self.get_service_tag())
|
||||||
|
if not server:
|
||||||
|
raise Exception("The server (Serial: {}) isn't yet registered in Netbox, register"
|
||||||
|
'it before updating it'.format(self.get_service_tag()))
|
||||||
|
update = False
|
||||||
|
if self.is_blade():
|
||||||
|
# get current chassis device bay
|
||||||
|
device_bay = nb.dcim.device_bays.get(
|
||||||
|
server.parent_device.device_bay.id
|
||||||
|
)
|
||||||
|
netbox_chassis_serial = server.parent_device.device_bay.device.serial
|
||||||
|
chassis = server.parent_device.device_bay.device
|
||||||
|
move_device_bay = False
|
||||||
|
|
||||||
|
# check chassis serial with dmidecode
|
||||||
|
if netbox_chassis_serial != self.get_chassis_service_tag():
|
||||||
|
move_device_bay = True
|
||||||
|
# try to find the new netbox chassis
|
||||||
|
chassis = nb.dcim.devices.get(
|
||||||
|
serial=self.get_chassis_service_tag()
|
||||||
|
)
|
||||||
|
# create the new chassis if it doesn't exist
|
||||||
|
if not chassis:
|
||||||
|
datacenter = self.get_netbox_datacenter()
|
||||||
|
chassis = self._netbox_create_blade_chassis(datacenter)
|
||||||
|
|
||||||
|
if move_device_bay or device_bay.name != 'Blade {}'.format(self.get_blade_slot()):
|
||||||
|
device_bay.installed_device = None
|
||||||
|
device_bay.save()
|
||||||
|
# Find the slot and update it with our blade
|
||||||
|
device_bays = nb.dcim.device_bays.filter(
|
||||||
|
device_id=chassis.id,
|
||||||
|
name='Blade {}'.format(self.get_blade_slot()),
|
||||||
|
)
|
||||||
|
if len(device_bays) > 0:
|
||||||
|
device_bay = device_bays[0]
|
||||||
|
device_bay.installed_device = server
|
||||||
|
device_bay.save()
|
||||||
|
|
||||||
|
# for every other specs
|
||||||
|
# check hostname
|
||||||
|
if server.name != self.get_hostname():
|
||||||
|
update = True
|
||||||
|
server.hostname = self.get_hostname()
|
||||||
|
# check network cards
|
||||||
self.network.update_netbox_network_cards()
|
self.network.update_netbox_network_cards()
|
||||||
|
if update:
|
||||||
|
server.save()
|
||||||
|
|
||||||
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