Data File

Source
Path
report.py
Last updated
2026-05-31 20:55:51
Size
19840 bytes
SHA256 hash
d9172936f3ead528e7bd0c7ae3ff26d0b453a3f12b996a9b5968a96c66f62dad

Content

from extras.scripts import Script
from extras.reports import Report

from dcim.models import Device
from virtualization.models import VirtualMachine

from dcim.choices import DeviceStatusChoices

class TenantReport(Script):
    class Meta:
        name = "Tenant Zuweisung prüfen"
        description = "Prüft, ob bei allen aktiven Devices und VMs ein Tenant gesetzt ist."

    def test_device_tenants(self):
        """Prüft alle aktiven Devices auf zugewiesene Tenants."""
        active_devices = Device.objects.filter(status="active")

        for device in active_devices:
            if device.device_type.is_child_device:
                self.log_success("Child Device übersprungen.", obj=device)
                continue

            if device.tenant_id is None:
                # In NetBox v4: Erst die Nachricht, dann obj=device für die URL-Spalte
                self.log_failure("Device hat keinen Tenant zugewiesen.", obj=device)
            else:
                self.log_success("Tenant zugewiesen.", obj=device)

    def test_vm_tenants(self):
        """Prüft alle aktiven virtuellen Maschinen auf zugewiesene Tenants."""
        active_vms = VirtualMachine.objects.filter(status="active")

        for vm in active_vms:
            if vm.tenant_id is None:
                # In NetBox v4: Erst die Nachricht, dann obj=vm für die URL-Spalte
                self.log_failure("Virtual Machine hat keinen Tenant zugewiesen.", obj=vm)
            else:
                self.log_success("Tenant zugewiesen.", obj=vm)

class DescriptionsReport(Script):
    class Meta:
        name = "Description prüfen"
        description = "Prüft, ob bei allen aktiven Devices und VMs eine Beschreibung angegeben ist."

    def test_device_descriptions(self):
        """Prüft alle aktiven Devices auf eine vorhandene Beschreibung."""
        active_devices = Device.objects.filter(status="active")
        for device in active_devices:
            if device.device_type.is_child_device:
                self.log_success("Child Device übersprungen.", obj=device)
                continue

            # strip() entfernt eventuelle Leerzeichen. Wenn das Feld leer ist, ist der String False.
            if not device.description or not device.description.strip():
                self.log_failure("Device Beschreibung ist leer.", obj=device)
            else:
                self.log_success("Beschreibung vorhanden.", obj=device)

    def test_vm_descriptions(self):
        """Prüft alle aktiven virtuellen Maschinen auf eine vorhandene Beschreibung."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            if not vm.description or not vm.description.strip():
                self.log_failure("Virtual Machine Beschreibung ist leer.", obj=vm)
            else:
                self.log_success("Beschreibung vorhanden.", obj=vm)

class RoleReport(Script):
    class Meta:
        name = "Rollen prüfen"
        description = "Prüft, ob bei allen aktiven Devices und VMs eine Role angegeben ist."

    def test_device_roles(self):
        """Prüft alle aktiven Devices auf eine zugewiesene Rolle."""
        active_devices = Device.objects.filter(status="active")
        for device in active_devices:
            if device.device_type.is_child_device:
                self.log_success("Child Device übersprungen.", obj=device)
                continue

            if device.role_id is None:
                self.log_failure("Device hat keine Rolle zugewiesen.", obj=device)
            else:
                self.log_success("Rolle zugewiesen.", obj=device)

    def test_vm_roles(self):
        """Prüft alle aktiven virtuellen Maschinen auf eine zugewiesene Rolle."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            if vm.role_id is None:
                self.log_failure("Virtual Machine hat keine Rolle zugewiesen.", obj=vm)
            else:
                self.log_success("Rolle zugewiesen.", obj=vm)

class SiteReport(Script):
    class Meta:
        name = "Site prüfen"
        description = "Prüft, ob eine Site angegeben ist."

    def test_device_sites(self):
        """Prüft alle aktiven Devices auf eine zugewiesene Site."""
        active_devices = Device.objects.filter(status="active")
        for device in active_devices:
            if device.device_type.is_child_device:
                self.log_success("Child Device übersprungen.", obj=device)
                continue

            if device.site_id is None:
                self.log_failure("Device hat keine Site zugewiesen.", obj=device)
            else:
                self.log_success("Site zugewiesen.", obj=device)

    def test_vm_sites(self):
        """Prüft alle aktiven virtuellen Maschinen auf eine zugewiesene Site."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            # NetBox v4 erlaubt direkte site_id an der VM. Falls leer, prüfen wir das Cluster.
            if vm.site_id is not None:
                self.log_success("Site direkt an VM zugewiesen.", obj=vm)
            elif vm.cluster and vm.cluster.site_id is not None:
                self.log_success("Site über Cluster zugewiesen.", obj=vm)
            else:
                self.log_failure("Virtual Machine hat weder direkt noch über das Cluster eine Site zugewiesen.", obj=vm)

class VMDeviceReport(Script):
    class Meta:
        name = "VM Device prüfen"
        description = "Prüft, ob ein Device bei VMs angegeben ist."

    def test_vm_host_devices(self):
        """Prüft, ob der VM das konkrete physische Host-Device (Hypervisor) zugewiesen wurde (außer OpenStack)."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            # 1. Prüfen, ob die VM ein Cluster hat und ob der Cluster-Typ OpenStack ist
            if vm.cluster and vm.cluster.type:
                cluster_type_name = vm.cluster.type.name.lower()
                if "openstack" in cluster_type_name:
                    self.log_success("OpenStack VM - Physisches Host-Device nicht erforderlich.", obj=vm)
                    continue

            # 2. Reguläre Prüfung für alle anderen Cluster-Typen (VMware, Proxmox etc.)
            if vm.device_id is None:
                self.log_failure("Der VM ist kein physisches Host-Device (Server) zugewiesen.", obj=vm)
            else:
                self.log_success(f"Läuft auf Host-Device: {vm.device.name}", obj=vm)

class DeviceIPReport(Report):
    description = "Check that every device has either an IPv4 or IPv6 primary address assigned"

    def test_primary_ip4(self):
        for device in Device.objects.filter(status=DeviceStatusChoices.STATUS_ACTIVE):
            intcount = 0
            for interface in device.interfaces.all():
                if not interface.mgmt_only:
                    intcount += 1
            # There may be dumb devices with no interfaces so no IP addresses, that's OK
            if intcount == 0:
                if device.primary_ip4_id is not None:
                    if device.primary_ip6_id is not None:
                        self.log_failure(device, "Device has primary IPv4 and IPv6 address but no interfaces")
                    else:
                        self.log_warning(device, "Device has missing primary IPv4 addresses but no interfaces")
                else:
                    self.log_success(device)
            elif device.primary_ip4_id is None:
                if device.device_type.is_child_device is True:
                    self.log_success(device)
                else:
                    if device.primary_ip6_id is None:
                        self.log_failure(device, "Device is missing primary IPv4 and IPv6 address")
                    else:
                        self.log_warning(device, "Device is missing primary IPv4 addresses")
            else:
                if device.device_type.is_child_device is True:
                    self.log_success(device)
                else:
                    if device.primary_ip6_id is None:
                        self.log_info(device, "Device is missing primary IPv6 address")
                    else:
                        self.log_success(device)

class PlatformReport(Script):
    class Meta:
        name = "Platform prüfen"
        description = "Prüft, ob eine Platform angegeben ist."

    def test_device_platforms(self):
        """Prüft alle aktiven Devices auf eine zugewiesene Plattform."""
        active_devices = Device.objects.filter(status="active")
        for device in active_devices:
            if device.device_type.is_child_device:
                self.log_success("Child Device übersprungen.", obj=device)
                continue

            if device.platform_id is None:
                self.log_failure("Device hat keine Plattform zugewiesen.", obj=device)
            else:
                self.log_success("Plattform zugewiesen.", obj=device)

    def test_vm_platforms(self):
        """Prüft alle aktiven virtuellen Maschinen auf eine zugewiesene Plattform."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            if vm.platform_id is None:
                self.log_failure("Virtual Machine hat keine Plattform zugewiesen.", obj=vm)
            else:
                self.log_success("Plattform zugewiesen.", obj=vm)

class VMScaleReport(Script):
    class Meta:
        name = "VM Scalierung prüfen"
        description = "Prüft, ob eine VM Scalierung angegeben ist."

    def test_vm_vcpus(self):
        """Prüft, ob die Anzahl der vCPUs definiert und größer als 0 ist."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            if vm.vcpus is None:
                self.log_failure("Anzahl der vCPUs ist nicht definiert.", obj=vm)
            elif vm.vcpus <= 0:
                self.log_failure(f"Ungültige vCPU-Anzahl definiert: {vm.vcpus}", obj=vm)
            else:
                self.log_success(f"vCPUs konfiguriert: {vm.vcpus}", obj=vm)

    def test_vm_memory(self):
        """Prüft, ob der Arbeitsspeicher (RAM) definiert und größer als 0 ist."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            if vm.memory is None:
                self.log_failure("Arbeitsspeicher (RAM) ist nicht definiert.", obj=vm)
            elif vm.memory <= 0:
                self.log_failure(f"Ungültiger RAM-Wert definiert: {vm.memory} MB", obj=vm)
            else:
                self.log_success(f"RAM konfiguriert: {vm.memory} MB", obj=vm)

    def test_vm_disk(self):
        """Prüft, ob der Festplattenspeicher (Disk) definiert und größer als 0 ist."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            if vm.disk is None:
                self.log_failure("Festplattenspeicher (Disk) ist nicht definiert.", obj=vm)
            elif vm.disk <= 0:
                self.log_failure(f"Ungültiger Disk-Wert definiert: {vm.disk} GB", obj=vm)
            else:
                self.log_success(f"Disk konfiguriert: {vm.disk} GB", obj=vm)

class DokuReport(Script):
    class Meta:
        name = "Prüfung der gesamten Netbox Dokumentation"
        description = "Prüft alle Netbox Dokupunkte, ob die wie vorgeshenen pannsen."

    def test_device_tenants(self):
        """Prüft alle aktiven Devices auf zugewiesene Tenants."""
        active_devices = Device.objects.filter(status="active")

        for device in active_devices:
            if device.device_type.is_child_device:
                self.log_success("Child Device übersprungen.", obj=device)
                continue

            if device.tenant_id is None:
                # In NetBox v4: Erst die Nachricht, dann obj=device für die URL-Spalte
                self.log_failure("Device hat keinen Tenant zugewiesen.", obj=device)
            else:
                self.log_success("Tenant zugewiesen.", obj=device)

    def test_vm_tenants(self):
        """Prüft alle aktiven virtuellen Maschinen auf zugewiesene Tenants."""
        active_vms = VirtualMachine.objects.filter(status="active")

        for vm in active_vms:
            if vm.tenant_id is None:
                # In NetBox v4: Erst die Nachricht, dann obj=vm für die URL-Spalte
                self.log_failure("Virtual Machine hat keinen Tenant zugewiesen.", obj=vm)
            else:
                self.log_success("Tenant zugewiesen.", obj=vm)

    def test_device_descriptions(self):
        """Prüft alle aktiven Devices auf eine vorhandene Beschreibung und korrekte Interpunktion."""
        active_devices = Device.objects.filter(status="active")
        for device in active_devices:
            if not device.description or not device.description.strip():
                self.log_failure("Device Beschreibung ist leer.", obj=device)
            elif not device.description.strip().endswith('.'):
                self.log_warning("Beschreibung endet nicht mit einem Punkt.", obj=device)
            else:
                self.log_success("Beschreibung vorhanden und korrekt.", obj=device)

    def test_vm_descriptions(self):
        """Prüft alle aktiven virtuellen Maschinen auf eine vorhandene Beschreibung und korrekte Interpunktion."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            if not vm.description or not vm.description.strip():
                self.log_failure("Virtual Machine Beschreibung ist leer.", obj=vm)
            elif not vm.description.strip().endswith('.'):
                self.log_warning("Beschreibung endet nicht mit einem Punkt.", obj=vm)
            else:
                self.log_success("Beschreibung vorhanden und korrekt.", obj=vm)

    def test_device_roles(self):
        """Prüft alle aktiven Devices auf eine zugewiesene Rolle."""
        active_devices = Device.objects.filter(status="active")
        for device in active_devices:
            if device.device_type.is_child_device:
                self.log_success("Child Device übersprungen.", obj=device)
                continue

            if device.role_id is None:
                self.log_failure("Device hat keine Rolle zugewiesen.", obj=device)
            else:
                self.log_success("Rolle zugewiesen.", obj=device)

    def test_vm_roles(self):
        """Prüft alle aktiven virtuellen Maschinen auf eine zugewiesene Rolle."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            if vm.role_id is None:
                self.log_failure("Virtual Machine hat keine Rolle zugewiesen.", obj=vm)
            else:
                self.log_success("Rolle zugewiesen.", obj=vm)

    def test_device_sites(self):
        """Prüft alle aktiven Devices auf eine zugewiesene Site."""
        active_devices = Device.objects.filter(status="active")
        for device in active_devices:
            if device.device_type.is_child_device:
                self.log_success("Child Device übersprungen.", obj=device)
                continue

            if device.site_id is None:
                self.log_failure("Device hat keine Site zugewiesen.", obj=device)
            else:
                self.log_success("Site zugewiesen.", obj=device)

    def test_vm_sites(self):
        """Prüft alle aktiven virtuellen Maschinen auf eine zugewiesene Site."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            # NetBox v4 erlaubt direkte site_id an der VM. Falls leer, prüfen wir das Cluster.
            if vm.site_id is not None:
                self.log_success("Site direkt an VM zugewiesen.", obj=vm)
            elif vm.cluster and vm.cluster.site_id is not None:
                self.log_success("Site über Cluster zugewiesen.", obj=vm)
            else:
                self.log_failure("Virtual Machine hat weder direkt noch über das Cluster eine Site zugewiesen.", obj=vm)

    def test_vm_host_devices(self):
        """Prüft, ob der VM das konkrete physische Host-Device (Hypervisor) zugewiesen wurde (außer OpenStack)."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            # 1. Prüfen, ob die VM ein Cluster hat und ob der Cluster-Typ OpenStack ist
            if vm.cluster and vm.cluster.type:
                cluster_type_name = vm.cluster.type.name.lower()
                if "openstack" in cluster_type_name:
                    self.log_success("OpenStack VM - Physisches Host-Device nicht erforderlich.", obj=vm)
                    continue

            # 2. Reguläre Prüfung für alle anderen Cluster-Typen (VMware, Proxmox etc.)
            if vm.device_id is None:
                self.log_failure("Der VM ist kein physisches Host-Device (Server) zugewiesen.", obj=vm)
            else:
                self.log_success(f"Läuft auf Host-Device: {vm.device.name}", obj=vm)

    def test_device_platforms(self):
        """Prüft alle aktiven Devices auf eine zugewiesene Plattform."""
        active_devices = Device.objects.filter(status="active")
        for device in active_devices:
            if device.device_type.is_child_device:
                self.log_success("Child Device übersprungen.", obj=device)
                continue

            if device.platform_id is None:
                self.log_failure("Device hat keine Plattform zugewiesen.", obj=device)
            else:
                self.log_success("Plattform zugewiesen.", obj=device)

    def test_vm_platforms(self):
        """Prüft alle aktiven virtuellen Maschinen auf eine zugewiesene Plattform."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            if vm.platform_id is None:
                self.log_failure("Virtual Machine hat keine Plattform zugewiesen.", obj=vm)
            else:
                self.log_success("Plattform zugewiesen.", obj=vm)

    def test_vm_vcpus(self):
        """Prüft, ob die Anzahl der vCPUs definiert und größer als 0 ist."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            if vm.vcpus is None:
                self.log_failure("Anzahl der vCPUs ist nicht definiert.", obj=vm)
            elif vm.vcpus <= 0:
                self.log_failure(f"Ungültige vCPU-Anzahl definiert: {vm.vcpus}", obj=vm)
            else:
                self.log_success(f"vCPUs konfiguriert: {vm.vcpus}", obj=vm)

    def test_vm_memory(self):
        """Prüft, ob der Arbeitsspeicher (RAM) definiert und größer als 0 ist."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            if vm.memory is None:
                self.log_failure("Arbeitsspeicher (RAM) ist nicht definiert.", obj=vm)
            elif vm.memory <= 0:
                self.log_failure(f"Ungültiger RAM-Wert definiert: {vm.memory} MB", obj=vm)
            else:
                self.log_success(f"RAM konfiguriert: {vm.memory} MB", obj=vm)

    def test_vm_disk(self):
        """Prüft, ob der Festplattenspeicher (Disk) definiert und größer als 0 ist."""
        active_vms = VirtualMachine.objects.filter(status="active")
        for vm in active_vms:
            if vm.disk is None:
                self.log_failure("Festplattenspeicher (Disk) ist nicht definiert.", obj=vm)
            elif vm.disk <= 0:
                self.log_failure(f"Ungültiger Disk-Wert definiert: {vm.disk} GB", obj=vm)
            else:
                self.log_success(f"Disk konfiguriert: {vm.disk} GB", obj=vm)
Documents
None