-
Notifications
You must be signed in to change notification settings - Fork 54
/
create_vm.py
105 lines (97 loc) · 4.06 KB
/
create_vm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
"""
This script allows you to create a VM, an interface and primary IP address
all in one screen.
Workaround for issues:
https://github.com/netbox-community/netbox/issues/1492
https://github.com/netbox-community/netbox/issues/648
"""
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 NewVM(Script):
class Meta:
name = "New VM"
description = "Create a new VM"
vm_name = StringVar(label="VM name")
dns_name = StringVar(label="DNS name", required=False)
vm_tags = MultiObjectVar(model=Tag, label="VM tags", required=False)
primary_ip4 = IPAddressWithMaskVar(label="IPv4 address")
#primary_ip4_tags = MultiObjectVar(model=Tag, label="IPv4 tags", required=False)
primary_ip6 = IPAddressWithMaskVar(label="IPv6 address", required=False)
#primary_ip6_tags = MultiObjectVar(model=Tag, label="IPv6 tags", required=False)
#vrf = ObjectVar(model=VRF, 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)
tenant = ObjectVar(model=Tenant, required=False)
platform = ObjectVar(model=Platform, required=False)
interface_name = StringVar(default="eth0")
mac_address = StringVar(label="MAC address", required=False)
vcpus = IntegerVar(label="VCPUs", required=False)
memory = IntegerVar(label="Memory (MB)", required=False)
disk = IntegerVar(label="Disk (GB)", required=False)
comments = TextVar(label="Comments", required=False)
def run(self, data, commit):
vm = VirtualMachine(
name=data["vm_name"],
role=data["role"],
status=data["status"],
cluster=data["cluster"],
platform=data["platform"],
vcpus=data["vcpus"],
memory=data["memory"],
disk=data["disk"],
comments=data["comments"],
tenant=data.get("tenant"),
)
vm.full_clean()
vm.save()
vm.tags.set(data["vm_tags"])
vminterface = VMInterface(
name=data["interface_name"],
mac_address=data["mac_address"],
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 {a}")
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
a.dns_name = data["dns_name"]
if a.assigned_object:
raise RuntimeError(f"Address {addr} is already assigned")
a.assigned_object = vminterface
a.tenant = data.get("tenant")
a.full_clean()
a.save()
#a.tags.set(data[f"primary_ip{family}_tags"])
self.log_info(f"{result} IP address {a.address} {a.vrf or ''}")
setattr(vm, f"primary_ip{family}", a)
vm.snapshot()
add_addr(data["primary_ip4"], 4)
add_addr(data["primary_ip6"], 6)
vm.full_clean()
vm.save()
self.log_success(f"Created VM [{vm.name}](/virtualization/virtual-machines/{vm.id}/)")