mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 01:41:22 -06:00
Merge branch 'develop' into feature
This commit is contained in:
commit
f93d6813a9
5
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
5
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
||||

|
||||
|
||||
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
|
||||
|
@ -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:
|
||||
|
||||

|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
||||
---
|
||||
|
||||
|
@ -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'),
|
||||
|
@ -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',
|
||||
|
@ -41,15 +41,11 @@ 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 }}"
|
||||
{% 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 %}
|
||||
>
|
||||
{{ ip }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
"""
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
BIN
netbox/project-static/dist/netbox-dark.css
vendored
BIN
netbox/project-static/dist/netbox-dark.css
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox-light.css
vendored
BIN
netbox/project-static/dist/netbox-light.css
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox-print.css
vendored
BIN
netbox/project-static/dist/netbox-print.css
vendored
Binary file not shown.
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
"""
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user