Add GPU inventory support (#164)

* Add GPU support

* Some update in the doc
This commit is contained in:
Cyrinux 2020-09-18 12:29:05 +02:00 committed by GitHub
parent 28955612be
commit 0fe17c9687
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 1 deletions

View file

@ -13,8 +13,9 @@ The goal is to generate an existing infrastructure on Netbox and have the abilit
* Generic ability to guess datacenters and rack location through drivers (`cmd` and `file` and custom ones) * Generic ability to guess datacenters and rack location through drivers (`cmd` and `file` and custom ones)
* Update existing `Device` and `Interface` * Update existing `Device` and `Interface`
* Handle blade moving (new slot, new chassis) * Handle blade moving (new slot, new chassis)
* Handle blade GPU expansions
* Automatic cabling (server's interface to switch's interface) using lldp * Automatic cabling (server's interface to switch's interface) using lldp
* Local inventory using `Inventory Item` for CPU, RAM, RAID cards, physical disks (behind raid cards) * Local inventory using `Inventory Item` for CPU, GPU, RAM, RAID cards, physical disks (behind raid cards)
* PSUs creation and power consumption reporting (based on vendor's tools) * PSUs creation and power consumption reporting (based on vendor's tools)
# Requirements # Requirements

View file

@ -13,6 +13,7 @@ from netbox_agent.raid.storcli import StorcliRaid
INVENTORY_TAG = { INVENTORY_TAG = {
'cpu': {'name': 'hw:cpu', 'slug': 'hw-cpu'}, 'cpu': {'name': 'hw:cpu', 'slug': 'hw-cpu'},
'gpu': {'name': 'hw:gpu', 'slug': 'hw-gpu'},
'disk': {'name': 'hw:disk', 'slug': 'hw-disk'}, 'disk': {'name': 'hw:disk', 'slug': 'hw-disk'},
'interface': {'name': 'hw:interface', 'slug': 'hw-interface'}, 'interface': {'name': 'hw:interface', 'slug': 'hw-interface'},
'memory': {'name': 'hw:memory', 'slug': 'hw-memory'}, 'memory': {'name': 'hw:memory', 'slug': 'hw-memory'},
@ -32,6 +33,7 @@ class Inventory():
* cpu * cpu
* raid cards * raid cards
* disks * disks
* gpus
methods that: methods that:
* get local item * get local item
@ -438,6 +440,34 @@ class Inventory():
if memory.get('serial') not in [x.serial for x in nb_memories]: if memory.get('serial') not in [x.serial for x in nb_memories]:
self.create_netbox_memory(memory) self.create_netbox_memory(memory)
def create_netbox_gpus(self):
for gpu in self.lshw.get_hw_linux('gpu'):
manufacturer = self.find_or_create_manufacturer(gpu["vendor"])
_ = nb.dcim.inventory_items.create(
device=self.device_id,
manufacturer=manufacturer.id,
discovered=True,
tags=[INVENTORY_TAG['gpu']['name']],
name=gpu['product'],
description='GPU {}'.format(gpu['product']),
)
logging.info('Creating GPU model {}'.format(gpu['product']))
def do_netbox_gpus(self):
gpus = self.lshw.get_hw_linux('gpu')
nb_gpus = self.get_netbox_inventory(
device_id=self.device_id,
tag=INVENTORY_TAG['gpu']['slug'],
)
if not len(nb_gpus) or \
len(nb_gpus) and len(gpus) != len(nb_gpus):
for x in nb_gpus:
x.delete()
self.create_netbox_gpus()
def create_or_update(self): def create_or_update(self):
if config.inventory is None or config.update_inventory is None: if config.inventory is None or config.update_inventory is None:
return False return False
@ -447,4 +477,5 @@ class Inventory():
self.do_netbox_disks() self.do_netbox_disks()
self.do_netbox_interfaces() self.do_netbox_interfaces()
self.do_netbox_motherboard() self.do_netbox_motherboard()
self.do_netbox_gpus()
return True return True

View file

@ -22,6 +22,7 @@ class LSHW():
self.cpus = [] self.cpus = []
self.power = [] self.power = []
self.disks = [] self.disks = []
self.gpus = []
self.vendor = self.hw_info["vendor"] self.vendor = self.hw_info["vendor"]
self.product = self.hw_info["product"] self.product = self.hw_info["product"]
self.chassis_serial = self.hw_info["serial"] self.chassis_serial = self.hw_info["serial"]
@ -53,6 +54,8 @@ class LSHW():
def get_hw_linux(self, hwclass): def get_hw_linux(self, hwclass):
if hwclass == "cpu": if hwclass == "cpu":
return self.cpus return self.cpus
if hwclass == "gpu":
return self.gpus
if hwclass == "network": if hwclass == "network":
return self.interfaces return self.interfaces
if hwclass == 'storage': if hwclass == 'storage':
@ -132,6 +135,15 @@ class LSHW():
self.memories.append(d) self.memories.append(d)
def find_gpus(self, obj):
if "product" in obj:
c = {}
c["product"] = obj["product"]
c["vendor"] = obj["vendor"]
c["description"] = obj["description"]
self.gpus.append(c)
def walk_bridge(self, obj): def walk_bridge(self, obj):
if "children" not in obj: if "children" not in obj:
return return
@ -139,6 +151,8 @@ class LSHW():
for bus in obj["children"]: for bus in obj["children"]:
if bus["class"] == "storage": if bus["class"] == "storage":
self.find_storage(bus) self.find_storage(bus)
if bus["class"] == "display":
self.find_gpus(bus)
if "children" in bus: if "children" in bus:
for b in bus["children"]: for b in bus["children"]:
@ -146,6 +160,8 @@ class LSHW():
self.find_storage(b) self.find_storage(b)
if b["class"] == "network": if b["class"] == "network":
self.find_network(b) self.find_network(b)
if b["class"] == "display":
self.find_gpus(b)
if __name__ == "__main__": if __name__ == "__main__":