2025-06-14 23:32:30 +02:00

90 lines
3.3 KiB
Python
Executable File

# -----------------------------------------------------------------------------
# Swissmakers GmbH - NetBox Custom Script
# © 2025 Swissmakers GmbH. All rights reserved.
# https://swissmakers.ch
# -----------------------------------------------------------------------------
from dcim.models import DeviceRole, Platform
from django.core.exceptions import ObjectDoesNotExist
from extras.models import Tag
from ipam.choices import IPAddressStatusChoices
from ipam.models import IPAddress, VRF
from tenancy.models import Tenant
from virtualization.choices import VirtualMachineStatusChoices
from virtualization.models import Cluster, VirtualMachine, VMInterface
from extras.scripts import Script, StringVar, IPAddressWithMaskVar, ObjectVar, MultiObjectVar, ChoiceVar, IntegerVar, TextVar
class NewVMA(Script):
class Meta:
name = "New VM"
description = "Create a new VM"
scheduling_enabled = False
vm_name = StringVar(label="VM name (FQDN)")
vm_description = StringVar(label="Description", required=False, max_length=200)
primary_ip4 = IPAddressWithMaskVar(label="IPv4 address in CIDR (/24)")
interface_name = StringVar(default="ens18", required=False)
role = ObjectVar(model=DeviceRole, query_params=dict(vm_role=True), required=False)
status = ChoiceVar(VirtualMachineStatusChoices, default=VirtualMachineStatusChoices.STATUS_ACTIVE)
cluster = ObjectVar(model=Cluster)
def run(self, data, commit):
# add vm
vm = VirtualMachine(
name=data["vm_name"],
role=data["role"],
status=data["status"],
cluster=data["cluster"],
description=data.get("vm_description", "")
)
vm.full_clean()
vm.save()
# add interface
if data["interface_name"]:
vminterface = VMInterface(
name=data["interface_name"],
virtual_machine=vm,
)
vminterface.full_clean()
vminterface.save()
def add_addr(addr, family):
if not addr:
return
if addr.version != family:
raise RuntimeError(f"Wrong family for {addr}")
try:
a = IPAddress.objects.get(
address=addr,
vrf=data.get("vrf"),
)
a.snapshot()
result = "Assigned"
except ObjectDoesNotExist:
a = IPAddress(
address=addr,
vrf=data.get("vrf"),
)
result = "Created"
a.status = IPAddressStatusChoices.STATUS_ACTIVE
if a.assigned_object:
raise RuntimeError(f"Address {addr} is already assigned")
a.assigned_object = vminterface
# set DNS-name to fqdn of the vm
a.dns_name = vm.name
# validate and save
a.full_clean()
a.save()
self.log_info(f"{result} IP address {a.address} {a.vrf or ''} with DNS name {a.dns_name}")
# set primary ip to vm-object
setattr(vm, f"primary_ip{family}", a)
vm.snapshot()
if data["primary_ip4"]:
add_addr(data["primary_ip4"], 4)
vm.full_clean()
vm.save()
self.log_success(f"Created VM {vm.name}")