Преглед изворни кода

Merge branch 'develop' into feature

jeremystretch пре 4 година
родитељ
комит
f93d6813a9

+ 1 - 4
.github/ISSUE_TEMPLATE/bug_report.yaml

@@ -13,10 +13,7 @@ body:
   - type: input
     attributes:
       label: NetBox version
-      description: >
-        What version of NetBox are you currently running? (If you don't have access to the most
-        recent NetBox release, consider testing on our [demo instance](https://demo.netbox.dev/)
-        before opening a bug report to see if your issue has already been addressed.)
+      description: What version of NetBox are you currently running?
       placeholder: v3.0.9
     validations:
       required: true

+ 4 - 8
CONTRIBUTING.md

@@ -76,14 +76,10 @@ free to add a comment with any additional justification for the feature.
 (However, note that comments with no substance other than a "+1" will be
 deleted. Please use GitHub's reactions feature to indicate your support.)
 
-* Due to a large backlog of feature requests, we are not currently accepting
-any proposals which substantially extend NetBox's functionality beyond its
-current feature set. This includes the introduction of any new views or models
-which have not already been proposed in an existing feature request.
-
-* Before filing a new feature request, consider raising your idea on the
-mailing list first. Feedback you receive there will help validate and shape the
-proposed feature before filing a formal issue.
+* Before filing a new feature request, consider raising your idea in a
+[GitHub discussion](https://github.com/netbox-community/netbox/discussions)
+first. Feedback you receive there will help validate and shape the proposed
+feature before filing a formal issue.
 
 * Good feature requests are very narrowly defined. Be sure to thoroughly
 describe the functionality and data model(s) being proposed. The more effort

+ 10 - 0
docs/core-functionality/devices.md

@@ -27,3 +27,13 @@ Device components represent discrete objects within a device which are used to t
 ---
 
 {!models/dcim/cable.md!}
+
+In the example below, three individual cables comprise a path between devices A and D:
+
+![Cable path](../media/models/dcim_cable_trace.png)
+
+Traced from Interface 1 on Device A, NetBox will show the following path:
+
+* Cable 1: Interface 1 to Front Port 1
+* Cable 2: Rear Port 1 to Rear Port 2
+* Cable 3: Front Port 2 to Interface 2

+ 0 - 10
docs/models/dcim/cable.md

@@ -22,13 +22,3 @@ Each cable may be assigned a type, label, length, and color. Each cable is also
 ## Tracing Cables
 
 A cable may be traced from either of its endpoints by clicking the "trace" button. (A REST API endpoint also provides this functionality.) NetBox will follow the path of connected cables from this termination across the directly connected cable to the far-end termination. If the cable connects to a pass-through port, and the peer port has another cable connected, NetBox will continue following the cable path until it encounters a non-pass-through or unconnected termination point. The entire path will be displayed to the user.
-
-In the example below, three individual cables comprise a path between devices A and D:
-
-![Cable path](../media/models/dcim_cable_trace.png)
-
-Traced from Interface 1 on Device A, NetBox will show the following path:
-
-* Cable 1: Interface 1 to Front Port 1
-* Cable 2: Rear Port 1 to Rear Port 2
-* Cable 3: Front Port 2 to Interface 2

+ 10 - 0
docs/release-notes/version-3.0.md

@@ -2,9 +2,19 @@
 
 ## v3.0.10 (FUTURE)
 
+### Enhancements
+
+* [#7740](https://github.com/netbox-community/netbox/issues/7740) - Add mini-DIN 8 console port type
+* [#7760](https://github.com/netbox-community/netbox/issues/7760) - Add `vid` filter field to VLANs list
+
 ### Bug Fixes
 
+* [#7701](https://github.com/netbox-community/netbox/issues/7701) - Fix conflation of assigned IP status & role in interface tables
+* [#7741](https://github.com/netbox-community/netbox/issues/7741) - Fix 404 when attaching multiple images in succession
 * [#7752](https://github.com/netbox-community/netbox/issues/7752) - Fix minimum version check under Python v3.10
+* [#7766](https://github.com/netbox-community/netbox/issues/7766) - Add missing outer dimension columns to rack table
+* [#7780](https://github.com/netbox-community/netbox/issues/7780) - Preserve mutli-line values during CSV file import
+* [#7783](https://github.com/netbox-community/netbox/issues/7783) - Fix indentation of locations under site view
 
 ---
 

+ 2 - 0
netbox/dcim/choices.py

@@ -204,6 +204,7 @@ class ConsolePortTypeChoices(ChoiceSet):
     TYPE_RJ11 = 'rj-11'
     TYPE_RJ12 = 'rj-12'
     TYPE_RJ45 = 'rj-45'
+    TYPE_MINI_DIN_8 = 'mini-din-8'
     TYPE_USB_A = 'usb-a'
     TYPE_USB_B = 'usb-b'
     TYPE_USB_C = 'usb-c'
@@ -221,6 +222,7 @@ class ConsolePortTypeChoices(ChoiceSet):
             (TYPE_RJ11, 'RJ-11'),
             (TYPE_RJ12, 'RJ-12'),
             (TYPE_RJ45, 'RJ-45'),
+            (TYPE_MINI_DIN_8, 'Mini-DIN 8'),
         )),
         ('USB', (
             (TYPE_USB_A, 'USB Type A'),

+ 9 - 1
netbox/dcim/tables/racks.py

@@ -75,12 +75,20 @@ class RackTable(BaseTable):
     tags = TagColumn(
         url_name='dcim:rack_list'
     )
+    outer_width = tables.TemplateColumn(
+        template_code="{{ record.outer_width }} {{ record.outer_unit }}",
+        verbose_name='Outer Width'
+    )
+    outer_depth = tables.TemplateColumn(
+        template_code="{{ record.outer_depth }} {{ record.outer_unit }}",
+        verbose_name='Outer Depth'
+    )
 
     class Meta(BaseTable.Meta):
         model = Rack
         fields = (
             'pk', 'id', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'role', 'serial', 'asset_tag', 'type',
-            'width', 'u_height', 'comments', 'device_count', 'get_utilization', 'get_power_utilization', 'tags',
+            'width', 'outer_width', 'outer_depth', 'u_height', 'comments', 'device_count', 'get_utilization', 'get_power_utilization', 'tags',
         )
         default_columns = (
             'pk', 'name', 'site', 'location', 'status', 'facility_id', 'tenant', 'role', 'u_height', 'device_count',

+ 7 - 11
netbox/dcim/tables/template_code.py

@@ -40,17 +40,13 @@ DEVICEBAY_STATUS = """
 
 INTERFACE_IPADDRESSES = """
 <div class="table-badge-group">
-    {% for ip in record.ip_addresses.all %}
-        <a
-        class="table-badge{% if ip.status != 'active' %} badge bg-{{ ip.get_status_class }}{% elif ip.role %} badge bg-{{ ip.get_role_class }}{% endif %}"
-        href="{{ ip.get_absolute_url }}"
-        {% if ip.status != 'active'%}data-bs-toggle="tooltip" data-bs-placement="left" title="{{ ip.get_status_display }}"
-        {% elif ip.role %}data-bs-toggle="tooltip" data-bs-placement="left" title="{{ ip.get_role_display }}"
-        {% endif %}
-        >
-        {{ ip }}
-        </a>
-    {% endfor %}
+  {% for ip in record.ip_addresses.all %}
+    {% if ip.status != 'active' %}
+      <a href="{{ ip.get_absolute_url }}" class="table-badge badge bg-{{ ip.get_status_class }}" data-bs-toggle="tooltip" data-bs-placement="left" title="{{ ip.get_status_display }}">{{ ip }}</a>
+    {% else %}
+      <a href="{{ ip.get_absolute_url }}" class="table-badge">{{ ip }}</a>
+    {% endif %}
+  {% endfor %}
 </div>
 """
 

+ 2 - 0
netbox/extras/models/models.py

@@ -353,6 +353,8 @@ class ImageAttachment(BigIDModel):
 
     objects = RestrictedQuerySet.as_manager()
 
+    clone_fields = ('content_type', 'object_id')
+
     class Meta:
         ordering = ('name', 'pk')  # name may be non-unique
 

+ 1 - 5
netbox/extras/views.py

@@ -475,11 +475,7 @@ class ImageAttachmentEditView(generic.ObjectEditView):
     def alter_obj(self, instance, request, args, kwargs):
         if not instance.pk:
             # Assign the parent object based on URL kwargs
-            try:
-                app_label, model = request.GET.get('content_type').split('.')
-            except (AttributeError, ValueError):
-                raise Http404("Content type not specified")
-            content_type = get_object_or_404(ContentType, app_label=app_label, model=model)
+            content_type = get_object_or_404(ContentType, pk=request.GET.get('content_type'))
             instance.parent = get_object_or_404(content_type.model_class(), pk=request.GET.get('object_id'))
         return instance
 

+ 6 - 1
netbox/ipam/forms/filtersets.py

@@ -1,3 +1,4 @@
+import django_filters
 from django import forms
 from django.utils.translation import gettext as _
 
@@ -471,7 +472,7 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo
     field_groups = [
         ['q', 'tag'],
         ['region_id', 'site_group_id', 'site_id'],
-        ['group_id', 'status', 'role_id'],
+        ['group_id', 'status', 'role_id', 'vid'],
         ['tenant_group_id', 'tenant_id'],
     ]
     q = forms.CharField(
@@ -523,6 +524,10 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo
         label=_('Role'),
         fetch_trigger='open'
     )
+    vid = forms.IntegerField(
+        required=False,
+        label='VLAN ID'
+    )
     tag = TagFilterField(model)
 
 

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
netbox/project-static/dist/netbox-dark.css


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
netbox/project-static/dist/netbox-light.css


Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
netbox/project-static/dist/netbox-print.css


+ 1 - 1
netbox/project-static/styles/netbox.scss

@@ -814,7 +814,7 @@ table .table-badge-group {
     }
 
     &.badge:not(:last-of-type):not(:only-child) {
-      margin-bottom: map.get($spacers, 2);
+      margin-bottom: map.get($spacers, 1);
     }
   }
 }

+ 2 - 2
netbox/templates/dcim/site.html

@@ -236,8 +236,8 @@
                     </tr>
                     {% for location in locations %}
                         <tr>
-                            <td style="padding-left: {{ location.level }}8px">
-                                <i class="mdi mdi-folder-open"></i>
+                            <td>
+                                {% for i in location.level|as_range %}<i class="mdi mdi-circle-small"></i>{% endfor %}
                                 <a href="{{ location.get_absolute_url }}">{{ location }}</a>
                             </td>
                             <td>

+ 1 - 1
netbox/templates/inc/panels/image_attachments.html

@@ -44,7 +44,7 @@
   </div>
   {% if perms.extras.add_imageattachment %}
     <div class="card-footer text-end noprint">
-      <a href="{% url 'extras:imageattachment_add' %}?content_type={{ object|meta:"app_label" }}.{{ object|meta:"model_name" }}&object_id={{ object.pk }}" class="btn btn-primary btn-sm">
+      <a href="{% url 'extras:imageattachment_add' %}?content_type={{ object|content_type_id }}&object_id={{ object.pk }}" class="btn btn-primary btn-sm">
         <i class="mdi mdi-plus-thick" aria-hidden="true"></i> Attach an image
       </a>
     </div>

+ 1 - 1
netbox/utilities/forms/fields.py

@@ -248,7 +248,7 @@ class CSVFileField(forms.FileField):
             return None
 
         csv_str = file.read().decode('utf-8').strip()
-        reader = csv.reader(csv_str.splitlines())
+        reader = csv.reader(StringIO(csv_str))
         headers, records = parse_csv(reader)
 
         return headers, records

+ 20 - 0
netbox/utilities/templatetags/helpers.py

@@ -7,6 +7,7 @@ from typing import Dict, Any
 import yaml
 from django import template
 from django.conf import settings
+from django.contrib.contenttypes.models import ContentType
 from django.template.defaultfilters import date
 from django.urls import NoReverseMatch, reverse
 from django.utils import timezone
@@ -80,6 +81,25 @@ def meta(obj, attr):
     return getattr(obj._meta, attr, '')
 
 
+@register.filter()
+def content_type(obj):
+    """
+    Return the ContentType for the given object.
+    """
+    return ContentType.objects.get_for_model(obj)
+
+
+@register.filter()
+def content_type_id(obj):
+    """
+    Return the ContentType ID for the given object.
+    """
+    content_type = ContentType.objects.get_for_model(obj)
+    if content_type:
+        return content_type.pk
+    return None
+
+
 @register.filter()
 def viewname(model, action):
     """

+ 6 - 0
scripts/git-hooks/pre-commit

@@ -11,6 +11,7 @@ exec 1>&2
 
 EXIT=0
 RED='\033[0;31m'
+YELLOW='\033[0;33m'
 NOCOLOR='\033[0m'
 
 if [ -d ./venv/ ]; then
@@ -22,6 +23,11 @@ if [ -d ./venv/ ]; then
     fi
 fi
 
+if [ ${NOVALIDATE} ]; then
+  echo "${YELLOW}Skipping validation checks${NOCOLOR}"
+  exit $EXIT
+fi
+
 echo "Validating PEP8 compliance..."
 pycodestyle --ignore=W504,E501 --exclude=node_modules netbox/
 if [ $? != 0 ]; then

Неке датотеке нису приказане због велике количине промена