Skip to content

Release v2.7.2 #3980

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 37 commits into from
Jan 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d3f2784
Post-release version bump
jeremystretch Jan 17, 2020
83427d5
Closes #3949: Add tests for IPAM model methods
jeremystretch Jan 17, 2020
f15cde0
Fixes #3951: Fix exception in webhook worker due to missing constant
jeremystretch Jan 17, 2020
c6eb40d
#3951: Add tests for webhook queuing
jeremystretch Jan 17, 2020
439fa73
Fixes #3953: Fix validation error when creating child devices
jeremystretch Jan 17, 2020
302f87e
Fixes #3937: Suppress warning messages in tests for requests expected…
jeremystretch Jan 17, 2020
a4687be
Closes #3842: Add 802.11ax interface type
jeremystretch Jan 17, 2020
aa73a7a
Closes #3954: Add device_bays filter for devices and device types
jeremystretch Jan 17, 2020
606f3da
Fixes #3721: Allow Unicode characters in tag slugs
jeremystretch Jan 17, 2020
c6d18da
3923 validate key format
kobayashi Jan 19, 2020
939a7bb
Fixes #3135: Documented power modelling
hSaria Jan 19, 2020
a6fde31
Minor corrections
hSaria Jan 20, 2020
9e855ac
3960 legacy device status
kobayashi Jan 21, 2020
9d3215e
Fixes #3967: Resolve migration of "other" interface type
jeremystretch Jan 21, 2020
eb7fbe4
dcim: fix #3962 by moving away from device.name
hellerve Jan 21, 2020
1a56a55
Add systemd migration doc to pages list
jeremystretch Jan 21, 2020
134cf38
Merge branch 'develop' into 3960-legacy-device-status
jeremystretch Jan 21, 2020
856d14a
Merge pull request #3969 from kobayashi/3960-legacy-device-status
jeremystretch Jan 21, 2020
255d123
dcim: fix #3965 by adding an option to get_rack_units
hellerve Jan 21, 2020
cdd7ed2
Merge pull request #3970 from hellerve/veit/fix-3962
jeremystretch Jan 21, 2020
5f3f212
dcim: fix #3964 by moving away from properties to inline styles
hellerve Jan 21, 2020
63dbee1
Changelog for #3962
jeremystretch Jan 21, 2020
469a088
dcim: fix tooltips in svg rack display
hellerve Jan 21, 2020
e421c15
dcim: merge elevations as necessary
hellerve Jan 21, 2020
e184eb3
dcim: make pep happy
hellerve Jan 21, 2020
007de40
Merge pull request #3973 from hellerve/veit/fix-3963
jeremystretch Jan 21, 2020
74e1c08
Changelog for #3963
jeremystretch Jan 21, 2020
a7a166a
Merge branch 'develop' into veit/fix-3964
jeremystretch Jan 21, 2020
1d0546b
Merge pull request #3972 from hellerve/veit/fix-3964
jeremystretch Jan 21, 2020
737b05d
Changelog for #3964
jeremystretch Jan 21, 2020
48b4695
Fixes #3966: Fix filtering of device components by region/site
jeremystretch Jan 21, 2020
60c5418
Add tests for device component filtering by region/site
jeremystretch Jan 21, 2020
3357c05
Merge pull request #3959 from hSaria/3135-document-power
jeremystretch Jan 21, 2020
9dfd0e5
Merge pull request #3957 from kobayashi/3923-validate-key-format
jeremystretch Jan 21, 2020
838aaff
Merge pull request #3971 from hellerve/veit/fix-3965
jeremystretch Jan 21, 2020
aa4b89f
Changelog for #3965
jeremystretch Jan 21, 2020
2581a55
Release v2.7.2
jeremystretch Jan 21, 2020
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
58 changes: 58 additions & 0 deletions docs/core-functionality/power.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Power Panel

A power panel represents the distribution board where power circuits – and their circuit breakers – terminate on. If you have multiple power panels in your data center, you should model them as such in NetBox to assist you in determining the redundancy of your power allocation.

# Power Feed

A power feed identifies the power outlet/drop that goes to a rack and is terminated to a power panel. Power feeds have a supply type (AC/DC), voltage, amperage, and phase type (single/three).

Power feeds are optionally assigned to a rack. In addition, a power port – and only one – can connect to a power feed; in the context of a PDU, the power feed is analogous to the power outlet that a PDU's power port/inlet connects to.

!!! info
The power usage of a rack is calculated when a power feed (or multiple) is assigned to that rack and connected to a power port.

# Power Outlet

Power outlets represent the ports on a PDU that supply power to other devices. Power outlets are downstream-facing towards power ports. A power outlet can be associated with a power port on the same device and a feed leg (i.e. in a case of a three-phase supply). This indicates which power port supplies power to a power outlet.

# Power Port

A power port is the inlet of a device where it draws its power. Power ports are upstream-facing towards power outlets. Alternatively, a power port can connect to a power feed – as mentioned in the power feed section – to indicate the power source of a PDU's inlet.

!!! info
If the draw of a power port is left empty, it will be dynamically calculated based on the power outlets associated with that power port. This is usually the case on the power ports of devices that supply power, like a PDU.


# Example

Below is a simple diagram demonstrating how power is modelled in NetBox.

!!! note
The power feeds are connected to the same power panel for illustrative purposes; usually, you would have such feeds diversely connected to panels to avoid the single point of failure.

```
+---------------+
| Power panel 1 |
+---------------+
| |
| |
+--------------+ +--------------+
| Power feed 1 | | Power feed 2 |
+--------------+ +--------------+
| |
| |
| | <-- Power ports
+---------+ +---------+
| PDU 1 | | PDU 2 |
+---------+ +---------+
| \ / | <-- Power outlets
| \ / |
| \ / |
| X |
| / \ |
| / \ |
| / \ | <-- Power ports
+--------+ +--------+
| Server | | Router |
+--------+ +--------+
```
14 changes: 14 additions & 0 deletions docs/core-functionality/secrets.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@ Each user within NetBox can associate his or her account with an RSA public key.

User keys may be created by users individually, however they are of no use until they have been activated by a user who already possesses an active user key.

## Supported Key Format

Public key formats supported

- PKCS#1 RSAPublicKey* (PEM header: BEGIN RSA PUBLIC KEY)
- X.509 SubjectPublicKeyInfo** (PEM header: BEGIN PUBLIC KEY)
- **OpenSSH line format is not supported.**

Private key formats supported (unencrypted)

- PKCS#1 RSAPrivateKey** (PEM header: BEGIN RSA PRIVATE KEY)
- PKCS#8 PrivateKeyInfo* (PEM header: BEGIN PRIVATE KEY)


## Creating the First User Key

When NetBox is first installed, it contains no encryption keys. Before it can store secrets, a user (typically the superuser) must create a user key. This can be done by navigating to Profile > User Key.
Expand Down
24 changes: 24 additions & 0 deletions docs/release-notes/version-2.7.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
# v2.7.2 (2020-01-21)

## Enhancements

* [#3135](https://github.com/netbox-community/netbox/issues/3135) - Documented power modelling
* [#3842](https://github.com/netbox-community/netbox/issues/3842) - Add 802.11ax interface type
* [#3954](https://github.com/netbox-community/netbox/issues/3954) - Add `device_bays` filter for devices and device types

## Bug Fixes

* [#3721](https://github.com/netbox-community/netbox/issues/3721) - Allow Unicode characters in tag slugs
* [#3923](https://github.com/netbox-community/netbox/issues/3923) - Indicate validation failure when using SSH-style RSA keys
* [#3951](https://github.com/netbox-community/netbox/issues/3951) - Fix exception in webhook worker due to missing constant
* [#3953](https://github.com/netbox-community/netbox/issues/3953) - Fix validation error when creating child devices
* [#3960](https://github.com/netbox-community/netbox/issues/3960) - Fix legacy device status choice
* [#3962](https://github.com/netbox-community/netbox/issues/3962) - Fix display of unnamed devices in rack elevations
* [#3963](https://github.com/netbox-community/netbox/issues/3963) - Restore tooltip for devices in rack elevations
* [#3964](https://github.com/netbox-community/netbox/issues/3964) - Show borders around devices in rack elevations
* [#3965](https://github.com/netbox-community/netbox/issues/3965) - Indicate the presence of "background" devices in rack elevations
* [#3966](https://github.com/netbox-community/netbox/issues/3966) - Fix filtering of device components by region/site
* [#3967](https://github.com/netbox-community/netbox/issues/3967) - Resolve migration of "other" interface type

---

# v2.7.1 (2020-01-16)

## Bug Fixes
Expand Down
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pages:
- 4. LDAP (Optional): 'installation/4-ldap.md'
- Upgrading NetBox: 'installation/upgrading.md'
- Migrating to Python3: 'installation/migrating-to-python3.md'
- Migrating to systemd: 'installation/migrating-to-systemd.md'
- Configuration:
- Configuring NetBox: 'configuration/index.md'
- Required Settings: 'configuration/required-settings.md'
Expand All @@ -24,6 +25,7 @@ pages:
- Virtual Machines: 'core-functionality/virtual-machines.md'
- Services: 'core-functionality/services.md'
- Circuits: 'core-functionality/circuits.md'
- Power: 'core-functionality/power.md'
- Secrets: 'core-functionality/secrets.md'
- Tenancy: 'core-functionality/tenancy.md'
- Additional Features:
Expand Down
3 changes: 3 additions & 0 deletions netbox/dcim/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ class InterfaceTypeChoices(ChoiceSet):
TYPE_80211N = 'ieee802.11n'
TYPE_80211AC = 'ieee802.11ac'
TYPE_80211AD = 'ieee802.11ad'
TYPE_80211AX = 'ieee802.11ax'

# Cellular
TYPE_GSM = 'gsm'
Expand Down Expand Up @@ -650,6 +651,7 @@ class InterfaceTypeChoices(ChoiceSet):
(TYPE_80211N, 'IEEE 802.11n'),
(TYPE_80211AC, 'IEEE 802.11ac'),
(TYPE_80211AD, 'IEEE 802.11ad'),
(TYPE_80211AX, 'IEEE 802.11ax'),
)
),
(
Expand Down Expand Up @@ -800,6 +802,7 @@ class InterfaceTypeChoices(ChoiceSet):
TYPE_SUMMITSTACK128: 5310,
TYPE_SUMMITSTACK256: 5320,
TYPE_SUMMITSTACK512: 5330,
TYPE_OTHER: 32767,
}


Expand Down
63 changes: 24 additions & 39 deletions netbox/dcim/filters.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import django_filters
from django.contrib.auth.models import User
from django.db.models import Q

from extras.filters import CustomFieldFilterSet, LocalConfigContextFilterSet, CreatedUpdatedFilterSet
from tenancy.filters import TenancyFilterSet
Expand Down Expand Up @@ -356,6 +355,10 @@ class DeviceTypeFilterSet(CustomFieldFilterSet, CreatedUpdatedFilterSet):
method='_pass_through_ports',
label='Has pass-through ports',
)
device_bays = django_filters.BooleanFilter(
method='_device_bays',
label='Has device bays',
)
tag = TagFilter()

class Meta:
Expand Down Expand Up @@ -395,6 +398,9 @@ def _pass_through_ports(self, queryset, name, value):
rearport_templates__isnull=value
)

def _device_bays(self, queryset, name, value):
return queryset.exclude(device_bay_templates__isnull=value)


class DeviceTypeComponentFilterSet(NameSlugSearchFilterSet):
devicetype_id = django_filters.ModelMultipleChoiceFilter(
Expand Down Expand Up @@ -623,6 +629,10 @@ class DeviceFilterSet(LocalConfigContextFilterSet, TenancyFilterSet, CustomField
method='_pass_through_ports',
label='Has pass-through ports',
)
device_bays = django_filters.BooleanFilter(
method='_device_bays',
label='Has device bays',
)
tag = TagFilter()

class Meta:
Expand Down Expand Up @@ -676,21 +686,25 @@ def _pass_through_ports(self, queryset, name, value):
rearports__isnull=value
)

def _device_bays(self, queryset, name, value):
return queryset.exclude(device_bays__isnull=value)


class DeviceComponentFilterSet(django_filters.FilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
region_id = django_filters.ModelMultipleChoiceFilter(
field_name='device__site__region',
region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
field_name='device__site__region__in',
label='Region (ID)',
)
region = django_filters.ModelMultipleChoiceFilter(
field_name='device__site__region__in',
region = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(),
label='Region name (slug)',
field_name='device__site__region__in',
to_field_name='slug',
label='Region (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
field_name='device__site',
Expand All @@ -700,6 +714,7 @@ class DeviceComponentFilterSet(django_filters.FilterSet):
site = django_filters.ModelMultipleChoiceFilter(
field_name='device__site__slug',
queryset=Site.objects.all(),
to_field_name='slug',
label='Site name (slug)',
)
device_id = django_filters.ModelMultipleChoiceFilter(
Expand Down Expand Up @@ -787,35 +802,13 @@ class Meta:
fields = ['id', 'name', 'feed_leg', 'description', 'connection_status']


class InterfaceFilterSet(django_filters.FilterSet):
"""
Not using DeviceComponentFilterSet for Interfaces because we need to check for VirtualChassis membership.
"""
class InterfaceFilterSet(DeviceComponentFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
region_id = django_filters.ModelMultipleChoiceFilter(
field_name='device__site__region',
queryset=Region.objects.all(),
label='Region (ID)',
)
region = django_filters.ModelMultipleChoiceFilter(
field_name='device__site__region__in',
queryset=Region.objects.all(),
label='Region name (slug)',
)
site_id = django_filters.ModelMultipleChoiceFilter(
field_name='device__site',
queryset=Site.objects.all(),
label='Site (ID)',
)
site = django_filters.ModelMultipleChoiceFilter(
field_name='device__site__slug',
to_field_name='slug',
queryset=Site.objects.all(),
label='Site name (slug)',
)
# Override device and device_id filters from DeviceComponentFilterSet to match against any peer virtual chassis
# members
device = MultiValueCharFilter(
method='filter_device',
field_name='name',
Expand Down Expand Up @@ -859,14 +852,6 @@ class Meta:
model = Interface
fields = ['id', 'name', 'connection_status', 'type', 'enabled', 'mtu', 'mgmt_only', 'mode', 'description']

def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(description__icontains=value)
).distinct()

def filter_device(self, queryset, name, value):
try:
devices = Device.objects.filter(**{'{}__in'.format(name): value})
Expand Down
22 changes: 13 additions & 9 deletions netbox/dcim/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,21 +66,25 @@ class DeviceComponentFilterForm(BootstrapMixin, forms.Form):
required=False,
label='Search'
)
region = TreeNodeChoiceField(
region = FilterChoiceField(
queryset=Region.objects.all(),
to_field_name='slug',
required=False,
widget=APISelect(
api_url="/api/dcim/regions/"
widget=APISelectMultiple(
api_url='/api/dcim/regions/',
value_field='slug',
filter_for={
'site': 'region'
}
)
)
site = forms.ModelChoiceField(
site = FilterChoiceField(
queryset=Site.objects.all(),
to_field_name='slug',
required=False,
help_text='Name of parent site',
error_messages={
'invalid_choice': 'Site not found.',
}
widget=APISelectMultiple(
api_url="/api/dcim/sites/",
value_field="slug"
)
)


Expand Down
20 changes: 20 additions & 0 deletions netbox/dcim/migrations/0091_interface_type_other.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django.db import migrations


def interface_type_to_slug(apps, schema_editor):
Interface = apps.get_model('dcim', 'Interface')
Interface.objects.filter(type=32767).update(type='other')


class Migration(migrations.Migration):

dependencies = [
('dcim', '0090_cable_termination_models'),
]

operations = [
# Missed type "other" in the initial migration (see #3967)
migrations.RunPython(
code=interface_type_to_slug
),
]
Loading