mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-20 04:12:25 -06:00
Merge upstream v2.7.8 into develop
This commit is contained in:
@@ -1,19 +1,9 @@
|
||||
from extras.constants import CF_TYPE_TEXT, CF_TYPE_INTEGER, CF_TYPE_BOOLEAN, CF_TYPE_DATE, CF_TYPE_URL, CF_TYPE_SELECT, CF_FILTER_CHOICES
|
||||
from extras.models import CustomField, CustomFieldChoice
|
||||
|
||||
from ruamel.yaml import YAML
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
text_to_fields = {
|
||||
'boolean': CF_TYPE_BOOLEAN,
|
||||
'date': CF_TYPE_DATE,
|
||||
'integer': CF_TYPE_INTEGER,
|
||||
'selection': CF_TYPE_SELECT,
|
||||
'text': CF_TYPE_TEXT,
|
||||
'url': CF_TYPE_URL,
|
||||
}
|
||||
|
||||
def get_class_for_class_path(class_path):
|
||||
import importlib
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
@@ -42,12 +32,6 @@ with file.open('r') as stream:
|
||||
if cf_details.get('description', 0):
|
||||
custom_field.description = cf_details['description']
|
||||
|
||||
# If no filter_logic is specified then it will default to 'Loose'
|
||||
if cf_details.get('filter_logic', 0):
|
||||
for choice_id, choice_text in CF_FILTER_CHOICES:
|
||||
if choice_text.lower() == cf_details['filter_logic']:
|
||||
custom_field.filter_logic = choice_id
|
||||
|
||||
if cf_details.get('label', 0):
|
||||
custom_field.label = cf_details['label']
|
||||
|
||||
@@ -58,7 +42,7 @@ with file.open('r') as stream:
|
||||
custom_field.required = cf_details['required']
|
||||
|
||||
if cf_details.get('type', 0):
|
||||
custom_field.type = text_to_fields[cf_details['type']]
|
||||
custom_field.type = cf_details['type']
|
||||
|
||||
if cf_details.get('weight', 0):
|
||||
custom_field.weight = cf_details['weight']
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from dcim.models import Site, RackRole, Rack, RackGroup
|
||||
from tenancy.models import Tenant
|
||||
from extras.models import CustomField, CustomFieldValue
|
||||
from dcim.constants import RACK_TYPE_CHOICES, RACK_WIDTH_CHOICES
|
||||
from ruamel.yaml import YAML
|
||||
from pathlib import Path
|
||||
import sys
|
||||
@@ -41,14 +40,6 @@ with file.open('r') as stream:
|
||||
|
||||
params[assoc] = model.objects.get(**query)
|
||||
|
||||
for rack_type in RACK_TYPE_CHOICES:
|
||||
if params['type'] in rack_type:
|
||||
params['type'] = rack_type[0]
|
||||
|
||||
for rack_width in RACK_WIDTH_CHOICES:
|
||||
if params['width'] in rack_width:
|
||||
params['width'] = rack_width[0]
|
||||
|
||||
rack, created = Rack.objects.get_or_create(**params)
|
||||
|
||||
if created:
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from dcim.models import Site, Rack, DeviceRole, DeviceType, Device, Platform
|
||||
from dcim.constants import RACK_FACE_CHOICES
|
||||
from ipam.models import IPAddress
|
||||
from virtualization.models import Cluster
|
||||
from tenancy.models import Tenant
|
||||
@@ -26,6 +25,7 @@ with file.open('r') as stream:
|
||||
optional_assocs = {
|
||||
'tenant': (Tenant, 'name'),
|
||||
'platform': (Platform, 'name'),
|
||||
'rack': (Rack, 'name'),
|
||||
'cluster': (Cluster, 'name'),
|
||||
'primary_ip4': (IPAddress, 'address'),
|
||||
'primary_ip6': (IPAddress, 'address')
|
||||
@@ -48,14 +48,6 @@ with file.open('r') as stream:
|
||||
|
||||
params[assoc] = model.objects.get(**query)
|
||||
|
||||
if 'rack' in params:
|
||||
params['rack'] = Rack.objects.get(name=params.pop('rack'), site=params['site'].id)
|
||||
|
||||
if 'face' in params:
|
||||
for rack_face in RACK_FACE_CHOICES:
|
||||
if params['face'] in rack_face:
|
||||
params['face'] = rack_face[0]
|
||||
|
||||
device, created = Device.objects.get_or_create(**params)
|
||||
|
||||
if created:
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from dcim.models import Interface, Device, DeviceRole
|
||||
from dcim.constants import IFACE_TYPE_KEYSTONE
|
||||
|
||||
from ruamel.yaml import YAML
|
||||
from pathlib import Path
|
||||
@@ -31,6 +30,6 @@ with file.open('r') as stream:
|
||||
|
||||
i += 2
|
||||
|
||||
interface, created = Interface.objects.get_or_create(name=name, device=locker, type=IFACE_TYPE_KEYSTONE)
|
||||
interface, created = Interface.objects.get_or_create(name=name, device=locker, type='keystone')
|
||||
if created:
|
||||
print("🔗 Created interface {} for {}".format(interface.name, locker.name))
|
||||
|
||||
51
docker/startup_scripts/210_vlans.py
Normal file
51
docker/startup_scripts/210_vlans.py
Normal file
@@ -0,0 +1,51 @@
|
||||
from dcim.models import Site
|
||||
from ipam.models import VLAN, VLANGroup, Role
|
||||
from tenancy.models import Tenant, TenantGroup
|
||||
from extras.models import CustomField, CustomFieldValue
|
||||
from ruamel.yaml import YAML
|
||||
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
file = Path('/opt/netbox/initializers/vlans.yml')
|
||||
if not file.is_file():
|
||||
sys.exit()
|
||||
|
||||
with file.open('r') as stream:
|
||||
yaml = YAML(typ='safe')
|
||||
vlans = yaml.load(stream)
|
||||
|
||||
optional_assocs = {
|
||||
'site': (Site, 'name'),
|
||||
'tenant': (Tenant, 'name'),
|
||||
'tenant_group': (TenantGroup, 'name'),
|
||||
'group': (VLANGroup, 'name'),
|
||||
'role': (Role, 'name')
|
||||
}
|
||||
|
||||
if vlans is not None:
|
||||
for params in vlans:
|
||||
custom_fields = params.pop('custom_fields', None)
|
||||
|
||||
for assoc, details in optional_assocs.items():
|
||||
if assoc in params:
|
||||
model, field = details
|
||||
query = { field: params.pop(assoc) }
|
||||
|
||||
params[assoc] = model.objects.get(**query)
|
||||
|
||||
vlan, created = VLAN.objects.get_or_create(**params)
|
||||
|
||||
if created:
|
||||
if custom_fields is not None:
|
||||
for cf_name, cf_value in custom_fields.items():
|
||||
custom_field = CustomField.objects.get(name=cf_name)
|
||||
custom_field_value = CustomFieldValue.objects.create(
|
||||
field=custom_field,
|
||||
obj=vlan,
|
||||
value=cf_value
|
||||
)
|
||||
|
||||
vlan.custom_field_values.add(custom_field_value)
|
||||
|
||||
print("🏠 Created VLAN", vlan.name)
|
||||
54
docker/startup_scripts/220_prefixes.py
Normal file
54
docker/startup_scripts/220_prefixes.py
Normal file
@@ -0,0 +1,54 @@
|
||||
from dcim.models import Site
|
||||
from ipam.models import Prefix, VLAN, Role, VRF
|
||||
from tenancy.models import Tenant, TenantGroup
|
||||
from extras.models import CustomField, CustomFieldValue
|
||||
from ruamel.yaml import YAML
|
||||
|
||||
from netaddr import IPNetwork
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
file = Path('/opt/netbox/initializers/prefixes.yml')
|
||||
if not file.is_file():
|
||||
sys.exit()
|
||||
|
||||
with file.open('r') as stream:
|
||||
yaml = YAML(typ='safe')
|
||||
prefixes = yaml.load(stream)
|
||||
|
||||
optional_assocs = {
|
||||
'site': (Site, 'name'),
|
||||
'tenant': (Tenant, 'name'),
|
||||
'tenant_group': (TenantGroup, 'name'),
|
||||
'vlan': (VLAN, 'name'),
|
||||
'role': (Role, 'name'),
|
||||
'vrf': (VRF, 'name')
|
||||
}
|
||||
|
||||
if prefixes is not None:
|
||||
for params in prefixes:
|
||||
custom_fields = params.pop('custom_fields', None)
|
||||
params['prefix'] = IPNetwork(params['prefix'])
|
||||
|
||||
for assoc, details in optional_assocs.items():
|
||||
if assoc in params:
|
||||
model, field = details
|
||||
query = { field: params.pop(assoc) }
|
||||
|
||||
params[assoc] = model.objects.get(**query)
|
||||
|
||||
prefix, created = Prefix.objects.get_or_create(**params)
|
||||
|
||||
if created:
|
||||
if custom_fields is not None:
|
||||
for cf_name, cf_value in custom_fields.items():
|
||||
custom_field = CustomField.objects.get(name=cf_name)
|
||||
custom_field_value = CustomFieldValue.objects.create(
|
||||
field=custom_field,
|
||||
obj=prefix,
|
||||
value=cf_value
|
||||
)
|
||||
|
||||
prefix.custom_field_values.add(custom_field_value)
|
||||
|
||||
print("📌 Created Prefix", prefix.prefix)
|
||||
44
docker/startup_scripts/250_dcim_interfaces.py
Normal file
44
docker/startup_scripts/250_dcim_interfaces.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from dcim.models import Interface, Device
|
||||
from extras.models import CustomField, CustomFieldValue
|
||||
from ruamel.yaml import YAML
|
||||
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
file = Path('/opt/netbox/initializers/dcim_interfaces.yml')
|
||||
if not file.is_file():
|
||||
sys.exit()
|
||||
|
||||
with file.open('r') as stream:
|
||||
yaml = YAML(typ='safe')
|
||||
interfaces = yaml.load(stream)
|
||||
|
||||
required_assocs = {
|
||||
'device': (Device, 'name')
|
||||
}
|
||||
|
||||
if interfaces is not None:
|
||||
for params in interfaces:
|
||||
custom_fields = params.pop('custom_fields', None)
|
||||
|
||||
for assoc, details in required_assocs.items():
|
||||
model, field = details
|
||||
query = { field: params.pop(assoc) }
|
||||
|
||||
params[assoc] = model.objects.get(**query)
|
||||
|
||||
interface, created = Interface.objects.get_or_create(**params)
|
||||
|
||||
if created:
|
||||
if custom_fields is not None:
|
||||
for cf_name, cf_value in custom_fields.items():
|
||||
custom_field = CustomField.objects.get(name=cf_name)
|
||||
custom_field_value = CustomFieldValue.objects.create(
|
||||
field=custom_field,
|
||||
obj=interface,
|
||||
value=cf_value
|
||||
)
|
||||
|
||||
interface.custom_field_values.add(custom_field_value)
|
||||
|
||||
print("🧷 Created interface", interface.name, interface.device.name)
|
||||
65
docker/startup_scripts/260_ip_addresses.py
Normal file
65
docker/startup_scripts/260_ip_addresses.py
Normal file
@@ -0,0 +1,65 @@
|
||||
from ipam.models import IPAddress, VRF
|
||||
from dcim.models import Device, Interface
|
||||
from virtualization.models import VirtualMachine
|
||||
from tenancy.models import Tenant
|
||||
from extras.models import CustomField, CustomFieldValue
|
||||
from ruamel.yaml import YAML
|
||||
|
||||
from netaddr import IPNetwork
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
file = Path('/opt/netbox/initializers/ip_addresses.yml')
|
||||
if not file.is_file():
|
||||
sys.exit()
|
||||
|
||||
with file.open('r') as stream:
|
||||
yaml = YAML(typ='safe')
|
||||
ip_addresses = yaml.load(stream)
|
||||
|
||||
optional_assocs = {
|
||||
'tenant': (Tenant, 'name'),
|
||||
'vrf': (VRF, 'name'),
|
||||
'interface': (Interface, 'name')
|
||||
}
|
||||
|
||||
if ip_addresses is not None:
|
||||
for params in ip_addresses:
|
||||
vm = params.pop('virtual_machine', None)
|
||||
device = params.pop('device', None)
|
||||
custom_fields = params.pop('custom_fields', None)
|
||||
params['address'] = IPNetwork(params['address'])
|
||||
|
||||
if vm and device:
|
||||
print("IP Address can only specify one of the following: virtual_machine or device.")
|
||||
sys.exit()
|
||||
|
||||
for assoc, details in optional_assocs.items():
|
||||
if assoc in params:
|
||||
model, field = details
|
||||
if assoc == 'interface':
|
||||
if vm:
|
||||
vm_id = VirtualMachine.objects.get(name=vm).id
|
||||
query = { field: params.pop(assoc), "virtual_machine_id": vm_id }
|
||||
elif device:
|
||||
dev_id = Device.objects.get(name=device).id
|
||||
query = { field: params.pop(assoc), "device_id": dev_id }
|
||||
else:
|
||||
query = { field: params.pop(assoc) }
|
||||
params[assoc] = model.objects.get(**query)
|
||||
|
||||
ip_address, created = IPAddress.objects.get_or_create(**params)
|
||||
|
||||
if created:
|
||||
if custom_fields is not None:
|
||||
for cf_name, cf_value in custom_fields.items():
|
||||
custom_field = CustomField.objects.get(name=cf_name)
|
||||
custom_field_value = CustomFieldValue.objects.create(
|
||||
field=custom_field,
|
||||
obj=ip_address,
|
||||
value=cf_value
|
||||
)
|
||||
|
||||
ip_address.custom_field_values.add(custom_field_value)
|
||||
|
||||
print("🧬 Created IP Address", ip_address.address)
|
||||
Reference in New Issue
Block a user