mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-18 13:06:30 -06:00
Merge v2.11.5
This commit is contained in:
commit
0e23038e28
2
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@ -17,7 +17,7 @@ body:
|
|||||||
What version of NetBox are you currently running? (If you don't have access to the most
|
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/)
|
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.)
|
before opening a bug report to see if your issue has already been addressed.)
|
||||||
placeholder: v2.11.4
|
placeholder: v2.11.5
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
|
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
@ -14,7 +14,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: NetBox version
|
label: NetBox version
|
||||||
description: What version of NetBox are you currently running?
|
description: What version of NetBox are you currently running?
|
||||||
placeholder: v2.11.4
|
placeholder: v2.11.5
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
|
@ -80,7 +80,7 @@ class DeviceConnectionsReport(Report):
|
|||||||
self.log_success(device)
|
self.log_success(device)
|
||||||
```
|
```
|
||||||
|
|
||||||
As you can see, reports are completely customizable. Validation logic can be as simple or as complex as needed.
|
As you can see, reports are completely customizable. Validation logic can be as simple or as complex as needed. Also note that the `description` attribute support markdown syntax. It will be rendered in the report list page.
|
||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
Reports should never alter data: If you find yourself using the `create()`, `save()`, `update()`, or `delete()` methods on objects within reports, stop and re-evaluate what you're trying to accomplish. Note that there are no safeguards against the accidental alteration or destruction of data.
|
Reports should never alter data: If you find yourself using the `create()`, `save()`, `update()`, or `delete()` methods on objects within reports, stop and re-evaluate what you're trying to accomplish. Note that there are no safeguards against the accidental alteration or destruction of data.
|
||||||
@ -93,7 +93,7 @@ The following methods are available to log results within a report:
|
|||||||
* log_warning(object, message)
|
* log_warning(object, message)
|
||||||
* log_failure(object, message)
|
* log_failure(object, message)
|
||||||
|
|
||||||
The recording of one or more failure messages will automatically flag a report as failed. It is advised to log a success for each object that is evaluated so that the results will reflect how many objects are being reported on. (The inclusion of a log message is optional for successes.) Messages recorded with `log()` will appear in a report's results but are not associated with a particular object or status.
|
The recording of one or more failure messages will automatically flag a report as failed. It is advised to log a success for each object that is evaluated so that the results will reflect how many objects are being reported on. (The inclusion of a log message is optional for successes.) Messages recorded with `log()` will appear in a report's results but are not associated with a particular object or status. Log messages also support using markdown syntax and will be rendered on the report result page.
|
||||||
|
|
||||||
To perform additional tasks, such as sending an email or calling a webhook, after a report has been run, extend the `post_run()` method. The status of the report is available as `self.failed` and the results object is `self.result`.
|
To perform additional tasks, such as sending an email or calling a webhook, after a report has been run, extend the `post_run()` method. The status of the report is available as `self.failed` and the results object is `self.result`.
|
||||||
|
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
# NetBox v2.11
|
# NetBox v2.11
|
||||||
|
|
||||||
## v2.11.5 (FUTURE)
|
## v2.11.5 (2021-06-04)
|
||||||
|
|
||||||
|
**NOTE:** This release includes a database migration that calculates and annotates prefix depth. It may impose a noticeable delay on the upgrade process: Users should anticipate roughly one minute of delay per 100 thousand prefixes being updated.
|
||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
||||||
* [#6087](https://github.com/netbox-community/netbox/issues/6087) - Improved prefix hierarchy rendering
|
* [#6087](https://github.com/netbox-community/netbox/issues/6087) - Improved prefix hierarchy rendering
|
||||||
* [#6487](https://github.com/netbox-community/netbox/issues/6487) - Add location filter to cable connection form
|
* [#6487](https://github.com/netbox-community/netbox/issues/6487) - Add location filter to cable connection form
|
||||||
* [#6501](https://github.com/netbox-community/netbox/issues/6501) - Expose prefix depth and children on REST API serializer
|
* [#6501](https://github.com/netbox-community/netbox/issues/6501) - Expose prefix depth and children on REST API serializer
|
||||||
|
* [#6527](https://github.com/netbox-community/netbox/issues/6527) - Support Markdown for report descriptions
|
||||||
|
* [#6540](https://github.com/netbox-community/netbox/issues/6540) - Add a "flat" column to the prefix table
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ class IPAddressSerializer(PrimaryModelSerializer):
|
|||||||
)
|
)
|
||||||
assigned_object = serializers.SerializerMethodField(read_only=True)
|
assigned_object = serializers.SerializerMethodField(read_only=True)
|
||||||
nat_inside = NestedIPAddressSerializer(required=False, allow_null=True)
|
nat_inside = NestedIPAddressSerializer(required=False, allow_null=True)
|
||||||
nat_outside = NestedIPAddressSerializer(read_only=True)
|
nat_outside = NestedIPAddressSerializer(required=False, read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IPAddress
|
model = IPAddress
|
||||||
@ -282,7 +282,7 @@ class IPAddressSerializer(PrimaryModelSerializer):
|
|||||||
'assigned_object_id', 'assigned_object', 'nat_inside', 'nat_outside', 'dns_name', 'description', 'tags',
|
'assigned_object_id', 'assigned_object', 'nat_inside', 'nat_outside', 'dns_name', 'description', 'tags',
|
||||||
'custom_fields', 'created', 'last_updated',
|
'custom_fields', 'created', 'last_updated',
|
||||||
]
|
]
|
||||||
read_only_fields = ['family']
|
read_only_fields = ['family', 'nat_outside']
|
||||||
|
|
||||||
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
||||||
def get_assigned_object(self, obj):
|
def get_assigned_object(self, obj):
|
||||||
|
@ -4,17 +4,6 @@ from django.db import migrations
|
|||||||
from ipam.utils import rebuild_prefixes
|
from ipam.utils import rebuild_prefixes
|
||||||
|
|
||||||
|
|
||||||
def push_to_stack(stack, prefix):
|
|
||||||
# Increment child count on parent nodes
|
|
||||||
for n in stack:
|
|
||||||
n['children'] += 1
|
|
||||||
stack.append({
|
|
||||||
'pk': prefix['pk'],
|
|
||||||
'prefix': prefix['prefix'],
|
|
||||||
'children': 0,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
def populate_prefix_hierarchy(apps, schema_editor):
|
def populate_prefix_hierarchy(apps, schema_editor):
|
||||||
"""
|
"""
|
||||||
Populate _depth and _children attrs for all Prefixes.
|
Populate _depth and _children attrs for all Prefixes.
|
||||||
|
@ -277,6 +277,11 @@ class PrefixTable(BaseTable):
|
|||||||
template_code=PREFIX_LINK,
|
template_code=PREFIX_LINK,
|
||||||
attrs={'td': {'class': 'text-nowrap'}}
|
attrs={'td': {'class': 'text-nowrap'}}
|
||||||
)
|
)
|
||||||
|
prefix_flat = tables.Column(
|
||||||
|
accessor=Accessor('prefix'),
|
||||||
|
linkify=True,
|
||||||
|
verbose_name='Prefix (Flat)'
|
||||||
|
)
|
||||||
depth = tables.Column(
|
depth = tables.Column(
|
||||||
accessor=Accessor('_depth'),
|
accessor=Accessor('_depth'),
|
||||||
verbose_name='Depth'
|
verbose_name='Depth'
|
||||||
@ -318,8 +323,8 @@ class PrefixTable(BaseTable):
|
|||||||
class Meta(BaseTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
model = Prefix
|
model = Prefix
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'prefix', 'status', 'depth', 'children', 'vrf', 'tenant', 'site', 'vlan', 'role', 'is_pool',
|
'pk', 'prefix', 'prefix_flat', 'status', 'depth', 'children', 'vrf', 'tenant', 'site', 'vlan', 'role',
|
||||||
'mark_utilized', 'description',
|
'is_pool', 'mark_utilized', 'description',
|
||||||
)
|
)
|
||||||
default_columns = ('pk', 'prefix', 'status', 'vrf', 'tenant', 'site', 'vlan', 'role', 'description')
|
default_columns = ('pk', 'prefix', 'status', 'vrf', 'tenant', 'site', 'vlan', 'role', 'description')
|
||||||
row_attrs = {
|
row_attrs = {
|
||||||
@ -332,15 +337,14 @@ class PrefixDetailTable(PrefixTable):
|
|||||||
accessor='get_utilization',
|
accessor='get_utilization',
|
||||||
orderable=False
|
orderable=False
|
||||||
)
|
)
|
||||||
tenant = TenantColumn()
|
|
||||||
tags = TagColumn(
|
tags = TagColumn(
|
||||||
url_name='ipam:prefix_list'
|
url_name='ipam:prefix_list'
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(PrefixTable.Meta):
|
class Meta(PrefixTable.Meta):
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'prefix', 'status', 'children', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role', 'is_pool',
|
'pk', 'prefix', 'prefix_flat', 'status', 'children', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role',
|
||||||
'mark_utilized', 'description', 'tags',
|
'is_pool', 'mark_utilized', 'description', 'tags',
|
||||||
)
|
)
|
||||||
default_columns = (
|
default_columns = (
|
||||||
'pk', 'prefix', 'status', 'children', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role', 'description',
|
'pk', 'prefix', 'status', 'children', 'vrf', 'utilization', 'tenant', 'site', 'vlan', 'role', 'description',
|
||||||
|
@ -16,7 +16,7 @@ from django.core.validators import URLValidator
|
|||||||
# Environment setup
|
# Environment setup
|
||||||
#
|
#
|
||||||
|
|
||||||
VERSION = '2.12-beta1'
|
VERSION = '3.0-beta1'
|
||||||
|
|
||||||
# Hostname
|
# Hostname
|
||||||
HOSTNAME = platform.node()
|
HOSTNAME = platform.node()
|
||||||
|
@ -774,9 +774,7 @@ class BulkEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
|
|||||||
|
|
||||||
# If we are editing *all* objects in the queryset, replace the PK list with all matched objects.
|
# If we are editing *all* objects in the queryset, replace the PK list with all matched objects.
|
||||||
if request.POST.get('_all') and self.filterset is not None:
|
if request.POST.get('_all') and self.filterset is not None:
|
||||||
pk_list = [
|
pk_list = self.filterset(request.GET, self.queryset.values_list('pk', flat=True)).qs
|
||||||
obj.pk for obj in self.filterset(request.GET, self.queryset.only('pk')).qs
|
|
||||||
]
|
|
||||||
else:
|
else:
|
||||||
pk_list = request.POST.getlist('pk')
|
pk_list = request.POST.getlist('pk')
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if report.description %}
|
{% if report.description %}
|
||||||
<p class="text-muted">{{ report.description }}</p>
|
<p class="text-muted">{{ report.description|render_markdown }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.extras.run_report %}
|
{% if perms.extras.run_report %}
|
||||||
<div class="float-end noprint">
|
<div class="float-end noprint">
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
{% if reports %}
|
{% if reports %}
|
||||||
{% for module, module_reports in reports %}
|
{% for module, module_reports in reports %}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h5 class="card-header"><a name="module.{{ module }}"></a>{{ module|bettertitle }}</h3>
|
<h5 class="card-header"><a name="module.{{ module }}"></a>{{ module|bettertitle }}</h5>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<table class="table table-hover table-headings reports">
|
<table class="table table-hover table-headings reports">
|
||||||
<thead>
|
<thead>
|
||||||
@ -32,7 +32,7 @@
|
|||||||
<td>
|
<td>
|
||||||
{% include 'extras/inc/job_label.html' with result=report.result %}
|
{% include 'extras/inc/job_label.html' with result=report.result %}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ report.description|placeholder }}</td>
|
<td>{{ report.description|render_markdown|placeholder }}</td>
|
||||||
<td class="text-end">
|
<td class="text-end">
|
||||||
{% if report.result %}
|
{% if report.result %}
|
||||||
<a href="{% url 'extras:report_result' job_result_pk=report.result.pk %}">{{ report.result.created }}</a>
|
<a href="{% url 'extras:report_result' job_result_pk=report.result.pk %}">{{ report.result.created }}</a>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
Django==3.2.3
|
Django==3.2.4
|
||||||
django-cacheops==6.0
|
django-cacheops==6.0
|
||||||
django-cors-headers==3.7.0
|
django-cors-headers==3.7.0
|
||||||
django-debug-toolbar==3.2.1
|
django-debug-toolbar==3.2.1
|
||||||
|
Loading…
Reference in New Issue
Block a user