|
@@ -23,7 +23,6 @@ from tenancy.models import Tenant
|
|
|
from utilities.fields import ColorField, NullableCharField
|
|
from utilities.fields import ColorField, NullableCharField
|
|
|
from utilities.managers import NaturalOrderByManager
|
|
from utilities.managers import NaturalOrderByManager
|
|
|
from utilities.models import CreatedUpdatedModel
|
|
from utilities.models import CreatedUpdatedModel
|
|
|
-from utilities.utils import csv_format
|
|
|
|
|
from .constants import *
|
|
from .constants import *
|
|
|
from .fields import ASNField, MACAddressField
|
|
from .fields import ASNField, MACAddressField
|
|
|
from .querysets import InterfaceQuerySet
|
|
from .querysets import InterfaceQuerySet
|
|
@@ -44,9 +43,7 @@ class Region(MPTTModel):
|
|
|
name = models.CharField(max_length=50, unique=True)
|
|
name = models.CharField(max_length=50, unique=True)
|
|
|
slug = models.SlugField(unique=True)
|
|
slug = models.SlugField(unique=True)
|
|
|
|
|
|
|
|
- csv_headers = [
|
|
|
|
|
- 'name', 'slug', 'parent',
|
|
|
|
|
- ]
|
|
|
|
|
|
|
+ csv_headers = ['name', 'slug', 'parent']
|
|
|
|
|
|
|
|
class MPTTMeta:
|
|
class MPTTMeta:
|
|
|
order_insertion_by = ['name']
|
|
order_insertion_by = ['name']
|
|
@@ -58,11 +55,11 @@ class Region(MPTTModel):
|
|
|
return "{}?region={}".format(reverse('dcim:site_list'), self.slug)
|
|
return "{}?region={}".format(reverse('dcim:site_list'), self.slug)
|
|
|
|
|
|
|
|
def to_csv(self):
|
|
def to_csv(self):
|
|
|
- return csv_format([
|
|
|
|
|
|
|
+ return (
|
|
|
self.name,
|
|
self.name,
|
|
|
self.slug,
|
|
self.slug,
|
|
|
self.parent.name if self.parent else None,
|
|
self.parent.name if self.parent else None,
|
|
|
- ])
|
|
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
#
|
|
@@ -102,8 +99,8 @@ class Site(CreatedUpdatedModel, CustomFieldModel):
|
|
|
objects = SiteManager()
|
|
objects = SiteManager()
|
|
|
|
|
|
|
|
csv_headers = [
|
|
csv_headers = [
|
|
|
- 'name', 'slug', 'status', 'region', 'tenant', 'facility', 'asn', 'time_zone', 'description', 'contact_name',
|
|
|
|
|
- 'contact_phone', 'contact_email',
|
|
|
|
|
|
|
+ 'name', 'slug', 'status', 'region', 'tenant', 'facility', 'asn', 'time_zone', 'description', 'physical_address',
|
|
|
|
|
+ 'shipping_address', 'contact_name', 'contact_phone', 'contact_email', 'comments',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
@@ -116,7 +113,7 @@ class Site(CreatedUpdatedModel, CustomFieldModel):
|
|
|
return reverse('dcim:site', args=[self.slug])
|
|
return reverse('dcim:site', args=[self.slug])
|
|
|
|
|
|
|
|
def to_csv(self):
|
|
def to_csv(self):
|
|
|
- return csv_format([
|
|
|
|
|
|
|
+ return (
|
|
|
self.name,
|
|
self.name,
|
|
|
self.slug,
|
|
self.slug,
|
|
|
self.get_status_display(),
|
|
self.get_status_display(),
|
|
@@ -126,10 +123,13 @@ class Site(CreatedUpdatedModel, CustomFieldModel):
|
|
|
self.asn,
|
|
self.asn,
|
|
|
self.time_zone,
|
|
self.time_zone,
|
|
|
self.description,
|
|
self.description,
|
|
|
|
|
+ self.physical_address,
|
|
|
|
|
+ self.shipping_address,
|
|
|
self.contact_name,
|
|
self.contact_name,
|
|
|
self.contact_phone,
|
|
self.contact_phone,
|
|
|
self.contact_email,
|
|
self.contact_email,
|
|
|
- ])
|
|
|
|
|
|
|
+ self.comments,
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
def get_status_class(self):
|
|
def get_status_class(self):
|
|
|
return STATUS_CLASSES[self.status]
|
|
return STATUS_CLASSES[self.status]
|
|
@@ -175,9 +175,7 @@ class RackGroup(models.Model):
|
|
|
slug = models.SlugField()
|
|
slug = models.SlugField()
|
|
|
site = models.ForeignKey('Site', related_name='rack_groups', on_delete=models.CASCADE)
|
|
site = models.ForeignKey('Site', related_name='rack_groups', on_delete=models.CASCADE)
|
|
|
|
|
|
|
|
- csv_headers = [
|
|
|
|
|
- 'site', 'name', 'slug',
|
|
|
|
|
- ]
|
|
|
|
|
|
|
+ csv_headers = ['site', 'name', 'slug']
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
|
ordering = ['site', 'name']
|
|
ordering = ['site', 'name']
|
|
@@ -193,11 +191,11 @@ class RackGroup(models.Model):
|
|
|
return "{}?group_id={}".format(reverse('dcim:rack_list'), self.pk)
|
|
return "{}?group_id={}".format(reverse('dcim:rack_list'), self.pk)
|
|
|
|
|
|
|
|
def to_csv(self):
|
|
def to_csv(self):
|
|
|
- return csv_format([
|
|
|
|
|
|
|
+ return (
|
|
|
self.site,
|
|
self.site,
|
|
|
self.name,
|
|
self.name,
|
|
|
self.slug,
|
|
self.slug,
|
|
|
- ])
|
|
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
@python_2_unicode_compatible
|
|
@@ -209,6 +207,8 @@ class RackRole(models.Model):
|
|
|
slug = models.SlugField(unique=True)
|
|
slug = models.SlugField(unique=True)
|
|
|
color = ColorField()
|
|
color = ColorField()
|
|
|
|
|
|
|
|
|
|
+ csv_headers = ['name', 'slug', 'color']
|
|
|
|
|
+
|
|
|
class Meta:
|
|
class Meta:
|
|
|
ordering = ['name']
|
|
ordering = ['name']
|
|
|
|
|
|
|
@@ -218,6 +218,13 @@ class RackRole(models.Model):
|
|
|
def get_absolute_url(self):
|
|
def get_absolute_url(self):
|
|
|
return "{}?role={}".format(reverse('dcim:rack_list'), self.slug)
|
|
return "{}?role={}".format(reverse('dcim:rack_list'), self.slug)
|
|
|
|
|
|
|
|
|
|
+ def to_csv(self):
|
|
|
|
|
+ return (
|
|
|
|
|
+ self.name,
|
|
|
|
|
+ self.slug,
|
|
|
|
|
+ self.color,
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
|
|
|
class RackManager(NaturalOrderByManager):
|
|
class RackManager(NaturalOrderByManager):
|
|
|
|
|
|
|
@@ -253,7 +260,7 @@ class Rack(CreatedUpdatedModel, CustomFieldModel):
|
|
|
|
|
|
|
|
csv_headers = [
|
|
csv_headers = [
|
|
|
'site', 'group_name', 'name', 'facility_id', 'tenant', 'role', 'type', 'serial', 'width', 'u_height',
|
|
'site', 'group_name', 'name', 'facility_id', 'tenant', 'role', 'type', 'serial', 'width', 'u_height',
|
|
|
- 'desc_units',
|
|
|
|
|
|
|
+ 'desc_units', 'comments',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
@@ -303,7 +310,7 @@ class Rack(CreatedUpdatedModel, CustomFieldModel):
|
|
|
Device.objects.filter(rack=self).update(site_id=self.site.pk)
|
|
Device.objects.filter(rack=self).update(site_id=self.site.pk)
|
|
|
|
|
|
|
|
def to_csv(self):
|
|
def to_csv(self):
|
|
|
- return csv_format([
|
|
|
|
|
|
|
+ return (
|
|
|
self.site.name,
|
|
self.site.name,
|
|
|
self.group.name if self.group else None,
|
|
self.group.name if self.group else None,
|
|
|
self.name,
|
|
self.name,
|
|
@@ -315,7 +322,8 @@ class Rack(CreatedUpdatedModel, CustomFieldModel):
|
|
|
self.width,
|
|
self.width,
|
|
|
self.u_height,
|
|
self.u_height,
|
|
|
self.desc_units,
|
|
self.desc_units,
|
|
|
- ])
|
|
|
|
|
|
|
+ self.comments,
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
@property
|
|
@property
|
|
|
def units(self):
|
|
def units(self):
|
|
@@ -491,9 +499,7 @@ class Manufacturer(models.Model):
|
|
|
name = models.CharField(max_length=50, unique=True)
|
|
name = models.CharField(max_length=50, unique=True)
|
|
|
slug = models.SlugField(unique=True)
|
|
slug = models.SlugField(unique=True)
|
|
|
|
|
|
|
|
- csv_headers = [
|
|
|
|
|
- 'name', 'slug',
|
|
|
|
|
- ]
|
|
|
|
|
|
|
+ csv_headers = ['name', 'slug']
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
|
ordering = ['name']
|
|
ordering = ['name']
|
|
@@ -505,10 +511,10 @@ class Manufacturer(models.Model):
|
|
|
return "{}?manufacturer={}".format(reverse('dcim:devicetype_list'), self.slug)
|
|
return "{}?manufacturer={}".format(reverse('dcim:devicetype_list'), self.slug)
|
|
|
|
|
|
|
|
def to_csv(self):
|
|
def to_csv(self):
|
|
|
- return csv_format([
|
|
|
|
|
|
|
+ return (
|
|
|
self.name,
|
|
self.name,
|
|
|
self.slug,
|
|
self.slug,
|
|
|
- ])
|
|
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
@python_2_unicode_compatible
|
|
@@ -551,7 +557,7 @@ class DeviceType(models.Model, CustomFieldModel):
|
|
|
|
|
|
|
|
csv_headers = [
|
|
csv_headers = [
|
|
|
'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'is_console_server',
|
|
'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'is_console_server',
|
|
|
- 'is_pdu', 'is_network_device', 'subdevice_role', 'interface_ordering',
|
|
|
|
|
|
|
+ 'is_pdu', 'is_network_device', 'subdevice_role', 'interface_ordering', 'comments',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
@@ -574,7 +580,7 @@ class DeviceType(models.Model, CustomFieldModel):
|
|
|
return reverse('dcim:devicetype', args=[self.pk])
|
|
return reverse('dcim:devicetype', args=[self.pk])
|
|
|
|
|
|
|
|
def to_csv(self):
|
|
def to_csv(self):
|
|
|
- return csv_format([
|
|
|
|
|
|
|
+ return (
|
|
|
self.manufacturer.name,
|
|
self.manufacturer.name,
|
|
|
self.model,
|
|
self.model,
|
|
|
self.slug,
|
|
self.slug,
|
|
@@ -586,7 +592,8 @@ class DeviceType(models.Model, CustomFieldModel):
|
|
|
self.is_network_device,
|
|
self.is_network_device,
|
|
|
self.get_subdevice_role_display() if self.subdevice_role else None,
|
|
self.get_subdevice_role_display() if self.subdevice_role else None,
|
|
|
self.get_interface_ordering_display(),
|
|
self.get_interface_ordering_display(),
|
|
|
- ])
|
|
|
|
|
|
|
+ self.comments,
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
def clean(self):
|
|
def clean(self):
|
|
|
|
|
|
|
@@ -766,6 +773,8 @@ class DeviceRole(models.Model):
|
|
|
help_text="Virtual machines may be assigned to this role"
|
|
help_text="Virtual machines may be assigned to this role"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+ csv_headers = ['name', 'slug', 'color', 'vm_role']
|
|
|
|
|
+
|
|
|
class Meta:
|
|
class Meta:
|
|
|
ordering = ['name']
|
|
ordering = ['name']
|
|
|
|
|
|
|
@@ -775,6 +784,14 @@ class DeviceRole(models.Model):
|
|
|
def get_absolute_url(self):
|
|
def get_absolute_url(self):
|
|
|
return "{}?role={}".format(reverse('dcim:device_list'), self.slug)
|
|
return "{}?role={}".format(reverse('dcim:device_list'), self.slug)
|
|
|
|
|
|
|
|
|
|
+ def to_csv(self):
|
|
|
|
|
+ return (
|
|
|
|
|
+ self.name,
|
|
|
|
|
+ self.slug,
|
|
|
|
|
+ self.color,
|
|
|
|
|
+ self.vm_role,
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
|
|
|
@python_2_unicode_compatible
|
|
@python_2_unicode_compatible
|
|
|
class Platform(models.Model):
|
|
class Platform(models.Model):
|
|
@@ -805,6 +822,8 @@ class Platform(models.Model):
|
|
|
verbose_name="Legacy RPC client"
|
|
verbose_name="Legacy RPC client"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+ csv_headers = ['name', 'slug', 'manufacturer', 'napalm_driver']
|
|
|
|
|
+
|
|
|
class Meta:
|
|
class Meta:
|
|
|
ordering = ['name']
|
|
ordering = ['name']
|
|
|
|
|
|
|
@@ -814,6 +833,14 @@ class Platform(models.Model):
|
|
|
def get_absolute_url(self):
|
|
def get_absolute_url(self):
|
|
|
return "{}?platform={}".format(reverse('dcim:device_list'), self.slug)
|
|
return "{}?platform={}".format(reverse('dcim:device_list'), self.slug)
|
|
|
|
|
|
|
|
|
|
+ def to_csv(self):
|
|
|
|
|
+ return (
|
|
|
|
|
+ self.name,
|
|
|
|
|
+ self.slug,
|
|
|
|
|
+ self.manufacturer.name if self.manufacturer else None,
|
|
|
|
|
+ self.napalm_driver,
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
|
|
|
class DeviceManager(NaturalOrderByManager):
|
|
class DeviceManager(NaturalOrderByManager):
|
|
|
|
|
|
|
@@ -892,7 +919,7 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
|
|
|
|
|
|
|
|
csv_headers = [
|
|
csv_headers = [
|
|
|
'name', 'device_role', 'tenant', 'manufacturer', 'model_name', 'platform', 'serial', 'asset_tag', 'status',
|
|
'name', 'device_role', 'tenant', 'manufacturer', 'model_name', 'platform', 'serial', 'asset_tag', 'status',
|
|
|
- 'site', 'rack_group', 'rack_name', 'position', 'face',
|
|
|
|
|
|
|
+ 'site', 'rack_group', 'rack_name', 'position', 'face', 'comments',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
@@ -1049,7 +1076,7 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
|
|
|
Device.objects.filter(parent_bay__device=self).update(site=self.site, rack=self.rack)
|
|
Device.objects.filter(parent_bay__device=self).update(site=self.site, rack=self.rack)
|
|
|
|
|
|
|
|
def to_csv(self):
|
|
def to_csv(self):
|
|
|
- return csv_format([
|
|
|
|
|
|
|
+ return (
|
|
|
self.name or '',
|
|
self.name or '',
|
|
|
self.device_role.name,
|
|
self.device_role.name,
|
|
|
self.tenant.name if self.tenant else None,
|
|
self.tenant.name if self.tenant else None,
|
|
@@ -1064,7 +1091,8 @@ class Device(CreatedUpdatedModel, CustomFieldModel):
|
|
|
self.rack.name if self.rack else None,
|
|
self.rack.name if self.rack else None,
|
|
|
self.position,
|
|
self.position,
|
|
|
self.get_face_display(),
|
|
self.get_face_display(),
|
|
|
- ])
|
|
|
|
|
|
|
+ self.comments,
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
@property
|
|
@property
|
|
|
def display_name(self):
|
|
def display_name(self):
|
|
@@ -1158,15 +1186,14 @@ class ConsolePort(models.Model):
|
|
|
def get_absolute_url(self):
|
|
def get_absolute_url(self):
|
|
|
return self.device.get_absolute_url()
|
|
return self.device.get_absolute_url()
|
|
|
|
|
|
|
|
- # Used for connections export
|
|
|
|
|
def to_csv(self):
|
|
def to_csv(self):
|
|
|
- return csv_format([
|
|
|
|
|
|
|
+ return (
|
|
|
self.cs_port.device.identifier if self.cs_port else None,
|
|
self.cs_port.device.identifier if self.cs_port else None,
|
|
|
self.cs_port.name if self.cs_port else None,
|
|
self.cs_port.name if self.cs_port else None,
|
|
|
self.device.identifier,
|
|
self.device.identifier,
|
|
|
self.name,
|
|
self.name,
|
|
|
self.get_connection_status_display(),
|
|
self.get_connection_status_display(),
|
|
|
- ])
|
|
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
#
|
|
@@ -1241,15 +1268,14 @@ class PowerPort(models.Model):
|
|
|
def get_absolute_url(self):
|
|
def get_absolute_url(self):
|
|
|
return self.device.get_absolute_url()
|
|
return self.device.get_absolute_url()
|
|
|
|
|
|
|
|
- # Used for connections export
|
|
|
|
|
def to_csv(self):
|
|
def to_csv(self):
|
|
|
- return csv_format([
|
|
|
|
|
|
|
+ return (
|
|
|
self.power_outlet.device.identifier if self.power_outlet else None,
|
|
self.power_outlet.device.identifier if self.power_outlet else None,
|
|
|
self.power_outlet.name if self.power_outlet else None,
|
|
self.power_outlet.name if self.power_outlet else None,
|
|
|
self.device.identifier,
|
|
self.device.identifier,
|
|
|
self.name,
|
|
self.name,
|
|
|
self.get_connection_status_display(),
|
|
self.get_connection_status_display(),
|
|
|
- ])
|
|
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
#
|
|
@@ -1501,15 +1527,14 @@ class InterfaceConnection(models.Model):
|
|
|
except ObjectDoesNotExist:
|
|
except ObjectDoesNotExist:
|
|
|
pass
|
|
pass
|
|
|
|
|
|
|
|
- # Used for connections export
|
|
|
|
|
def to_csv(self):
|
|
def to_csv(self):
|
|
|
- return csv_format([
|
|
|
|
|
|
|
+ return (
|
|
|
self.interface_a.device.identifier,
|
|
self.interface_a.device.identifier,
|
|
|
self.interface_a.name,
|
|
self.interface_a.name,
|
|
|
self.interface_b.device.identifier,
|
|
self.interface_b.device.identifier,
|
|
|
self.interface_b.name,
|
|
self.interface_b.name,
|
|
|
self.get_connection_status_display(),
|
|
self.get_connection_status_display(),
|
|
|
- ])
|
|
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
#
|
|
@@ -1575,7 +1600,7 @@ class InventoryItem(models.Model):
|
|
|
description = models.CharField(max_length=100, blank=True)
|
|
description = models.CharField(max_length=100, blank=True)
|
|
|
|
|
|
|
|
csv_headers = [
|
|
csv_headers = [
|
|
|
- 'device', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description',
|
|
|
|
|
|
|
+ 'device', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered', 'description',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
@@ -1589,15 +1614,16 @@ class InventoryItem(models.Model):
|
|
|
return self.device.get_absolute_url()
|
|
return self.device.get_absolute_url()
|
|
|
|
|
|
|
|
def to_csv(self):
|
|
def to_csv(self):
|
|
|
- return csv_format([
|
|
|
|
|
|
|
+ return (
|
|
|
self.device.name or '{' + self.device.pk + '}',
|
|
self.device.name or '{' + self.device.pk + '}',
|
|
|
self.name,
|
|
self.name,
|
|
|
self.manufacturer.name if self.manufacturer else None,
|
|
self.manufacturer.name if self.manufacturer else None,
|
|
|
self.part_id,
|
|
self.part_id,
|
|
|
self.serial,
|
|
self.serial,
|
|
|
self.asset_tag,
|
|
self.asset_tag,
|
|
|
- self.description
|
|
|
|
|
- ])
|
|
|
|
|
|
|
+ self.discovered,
|
|
|
|
|
+ self.description,
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
#
|
|
@@ -1632,4 +1658,4 @@ class VirtualChassis(models.Model):
|
|
|
if self.pk and self.master not in self.members.all():
|
|
if self.pk and self.master not in self.members.all():
|
|
|
raise ValidationError({
|
|
raise ValidationError({
|
|
|
'master': "The selected master is not assigned to this virtual chassis."
|
|
'master': "The selected master is not assigned to this virtual chassis."
|
|
|
- })
|
|
|
|
|
|
|
+ })
|