Select Git revision
-
fmkiotheka authoredfmkiotheka authored
models.py 5.46 KiB
from netbox_proxmox_sync.api.config import (
NETBOX_DEFAULT_TAG_COLOR,
NETBOX_VM_ROLE_ID,
)
# Classes to ensure NetBox and Proxmox data have the exact same format and fields,
# which makes updating stuff correctly easier
class VirtualMachine:
def __init__(self, vmid, name, status, node_name, cluster_name, vcpus, maxmem,
role_id, tags=[], maxdisk=None, description=None, id=None):
self.vmid = vmid
self.name = name
self.status = status
self.node_name = node_name
self.cluster_name = cluster_name
self.role_id = role_id
self.vcpus = vcpus
self.maxmem = maxmem
self.tags = sorted(tags)
self.maxdisk = maxdisk
self.description = description
self.id = id
def to_dict(self):
# Trust me, it's important that they're sorted
vm_data = {
'name': self.name,
'status': self.status,
'device': {'name': self.node_name},
'cluster': {'name': self.cluster_name},
'vcpus': self.vcpus,
'memory': self.maxmem,
'role': self.role_id,
'tags': [{'name': tag} for tag in self.tags],
'custom_fields': {'vmid': self.vmid}
}
# Both these fields may be None, so we have to set them separately
if self.maxdisk is not None and self.maxdisk > 0:
vm_data['disk'] = int(self.maxdisk)
if self.description is not None:
# NetBox only allows 200 char description, but our VMs have more
# so we store the description in the "comments" instead
vm_data['comments'] = self.description
if self.id is not None:
vm_data['id'] = self.id
return vm_data
class VirtualInterface:
def __init__(self, name, vm_name, mac_address, vlan_id, id=None):
self.name = name
self.vm_name = vm_name
self.mac_address = mac_address
self.vlan_id = vlan_id
self.id = id
def to_dict(self):
interface = {
'name': self.name,
'virtual_machine': {'name': self.vm_name},
'mac_address': self.mac_address,
'mode': 'access',
'untagged_vlan': {'vid': self.vlan_id},
# 'bridge': bridge
}
if self.id is not None:
interface['id'] = self.id
return interface
class VirtualMachineTag:
def __init__(self, name, id=None, color=NETBOX_DEFAULT_TAG_COLOR):
self.name = name
self.slug = name.lower().replace(' ', '-').replace('.', '_')
self.color = color
self.id = id
def to_dict(self):
vm_tag = {
'name': self.name,
'slug': self.slug,
'color': self.color,
'object_types': ['virtualization.virtualmachine'],
}
if self.id is not None:
vm_tag['id'] = self.id
return vm_tag
def tag_from_netbox(netbox_tag):
return VirtualMachineTag(
id=netbox_tag['id'],
name=netbox_tag['name'],
# slug=netbox_tag.slug,
color=netbox_tag['color'],
).to_dict()
def vm_from_netbox(netbox_vm):
return VirtualMachine(
id=netbox_vm['id'],
vmid=netbox_vm['custom_fields']['vmid'],
name=netbox_vm['name'],
status=netbox_vm['status']['value'],
# FIXME: some of these are tricky
node_name=netbox_vm['device']['name'] if netbox_vm['device'] else None,
cluster_name=netbox_vm['cluster']['name'] if netbox_vm['device'] else None,
role_id=netbox_vm['role']['id'] if netbox_vm['role'] else None,
vcpus=netbox_vm['vcpus'],
maxmem=netbox_vm['memory'],
tags=[tag['name'] for tag in netbox_vm['tags']],
maxdisk=netbox_vm.get('disk'),
description=netbox_vm.get('comments'),
).to_dict()
def interface_from_netbox(netbox_interface):
return VirtualInterface(
id=netbox_interface['id'],
name=netbox_interface['name'],
vm_name=netbox_interface['virtual_machine']['name'],
mac_address=netbox_interface['mac_address'].upper(),
vlan_id=netbox_interface['untagged_vlan']['vid'] if netbox_interface['untagged_vlan'] else None,
).to_dict()
def tag_from_proxmox(tag_name, color=NETBOX_DEFAULT_TAG_COLOR):
return VirtualMachineTag(
tag_name,
color,
).to_dict()
def vm_from_proxmox(cluster_name, proxmox_node_name, proxmox_vm, tags=[]):
maxdisk = proxmox_vm.get('maxdisk')
if maxdisk is not None:
maxdisk = int(maxdisk) / 2 ** 20 # B -> MB
memory = int(proxmox_vm['maxmem']) / 2**20 # B -> MB
return VirtualMachine(
vmid=proxmox_vm['vmid'],
name=proxmox_vm['name'],
status='active' if proxmox_vm['status'] == 'running' else 'offline',
node_name=proxmox_node_name,
cluster_name=cluster_name,
vcpus=proxmox_vm['cpus'],
role_id=NETBOX_VM_ROLE_ID,
maxmem=memory,
tags=tags,
maxdisk=maxdisk,
description=proxmox_vm.get('description'),
).to_dict()
def interface_from_proxmox(proxmox_vm_name, interface_name, proxmox_interface):
# net[0-9]+: 'virtio=00:00:00:00:00:00,bridge=vmbr<VID>'
mac = proxmox_interface.split('virtio=')[1].split(',')[0]
vlan_id = int(proxmox_interface.split('bridge=vmbr')[1].split(',firewall')[0])
return VirtualInterface(
name=f'{proxmox_vm_name}:{interface_name}',
vm_name=proxmox_vm_name,
mac_address=mac.upper(),
vlan_id=vlan_id,
).to_dict()