diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index c572328bc..d5aad7a69 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -1,15 +1,21 @@ # NetBox v3.2 -## v3.2.9 (FUTURE) +## v3.2.9 (2022-08-16) ### Enhancements +* [#8595](https://github.com/netbox-community/netbox/issues/8595) - Add PON interface types +* [#8723](https://github.com/netbox-community/netbox/issues/8723) - Enable bulk renaming of devices * [#9161](https://github.com/netbox-community/netbox/issues/9161) - Pretty print JSON custom field data when editing +* [#9505](https://github.com/netbox-community/netbox/issues/9505) - Display extra addressing details for IPv4 prefixes * [#9625](https://github.com/netbox-community/netbox/issues/9625) - Add phone & email details to contacts panel * [#9857](https://github.com/netbox-community/netbox/issues/9857) - Add clear button to quick search fields +* [#9933](https://github.com/netbox-community/netbox/issues/9933) - Add DOCSIS interface type ### Bug Fixes +* [#9491](https://github.com/netbox-community/netbox/issues/9491) - Remove button for adding inventory item templates to module type components +* [#9979](https://github.com/netbox-community/netbox/issues/9979) - Fix Markdown rendering for custom fields in table columns * [#9986](https://github.com/netbox-community/netbox/issues/9986) - Workaround for upstream timezone data bug --- diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index 1fe21ed4b..79049384a 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -836,6 +836,17 @@ class InterfaceTypeChoices(ChoiceSet): # ATM/DSL TYPE_XDSL = 'xdsl' + # Coaxial + TYPE_DOCSIS = 'docsis' + + # PON + TYPE_GPON = 'gpon' + TYPE_XG_PON = 'xg-pon' + TYPE_XGS_PON = 'xgs-pon' + TYPE_NG_PON2 = 'ng-pon2' + TYPE_EPON = 'epon' + TYPE_10G_EPON = '10g-epon' + # Stacking TYPE_STACKWISE = 'cisco-stackwise' TYPE_STACKWISE_PLUS = 'cisco-stackwise-plus' @@ -972,6 +983,23 @@ class InterfaceTypeChoices(ChoiceSet): (TYPE_XDSL, 'xDSL'), ) ), + ( + 'Coaxial', + ( + (TYPE_DOCSIS, 'DOCSIS'), + ) + ), + ( + 'PON', + ( + (TYPE_GPON, 'GPON (2.5 Gbps / 1.25 Gps)'), + (TYPE_XG_PON, 'XG-PON (10 Gbps / 2.5 Gbps)'), + (TYPE_XGS_PON, 'XGS-PON (10 Gbps)'), + (TYPE_NG_PON2, 'NG-PON2 (TWDM-PON) (4x10 Gbps)'), + (TYPE_EPON, 'EPON (1 Gbps)'), + (TYPE_10G_EPON, '10G-EPON (10 Gbps)'), + ) + ), ( 'Stacking', ( diff --git a/netbox/dcim/tables/template_code.py b/netbox/dcim/tables/template_code.py index 04ef74192..cc2cc4c84 100644 --- a/netbox/dcim/tables/template_code.py +++ b/netbox/dcim/tables/template_code.py @@ -88,7 +88,7 @@ LOCATION_BUTTONS = """ MODULAR_COMPONENT_TEMPLATE_BUTTONS = """ {% load helpers %} -{% if perms.dcim.add_inventoryitemtemplate %} +{% if perms.dcim.add_inventoryitemtemplate and record.device_type_id %} diff --git a/netbox/dcim/urls.py b/netbox/dcim/urls.py index dbbd8707a..c11a92a99 100644 --- a/netbox/dcim/urls.py +++ b/netbox/dcim/urls.py @@ -248,6 +248,7 @@ urlpatterns = [ path('devices/import/', views.DeviceBulkImportView.as_view(), name='device_import'), path('devices/import/child-devices/', views.ChildDeviceBulkImportView.as_view(), name='device_import_child'), path('devices/edit/', views.DeviceBulkEditView.as_view(), name='device_bulk_edit'), + path('devices/rename/', views.DeviceBulkRenameView.as_view(), name='device_bulk_rename'), path('devices/delete/', views.DeviceBulkDeleteView.as_view(), name='device_bulk_delete'), path('devices//', views.DeviceView.as_view(), name='device'), path('devices//edit/', views.DeviceEditView.as_view(), name='device_edit'), diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 77c6b2218..a31eabc5e 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1798,6 +1798,12 @@ class DeviceBulkDeleteView(generic.BulkDeleteView): table = tables.DeviceTable +class DeviceBulkRenameView(generic.BulkRenameView): + queryset = Device.objects.all() + filterset = filtersets.DeviceFilterSet + table = tables.DeviceTable + + # # Devices # diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index f78b9f37c..6ab50d4c2 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -14,6 +14,7 @@ from django_tables2.columns import library from django_tables2.utils import Accessor from extras.choices import CustomFieldTypeChoices +from utilities.templatetags.builtins.filters import render_markdown from utilities.utils import content_type_identifier, content_type_name, get_viewname __all__ = ( @@ -427,7 +428,7 @@ class CustomFieldColumn(tables.Column): super().__init__(*args, **kwargs) @staticmethod - def _likify_item(item): + def _linkify_item(item): if hasattr(item, 'get_absolute_url'): return f'{escape(item)}' return escape(item) @@ -443,11 +444,13 @@ class CustomFieldColumn(tables.Column): return ', '.join(v for v in value) if self.customfield.type == CustomFieldTypeChoices.TYPE_MULTIOBJECT: return mark_safe(', '.join( - self._likify_item(obj) for obj in self.customfield.deserialize(value) + self._linkify_item(obj) for obj in self.customfield.deserialize(value) )) + if self.customfield.type == CustomFieldTypeChoices.TYPE_LONGTEXT and value: + return render_markdown(value) if value is not None: obj = self.customfield.deserialize(value) - return mark_safe(self._likify_item(obj)) + return mark_safe(self._linkify_item(obj)) return self.default def value(self, value): diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index 09b4fc8e9..60ad4a2cc 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -603,7 +603,7 @@ class BulkRenameView(GetReturnURLMixin, BaseMultiObjectView): replace = form.cleaned_data['replace'] if form.cleaned_data['use_regex']: try: - obj.new_name = re.sub(find, replace, obj.name) + obj.new_name = re.sub(find, replace, obj.name or '') # Catch regex group reference errors except re.error: obj.new_name = obj.name diff --git a/netbox/templates/dcim/device/consoleports.html b/netbox/templates/dcim/device/consoleports.html index 04184be7c..1f7cd037e 100644 --- a/netbox/templates/dcim/device/consoleports.html +++ b/netbox/templates/dcim/device/consoleports.html @@ -16,31 +16,37 @@
-
- {% if 'bulk_edit' in actions %} - - - - {% endif %} - {% if 'bulk_delete' in actions %} - - {% endif %} -
- {% if perms.dcim.add_consoleport %} - +
+ {% if 'bulk_edit' in actions %} +
+ + +
{% endif %} +
+ {% if 'bulk_delete' in actions %} + + {% endif %} + {% if 'bulk_edit' in actions %} + + {% endif %} +
+
+ {% if perms.dcim.add_consoleport %} + + {% endif %}
{% endblock %} diff --git a/netbox/templates/dcim/device/consoleserverports.html b/netbox/templates/dcim/device/consoleserverports.html index ee1be91d7..259a072b4 100644 --- a/netbox/templates/dcim/device/consoleserverports.html +++ b/netbox/templates/dcim/device/consoleserverports.html @@ -16,31 +16,37 @@
-
- {% if 'bulk_edit' in actions %} - - - - {% endif %} - {% if 'bulk_delete' in actions %} - - {% endif %} -
- {% if perms.dcim.add_consoleserverport %} - +
+ {% if 'bulk_edit' in actions %} +
+ + +
{% endif %} +
+ {% if 'bulk_delete' in actions %} + + {% endif %} + {% if 'bulk_edit' in actions %} + + {% endif %} +
+
+ {% if perms.dcim.add_consoleserverport %} + + {% endif %}
{% endblock %} diff --git a/netbox/templates/dcim/device/devicebays.html b/netbox/templates/dcim/device/devicebays.html index 7836935d9..5081b752b 100644 --- a/netbox/templates/dcim/device/devicebays.html +++ b/netbox/templates/dcim/device/devicebays.html @@ -16,28 +16,30 @@
-
- {% if 'bulk_edit' in actions %} - - - {% endif %} - {% if 'bulk_delete' in actions %} - - {% endif %} -
- {% if perms.dcim.add_devicebay %} - +
+ {% if 'bulk_edit' in actions %} +
+ + +
{% endif %} + {% if 'bulk_delete' in actions %} + + {% endif %} +
+ {% if perms.dcim.add_devicebay %} + + {% endif %}
{% endblock %} diff --git a/netbox/templates/dcim/device/frontports.html b/netbox/templates/dcim/device/frontports.html index 8590fd50e..044337d00 100644 --- a/netbox/templates/dcim/device/frontports.html +++ b/netbox/templates/dcim/device/frontports.html @@ -16,31 +16,37 @@
-
- {% if 'bulk_edit' in actions %} - - - - {% endif %} - {% if 'bulk_delete' in actions %} - - {% endif %} -
- {% if perms.dcim.add_frontport %} - +
+ {% if 'bulk_edit' in actions %} +
+ + +
{% endif %} +
+ {% if 'bulk_delete' in actions %} + + {% endif %} + {% if 'bulk_edit' in actions %} + + {% endif %} +
+
+ {% if perms.dcim.add_frontport %} + + {% endif %}
{% endblock %} diff --git a/netbox/templates/dcim/device/inc/interface_table_controls.html b/netbox/templates/dcim/device/inc/interface_table_controls.html new file mode 100644 index 000000000..14e552439 --- /dev/null +++ b/netbox/templates/dcim/device/inc/interface_table_controls.html @@ -0,0 +1,11 @@ +{% extends 'inc/table_controls_htmx.html' %} + +{% block extra_table_controls %} + + +{% endblock extra_table_controls %} diff --git a/netbox/templates/dcim/device/interfaces.html b/netbox/templates/dcim/device/interfaces.html index ffb574ef3..9de486a6f 100644 --- a/netbox/templates/dcim/device/interfaces.html +++ b/netbox/templates/dcim/device/interfaces.html @@ -4,39 +4,11 @@ {% load static %} {% block content %} -
-
-
- - -
-
-
-
- {% if request.user.is_authenticated %} - - {% endif %} - - -
-
-
+ {% include 'dcim/device/inc/interface_table_controls.html' with table_modal="DeviceInterfaceTable_config" %}
{% csrf_token %} -
{% include 'htmx/table.html' %} @@ -45,30 +17,36 @@
- {% if perms.dcim.change_interface %} - - - - {% endif %} - {% if perms.dcim.delete_interface %} - + {% if 'bulk_edit' in actions %} +
+ + +
{% endif %} +
+ {% if 'bulk_delete' in actions %} + + {% endif %} + {% if 'bulk_edit' in actions %} + + {% endif %} +
{% if perms.dcim.add_interface %}
diff --git a/netbox/templates/dcim/device/inventory.html b/netbox/templates/dcim/device/inventory.html index de981c545..065fd92f6 100644 --- a/netbox/templates/dcim/device/inventory.html +++ b/netbox/templates/dcim/device/inventory.html @@ -16,28 +16,30 @@
-
- {% if 'bulk_edit' in actions %} - - - {% endif %} - {% if 'bulk_delete' in actions %} - - {% endif %} -
- {% if perms.dcim.add_inventoryitem %} - +
+ {% if 'bulk_edit' in actions %} +
+ + +
{% endif %} + {% if 'bulk_delete' in actions %} + + {% endif %} +
+ {% if perms.dcim.add_inventoryitem %} + + {% endif %}
{% endblock %} diff --git a/netbox/templates/dcim/device/modulebays.html b/netbox/templates/dcim/device/modulebays.html index 3e4dadb30..6358a3815 100644 --- a/netbox/templates/dcim/device/modulebays.html +++ b/netbox/templates/dcim/device/modulebays.html @@ -16,28 +16,30 @@
-
- {% if 'bulk_edit' in actions %} - - - {% endif %} - {% if 'bulk_delete' in actions %} - - {% endif %} -
- {% if perms.dcim.add_modulebay %} - +
+ {% if 'bulk_edit' in actions %} +
+ + +
{% endif %} + {% if 'bulk_delete' in actions %} + + {% endif %} +
+ {% if perms.dcim.add_modulebay %} + + {% endif %}
{% table_config_form table %} diff --git a/netbox/templates/dcim/device/poweroutlets.html b/netbox/templates/dcim/device/poweroutlets.html index f9880a4b1..35a9795d5 100644 --- a/netbox/templates/dcim/device/poweroutlets.html +++ b/netbox/templates/dcim/device/poweroutlets.html @@ -16,31 +16,37 @@
-
- {% if 'bulk_edit' in actions %} - - - - {% endif %} - {% if 'bulk_delete' in actions %} - - {% endif %} -
- {% if perms.dcim.add_poweroutlet %} - +
+ {% if 'bulk_edit' in actions %} +
+ + +
{% endif %} +
+ {% if 'bulk_delete' in actions %} + + {% endif %} + {% if 'bulk_edit' in actions %} + + {% endif %} +
+
+ {% if perms.dcim.add_poweroutlet %} + + {% endif %}
{% endblock %} diff --git a/netbox/templates/dcim/device/powerports.html b/netbox/templates/dcim/device/powerports.html index fc426a023..69485c985 100644 --- a/netbox/templates/dcim/device/powerports.html +++ b/netbox/templates/dcim/device/powerports.html @@ -16,31 +16,37 @@
-
- {% if 'bulk_edit' in actions %} - - - - {% endif %} - {% if 'bulk_delete' in actions %} - - {% endif %} -
- {% if perms.dcim.add_powerport %} - +
+ {% if 'bulk_edit' in actions %} +
+ + +
{% endif %} +
+ {% if 'bulk_delete' in actions %} + + {% endif %} + {% if 'bulk_edit' in actions %} + + {% endif %} +
+
+ {% if perms.dcim.add_powerport %} + + {% endif %}
{% endblock %} diff --git a/netbox/templates/dcim/device/rearports.html b/netbox/templates/dcim/device/rearports.html index eee67b6fd..109e195dc 100644 --- a/netbox/templates/dcim/device/rearports.html +++ b/netbox/templates/dcim/device/rearports.html @@ -16,31 +16,37 @@
-
- {% if 'bulk_edit' in actions %} - - - - {% endif %} - {% if 'bulk_delete' in actions %} - - {% endif %} -
- {% if perms.dcim.add_rearport %} - +
+ {% if 'bulk_edit' in actions %} +
+ + +
{% endif %} +
+ {% if 'bulk_delete' in actions %} + + {% endif %} + {% if 'bulk_edit' in actions %} + + {% endif %} +
+
+ {% if perms.dcim.add_rearport %} + + {% endif %}
{% endblock %} diff --git a/netbox/templates/dcim/device_list.html b/netbox/templates/dcim/device_list.html index 60efc842e..50af50525 100644 --- a/netbox/templates/dcim/device_list.html +++ b/netbox/templates/dcim/device_list.html @@ -1,4 +1,5 @@ {% extends 'generic/object_list.html' %} +{% load buttons %} {% block bulk_buttons %} {% if perms.dcim.change_device %} @@ -73,5 +74,15 @@ {% endif %} - {{ block.super }} + {% if 'bulk_edit' in actions %} +
+ {% bulk_edit_button model query_params=request.GET %} + +
+ {% endif %} + {% if 'bulk_delete' in actions %} + {% bulk_delete_button model query_params=request.GET %} + {% endif %} {% endblock %} diff --git a/netbox/templates/inc/table_controls_htmx.html b/netbox/templates/inc/table_controls_htmx.html index 099ad537e..6d6926d5d 100644 --- a/netbox/templates/inc/table_controls_htmx.html +++ b/netbox/templates/inc/table_controls_htmx.html @@ -1,22 +1,22 @@ {% load helpers %} -
-
-
+
+
+
- +
+ {% block extra_table_controls %}{% endblock %}
-
+
{% if request.user.is_authenticated and table_modal %} -
- -
+
+ +
{% endif %}
-
\ No newline at end of file +
diff --git a/netbox/templates/ipam/prefix.html b/netbox/templates/ipam/prefix.html index a47566ff7..b15aa60bb 100644 --- a/netbox/templates/ipam/prefix.html +++ b/netbox/templates/ipam/prefix.html @@ -144,6 +144,13 @@ + {% if object.prefix.version == 4 %} + + {% endif %}
{% include 'inc/panels/custom_fields.html' %} @@ -161,3 +168,39 @@
{% endblock %} + +{% block modals %} + {{ block.super }} + {% if object.prefix.version == 4 %} + + {% endif %} +{% endblock %} diff --git a/netbox/templates/virtualization/virtualmachine/interfaces.html b/netbox/templates/virtualization/virtualmachine/interfaces.html index e3ffb84d4..eff98cdd6 100644 --- a/netbox/templates/virtualization/virtualmachine/interfaces.html +++ b/netbox/templates/virtualization/virtualmachine/interfaces.html @@ -15,27 +15,28 @@
- {% if perms.virtualization.change_vminterface %} - - - {% endif %} - {% if perms.virtualization.delete_vminterface %} - - {% endif %} - {% if perms.virtualization.add_vminterface %} - - {% endif %} -
+ {% if perms.virtualization.change_vminterface %} +
+ + +
+ {% endif %} + {% if perms.virtualization.delete_vminterface %} + + {% endif %} + {% if perms.virtualization.add_vminterface %} + + {% endif %}
{% endblock content %} diff --git a/requirements.txt b/requirements.txt index 1a9aa5f46..9e801a722 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,13 +20,13 @@ gunicorn==20.1.0 Jinja2==3.1.2 Markdown==3.4.1 markdown-include==0.7.0 -mkdocs-material==8.3.9 +mkdocs-material==8.4.0 mkdocstrings[python-legacy]==0.19.0 netaddr==0.8.0 Pillow==9.2.0 psycopg2-binary==2.9.3 PyYAML==6.0 -sentry-sdk==1.9.2 +sentry-sdk==1.9.5 social-auth-app-django==5.0.0 social-auth-core==4.3.0 svgwrite==1.4.3