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

106 lines
4.0 KiB
Python
Executable File

# -----------------------------------------------------------------------------
# Swissmakers GmbH - NetBox Custom Script
# © 2025 Swissmakers GmbH. All rights reserved.
# https://swissmakers.ch
# -----------------------------------------------------------------------------
from dcim.models import DeviceRole, Platform, Device, DeviceType, Site, Interface, Rack, Location
from django.core.exceptions import ObjectDoesNotExist
from ipam.choices import IPAddressStatusChoices
from ipam.models import IPAddress, VRF
from extras.scripts import Script, StringVar, IPAddressWithMaskVar, ObjectVar, ChoiceVar
from dcim.choices import DeviceStatusChoices, InterfaceTypeChoices
class NewDevice(Script):
class Meta:
name = "New Device"
description = "Create a new Device"
scheduling_enabled = False
device_name = StringVar(label="Device name (FQDN)")
access_description = StringVar(
label="Description",
required=False,
max_length=200,
)
primary_ip4 = IPAddressWithMaskVar(label="IPv4 address in CIDR (/24)", required=False)
interface_name = StringVar(default="ens18", required=False)
role = ObjectVar(model=DeviceRole, required=False)
status = ChoiceVar(choices=DeviceStatusChoices, default=DeviceStatusChoices.STATUS_ACTIVE)
device_type = ObjectVar(model=DeviceType)
site = ObjectVar(model=Site)
rack = ObjectVar(model=Rack, required=False)
location = ObjectVar(model=Location, required=False)
serial = StringVar(label="Serial Number", required=False)
def run(self, data, commit):
device = Device(
name=data["device_name"],
role=data["role"],
status=data["status"],
device_type=data["device_type"],
site=data["site"],
rack=data.get("rack"),
location=data.get("location"),
description=data.get("access_description"),
serial=data.get("serial"),
)
device.full_clean()
device.save()
if data["interface_name"]:
try:
interface = Interface.objects.get(
name=data["interface_name"],
device=device
)
self.log_info(f"Interface {data['interface_name']} already exists for device {device.name}")
except ObjectDoesNotExist:
interface = Interface(
name=data["interface_name"],
device=device,
type=InterfaceTypeChoices.TYPE_1GE_FIXED,
)
interface.full_clean()
interface.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 = interface
# set DNS-name to fqdn of the device
a.dns_name = device.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}")
setattr(device, f"primary_ip{family}", a)
device.snapshot()
if data["primary_ip4"]:
add_addr(data["primary_ip4"], 4)
device.full_clean()
device.save()
self.log_success(f"Created Device {device.name}")
self.log_info(f"Device details: <a href='{device.get_absolute_url()}'>{device.name}</a>")