Skip to content

Release v2.11.7 #6616

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a665b79
#6455 - initial
Jun 4, 2021
7444110
PRVB
jeremystretch Jun 4, 2021
a224e5d
Closes #6493: show ObjectChange diff for non-atomic changes
Jun 5, 2021
cb43926
Fixes #6553: ProviderNetwork search should match on name
jeremystretch Jun 8, 2021
6ec296f
Fixes #6563: Fix filtering by location for cable connection forms
jeremystretch Jun 8, 2021
b3cde51
Fixes #6562: Disable ordering of secrets by assigned object
jeremystretch Jun 8, 2021
6523334
Merge pull request #6545 from crafty-ua/Add_ipv4_32_and_ipv6_128_pref…
jeremystretch Jun 8, 2021
6195fc0
Merge pull request #6552 from drmsoffall/6493-diff-legacy-changes
jeremystretch Jun 8, 2021
79c0644
Changelog for #6455, 6493
jeremystretch Jun 8, 2021
809d9e4
Fixes #6584: Fix ordering of nested inventory items
jeremystretch Jun 10, 2021
7e48196
Optimize MPTTColumn rendering
jeremystretch Jun 14, 2021
54ccc70
Adopt IRM terminology
jeremystretch Jun 14, 2021
f56a470
Fixes #6602: Fix deletion of devices with cables attached
jeremystretch Jun 14, 2021
9f2c491
Update NetDev Slack links
jeremystretch Jun 14, 2021
c8a8bfd
custom fields documentation missing word "more"
bluikko Jun 15, 2021
52edeb4
Merge pull request #6604 from bluikko/patch-2
jeremystretch Jun 15, 2021
e68be6f
Add Equinix Metal as a sponsor
jeremystretch Jun 15, 2021
857c70e
Closes #6564: Add N connector type for pass-through ports
jeremystretch Jun 16, 2021
6a6b023
Closes #6589: Standardize breadcrumb navigation for power panels and …
jeremystretch Jun 16, 2021
685e0ce
Closes #6588: Add support for webp files as front/rear device type im…
jeremystretch Jun 16, 2021
2bf20fa
Release NetBox v2.11.7
jeremystretch Jun 16, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ body:
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.)
placeholder: v2.11.6
placeholder: v2.11.7
validations:
required: true
- type: dropdown
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ body:
attributes:
label: NetBox version
description: What version of NetBox are you currently running?
placeholder: v2.11.6
placeholder: v2.11.7
validations:
required: true
- type: dropdown
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ discussions.

### Slack

For real-time chat, you can join the **#netbox** Slack channel on [NetDev Community](https://slack.netbox.dev/).
For real-time chat, you can join the **#netbox** Slack channel on [NetDev Community](https://netdev.chat/).
Unfortunately, the Slack channel does not provide long-term retention of chat
history, so try to avoid it for any discussions would benefit from being
preserved for future reference.
Expand Down
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
<img src="https://raw.githubusercontent.com/netbox-community/netbox/develop/docs/netbox_logo.svg" width="400" alt="NetBox logo" />
</div>

NetBox is an IP address management (IPAM) and data center infrastructure
management (DCIM) tool. Initially conceived by the network engineering team at
![Master branch build status](https://github.com/netbox-community/netbox/workflows/CI/badge.svg?branch=master)

NetBox is an infrastructure resource modeling (IRM) tool designed to empower
network automation. Initially conceived by the network engineering team at
[DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically
to address the needs of network and infrastructure engineers. It is intended to
function as a domain-specific source of truth for network operations.
Expand All @@ -14,26 +16,23 @@ complete list of requirements, see `requirements.txt`. The code is available [on

The complete documentation for NetBox can be found at [Read the Docs](https://netbox.readthedocs.io/en/stable/). A public demo instance is available at https://demo.netbox.dev.

| | status |
|-------------|------------|
| **master** | ![Build status](https://github.com/netbox-community/netbox/workflows/CI/badge.svg?branch=master) |
| **develop** | ![Build status](https://github.com/netbox-community/netbox/workflows/CI/badge.svg?branch=develop) |

<div align="center">
<h4>Thank you to our sponsors!</h4>

[![DigitalOcean](https://raw.githubusercontent.com/wiki/netbox-community/netbox/images/sponsors/digitalocean.png)](https://try.digitalocean.com/developer-cloud)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
[![NS1](https://raw.githubusercontent.com/wiki/netbox-community/netbox/images/sponsors/ns1.png)](https://ns1.com/)
[![Equinix Metal](https://raw.githubusercontent.com/wiki/netbox-community/netbox/images/sponsors/equinix.png)](https://metal.equinix.com/)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
[![NS1](https://raw.githubusercontent.com/wiki/netbox-community/netbox/images/sponsors/ns1.png)](https://ns1.com/)
<br />
[![Stellar Technologies](https://raw.githubusercontent.com/wiki/netbox-community/netbox/images/sponsors/stellar.png)](https://stellar.tech/)

</div>

### Discussion

* [GitHub Discussions](https://github.com/netbox-community/netbox/discussions) - Discussion forum hosted by GitHub; ideal for Q&A and other structured discussions
* [Slack](https://slack.netbox.dev/) - Real-time chat hosted by the NetDev Community; best for unstructured discussion or just hanging out
* [Slack](https://netdev.chat/) - Real-time chat hosted by the NetDev Community; best for unstructured discussion or just hanging out
* [Google Group](https://groups.google.com/g/netbox-discuss) - Legacy mailing list; slowly being replaced by GitHub discussions

### Installation
Expand Down
2 changes: 1 addition & 1 deletion docs/additional-features/custom-fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Marking a field as required will force the user to provide a value for the field

The filter logic controls how values are matched when filtering objects by the custom field. Loose filtering (the default) matches on a partial value, whereas exact matching requires a complete match of the given string to a field's value. For example, exact filtering with the string "red" will only match the exact value "red", whereas loose filtering will match on the values "red", "red-orange", or "bored". Setting the filter logic to "disabled" disables filtering by the field entirely.

A custom field must be assigned to one or object types, or models, in NetBox. Once created, custom fields will automatically appear as part of these models in the web UI and REST API. Note that not all models support custom fields.
A custom field must be assigned to one or more object types, or models, in NetBox. Once created, custom fields will automatically appear as part of these models in the web UI and REST API. Note that not all models support custom fields.

### Custom Field Validation

Expand Down
2 changes: 1 addition & 1 deletion docs/development/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ There are several official forums for communication among the developers and com

* [GitHub issues](https://github.com/netbox-community/netbox/issues) - All feature requests, bug reports, and other substantial changes to the code base **must** be documented in an issue.
* [GitHub Discussions](https://github.com/netbox-community/netbox/discussions) - The preferred forum for general discussion and support issues. Ideal for shaping a feature request prior to submitting an issue.
* [#netbox on NetDev Community Slack](https://slack.netbox.dev/) - Good for quick chats. Avoid any discussion that might need to be referenced later on, as the chat history is not retained long.
* [#netbox on NetDev Community Slack](https://netdev.chat/) - Good for quick chats. Avoid any discussion that might need to be referenced later on, as the chat history is not retained long.
* [Google Group](https://groups.google.com/g/netbox-discuss) - Legacy mailing list; slowly being phased out in favor of GitHub discussions.

## Governance
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# What is NetBox?

NetBox is an open source web application designed to help manage and document computer networks. Initially conceived by the network engineering team at [DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically to address the needs of network and infrastructure engineers. It encompasses the following aspects of network management:
NetBox is an infrastructure resource modeling (IRM) application designed to empower network automation. Initially conceived by the network engineering team at [DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically to address the needs of network and infrastructure engineers. NetBox is made available as open source under the Apache 2 license. It encompasses the following aspects of network management:

* **IP address management (IPAM)** - IP networks and addresses, VRFs, and VLANs
* **Equipment racks** - Organized by group and site
Expand Down
20 changes: 20 additions & 0 deletions docs/release-notes/version-2.11.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# NetBox v2.11

## v2.11.7 (2021-06-16)

### Enhancements

* [#6455](https://github.com/netbox-community/netbox/issues/6455) - Permit /32 IPv4 and /128 IPv6 prefixes
* [#6493](https://github.com/netbox-community/netbox/issues/6493) - Show change log diff for non-atomic (pre-2.11) changes
* [#6564](https://github.com/netbox-community/netbox/issues/6564) - Add N connector type for pass-through ports
* [#6588](https://github.com/netbox-community/netbox/issues/6588) - Add support for webp files as front/rear device type images
* [#6589](https://github.com/netbox-community/netbox/issues/6589) - Standardize breadcrumb navigation for power panels and feeds

### Bug Fixes

* [#6553](https://github.com/netbox-community/netbox/issues/6553) - ProviderNetwork search should match on name
* [#6562](https://github.com/netbox-community/netbox/issues/6562) - Disable ordering of secrets by assigned object
* [#6563](https://github.com/netbox-community/netbox/issues/6563) - Fix filtering by location for cable connection forms
* [#6584](https://github.com/netbox-community/netbox/issues/6584) - Fix ordering of nested inventory items
* [#6602](https://github.com/netbox-community/netbox/issues/6602) - Fix deletion of devices with cables attached

---

## v2.11.6 (2021-06-04)

### Bug Fixes
Expand Down
1 change: 1 addition & 0 deletions netbox/circuits/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(description__icontains=value) |
Q(comments__icontains=value)
).distinct()
Expand Down
2 changes: 2 additions & 0 deletions netbox/dcim/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,7 @@ class PortTypeChoices(ChoiceSet):
TYPE_110_PUNCH = '110-punch'
TYPE_BNC = 'bnc'
TYPE_F = 'f'
TYPE_N = 'n'
TYPE_MRJ21 = 'mrj21'
TYPE_ST = 'st'
TYPE_SC = 'sc'
Expand Down Expand Up @@ -954,6 +955,7 @@ class PortTypeChoices(ChoiceSet):
(TYPE_110_PUNCH, '110 Punch'),
(TYPE_BNC, 'BNC'),
(TYPE_F, 'F Connector'),
(TYPE_N, 'N Connector'),
(TYPE_MRJ21, 'MRJ21'),
),
),
Expand Down
3 changes: 3 additions & 0 deletions netbox/dcim/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

from .choices import InterfaceTypeChoices

# Exclude SVG images (unsupported by PIL)
DEVICETYPE_IMAGE_FORMATS = 'image/bmp,image/gif,image/jpeg,image/png,image/tiff,image/webp'


#
# Racks
Expand Down
6 changes: 3 additions & 3 deletions netbox/dcim/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1172,12 +1172,11 @@ class Meta:
)
widgets = {
'subdevice_role': StaticSelect2(),
# Exclude SVG images (unsupported by PIL)
'front_image': forms.ClearableFileInput(attrs={
'accept': 'image/bmp,image/gif,image/jpeg,image/png,image/tiff'
'accept': DEVICETYPE_IMAGE_FORMATS
}),
'rear_image': forms.ClearableFileInput(attrs={
'accept': 'image/bmp,image/gif,image/jpeg,image/png,image/tiff'
'accept': DEVICETYPE_IMAGE_FORMATS
})
}

Expand Down Expand Up @@ -3948,6 +3947,7 @@ class ConnectCableToDeviceForm(BootstrapMixin, CustomFieldModelForm):
required=False,
query_params={
'site_id': '$termination_b_site',
'location_id': '$termination_b_location',
'rack_id': '$termination_b_rack',
}
)
Expand Down
10 changes: 4 additions & 6 deletions netbox/dcim/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,12 @@ def nullify_connected_endpoints(instance, **kwargs):
# Disassociate the Cable from its termination points
if instance.termination_a is not None:
logger.debug(f"Nullifying termination A for cable {instance}")
instance.termination_a.cable = None
instance.termination_a._cable_peer = None
instance.termination_a.save()
model = instance.termination_a._meta.model
model.objects.filter(pk=instance.termination_a.pk).update(_cable_peer_type=None, _cable_peer_id=None)
if instance.termination_b is not None:
logger.debug(f"Nullifying termination B for cable {instance}")
instance.termination_b.cable = None
instance.termination_b._cable_peer = None
instance.termination_b.save()
model = instance.termination_b._meta.model
model.objects.filter(pk=instance.termination_b.pk).update(_cable_peer_type=None, _cable_peer_id=None)

# Delete and retrace any dependent cable paths
for cablepath in CablePath.objects.filter(path__contains=instance):
Expand Down
4 changes: 2 additions & 2 deletions netbox/dcim/tables/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ class InventoryItemTable(DeviceComponentTable):
)
cable = None # Override DeviceComponentTable

class Meta(DeviceComponentTable.Meta):
class Meta(BaseTable.Meta):
model = InventoryItem
fields = (
'pk', 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description',
Expand All @@ -715,7 +715,7 @@ class DeviceInventoryItemTable(InventoryItemTable):
buttons=('edit', 'delete')
)

class Meta(DeviceComponentTable.Meta):
class Meta(BaseTable.Meta):
model = InventoryItem
fields = (
'pk', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description', 'discovered',
Expand Down
18 changes: 13 additions & 5 deletions netbox/extras/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,15 +202,22 @@ def get_extra_context(self, request, instance):
next_change = objectchanges.filter(time__gt=instance.time).order_by('time').first()
prev_change = objectchanges.filter(time__lt=instance.time).order_by('-time').first()

if instance.prechange_data and instance.postchange_data:
if not instance.prechange_data and instance.action in ['update', 'delete'] and prev_change:
non_atomic_change = True
prechange_data = prev_change.postchange_data
else:
non_atomic_change = False
prechange_data = instance.prechange_data

if prechange_data and instance.postchange_data:
diff_added = shallow_compare_dict(
instance.prechange_data or dict(),
prechange_data or dict(),
instance.postchange_data or dict(),
exclude=['last_updated'],
)
diff_removed = {
x: instance.prechange_data.get(x) for x in diff_added
} if instance.prechange_data else {}
x: prechange_data.get(x) for x in diff_added
} if prechange_data else {}
else:
diff_added = None
diff_removed = None
Expand All @@ -221,7 +228,8 @@ def get_extra_context(self, request, instance):
'next_change': next_change,
'prev_change': prev_change,
'related_changes_table': related_changes_table,
'related_changes_count': related_changes.count()
'related_changes_count': related_changes.count(),
'non_atomic_change': non_atomic_change
}


Expand Down
14 changes: 2 additions & 12 deletions netbox/ipam/models/ip.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,16 +340,6 @@ def clean(self):
'prefix': "Cannot create prefix with /0 mask."
})

# Disallow host masks
if self.prefix.version == 4 and self.prefix.prefixlen == 32:
raise ValidationError({
'prefix': "Cannot create host addresses (/32) as prefixes. Create an IPv4 address instead."
})
elif self.prefix.version == 6 and self.prefix.prefixlen == 128:
raise ValidationError({
'prefix': "Cannot create host addresses (/128) as prefixes. Create an IPv6 address instead."
})

# Enforce unique IP space (if applicable)
if (self.vrf is None and settings.ENFORCE_GLOBAL_UNIQUE) or (self.vrf and self.vrf.enforce_unique):
duplicate_prefixes = self.get_duplicates()
Expand Down Expand Up @@ -471,8 +461,8 @@ def get_available_ips(self):
child_ips = netaddr.IPSet([ip.address.ip for ip in self.get_child_ips()])
available_ips = prefix - child_ips

# IPv6, pool, or IPv4 /31 sets are fully usable
if self.family == 6 or self.is_pool or self.prefix.prefixlen == 31:
# IPv6, pool, or IPv4 /31-/32 sets are fully usable
if self.family == 6 or self.is_pool or (self.family == 4 and self.prefix.prefixlen >= 31):
return available_ips

# For "normal" IPv4 prefixes, omit first and last addresses
Expand Down
2 changes: 1 addition & 1 deletion netbox/ipam/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ def get_extra_context(self, request, instance):
# Parent prefixes table
parent_prefixes = Prefix.objects.restrict(request.user, 'view').filter(
vrf=instance.vrf,
prefix__net_contains=str(instance.address.ip)
prefix__net_contains_or_equals=str(instance.address.ip)
).prefetch_related(
'site', 'role'
)
Expand Down
2 changes: 1 addition & 1 deletion netbox/netbox/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# Environment setup
#

VERSION = '2.11.6'
VERSION = '2.11.7'

# Hostname
HOSTNAME = platform.node()
Expand Down
1 change: 1 addition & 0 deletions netbox/secrets/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class SecretTable(BaseTable):
)
assigned_object = tables.Column(
linkify=True,
orderable=False,
verbose_name='Assigned object'
)
role = tables.Column(
Expand Down
6 changes: 3 additions & 3 deletions netbox/templates/dcim/powerfeed.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

{% block breadcrumbs %}
<li><a href="{% url 'dcim:powerfeed_list' %}">Power Feeds</a></li>
<li><a href="{{ object.power_panel.site.get_absolute_url }}">{{ object.power_panel.site }}</a></li>
<li><a href="{{ object.power_panel.get_absolute_url }}">{{ object.power_panel }}</a></li>
<li><a href="{% url 'dcim:powerfeed_list' %}?site_id={{ object.power_panel.site.pk }}">{{ object.power_panel.site }}</a></li>
<li><a href="{% url 'dcim:powerfeed_list' %}?power_panel_id={{ object.power_panel.pk }}">{{ object.power_panel }}</a></li>
{% if object.rack %}
<li><a href="{{ object.rack.get_absolute_url }}">{{ object.rack }}</a></li>
<li><a href="{% url 'dcim:powerfeed_list' %}?rack_id={{ object.rack.pk }}">{{ object.rack }}</a></li>
{% endif %}
<li>{{ object }}</li>
{% endblock %}
Expand Down
2 changes: 1 addition & 1 deletion netbox/templates/dcim/powerpanel.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

{% block breadcrumbs %}
<li><a href="{% url 'dcim:powerpanel_list' %}">Power Panels</a></li>
<li><a href="{{ object.site.get_absolute_url }}">{{ object.site }}</a></li>
<li><a href="{% url 'dcim:powerpanel_list' %}?site_id={{ object.site.pk }}">{{ object.site }}</a></li>
{% if object.location %}
<li><a href="{{ object.location.get_absolute_url }}">{{ object.location }}</a></li>
{% endif %}
Expand Down
2 changes: 2 additions & 0 deletions netbox/templates/extras/objectchange.html
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@
<span{% if k in diff_removed %} style="background-color: #ffdce0"{% endif %}>{{ k }}: {{ v|render_json }}</span>
{% endspaceless %}
{% endfor %}</pre>
{% elif non_atomic_change %}
Warning: Comparing non-atomic change to previous change record (<a href="{% url 'extras:objectchange' pk=prev_change.pk %}">{{ prev_change.pk }}</a>)
{% else %}
<span class="text-muted">None</span>
{% endif %}
Expand Down
7 changes: 5 additions & 2 deletions netbox/utilities/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,11 @@ class MPTTColumn(tables.TemplateColumn):
"""
Display a nested hierarchy for MPTT-enabled models.
"""
template_code = """{% for i in record.get_ancestors %}<i class="mdi mdi-circle-small"></i>{% endfor %}""" \
"""<a href="{{ record.get_absolute_url }}">{{ record.name }}</a>"""
template_code = """
{% load helpers %}
{% for i in record.level|as_range %}<i class="mdi mdi-circle-small"></i>{% endfor %}
<a href="{{ record.get_absolute_url }}">{{ record.name }}</a>
"""

def __init__(self, *args, **kwargs):
super().__init__(
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Jinja2==3.0.1
Markdown==3.3.4
netaddr==0.8.0
Pillow==8.2.0
psycopg2-binary==2.8.6
psycopg2-binary==2.9
pycryptodome==3.10.1
PyYAML==5.4.1
svgwrite==1.4.1
Expand Down