From 1a8913f625c87ae19944b0fb0651af29dfbf0fc3 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 16:51:42 -0400 Subject: [PATCH 001/204] Changes to allow import of interfaces and show descriptions inline in interface...some work on description column display --- netbox/dcim/forms.py | 35 ++++++++++++++++++++++++ netbox/dcim/models.py | 11 ++++++++ netbox/dcim/tables.py | 13 +++++++++ netbox/dcim/urls.py | 1 + netbox/templates/_base.html | 3 ++ netbox/templates/dcim/device.html | 8 ++++++ netbox/templates/dcim/inc/interface.html | 5 ++++ 7 files changed, 76 insertions(+) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 440c12623..ef3ff3873 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1696,6 +1696,41 @@ class InterfaceConnectionCSVForm(forms.ModelForm): return interface +class InterfaceCSVForm(forms.ModelForm): + device = FlexibleModelChoiceField( + queryset=Device.objects.all(), + to_field_name='name', + help_text='Name or ID of device', + error_messages={'invalid_choice': 'Device not found.'} + ) + name = forms.CharField( + help_text='Name of interface' + ) + mac_address = forms.CharField( + required=False, + help_text='MAC address of interface' + ) + description = forms.CharField( + required=False, + help_text='Description for interface' + ) + + class Meta: + model = Interface + fields = [ + 'device', 'name', 'mac_address', 'description' + ] + + + def clean_interface(self): + + interface_name = self.cleaned_data.get('interface_name') + if not interface: + return None + + return interface + + class InterfaceConnectionDeletionForm(ConfirmationForm): # Used for HTTP redirect upon successful deletion device = forms.ModelChoiceField(queryset=Device.objects.all(), widget=forms.HiddenInput(), required=False) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 8dd11e663..43e3d561f 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -1233,6 +1233,17 @@ class Interface(models.Model): pass return None + # Used for export + def to_csv(self): + return csv_format([ + self.device.identifier, + self.lag, + self.name, + self.mac, + self.form_factor, + self.description, + ]) + class InterfaceConnection(models.Model): """ diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 427f0bb42..087473b11 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -523,3 +523,16 @@ class InterfaceConnectionTable(BaseTable): class Meta(BaseTable.Meta): model = Interface fields = ('device_a', 'interface_a', 'device_b', 'interface_b') + + +class InterfaceImportTable(BaseTable): + device = tables.LinkColumn('dcim:device', accessor=Accessor('interface.device'), + args=[Accessor('interface.device.pk')], verbose_name='Device') + name = tables.Column(verbose_name='Interface') + form_factor = tables.Column(verbose_name='Form Factor') + mac_address = tables.Column(verbose_name='MAC Address') + description = tables.Column(verbose_name='Description') + + class Meta(BaseTable.Meta): + model = Interface + fields = ('device', 'name', 'form_factor','mac_address', 'description') diff --git a/netbox/dcim/urls.py b/netbox/dcim/urls.py index 172f634fb..dbf85292b 100644 --- a/netbox/dcim/urls.py +++ b/netbox/dcim/urls.py @@ -177,6 +177,7 @@ urlpatterns = [ url(r'^interface-connections/(?P\d+)/delete/$', views.interfaceconnection_delete, name='interfaceconnection_delete'), url(r'^interfaces/(?P\d+)/edit/$', views.InterfaceEditView.as_view(), name='interface_edit'), url(r'^interfaces/(?P\d+)/delete/$', views.InterfaceDeleteView.as_view(), name='interface_delete'), + url(r'^interfaces/import/$', views.InterfacesBulkImportView.as_view(), name='interfaces_import'), # Device bays url(r'^devices/device-bays/add/$', views.DeviceBulkAddDeviceBayView.as_view(), name='device_bulk_add_devicebay'), diff --git a/netbox/templates/_base.html b/netbox/templates/_base.html index 10b4970a8..134ffff4e 100644 --- a/netbox/templates/_base.html +++ b/netbox/templates/_base.html @@ -85,6 +85,9 @@
  • Add a Device
  • Import Devices
  • {% endif %} + {% if perms.dcim.add_interface %} +
  • Import Interfaces
  • + {% endif %} {% if perms.ipam.add_device or perms.ipam.add_devicetype %}
  • {% endif %} diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html index 3bf92fbca..ce18148c5 100644 --- a/netbox/templates/dcim/device.html +++ b/netbox/templates/dcim/device.html @@ -374,6 +374,14 @@ {% endif %}
    +
    + {% if perms.dcim.add_interface %} + + + Import Interfaces + + {% endif %} + {% include 'inc/export_button.html' with obj_type='interfaces' %}
    Interfaces
    diff --git a/netbox/templates/dcim/inc/interface.html b/netbox/templates/dcim/inc/interface.html index 75d0f027d..bdda8eace 100644 --- a/netbox/templates/dcim/inc/interface.html +++ b/netbox/templates/dcim/inc/interface.html @@ -13,6 +13,11 @@ {% if iface.description %} {% endif %} + + {% if iface.description %} + {{ iface.description }} + {% endif %} + {{ iface.mtu|default:"" }} {{ iface.mac_address|default:"" }} From ac8a23bd8a2c51fbffc4cce50e98081a09cd2649 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 18:07:07 -0400 Subject: [PATCH 002/204] Missed InterfacesBulkImportView changes. --- netbox/dcim/views.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index ea07138d5..1f1586036 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1838,6 +1838,13 @@ class InterfaceConnectionsBulkImportView(PermissionRequiredMixin, BulkImportView default_return_url = 'dcim:interface_connections_list' +class InterfacesBulkImportView(PermissionRequiredMixin, BulkImportView): + permission_required = 'dcim.change_interface' + model_form = forms.InterfaceCSVForm + table = tables.InterfaceImportTable + default_return_url = 'dcim:device_list' + + # # Connections # From f49a4074518f868f323cb7d5e756743bdb75b28d Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 19:54:35 -0400 Subject: [PATCH 003/204] Adding export interface and interface list views --- netbox/dcim/forms.py | 75 ++++++++++++----------- netbox/dcim/urls.py | 3 +- netbox/dcim/views.py | 23 ++++--- netbox/templates/_base.html | 2 +- netbox/templates/dcim/device.html | 2 +- netbox/templates/dcim/interface_list.html | 24 ++++++++ 6 files changed, 84 insertions(+), 45 deletions(-) create mode 100644 netbox/templates/dcim/interface_list.html diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index ef3ff3873..0f697a276 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1531,6 +1531,46 @@ class InterfaceBulkDisconnectForm(ConfirmationForm): pk = forms.ModelMultipleChoiceField(queryset=Interface.objects.all(), widget=forms.MultipleHiddenInput) +class InterfaceCSVForm(forms.ModelForm): + device = FlexibleModelChoiceField( + queryset=Device.objects.all(), + to_field_name='name', + help_text='Name or ID of device', + error_messages={'invalid_choice': 'Device not found.'} + ) + name = forms.CharField( + help_text='Name of interface' + ) + mac_address = forms.CharField( + required=False, + help_text='MAC address of interface' + ) + description = forms.CharField( + required=False, + help_text='Description for interface' + ) + + class Meta: + model = Interface + fields = [ + 'device', 'name', 'mac_address', 'description' + ] + + + def clean_interface(self): + + interface_name = self.cleaned_data.get('interface_name') + if not interface: + return None + + return interface + + +class InterfaceFilterForm(BootstrapMixin, forms.Form): + site = forms.ModelChoiceField(required=False, queryset=Site.objects.all(), to_field_name='slug') + device = forms.CharField(required=False, label='Device name') + + # # Interface connections # @@ -1696,41 +1736,6 @@ class InterfaceConnectionCSVForm(forms.ModelForm): return interface -class InterfaceCSVForm(forms.ModelForm): - device = FlexibleModelChoiceField( - queryset=Device.objects.all(), - to_field_name='name', - help_text='Name or ID of device', - error_messages={'invalid_choice': 'Device not found.'} - ) - name = forms.CharField( - help_text='Name of interface' - ) - mac_address = forms.CharField( - required=False, - help_text='MAC address of interface' - ) - description = forms.CharField( - required=False, - help_text='Description for interface' - ) - - class Meta: - model = Interface - fields = [ - 'device', 'name', 'mac_address', 'description' - ] - - - def clean_interface(self): - - interface_name = self.cleaned_data.get('interface_name') - if not interface: - return None - - return interface - - class InterfaceConnectionDeletionForm(ConfirmationForm): # Used for HTTP redirect upon successful deletion device = forms.ModelChoiceField(queryset=Device.objects.all(), widget=forms.HiddenInput(), required=False) diff --git a/netbox/dcim/urls.py b/netbox/dcim/urls.py index dbf85292b..f578728f0 100644 --- a/netbox/dcim/urls.py +++ b/netbox/dcim/urls.py @@ -177,7 +177,8 @@ urlpatterns = [ url(r'^interface-connections/(?P\d+)/delete/$', views.interfaceconnection_delete, name='interfaceconnection_delete'), url(r'^interfaces/(?P\d+)/edit/$', views.InterfaceEditView.as_view(), name='interface_edit'), url(r'^interfaces/(?P\d+)/delete/$', views.InterfaceDeleteView.as_view(), name='interface_delete'), - url(r'^interfaces/import/$', views.InterfacesBulkImportView.as_view(), name='interfaces_import'), + url(r'^interfaces/$', views.InterfaceListView.as_view(), name='interface_list'), + url(r'^interfaces/import/$', views.InterfacesBulkImportView.as_view(), name='interface_import'), # Device bays url(r'^devices/device-bays/add/$', views.DeviceBulkAddDeviceBayView.as_view(), name='device_bulk_add_devicebay'), diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 1f1586036..2a993c3b9 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1548,6 +1548,22 @@ class InterfaceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): table = tables.InterfaceTable +class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): + permission_required = 'dcim.change_interface' + model_form = forms.InterfaceCSVForm + table = tables.InterfaceImportTable + default_return_url = 'dcim:interface_list' + + +class InterfaceListView(ObjectListView): + queryset = InterfaceConnection.objects.select_related('device')\ + .order_by('device', 'interface') + filter = filters.InterfaceFilter + filter_form = forms.InterfaceFilterForm + table = tables.InterfaceTable + template_name = 'dcim/interface_list.html' + + # # Device bays # @@ -1838,13 +1854,6 @@ class InterfaceConnectionsBulkImportView(PermissionRequiredMixin, BulkImportView default_return_url = 'dcim:interface_connections_list' -class InterfacesBulkImportView(PermissionRequiredMixin, BulkImportView): - permission_required = 'dcim.change_interface' - model_form = forms.InterfaceCSVForm - table = tables.InterfaceImportTable - default_return_url = 'dcim:device_list' - - # # Connections # diff --git a/netbox/templates/_base.html b/netbox/templates/_base.html index 134ffff4e..844d39295 100644 --- a/netbox/templates/_base.html +++ b/netbox/templates/_base.html @@ -86,7 +86,7 @@
  • Import Devices
  • {% endif %} {% if perms.dcim.add_interface %} -
  • Import Interfaces
  • +
  • Import Interfaces
  • {% endif %} {% if perms.ipam.add_device or perms.ipam.add_devicetype %}
  • diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html index ce18148c5..3e055333c 100644 --- a/netbox/templates/dcim/device.html +++ b/netbox/templates/dcim/device.html @@ -376,7 +376,7 @@
    {% if perms.dcim.add_interface %} - + Import Interfaces diff --git a/netbox/templates/dcim/interface_list.html b/netbox/templates/dcim/interface_list.html new file mode 100644 index 000000000..7e2def732 --- /dev/null +++ b/netbox/templates/dcim/interface_list.html @@ -0,0 +1,24 @@ +{% extends '_base.html' %} + +{% block title %}Interfaces{% endblock %} + +{% block content %} +
    + {% if perms.dcim.add_interfaces %} + + + Import Interfaces + + {% endif %} + {% include 'inc/export_button.html' with obj_type='interface' %} +
    +

    Interface Connections

    +
    +
    + {% include 'responsive_table.html' %} +
    +
    + {% include 'inc/search_panel.html' %} +
    +
    +{% endblock %} From 61a12c5850b8d3d22718d024911ab8c96dbf86c6 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 20:07:33 -0400 Subject: [PATCH 004/204] Fix a heading --- netbox/templates/dcim/interface_list.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/templates/dcim/interface_list.html b/netbox/templates/dcim/interface_list.html index 7e2def732..f0abed36b 100644 --- a/netbox/templates/dcim/interface_list.html +++ b/netbox/templates/dcim/interface_list.html @@ -12,7 +12,7 @@ {% endif %} {% include 'inc/export_button.html' with obj_type='interface' %}
    -

    Interface Connections

    +

    Interfaces

    {% include 'responsive_table.html' %} From be9896733614709af5c22c3ad493d0e5531f7d22 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 20:24:32 -0400 Subject: [PATCH 005/204] Fixed reference to InterfaceBulkImportView --- netbox/dcim/urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/urls.py b/netbox/dcim/urls.py index f578728f0..6ef058bf9 100644 --- a/netbox/dcim/urls.py +++ b/netbox/dcim/urls.py @@ -178,7 +178,7 @@ urlpatterns = [ url(r'^interfaces/(?P\d+)/edit/$', views.InterfaceEditView.as_view(), name='interface_edit'), url(r'^interfaces/(?P\d+)/delete/$', views.InterfaceDeleteView.as_view(), name='interface_delete'), url(r'^interfaces/$', views.InterfaceListView.as_view(), name='interface_list'), - url(r'^interfaces/import/$', views.InterfacesBulkImportView.as_view(), name='interface_import'), + url(r'^interfaces/import/$', views.InterfaceBulkImportView.as_view(), name='interface_import'), # Device bays url(r'^devices/device-bays/add/$', views.DeviceBulkAddDeviceBayView.as_view(), name='device_bulk_add_devicebay'), From d4dd073b840cdb54143e2495ac46502fa4a99124 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 20:50:31 -0400 Subject: [PATCH 006/204] Fix object type --- netbox/templates/dcim/interface_list.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/templates/dcim/interface_list.html b/netbox/templates/dcim/interface_list.html index f0abed36b..f004a2e97 100644 --- a/netbox/templates/dcim/interface_list.html +++ b/netbox/templates/dcim/interface_list.html @@ -10,7 +10,7 @@ Import Interfaces {% endif %} - {% include 'inc/export_button.html' with obj_type='interface' %} + {% include 'inc/export_button.html' with obj_type='interfaces' %}

    Interfaces

    From 20f03db8e53913475f4d1957ed61d4409f434e83 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 20:53:38 -0400 Subject: [PATCH 007/204] Fix InterfaceListView queryset --- netbox/dcim/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 2a993c3b9..097bc44e0 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1556,7 +1556,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): - queryset = InterfaceConnection.objects.select_related('device')\ + queryset = Interface.objects.select_related('device')\ .order_by('device', 'interface') filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm From 306f0a84e9090ad85f43518467d284cc3b813d2d Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 21:12:36 -0400 Subject: [PATCH 008/204] . --- netbox/dcim/views.py | 4 ++-- netbox/templates/_base.html | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 097bc44e0..df5afe564 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1556,8 +1556,8 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): - queryset = Interface.objects.select_related('device')\ - .order_by('device', 'interface') + queryset = Interface.objects.select_related('device', 'name', 'description')\ + .order_by('device', 'name', 'description') filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm table = tables.InterfaceTable diff --git a/netbox/templates/_base.html b/netbox/templates/_base.html index 844d39295..dd7e319e6 100644 --- a/netbox/templates/_base.html +++ b/netbox/templates/_base.html @@ -85,6 +85,7 @@
  • Add a Device
  • Import Devices
  • {% endif %} +
  • Interfaces
  • {% if perms.dcim.add_interface %}
  • Import Interfaces
  • {% endif %} From df59845c17f6181345586867011b8ee9407469c7 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 21:50:00 -0400 Subject: [PATCH 009/204] Fixed permission value and working on queryset options for export --- netbox/dcim/views.py | 4 ++-- netbox/templates/dcim/interface_list.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index df5afe564..d79e8b035 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1556,8 +1556,8 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): - queryset = Interface.objects.select_related('device', 'name', 'description')\ - .order_by('device', 'name', 'description') + queryset = Interface.objects.select_related('device', 'interface__device')\ + .order_by('device__name', 'interface__name', 'interface__description') filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm table = tables.InterfaceTable diff --git a/netbox/templates/dcim/interface_list.html b/netbox/templates/dcim/interface_list.html index f004a2e97..f3346980a 100644 --- a/netbox/templates/dcim/interface_list.html +++ b/netbox/templates/dcim/interface_list.html @@ -4,7 +4,7 @@ {% block content %}
    - {% if perms.dcim.add_interfaces %} + {% if perms.dcim.add_interface %} Import Interfaces From 44f8bc47e88f2b417a5b93386a1d041b814e28da Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 22:19:21 -0400 Subject: [PATCH 010/204] Added InterfaceListTable for queryset and updated view InterfaceViewList --- netbox/dcim/tables.py | 13 +++++++++++++ netbox/dcim/views.py | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 087473b11..b0872b843 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -536,3 +536,16 @@ class InterfaceImportTable(BaseTable): class Meta(BaseTable.Meta): model = Interface fields = ('device', 'name', 'form_factor','mac_address', 'description') + + +class InterfaceListTable(BaseTable): + device = tables.LinkColumn('dcim:device', accessor=Accessor('interface.device'), + args=[Accessor('interface.device.pk')], verbose_name='Device') + name = tables.Column(verbose_name='Interface') + form_factor = tables.Column(verbose_name='Form Factor') + mac_address = tables.Column(verbose_name='MAC Address') + description = tables.Column(verbose_name='Description') + + class Meta(BaseTable.Meta): + model = Interface + fields = ('device', 'name', 'form_factor','mac_address', 'description') diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index d79e8b035..3f12071e8 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1557,10 +1557,10 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): queryset = Interface.objects.select_related('device', 'interface__device')\ - .order_by('device__name', 'interface__name', 'interface__description') + .order_by('device', 'interface__name', 'interface__description') filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm - table = tables.InterfaceTable + table = tables.InterfaceListTable template_name = 'dcim/interface_list.html' From 3079acc132e6de09d195a285e83b1851d062568b Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 22:32:44 -0400 Subject: [PATCH 011/204] More with select_related --- netbox/dcim/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 3f12071e8..37c44d0ef 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1556,7 +1556,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): - queryset = Interface.objects.select_related('device', 'interface__device')\ + queryset = Interface.objects.select_related('device')\ .order_by('device', 'interface__name', 'interface__description') filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm From 7e9d0522484c97d359f9af11fae3eecc8d1beab8 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 22:46:14 -0400 Subject: [PATCH 012/204] Remove queryset to test output --- netbox/dcim/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 37c44d0ef..d81a71c59 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1556,8 +1556,8 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): - queryset = Interface.objects.select_related('device')\ - .order_by('device', 'interface__name', 'interface__description') + #queryset = Interface.objects.select_related('device')\ + # .order_by('device', 'interface__name', 'interface__description') filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm table = tables.InterfaceListTable From 836dc37ee11dd8e465cf43e7afdf800440c52c49 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 22:54:42 -0400 Subject: [PATCH 013/204] Change queryset to test output --- netbox/dcim/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index d81a71c59..388c830c8 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1556,8 +1556,8 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): - #queryset = Interface.objects.select_related('device')\ - # .order_by('device', 'interface__name', 'interface__description') + queryset = Interface.objects.select_related('device').filter(interface__isnull=False)\\ + .order_by('interface__device__name', 'interface__name') filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm table = tables.InterfaceListTable From 39a9c1a7239cf1aa29257d516de834b4094a41e5 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 23:01:50 -0400 Subject: [PATCH 014/204] Bad character --- netbox/dcim/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 388c830c8..55d494e74 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1556,7 +1556,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): - queryset = Interface.objects.select_related('device').filter(interface__isnull=False)\\ + queryset = Interface.objects.select_related('device').filter(interface__isnull=False)\ .order_by('interface__device__name', 'interface__name') filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm From 8475f788028381ba6267f43a90610d1d0a6a6fc3 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 1 Aug 2017 23:10:57 -0400 Subject: [PATCH 015/204] Switch to all() --- netbox/dcim/views.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 55d494e74..d31509acb 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1556,8 +1556,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): - queryset = Interface.objects.select_related('device').filter(interface__isnull=False)\ - .order_by('interface__device__name', 'interface__name') + queryset = Interface.objects.all() filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm table = tables.InterfaceListTable From 2232b0425674eb32b5d734ee8397d6a04e62b1f1 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Wed, 2 Aug 2017 17:44:33 -0400 Subject: [PATCH 016/204] Trying select_related again. --- netbox/dcim/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index d31509acb..02b4a0d01 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1556,7 +1556,8 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): - queryset = Interface.objects.all() + #queryset = Interface.objects.all() + queryset = Interface.objects.select_related('device__name') filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm table = tables.InterfaceListTable From 9fccbc5c3c0d107bb77b94f3ff080fdab6cca609 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Wed, 2 Aug 2017 18:18:43 -0400 Subject: [PATCH 017/204] More attempts to fix InterfaceListView --- netbox/dcim/models.py | 2 +- netbox/dcim/views.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 43e3d561f..d0fa2cf94 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -1239,7 +1239,7 @@ class Interface(models.Model): self.device.identifier, self.lag, self.name, - self.mac, + self.mac_address, self.form_factor, self.description, ]) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 02b4a0d01..fd89fc5f1 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1556,8 +1556,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): - #queryset = Interface.objects.all() - queryset = Interface.objects.select_related('device__name') + queryset = Interface.objects.all().filter(device=device) filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm table = tables.InterfaceListTable From 3f6cba446ce76a09dec12231b938ff502b47492a Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 3 Aug 2017 01:36:23 -0400 Subject: [PATCH 018/204] Working on table view --- netbox/dcim/models.py | 7 +++++++ netbox/dcim/views.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index d0fa2cf94..6ae36657e 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -1241,7 +1241,14 @@ class Interface(models.Model): self.name, self.mac_address, self.form_factor, + self.enabled, self.description, + self.mtu, + self.mgmt_only, + self.is_virtual, + self.is_wireless, + self.is_connected, + self.is_lag, ]) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index fd89fc5f1..d31509acb 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1556,7 +1556,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): - queryset = Interface.objects.all().filter(device=device) + queryset = Interface.objects.all() filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm table = tables.InterfaceListTable From 01856f499026909574c1b74bfa4de71294f2bbd3 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 3 Aug 2017 03:25:48 -0400 Subject: [PATCH 019/204] Changes to tables for InterfaceListView --- netbox/dcim/tables.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index b0872b843..46cb9a40d 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -539,13 +539,15 @@ class InterfaceImportTable(BaseTable): class InterfaceListTable(BaseTable): + pk = ToggleColumn() device = tables.LinkColumn('dcim:device', accessor=Accessor('interface.device'), args=[Accessor('interface.device.pk')], verbose_name='Device') - name = tables.Column(verbose_name='Interface') + name = tables.TemplateColumn(template_code=INTERFACE_LINK, verbose_name='Interface') + enabled = tables.TemplateColumn(template_code=INTERFACE_ENABLED, verbose_name='Enabled') form_factor = tables.Column(verbose_name='Form Factor') mac_address = tables.Column(verbose_name='MAC Address') - description = tables.Column(verbose_name='Description') + description = tables.TemplateColumn(template_code=INTERFACE_LINK, verbose_name='Description') class Meta(BaseTable.Meta): model = Interface - fields = ('device', 'name', 'form_factor','mac_address', 'description') + fields = ('pk','device', 'name', 'form_factor','mac_address', 'description') From 34c3c2e10ed640a182f4b88ac1ef1d2f2f389917 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 3 Aug 2017 03:49:44 -0400 Subject: [PATCH 020/204] Fix template references --- netbox/dcim/tables.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 46cb9a40d..8e6069270 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -39,6 +39,12 @@ DEVICE_LINK = """ """ +INTERFACE_LINK = """ + + {{ record.name|default:'--' }} + +""" + REGION_ACTIONS = """ {% if perms.dcim.change_region %} @@ -97,6 +103,10 @@ DEVICE_STATUS = """ {{ record.get_status_display }} """ +INTERFACE_ENABLED = """ +{{ record.is_enabled }} +""" + DEVICE_PRIMARY_IP = """ {{ record.primary_ip6.address.ip|default:"" }} {% if record.primary_ip6 and record.primary_ip4 %}
    {% endif %} From f7d371741396e2ef1b73884f0e8371139f172101 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 3 Aug 2017 04:06:06 -0400 Subject: [PATCH 021/204] Revert description column --- netbox/dcim/tables.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 8e6069270..8b0507597 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -556,8 +556,8 @@ class InterfaceListTable(BaseTable): enabled = tables.TemplateColumn(template_code=INTERFACE_ENABLED, verbose_name='Enabled') form_factor = tables.Column(verbose_name='Form Factor') mac_address = tables.Column(verbose_name='MAC Address') - description = tables.TemplateColumn(template_code=INTERFACE_LINK, verbose_name='Description') + description = tables.Column(verbose_name='Description') class Meta(BaseTable.Meta): model = Interface - fields = ('pk','device', 'name', 'form_factor','mac_address', 'description') + fields = ('pk','device', 'name', 'enabled', 'form_factor','mac_address', 'description') From 23c29781c25c1596d03b32d409898ca2bba5420a Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 3 Aug 2017 18:20:35 -0400 Subject: [PATCH 022/204] One change at a time... --- netbox/dcim/tables.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 8b0507597..5b05a62af 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -553,11 +553,11 @@ class InterfaceListTable(BaseTable): device = tables.LinkColumn('dcim:device', accessor=Accessor('interface.device'), args=[Accessor('interface.device.pk')], verbose_name='Device') name = tables.TemplateColumn(template_code=INTERFACE_LINK, verbose_name='Interface') - enabled = tables.TemplateColumn(template_code=INTERFACE_ENABLED, verbose_name='Enabled') + #enabled = tables.TemplateColumn(template_code=INTERFACE_ENABLED, verbose_name='Enabled') form_factor = tables.Column(verbose_name='Form Factor') mac_address = tables.Column(verbose_name='MAC Address') description = tables.Column(verbose_name='Description') class Meta(BaseTable.Meta): model = Interface - fields = ('pk','device', 'name', 'enabled', 'form_factor','mac_address', 'description') + fields = ('pk','device','name','form_factor','mac_address','description') From d1b7f49560d53523589afeb1bf415d902a7a05ae Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 3 Aug 2017 19:35:32 -0400 Subject: [PATCH 023/204] Remove toggle field --- netbox/dcim/tables.py | 1 - 1 file changed, 1 deletion(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 5b05a62af..2a075cf15 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -549,7 +549,6 @@ class InterfaceImportTable(BaseTable): class InterfaceListTable(BaseTable): - pk = ToggleColumn() device = tables.LinkColumn('dcim:device', accessor=Accessor('interface.device'), args=[Accessor('interface.device.pk')], verbose_name='Device') name = tables.TemplateColumn(template_code=INTERFACE_LINK, verbose_name='Interface') From 747830fc01799f63410fe7fb7af9b4f0f3452001 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 3 Aug 2017 19:47:02 -0400 Subject: [PATCH 024/204] . --- netbox/dcim/tables.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 2a075cf15..1a5b6499d 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -551,7 +551,8 @@ class InterfaceImportTable(BaseTable): class InterfaceListTable(BaseTable): device = tables.LinkColumn('dcim:device', accessor=Accessor('interface.device'), args=[Accessor('interface.device.pk')], verbose_name='Device') - name = tables.TemplateColumn(template_code=INTERFACE_LINK, verbose_name='Interface') + #name = tables.TemplateColumn(template_code=INTERFACE_LINK, verbose_name='Interface') + name = tables.Column(verbose_name='Interface') #enabled = tables.TemplateColumn(template_code=INTERFACE_ENABLED, verbose_name='Enabled') form_factor = tables.Column(verbose_name='Form Factor') mac_address = tables.Column(verbose_name='MAC Address') @@ -559,4 +560,4 @@ class InterfaceListTable(BaseTable): class Meta(BaseTable.Meta): model = Interface - fields = ('pk','device','name','form_factor','mac_address','description') + fields = ('device','name','form_factor','mac_address','description') From dd62e7576a5146bb690d73bb1b590f19832d1b34 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 3 Aug 2017 20:15:51 -0400 Subject: [PATCH 025/204] Trying link in interface name --- netbox/dcim/tables.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 1a5b6499d..cb36dcc68 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -41,7 +41,7 @@ DEVICE_LINK = """ INTERFACE_LINK = """ - {{ record.name|default:'--' }} + {{ record.name|default:'' }} """ @@ -551,8 +551,8 @@ class InterfaceImportTable(BaseTable): class InterfaceListTable(BaseTable): device = tables.LinkColumn('dcim:device', accessor=Accessor('interface.device'), args=[Accessor('interface.device.pk')], verbose_name='Device') - #name = tables.TemplateColumn(template_code=INTERFACE_LINK, verbose_name='Interface') - name = tables.Column(verbose_name='Interface') + name = tables.TemplateColumn(template_code=INTERFACE_LINK, verbose_name='Interface') + #name = tables.Column(verbose_name='Interface') #enabled = tables.TemplateColumn(template_code=INTERFACE_ENABLED, verbose_name='Enabled') form_factor = tables.Column(verbose_name='Form Factor') mac_address = tables.Column(verbose_name='MAC Address') From 81bca1bc31b772e5d8e9037ebdc47079da756fc3 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 3 Aug 2017 21:02:50 -0400 Subject: [PATCH 026/204] Fix Interface Link to use device and device fk --- netbox/dcim/tables.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index cb36dcc68..14641bf39 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -40,8 +40,8 @@ DEVICE_LINK = """ """ INTERFACE_LINK = """ - - {{ record.name|default:'' }} + + {{ record.name|default:' - ' }} """ From 8b70ea78ce78e73becf7c1aba57a1f8157c4cdce Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 3 Aug 2017 21:16:00 -0400 Subject: [PATCH 027/204] Try again on pk variable --- netbox/dcim/tables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 14641bf39..1acce6218 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -40,7 +40,7 @@ DEVICE_LINK = """ """ INTERFACE_LINK = """ - + {{ record.name|default:' - ' }} """ From 13170708a2c11a58b05aa995b93e1ee52c559b9b Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 3 Aug 2017 21:23:41 -0400 Subject: [PATCH 028/204] Switch device link in InterfaceListTable to identifier property --- netbox/dcim/tables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 1acce6218..fa3fa3f9a 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -550,7 +550,7 @@ class InterfaceImportTable(BaseTable): class InterfaceListTable(BaseTable): device = tables.LinkColumn('dcim:device', accessor=Accessor('interface.device'), - args=[Accessor('interface.device.pk')], verbose_name='Device') + args=[Accessor('interface.device.identifier')], verbose_name='Device') name = tables.TemplateColumn(template_code=INTERFACE_LINK, verbose_name='Interface') #name = tables.Column(verbose_name='Interface') #enabled = tables.TemplateColumn(template_code=INTERFACE_ENABLED, verbose_name='Enabled') From 04ea5bdebb8f74d49bee477c0c4dbb4fb6f72fcf Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 3 Aug 2017 21:40:40 -0400 Subject: [PATCH 029/204] Messing with accessors --- netbox/dcim/tables.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index fa3fa3f9a..571eb7d6c 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -549,15 +549,15 @@ class InterfaceImportTable(BaseTable): class InterfaceListTable(BaseTable): - device = tables.LinkColumn('dcim:device', accessor=Accessor('interface.device'), - args=[Accessor('interface.device.identifier')], verbose_name='Device') + device = tables.LinkColumn('dcim:device', accessor=Accessor('device'), + args=[Accessor('device.pk')], verbose_name='Device') name = tables.TemplateColumn(template_code=INTERFACE_LINK, verbose_name='Interface') #name = tables.Column(verbose_name='Interface') - #enabled = tables.TemplateColumn(template_code=INTERFACE_ENABLED, verbose_name='Enabled') + enabled = tables.TemplateColumn(template_code=INTERFACE_ENABLED, verbose_name='Enabled') form_factor = tables.Column(verbose_name='Form Factor') mac_address = tables.Column(verbose_name='MAC Address') description = tables.Column(verbose_name='Description') class Meta(BaseTable.Meta): model = Interface - fields = ('device','name','form_factor','mac_address','description') + fields = ('device','name','enabled','form_factor','mac_address','description') From 62281cb1aaec91c01b6712d663cff9bcc95113c0 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Fri, 4 Aug 2017 04:53:02 -0400 Subject: [PATCH 030/204] Created InterfaceListFilterForm and added more search terms. Remove export on device page. Fix enabled column --- netbox/dcim/forms.py | 11 +++++++++++ netbox/dcim/tables.py | 2 +- netbox/dcim/views.py | 2 +- netbox/templates/dcim/interface_list.html | 1 - 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 0f697a276..7d37de4a6 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1571,6 +1571,17 @@ class InterfaceFilterForm(BootstrapMixin, forms.Form): device = forms.CharField(required=False, label='Device name') +class InterfaceListFilterForm(BootstrapMixin, forms.Form): + site = forms.ModelChoiceField(required=False, queryset=Site.objects.all(), to_field_name='slug') + device = forms.ModelChoiceField(required=False, queryset=Device.objects.all(), to_field_name='slug') + enabled = form.ModelChoiceField(choices=((INTERFACE_ENABLED,'Enabled'),(INTERFACE_DISABLED,'Disabled')),required=False) + role = FilterChoiceField( + queryset=DeviceRole.objects.annotate(filter_count=Count('devices')), + to_field_name='slug', + ) + mac_address = forms.CharField(required=False, label='MAC address') + + # # Interface connections # diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 571eb7d6c..971c69e40 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -104,7 +104,7 @@ DEVICE_STATUS = """ """ INTERFACE_ENABLED = """ -{{ record.is_enabled }} +{{ record.enabled }} """ DEVICE_PRIMARY_IP = """ diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index d31509acb..045154138 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1558,7 +1558,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): queryset = Interface.objects.all() filter = filters.InterfaceFilter - filter_form = forms.InterfaceFilterForm + filter_form = forms.InterfaceListFilterForm table = tables.InterfaceListTable template_name = 'dcim/interface_list.html' diff --git a/netbox/templates/dcim/interface_list.html b/netbox/templates/dcim/interface_list.html index f3346980a..70f071df4 100644 --- a/netbox/templates/dcim/interface_list.html +++ b/netbox/templates/dcim/interface_list.html @@ -10,7 +10,6 @@ Import Interfaces {% endif %} - {% include 'inc/export_button.html' with obj_type='interfaces' %}

    Interfaces

    From c97f490ee8e5651e2fbf011eb9bf356f047b7654 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Fri, 4 Aug 2017 05:07:59 -0400 Subject: [PATCH 031/204] Typo on forms --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 7d37de4a6..5a740d6b9 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1574,7 +1574,7 @@ class InterfaceFilterForm(BootstrapMixin, forms.Form): class InterfaceListFilterForm(BootstrapMixin, forms.Form): site = forms.ModelChoiceField(required=False, queryset=Site.objects.all(), to_field_name='slug') device = forms.ModelChoiceField(required=False, queryset=Device.objects.all(), to_field_name='slug') - enabled = form.ModelChoiceField(choices=((INTERFACE_ENABLED,'Enabled'),(INTERFACE_DISABLED,'Disabled')),required=False) + enabled = forms.ModelChoiceField(choices=((INTERFACE_ENABLED,'Enabled'),(INTERFACE_DISABLED,'Disabled')),required=False) role = FilterChoiceField( queryset=DeviceRole.objects.annotate(filter_count=Count('devices')), to_field_name='slug', From 35f3e573b32a1a7695dc1f3ddd720794244375b2 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Fri, 4 Aug 2017 05:23:23 -0400 Subject: [PATCH 032/204] Added IFACE_ENABLED_CHOICES for InterfaceListFilterForm --- netbox/dcim/constants.py | 5 +++++ netbox/dcim/forms.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/netbox/dcim/constants.py b/netbox/dcim/constants.py index f2c047910..144baf447 100644 --- a/netbox/dcim/constants.py +++ b/netbox/dcim/constants.py @@ -48,6 +48,11 @@ IFACE_ORDERING_CHOICES = [ [IFACE_ORDERING_NAME, 'Name (alphabetically)'] ] +IFACE_ENABLED_CHOICES = [ + [IFACE_ENABLED,'Enabled'], + [IFACE_DISABLED,'Disabled'] +] + # Interface form factors # Virtual IFACE_FF_VIRTUAL = 0 diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 5a740d6b9..d28eced89 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1574,7 +1574,7 @@ class InterfaceFilterForm(BootstrapMixin, forms.Form): class InterfaceListFilterForm(BootstrapMixin, forms.Form): site = forms.ModelChoiceField(required=False, queryset=Site.objects.all(), to_field_name='slug') device = forms.ModelChoiceField(required=False, queryset=Device.objects.all(), to_field_name='slug') - enabled = forms.ModelChoiceField(choices=((INTERFACE_ENABLED,'Enabled'),(INTERFACE_DISABLED,'Disabled')),required=False) + enabled = forms.ModelChoiceField(choices=IFACE_ENABLED_CHOICES,required=False) role = FilterChoiceField( queryset=DeviceRole.objects.annotate(filter_count=Count('devices')), to_field_name='slug', From 266e948865b82d3d3afae9f35f47ad917a32abef Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Fri, 4 Aug 2017 11:19:51 -0400 Subject: [PATCH 033/204] Define IFACE_ENABLED choices 'properly' --- netbox/dcim/constants.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/netbox/dcim/constants.py b/netbox/dcim/constants.py index 144baf447..0a2596e22 100644 --- a/netbox/dcim/constants.py +++ b/netbox/dcim/constants.py @@ -48,6 +48,9 @@ IFACE_ORDERING_CHOICES = [ [IFACE_ORDERING_NAME, 'Name (alphabetically)'] ] +# Interface enabled as choice +IFACE_DISABLED = 0 +IFACE_ENABLED = 1 IFACE_ENABLED_CHOICES = [ [IFACE_ENABLED,'Enabled'], [IFACE_DISABLED,'Disabled'] From 6ad30dab737c47215594769dcfb403aacbc66790 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Fri, 4 Aug 2017 11:36:35 -0400 Subject: [PATCH 034/204] Fix IFACE_ENABLED_CHOICES...again --- netbox/dcim/constants.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/netbox/dcim/constants.py b/netbox/dcim/constants.py index 0a2596e22..10bef0b23 100644 --- a/netbox/dcim/constants.py +++ b/netbox/dcim/constants.py @@ -49,11 +49,11 @@ IFACE_ORDERING_CHOICES = [ ] # Interface enabled as choice -IFACE_DISABLED = 0 -IFACE_ENABLED = 1 +IFACE_DISABLED = False +IFACE_ENABLED = True IFACE_ENABLED_CHOICES = [ - [IFACE_ENABLED,'Enabled'], - [IFACE_DISABLED,'Disabled'] + [IFACE_DISABLED, 'Disabled'], + [IFACE_ENABLED, 'Enabled'], ] # Interface form factors From dd0544c25ce27b883572b00a864d5001ec97235d Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Fri, 4 Aug 2017 11:47:16 -0400 Subject: [PATCH 035/204] Missing constant import --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index d28eced89..150026283 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -21,7 +21,7 @@ from .formfields import MACAddressFormField from .models import ( DeviceBay, DeviceBayTemplate, CONNECTION_STATUS_CHOICES, CONNECTION_STATUS_CONNECTED, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceRole, DeviceType, Interface, - IFACE_FF_CHOICES, IFACE_FF_LAG, IFACE_ORDERING_CHOICES, InterfaceConnection, InterfaceTemplate, Manufacturer, + IFACE_FF_CHOICES, IFACE_FF_LAG, IFACE_ENABLED_CHOICES, 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, From 8ec6f7c0b5ee98c8369b3ad39f3065fb5b69f092 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Fri, 4 Aug 2017 12:08:22 -0400 Subject: [PATCH 036/204] Switched to correct ChoiceField --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 150026283..760a180b4 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1574,7 +1574,7 @@ class InterfaceFilterForm(BootstrapMixin, forms.Form): class InterfaceListFilterForm(BootstrapMixin, forms.Form): site = forms.ModelChoiceField(required=False, queryset=Site.objects.all(), to_field_name='slug') device = forms.ModelChoiceField(required=False, queryset=Device.objects.all(), to_field_name='slug') - enabled = forms.ModelChoiceField(choices=IFACE_ENABLED_CHOICES,required=False) + enabled = forms.ChoiceField(choices=add_blank_choice(IFACE_ENABLED_CHOICES), required=False) role = FilterChoiceField( queryset=DeviceRole.objects.annotate(filter_count=Count('devices')), to_field_name='slug', From d71556547e1194688118b2fcf8cf7be39511a0b7 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 15 Aug 2017 02:23:26 -0400 Subject: [PATCH 037/204] Added Interface export and custom field option --- netbox/extras/constants.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/netbox/extras/constants.py b/netbox/extras/constants.py index 86da90895..5d3d6d16c 100644 --- a/netbox/extras/constants.py +++ b/netbox/extras/constants.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals # Models which support custom fields CUSTOMFIELD_MODELS = ( - 'site', 'rack', 'devicetype', 'device', # DCIM + 'site', 'rack', 'devicetype', 'device', 'interface', # DCIM 'aggregate', 'prefix', 'ipaddress', 'vlan', 'vrf', # IPAM 'provider', 'circuit', # Circuits 'tenant', # Tenants @@ -37,10 +37,10 @@ GRAPH_TYPE_CHOICES = ( # Models which support export templates EXPORTTEMPLATE_MODELS = [ - 'site', 'rack', 'device', 'consoleport', 'powerport', 'interfaceconnection', # DCIM - 'aggregate', 'prefix', 'ipaddress', 'vlan', # IPAM - 'provider', 'circuit', # Circuits - 'tenant', # Tenants + 'site', 'rack', 'device', 'consoleport', 'powerport', 'interfaceconnection', 'interface', # DCIM + 'aggregate', 'prefix', 'ipaddress', 'vlan', # IPAM + 'provider', 'circuit', # Circuits + 'tenant', # Tenants ] # User action types From 322ad2ca1526aad39ba5c581da413d09d9f8f82c Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 15 Aug 2017 21:48:06 -0400 Subject: [PATCH 038/204] Checking filter on InterfaceListView to see if the broke the view --- netbox/dcim/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 045154138..0fc9253bf 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1557,7 +1557,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): queryset = Interface.objects.all() - filter = filters.InterfaceFilter + filter = filters.DeviceFilter filter_form = forms.InterfaceListFilterForm table = tables.InterfaceListTable template_name = 'dcim/interface_list.html' From 4b13149769ed847ae5a8aca5776264907a8e49cf Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Wed, 16 Aug 2017 14:20:26 -0400 Subject: [PATCH 039/204] Switch to DeviceFilterForm in InterfaceListView to confirm InterfaceListFilterForm is broken --- netbox/dcim/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 0fc9253bf..7725360bd 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1557,8 +1557,8 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): queryset = Interface.objects.all() - filter = filters.DeviceFilter - filter_form = forms.InterfaceListFilterForm + filter = filters.InterfaceFilter + filter_form = forms.DeviceFilterForm table = tables.InterfaceListTable template_name = 'dcim/interface_list.html' From 6dbc014fee03e9f3af8f3729c0d1c457dbd766b4 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Wed, 16 Aug 2017 16:48:16 -0400 Subject: [PATCH 040/204] Switching to forms.InterfaceConnectionFilterForm now --- netbox/dcim/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 7725360bd..93019da97 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1558,7 +1558,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): queryset = Interface.objects.all() filter = filters.InterfaceFilter - filter_form = forms.DeviceFilterForm + filter_form = forms.InterfaceConnectionFilterForm table = tables.InterfaceListTable template_name = 'dcim/interface_list.html' From 86c1503f120208107ffaa5ba7658937f60cfe4fd Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Wed, 16 Aug 2017 18:13:05 -0400 Subject: [PATCH 041/204] Revert to InterfaceFilterForm --- netbox/dcim/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 93019da97..d31509acb 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1558,7 +1558,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): queryset = Interface.objects.all() filter = filters.InterfaceFilter - filter_form = forms.InterfaceConnectionFilterForm + filter_form = forms.InterfaceFilterForm table = tables.InterfaceListTable template_name = 'dcim/interface_list.html' From 57584b9254f358650804ce8b25bf7c4986ccc194 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 17 Aug 2017 19:56:14 -0400 Subject: [PATCH 042/204] Remove filter from InterfaceListView --- netbox/dcim/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index d31509acb..c8ae7cd51 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1557,7 +1557,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): queryset = Interface.objects.all() - filter = filters.InterfaceFilter + #filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm table = tables.InterfaceListTable template_name = 'dcim/interface_list.html' From ad3814968ab209e9cb50923a9e58e3842c22a54b Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 17 Aug 2017 20:15:39 -0400 Subject: [PATCH 043/204] Revert filter in InterfaceListView --- netbox/dcim/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index c8ae7cd51..d31509acb 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1557,7 +1557,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): queryset = Interface.objects.all() - #filter = filters.InterfaceFilter + filter = filters.InterfaceFilter filter_form = forms.InterfaceFilterForm table = tables.InterfaceListTable template_name = 'dcim/interface_list.html' From e729b560deab1e6f23bc353690391f73d0a1be73 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 17 Aug 2017 21:01:05 -0400 Subject: [PATCH 044/204] Custom fields don't work with the interface list at present. Trying to fix export and InterfaceListFilterForm now. --- netbox/dcim/views.py | 2 +- netbox/templates/dcim/interface_list.html | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index d31509acb..045154138 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1558,7 +1558,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): queryset = Interface.objects.all() filter = filters.InterfaceFilter - filter_form = forms.InterfaceFilterForm + filter_form = forms.InterfaceListFilterForm table = tables.InterfaceListTable template_name = 'dcim/interface_list.html' diff --git a/netbox/templates/dcim/interface_list.html b/netbox/templates/dcim/interface_list.html index 70f071df4..f3346980a 100644 --- a/netbox/templates/dcim/interface_list.html +++ b/netbox/templates/dcim/interface_list.html @@ -10,6 +10,7 @@ Import Interfaces {% endif %} + {% include 'inc/export_button.html' with obj_type='interfaces' %}

    Interfaces

    From b145fb0e69fc52e9e7cb3b873e84bd58a1e00776 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 17 Aug 2017 21:16:33 -0400 Subject: [PATCH 045/204] Remove enabled field from IntefaceListFilterForm to test. --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 760a180b4..5d333c67a 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1574,7 +1574,7 @@ class InterfaceFilterForm(BootstrapMixin, forms.Form): class InterfaceListFilterForm(BootstrapMixin, forms.Form): site = forms.ModelChoiceField(required=False, queryset=Site.objects.all(), to_field_name='slug') device = forms.ModelChoiceField(required=False, queryset=Device.objects.all(), to_field_name='slug') - enabled = forms.ChoiceField(choices=add_blank_choice(IFACE_ENABLED_CHOICES), required=False) + #enabled = forms.ChoiceField(choices=add_blank_choice(IFACE_ENABLED_CHOICES), required=False) role = FilterChoiceField( queryset=DeviceRole.objects.annotate(filter_count=Count('devices')), to_field_name='slug', From de9229b532a6398d548b6547a33fb80a299fe8e5 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 17 Aug 2017 21:25:02 -0400 Subject: [PATCH 046/204] Comment role FilterChoiceField and uncomment enabled field. --- netbox/dcim/forms.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 5d333c67a..531e48f5c 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1574,11 +1574,11 @@ class InterfaceFilterForm(BootstrapMixin, forms.Form): class InterfaceListFilterForm(BootstrapMixin, forms.Form): site = forms.ModelChoiceField(required=False, queryset=Site.objects.all(), to_field_name='slug') device = forms.ModelChoiceField(required=False, queryset=Device.objects.all(), to_field_name='slug') - #enabled = forms.ChoiceField(choices=add_blank_choice(IFACE_ENABLED_CHOICES), required=False) - role = FilterChoiceField( - queryset=DeviceRole.objects.annotate(filter_count=Count('devices')), - to_field_name='slug', - ) + enabled = forms.ChoiceField(choices=add_blank_choice(IFACE_ENABLED_CHOICES), required=False) + #role = FilterChoiceField( + # queryset=DeviceRole.objects.annotate(filter_count=Count('devices')), + # to_field_name='slug', + #) mac_address = forms.CharField(required=False, label='MAC address') From 2c339b1bda205cdfe6fb878b8f4fe90338f4737f Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 17 Aug 2017 21:32:30 -0400 Subject: [PATCH 047/204] Comment mac_address and enabled in InterfaceListFilterForm --- netbox/dcim/forms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 531e48f5c..806bd2477 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1574,12 +1574,12 @@ class InterfaceFilterForm(BootstrapMixin, forms.Form): class InterfaceListFilterForm(BootstrapMixin, forms.Form): site = forms.ModelChoiceField(required=False, queryset=Site.objects.all(), to_field_name='slug') device = forms.ModelChoiceField(required=False, queryset=Device.objects.all(), to_field_name='slug') - enabled = forms.ChoiceField(choices=add_blank_choice(IFACE_ENABLED_CHOICES), required=False) + #enabled = forms.ChoiceField(choices=add_blank_choice(IFACE_ENABLED_CHOICES), required=False) #role = FilterChoiceField( # queryset=DeviceRole.objects.annotate(filter_count=Count('devices')), # to_field_name='slug', #) - mac_address = forms.CharField(required=False, label='MAC address') + #mac_address = forms.CharField(required=False, label='MAC address') # From d8fb8e60f936bdd8d60fff47943a07e6e402afce Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 17 Aug 2017 21:40:10 -0400 Subject: [PATCH 048/204] Comment out device field as ModelChoiceField. --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 806bd2477..b35c2f058 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1573,7 +1573,7 @@ class InterfaceFilterForm(BootstrapMixin, forms.Form): class InterfaceListFilterForm(BootstrapMixin, forms.Form): site = forms.ModelChoiceField(required=False, queryset=Site.objects.all(), to_field_name='slug') - device = forms.ModelChoiceField(required=False, queryset=Device.objects.all(), to_field_name='slug') + #device = forms.ModelChoiceField(required=False, queryset=Device.objects.all(), to_field_name='slug') #enabled = forms.ChoiceField(choices=add_blank_choice(IFACE_ENABLED_CHOICES), required=False) #role = FilterChoiceField( # queryset=DeviceRole.objects.annotate(filter_count=Count('devices')), From 421779cb56b144466b4ac6668791b110ac745bed Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 17 Aug 2017 21:54:09 -0400 Subject: [PATCH 049/204] Adding back all but device field to InterfaceListFilterForm. --- netbox/dcim/forms.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index b35c2f058..317738d40 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1574,12 +1574,12 @@ class InterfaceFilterForm(BootstrapMixin, forms.Form): class InterfaceListFilterForm(BootstrapMixin, forms.Form): site = forms.ModelChoiceField(required=False, queryset=Site.objects.all(), to_field_name='slug') #device = forms.ModelChoiceField(required=False, queryset=Device.objects.all(), to_field_name='slug') - #enabled = forms.ChoiceField(choices=add_blank_choice(IFACE_ENABLED_CHOICES), required=False) - #role = FilterChoiceField( - # queryset=DeviceRole.objects.annotate(filter_count=Count('devices')), - # to_field_name='slug', - #) - #mac_address = forms.CharField(required=False, label='MAC address') + enabled = forms.ChoiceField(choices=add_blank_choice(IFACE_ENABLED_CHOICES), required=False) + role = FilterChoiceField( + queryset=DeviceRole.objects.annotate(filter_count=Count('devices')), + to_field_name='slug', + ) + mac_address = forms.CharField(required=False, label='MAC address') # From bb7fc02654f918247e9cbe34cf0154b4a704b573 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 17 Aug 2017 22:10:45 -0400 Subject: [PATCH 050/204] Add InterfaceListFilter, add device as CharField instead of ModelChoiceField, and add the filter to InterfaceListView --- netbox/dcim/filters.py | 51 ++++++++++++++++++++++++++++++++++++++++++ netbox/dcim/forms.py | 1 + netbox/dcim/views.py | 2 +- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index ed6106c86..a1b90da38 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -577,6 +577,57 @@ class InterfaceFilter(django_filters.FilterSet): return queryset.none() +class InterfaceListFilter(django_filters.FilterSet): + device_id = django_filters.NumberFilter( + method='filter_device', + name='pk', + label='Device (ID)', + ) + type = django_filters.CharFilter( + method='filter_type', + label='Interface type', + ) + lag_id = django_filters.ModelMultipleChoiceFilter( + name='lag', + queryset=Interface.objects.all(), + label='LAG interface (ID)', + ) + mac_address = django_filters.CharFilter( + method='_mac_address', + label='MAC address', + ) + + class Meta: + model = Interface + fields = ['name', 'form_factor', 'enabled', 'mtu', 'mgmt_only'] + + def filter_device(self, queryset, name, value): + try: + device = Device.objects.select_related('device_type').get(**{name: value}) + ordering = device.device_type.interface_ordering + return queryset.filter(device=device).order_naturally(ordering) + except Device.DoesNotExist: + return queryset.none() + + def filter_type(self, queryset, name, value): + value = value.strip().lower() + return { + 'physical': queryset.exclude(form_factor__in=NONCONNECTABLE_IFACE_TYPES), + 'virtual': queryset.filter(form_factor__in=VIRTUAL_IFACE_TYPES), + 'wireless': queryset.filter(form_factor__in=WIRELESS_IFACE_TYPES), + 'lag': queryset.filter(form_factor=IFACE_FF_LAG), + }.get(value, queryset.none()) + + def _mac_address(self, queryset, name, value): + value = value.strip() + if not value: + return queryset + try: + return queryset.filter(mac_address=value) + except AddrFormatError: + return queryset.none() + + class DeviceBayFilter(DeviceComponentFilterSet): class Meta: diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 317738d40..aa691ff45 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1574,6 +1574,7 @@ class InterfaceFilterForm(BootstrapMixin, forms.Form): class InterfaceListFilterForm(BootstrapMixin, forms.Form): site = forms.ModelChoiceField(required=False, queryset=Site.objects.all(), to_field_name='slug') #device = forms.ModelChoiceField(required=False, queryset=Device.objects.all(), to_field_name='slug') + device = forms.CharField(required=False, label='Device name') enabled = forms.ChoiceField(choices=add_blank_choice(IFACE_ENABLED_CHOICES), required=False) role = FilterChoiceField( queryset=DeviceRole.objects.annotate(filter_count=Count('devices')), diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 045154138..cfc318de8 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1557,7 +1557,7 @@ class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView): class InterfaceListView(ObjectListView): queryset = Interface.objects.all() - filter = filters.InterfaceFilter + filter = filters.InterfaceListFilter filter_form = forms.InterfaceListFilterForm table = tables.InterfaceListTable template_name = 'dcim/interface_list.html' From 3e122c4a3282a0fd636f714716f2dc4300e8a873 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 22 Aug 2017 15:08:05 -0400 Subject: [PATCH 051/204] Added csv_headers to Interface model --- netbox/dcim/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 6ae36657e..17153c6f0 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -1148,7 +1148,9 @@ class Interface(models.Model): description = models.CharField(max_length=100, blank=True) objects = InterfaceQuerySet.as_manager() - + + csv_headers = ['device','lag','name','mac_address','form_factor','enabled','description','mtu','mgmt_only','is_virtual','is_wireless','is_connected','is_lag'] + class Meta: ordering = ['device', 'name'] unique_together = ['device', 'name'] From 67bf11ab82a47bde40a2e25910bb651026a0ad78 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 22 Aug 2017 18:44:55 -0400 Subject: [PATCH 052/204] Add more fields to InterfaceCSVForm and InterfaceImportTable --- netbox/dcim/forms.py | 32 +++++++++++++++++++++++++++++--- netbox/dcim/tables.py | 11 ++++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index aa691ff45..7c6830b81 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1541,20 +1541,46 @@ class InterfaceCSVForm(forms.ModelForm): name = forms.CharField( help_text='Name of interface' ) + lag = forms.CharField( + required=False, + help_text='Lag Name' + ) mac_address = forms.CharField( required=False, help_text='MAC address of interface' ) + form_factor = forms.CharField( + required=False, + help_text='Interface Form Factor' + ) description = forms.CharField( required=False, help_text='Description for interface' ) + enabled = forms.CharField( + required=False, + help_text='Enabled/Disabled' + ) + mtu = forms.CharField( + required=False, + help_text='MTU' + ) + mgmt_only = forms.CharField( + required=False, + help_text='Management Only' + ) + is_virtual = forms.CharField( + required=False, + help_text='Is Virtual?' + ) + is_wireless = forms.CharField( + required=False, + help_text='Is Wireless?' + ) class Meta: model = Interface - fields = [ - 'device', 'name', 'mac_address', 'description' - ] + fields = ('device', 'lag','name','mac_address','form_factor','enabled','description','mtu','mgmt_only','is_virtual','is_wireless') def clean_interface(self): diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 971c69e40..e3cacf5ad 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -538,14 +538,19 @@ class InterfaceConnectionTable(BaseTable): class InterfaceImportTable(BaseTable): device = tables.LinkColumn('dcim:device', accessor=Accessor('interface.device'), args=[Accessor('interface.device.pk')], verbose_name='Device') + lag = tables.Column(verbose_name='Lag') name = tables.Column(verbose_name='Interface') - form_factor = tables.Column(verbose_name='Form Factor') mac_address = tables.Column(verbose_name='MAC Address') + form_factor = tables.Column(verbose_name='Form Factor') + enabled = tables.Column(verbose_name='Enabled') description = tables.Column(verbose_name='Description') - + mtu = tables.Column(verbose_name='MTU') + mgmt_only = tables.Column(verbose_name='MGMT Only') + is_virtual = tables.Column(verbose_name='Virtual') + is_wireless = tables.Column(verbose_name='Wireless') class Meta(BaseTable.Meta): model = Interface - fields = ('device', 'name', 'form_factor','mac_address', 'description') + fields = ('device', 'lag','name','mac_address','form_factor','enabled','description','mtu','mgmt_only','is_virtual','is_wireless') class InterfaceListTable(BaseTable): From f7bb4009404a44ecce177e77d66c64068d813bea Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 22 Aug 2017 20:08:41 -0400 Subject: [PATCH 053/204] Try to fix lag field in InterfaceCSVForm...likely to fail --- netbox/dcim/forms.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 7c6830b81..08ecb5d47 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1541,9 +1541,11 @@ class InterfaceCSVForm(forms.ModelForm): name = forms.CharField( help_text='Name of interface' ) - lag = forms.CharField( + lag = FlexibleModelChoiceField( required=False, - help_text='Lag Name' + queryset = Interface.objects.order_naturally().filter(form_factor=IFACE_FF_LAG) + help_text='Lag Name', + error_messages={'invalid_choice': 'Lag not found.'} ) mac_address = forms.CharField( required=False, From 89b6aee205148cacd4ae38a20ee5e8605f9e16fa Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Tue, 22 Aug 2017 20:27:38 -0400 Subject: [PATCH 054/204] Missing comma... --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 08ecb5d47..262ca4cbd 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1543,7 +1543,7 @@ class InterfaceCSVForm(forms.ModelForm): ) lag = FlexibleModelChoiceField( required=False, - queryset = Interface.objects.order_naturally().filter(form_factor=IFACE_FF_LAG) + queryset = Interface.objects.order_naturally().filter(form_factor=IFACE_FF_LAG), help_text='Lag Name', error_messages={'invalid_choice': 'Lag not found.'} ) From 3fd2911bdc63e08227d289f886a75e39bb97402e Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 24 Aug 2017 20:09:22 -0400 Subject: [PATCH 055/204] Add is_lag field and try to fix lag FlexibleModelChoice in InterfaceCSVForm --- netbox/dcim/forms.py | 8 ++++++-- netbox/dcim/tables.py | 9 +++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 262ca4cbd..4bf975cd8 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1543,7 +1543,7 @@ class InterfaceCSVForm(forms.ModelForm): ) lag = FlexibleModelChoiceField( required=False, - queryset = Interface.objects.order_naturally().filter(form_factor=IFACE_FF_LAG), + queryset = Interface.objects.order_naturally(method=interface_ordering).filter(device=device,form_factor=IFACE_FF_LAG), help_text='Lag Name', error_messages={'invalid_choice': 'Lag not found.'} ) @@ -1579,10 +1579,14 @@ class InterfaceCSVForm(forms.ModelForm): required=False, help_text='Is Wireless?' ) + is_lag = forms.CharField( + required=False, + help_text='Is Lag?' + ) class Meta: model = Interface - fields = ('device', 'lag','name','mac_address','form_factor','enabled','description','mtu','mgmt_only','is_virtual','is_wireless') + fields = ('device', 'lag','name','mac_address','form_factor','enabled','description','mtu','mgmt_only','is_virtual','is_wireless','is_lag') def clean_interface(self): diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index e3cacf5ad..2f123ab4f 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -538,7 +538,7 @@ class InterfaceConnectionTable(BaseTable): class InterfaceImportTable(BaseTable): device = tables.LinkColumn('dcim:device', accessor=Accessor('interface.device'), args=[Accessor('interface.device.pk')], verbose_name='Device') - lag = tables.Column(verbose_name='Lag') + lag = tables.Column(verbose_name='Lag ID') name = tables.Column(verbose_name='Interface') mac_address = tables.Column(verbose_name='MAC Address') form_factor = tables.Column(verbose_name='Form Factor') @@ -546,11 +546,12 @@ class InterfaceImportTable(BaseTable): description = tables.Column(verbose_name='Description') mtu = tables.Column(verbose_name='MTU') mgmt_only = tables.Column(verbose_name='MGMT Only') - is_virtual = tables.Column(verbose_name='Virtual') - is_wireless = tables.Column(verbose_name='Wireless') + is_virtual = tables.Column(verbose_name='Is Virtual?') + is_wireless = tables.Column(verbose_name='Is Wireless?') + is_lag = tables.Column(verbose_name='Is Lag?') class Meta(BaseTable.Meta): model = Interface - fields = ('device', 'lag','name','mac_address','form_factor','enabled','description','mtu','mgmt_only','is_virtual','is_wireless') + fields = ('device', 'lag','name','mac_address','form_factor','enabled','description','mtu','mgmt_only','is_virtual','is_wireless','is_lag') class InterfaceListTable(BaseTable): From 0377474ecc43ce3e2effbd1a8ea5998845444d61 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 24 Aug 2017 20:17:50 -0400 Subject: [PATCH 056/204] Reference to nonexistent method removed --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 4bf975cd8..9f4d6f4df 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1543,7 +1543,7 @@ class InterfaceCSVForm(forms.ModelForm): ) lag = FlexibleModelChoiceField( required=False, - queryset = Interface.objects.order_naturally(method=interface_ordering).filter(device=device,form_factor=IFACE_FF_LAG), + queryset = Interface.objects.order_naturally().filter(device=device,form_factor=IFACE_FF_LAG), help_text='Lag Name', error_messages={'invalid_choice': 'Lag not found.'} ) From 5dd5608e5b285aefa167774ed9578119cb13e474 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Thu, 24 Aug 2017 20:32:41 -0400 Subject: [PATCH 057/204] Switch to BooleanFields --- netbox/dcim/forms.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 9f4d6f4df..114676f68 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1543,7 +1543,7 @@ class InterfaceCSVForm(forms.ModelForm): ) lag = FlexibleModelChoiceField( required=False, - queryset = Interface.objects.order_naturally().filter(device=device,form_factor=IFACE_FF_LAG), + queryset = Interface.objects.order_naturally().filter(form_factor=IFACE_FF_LAG), help_text='Lag Name', error_messages={'invalid_choice': 'Lag not found.'} ) @@ -1559,7 +1559,7 @@ class InterfaceCSVForm(forms.ModelForm): required=False, help_text='Description for interface' ) - enabled = forms.CharField( + enabled = forms.BooleanField( required=False, help_text='Enabled/Disabled' ) @@ -1571,15 +1571,15 @@ class InterfaceCSVForm(forms.ModelForm): required=False, help_text='Management Only' ) - is_virtual = forms.CharField( + is_virtual = forms.BooleanField( required=False, help_text='Is Virtual?' ) - is_wireless = forms.CharField( + is_wireless = forms.BooleanField( required=False, help_text='Is Wireless?' ) - is_lag = forms.CharField( + is_lag = forms.BooleanField( required=False, help_text='Is Lag?' ) From 6f7bb50475489860b904d01a2596f9259dd94d0e Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Fri, 25 Aug 2017 22:55:27 -0400 Subject: [PATCH 058/204] Change lag interface...add clean_lag function. Switch to NullBooleanField for other fields in InterfaceCSVForm --- netbox/dcim/forms.py | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 114676f68..2852d3ae8 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1541,11 +1541,9 @@ class InterfaceCSVForm(forms.ModelForm): name = forms.CharField( help_text='Name of interface' ) - lag = FlexibleModelChoiceField( + lag = forms.CharField( required=False, - queryset = Interface.objects.order_naturally().filter(form_factor=IFACE_FF_LAG), - help_text='Lag Name', - error_messages={'invalid_choice': 'Lag not found.'} + help_text='Lag Name' ) mac_address = forms.CharField( required=False, @@ -1559,7 +1557,7 @@ class InterfaceCSVForm(forms.ModelForm): required=False, help_text='Description for interface' ) - enabled = forms.BooleanField( + enabled = forms.NullBooleanField( required=False, help_text='Enabled/Disabled' ) @@ -1571,15 +1569,15 @@ class InterfaceCSVForm(forms.ModelForm): required=False, help_text='Management Only' ) - is_virtual = forms.BooleanField( + is_virtual = forms.NullBooleanField( required=False, help_text='Is Virtual?' ) - is_wireless = forms.BooleanField( + is_wireless = forms.NullBooleanField( required=False, help_text='Is Wireless?' ) - is_lag = forms.BooleanField( + is_lag = forms.NullBooleanField( required=False, help_text='Is Lag?' ) @@ -1587,10 +1585,10 @@ class InterfaceCSVForm(forms.ModelForm): class Meta: model = Interface fields = ('device', 'lag','name','mac_address','form_factor','enabled','description','mtu','mgmt_only','is_virtual','is_wireless','is_lag') + nullable_fields = ['lag','is_virtual','is_wireless','is_lag'] def clean_interface(self): - interface_name = self.cleaned_data.get('interface_name') if not interface: return None @@ -1598,6 +1596,25 @@ class InterfaceCSVForm(forms.ModelForm): return interface + def clean_lag(self): + try: + if device is not None: + interface_ordering = device.device_type.interface_ordering + lag = Interface.objects.order_naturally(method=interface_ordering).filter( + device=device, form_factor=IFACE_FF_LAG).get( + lag=self.cleaned_data['lag'], name=lag + ) + self.fields['lag'].queryset = Interface.objects.order_naturally(method=interface_ordering).filter( + device=device, form_factor=IFACE_FF_LAG + ) + except: + return None + + if not lag: + return None + return lag + + class InterfaceFilterForm(BootstrapMixin, forms.Form): site = forms.ModelChoiceField(required=False, queryset=Site.objects.all(), to_field_name='slug') device = forms.CharField(required=False, label='Device name') From 509848031b2c9597b298fb03e931cfbc4bc0c6b4 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Fri, 25 Aug 2017 23:20:44 -0400 Subject: [PATCH 059/204] Switch to IntegerField for form_factor and mtu and switch back to BooleanFields --- netbox/dcim/forms.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 2852d3ae8..9d56f52bd 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1549,7 +1549,7 @@ class InterfaceCSVForm(forms.ModelForm): required=False, help_text='MAC address of interface' ) - form_factor = forms.CharField( + form_factor = forms.IntegerField( required=False, help_text='Interface Form Factor' ) @@ -1557,11 +1557,11 @@ class InterfaceCSVForm(forms.ModelForm): required=False, help_text='Description for interface' ) - enabled = forms.NullBooleanField( + enabled = forms.BooleanField( required=False, help_text='Enabled/Disabled' ) - mtu = forms.CharField( + mtu = forms.IntegerField( required=False, help_text='MTU' ) @@ -1569,15 +1569,15 @@ class InterfaceCSVForm(forms.ModelForm): required=False, help_text='Management Only' ) - is_virtual = forms.NullBooleanField( + is_virtual = forms.BooleanField( required=False, help_text='Is Virtual?' ) - is_wireless = forms.NullBooleanField( + is_wireless = forms.BooleanField( required=False, help_text='Is Wireless?' ) - is_lag = forms.NullBooleanField( + is_lag = forms.BooleanField( required=False, help_text='Is Lag?' ) From da2f1560f4c2a1f90202ee7d57913335cb62be79 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Fri, 25 Aug 2017 23:50:55 -0400 Subject: [PATCH 060/204] Remove extraneous line and remove try for error testing --- netbox/dcim/forms.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 9d56f52bd..bf9b5a885 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1597,18 +1597,13 @@ class InterfaceCSVForm(forms.ModelForm): def clean_lag(self): - try: - if device is not None: - interface_ordering = device.device_type.interface_ordering - lag = Interface.objects.order_naturally(method=interface_ordering).filter( - device=device, form_factor=IFACE_FF_LAG).get( - lag=self.cleaned_data['lag'], name=lag - ) - self.fields['lag'].queryset = Interface.objects.order_naturally(method=interface_ordering).filter( - device=device, form_factor=IFACE_FF_LAG - ) - except: - return None + if device is not None: + interface_ordering = device.device_type.interface_ordering + lag = Interface.objects.order_naturally(method=interface_ordering).filter( + device=device, form_factor=IFACE_FF_LAG).get( + lag=self.cleaned_data['lag'], name=lag + ) + if not lag: return None From 17428e70571b3f7afd1e005d6d092ab34986781c Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 00:00:05 -0400 Subject: [PATCH 061/204] use self.device --- netbox/dcim/forms.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index bf9b5a885..f6a793cf2 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1597,10 +1597,10 @@ class InterfaceCSVForm(forms.ModelForm): def clean_lag(self): - if device is not None: - interface_ordering = device.device_type.interface_ordering + if self.device is not None: + interface_ordering = self.device.device_type.interface_ordering lag = Interface.objects.order_naturally(method=interface_ordering).filter( - device=device, form_factor=IFACE_FF_LAG).get( + device=self.device, form_factor=IFACE_FF_LAG).get( lag=self.cleaned_data['lag'], name=lag ) From e92a72cdb6dd74ec44254f6fd091a873e7a06141 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 00:17:21 -0400 Subject: [PATCH 062/204] Missing device reference --- netbox/dcim/forms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index f6a793cf2..c59aabc6c 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1597,6 +1597,7 @@ class InterfaceCSVForm(forms.ModelForm): def clean_lag(self): + device = None if self.device is not None: interface_ordering = self.device.device_type.interface_ordering lag = Interface.objects.order_naturally(method=interface_ordering).filter( From 952f6e7754aa04b66a9ff3d7b31a709bba0a8ddf Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 00:54:19 -0400 Subject: [PATCH 063/204] Trying self.fields attributes --- netbox/dcim/forms.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index c59aabc6c..14282594e 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1598,10 +1598,10 @@ class InterfaceCSVForm(forms.ModelForm): def clean_lag(self): device = None - if self.device is not None: - interface_ordering = self.device.device_type.interface_ordering + if self.fields['device'] is not None: + interface_ordering = self.fields['device'].device_type.interface_ordering lag = Interface.objects.order_naturally(method=interface_ordering).filter( - device=self.device, form_factor=IFACE_FF_LAG).get( + device=self.fields['device'], form_factor=IFACE_FF_LAG).get( lag=self.cleaned_data['lag'], name=lag ) From 37c0538f7df14a8a26bc735edb325d7345efa55a Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 01:07:33 -0400 Subject: [PATCH 064/204] Messing up interface ordering --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 14282594e..4762667d5 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1599,7 +1599,7 @@ class InterfaceCSVForm(forms.ModelForm): def clean_lag(self): device = None if self.fields['device'] is not None: - interface_ordering = self.fields['device'].device_type.interface_ordering + interface_ordering = device.device_type.interface_ordering lag = Interface.objects.order_naturally(method=interface_ordering).filter( device=self.fields['device'], form_factor=IFACE_FF_LAG).get( lag=self.cleaned_data['lag'], name=lag From b1ec7dfec2e135500151c239902a5c542c06781d Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 01:16:09 -0400 Subject: [PATCH 065/204] Removed ordering as it is unnecessary --- netbox/dcim/forms.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 4762667d5..5147ef59c 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1599,8 +1599,7 @@ class InterfaceCSVForm(forms.ModelForm): def clean_lag(self): device = None if self.fields['device'] is not None: - interface_ordering = device.device_type.interface_ordering - lag = Interface.objects.order_naturally(method=interface_ordering).filter( + lag = Interface.objects.filter( device=self.fields['device'], form_factor=IFACE_FF_LAG).get( lag=self.cleaned_data['lag'], name=lag ) From 35110beca8926c11b0408ca915a2602ffbf49bd0 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 01:41:30 -0400 Subject: [PATCH 066/204] Use cleaned_data --- netbox/dcim/forms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 5147ef59c..2abc67222 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1598,9 +1598,9 @@ class InterfaceCSVForm(forms.ModelForm): def clean_lag(self): device = None - if self.fields['device'] is not None: + if self.cleaned_data['device'] is not None: lag = Interface.objects.filter( - device=self.fields['device'], form_factor=IFACE_FF_LAG).get( + device=self.cleaned_data['device'], form_factor=IFACE_FF_LAG).get( lag=self.cleaned_data['lag'], name=lag ) From bb75f65cf5d6d9fd5ad3a55a64da35d370023e09 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 01:52:03 -0400 Subject: [PATCH 067/204] Error will robinson r Please enter the commit message for your changes. Lines starting --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 2abc67222..33f3209e8 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1601,7 +1601,7 @@ class InterfaceCSVForm(forms.ModelForm): if self.cleaned_data['device'] is not None: lag = Interface.objects.filter( device=self.cleaned_data['device'], form_factor=IFACE_FF_LAG).get( - lag=self.cleaned_data['lag'], name=lag + self.cleaned_data['lag'] ) From 6e1af855bf961925b26ee97de26e21313a9da73f Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 01:55:14 -0400 Subject: [PATCH 068/204] Whoops --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 33f3209e8..2d3eae002 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1601,7 +1601,7 @@ class InterfaceCSVForm(forms.ModelForm): if self.cleaned_data['device'] is not None: lag = Interface.objects.filter( device=self.cleaned_data['device'], form_factor=IFACE_FF_LAG).get( - self.cleaned_data['lag'] + lag=self.cleaned_data['lag'] ) From 23e20964e9bc6e27fbfc57185a163a4f5aead9b2 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 21:39:53 -0400 Subject: [PATCH 069/204] Switch to FlexibleModalChoiceField for lag...still broken clean_lag method --- netbox/dcim/forms.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 2d3eae002..30bb9354f 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1541,9 +1541,11 @@ class InterfaceCSVForm(forms.ModelForm): name = forms.CharField( help_text='Name of interface' ) - lag = forms.CharField( - required=False, - help_text='Lag Name' + lag = FlexibleModelChoiceField( + queryset=Interface.objects.filter(form_factor=IFACE_FF_LAG), + to_field_name='name', + help_text='Lag Name or ID of interface', + error_messages={'invalid_choice': 'Lag not found.'} ) mac_address = forms.CharField( required=False, @@ -1598,13 +1600,12 @@ class InterfaceCSVForm(forms.ModelForm): def clean_lag(self): device = None - if self.cleaned_data['device'] is not None: + lag_name = self.data.get('lag') + if self.data['device'] is not None: lag = Interface.objects.filter( - device=self.cleaned_data['device'], form_factor=IFACE_FF_LAG).get( - lag=self.cleaned_data['lag'] + device=self.data.get('device'), form_factor=IFACE_FF_LAG).get( + lag=lag_name ) - - if not lag: return None return lag From 2e01087aad53072c8a5181aba55f4a3c0838d7d3 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 21:44:09 -0400 Subject: [PATCH 070/204] Set required=False --- netbox/dcim/forms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 30bb9354f..048b0da4b 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1544,6 +1544,7 @@ class InterfaceCSVForm(forms.ModelForm): lag = FlexibleModelChoiceField( queryset=Interface.objects.filter(form_factor=IFACE_FF_LAG), to_field_name='name', + required=False, help_text='Lag Name or ID of interface', error_messages={'invalid_choice': 'Lag not found.'} ) From 197529514d444aad330786a5bd588d4091e14475 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 21:56:04 -0400 Subject: [PATCH 071/204] Try a different to_field_name --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 048b0da4b..40a7c775e 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1543,7 +1543,7 @@ class InterfaceCSVForm(forms.ModelForm): ) lag = FlexibleModelChoiceField( queryset=Interface.objects.filter(form_factor=IFACE_FF_LAG), - to_field_name='name', + to_field_name='lag', required=False, help_text='Lag Name or ID of interface', error_messages={'invalid_choice': 'Lag not found.'} From 26300649d2a5369d0ebcd413e26978759c134865 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 22:34:49 -0400 Subject: [PATCH 072/204] - --- netbox/dcim/forms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 40a7c775e..fe965dd6e 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1602,10 +1602,10 @@ class InterfaceCSVForm(forms.ModelForm): def clean_lag(self): device = None lag_name = self.data.get('lag') - if self.data['device'] is not None: + if self.data['device'] is not None and lag_name is not None: lag = Interface.objects.filter( device=self.data.get('device'), form_factor=IFACE_FF_LAG).get( - lag=lag_name + lag=lag_name.id ) if not lag: return None From 6c8671843469888b235f7dede655919a2af4c267 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 22:58:39 -0400 Subject: [PATCH 073/204] Switch to cleaned_data --- netbox/dcim/forms.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index fe965dd6e..c26b26a65 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1543,7 +1543,7 @@ class InterfaceCSVForm(forms.ModelForm): ) lag = FlexibleModelChoiceField( queryset=Interface.objects.filter(form_factor=IFACE_FF_LAG), - to_field_name='lag', + to_field_name='name', required=False, help_text='Lag Name or ID of interface', error_messages={'invalid_choice': 'Lag not found.'} @@ -1600,11 +1600,11 @@ class InterfaceCSVForm(forms.ModelForm): def clean_lag(self): - device = None - lag_name = self.data.get('lag') - if self.data['device'] is not None and lag_name is not None: + device_id = self.cleaned_data.get('device') + lag_name = self.cleaned_data.get('lag') + if device_id is not None and lag_name is not None: lag = Interface.objects.filter( - device=self.data.get('device'), form_factor=IFACE_FF_LAG).get( + device=device_id, form_factor=IFACE_FF_LAG).get( lag=lag_name.id ) if not lag: From 8271c9383cd0a030a9571076d8f4f94024db72db Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 23:32:33 -0400 Subject: [PATCH 074/204] self --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index c26b26a65..4c3b4c066 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1607,7 +1607,7 @@ class InterfaceCSVForm(forms.ModelForm): device=device_id, form_factor=IFACE_FF_LAG).get( lag=lag_name.id ) - if not lag: + if not self.lag: return None return lag From 01301777c8f2b2eeda45c840738e16d42dbff8df Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 23:33:38 -0400 Subject: [PATCH 075/204] ehhh --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 4c3b4c066..e4effaed6 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1607,7 +1607,7 @@ class InterfaceCSVForm(forms.ModelForm): device=device_id, form_factor=IFACE_FF_LAG).get( lag=lag_name.id ) - if not self.lag: + if not self.data('lag'): return None return lag From b9060d846c126bdcd71967b8fb3fa4fd23fda375 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 23:35:46 -0400 Subject: [PATCH 076/204] Try again... --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index e4effaed6..933e6b626 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1607,7 +1607,7 @@ class InterfaceCSVForm(forms.ModelForm): device=device_id, form_factor=IFACE_FF_LAG).get( lag=lag_name.id ) - if not self.data('lag'): + if lag is not None: return None return lag From f3abe1da4491372740b04bb1a6fbc13706160750 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 23:37:05 -0400 Subject: [PATCH 077/204] Wrong variable... --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 933e6b626..bc0361b49 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1607,7 +1607,7 @@ class InterfaceCSVForm(forms.ModelForm): device=device_id, form_factor=IFACE_FF_LAG).get( lag=lag_name.id ) - if lag is not None: + if not lag_name: return None return lag From 98308b2eef9881eedbc038913b98572d1d51e086 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 23:40:26 -0400 Subject: [PATCH 078/204] Back to name --- netbox/dcim/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index bc0361b49..f7f481d95 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1605,7 +1605,7 @@ class InterfaceCSVForm(forms.ModelForm): if device_id is not None and lag_name is not None: lag = Interface.objects.filter( device=device_id, form_factor=IFACE_FF_LAG).get( - lag=lag_name.id + lag=lag_name ) if not lag_name: return None From f855733f4644fb458ad477621e4bc865722162dd Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Sat, 26 Aug 2017 23:58:46 -0400 Subject: [PATCH 079/204] LinkColumn for lag and try to do a proper get --- netbox/dcim/forms.py | 2 +- netbox/dcim/tables.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index f7f481d95..46c782939 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1605,7 +1605,7 @@ class InterfaceCSVForm(forms.ModelForm): if device_id is not None and lag_name is not None: lag = Interface.objects.filter( device=device_id, form_factor=IFACE_FF_LAG).get( - lag=lag_name + name=lag_name ) if not lag_name: return None diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 2f123ab4f..4471b4880 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -538,7 +538,9 @@ class InterfaceConnectionTable(BaseTable): class InterfaceImportTable(BaseTable): device = tables.LinkColumn('dcim:device', accessor=Accessor('interface.device'), args=[Accessor('interface.device.pk')], verbose_name='Device') - lag = tables.Column(verbose_name='Lag ID') + lag = tables.LinkColumn('dcim:interface', accessor=Accessor('self.name'), + args=[Accessor('self.pk')], verbose_name='Lag ID') + #lag = tables.Column(verbose_name='Lag ID') name = tables.Column(verbose_name='Interface') mac_address = tables.Column(verbose_name='MAC Address') form_factor = tables.Column(verbose_name='Form Factor') From 271c771b76b74d979dfd4a72e823db1abe531c74 Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Mon, 28 Aug 2017 01:32:38 -0400 Subject: [PATCH 080/204] Allow custom fields for interfaces. Switch to get_status_display on INTERFACE_ENABLED template code. --- netbox/dcim/models.py | 2 +- netbox/dcim/tables.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 17153c6f0..1ca561280 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -1146,7 +1146,7 @@ class Interface(models.Model): help_text="This interface is used only for out-of-band management" ) description = models.CharField(max_length=100, blank=True) - + custom_field_values = GenericRelation(CustomFieldValue, content_type_field='obj_type', object_id_field='obj_id') objects = InterfaceQuerySet.as_manager() csv_headers = ['device','lag','name','mac_address','form_factor','enabled','description','mtu','mgmt_only','is_virtual','is_wireless','is_connected','is_lag'] diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 4471b4880..599ff878e 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -104,7 +104,7 @@ DEVICE_STATUS = """ """ INTERFACE_ENABLED = """ -{{ record.enabled }} +{{ record.get_status_display }} """ DEVICE_PRIMARY_IP = """ From 9e086932d9ab1cccf783b99c8675f4add57d14ca Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Mon, 28 Aug 2017 02:24:50 -0400 Subject: [PATCH 081/204] Added get_status_class to template code and change to CustomFieldModel for InterfaceModel --- netbox/dcim/models.py | 5 ++++- netbox/dcim/tables.py | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 1ca561280..c396be3a2 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -1121,7 +1121,7 @@ class PowerOutlet(models.Model): # @python_2_unicode_compatible -class Interface(models.Model): +class Interface(CreatedUpdatedModel, CustomFieldModel): """ A physical data interface within a Device. An Interface can connect to exactly one other Interface via the creation of an InterfaceConnection. @@ -1209,6 +1209,9 @@ class Interface(models.Model): pass return bool(self.connection) + def get_status_class(self): + return IFACE_ENABLED_CHOICES[self.enabled] + @property def connection(self): try: diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py index 599ff878e..29fefc1f8 100644 --- a/netbox/dcim/tables.py +++ b/netbox/dcim/tables.py @@ -104,7 +104,7 @@ DEVICE_STATUS = """ """ INTERFACE_ENABLED = """ -{{ record.get_status_display }} +{{ record.enabled }} """ DEVICE_PRIMARY_IP = """ @@ -540,7 +540,6 @@ class InterfaceImportTable(BaseTable): args=[Accessor('interface.device.pk')], verbose_name='Device') lag = tables.LinkColumn('dcim:interface', accessor=Accessor('self.name'), args=[Accessor('self.pk')], verbose_name='Lag ID') - #lag = tables.Column(verbose_name='Lag ID') name = tables.Column(verbose_name='Interface') mac_address = tables.Column(verbose_name='MAC Address') form_factor = tables.Column(verbose_name='Form Factor') From 98e3461503a03a52e7384d75ea7b44573d0852fa Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Mon, 28 Aug 2017 02:29:09 -0400 Subject: [PATCH 082/204] Switch back to base model for Interface and remove custom_fields --- netbox/dcim/models.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index c396be3a2..ba7928bd1 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -1121,7 +1121,7 @@ class PowerOutlet(models.Model): # @python_2_unicode_compatible -class Interface(CreatedUpdatedModel, CustomFieldModel): +class Interface(models.Model): """ A physical data interface within a Device. An Interface can connect to exactly one other Interface via the creation of an InterfaceConnection. @@ -1146,7 +1146,6 @@ class Interface(CreatedUpdatedModel, CustomFieldModel): help_text="This interface is used only for out-of-band management" ) description = models.CharField(max_length=100, blank=True) - custom_field_values = GenericRelation(CustomFieldValue, content_type_field='obj_type', object_id_field='obj_id') objects = InterfaceQuerySet.as_manager() csv_headers = ['device','lag','name','mac_address','form_factor','enabled','description','mtu','mgmt_only','is_virtual','is_wireless','is_connected','is_lag'] From 39f139a24d880fe19af9d1030fd41099c17b6b0c Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Mon, 28 Aug 2017 03:25:43 -0400 Subject: [PATCH 083/204] Reorder items --- netbox/dcim/models.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index ba7928bd1..deaa9e834 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -1208,9 +1208,6 @@ class Interface(models.Model): pass return bool(self.connection) - def get_status_class(self): - return IFACE_ENABLED_CHOICES[self.enabled] - @property def connection(self): try: @@ -1237,6 +1234,9 @@ class Interface(models.Model): pass return None + def get_status_class(self): + return IFACE_ENABLED_CHOICES[self.enabled] + # Used for export def to_csv(self): return csv_format([ From e6bc968d6231977253945e771954caa3104592ac Mon Sep 17 00:00:00 2001 From: Joseph Kennedy Date: Mon, 28 Aug 2017 15:24:50 -0400 Subject: [PATCH 084/204] Add toggle to show description field. Need to add conditional for comment bubble --- netbox/templates/dcim/device.html | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html index 3e055333c..8c66e5c21 100644 --- a/netbox/templates/dcim/device.html +++ b/netbox/templates/dcim/device.html @@ -388,6 +388,9 @@ + {% if perms.dcim.change_interface and interfaces|length > 1 %} - {% if perms.dcim.change_interface and interfaces|length > 1 %} {% if perms.dcim.change_interface and interfaces|length > 1 %} {% if perms.dcim.change_interface and interfaces|length > 1 %}