Skip to content

Commit

Permalink
Merge pull request #14386 from netbox-community/develop
Browse files Browse the repository at this point in the history
Release v3.6.6
  • Loading branch information
jeremystretch committed Nov 30, 2023
2 parents 6ac25ee + 04fd455 commit 28080e9
Show file tree
Hide file tree
Showing 26 changed files with 176 additions and 113 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yaml
Expand Up @@ -14,7 +14,7 @@ body:
attributes:
label: NetBox version
description: What version of NetBox are you currently running?
placeholder: v3.6.5
placeholder: v3.6.6
validations:
required: true
- type: dropdown
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature_request.yaml
Expand Up @@ -14,7 +14,7 @@ body:
attributes:
label: NetBox version
description: What version of NetBox are you currently running?
placeholder: v3.6.5
placeholder: v3.6.6
validations:
required: true
- type: dropdown
Expand Down
23 changes: 23 additions & 0 deletions docs/release-notes/version-3.6.md
@@ -1,5 +1,28 @@
# NetBox v3.6

## v3.6.6 (2023-11-29)

### Enhancements

* [#13735](https://github.com/netbox-community/netbox/issues/13735) - Show complete region hierarchy in UI for all relevant objects

### Bug Fixes

* [#14056](https://github.com/netbox-community/netbox/issues/14056) - Record a pre-change snapshot when bulk editing objects via CSV
* [#14187](https://github.com/netbox-community/netbox/issues/14187) - Raise a validation error when attempting to create a duplicate script or report
* [#14199](https://github.com/netbox-community/netbox/issues/14199) - Fix jobs list for reports with a custom name
* [#14239](https://github.com/netbox-community/netbox/issues/14239) - Fix CustomFieldChoiceSet search filter
* [#14242](https://github.com/netbox-community/netbox/issues/14242) - Enable export templates for contact assignments
* [#14299](https://github.com/netbox-community/netbox/issues/14299) - Webhook timestamps should be in proper ISO 8601 format
* [#14325](https://github.com/netbox-community/netbox/issues/14325) - Fix numeric ordering of service ports
* [#14339](https://github.com/netbox-community/netbox/issues/14339) - Correctly hash local user password when set via REST API
* [#14343](https://github.com/netbox-community/netbox/issues/14343) - Fix ordering ASN table by ASDOT column
* [#14346](https://github.com/netbox-community/netbox/issues/14346) - Fix running reports via REST API
* [#14349](https://github.com/netbox-community/netbox/issues/14349) - Fix custom validation support for remote data sources
* [#14363](https://github.com/netbox-community/netbox/issues/14363) - Fix bulk editing of interfaces assigned to VM with no cluster

---

## v3.6.5 (2023-11-09)

### Enhancements
Expand Down
1 change: 1 addition & 0 deletions netbox/core/models/data.py
Expand Up @@ -122,6 +122,7 @@ def ready_for_sync(self):
)

def clean(self):
super().clean()

# Ensure URL scheme matches selected type
if self.type == DataSourceTypeChoices.LOCAL and self.url_scheme not in ('file', ''):
Expand Down
9 changes: 9 additions & 0 deletions netbox/core/models/files.py
Expand Up @@ -2,6 +2,7 @@
import os

from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models
from django.urls import reverse
from django.utils.translation import gettext as _
Expand Down Expand Up @@ -84,6 +85,14 @@ def sync_data(self):
self.file_path = os.path.basename(self.data_path)
self.data_file.write_to_disk(self.full_path, overwrite=True)

def clean(self):
super().clean()

# Ensure that the file root and path make a unique pair
if self._meta.model.objects.filter(file_root=self.file_root, file_path=self.file_path).exclude(pk=self.pk).exists():
raise ValidationError(
f"A {self._meta.verbose_name.lower()} with this file path already exists ({self.file_root}/{self.file_path}).")

def delete(self, *args, **kwargs):
# Delete file from disk
try:
Expand Down
2 changes: 1 addition & 1 deletion netbox/core/models/jobs.py
Expand Up @@ -229,7 +229,7 @@ def trigger_webhooks(self, event):
model_name=self.object_type.model,
event=event,
data=self.data,
timestamp=str(timezone.now()),
timestamp=timezone.now().isoformat(),
username=self.user.username,
retry=get_rq_retry()
)
2 changes: 1 addition & 1 deletion netbox/extras/api/views.py
Expand Up @@ -283,7 +283,7 @@ def run(self, request, pk):

# Retrieve and run the Report. This will create a new Job.
module, report_cls = self._get_report(pk)
report = report_cls()
report = report_cls
input_serializer = serializers.ReportInputSerializer(
data=request.data,
context={'report': report}
Expand Down
3 changes: 1 addition & 2 deletions netbox/extras/filtersets.py
Expand Up @@ -122,8 +122,7 @@ def search(self, queryset, name, value):
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(description__icontains=value) |
Q(extra_choices__contains=value)
Q(description__icontains=value)
)

def filter_by_choice(self, queryset, name, value):
Expand Down
2 changes: 1 addition & 1 deletion netbox/extras/views.py
Expand Up @@ -1073,7 +1073,7 @@ def get(self, request, module, name):
jobs = Job.objects.filter(
object_type=object_type,
object_id=module.pk,
name=report.name
name=report.class_name
)

jobs_table = JobTable(
Expand Down
2 changes: 1 addition & 1 deletion netbox/extras/webhooks.py
Expand Up @@ -115,7 +115,7 @@ def flush_webhooks(queue):
event=data['event'],
data=data['data'],
snapshots=data['snapshots'],
timestamp=str(timezone.now()),
timestamp=timezone.now().isoformat(),
username=data['username'],
request_id=data['request_id'],
retry=get_rq_retry()
Expand Down
1 change: 1 addition & 0 deletions netbox/ipam/tables/asn.py
Expand Up @@ -48,6 +48,7 @@ class ASNTable(TenancyColumnsMixin, NetBoxTable):
asn_asdot = tables.Column(
accessor=tables.A('asn_asdot'),
linkify=True,
order_by=tables.A('asn'),
verbose_name=_('ASDOT')
)
site_count = columns.LinkedCountColumn(
Expand Down
2 changes: 1 addition & 1 deletion netbox/netbox/settings.py
Expand Up @@ -25,7 +25,7 @@
# Environment setup
#

VERSION = '3.6.5'
VERSION = '3.6.6'

# Hostname
HOSTNAME = platform.node()
Expand Down
4 changes: 4 additions & 0 deletions netbox/netbox/views/generic/bulk_views.py
Expand Up @@ -394,6 +394,10 @@ def create_and_update_objects(self, form, request):
form.add_error('data', f"Row {i}: Object with ID {object_id} does not exist")
raise ValidationError('')

# Take a snapshot for change logging
if instance.pk and hasattr(instance, 'snapshot'):
instance.snapshot()

# Instantiate the model form for the object
model_form_kwargs = {
'data': record,
Expand Down
23 changes: 3 additions & 20 deletions netbox/templates/dcim/device.html
Expand Up @@ -5,6 +5,7 @@
{% load helpers %}
{% load plugins %}
{% load i18n %}
{% load mptt %}

{% block content %}
<div class="row">
Expand All @@ -15,33 +16,15 @@ <h5 class="card-header">{% trans "Device" %}</h5>
<table class="table table-hover attr-table">
<tr>
<th scope="row">{% trans "Region" %}</th>
<td>
{% if object.site.region %}
{% for region in object.site.region.get_ancestors %}
{{ region|linkify }} /
{% endfor %}
{{ object.site.region|linkify }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
<td>{% nested_tree object.site.region %}</td>
</tr>
<tr>
<th scope="row">{% trans "Site" %}</th>
<td>{{ object.site|linkify }}</td>
</tr>
<tr>
<th scope="row">{% trans "Location" %}</th>
<td>
{% if object.location %}
{% for location in object.location.get_ancestors %}
{{ location|linkify }} /
{% endfor %}
{{ object.location|linkify }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
<td>{% nested_tree object.location %}</td>
</tr>
<tr>
<th scope="row">{% trans "Rack" %}</th>
Expand Down
23 changes: 8 additions & 15 deletions netbox/templates/dcim/rack.html
Expand Up @@ -4,6 +4,7 @@
{% load static %}
{% load plugins %}
{% load i18n %}
{% load mptt %}

{% block content %}
<div class="row">
Expand All @@ -15,26 +16,18 @@ <h5 class="card-header">
<div class="card-body">
<table class="table table-hover attr-table">
<tr>
<th scope="row">{% trans "Site" %}</th>
<th scope="row">{% trans "Region" %}</th>
<td>
{% if object.site.region %}
{{ object.site.region|linkify }} /
{% endif %}
{{ object.site|linkify }}
{% nested_tree object.site.region %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Site" %}</th>
<td>{{ object.site|linkify }}</td>
</tr>
<tr>
<th scope="row">{% trans "Location" %}</th>
<td>
{% if object.location %}
{% for location in object.location.get_ancestors %}
{{ location|linkify }} /
{% endfor %}
{{ object.location|linkify }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
<td>{% nested_tree object.location %}</td>
</tr>
<tr>
<th scope="row">{% trans "Facility ID" %}</th>
Expand Down
38 changes: 19 additions & 19 deletions netbox/templates/dcim/rackreservation.html
Expand Up @@ -4,6 +4,7 @@
{% load static %}
{% load plugins %}
{% load i18n %}
{% load mptt %}

{% block breadcrumbs %}
{{ block.super }}
Expand All @@ -20,25 +21,24 @@ <h5 class="card-header">
</h5>
<div class="card-body">
<table class="table table-hover attr-table">
{% with rack=object.rack %}
<tr>
<th scope="row">{% trans "Site" %}</th>
<td>
{% if rack.site.region %}
{{ rack.site.region|linkify }} /
{% endif %}
{{ rack.site|linkify }}
</td>
</tr>
<tr>
<th scope="row">{% trans "Location" %}</th>
<td>{{ rack.location|linkify|placeholder }}</td>
</tr>
<tr>
<th scope="row">{% trans "Rack" %}</th>
<td>{{ rack|linkify }}</td>
</tr>
{% endwith %}
<tr>
<th scope="row">{% trans "Region" %}</th>
<td>
{% nested_tree object.rack.site.region %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Site" %}</th>
<td>{{ object.rack.site|linkify }}</td>
</tr>
<tr>
<th scope="row">{% trans "Location" %}</th>
<td>{{ object.rack.location|linkify|placeholder }}</td>
</tr>
<tr>
<th scope="row">{% trans "Rack" %}</th>
<td>{{ object.rack|linkify }}</td>
</tr>
</table>
</div>
</div>
Expand Down
19 changes: 3 additions & 16 deletions netbox/templates/dcim/site.html
Expand Up @@ -3,6 +3,7 @@
{% load plugins %}
{% load tz %}
{% load i18n %}
{% load mptt %}

{% block breadcrumbs %}
{{ block.super }}
Expand All @@ -29,27 +30,13 @@ <h5 class="card-header">{% trans "Site" %}</h5>
<tr>
<th scope="row">{% trans "Region" %}</th>
<td>
{% if object.region %}
{% for region in object.region.get_ancestors %}
{{ region|linkify }} /
{% endfor %}
{{ object.region|linkify }}
{% else %}
{{ ''|placeholder }}
{% endif %}
{% nested_tree object.region %}
</td>
</tr>
<tr>
<th scope="row">{% trans "Group" %}</th>
<td>
{% if object.group %}
{% for group in object.group.get_ancestors %}
{{ group|linkify }} /
{% endfor %}
{{ object.group|linkify }}
{% else %}
{{ ''|placeholder }}
{% endif %}
{% nested_tree object.group %}
</td>
</tr>
<tr>
Expand Down
20 changes: 10 additions & 10 deletions netbox/templates/ipam/prefix.html
Expand Up @@ -3,6 +3,7 @@
{% load helpers %}
{% load plugins %}
{% load i18n %}
{% load mptt %}

{% block content %}
<div class="row">
Expand Down Expand Up @@ -44,18 +45,17 @@ <h5 class="card-header">{% trans "Prefix" %}</h5>
{% endif %}
</td>
</tr>
{% if object.site.region %}
<tr>
<th scope="row">{% trans "Region" %}</th>
<td>
{% nested_tree object.site.region %}
</td>
</tr>
{% endif %}
<tr>
<th scope="row">{% trans "Site" %}</th>
<td>
{% if object.site %}
{% if object.site.region %}
{{ object.site.region|linkify }} /
{% endif %}
{{ object.site|linkify }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
<td>{{ object.site|linkify|placeholder }}</td>
</tr>
<tr>
<th scope="row">{% trans "VLAN" %}</th>
Expand Down
20 changes: 10 additions & 10 deletions netbox/templates/ipam/vlan.html
Expand Up @@ -3,6 +3,7 @@
{% load render_table from django_tables2 %}
{% load plugins %}
{% load i18n %}
{% load mptt %}

{% block content %}
<div class="row">
Expand All @@ -13,18 +14,17 @@ <h5 class="card-header">
</h5>
<div class="card-body">
<table class="table table-hover attr-table">
{% if object.site.region %}
<tr>
<th scope="row">{% trans "Region" %}</th>
<td>
{% nested_tree object.site.region %}
</td>
</tr>
{% endif %}
<tr>
<th scope="row">{% trans "Site" %}</th>
<td>
{% if object.site %}
{% if object.site.region %}
{{ object.site.region|linkify }} /
{% endif %}
{{ object.site|linkify }}
{% else %}
{{ ''|placeholder }}
{% endif %}
</td>
<td>{{ object.site|linkify|placeholder }}</td>
</tr>
<tr>
<th scope="row">{% trans "Group" %}</th>
Expand Down

0 comments on commit 28080e9

Please sign in to comment.