From f28474d86ee2f29cbf6e761b25cf1d464dc329c0 Mon Sep 17 00:00:00 2001 From: Brian Candler Date: Tue, 2 Feb 2021 08:16:35 +0000 Subject: [PATCH 01/10] Fix sample report in documentation Raised in #5729 --- docs/additional-features/reports.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/additional-features/reports.md b/docs/additional-features/reports.md index 9d60f797e..1266c22ec 100644 --- a/docs/additional-features/reports.md +++ b/docs/additional-features/reports.md @@ -66,7 +66,7 @@ class DeviceConnectionsReport(Report): for power_port in PowerPort.objects.filter(device=device): if power_port.connected_endpoint is not None: connected_ports += 1 - if not power_port.connection_status: + if not power_port.path.is_active: self.log_warning( device, "Power connection for {} marked as planned".format(power_port.name) From b4ba5cbb7a3e365f8c1d145b0b2ce05850323ca1 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 2 Feb 2021 11:49:38 -0500 Subject: [PATCH 02/10] Fixes #5716: Fix filtering rack reservations by custom field --- docs/release-notes/version-2.10.md | 8 ++++++++ netbox/dcim/filters.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index b6bc33229..49f80d897 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -1,5 +1,13 @@ # NetBox v2.10 +## v2.10.5 (FUTURE) + +### Bug Fixes + +* [#5716](https://github.com/netbox-community/netbox/issues/5716) - Fix filtering rack reservations by custom field + +--- + ## v2.10.4 (2021-01-26) ### Enhancements diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index 03deca2a4..41363c261 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -264,7 +264,7 @@ class RackFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet, ) -class RackReservationFilterSet(BaseFilterSet, TenancyFilterSet): +class RackReservationFilterSet(BaseFilterSet, TenancyFilterSet, CustomFieldModelFilterSet): q = django_filters.CharFilter( method='search', label='Search', From e3e928f1c4dbd45a66b35328dfb2252d3b512417 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 4 Feb 2021 13:01:55 -0500 Subject: [PATCH 03/10] Fixes #5718: Fix bulk editing of services when no port(s) are defined --- docs/release-notes/version-2.10.md | 1 + netbox/netbox/views/generic.py | 2 +- netbox/utilities/forms/widgets.py | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 49f80d897..fccd86abd 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -5,6 +5,7 @@ ### Bug Fixes * [#5716](https://github.com/netbox-community/netbox/issues/5716) - Fix filtering rack reservations by custom field +* [#5718](https://github.com/netbox-community/netbox/issues/5718) - Fix bulk editing of services when no port(s) are defined --- diff --git a/netbox/netbox/views/generic.py b/netbox/netbox/views/generic.py index bd21d469c..216b50759 100644 --- a/netbox/netbox/views/generic.py +++ b/netbox/netbox/views/generic.py @@ -792,7 +792,7 @@ class BulkEditView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View): if form.cleaned_data[name]: getattr(obj, name).set(form.cleaned_data[name]) # Normal fields - elif form.cleaned_data[name] not in (None, ''): + elif form.cleaned_data[name] not in (None, '', []): setattr(obj, name, form.cleaned_data[name]) # Update custom fields diff --git a/netbox/utilities/forms/widgets.py b/netbox/utilities/forms/widgets.py index cd6fb0fbb..1c456c74c 100644 --- a/netbox/utilities/forms/widgets.py +++ b/netbox/utilities/forms/widgets.py @@ -114,7 +114,10 @@ class ContentTypeSelect(StaticSelect2): class NumericArrayField(SimpleArrayField): def to_python(self, value): - value = ','.join([str(n) for n in parse_numeric_range(value)]) + if not value: + return [] + if isinstance(value, str): + value = ','.join([str(n) for n in parse_numeric_range(value)]) return super().to_python(value) From 1430c0a6e6444b06581dae6e6deb4a0434dd95ee Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 4 Feb 2021 13:19:42 -0500 Subject: [PATCH 04/10] Fixes #5738: Fix redirect to device components view after disconnecting a cable --- docs/release-notes/version-2.10.md | 1 + netbox/dcim/tables/template_code.py | 35 +++++++++++++++++++ .../dcim/inc/cable_toggle_buttons.html | 5 --- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index fccd86abd..94b80ef1c 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -6,6 +6,7 @@ * [#5716](https://github.com/netbox-community/netbox/issues/5716) - Fix filtering rack reservations by custom field * [#5718](https://github.com/netbox-community/netbox/issues/5718) - Fix bulk editing of services when no port(s) are defined +* [#5738](https://github.com/netbox-community/netbox/issues/5738) - Fix redirect to device components view after disconnecting a cable --- diff --git a/netbox/dcim/tables/template_code.py b/netbox/dcim/tables/template_code.py index ee1dc091b..7a52b85b0 100644 --- a/netbox/dcim/tables/template_code.py +++ b/netbox/dcim/tables/template_code.py @@ -95,6 +95,11 @@ CONSOLEPORT_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} + {% if perms.dcim.delete_cable %} + + + + {% endif %} {% elif perms.dcim.add_cable %} @@ -115,6 +120,11 @@ CONSOLESERVERPORT_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} + {% if perms.dcim.delete_cable %} + + + + {% endif %} {% elif perms.dcim.add_cable %} @@ -135,6 +145,11 @@ POWERPORT_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} + {% if perms.dcim.delete_cable %} + + + + {% endif %} {% elif perms.dcim.add_cable %} @@ -154,6 +169,11 @@ POWEROUTLET_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} + {% if perms.dcim.delete_cable %} + + + + {% endif %} {% elif perms.dcim.add_cable %} @@ -172,6 +192,11 @@ INTERFACE_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} + {% if perms.dcim.delete_cable %} + + + + {% endif %} {% elif record.is_connectable and perms.dcim.add_cable %} @@ -193,6 +218,11 @@ FRONTPORT_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} + {% if perms.dcim.delete_cable %} + + + + {% endif %} {% elif perms.dcim.add_cable %} @@ -216,6 +246,11 @@ REARPORT_BUTTONS = """ {% if record.cable %} {% include 'dcim/inc/cable_toggle_buttons.html' with cable=record.cable %} + {% if perms.dcim.delete_cable %} + + + + {% endif %} {% elif perms.dcim.add_cable %} diff --git a/netbox/templates/dcim/inc/cable_toggle_buttons.html b/netbox/templates/dcim/inc/cable_toggle_buttons.html index 98e4efd94..e3eb318ac 100644 --- a/netbox/templates/dcim/inc/cable_toggle_buttons.html +++ b/netbox/templates/dcim/inc/cable_toggle_buttons.html @@ -9,8 +9,3 @@ {% endif %} {% endif %} -{% if perms.dcim.delete_cable %} - - - -{% endif %} From 5fbe766a0a3e887298ce4c993b282525c0df3a93 Mon Sep 17 00:00:00 2001 From: Robin Schneider Date: Thu, 4 Feb 2021 21:36:06 +0100 Subject: [PATCH 05/10] NetBox should always be referred to as NetBox Fix all instances of "Netbox" except the one that is used as an example how not to write it. Ref: docs/development/style-guide.md --- docs/additional-features/prometheus-metrics.md | 2 +- docs/installation/6-ldap.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/additional-features/prometheus-metrics.md b/docs/additional-features/prometheus-metrics.md index 048eb68b3..56365e336 100644 --- a/docs/additional-features/prometheus-metrics.md +++ b/docs/additional-features/prometheus-metrics.md @@ -26,4 +26,4 @@ For the exhaustive list of exposed metrics, visit the `/metrics` endpoint on you When deploying NetBox in a multiprocess manner (e.g. running multiple Gunicorn workers) the Prometheus client library requires the use of a shared directory to collect metrics from all worker processes. To configure this, first create or designate a local directory to which the worker processes have read and write access, and then configure your WSGI service (e.g. Gunicorn) to define this path as the `prometheus_multiproc_dir` environment variable. !!! warning - If having accurate long-term metrics in a multiprocess environment is crucial to your deployment, it's recommended you use the `uwsgi` library instead of `gunicorn`. The issue lies in the way `gunicorn` tracks worker processes (vs `uwsgi`) which helps manage the metrics files created by the above configurations. If you're using Netbox with gunicorn in a containerized enviroment following the one-process-per-container methodology, then you will likely not need to change to `uwsgi`. More details can be found in [issue #3779](https://github.com/netbox-community/netbox/issues/3779#issuecomment-590547562). \ No newline at end of file + If having accurate long-term metrics in a multiprocess environment is crucial to your deployment, it's recommended you use the `uwsgi` library instead of `gunicorn`. The issue lies in the way `gunicorn` tracks worker processes (vs `uwsgi`) which helps manage the metrics files created by the above configurations. If you're using NetBox with gunicorn in a containerized enviroment following the one-process-per-container methodology, then you will likely not need to change to `uwsgi`. More details can be found in [issue #3779](https://github.com/netbox-community/netbox/issues/3779#issuecomment-590547562). diff --git a/docs/installation/6-ldap.md b/docs/installation/6-ldap.md index 25f9c8f2b..1c5424595 100644 --- a/docs/installation/6-ldap.md +++ b/docs/installation/6-ldap.md @@ -140,7 +140,7 @@ AUTH_LDAP_CACHE_TIMEOUT = 3600 ## Troubleshooting LDAP -`systemctl restart netbox` restarts the Netbox service, and initiates any changes made to `ldap_config.py`. If there are syntax errors present, the NetBox process will not spawn an instance, and errors should be logged to `/var/log/messages`. +`systemctl restart netbox` restarts the NetBox service, and initiates any changes made to `ldap_config.py`. If there are syntax errors present, the NetBox process will not spawn an instance, and errors should be logged to `/var/log/messages`. For troubleshooting LDAP user/group queries, add or merge the following [logging](/configuration/optional-settings.md#logging) configuration to `configuration.py`: From 713f02ca3fe7d05a005ef8f0975c62f6bb812052 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 7 Feb 2021 10:31:56 +0000 Subject: [PATCH 06/10] Fixes #5735: enforcement of duplicate IP address detection with roles --- netbox/ipam/models.py | 11 +++++------ netbox/ipam/tests/test_models.py | 12 ++++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index 0ae9db7b2..e8b3dff0a 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -734,13 +734,12 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel): }) # Enforce unique IP space (if applicable) - if self.role not in IPADDRESS_ROLES_NONUNIQUE and (( - self.vrf is None and settings.ENFORCE_GLOBAL_UNIQUE - ) or ( - self.vrf and self.vrf.enforce_unique - )): + if (self.vrf is None and settings.ENFORCE_GLOBAL_UNIQUE) or (self.vrf and self.vrf.enforce_unique): duplicate_ips = self.get_duplicates() - if duplicate_ips: + if duplicate_ips and ( + self.role not in IPADDRESS_ROLES_NONUNIQUE or + any(dip.role not in IPADDRESS_ROLES_NONUNIQUE for dip in duplicate_ips) + ): raise ValidationError({ 'address': "Duplicate IP address found in {}: {}".format( "VRF {}".format(self.vrf) if self.vrf else "global table", diff --git a/netbox/ipam/tests/test_models.py b/netbox/ipam/tests/test_models.py index 6091aa70e..a47862165 100644 --- a/netbox/ipam/tests/test_models.py +++ b/netbox/ipam/tests/test_models.py @@ -259,6 +259,18 @@ class TestIPAddress(TestCase): duplicate_ip = IPAddress(vrf=vrf, address=netaddr.IPNetwork('192.0.2.1/24')) self.assertRaises(ValidationError, duplicate_ip.clean) + @override_settings(ENFORCE_GLOBAL_UNIQUE=True) + def test_duplicate_nonunique_nonrole_role(self): + IPAddress.objects.create(address=netaddr.IPNetwork('192.0.2.1/24')) + duplicate_ip = IPAddress(address=netaddr.IPNetwork('192.0.2.1/24'), role=IPAddressRoleChoices.ROLE_VIP) + self.assertRaises(ValidationError, duplicate_ip.clean) + + @override_settings(ENFORCE_GLOBAL_UNIQUE=True) + def test_duplicate_nonunique_role_nonrole(self): + IPAddress.objects.create(address=netaddr.IPNetwork('192.0.2.1/24'), role=IPAddressRoleChoices.ROLE_VIP) + duplicate_ip = IPAddress(address=netaddr.IPNetwork('192.0.2.1/24')) + self.assertRaises(ValidationError, duplicate_ip.clean) + @override_settings(ENFORCE_GLOBAL_UNIQUE=True) def test_duplicate_nonunique_role(self): IPAddress.objects.create(address=netaddr.IPNetwork('192.0.2.1/24'), role=IPAddressRoleChoices.ROLE_VIP) From 6c676d21c3d3eed26b330e71eb9ed3bf81c1f9f6 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 8 Feb 2021 15:09:20 -0500 Subject: [PATCH 07/10] Changelog for #5735 --- docs/release-notes/version-2.10.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index 94b80ef1c..caf37b1ce 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -6,6 +6,7 @@ * [#5716](https://github.com/netbox-community/netbox/issues/5716) - Fix filtering rack reservations by custom field * [#5718](https://github.com/netbox-community/netbox/issues/5718) - Fix bulk editing of services when no port(s) are defined +* [#5735](https://github.com/netbox-community/netbox/issues/5735) - Ensure consistent treatment of duplicate IP addresses * [#5738](https://github.com/netbox-community/netbox/issues/5738) - Fix redirect to device components view after disconnecting a cable --- From 3d90e3aee9e14875c6caa25f22a62baafa7e065c Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 8 Feb 2021 16:44:04 -0500 Subject: [PATCH 08/10] Fixes #5626: Fix REST API representation for circuit terminations connected to non-interface endpoints --- docs/release-notes/version-2.10.md | 1 + netbox/circuits/api/serializers.py | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/release-notes/version-2.10.md b/docs/release-notes/version-2.10.md index caf37b1ce..320217a74 100644 --- a/docs/release-notes/version-2.10.md +++ b/docs/release-notes/version-2.10.md @@ -4,6 +4,7 @@ ### Bug Fixes +* [#5626](https://github.com/netbox-community/netbox/issues/5626) - Fix REST API representation for circuit terminations connected to non-interface endpoints * [#5716](https://github.com/netbox-community/netbox/issues/5716) - Fix filtering rack reservations by custom field * [#5718](https://github.com/netbox-community/netbox/issues/5718) - Fix bulk editing of services when no port(s) are defined * [#5735](https://github.com/netbox-community/netbox/issues/5735) - Ensure consistent treatment of duplicate IP addresses diff --git a/netbox/circuits/api/serializers.py b/netbox/circuits/api/serializers.py index 88890bf95..12ec9ba7f 100644 --- a/netbox/circuits/api/serializers.py +++ b/netbox/circuits/api/serializers.py @@ -40,14 +40,16 @@ class CircuitTypeSerializer(ValidatedModelSerializer): fields = ['id', 'url', 'name', 'slug', 'description', 'circuit_count'] -class CircuitCircuitTerminationSerializer(WritableNestedSerializer): +class CircuitCircuitTerminationSerializer(WritableNestedSerializer, ConnectedEndpointSerializer): url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittermination-detail') site = NestedSiteSerializer() - connected_endpoint = NestedInterfaceSerializer() class Meta: model = CircuitTermination - fields = ['id', 'url', 'site', 'connected_endpoint', 'port_speed', 'upstream_speed', 'xconnect_id'] + fields = [ + 'id', 'url', 'site', 'port_speed', 'upstream_speed', 'xconnect_id', 'connected_endpoint', + 'connected_endpoint_type', 'connected_endpoint_reachable', + ] class CircuitSerializer(TaggedObjectSerializer, CustomFieldModelSerializer): From 8640f500d1439f3d2deddb4edbe3069ee9594b62 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 9 Feb 2021 13:32:29 -0500 Subject: [PATCH 09/10] Closes #5776: Upgrade pip when running upgrade.sh --- upgrade.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/upgrade.sh b/upgrade.sh index 2e35a02f9..648f825a0 100755 --- a/upgrade.sh +++ b/upgrade.sh @@ -29,19 +29,25 @@ eval $COMMAND || { # Activate the virtual environment source "${VIRTUALENV}/bin/activate" +# Upgrade pip +COMMAND="pip install --upgrade pip" +echo "Updating pip ($COMMAND)..." +eval $COMMAND || exit 1 +pip -V + # Install necessary system packages -COMMAND="pip3 install wheel" +COMMAND="pip install wheel" echo "Installing Python system packages ($COMMAND)..." eval $COMMAND || exit 1 # Install required Python packages -COMMAND="pip3 install -r requirements.txt" +COMMAND="pip install -r requirements.txt" echo "Installing core dependencies ($COMMAND)..." eval $COMMAND || exit 1 # Install optional packages (if any) if [ -s "local_requirements.txt" ]; then - COMMAND="pip3 install -r local_requirements.txt" + COMMAND="pip install -r local_requirements.txt" echo "Installing local dependencies ($COMMAND)..." eval $COMMAND || exit 1 elif [ -f "local_requirements.txt" ]; then From efbda6d5afa9929148a346bbaf5b31011bb08a63 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 9 Feb 2021 15:15:49 -0500 Subject: [PATCH 10/10] Apply stale rules to PRs --- .github/stale.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/stale.yml b/.github/stale.yml index fdfb1d590..92da07e6a 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -1,8 +1,5 @@ # Configuration for Stale (https://github.com/apps/stale) -# Pull requests are exempt from being marked as stale -only: issues - # Number of days of inactivity before an issue becomes stale daysUntilStale: 45