from netbox_proxmox_sync.api.config import NB_API from netbox_proxmox_sync.api.utils.errors import ValidationError from netbox_proxmox_sync.api.proxmox.extract import Proxmox from netbox_proxmox_sync.api.netbox.extract import NetBox # MERGE, get created_*, updated_*, deleted_* def tags(): proxmox_tags = Proxmox.fetch_tags() netbox_tags = NetBox.fetch_tags() px_tags = {tag['name']: tag for tag in proxmox_tags} nb_tags = {tag['name']: tag for tag in netbox_tags} # "merge" information, extract stuff to C/U/D created = [tag for tag in proxmox_tags if tag['name'] not in nb_tags] deleted = [tag for tag in netbox_tags if tag['name'] not in px_tags] updated = [] for name in px_tags: # only thing that can really change for tags is their color if name in nb_tags and px_tags[name]['color'] != nb_tags[name]['color']: nb_tags[name]['color'] = px_tags[name]['color'] updated.append(nb_tags[name]) # FIXME: error handling NB_API.extras.tags.delete([d['id'] for d in deleted]) NB_API.extras.tags.update(updated) NB_API.extras.tags.create(created) return created, updated, deleted # TODO: allow for updates of custom fields in case the plugin is updated to use more # def custom_fields(): def vms(proxmox_vms, netbox_vms): px_vms = {vm['custom_fields']['vmid']: vm for vm in proxmox_vms} nb_vms = {vm['custom_fields']['vmid']: vm for vm in netbox_vms} # "merge" information, extract stuff to C/U/D created = [vm for vm in proxmox_vms if vm['custom_fields']['vmid'] not in nb_vms] deleted = [vm for vm in netbox_vms if vm['custom_fields']['vmid'] not in px_vms] updated = [] for name in px_vms: changed = False px_vm = px_vms[name] if nb_vms.get(name) is None: continue nb_vm = nb_vms[name] # Update all fields for field in px_vm: if px_vm.get(field) is not None: changed |= nb_vm[field] != px_vm[field] nb_vm[field] = px_vm[field] if changed: updated.append(nb_vm) return created, updated, deleted def interfaces(proxmox_interfaces, netbox_interfaces): # Note: if the MAC changes the IP for the VM is lost :) px_interfaces = {i['mac_address']: i for i in proxmox_interfaces} nb_interfaces = {i['mac_address']: i for i in netbox_interfaces} created = [i for i in proxmox_interfaces if i['mac_address'] not in nb_interfaces] deleted = [i for i in netbox_interfaces if i['mac_address'] not in px_interfaces] updated = [] for name in px_interfaces: changed = False # Update all fields px_interface = px_interfaces[name] if nb_interfaces.get(name) is None: continue nb_interface = nb_interfaces[name] for field in px_interface: changed |= nb_interface[field] != px_interface[field] nb_interface[field] = px_interface[field] if changed: updated.append(nb_interface) return created, updated, deleted def vms_and_interfaces(cluster_id): proxmox_vms, proxmox_interfaces = Proxmox.fetch_virtual_machines_and_interfaces() netbox_vms, netbox_interfaces = NetBox.fetch_virtual_machines_and_interfaces(cluster_id) created_vms, updated_vms, deleted_vms = vms(proxmox_vms, netbox_vms) created_i, updated_i, deleted_i = interfaces(proxmox_interfaces, netbox_interfaces) # FIXME: error handling NB_API.virtualization.virtual_machines.delete([d['id'] for d in deleted_vms]) NB_API.virtualization.virtual_machines.update(updated_vms) NB_API.virtualization.virtual_machines.create(created_vms) # NB_API.virtualization.interfaces.delete([d['id'] for d in deleted]) NB_API.virtualization.interfaces.update(updated_i) NB_API.virtualization.interfaces.create(created_i) return created_vms, updated_vms, deleted_vms, \ created_i, updated_i, deleted_i def all(): proxmox_cluster = Proxmox.fetch_cluster() cluster_name = proxmox_cluster['name'] clusters = list(NB_API.virtualization.clusters.filter(name=cluster_name)) if (len(clusters)) == 0: raise ValidationError(f'Cluster "{cluster_name}" does not exist!') netbox_cluster = clusters[0] created_tags, updated_tags, deleted_tags = tags() created_vms, updated_vms, deleted_vms, \ created_interfaces, updated_interfaces, deleted_interfaces = \ vms_and_interfaces(cluster_id=netbox_cluster.id) return { 'tags': { 'created': created_tags, 'updated': updated_tags, 'deleted': deleted_tags, }, 'virtual_machines': { 'created': created_vms, 'updated': updated_vms, 'deleted': deleted_vms, }, 'interfaces': { 'created': created_interfaces, 'updated': updated_interfaces, 'deleted': deleted_interfaces, } }