Skip to content

Commit

Permalink
Allow import/export of device types (netbox-community#1347)
Browse files Browse the repository at this point in the history
  • Loading branch information
paravoid authored and John Anderson committed Oct 13, 2017
1 parent 994eb3c commit 34b69b6
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 3 deletions.
33 changes: 32 additions & 1 deletion netbox/dcim/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
IFACE_FF_CHOICES, IFACE_FF_LAG, IFACE_ORDERING_CHOICES, InterfaceConnection, InterfaceTemplate, Manufacturer,
InventoryItem, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, RACK_FACE_CHOICES,
RACK_TYPE_CHOICES, RACK_WIDTH_CHOICES, Rack, RackGroup, RackReservation, RackRole, RACK_WIDTH_19IN, RACK_WIDTH_23IN,
Region, Site, STATUS_CHOICES, SUBDEVICE_ROLE_CHILD, SUBDEVICE_ROLE_PARENT,
Region, Site, STATUS_CHOICES, SUBDEVICE_ROLE_CHILD, SUBDEVICE_ROLE_PARENT, SUBDEVICE_ROLE_CHOICES,
)
from .constants import *

Expand Down Expand Up @@ -446,6 +446,37 @@ class Meta:
}


class DeviceTypeCSVForm(forms.ModelForm):
manufacturer = forms.ModelChoiceField(
queryset=Manufacturer.objects.all(),
required=True,
to_field_name='name',
help_text='Manufacturer name',
error_messages={
'invalid_choice': 'Manufacturer not found.',
}
)
subdevice_role = CSVChoiceField(
choices=SUBDEVICE_ROLE_CHOICES,
required=False,
help_text='Parent/child status'
)
interface_ordering = CSVChoiceField(
choices=IFACE_ORDERING_CHOICES,
required=False,
help_text='Interface ordering'
)

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']
help_texts = {
'model': 'Model name',
'slug': 'URL-friendly slug',
}


class DeviceTypeBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
pk = forms.ModelMultipleChoiceField(queryset=DeviceType.objects.all(), widget=forms.MultipleHiddenInput)
manufacturer = forms.ModelChoiceField(queryset=Manufacturer.objects.all(), required=False)
Expand Down
20 changes: 20 additions & 0 deletions netbox/dcim/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,11 @@ class DeviceType(models.Model, CustomFieldModel):
comments = models.TextField(blank=True)
custom_field_values = GenericRelation(CustomFieldValue, content_type_field='obj_type', object_id_field='obj_id')

csv_headers = [
'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'is_console_server',
'is_pdu', 'is_network_device', 'subdevice_role', 'interface_ordering',
]

class Meta:
ordering = ['manufacturer', 'model']
unique_together = [
Expand All @@ -542,6 +547,21 @@ def __init__(self, *args, **kwargs):
def get_absolute_url(self):
return reverse('dcim:devicetype', args=[self.pk])

def to_csv(self):
return csv_format([
self.manufacturer.name,
self.model,
self.slug,
self.part_number,
self.u_height,
self.is_full_depth,
self.is_console_server,
self.is_pdu,
self.is_network_device,
self.get_subdevice_role_display() if self.subdevice_role else None,
self.get_interface_ordering_display(),
])

def clean(self):

# If editing an existing DeviceType to have a larger u_height, first validate that *all* instances of it have
Expand Down
1 change: 1 addition & 0 deletions netbox/dcim/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
# Device types
url(r'^device-types/$', views.DeviceTypeListView.as_view(), name='devicetype_list'),
url(r'^device-types/add/$', views.DeviceTypeCreateView.as_view(), name='devicetype_add'),
url(r'^device-types/import/$', views.DeviceTypeBulkImportView.as_view(), name='devicetype_import'),
url(r'^device-types/edit/$', views.DeviceTypeBulkEditView.as_view(), name='devicetype_bulk_edit'),
url(r'^device-types/delete/$', views.DeviceTypeBulkDeleteView.as_view(), name='devicetype_bulk_delete'),
url(r'^device-types/(?P<pk>\d+)/$', views.DeviceTypeView.as_view(), name='devicetype'),
Expand Down
7 changes: 7 additions & 0 deletions netbox/dcim/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,13 @@ class DeviceTypeDeleteView(PermissionRequiredMixin, ObjectDeleteView):
default_return_url = 'dcim:devicetype_list'


class DeviceTypeBulkImportView(PermissionRequiredMixin, BulkImportView):
permission_required = 'dcim.add_devicetype'
model_form = forms.DeviceTypeCSVForm
table = tables.DeviceTypeTable
default_return_url = 'dcim:devicetype_list'


class DeviceTypeBulkEditView(PermissionRequiredMixin, BulkEditView):
permission_required = 'dcim.change_devicetype'
cls = DeviceType
Expand Down
2 changes: 1 addition & 1 deletion netbox/extras/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

# Models which support export templates
EXPORTTEMPLATE_MODELS = [
'site', 'region', 'rack', 'rackgroup', 'manufacturer', 'device', # DCIM
'site', 'region', 'rack', 'rackgroup', 'manufacturer', 'devicetype', 'device', # DCIM
'consoleport', 'powerport', 'interfaceconnection', # DCIM
'aggregate', 'prefix', 'ipaddress', 'vlan', # IPAM
'provider', 'circuit', # Circuits
Expand Down
3 changes: 2 additions & 1 deletion netbox/templates/_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@
{% endif %}
<li><a href="{% url 'dcim:devicetype_list' %}"><strong>Device Types</strong></a></li>
{% if perms.dcim.add_devicetype %}
<li class="subnav"><a href="{% url 'dcim:devicetype_add' %}"><i class="fa fa-plus"></i> Add a Device Type</a></li>
<li><a href="{% url 'dcim:devicetype_add' %}"><i class="fa fa-plus" aria-hidden="true"></i> Add a Device Type</a></li>
<li><a href="{% url 'dcim:devicetype_import' %}"><i class="fa fa-download" aria-hidden="true"></i> Import Device Types</a></li>
{% endif %}
<li class="divider"></li>
<li><a href="{% url 'dcim:devicerole_list' %}"><strong>Device Roles</strong></a></li>
Expand Down
5 changes: 5 additions & 0 deletions netbox/templates/dcim/devicetype_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
<span class="fa fa-plus" aria-hidden="true"></span>
Add a device type
</a>
<a href="{% url 'dcim:devicetype_import' %}" class="btn btn-info">
<span class="fa fa-download" aria-hidden="true"></span>
Import device types
</a>
{% endif %}
{% include 'inc/export_button.html' with obj_type='devicetypes' %}
</div>
<h1>{% block title %}Device Types{% endblock %}</h1>
<div class="row">
Expand Down

0 comments on commit 34b69b6

Please sign in to comment.