diff --git a/netbox_awx_plugin/signals.py b/netbox_awx_plugin/signals.py index 90a3ddc591898164df0fee1920b70ff0d54e8f77..71e597fec08e0d033bb460fc513e9cc304a3c95f 100644 --- a/netbox_awx_plugin/signals.py +++ b/netbox_awx_plugin/signals.py @@ -3,6 +3,7 @@ from django.dispatch import receiver from django_rq import get_queue from dcim.models import Interface, Device, DeviceRole, DeviceType, Site from ipam.models import Prefix +from virtualization.models import VirtualMachine from netbox.config import get_config from netbox.constants import RQ_QUEUE_DEFAULT from .models import AWXInventory @@ -54,6 +55,7 @@ def save_group_instance(sender, instance, **kwargs): @receiver(post_save, sender=Device) +@receiver(post_save, sender=VirtualMachine) def save_device(sender, instance, created, **kwargs): device = sender.objects.get(id=instance.id) if not device.primary_ip4 is None and device.primary_ip4.dns_name: diff --git a/netbox_awx_plugin/synchronization.py b/netbox_awx_plugin/synchronization.py index 685bbf03620906dd7e557badf165f90ad57d6108..e5114fdef8b5fbb8ab0b59bf0164f5a7082d9364 100644 --- a/netbox_awx_plugin/synchronization.py +++ b/netbox_awx_plugin/synchronization.py @@ -1,6 +1,8 @@ from dcim.models import Device, DeviceRole, DeviceType, Site from ipam.models import Prefix from dcim.choices import DeviceStatusChoices +from virtualization.choices import VirtualMachineStatusChoices +from virtualization.models import VirtualMachine from rest_framework import serializers import json import logging @@ -89,6 +91,39 @@ class DeviceSerializer(serializers.BaseSerializer): } +class VMInterfaceSerializer(serializers.BaseSerializer): + def to_representation(self, instance): + ip_addresses = [] + for ip in instance.ip_addresses.all(): + serializer = IPAddressSerializer(ip) + ip_addresses.append(serializer.data) + return { + "name": instance.name, + "mac": instance.mac_address, + "ip_addresses": ip_addresses + } + + +class VMSerializer(serializers.BaseSerializer): + def to_representation(self, instance): + variables = { + "netbox_virtualmachine_name": instance.name, + "netbox_virtualmachine_vcpus": float(instance.vcpus), + "netbox_virtualmachine_memory": instance.memory, + "netbox_virtualmachine_disk": instance.disk, + } + variables["netbox_interfaces"] = [] + for interface in instance.interfaces.all(): + serializer = VMInterfaceSerializer(interface) + variables["netbox_interfaces"].append(serializer.data) + return { + "name": instance.primary_ip4.dns_name, + "description": instance.description, + "enabled": instance.status == VirtualMachineStatusChoices.STATUS_ACTIVE, + "variables": json.dumps(variables), + } + + class AWXHostSerializer(serializers.BaseSerializer): def to_internal_value(self, data): return { @@ -113,6 +148,7 @@ serializers = { DeviceType: DeviceTypeSerializer, Prefix: PrefixSerializer, Device: DeviceSerializer, + VirtualMachine: VMSerializer, } @@ -127,9 +163,12 @@ def sync_host(inventory, sender, instance): if not host_serializer.is_valid() or host_serializer.validated_data != serializer.data: inventory.update_host(host["id"], serializer.data) - sync_host_group_association(inventory, host, DeviceRole, instance.device_role) - sync_host_group_association(inventory, host, DeviceType, instance.device_type) - sync_host_group_association(inventory, host, Site, instance.site) + if instance.site: + sync_host_group_association(inventory, host, Site, instance.site) + if instance.role: + sync_host_group_association(inventory, host, DeviceRole, instance.role) + if sender == Device: + sync_host_group_association(inventory, host, DeviceType, instance.device_type) # print(Prefix.objects.filter(prefix__net_contains_or_equals=device.primary_ip4.address)) @@ -188,4 +227,7 @@ def sync_all(job): for device in Device.objects.all(): if not device.primary_ip4 is None and device.primary_ip4.dns_name: sync_host(inventory, Device, device) + for vm in VirtualMachine.objects.all(): + if not vm.primary_ip4 is None and vm.primary_ip4.dns_name: + sync_host(inventory, VirtualMachine, vm) job.terminate()