158 lines
6.4 KiB
Python
158 lines
6.4 KiB
Python
import os
|
|
import sys
|
|
|
|
import pynetbox
|
|
from proxmoxer import ProxmoxAPI
|
|
from rich import print
|
|
|
|
|
|
def _parse_pve_network_definition(_raw_network_definition: str) -> dict:
|
|
_network_definition = {}
|
|
|
|
for _component in _raw_network_definition.split(','):
|
|
_component_parts = _component.split('=')
|
|
_network_definition[_component_parts[0]] = _component_parts[1]
|
|
|
|
return _network_definition
|
|
|
|
|
|
def main():
|
|
# Instantiate connection to the Proxmox VE API
|
|
pve_api = ProxmoxAPI(
|
|
host=os.environ['PVE_API_HOST'],
|
|
user=os.environ['PVE_API_USER'],
|
|
token_name=os.environ['PVE_API_TOKEN'],
|
|
token_value=os.environ['PVE_API_SECRET'],
|
|
verify_ssl=os.getenv('PVE_API_VERIFY_SSL', 'false').lower() == 'true',
|
|
)
|
|
|
|
# Instantiate connection to the Netbox API
|
|
nb_api = pynetbox.api(
|
|
url=os.environ['NB_API_URL'],
|
|
token=os.environ['NB_API_TOKEN'],
|
|
)
|
|
|
|
# Load NetBox devices
|
|
nb_devices = {}
|
|
for _nb_device in nb_api.dcim.devices.all():
|
|
nb_devices[_nb_device.name.lower()] = _nb_device
|
|
|
|
# Load NetBox virtual machines
|
|
nb_virtual_machines = {}
|
|
for _nb_virtual_machine in nb_api.virtualization.virtual_machines.all():
|
|
nb_virtual_machines[_nb_virtual_machine.serial] = _nb_virtual_machine
|
|
|
|
# Load NetBox interfaces
|
|
nb_virtual_machines_interfaces = {}
|
|
for _nb_interface in nb_api.virtualization.interfaces.all():
|
|
if _nb_interface.virtual_machine.id not in nb_virtual_machines_interfaces:
|
|
nb_virtual_machines_interfaces[_nb_interface.virtual_machine.id] = {}
|
|
|
|
nb_virtual_machines_interfaces[_nb_interface.virtual_machine.id][_nb_interface.name] = _nb_interface
|
|
|
|
# Load NetBox mac addresses
|
|
nb_mac_addresses = {}
|
|
for _nb_mac_address in nb_api.dcim.mac_addresses.all():
|
|
nb_mac_addresses[_nb_mac_address.mac_address] = _nb_mac_address
|
|
|
|
# Load NetBox IP addresses
|
|
nb_ip_addresses = {}
|
|
for _nb_ip_address in nb_api.ipam.ip_addresses.all():
|
|
nb_ip_addresses[_nb_ip_address['address']] = _nb_ip_address
|
|
|
|
# Process Proxmox nodes
|
|
for pve_node in pve_api.nodes.get():
|
|
# Process Proxmox virtual machines per node
|
|
for pve_virtual_machine in pve_api.nodes(pve_node["node"]).qemu.get():
|
|
pve_virtual_machine_config = pve_api.nodes(pve_node['node']).qemu(pve_virtual_machine['vmid']).config.get()
|
|
|
|
# This script does not create the hardware devices.
|
|
nb_device = nb_devices.get(pve_node['node'].lower())
|
|
if nb_device is None:
|
|
print(f'The device {pve_node["node"]} is not created on NetBox. Exiting.')
|
|
sys.exit(1)
|
|
else:
|
|
pass
|
|
|
|
# Create the virtual machine if it exists, update it otherwise
|
|
nb_virtual_machine = nb_virtual_machines.get(str(pve_virtual_machine['vmid']))
|
|
if nb_virtual_machine is None:
|
|
nb_virtual_machine = nb_api.virtualization.virtual_machines.create(
|
|
serial=pve_virtual_machine['vmid'],
|
|
name=pve_virtual_machine['name'],
|
|
site=nb_device.site.id,
|
|
cluster=1, # TODO
|
|
device=nb_device.id,
|
|
vcpus=pve_virtual_machine_config['cores'],
|
|
memory=int(pve_virtual_machine_config['memory']),
|
|
)
|
|
else:
|
|
nb_virtual_machine.name = pve_virtual_machine['name']
|
|
nb_virtual_machine.site = nb_device.site.id
|
|
nb_virtual_machine.cluster = 1
|
|
nb_virtual_machine.device = nb_device.id
|
|
nb_virtual_machine.vcpus = pve_virtual_machine_config['cores']
|
|
nb_virtual_machine.memory = int(pve_virtual_machine_config['memory'])
|
|
nb_virtual_machine.save()
|
|
|
|
# Handle the VM network interfaces
|
|
for (_config_key, _config_value) in pve_virtual_machine_config.items():
|
|
if not _config_key.startswith('net'):
|
|
continue
|
|
|
|
_network_definition = _parse_pve_network_definition(_config_value)
|
|
|
|
# Determinate MAC address
|
|
network_mac_address = None
|
|
for _model in ['virtio', 'e1000']:
|
|
if _model in _network_definition:
|
|
network_mac_address = _network_definition[_model]
|
|
break
|
|
|
|
if network_mac_address is None:
|
|
continue
|
|
|
|
nb_virtual_machines_interface = nb_virtual_machines_interfaces \
|
|
.get(nb_virtual_machine.id, {}) \
|
|
.get(_config_key)
|
|
|
|
if nb_virtual_machines_interface is None:
|
|
nb_virtual_machines_interface = nb_api.virtualization.interfaces.create(
|
|
virtual_machine=nb_virtual_machine.id,
|
|
name=_config_key,
|
|
description=network_mac_address,
|
|
)
|
|
|
|
if nb_virtual_machine.id not in nb_virtual_machines_interfaces:
|
|
nb_virtual_machines_interfaces[nb_virtual_machine.id] = {}
|
|
|
|
nb_virtual_machines_interfaces[nb_virtual_machine.id][_config_key] = nb_virtual_machines_interface
|
|
|
|
# Create the MAC address and link it to the VM
|
|
nb_mac_address = nb_mac_addresses.get(network_mac_address)
|
|
if nb_mac_address is None:
|
|
nb_mac_address = nb_api.dcim.mac_addresses.create(
|
|
mac_address=network_mac_address,
|
|
assigned_object_type='virtualization.vminterface',
|
|
assigned_object_id=nb_virtual_machines_interface.id,
|
|
)
|
|
|
|
nb_mac_addresses[network_mac_address] = nb_mac_address
|
|
|
|
nb_virtual_machines_interface.primary_mac_address = nb_mac_address.id
|
|
nb_virtual_machines_interface.save()
|
|
|
|
# TODO: Handle the disk
|
|
|
|
# Then create the disks if not exists, update them otherwise
|
|
# Then create the network interface if not exists, update them otherwise
|
|
# Link the network interface to the range if not exists
|
|
|
|
# print(pve_api.nodes(pve_node['node']).qemu(pve_virtual_machine['vmid']).config.get())
|
|
|
|
# if vm['status'] == 'running':
|
|
# print(pve_api.nodes(node['node']).qemu(vm['vmid']).agent('network-get-interfaces').get())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|