Skip to content

Commit

Permalink
Merge pull request #6947 from netbox-community/develop
Browse files Browse the repository at this point in the history
Release v2.11.11
  • Loading branch information
jeremystretch committed Aug 12, 2021
2 parents 15ed575 + 11a9dc5 commit 2e895c7
Show file tree
Hide file tree
Showing 28 changed files with 142 additions and 60 deletions.
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.10
placeholder: v2.11.11
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.10
placeholder: v2.11.11
validations:
required: true
- type: dropdown
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
- uses: actions/stale@v4
with:
close-issue-message: >
This issue has been automatically closed due to lack of activity. In an
Expand Down
3 changes: 3 additions & 0 deletions docs/additional-features/custom-links.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ When viewing a device named Router4, this link would render as:

Custom links appear as buttons at the top right corner of the page. Numeric weighting can be used to influence the ordering of links.

!!! warning
Custom links rely on user-created code to generate arbitrary HTML output, which may be dangerous. Only grant permission to create or modify custom links to trusted users.

## Context Data

The following context data is available within the template when rendering a custom link's text or URL.
Expand Down
5 changes: 4 additions & 1 deletion docs/additional-features/export-templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ NetBox allows users to define custom templates that can be used when exporting o

Each export template is associated with a certain type of object. For instance, if you create an export template for VLANs, your custom template will appear under the "Export" button on the VLANs list. Each export template must have a name, and may optionally designate a specific export [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) and/or file extension.

Export templates must be written in [Jinja2](https://jinja.palletsprojects.com/).

!!! note
The name `table` is reserved for internal use.

Export templates must be written in [Jinja2](https://jinja.palletsprojects.com/).
!!! warning
Export templates are rendered using user-submitted code, which may pose security risks under certain conditions. Only grant permission to create or modify export templates to trusted users.

The list of objects returned from the database when rendering an export template is stored in the `queryset` variable, which you'll typically want to iterate through using a `for` loop. Object properties can be access by name. For example:

Expand Down
3 changes: 3 additions & 0 deletions docs/additional-features/webhooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

A webhook is a mechanism for conveying to some external system a change that took place in NetBox. For example, you may want to notify a monitoring system whenever the status of a device is updated in NetBox. This can be done by creating a webhook for the device model in NetBox and identifying the webhook receiver. When NetBox detects a change to a device, an HTTP request containing the details of the change and who made it be sent to the specified receiver. Webhooks are configured in the admin UI under Extras > Webhooks.

!!! warning
Webhooks support the inclusion of user-submitted code to generate custom headers and payloads, which may pose security risks under certain conditions. Only grant permission to create or modify webhooks to trusted users.

## Configuration

* **Name** - A unique name for the webhook. The name is not included with outbound messages.
Expand Down
4 changes: 2 additions & 2 deletions docs/installation/1-postgresql.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ This section entails the installation and configuration of a local PostgreSQL da

```no-highlight
sudo apt update
sudo apt install -y postgresql libpq-dev
sudo apt install -y postgresql
```

=== "CentOS"

```no-highlight
sudo yum install -y postgresql-server libpq-devel
sudo yum install -y postgresql-server
sudo postgresql-setup --initdb
```

Expand Down
2 changes: 1 addition & 1 deletion docs/installation/3-netbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Begin by installing all system packages required by NetBox and its dependencies.
=== "CentOS"

```no-highlight
sudo yum install -y gcc python36 python36-devel python3-pip libxml2-devel libxslt-devel libffi-devel openssl-devel redhat-rpm-config
sudo yum install -y gcc python36 python36-devel python3-pip libxml2-devel libxslt-devel libffi-devel libpq-devel openssl-devel redhat-rpm-config
```

Before continuing with either platform, update pip (Python's package management tool) to its latest release:
Expand Down
Binary file modified docs/media/installation/netbox_application_stack.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions docs/release-notes/version-2.11.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# NetBox v2.11

## v2.11.11 (2021-08-12)

### Enhancements

* [#6883](https://github.com/netbox-community/netbox/issues/6883) - Add C21 & C22 power types
* [#6921](https://github.com/netbox-community/netbox/issues/6921) - Employ a sandbox when rendering Jinja2 code for increased security

### Bug Fixes

* [#6740](https://github.com/netbox-community/netbox/issues/6740) - Add import button to VM interfaces list
* [#6892](https://github.com/netbox-community/netbox/issues/6892) - Fix validation of unit ranges when creating a rack reservation
* [#6896](https://github.com/netbox-community/netbox/issues/6896) - Fix validation of IP address assigned as device/VM primary via NAT relation
* [#6902](https://github.com/netbox-community/netbox/issues/6902) - Populate device field when cloning device components
* [#6908](https://github.com/netbox-community/netbox/issues/6908) - Allow assignment of scope to VLAN groups upon import
* [#6909](https://github.com/netbox-community/netbox/issues/6909) - Remove extraneous `site` column from VLAN group import form
* [#6910](https://github.com/netbox-community/netbox/issues/6910) - Fix exception on invalid CSV import column name
* [#6918](https://github.com/netbox-community/netbox/issues/6918) - Fix return URL persistence when adding multiple objects sequentially
* [#6935](https://github.com/netbox-community/netbox/issues/6935) - Remove extraneous columns from inventory item and device bay tables
* [#6936](https://github.com/netbox-community/netbox/issues/6936) - Add missing `parent` column to inventory item import form

---

## v2.11.10 (2021-07-28)

### Enhancements
Expand Down
18 changes: 17 additions & 1 deletion docs/rest-api/filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ Numeric based fields (ASN, VLAN ID, etc) support these lookup expressions:
| `gt` | Greater than |
| `gte` | Greater than or equal to |

Here is an example of a numeric field lookup expression that will return all VLANs with a VLAN ID greater than 900:

```no-highlight
GET /api/ipam/vlans/?vid__gt=900
```

### String Fields

String based (char) fields (Name, Address, etc) support these lookup expressions:
Expand All @@ -86,7 +92,17 @@ String based (char) fields (Name, Address, etc) support these lookup expressions
| `nie` | Inverse exact match (case-insensitive) |
| `empty` | Is empty (boolean) |

Here is an example of a lookup expression on a string field that will return all devices with `switch` in the name:

```no-highlight
GET /api/dcim/devices/?name__ic=switch
```

### Foreign Keys & Other Fields

Certain other fields, namely foreign key relationships support just the negation
expression: `n`.
expression: `n`. Here is an example of a lookup expression on a foreign key, it would return all the VLANs that don't have a VLAN Group ID of 3203:

```no-highlight
GET /api/ipam/vlans/?group_id__n=3203
```
4 changes: 4 additions & 0 deletions netbox/dcim/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ class PowerPortTypeChoices(ChoiceSet):
TYPE_IEC_C14 = 'iec-60320-c14'
TYPE_IEC_C16 = 'iec-60320-c16'
TYPE_IEC_C20 = 'iec-60320-c20'
TYPE_IEC_C22 = 'iec-60320-c22'
# IEC 60309
TYPE_IEC_PNE4H = 'iec-60309-p-n-e-4h'
TYPE_IEC_PNE6H = 'iec-60309-p-n-e-6h'
Expand Down Expand Up @@ -351,6 +352,7 @@ class PowerPortTypeChoices(ChoiceSet):
(TYPE_IEC_C14, 'C14'),
(TYPE_IEC_C16, 'C16'),
(TYPE_IEC_C20, 'C20'),
(TYPE_IEC_C22, 'C22'),
)),
('IEC 60309', (
(TYPE_IEC_PNE4H, 'P+N+E 4H'),
Expand Down Expand Up @@ -467,6 +469,7 @@ class PowerOutletTypeChoices(ChoiceSet):
TYPE_IEC_C13 = 'iec-60320-c13'
TYPE_IEC_C15 = 'iec-60320-c15'
TYPE_IEC_C19 = 'iec-60320-c19'
TYPE_IEC_C21 = 'iec-60320-c21'
# IEC 60309
TYPE_IEC_PNE4H = 'iec-60309-p-n-e-4h'
TYPE_IEC_PNE6H = 'iec-60309-p-n-e-6h'
Expand Down Expand Up @@ -558,6 +561,7 @@ class PowerOutletTypeChoices(ChoiceSet):
(TYPE_IEC_C13, 'C13'),
(TYPE_IEC_C15, 'C15'),
(TYPE_IEC_C19, 'C19'),
(TYPE_IEC_C21, 'C21'),
)),
('IEC 60309', (
(TYPE_IEC_PNE4H, 'P+N+E 4H'),
Expand Down
21 changes: 21 additions & 0 deletions netbox/dcim/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3852,11 +3852,32 @@ class InventoryItemCSVForm(CustomFieldModelCSVForm):
to_field_name='name',
required=False
)
parent = CSVModelChoiceField(
queryset=Device.objects.all(),
to_field_name='name',
required=False,
help_text='Parent inventory item'
)

class Meta:
model = InventoryItem
fields = InventoryItem.csv_headers

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

# Limit parent choices to inventory items belonging to this device
device = None
if self.is_bound and 'device' in self.data:
try:
device = self.fields['device'].to_python(self.data['device'])
except forms.ValidationError:
pass
if device:
self.fields['parent'].queryset = InventoryItem.objects.filter(device=device)
else:
self.fields['parent'].queryset = InventoryItem.objects.none()


class InventoryItemBulkCreateForm(
form_from_model(InventoryItem, ['manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered']),
Expand Down
9 changes: 9 additions & 0 deletions netbox/dcim/models/device_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ class ConsolePort(ComponentModel, CableTermination, PathEndpoint):
)

csv_headers = ['device', 'name', 'label', 'type', 'speed', 'mark_connected', 'description']
clone_fields = ['device', 'type', 'speed']

class Meta:
ordering = ('device', '_name')
Expand Down Expand Up @@ -273,6 +274,7 @@ class ConsoleServerPort(ComponentModel, CableTermination, PathEndpoint):
)

csv_headers = ['device', 'name', 'label', 'type', 'speed', 'mark_connected', 'description']
clone_fields = ['device', 'type', 'speed']

class Meta:
ordering = ('device', '_name')
Expand Down Expand Up @@ -324,6 +326,7 @@ class PowerPort(ComponentModel, CableTermination, PathEndpoint):
csv_headers = [
'device', 'name', 'label', 'type', 'mark_connected', 'maximum_draw', 'allocated_draw', 'description',
]
clone_fields = ['device', 'maximum_draw', 'allocated_draw']

class Meta:
ordering = ('device', '_name')
Expand Down Expand Up @@ -434,6 +437,7 @@ class PowerOutlet(ComponentModel, CableTermination, PathEndpoint):
)

csv_headers = ['device', 'name', 'label', 'type', 'mark_connected', 'power_port', 'feed_leg', 'description']
clone_fields = ['device', 'type', 'power_port', 'feed_leg']

class Meta:
ordering = ('device', '_name')
Expand Down Expand Up @@ -577,6 +581,7 @@ class Interface(ComponentModel, BaseInterface, CableTermination, PathEndpoint):
'device', 'name', 'label', 'parent', 'lag', 'type', 'enabled', 'mark_connected', 'mac_address', 'mtu',
'mgmt_only', 'description', 'mode',
]
clone_fields = ['device', 'parent', 'lag', 'type', 'mgmt_only']

class Meta:
ordering = ('device', CollateAsChar('_name'))
Expand Down Expand Up @@ -711,6 +716,7 @@ class FrontPort(ComponentModel, CableTermination):
csv_headers = [
'device', 'name', 'label', 'type', 'mark_connected', 'rear_port', 'rear_port_position', 'description',
]
clone_fields = ['device', 'type']

class Meta:
ordering = ('device', '_name')
Expand Down Expand Up @@ -767,6 +773,7 @@ class RearPort(ComponentModel, CableTermination):
MaxValueValidator(REARPORT_POSITIONS_MAX)
]
)
clone_fields = ['device', 'type', 'positions']

csv_headers = ['device', 'name', 'label', 'type', 'mark_connected', 'positions', 'description']

Expand Down Expand Up @@ -818,6 +825,7 @@ class DeviceBay(ComponentModel):
)

csv_headers = ['device', 'name', 'label', 'installed_device', 'description']
clone_fields = ['device']

class Meta:
ordering = ('device', '_name')
Expand Down Expand Up @@ -913,6 +921,7 @@ class InventoryItem(MPTTModel, ComponentModel):
csv_headers = [
'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered', 'description',
]
clone_fields = ['device', 'parent', 'manufacturer', 'part_id']

class Meta:
ordering = ('device__id', 'parent__id', '_name')
Expand Down
4 changes: 0 additions & 4 deletions netbox/dcim/tables/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,6 @@ class DeviceComponentTable(BaseTable):
linkify=True,
order_by=('_name',)
)
cable = tables.Column(
linkify=True
)
mark_connected = BooleanColumn()

class Meta(BaseTable.Meta):
order_by = ('device', 'name')
Expand Down
8 changes: 4 additions & 4 deletions netbox/dcim/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1736,10 +1736,10 @@ def setUpTestData(cls):
}

cls.csv_data = (
"device,name",
"Device 1,Inventory Item 4",
"Device 1,Inventory Item 5",
"Device 1,Inventory Item 6",
"device,name,parent",
"Device 1,Inventory Item 4,Inventory Item 1",
"Device 1,Inventory Item 5,Inventory Item 2",
"Device 1,Inventory Item 6,Inventory Item 3",
)


Expand Down
18 changes: 10 additions & 8 deletions netbox/ipam/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
from tenancy.models import Tenant
from utilities.forms import (
add_blank_choice, BootstrapMixin, BulkEditNullBooleanSelect, ContentTypeChoiceField, CSVChoiceField,
CSVModelChoiceField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField, ExpandableIPAddressField,
NumericArrayField, ReturnURLForm, SlugField, StaticSelect2, StaticSelect2Multiple, TagFilterField,
CSVContentTypeField, CSVModelChoiceField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
ExpandableIPAddressField, NumericArrayField, SlugField, StaticSelect2, StaticSelect2Multiple, TagFilterField,
BOOLEAN_WITH_BLANK_CHOICES,
)
from virtualization.models import Cluster, ClusterGroup, VirtualMachine, VMInterface
Expand Down Expand Up @@ -682,7 +682,7 @@ class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm)
# IP addresses
#

class IPAddressForm(BootstrapMixin, TenancyForm, ReturnURLForm, CustomFieldModelForm):
class IPAddressForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
device = DynamicModelChoiceField(
queryset=Device.objects.all(),
required=False,
Expand Down Expand Up @@ -1238,17 +1238,19 @@ def clean(self):


class VLANGroupCSVForm(CustomFieldModelCSVForm):
site = CSVModelChoiceField(
queryset=Site.objects.all(),
slug = SlugField()
scope_type = CSVContentTypeField(
queryset=ContentType.objects.filter(model__in=VLANGROUP_SCOPE_TYPES),
required=False,
to_field_name='name',
help_text='Assigned site'
label='Scope type (app & model)'
)
slug = SlugField()

class Meta:
model = VLANGroup
fields = VLANGroup.csv_headers
labels = {
'scope_id': 'Scope ID',
}


class VLANGroupBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
Expand Down
21 changes: 9 additions & 12 deletions netbox/ipam/models/ip.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,18 +649,15 @@ def clean(self):

# Check for primary IP assignment that doesn't match the assigned device/VM
if self.pk:
device = Device.objects.filter(Q(primary_ip4=self) | Q(primary_ip6=self)).first()
if device:
if getattr(self.assigned_object, 'device', None) != device:
raise ValidationError({
'interface': f"IP address is primary for device {device} but not assigned to it!"
})
vm = VirtualMachine.objects.filter(Q(primary_ip4=self) | Q(primary_ip6=self)).first()
if vm:
if getattr(self.assigned_object, 'virtual_machine', None) != vm:
raise ValidationError({
'vminterface': f"IP address is primary for virtual machine {vm} but not assigned to it!"
})
for cls, attr in ((Device, 'device'), (VirtualMachine, 'virtual_machine')):
parent = cls.objects.filter(Q(primary_ip4=self) | Q(primary_ip6=self)).first()
if parent and getattr(self.assigned_object, attr) != parent:
# Check for a NAT relationship
if not self.nat_inside or getattr(self.nat_inside.assigned_object, attr) != parent:
raise ValidationError({
'interface': f"IP address is primary for {cls._meta.model_name} {parent} but "
f"not assigned to it!"
})

# Validate IP status selection
if self.status == IPAddressStatusChoices.STATUS_SLAAC and self.family != 6:
Expand Down
8 changes: 4 additions & 4 deletions netbox/ipam/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,10 +333,10 @@ def setUpTestData(cls):
}

cls.csv_data = (
"name,slug,description",
"VLAN Group 4,vlan-group-4,Fourth VLAN group",
"VLAN Group 5,vlan-group-5,Fifth VLAN group",
"VLAN Group 6,vlan-group-6,Sixth VLAN group",
f"name,slug,scope_type,scope_id,description",
f"VLAN Group 4,vlan-group-4,,,Fourth VLAN group",
f"VLAN Group 5,vlan-group-5,dcim.site,{sites[0].pk},Fifth VLAN group",
f"VLAN Group 6,vlan-group-6,dcim.site,{sites[1].pk},Sixth VLAN group",
)

cls.bulk_edit_data = {
Expand Down
Loading

0 comments on commit 2e895c7

Please sign in to comment.