90 lines
3.3 KiB
Python
Executable File
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}")
|