From 12e6fe1d504a0303d3362b46c521723410e21a74 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 2 Feb 2018 14:26:16 -0500 Subject: [PATCH] Standardized declaration of csv_headers on models --- netbox/circuits/forms.py | 4 +-- netbox/circuits/models.py | 16 +++++++-- netbox/dcim/forms.py | 39 +++++++------------- netbox/dcim/models.py | 63 +++++++++++++++++++++++---------- netbox/ipam/forms.py | 21 +++++------ netbox/ipam/models.py | 27 ++++++++++++++ netbox/secrets/forms.py | 4 +-- netbox/secrets/models.py | 8 +++++ netbox/tenancy/forms.py | 4 +-- netbox/tenancy/models.py | 9 +++++ netbox/virtualization/forms.py | 8 ++--- netbox/virtualization/models.py | 23 +++++++++--- 12 files changed, 153 insertions(+), 73 deletions(-) diff --git a/netbox/circuits/forms.py b/netbox/circuits/forms.py index 8acad4bb9..7afd1476e 100644 --- a/netbox/circuits/forms.py +++ b/netbox/circuits/forms.py @@ -43,7 +43,7 @@ class ProviderCSVForm(forms.ModelForm): class Meta: model = Provider - fields = ['name', 'slug', 'asn', 'account', 'portal_url', 'comments'] + fields = Provider.csv_headers help_texts = { 'name': 'Provider name', 'asn': '32-bit autonomous system number', @@ -89,7 +89,7 @@ class CircuitTypeCSVForm(forms.ModelForm): class Meta: model = CircuitType - fields = ['name', 'slug'] + fields = CircuitType.csv_headers help_texts = { 'name': 'Name of circuit type', } diff --git a/netbox/circuits/models.py b/netbox/circuits/models.py index 3b50694ca..e3a688ee5 100644 --- a/netbox/circuits/models.py +++ b/netbox/circuits/models.py @@ -28,7 +28,7 @@ class Provider(CreatedUpdatedModel, CustomFieldModel): comments = models.TextField(blank=True) 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: ordering = ['name'] @@ -46,6 +46,9 @@ class Provider(CreatedUpdatedModel, CustomFieldModel): self.asn, self.account, 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) slug = models.SlugField(unique=True) + csv_headers = ['name', 'slug'] + class Meta: ordering = ['name'] @@ -67,6 +72,12 @@ class CircuitType(models.Model): def get_absolute_url(self): return "{}?type={}".format(reverse('circuits:circuit_list'), self.slug) + def to_csv(self): + return ( + self.name, + self.slug, + ) + @python_2_unicode_compatible class Circuit(CreatedUpdatedModel, CustomFieldModel): @@ -85,7 +96,7 @@ class Circuit(CreatedUpdatedModel, CustomFieldModel): comments = models.TextField(blank=True) 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: ordering = ['provider', 'cid'] @@ -106,6 +117,7 @@ class Circuit(CreatedUpdatedModel, CustomFieldModel): self.install_date, self.commit_rate, self.description, + self.comments, ) def _get_termination(self, side): diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 98c075cd3..c756d821f 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -72,9 +72,7 @@ class RegionCSVForm(forms.ModelForm): class Meta: model = Region - fields = [ - 'name', 'slug', 'parent', - ] + fields = Region.csv_headers help_texts = { 'name': 'Region name', 'slug': 'URL-friendly slug', @@ -136,10 +134,7 @@ class SiteCSVForm(forms.ModelForm): class Meta: 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 = { 'name': 'Site name', 'slug': 'URL-friendly slug', @@ -196,9 +191,7 @@ class RackGroupCSVForm(forms.ModelForm): class Meta: model = RackGroup - fields = [ - 'site', 'name', 'slug', - ] + fields = RackGroup.csv_headers help_texts = { 'name': 'Name of rack group', 'slug': 'URL-friendly slug', @@ -226,7 +219,7 @@ class RackRoleCSVForm(forms.ModelForm): class Meta: model = RackRole - fields = ['name', 'slug', 'color'] + fields = RackRole.csv_headers help_texts = { 'name': 'Name of rack role', 'color': 'RGB color in hexadecimal (e.g. 00ff00)' @@ -313,10 +306,7 @@ class RackCSVForm(forms.ModelForm): class Meta: model = Rack - fields = [ - 'site', 'group_name', 'name', 'facility_id', 'tenant', 'role', 'serial', 'type', 'width', 'u_height', - 'desc_units', - ] + fields = Rack.csv_headers help_texts = { 'name': 'Rack name', 'u_height': 'Height in rack units', @@ -444,9 +434,7 @@ class ManufacturerForm(BootstrapMixin, forms.ModelForm): class ManufacturerCSVForm(forms.ModelForm): class Meta: model = Manufacturer - fields = [ - 'name', 'slug' - ] + fields = Manufacturer.csv_headers help_texts = { 'name': 'Manufacturer name', 'slug': 'URL-friendly slug', @@ -492,8 +480,7 @@ class DeviceTypeCSVForm(forms.ModelForm): class Meta: 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 = { 'model': 'Model name', 'slug': 'URL-friendly slug', @@ -658,7 +645,7 @@ class DeviceRoleCSVForm(forms.ModelForm): class Meta: model = DeviceRole - fields = ['name', 'slug', 'color', 'vm_role'] + fields = DeviceRole.csv_headers help_texts = { 'name': 'Name of device role', 'color': 'RGB color in hexadecimal (e.g. 00ff00)' @@ -682,7 +669,7 @@ class PlatformCSVForm(forms.ModelForm): class Meta: model = Platform - fields = ['name', 'slug', 'napalm_driver'] + fields = Platform.csv_headers help_texts = { 'name': 'Platform name', } @@ -932,7 +919,7 @@ class DeviceCSVForm(BaseDeviceCSVForm): class Meta(BaseDeviceCSVForm.Meta): fields = [ '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): @@ -981,7 +968,7 @@ class ChildDeviceCSVForm(BaseDeviceCSVForm): class Meta(BaseDeviceCSVForm.Meta): fields = [ '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): @@ -1808,7 +1795,7 @@ class InterfaceConnectionCSVForm(forms.ModelForm): class Meta: model = InterfaceConnection - fields = ['device_a', 'interface_a', 'device_b', 'interface_b', 'connection_status'] + fields = InterfaceConnection.csv_headers def clean_interface_a(self): @@ -1951,7 +1938,7 @@ class InventoryItemCSVForm(forms.ModelForm): class Meta: model = InventoryItem - fields = ['device', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description'] + fields = InventoryItem.csv_headers class InventoryItemBulkEditForm(BootstrapMixin, BulkEditForm): diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 956023061..2b33ba6fe 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -42,9 +42,7 @@ class Region(MPTTModel): name = models.CharField(max_length=50, unique=True) slug = models.SlugField(unique=True) - csv_headers = [ - 'name', 'slug', 'parent', - ] + csv_headers = ['name', 'slug', 'parent'] class MPTTMeta: order_insertion_by = ['name'] @@ -97,7 +95,8 @@ class Site(CreatedUpdatedModel, CustomFieldModel): objects = SiteManager() 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: @@ -117,9 +116,12 @@ class Site(CreatedUpdatedModel, CustomFieldModel): self.tenant.name if self.tenant else None, self.facility, self.asn, + self.physical_address, + self.shipping_address, self.contact_name, self.contact_phone, self.contact_email, + self.comments, ) @property @@ -163,9 +165,7 @@ class RackGroup(models.Model): slug = models.SlugField() site = models.ForeignKey('Site', related_name='rack_groups', on_delete=models.CASCADE) - csv_headers = [ - 'site', 'name', 'slug', - ] + csv_headers = ['site', 'name', 'slug'] class Meta: ordering = ['site', 'name'] @@ -197,6 +197,8 @@ class RackRole(models.Model): slug = models.SlugField(unique=True) color = ColorField() + csv_headers = ['name', 'slug', 'color'] + class Meta: ordering = ['name'] @@ -206,6 +208,13 @@ class RackRole(models.Model): def get_absolute_url(self): return "{}?role={}".format(reverse('dcim:rack_list'), self.slug) + def to_csv(self): + return ( + self.name, + self.slug, + self.color, + ) + class RackManager(NaturalOrderByManager): @@ -241,7 +250,7 @@ class Rack(CreatedUpdatedModel, CustomFieldModel): csv_headers = [ 'site', 'group_name', 'name', 'facility_id', 'tenant', 'role', 'type', 'serial', 'width', 'u_height', - 'desc_units', + 'desc_units', 'comments', ] class Meta: @@ -303,6 +312,7 @@ class Rack(CreatedUpdatedModel, CustomFieldModel): self.width, self.u_height, self.desc_units, + self.comments, ) @property @@ -478,9 +488,7 @@ class Manufacturer(models.Model): name = models.CharField(max_length=50, unique=True) slug = models.SlugField(unique=True) - csv_headers = [ - 'name', 'slug', - ] + csv_headers = ['name', 'slug'] class Meta: ordering = ['name'] @@ -538,7 +546,7 @@ class DeviceType(models.Model, CustomFieldModel): csv_headers = [ '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: @@ -573,6 +581,7 @@ class DeviceType(models.Model, CustomFieldModel): self.is_network_device, self.get_subdevice_role_display() if self.subdevice_role else None, self.get_interface_ordering_display(), + self.comments, ) def clean(self): @@ -753,6 +762,8 @@ class DeviceRole(models.Model): help_text="Virtual machines may be assigned to this role" ) + csv_headers = ['name', 'slug', 'color', 'vm_role'] + class Meta: ordering = ['name'] @@ -762,6 +773,14 @@ class DeviceRole(models.Model): def get_absolute_url(self): 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 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, verbose_name='Legacy RPC client') + csv_headers = ['name', 'slug', 'napalm_driver'] + class Meta: ordering = ['name'] @@ -786,6 +807,13 @@ class Platform(models.Model): def get_absolute_url(self): return "{}?platform={}".format(reverse('dcim:device_list'), self.slug) + def to_csv(self): + return ( + self.name, + self.slug, + self.napalm_driver, + ) + class DeviceManager(NaturalOrderByManager): @@ -847,7 +875,7 @@ class Device(CreatedUpdatedModel, CustomFieldModel): csv_headers = [ '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: @@ -1003,6 +1031,7 @@ class Device(CreatedUpdatedModel, CustomFieldModel): self.rack.name if self.rack else None, self.position, self.get_face_display(), + self.comments, ) @property @@ -1075,7 +1104,6 @@ class ConsolePort(models.Model): def __str__(self): return self.name - # Used for connections export def to_csv(self): return ( self.cs_port.device.identifier if self.cs_port else None, @@ -1152,7 +1180,6 @@ class PowerPort(models.Model): def __str__(self): return self.name - # Used for connections export def to_csv(self): return ( self.power_outlet.device.identifier if self.power_outlet else None, @@ -1381,7 +1408,6 @@ class InterfaceConnection(models.Model): except ObjectDoesNotExist: pass - # Used for connections export def to_csv(self): return ( self.interface_a.device.identifier, @@ -1452,7 +1478,7 @@ class InventoryItem(models.Model): description = models.CharField(max_length=100, blank=True) csv_headers = [ - 'device', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description', + 'device', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered', 'description', ] class Meta: @@ -1470,5 +1496,6 @@ class InventoryItem(models.Model): self.part_id, self.serial, self.asset_tag, - self.description + self.discovered, + self.description, ) diff --git a/netbox/ipam/forms.py b/netbox/ipam/forms.py index c67921e3e..afd533906 100644 --- a/netbox/ipam/forms.py +++ b/netbox/ipam/forms.py @@ -57,7 +57,7 @@ class VRFCSVForm(forms.ModelForm): class Meta: model = VRF - fields = ['name', 'rd', 'tenant', 'enforce_unique', 'description'] + fields = VRF.csv_headers help_texts = { 'name': 'VRF name', } @@ -102,7 +102,7 @@ class RIRCSVForm(forms.ModelForm): class Meta: model = RIR - fields = ['name', 'slug', 'is_private'] + fields = RIR.csv_headers help_texts = { 'name': 'RIR name', } @@ -144,7 +144,7 @@ class AggregateCSVForm(forms.ModelForm): class Meta: model = Aggregate - fields = ['prefix', 'rir', 'date_added', 'description'] + fields = Aggregate.csv_headers class AggregateBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm): @@ -185,7 +185,7 @@ class RoleCSVForm(forms.ModelForm): class Meta: model = Role - fields = ['name', 'slug'] + fields = Role.csv_headers help_texts = { 'name': 'Role name', } @@ -299,9 +299,7 @@ class PrefixCSVForm(forms.ModelForm): class Meta: model = Prefix - fields = [ - 'prefix', 'vrf', 'tenant', 'site', 'vlan_group', 'vlan_vid', 'status', 'role', 'is_pool', 'description', - ] + fields = Prefix.csv_headers def clean(self): @@ -609,10 +607,7 @@ class IPAddressCSVForm(forms.ModelForm): class Meta: model = IPAddress - fields = [ - 'address', 'vrf', 'tenant', 'status', 'role', 'device', 'virtual_machine', 'interface_name', 'is_primary', - 'description', - ] + fields = IPAddress.csv_headers def clean(self): @@ -759,7 +754,7 @@ class VLANGroupCSVForm(forms.ModelForm): class Meta: model = VLANGroup - fields = ['site', 'name', 'slug'] + fields = VLANGroup.csv_headers help_texts = { 'name': 'Name of VLAN group', } @@ -849,7 +844,7 @@ class VLANCSVForm(forms.ModelForm): class Meta: model = VLAN - fields = ['site', 'group_name', 'vid', 'name', 'tenant', 'status', 'role', 'description'] + fields = VLAN.csv_headers help_texts = { 'vid': 'Numeric VLAN ID (1-4095)', 'name': 'VLAN name', diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index c238a4ec0..33da470b0 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -74,6 +74,8 @@ class RIR(models.Model): is_private = models.BooleanField(default=False, verbose_name='Private', help_text='IP space managed by this RIR is considered private') + csv_headers = ['name', 'slug', 'is_private'] + class Meta: ordering = ['name'] verbose_name = 'RIR' @@ -85,6 +87,13 @@ class RIR(models.Model): def get_absolute_url(self): 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 class Aggregate(CreatedUpdatedModel, CustomFieldModel): @@ -172,12 +181,21 @@ class Role(models.Model): slug = models.SlugField(unique=True) weight = models.PositiveSmallIntegerField(default=1000) + csv_headers = ['name', 'slug', 'weight'] + class Meta: ordering = ['weight', 'name'] def __str__(self): return self.name + def to_csv(self): + return ( + self.name, + self.slug, + self.weight, + ) + @property def count_prefixes(self): return self.prefixes.count() @@ -501,6 +519,8 @@ class VLANGroup(models.Model): slug = models.SlugField() site = models.ForeignKey('dcim.Site', related_name='vlan_groups', on_delete=models.PROTECT, blank=True, null=True) + csv_headers = ['name', 'slug', 'site'] + class Meta: ordering = ['site', 'name'] unique_together = [ @@ -516,6 +536,13 @@ class VLANGroup(models.Model): def get_absolute_url(self): 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): """ Return the first available VLAN ID (1-4094) in the group. diff --git a/netbox/secrets/forms.py b/netbox/secrets/forms.py index af0ad92cc..bcc79e2a5 100644 --- a/netbox/secrets/forms.py +++ b/netbox/secrets/forms.py @@ -47,7 +47,7 @@ class SecretRoleCSVForm(forms.ModelForm): class Meta: model = SecretRole - fields = ['name', 'slug'] + fields = SecretRole.csv_headers help_texts = { 'name': 'Name of secret role', } @@ -98,7 +98,7 @@ class SecretCSVForm(forms.ModelForm): class Meta: model = Secret - fields = ['device', 'role', 'name', 'plaintext'] + fields = Secret.csv_headers help_texts = { 'name': 'Name or username', } diff --git a/netbox/secrets/models.py b/netbox/secrets/models.py index d4e9874b3..e1f367d03 100644 --- a/netbox/secrets/models.py +++ b/netbox/secrets/models.py @@ -239,6 +239,8 @@ class SecretRole(models.Model): users = models.ManyToManyField(User, related_name='secretroles', blank=True) groups = models.ManyToManyField(Group, related_name='secretroles', blank=True) + csv_headers = ['name', 'slug'] + class Meta: ordering = ['name'] @@ -248,6 +250,12 @@ class SecretRole(models.Model): def get_absolute_url(self): return "{}?role={}".format(reverse('secrets:secret_list'), self.slug) + def to_csv(self): + return ( + self.name, + self.slug, + ) + def has_member(self, user): """ Check whether the given user has belongs to this SecretRole. Note that superusers belong to all roles. diff --git a/netbox/tenancy/forms.py b/netbox/tenancy/forms.py index 00194d4e8..4ea6c57ba 100644 --- a/netbox/tenancy/forms.py +++ b/netbox/tenancy/forms.py @@ -27,7 +27,7 @@ class TenantGroupCSVForm(forms.ModelForm): class Meta: model = TenantGroup - fields = ['name', 'slug'] + fields = TenantGroup.csv_headers help_texts = { 'name': 'Group name', } @@ -60,7 +60,7 @@ class TenantCSVForm(forms.ModelForm): class Meta: model = Tenant - fields = ['name', 'slug', 'group', 'description', 'comments'] + fields = Tenant.csv_headers help_texts = { 'name': 'Tenant name', 'comments': 'Free-form comments' diff --git a/netbox/tenancy/models.py b/netbox/tenancy/models.py index f908463dc..f83e0abc9 100644 --- a/netbox/tenancy/models.py +++ b/netbox/tenancy/models.py @@ -17,6 +17,8 @@ class TenantGroup(models.Model): name = models.CharField(max_length=50, unique=True) slug = models.SlugField(unique=True) + csv_headers = ['name', 'slug'] + class Meta: ordering = ['name'] @@ -26,6 +28,12 @@ class TenantGroup(models.Model): def get_absolute_url(self): return "{}?group={}".format(reverse('tenancy:tenant_list'), self.slug) + def to_csv(self): + return ( + self.name, + self.slug, + ) + @python_2_unicode_compatible class Tenant(CreatedUpdatedModel, CustomFieldModel): @@ -57,4 +65,5 @@ class Tenant(CreatedUpdatedModel, CustomFieldModel): self.slug, self.group.name if self.group else None, self.description, + self.comments, ) diff --git a/netbox/virtualization/forms.py b/netbox/virtualization/forms.py index d697de755..34e3fd5cc 100644 --- a/netbox/virtualization/forms.py +++ b/netbox/virtualization/forms.py @@ -41,7 +41,7 @@ class ClusterTypeCSVForm(forms.ModelForm): class Meta: model = ClusterType - fields = ['name', 'slug'] + fields = ClusterType.csv_headers help_texts = { 'name': 'Name of cluster type', } @@ -64,7 +64,7 @@ class ClusterGroupCSVForm(forms.ModelForm): class Meta: model = ClusterGroup - fields = ['name', 'slug'] + fields = ClusterGroup.csv_headers help_texts = { 'name': 'Name of cluster group', } @@ -112,7 +112,7 @@ class ClusterCSVForm(forms.ModelForm): class Meta: model = Cluster - fields = ['name', 'type', 'group', 'site', 'comments'] + fields = Cluster.csv_headers class ClusterBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm): @@ -306,7 +306,7 @@ class VirtualMachineCSVForm(forms.ModelForm): class Meta: model = VirtualMachine - fields = ['name', 'status', 'cluster', 'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments'] + fields = VirtualMachine.csv_headers class VirtualMachineBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm): diff --git a/netbox/virtualization/models.py b/netbox/virtualization/models.py index 7eca5b1b8..5552fb089 100644 --- a/netbox/virtualization/models.py +++ b/netbox/virtualization/models.py @@ -30,6 +30,8 @@ class ClusterType(models.Model): unique=True ) + csv_headers = ['name', 'slug'] + class Meta: ordering = ['name'] @@ -39,6 +41,12 @@ class ClusterType(models.Model): def get_absolute_url(self): return "{}?type={}".format(reverse('virtualization:cluster_list'), self.slug) + def to_csv(self): + return ( + self.name, + self.slug, + ) + # # Cluster groups @@ -57,6 +65,8 @@ class ClusterGroup(models.Model): unique=True ) + csv_headers = ['name', 'slug'] + class Meta: ordering = ['name'] @@ -66,6 +76,12 @@ class ClusterGroup(models.Model): def get_absolute_url(self): return "{}?group={}".format(reverse('virtualization:cluster_list'), self.slug) + def to_csv(self): + return ( + self.name, + self.slug, + ) + # # Clusters @@ -108,9 +124,7 @@ class Cluster(CreatedUpdatedModel, CustomFieldModel): object_id_field='obj_id' ) - csv_headers = [ - 'name', 'type', 'group', 'site', 'comments', - ] + csv_headers = ['name', 'type', 'group', 'site', 'comments'] class Meta: ordering = ['name'] @@ -229,7 +243,7 @@ class VirtualMachine(CreatedUpdatedModel, CustomFieldModel): ) csv_headers = [ - 'name', 'status', 'cluster', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments', + 'name', 'status', 'role', 'cluster', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments', ] class Meta: @@ -245,6 +259,7 @@ class VirtualMachine(CreatedUpdatedModel, CustomFieldModel): return ( self.name, self.get_status_display(), + self.role.name if self.role else None, self.cluster.name, self.tenant.name if self.tenant else None, self.platform.name if self.platform else None,