Browse Source

Standardized declaration of csv_headers on models

Jeremy Stretch 7 years ago
parent
commit
12e6fe1d50

+ 2 - 2
netbox/circuits/forms.py

@@ -43,7 +43,7 @@ class ProviderCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = Provider
         model = Provider
-        fields = ['name', 'slug', 'asn', 'account', 'portal_url', 'comments']
+        fields = Provider.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Provider name',
             'name': 'Provider name',
             'asn': '32-bit autonomous system number',
             'asn': '32-bit autonomous system number',
@@ -89,7 +89,7 @@ class CircuitTypeCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = CircuitType
         model = CircuitType
-        fields = ['name', 'slug']
+        fields = CircuitType.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Name of circuit type',
             'name': 'Name of circuit type',
         }
         }

+ 14 - 2
netbox/circuits/models.py

@@ -28,7 +28,7 @@ class Provider(CreatedUpdatedModel, CustomFieldModel):
     comments = models.TextField(blank=True)
     comments = models.TextField(blank=True)
     custom_field_values = GenericRelation(CustomFieldValue, content_type_field='obj_type', object_id_field='obj_id')
     custom_field_values = GenericRelation(CustomFieldValue, content_type_field='obj_type', object_id_field='obj_id')
 
 
-    csv_headers = ['name', 'slug', 'asn', 'account', 'portal_url']
+    csv_headers = ['name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments']
 
 
     class Meta:
     class Meta:
         ordering = ['name']
         ordering = ['name']
@@ -46,6 +46,9 @@ class Provider(CreatedUpdatedModel, CustomFieldModel):
             self.asn,
             self.asn,
             self.account,
             self.account,
             self.portal_url,
             self.portal_url,
+            self.noc_contact,
+            self.admin_contact,
+            self.comments,
         )
         )
 
 
 
 
@@ -58,6 +61,8 @@ class CircuitType(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']
+
     class Meta:
     class Meta:
         ordering = ['name']
         ordering = ['name']
 
 
@@ -67,6 +72,12 @@ class CircuitType(models.Model):
     def get_absolute_url(self):
     def get_absolute_url(self):
         return "{}?type={}".format(reverse('circuits:circuit_list'), self.slug)
         return "{}?type={}".format(reverse('circuits:circuit_list'), self.slug)
 
 
+    def to_csv(self):
+        return (
+            self.name,
+            self.slug,
+        )
+
 
 
 @python_2_unicode_compatible
 @python_2_unicode_compatible
 class Circuit(CreatedUpdatedModel, CustomFieldModel):
 class Circuit(CreatedUpdatedModel, CustomFieldModel):
@@ -85,7 +96,7 @@ class Circuit(CreatedUpdatedModel, CustomFieldModel):
     comments = models.TextField(blank=True)
     comments = models.TextField(blank=True)
     custom_field_values = GenericRelation(CustomFieldValue, content_type_field='obj_type', object_id_field='obj_id')
     custom_field_values = GenericRelation(CustomFieldValue, content_type_field='obj_type', object_id_field='obj_id')
 
 
-    csv_headers = ['cid', 'provider', 'type', 'tenant', 'install_date', 'commit_rate', 'description']
+    csv_headers = ['cid', 'provider', 'type', 'tenant', 'install_date', 'commit_rate', 'description', 'comments']
 
 
     class Meta:
     class Meta:
         ordering = ['provider', 'cid']
         ordering = ['provider', 'cid']
@@ -106,6 +117,7 @@ class Circuit(CreatedUpdatedModel, CustomFieldModel):
             self.install_date,
             self.install_date,
             self.commit_rate,
             self.commit_rate,
             self.description,
             self.description,
+            self.comments,
         )
         )
 
 
     def _get_termination(self, side):
     def _get_termination(self, side):

+ 13 - 26
netbox/dcim/forms.py

@@ -72,9 +72,7 @@ class RegionCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = Region
         model = Region
-        fields = [
-            'name', 'slug', 'parent',
-        ]
+        fields = Region.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Region name',
             'name': 'Region name',
             'slug': 'URL-friendly slug',
             'slug': 'URL-friendly slug',
@@ -136,10 +134,7 @@ class SiteCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = Site
         model = Site
-        fields = [
-            'name', 'slug', 'region', 'tenant', 'facility', 'asn', 'physical_address', 'shipping_address',
-            'contact_name', 'contact_phone', 'contact_email', 'comments',
-        ]
+        fields = Site.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Site name',
             'name': 'Site name',
             'slug': 'URL-friendly slug',
             'slug': 'URL-friendly slug',
@@ -196,9 +191,7 @@ class RackGroupCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = RackGroup
         model = RackGroup
-        fields = [
-            'site', 'name', 'slug',
-        ]
+        fields = RackGroup.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Name of rack group',
             'name': 'Name of rack group',
             'slug': 'URL-friendly slug',
             'slug': 'URL-friendly slug',
@@ -226,7 +219,7 @@ class RackRoleCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = RackRole
         model = RackRole
-        fields = ['name', 'slug', 'color']
+        fields = RackRole.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Name of rack role',
             'name': 'Name of rack role',
             'color': 'RGB color in hexadecimal (e.g. 00ff00)'
             'color': 'RGB color in hexadecimal (e.g. 00ff00)'
@@ -313,10 +306,7 @@ class RackCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = Rack
         model = Rack
-        fields = [
-            'site', 'group_name', 'name', 'facility_id', 'tenant', 'role', 'serial', 'type', 'width', 'u_height',
-            'desc_units',
-        ]
+        fields = Rack.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Rack name',
             'name': 'Rack name',
             'u_height': 'Height in rack units',
             'u_height': 'Height in rack units',
@@ -444,9 +434,7 @@ class ManufacturerForm(BootstrapMixin, forms.ModelForm):
 class ManufacturerCSVForm(forms.ModelForm):
 class ManufacturerCSVForm(forms.ModelForm):
     class Meta:
     class Meta:
         model = Manufacturer
         model = Manufacturer
-        fields = [
-            'name', 'slug'
-        ]
+        fields = Manufacturer.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Manufacturer name',
             'name': 'Manufacturer name',
             'slug': 'URL-friendly slug',
             'slug': 'URL-friendly slug',
@@ -492,8 +480,7 @@ class DeviceTypeCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = DeviceType
         model = DeviceType
-        fields = ['manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'is_console_server',
-                  'is_pdu', 'is_network_device', 'subdevice_role', 'interface_ordering', 'comments']
+        fields = DeviceType.csv_headers
         help_texts = {
         help_texts = {
             'model': 'Model name',
             'model': 'Model name',
             'slug': 'URL-friendly slug',
             'slug': 'URL-friendly slug',
@@ -658,7 +645,7 @@ class DeviceRoleCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = DeviceRole
         model = DeviceRole
-        fields = ['name', 'slug', 'color', 'vm_role']
+        fields = DeviceRole.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Name of device role',
             'name': 'Name of device role',
             'color': 'RGB color in hexadecimal (e.g. 00ff00)'
             'color': 'RGB color in hexadecimal (e.g. 00ff00)'
@@ -682,7 +669,7 @@ class PlatformCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = Platform
         model = Platform
-        fields = ['name', 'slug', 'napalm_driver']
+        fields = Platform.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Platform name',
             'name': 'Platform name',
         }
         }
@@ -932,7 +919,7 @@ class DeviceCSVForm(BaseDeviceCSVForm):
     class Meta(BaseDeviceCSVForm.Meta):
     class Meta(BaseDeviceCSVForm.Meta):
         fields = [
         fields = [
             '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', 'cluster',
+            'site', 'rack_group', 'rack_name', 'position', 'face', 'cluster', 'comments',
         ]
         ]
 
 
     def clean(self):
     def clean(self):
@@ -981,7 +968,7 @@ class ChildDeviceCSVForm(BaseDeviceCSVForm):
     class Meta(BaseDeviceCSVForm.Meta):
     class Meta(BaseDeviceCSVForm.Meta):
         fields = [
         fields = [
             'name', 'device_role', 'tenant', 'manufacturer', 'model_name', 'platform', 'serial', 'asset_tag', 'status',
             'name', 'device_role', 'tenant', 'manufacturer', 'model_name', 'platform', 'serial', 'asset_tag', 'status',
-            'parent', 'device_bay_name', 'cluster',
+            'parent', 'device_bay_name', 'cluster', 'comments',
         ]
         ]
 
 
     def clean(self):
     def clean(self):
@@ -1808,7 +1795,7 @@ class InterfaceConnectionCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = InterfaceConnection
         model = InterfaceConnection
-        fields = ['device_a', 'interface_a', 'device_b', 'interface_b', 'connection_status']
+        fields = InterfaceConnection.csv_headers
 
 
     def clean_interface_a(self):
     def clean_interface_a(self):
 
 
@@ -1951,7 +1938,7 @@ class InventoryItemCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = InventoryItem
         model = InventoryItem
-        fields = ['device', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description']
+        fields = InventoryItem.csv_headers
 
 
 
 
 class InventoryItemBulkEditForm(BootstrapMixin, BulkEditForm):
 class InventoryItemBulkEditForm(BootstrapMixin, BulkEditForm):

+ 45 - 18
netbox/dcim/models.py

@@ -42,9 +42,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']
@@ -97,7 +95,8 @@ class Site(CreatedUpdatedModel, CustomFieldModel):
     objects = SiteManager()
     objects = SiteManager()
 
 
     csv_headers = [
     csv_headers = [
-        'name', 'slug', 'region', 'tenant', 'facility', 'asn', 'contact_name', 'contact_phone', 'contact_email',
+        'name', 'slug', 'region', 'tenant', 'facility', 'asn', 'physical_address', 'shipping_address', 'contact_name',
+        'contact_phone', 'contact_email', 'comments',
     ]
     ]
 
 
     class Meta:
     class Meta:
@@ -117,9 +116,12 @@ class Site(CreatedUpdatedModel, CustomFieldModel):
             self.tenant.name if self.tenant else None,
             self.tenant.name if self.tenant else None,
             self.facility,
             self.facility,
             self.asn,
             self.asn,
+            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,
         )
         )
 
 
     @property
     @property
@@ -163,9 +165,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']
@@ -197,6 +197,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']
 
 
@@ -206,6 +208,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):
 
 
@@ -241,7 +250,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,6 +312,7 @@ class Rack(CreatedUpdatedModel, CustomFieldModel):
             self.width,
             self.width,
             self.u_height,
             self.u_height,
             self.desc_units,
             self.desc_units,
+            self.comments,
         )
         )
 
 
     @property
     @property
@@ -478,9 +488,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']
@@ -538,7 +546,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:
@@ -573,6 +581,7 @@ 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):
@@ -753,6 +762,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']
 
 
@@ -762,6 +773,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):
@@ -777,6 +796,8 @@ class Platform(models.Model):
     rpc_client = models.CharField(max_length=30, choices=RPC_CLIENT_CHOICES, blank=True,
     rpc_client = models.CharField(max_length=30, choices=RPC_CLIENT_CHOICES, blank=True,
                                   verbose_name='Legacy RPC client')
                                   verbose_name='Legacy RPC client')
 
 
+    csv_headers = ['name', 'slug', 'napalm_driver']
+
     class Meta:
     class Meta:
         ordering = ['name']
         ordering = ['name']
 
 
@@ -786,6 +807,13 @@ 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.napalm_driver,
+        )
+
 
 
 class DeviceManager(NaturalOrderByManager):
 class DeviceManager(NaturalOrderByManager):
 
 
@@ -847,7 +875,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:
@@ -1003,6 +1031,7 @@ 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
@@ -1075,7 +1104,6 @@ class ConsolePort(models.Model):
     def __str__(self):
     def __str__(self):
         return self.name
         return self.name
 
 
-    # Used for connections export
     def to_csv(self):
     def to_csv(self):
         return (
         return (
             self.cs_port.device.identifier if self.cs_port else None,
             self.cs_port.device.identifier if self.cs_port else None,
@@ -1152,7 +1180,6 @@ class PowerPort(models.Model):
     def __str__(self):
     def __str__(self):
         return self.name
         return self.name
 
 
-    # Used for connections export
     def to_csv(self):
     def to_csv(self):
         return (
         return (
             self.power_outlet.device.identifier if self.power_outlet else None,
             self.power_outlet.device.identifier if self.power_outlet else None,
@@ -1381,7 +1408,6 @@ class InterfaceConnection(models.Model):
         except ObjectDoesNotExist:
         except ObjectDoesNotExist:
             pass
             pass
 
 
-    # Used for connections export
     def to_csv(self):
     def to_csv(self):
         return (
         return (
             self.interface_a.device.identifier,
             self.interface_a.device.identifier,
@@ -1452,7 +1478,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:
@@ -1470,5 +1496,6 @@ class InventoryItem(models.Model):
             self.part_id,
             self.part_id,
             self.serial,
             self.serial,
             self.asset_tag,
             self.asset_tag,
-            self.description
+            self.discovered,
+            self.description,
         )
         )

+ 8 - 13
netbox/ipam/forms.py

@@ -57,7 +57,7 @@ class VRFCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = VRF
         model = VRF
-        fields = ['name', 'rd', 'tenant', 'enforce_unique', 'description']
+        fields = VRF.csv_headers
         help_texts = {
         help_texts = {
             'name': 'VRF name',
             'name': 'VRF name',
         }
         }
@@ -102,7 +102,7 @@ class RIRCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = RIR
         model = RIR
-        fields = ['name', 'slug', 'is_private']
+        fields = RIR.csv_headers
         help_texts = {
         help_texts = {
             'name': 'RIR name',
             'name': 'RIR name',
         }
         }
@@ -144,7 +144,7 @@ class AggregateCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = Aggregate
         model = Aggregate
-        fields = ['prefix', 'rir', 'date_added', 'description']
+        fields = Aggregate.csv_headers
 
 
 
 
 class AggregateBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
 class AggregateBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
@@ -185,7 +185,7 @@ class RoleCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = Role
         model = Role
-        fields = ['name', 'slug']
+        fields = Role.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Role name',
             'name': 'Role name',
         }
         }
@@ -299,9 +299,7 @@ class PrefixCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = Prefix
         model = Prefix
-        fields = [
-            'prefix', 'vrf', 'tenant', 'site', 'vlan_group', 'vlan_vid', 'status', 'role', 'is_pool', 'description',
-        ]
+        fields = Prefix.csv_headers
 
 
     def clean(self):
     def clean(self):
 
 
@@ -609,10 +607,7 @@ class IPAddressCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = IPAddress
         model = IPAddress
-        fields = [
-            'address', 'vrf', 'tenant', 'status', 'role', 'device', 'virtual_machine', 'interface_name', 'is_primary',
-            'description',
-        ]
+        fields = IPAddress.csv_headers
 
 
     def clean(self):
     def clean(self):
 
 
@@ -759,7 +754,7 @@ class VLANGroupCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = VLANGroup
         model = VLANGroup
-        fields = ['site', 'name', 'slug']
+        fields = VLANGroup.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Name of VLAN group',
             'name': 'Name of VLAN group',
         }
         }
@@ -849,7 +844,7 @@ class VLANCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = VLAN
         model = VLAN
-        fields = ['site', 'group_name', 'vid', 'name', 'tenant', 'status', 'role', 'description']
+        fields = VLAN.csv_headers
         help_texts = {
         help_texts = {
             'vid': 'Numeric VLAN ID (1-4095)',
             'vid': 'Numeric VLAN ID (1-4095)',
             'name': 'VLAN name',
             'name': 'VLAN name',

+ 27 - 0
netbox/ipam/models.py

@@ -74,6 +74,8 @@ class RIR(models.Model):
     is_private = models.BooleanField(default=False, verbose_name='Private',
     is_private = models.BooleanField(default=False, verbose_name='Private',
                                      help_text='IP space managed by this RIR is considered private')
                                      help_text='IP space managed by this RIR is considered private')
 
 
+    csv_headers = ['name', 'slug', 'is_private']
+
     class Meta:
     class Meta:
         ordering = ['name']
         ordering = ['name']
         verbose_name = 'RIR'
         verbose_name = 'RIR'
@@ -85,6 +87,13 @@ class RIR(models.Model):
     def get_absolute_url(self):
     def get_absolute_url(self):
         return "{}?rir={}".format(reverse('ipam:aggregate_list'), self.slug)
         return "{}?rir={}".format(reverse('ipam:aggregate_list'), self.slug)
 
 
+    def to_csv(self):
+        return (
+            self.name,
+            self.slug,
+            self.is_private,
+        )
+
 
 
 @python_2_unicode_compatible
 @python_2_unicode_compatible
 class Aggregate(CreatedUpdatedModel, CustomFieldModel):
 class Aggregate(CreatedUpdatedModel, CustomFieldModel):
@@ -172,12 +181,21 @@ class Role(models.Model):
     slug = models.SlugField(unique=True)
     slug = models.SlugField(unique=True)
     weight = models.PositiveSmallIntegerField(default=1000)
     weight = models.PositiveSmallIntegerField(default=1000)
 
 
+    csv_headers = ['name', 'slug', 'weight']
+
     class Meta:
     class Meta:
         ordering = ['weight', 'name']
         ordering = ['weight', 'name']
 
 
     def __str__(self):
     def __str__(self):
         return self.name
         return self.name
 
 
+    def to_csv(self):
+        return (
+            self.name,
+            self.slug,
+            self.weight,
+        )
+
     @property
     @property
     def count_prefixes(self):
     def count_prefixes(self):
         return self.prefixes.count()
         return self.prefixes.count()
@@ -501,6 +519,8 @@ class VLANGroup(models.Model):
     slug = models.SlugField()
     slug = models.SlugField()
     site = models.ForeignKey('dcim.Site', related_name='vlan_groups', on_delete=models.PROTECT, blank=True, null=True)
     site = models.ForeignKey('dcim.Site', related_name='vlan_groups', on_delete=models.PROTECT, blank=True, null=True)
 
 
+    csv_headers = ['name', 'slug', 'site']
+
     class Meta:
     class Meta:
         ordering = ['site', 'name']
         ordering = ['site', 'name']
         unique_together = [
         unique_together = [
@@ -516,6 +536,13 @@ class VLANGroup(models.Model):
     def get_absolute_url(self):
     def get_absolute_url(self):
         return "{}?group_id={}".format(reverse('ipam:vlan_list'), self.pk)
         return "{}?group_id={}".format(reverse('ipam:vlan_list'), self.pk)
 
 
+    def to_csv(self):
+        return (
+            self.name,
+            self.slug,
+            self.site.name if self.site else None,
+        )
+
     def get_next_available_vid(self):
     def get_next_available_vid(self):
         """
         """
         Return the first available VLAN ID (1-4094) in the group.
         Return the first available VLAN ID (1-4094) in the group.

+ 2 - 2
netbox/secrets/forms.py

@@ -47,7 +47,7 @@ class SecretRoleCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = SecretRole
         model = SecretRole
-        fields = ['name', 'slug']
+        fields = SecretRole.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Name of secret role',
             'name': 'Name of secret role',
         }
         }
@@ -98,7 +98,7 @@ class SecretCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = Secret
         model = Secret
-        fields = ['device', 'role', 'name', 'plaintext']
+        fields = Secret.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Name or username',
             'name': 'Name or username',
         }
         }

+ 8 - 0
netbox/secrets/models.py

@@ -239,6 +239,8 @@ class SecretRole(models.Model):
     users = models.ManyToManyField(User, related_name='secretroles', blank=True)
     users = models.ManyToManyField(User, related_name='secretroles', blank=True)
     groups = models.ManyToManyField(Group, related_name='secretroles', blank=True)
     groups = models.ManyToManyField(Group, related_name='secretroles', blank=True)
 
 
+    csv_headers = ['name', 'slug']
+
     class Meta:
     class Meta:
         ordering = ['name']
         ordering = ['name']
 
 
@@ -248,6 +250,12 @@ class SecretRole(models.Model):
     def get_absolute_url(self):
     def get_absolute_url(self):
         return "{}?role={}".format(reverse('secrets:secret_list'), self.slug)
         return "{}?role={}".format(reverse('secrets:secret_list'), self.slug)
 
 
+    def to_csv(self):
+        return (
+            self.name,
+            self.slug,
+        )
+
     def has_member(self, user):
     def has_member(self, user):
         """
         """
         Check whether the given user has belongs to this SecretRole. Note that superusers belong to all roles.
         Check whether the given user has belongs to this SecretRole. Note that superusers belong to all roles.

+ 2 - 2
netbox/tenancy/forms.py

@@ -27,7 +27,7 @@ class TenantGroupCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = TenantGroup
         model = TenantGroup
-        fields = ['name', 'slug']
+        fields = TenantGroup.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Group name',
             'name': 'Group name',
         }
         }
@@ -60,7 +60,7 @@ class TenantCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = Tenant
         model = Tenant
-        fields = ['name', 'slug', 'group', 'description', 'comments']
+        fields = Tenant.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Tenant name',
             'name': 'Tenant name',
             'comments': 'Free-form comments'
             'comments': 'Free-form comments'

+ 9 - 0
netbox/tenancy/models.py

@@ -17,6 +17,8 @@ class TenantGroup(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']
+
     class Meta:
     class Meta:
         ordering = ['name']
         ordering = ['name']
 
 
@@ -26,6 +28,12 @@ class TenantGroup(models.Model):
     def get_absolute_url(self):
     def get_absolute_url(self):
         return "{}?group={}".format(reverse('tenancy:tenant_list'), self.slug)
         return "{}?group={}".format(reverse('tenancy:tenant_list'), self.slug)
 
 
+    def to_csv(self):
+        return (
+            self.name,
+            self.slug,
+        )
+
 
 
 @python_2_unicode_compatible
 @python_2_unicode_compatible
 class Tenant(CreatedUpdatedModel, CustomFieldModel):
 class Tenant(CreatedUpdatedModel, CustomFieldModel):
@@ -57,4 +65,5 @@ class Tenant(CreatedUpdatedModel, CustomFieldModel):
             self.slug,
             self.slug,
             self.group.name if self.group else None,
             self.group.name if self.group else None,
             self.description,
             self.description,
+            self.comments,
         )
         )

+ 4 - 4
netbox/virtualization/forms.py

@@ -41,7 +41,7 @@ class ClusterTypeCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = ClusterType
         model = ClusterType
-        fields = ['name', 'slug']
+        fields = ClusterType.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Name of cluster type',
             'name': 'Name of cluster type',
         }
         }
@@ -64,7 +64,7 @@ class ClusterGroupCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = ClusterGroup
         model = ClusterGroup
-        fields = ['name', 'slug']
+        fields = ClusterGroup.csv_headers
         help_texts = {
         help_texts = {
             'name': 'Name of cluster group',
             'name': 'Name of cluster group',
         }
         }
@@ -112,7 +112,7 @@ class ClusterCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = Cluster
         model = Cluster
-        fields = ['name', 'type', 'group', 'site', 'comments']
+        fields = Cluster.csv_headers
 
 
 
 
 class ClusterBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
 class ClusterBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
@@ -306,7 +306,7 @@ class VirtualMachineCSVForm(forms.ModelForm):
 
 
     class Meta:
     class Meta:
         model = VirtualMachine
         model = VirtualMachine
-        fields = ['name', 'status', 'cluster', 'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments']
+        fields = VirtualMachine.csv_headers
 
 
 
 
 class VirtualMachineBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
 class VirtualMachineBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):

+ 19 - 4
netbox/virtualization/models.py

@@ -30,6 +30,8 @@ class ClusterType(models.Model):
         unique=True
         unique=True
     )
     )
 
 
+    csv_headers = ['name', 'slug']
+
     class Meta:
     class Meta:
         ordering = ['name']
         ordering = ['name']
 
 
@@ -39,6 +41,12 @@ class ClusterType(models.Model):
     def get_absolute_url(self):
     def get_absolute_url(self):
         return "{}?type={}".format(reverse('virtualization:cluster_list'), self.slug)
         return "{}?type={}".format(reverse('virtualization:cluster_list'), self.slug)
 
 
+    def to_csv(self):
+        return (
+            self.name,
+            self.slug,
+        )
+
 
 
 #
 #
 # Cluster groups
 # Cluster groups
@@ -57,6 +65,8 @@ class ClusterGroup(models.Model):
         unique=True
         unique=True
     )
     )
 
 
+    csv_headers = ['name', 'slug']
+
     class Meta:
     class Meta:
         ordering = ['name']
         ordering = ['name']
 
 
@@ -66,6 +76,12 @@ class ClusterGroup(models.Model):
     def get_absolute_url(self):
     def get_absolute_url(self):
         return "{}?group={}".format(reverse('virtualization:cluster_list'), self.slug)
         return "{}?group={}".format(reverse('virtualization:cluster_list'), self.slug)
 
 
+    def to_csv(self):
+        return (
+            self.name,
+            self.slug,
+        )
+
 
 
 #
 #
 # Clusters
 # Clusters
@@ -108,9 +124,7 @@ class Cluster(CreatedUpdatedModel, CustomFieldModel):
         object_id_field='obj_id'
         object_id_field='obj_id'
     )
     )
 
 
-    csv_headers = [
-        'name', 'type', 'group', 'site', 'comments',
-    ]
+    csv_headers = ['name', 'type', 'group', 'site', 'comments']
 
 
     class Meta:
     class Meta:
         ordering = ['name']
         ordering = ['name']
@@ -229,7 +243,7 @@ class VirtualMachine(CreatedUpdatedModel, CustomFieldModel):
     )
     )
 
 
     csv_headers = [
     csv_headers = [
-        'name', 'status', 'cluster', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments',
+        'name', 'status', 'role', 'cluster', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments',
     ]
     ]
 
 
     class Meta:
     class Meta:
@@ -245,6 +259,7 @@ class VirtualMachine(CreatedUpdatedModel, CustomFieldModel):
         return (
         return (
             self.name,
             self.name,
             self.get_status_display(),
             self.get_status_display(),
+            self.role.name if self.role else None,
             self.cluster.name,
             self.cluster.name,
             self.tenant.name if self.tenant else None,
             self.tenant.name if self.tenant else None,
             self.platform.name if self.platform else None,
             self.platform.name if self.platform else None,