new config system (#53)
This commit is contained in:
parent
c5707e8413
commit
d12ac49d50
9 changed files with 177 additions and 120 deletions
|
@ -1,11 +1,10 @@
|
||||||
import argparse
|
from netbox_agent.logging import logging # NOQA
|
||||||
|
|
||||||
from netbox_agent.vendors.dell import DellHost
|
from netbox_agent.vendors.dell import DellHost
|
||||||
import netbox_agent.dmidecode as dmidecode
|
import netbox_agent.dmidecode as dmidecode
|
||||||
|
from netbox_agent.config import config
|
||||||
from netbox_agent.vendors.hp import HPHost
|
from netbox_agent.vendors.hp import HPHost
|
||||||
from netbox_agent.vendors.qct import QCTHost
|
from netbox_agent.vendors.qct import QCTHost
|
||||||
from netbox_agent.vendors.supermicro import SupermicroHost
|
from netbox_agent.vendors.supermicro import SupermicroHost
|
||||||
from netbox_agent.logging import logging # NOQA
|
|
||||||
|
|
||||||
MANUFACTURERS = {
|
MANUFACTURERS = {
|
||||||
'Dell Inc.': DellHost,
|
'Dell Inc.': DellHost,
|
||||||
|
@ -16,29 +15,22 @@ MANUFACTURERS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def run(args):
|
def run(config):
|
||||||
manufacturer = dmidecode.get_by_type('Chassis')[0].get('Manufacturer')
|
manufacturer = dmidecode.get_by_type('Chassis')[0].get('Manufacturer')
|
||||||
server = MANUFACTURERS[manufacturer](dmi=dmidecode)
|
server = MANUFACTURERS[manufacturer](dmi=dmidecode)
|
||||||
if args.debug:
|
|
||||||
|
if config.debug:
|
||||||
server.print_debug()
|
server.print_debug()
|
||||||
if args.register:
|
if config.register:
|
||||||
server.netbox_create()
|
server.netbox_create(config)
|
||||||
if args.update:
|
if config.update_all or config.update_network or config.update_location or \
|
||||||
server.netbox_update()
|
config.update_inventory:
|
||||||
|
server.netbox_update(config)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description='Netbox agent command line')
|
return run(config)
|
||||||
parser.add_argument('-r', '--register', action='store_true',
|
|
||||||
help='Register server in Netbox')
|
|
||||||
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')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
return run(args)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -1,52 +1,65 @@
|
||||||
|
import logging
|
||||||
import pynetbox
|
import pynetbox
|
||||||
import yaml
|
import jsonargparse
|
||||||
|
import sys
|
||||||
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']
|
|
||||||
)
|
|
||||||
|
|
||||||
LOG_LEVEL = config.get('log_level', 'debug')
|
|
||||||
|
|
||||||
DATACENTER_LOCATION_DRIVER_FILE = None
|
|
||||||
DATACENTER_LOCATION = None
|
|
||||||
DATACENTER_LOCATION_REGEX = None
|
|
||||||
RACK_LOCATION_DRIVER_FILE = None
|
|
||||||
RACK_LOCATION = None
|
|
||||||
RACK_LOCATION_REGEX = None
|
|
||||||
SLOT_LOCATION_DRIVER_FILE = None
|
|
||||||
SLOT_LOCATION = None
|
|
||||||
SLOT_LOCATION_REGEX = None
|
|
||||||
|
|
||||||
if config.get('datacenter_location'):
|
|
||||||
dc_loc = config.get('datacenter_location')
|
|
||||||
DATACENTER_LOCATION_DRIVER_FILE = dc_loc.get('driver_file')
|
|
||||||
DATACENTER_LOCATION = dc_loc.get('driver')
|
|
||||||
DATACENTER_LOCATION_REGEX = dc_loc.get('regex')
|
|
||||||
|
|
||||||
if config.get('rack_location'):
|
|
||||||
rack_location = config['rack_location']
|
|
||||||
RACK_LOCATION_DRIVER_FILE = rack_location.get('driver_file')
|
|
||||||
RACK_LOCATION = rack_location.get('driver')
|
|
||||||
RACK_LOCATION_REGEX = rack_location.get('regex')
|
|
||||||
|
|
||||||
if config.get('slot_location'):
|
|
||||||
slot_location = config['slot_location']
|
|
||||||
SLOT_LOCATION_DRIVER_FILE = slot_location.get('driver_file')
|
|
||||||
SLOT_LOCATION = slot_location.get('driver')
|
|
||||||
SLOT_LOCATION_REGEX = slot_location.get('regex')
|
|
||||||
|
|
||||||
|
|
||||||
NETWORK_IGNORE_INTERFACES = None
|
def get_config():
|
||||||
NETWORK_IGNORE_IPS = None
|
p = jsonargparse.ArgumentParser(
|
||||||
NETWORK_LLDP = None
|
default_config_files=[
|
||||||
if config.get('network'):
|
'/etc/netbox_agent.yaml',
|
||||||
NETWORK_IGNORE_INTERFACES = config['network'].get('ignore_interfaces')
|
'~/.config/netbox_agent.yaml',
|
||||||
NETWORK_IGNORE_IPS = config['network'].get('ignore_ips')
|
'~/.netbox_agent.yaml',
|
||||||
NETWORK_LLDP = config['network'].get('lldp') is True
|
],
|
||||||
|
prog='netbox_agent',
|
||||||
|
description="Netbox agent to run on your infrastructure's servers",
|
||||||
|
)
|
||||||
|
p.add_argument('-c', '--config', action=jsonargparse.ActionConfigFile)
|
||||||
|
|
||||||
INVENTORY_ENABLED = config.get('inventory') is True
|
p.add_argument('-r', '--register', action='store_true', help='Register server to Netbox')
|
||||||
|
p.add_argument('-u', '--update-all', action='store_true', help='Update all infos in Netbox')
|
||||||
|
p.add_argument('-d', '--debug', action='store_true', help='Print debug infos')
|
||||||
|
p.add_argument('--update-network', action='store_true', help='Update network')
|
||||||
|
p.add_argument('--update-inventory', action='store_true', help='Update inventory')
|
||||||
|
p.add_argument('--update-location', action='store_true', help='Update location')
|
||||||
|
|
||||||
|
p.add_argument('--log_level', default='debug')
|
||||||
|
p.add_argument('--netbox.url', help='Netbox URL')
|
||||||
|
p.add_argument('--netbox.token', help='Netbox API Token')
|
||||||
|
p.add_argument('--datacenter_location.driver',
|
||||||
|
help='Datacenter location driver, ie: cmd, file')
|
||||||
|
p.add_argument('--datacenter_location.driver_file',
|
||||||
|
help='Datacenter location custom driver file path')
|
||||||
|
p.add_argument('--datacenter_location.regex',
|
||||||
|
help='Datacenter location regex to extract Netbox DC slug')
|
||||||
|
p.add_argument('--rack_location.driver', help='Rack location driver, ie: cmd, file')
|
||||||
|
p.add_argument('--rack_location.driver_file', help='Rack location custom driver file path')
|
||||||
|
p.add_argument('--rack_location.regex', help='Rack location regex to extract Rack name')
|
||||||
|
p.add_argument('--slot_location.driver', help='Slot location driver, ie: cmd, file')
|
||||||
|
p.add_argument('--slot_location.driver_file', help='Slot location custom driver file path')
|
||||||
|
p.add_argument('--slot_location.regex', help='Slot location regex to extract slot name')
|
||||||
|
p.add_argument('--network.ignore_interfaces', default=r'(dummy.*|docker.*)',
|
||||||
|
help='Regex to ignore interfaces')
|
||||||
|
p.add_argument('--network.ignore_ips', default=r'^(127\.0\.0\..*|fe80.*|::1.*)',
|
||||||
|
help='Regex to ignore IPs')
|
||||||
|
p.add_argument('--network.lldp', help='Enable auto-cabling feature through LLDP infos')
|
||||||
|
p.add_argument('--inventory', action='store_true',
|
||||||
|
help='Enable HW inventory (CPU, Memory, RAID Cards, Disks) feature')
|
||||||
|
|
||||||
|
options = p.parse_args()
|
||||||
|
return options
|
||||||
|
|
||||||
|
|
||||||
|
def get_netbox_instance():
|
||||||
|
config = get_config()
|
||||||
|
if config.netbox.url is None or config.netbox.token is None:
|
||||||
|
logging.error('Netbox URL and token are mandatory')
|
||||||
|
sys.exit(1)
|
||||||
|
return pynetbox.api(
|
||||||
|
url=get_config().netbox.url,
|
||||||
|
token=get_config().netbox.token,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
config = get_config()
|
||||||
|
netbox_instance = get_netbox_instance()
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import re as _re
|
import re as _re
|
||||||
import subprocess as _subprocess
|
import subprocess as _subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from netbox_agent.misc import is_tool
|
||||||
|
import logging
|
||||||
|
|
||||||
_handle_re = _re.compile('^Handle\\s+(.+),\\s+DMI\\s+type\\s+(\\d+),\\s+(\\d+)\\s+bytes$')
|
_handle_re = _re.compile('^Handle\\s+(.+),\\s+DMI\\s+type\\s+(\\d+),\\s+(\\d+)\\s+bytes$')
|
||||||
_in_block_re = _re.compile('^\\t\\t(.+)$')
|
_in_block_re = _re.compile('^\\t\\t(.+)$')
|
||||||
|
@ -131,6 +134,10 @@ def get_by_type(type_id):
|
||||||
|
|
||||||
|
|
||||||
def _execute_cmd():
|
def _execute_cmd():
|
||||||
|
if not is_tool('dmidecode'):
|
||||||
|
logging.error('Dmidecode does not seem to be present on your system. Add it your path or '
|
||||||
|
'check the compatibility of this project with your distro.')
|
||||||
|
sys.exit(1)
|
||||||
return _subprocess.check_output(['dmidecode', ], stderr=_subprocess.PIPE)
|
return _subprocess.check_output(['dmidecode', ], stderr=_subprocess.PIPE)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from netbox_agent.config import netbox_instance as nb, INVENTORY_ENABLED
|
from netbox_agent.config import netbox_instance as nb, config
|
||||||
from netbox_agent.misc import is_tool
|
from netbox_agent.misc import is_tool
|
||||||
from netbox_agent.raid.hp import HPRaid
|
from netbox_agent.raid.hp import HPRaid
|
||||||
from netbox_agent.raid.storcli import StorcliRaid
|
from netbox_agent.raid.storcli import StorcliRaid
|
||||||
|
@ -14,17 +14,6 @@ INVENTORY_TAG = {
|
||||||
'raid_card': {'name': 'hw:raid_card', 'slug': 'hw-raid-card'},
|
'raid_card': {'name': 'hw:raid_card', 'slug': 'hw-raid-card'},
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, tag in INVENTORY_TAG.items():
|
|
||||||
nb_tag = nb.extras.tags.get(
|
|
||||||
name=tag['name']
|
|
||||||
)
|
|
||||||
if not nb_tag:
|
|
||||||
nb_tag = nb.extras.tags.create(
|
|
||||||
name=tag['name'],
|
|
||||||
slug=tag['slug'],
|
|
||||||
comments=tag['name'],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Inventory():
|
class Inventory():
|
||||||
"""
|
"""
|
||||||
|
@ -50,11 +39,25 @@ class Inventory():
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, server):
|
def __init__(self, server):
|
||||||
|
self.create_netbox_tags()
|
||||||
self.server = server
|
self.server = server
|
||||||
self.device_id = self.server.get_netbox_server().id
|
netbox_server = self.server.get_netbox_server()
|
||||||
|
self.device_id = netbox_server.id if netbox_server else None
|
||||||
self.raid = None
|
self.raid = None
|
||||||
self.disks = []
|
self.disks = []
|
||||||
|
|
||||||
|
def create_netbox_tags():
|
||||||
|
for key, tag in INVENTORY_TAG.items():
|
||||||
|
nb_tag = nb.extras.tags.get(
|
||||||
|
name=tag['name']
|
||||||
|
)
|
||||||
|
if not nb_tag:
|
||||||
|
nb_tag = nb.extras.tags.create(
|
||||||
|
name=tag['name'],
|
||||||
|
slug=tag['slug'],
|
||||||
|
comments=tag['name'],
|
||||||
|
)
|
||||||
|
|
||||||
def get_cpus(self):
|
def get_cpus(self):
|
||||||
model = None
|
model = None
|
||||||
nb = None
|
nb = None
|
||||||
|
@ -310,7 +313,7 @@ class Inventory():
|
||||||
self.create_netbox_memory(memory)
|
self.create_netbox_memory(memory)
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
if not INVENTORY_ENABLED:
|
if config.inventory is None:
|
||||||
return False
|
return False
|
||||||
self.create_netbox_cpus()
|
self.create_netbox_cpus()
|
||||||
self.create_netbox_memory()
|
self.create_netbox_memory()
|
||||||
|
@ -319,7 +322,7 @@ class Inventory():
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
if not INVENTORY_ENABLED:
|
if config.inventory is None or config.update_inventory is None:
|
||||||
return False
|
return False
|
||||||
self.update_netbox_cpus()
|
self.update_netbox_cpus()
|
||||||
self.update_netbox_memory()
|
self.update_netbox_memory()
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import importlib
|
import importlib
|
||||||
import importlib.machinery
|
import importlib.machinery
|
||||||
|
|
||||||
from netbox_agent.config import DATACENTER_LOCATION, DATACENTER_LOCATION_DRIVER_FILE, \
|
from netbox_agent.config import config
|
||||||
DATACENTER_LOCATION_REGEX, RACK_LOCATION, RACK_LOCATION_DRIVER_FILE, RACK_LOCATION_REGEX, \
|
|
||||||
SLOT_LOCATION, SLOT_LOCATION_DRIVER_FILE, SLOT_LOCATION_REGEX
|
|
||||||
|
|
||||||
|
|
||||||
class LocationBase():
|
class LocationBase():
|
||||||
|
@ -53,27 +51,32 @@ class LocationBase():
|
||||||
|
|
||||||
class Datacenter(LocationBase):
|
class Datacenter(LocationBase):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
driver = DATACENTER_LOCATION.split(':')[0] if DATACENTER_LOCATION else None
|
driver = config.datacenter_location.driver.split(':')[0] if \
|
||||||
driver_value = ':'.join(DATACENTER_LOCATION.split(':')[1:]) if DATACENTER_LOCATION \
|
config.datacenter_location.driver else None
|
||||||
else None
|
driver_value = ':'.join(config.datacenter_location.driver.split(':')[1:]) if \
|
||||||
driver_file = DATACENTER_LOCATION_DRIVER_FILE
|
config.datacenter_location.driver else None
|
||||||
regex = DATACENTER_LOCATION_REGEX
|
driver_file = config.datacenter_location.driver_file
|
||||||
|
regex = config.datacenter_location.regex
|
||||||
super().__init__(driver, driver_value, driver_file, regex)
|
super().__init__(driver, driver_value, driver_file, regex)
|
||||||
|
|
||||||
|
|
||||||
class Rack(LocationBase):
|
class Rack(LocationBase):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
driver = RACK_LOCATION.split(':')[0] if RACK_LOCATION else None
|
driver = config.rack_location.driver.split(':')[0] if \
|
||||||
driver_value = ':'.join(RACK_LOCATION.split(':')[1:]) if RACK_LOCATION else None
|
config.rack_location.driver else None
|
||||||
driver_file = RACK_LOCATION_DRIVER_FILE
|
driver_value = ':'.join(config.rack_location.driver.split(':')[1:]) if \
|
||||||
regex = RACK_LOCATION_REGEX
|
config.rack_location.driver else None
|
||||||
|
driver_file = config.rack_location.driver_file
|
||||||
|
regex = config.rack_location.regex
|
||||||
super().__init__(driver, driver_value, driver_file, regex)
|
super().__init__(driver, driver_value, driver_file, regex)
|
||||||
|
|
||||||
|
|
||||||
class Slot(LocationBase):
|
class Slot(LocationBase):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
driver = SLOT_LOCATION.split(':')[0] if SLOT_LOCATION else None
|
driver = config.slot_location.driver.split(':')[0] if \
|
||||||
driver_value = ':'.join(SLOT_LOCATION.split(':')[1:]) if SLOT_LOCATION else None
|
config.slot_location.driver else None
|
||||||
driver_file = SLOT_LOCATION_DRIVER_FILE
|
driver_value = ':'.join(config.slot_location.driver.split(':')[1:]) if \
|
||||||
regex = SLOT_LOCATION_REGEX
|
config.slot_location.driver else None
|
||||||
|
driver_file = config.slot_location.driver_file
|
||||||
|
regex = config.slot_location.regex
|
||||||
super().__init__(driver, driver_value, driver_file, regex)
|
super().__init__(driver, driver_value, driver_file, regex)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from netbox_agent.config import LOG_LEVEL
|
from netbox_agent.config import config
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
if LOG_LEVEL == 'debug':
|
if config.log_level == 'debug':
|
||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
else:
|
else:
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
|
|
|
@ -6,8 +6,7 @@ import re
|
||||||
from netaddr import IPAddress, IPNetwork
|
from netaddr import IPAddress, IPNetwork
|
||||||
import netifaces
|
import netifaces
|
||||||
|
|
||||||
from netbox_agent.config import netbox_instance as nb
|
from netbox_agent.config import netbox_instance as nb, config
|
||||||
from netbox_agent.config import NETWORK_IGNORE_INTERFACES, NETWORK_IGNORE_IPS, NETWORK_LLDP
|
|
||||||
from netbox_agent.ethtool import Ethtool
|
from netbox_agent.ethtool import Ethtool
|
||||||
from netbox_agent.ipmi import IPMI
|
from netbox_agent.ipmi import IPMI
|
||||||
from netbox_agent.lldp import LLDP
|
from netbox_agent.lldp import LLDP
|
||||||
|
@ -56,8 +55,8 @@ class Network():
|
||||||
if not os.path.islink('/sys/class/net/{}'.format(interface)):
|
if not os.path.islink('/sys/class/net/{}'.format(interface)):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if NETWORK_IGNORE_INTERFACES and \
|
if config.network.ignore_interfaces and \
|
||||||
re.match(NETWORK_IGNORE_INTERFACES, interface):
|
re.match(config.network.ignore_interfaces, interface):
|
||||||
logging.debug('Ignore interface {interface}'.format(interface=interface))
|
logging.debug('Ignore interface {interface}'.format(interface=interface))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -84,9 +83,9 @@ class Network():
|
||||||
addr["netmask"] = addr["netmask"].split('/')[0]
|
addr["netmask"] = addr["netmask"].split('/')[0]
|
||||||
ip_addr.append(addr)
|
ip_addr.append(addr)
|
||||||
|
|
||||||
if NETWORK_IGNORE_IPS and ip_addr:
|
if config.network.ignore_ips and ip_addr:
|
||||||
for i, ip in enumerate(ip_addr):
|
for i, ip in enumerate(ip_addr):
|
||||||
if re.match(NETWORK_IGNORE_IPS, ip['addr']):
|
if re.match(config.network.ignore_ips, ip['addr']):
|
||||||
ip_addr.pop(i)
|
ip_addr.pop(i)
|
||||||
|
|
||||||
mac = open('/sys/class/net/{}/address'.format(interface), 'r').read().strip()
|
mac = open('/sys/class/net/{}/address'.format(interface), 'r').read().strip()
|
||||||
|
@ -202,7 +201,7 @@ class Network():
|
||||||
def reset_vlan_on_interface(self, nic, interface):
|
def reset_vlan_on_interface(self, nic, interface):
|
||||||
update = False
|
update = False
|
||||||
vlan_id = nic['vlan']
|
vlan_id = nic['vlan']
|
||||||
lldp_vlan = self.lldp.get_switch_vlan(nic['name']) if NETWORK_LLDP else None
|
lldp_vlan = self.lldp.get_switch_vlan(nic['name']) if config.network.lldp else None
|
||||||
|
|
||||||
# if local interface isn't a interface vlan or lldp doesn't report a vlan-id
|
# if local interface isn't a interface vlan or lldp doesn't report a vlan-id
|
||||||
if vlan_id is None and lldp_vlan is None and \
|
if vlan_id is None and lldp_vlan is None and \
|
||||||
|
@ -294,7 +293,7 @@ class Network():
|
||||||
interface.mode = 200
|
interface.mode = 200
|
||||||
interface.tagged_vlans = [nb_vlan.id]
|
interface.tagged_vlans = [nb_vlan.id]
|
||||||
interface.save()
|
interface.save()
|
||||||
elif NETWORK_LLDP and self.lldp.get_switch_vlan(nic['name']) is not None:
|
elif config.network.lldp and self.lldp.get_switch_vlan(nic['name']) is not None:
|
||||||
# if lldp reports a vlan on an interface, tag the interface in access and set the vlan
|
# if lldp reports a vlan on an interface, tag the interface in access and set the vlan
|
||||||
vlan_id = self.lldp.get_switch_vlan(nic['name'])
|
vlan_id = self.lldp.get_switch_vlan(nic['name'])
|
||||||
nb_vlan = self.get_or_create_vlan(vlan_id)
|
nb_vlan = self.get_or_create_vlan(vlan_id)
|
||||||
|
@ -303,7 +302,7 @@ class Network():
|
||||||
interface.save()
|
interface.save()
|
||||||
|
|
||||||
# cable the interface
|
# cable the interface
|
||||||
if NETWORK_LLDP:
|
if config.network.lldp:
|
||||||
switch_ip = self.lldp.get_switch_ip(interface.name)
|
switch_ip = self.lldp.get_switch_ip(interface.name)
|
||||||
switch_interface = self.lldp.get_switch_port(interface.name)
|
switch_interface = self.lldp.get_switch_port(interface.name)
|
||||||
|
|
||||||
|
@ -503,6 +502,9 @@ class Network():
|
||||||
logging.debug('Finished creating NIC!')
|
logging.debug('Finished creating NIC!')
|
||||||
|
|
||||||
def update_netbox_network_cards(self):
|
def update_netbox_network_cards(self):
|
||||||
|
if config.update_all is None or config.update_network is None:
|
||||||
|
print(config)
|
||||||
|
return None
|
||||||
logging.debug('Updating NIC...')
|
logging.debug('Updating NIC...')
|
||||||
|
|
||||||
# delete unknown interface
|
# delete unknown interface
|
||||||
|
@ -566,7 +568,7 @@ class Network():
|
||||||
interface.lag = None
|
interface.lag = None
|
||||||
|
|
||||||
# cable the interface
|
# cable the interface
|
||||||
if NETWORK_LLDP:
|
if config.network.lldp:
|
||||||
switch_ip = self.lldp.get_switch_ip(interface.name)
|
switch_ip = self.lldp.get_switch_ip(interface.name)
|
||||||
switch_interface = self.lldp.get_switch_port(interface.name)
|
switch_interface = self.lldp.get_switch_port(interface.name)
|
||||||
if switch_ip and switch_interface:
|
if switch_ip and switch_interface:
|
||||||
|
|
|
@ -30,6 +30,33 @@ class ServerBase():
|
||||||
)
|
)
|
||||||
return datacenter
|
return datacenter
|
||||||
|
|
||||||
|
def update_netbox_location(self, server):
|
||||||
|
dc = self.get_datacenter()
|
||||||
|
rack = self.get_rack()
|
||||||
|
nb_rack = self.get_netbox_rack()
|
||||||
|
nb_dc = self.get_netbox_datacenter()
|
||||||
|
|
||||||
|
update = False
|
||||||
|
if dc and server.site.slug != nb_dc.slug:
|
||||||
|
logging.info('Datacenter location has changed from {} to {}, updating'.format(
|
||||||
|
server.site.slug,
|
||||||
|
nb_dc.slug,
|
||||||
|
))
|
||||||
|
update = True
|
||||||
|
server.site = nb_dc.id
|
||||||
|
|
||||||
|
if rack and server.rack != nb_rack:
|
||||||
|
logging.info('Rack location has changed from {} to {}, updating'.format(
|
||||||
|
server.rack,
|
||||||
|
nb_rack,
|
||||||
|
))
|
||||||
|
update = True
|
||||||
|
server.rack = nb_rack
|
||||||
|
if nb_rack is None:
|
||||||
|
server.face = None
|
||||||
|
server.position = None
|
||||||
|
return update, server
|
||||||
|
|
||||||
def get_rack(self):
|
def get_rack(self):
|
||||||
rack = Rack()
|
rack = Rack()
|
||||||
return rack.get()
|
return rack.get()
|
||||||
|
@ -175,7 +202,7 @@ class ServerBase():
|
||||||
def get_netbox_server(self):
|
def get_netbox_server(self):
|
||||||
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, config):
|
||||||
logging.debug('Creating Server..')
|
logging.debug('Creating Server..')
|
||||||
datacenter = self.get_netbox_datacenter()
|
datacenter = self.get_netbox_datacenter()
|
||||||
rack = self.get_netbox_rack()
|
rack = self.get_netbox_rack()
|
||||||
|
@ -205,8 +232,9 @@ class ServerBase():
|
||||||
|
|
||||||
self.network = Network(server=self)
|
self.network = Network(server=self)
|
||||||
self.network.create_netbox_network_cards()
|
self.network.create_netbox_network_cards()
|
||||||
self.inventory = Inventory(server=self)
|
if config.inventory:
|
||||||
self.inventory.create()
|
self.inventory = Inventory(server=self)
|
||||||
|
self.inventory.create()
|
||||||
logging.debug('Server created!')
|
logging.debug('Server created!')
|
||||||
|
|
||||||
def _netbox_update_chassis_for_blade(self, server, datacenter):
|
def _netbox_update_chassis_for_blade(self, server, datacenter):
|
||||||
|
@ -235,7 +263,7 @@ class ServerBase():
|
||||||
# Set slot for blade
|
# Set slot for blade
|
||||||
self._netbox_set_blade_slot(chassis, server)
|
self._netbox_set_blade_slot(chassis, server)
|
||||||
|
|
||||||
def netbox_update(self):
|
def netbox_update(self, config):
|
||||||
"""
|
"""
|
||||||
Netbox method to update info about our server/blade
|
Netbox method to update info about our server/blade
|
||||||
|
|
||||||
|
@ -246,11 +274,12 @@ class ServerBase():
|
||||||
* new network infos
|
* new network infos
|
||||||
"""
|
"""
|
||||||
logging.debug('Updating Server...')
|
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"
|
||||||
'it before updating it'.format(self.get_service_tag()))
|
'it before updating it'.format(self.get_service_tag()))
|
||||||
update = False
|
update = 0
|
||||||
if self.is_blade():
|
if self.is_blade():
|
||||||
datacenter = self.get_netbox_datacenter()
|
datacenter = self.get_netbox_datacenter()
|
||||||
# if it's already linked to a chassis
|
# if it's already linked to a chassis
|
||||||
|
@ -269,14 +298,21 @@ class ServerBase():
|
||||||
# for every other specs
|
# for every other specs
|
||||||
# check hostname
|
# check hostname
|
||||||
if server.name != self.get_hostname():
|
if server.name != self.get_hostname():
|
||||||
update = True
|
update += 1
|
||||||
server.hostname = self.get_hostname()
|
server.hostname = self.get_hostname()
|
||||||
|
|
||||||
|
if config.update_all or config.update_location:
|
||||||
|
ret, server = self.update_netbox_location(server)
|
||||||
|
update += ret
|
||||||
|
|
||||||
# check network cards
|
# check network cards
|
||||||
self.network = Network(server=self)
|
if config.update_all or config.update_network:
|
||||||
self.network.update_netbox_network_cards()
|
self.network = Network(server=self)
|
||||||
|
self.network.update_netbox_network_cards()
|
||||||
# update inventory
|
# update inventory
|
||||||
self.inventory = Inventory(server=self)
|
if config.update_all or config.update_inventory:
|
||||||
self.inventory.update()
|
self.inventory = Inventory(server=self)
|
||||||
|
self.inventory.update()
|
||||||
if update:
|
if update:
|
||||||
server.save()
|
server.save()
|
||||||
logging.debug('Finished updating Server!')
|
logging.debug('Finished updating Server!')
|
||||||
|
|
|
@ -2,3 +2,4 @@ pynetbox==4.0.6
|
||||||
netaddr==0.7.19
|
netaddr==0.7.19
|
||||||
netifaces==0.10.9
|
netifaces==0.10.9
|
||||||
pyyaml==5.1.2
|
pyyaml==5.1.2
|
||||||
|
jsonargparse==2.2.1
|
||||||
|
|
Loading…
Add table
Reference in a new issue