Skip to content
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

Release v2.9.5 #5228

Merged
merged 29 commits into from
Oct 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d30874e
Post-release version bump
jeremystretch Sep 23, 2020
380f59a
Fixes #5175: Fix toggling of rack elevation order
jeremystretch Sep 24, 2020
856500b
Fixes #5174: Ensure consistent alignment of rack elevations
jeremystretch Sep 24, 2020
ff42c89
Closes #5177: Note permissions required for running reports and custo…
jeremystretch Sep 24, 2020
5c8694a
Fixes #5184: Fix missing Power Utilization
kobayashi Sep 27, 2020
015e25c
Merge pull request #5185 from kobayashi/5184-power-util
jeremystretch Sep 28, 2020
ee7f43a
Fixes #4523 - Add site vlan to certain scenarios where sites are the …
DanSheps Sep 29, 2020
068803d
Update 2.9 Release notes with 4523
DanSheps Sep 30, 2020
14ef7fa
Update version-2.9.md
DanSheps Sep 30, 2020
22a80c5
Update pre-commit script to support virtual environment within IDE
DanSheps Sep 30, 2020
23a9cb2
Fixes: #5199 - Change default logging for LDAP to INFO
DanSheps Oct 1, 2020
f2bc824
Fixes: #5199 - Change default logging for LDAP to INFO
DanSheps Oct 1, 2020
1a43ef8
Fixes: #5201 - Fix bulk "all" operations on VLAN Groups
DanSheps Oct 2, 2020
ae0a481
Fixes #5206: Apply user pagination preferences to all paginated objec…
jeremystretch Oct 2, 2020
6612e01
Limit main IPAddress view to a max of 10 duplicate addresses. Fixes #…
glennmatthews Oct 2, 2020
cd9c425
Merge pull request #5208 from glennmatthews/gfm-issue-5197
jeremystretch Oct 2, 2020
47ea753
Changelog for #5197
jeremystretch Oct 2, 2020
693b320
Update the netbox-discuss mailing list URL
jeremystretch Oct 7, 2020
9738257
Fixes #5217: Prevent erroneous removal of prefetched GenericForeignKe…
jeremystretch Oct 7, 2020
5089df3
Fix error in OBJECTCHANGE_OBJECT table column template
jeremystretch Oct 7, 2020
39e4ab1
Fixes #5218: Raise validation error if a power port's allocated_draw …
jeremystretch Oct 7, 2020
eadecf3
Fixes: #5221 - Fix bulk component creation over multiple VMs
DanSheps Oct 8, 2020
4896059
Fixes: #5220 - Fix API patch request against IP-Address endpoint with…
DanSheps Oct 8, 2020
a2c012d
Fixes #5224: Don't allow a rear port to have fewer positions than the…
jeremystretch Oct 8, 2020
3a21f7a
Fixes #5226: Custom choice fields should be blank initially if no def…
jeremystretch Oct 9, 2020
b5a65bc
Fixes #5211: Add missing has_primary_ip filter for virtual machines
jeremystretch Oct 9, 2020
f357156
Closes #5202: Extend the available context data when rendering custom…
jeremystretch Oct 9, 2020
24e5dd0
Add scope warning to plugins development doc
jeremystretch Oct 9, 2020
918ca4f
Release v2.9.5
jeremystretch Oct 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ about: Report a reproducible bug in the current release of NetBox
NetBox installation, or if you have a general question, DO NOT open an
issue. Instead, post to our mailing list:

https://groups.google.com/forum/#!forum/netbox-discuss
https://groups.google.com/g/netbox-discuss

Please describe the environment in which you are running NetBox. Be sure
that you are running an unmodified instance of the latest stable release
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ contact_links:
url: https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md
about: Please read through our contributing policy before opening an issue or pull request
- name: 💬 Discussion Group
url: https://groups.google.com/forum/#!forum/netbox-discuss
url: https://groups.google.com/g/netbox-discuss
about: Join our discussion group for assistance with installation issues and other problems
6 changes: 3 additions & 3 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ about: Propose a new NetBox feature or enhancement
If you have a general idea or question, please post to our mailing list
instead of opening an issue:

https://groups.google.com/forum/#!forum/netbox-discuss
https://groups.google.com/g/netbox-discuss

NOTE: Due to an excessive backlog of feature requests, we are not currently
accepting any proposals which significantly extend NetBox's feature scope.
Expand All @@ -21,8 +21,8 @@ about: Propose a new NetBox feature or enhancement
before submitting a bug report.
-->
### Environment
* Python version: <!-- Example: 3.6.9 -->
* NetBox version: <!-- Example: 2.7.3 -->
* Python version:
* NetBox version:

<!--
Describe in detail the new functionality you are proposing. Include any
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ except to report bugs or request features.

We have established a Google Groups Mailing List for issues and general
discussion. This is the best forum for obtaining assistance with NetBox
installation. You can find us [here](https://groups.google.com/forum/#!forum/netbox-discuss).
installation. You can find us [here](https://groups.google.com/g/netbox-discuss).

### Slack

Expand Down Expand Up @@ -164,7 +164,7 @@ overlooked.
* Official channels for communication include:

* GitHub issues/pull requests
* The [netbox-discuss](https://groups.google.com/forum/#!forum/netbox-discuss) mailing list
* The [netbox-discuss](https://groups.google.com/g/netbox-discuss) mailing list
* The **#netbox** channel on [NetworkToCode Slack](https://networktocode.slack.com/)

* Maintainers with no substantial recorded activity in a 60-day period will be
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ complete list of requirements, see `requirements.txt`. The code is available [on

The complete documentation for NetBox can be found at [Read the Docs](http://netbox.readthedocs.io/en/stable/).

Questions? Comments? Please subscribe to [the netbox-discuss mailing list](https://groups.google.com/forum/#!forum/netbox-discuss),
Questions? Comments? Please subscribe to [the netbox-discuss mailing list](https://groups.google.com/g/netbox-discuss),
or join us in the #netbox Slack channel on [NetworkToCode](https://networktocode.slack.com/)!

### Build Status
Expand Down Expand Up @@ -44,7 +44,7 @@ and run `upgrade.sh`.

Feature requests and bug reports must be submitted as GiHub issues. (Please be
sure to use the [appropriate template](https://github.com/netbox-community/netbox/issues/new/choose).)
For general discussion, please consider joining our [mailing list](https://groups.google.com/forum/#!forum/netbox-discuss).
For general discussion, please consider joining our [mailing list](https://groups.google.com/g/netbox-discuss).

If you are interested in contributing to the development of NetBox, please read
our [contributing guide](CONTRIBUTING.md) prior to beginning any work.
Expand Down
12 changes: 12 additions & 0 deletions docs/additional-features/custom-links.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ 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.

## Context Data

The following context data is available within the template when rendering a custom link's text or URL.

| Variable | Description |
|----------|-------------|
| `obj` | The NetBox object being displayed |
| `debug` | A boolean indicating whether debugging is enabled |
| `request` | The current WSGI request |
| `user` | The current user (if authenticated) |
| `perms` | The [permissions](https://docs.djangoproject.com/en/stable/topics/auth/default/#permissions) assigned to the user |

## Conditional Rendering

Only links which render with non-empty text are included on the page. You can employ conditional Jinja2 logic to control the conditions under which a link gets rendered.
Expand Down
24 changes: 24 additions & 0 deletions docs/additional-features/custom-scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,30 @@ An IPv4 or IPv6 network with a mask. Returns a `netaddr.IPNetwork` object. Two a
* `min_prefix_length` - Minimum length of the mask
* `max_prefix_length` - Maximum length of the mask

## Running Custom Scripts

!!! note
To run a custom script, a user must be assigned the `extras.run_script` permission. This is achieved by assigning the user (or group) a permission on the Script object and specifying the `run` action in the admin UI as shown below.

![Adding the run action to a permission](../../media/admin_ui_run_permission.png)

### Via the Web UI

Custom scripts can be run via the web UI by navigating to the script, completing any required form data, and clicking the "run script" button.

### Via the API

To run a script via the REST API, issue a POST request to the script's endpoint specifying the form data and commitment. For example, to run a script named `example.MyReport`, we would make a request such as the following:

```no-highlight
curl -X POST \
-H "Authorization: Token $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json; indent=4" \
http://netbox/api/extras/scripts/example.MyReport/ \
--data '{"data": {"foo": "somevalue", "bar": 123}, "commit": true}'
```

## Example

Below is an example script that creates new objects for a planned site. The user is prompted for three variables:
Expand Down
9 changes: 6 additions & 3 deletions docs/additional-features/reports.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,14 @@ Once you have created a report, it will appear in the reports list. Initially, r

## Running Reports

### Via the Web UI
!!! note
To run a report, a user must be assigned the `extras.run_report` permission. This is achieved by assigning the user (or group) a permission on the Report object and specifying the `run` action in the admin UI as shown below.

![Adding the run action to a permission](../../media/admin_ui_run_permission.png)

Reports can be run via the web UI by navigating to the report and clicking the "run report" button at top right. Note that a user must have permission to create ReportResults in order to run reports. (Permissions can be assigned through the admin UI.)
### Via the Web UI

Once a report has been run, its associated results will be included in the report view.
Reports can be run via the web UI by navigating to the report and clicking the "run report" button at top right. Once a report has been run, its associated results will be included in the report view.

### Via the API

Expand Down
2 changes: 1 addition & 1 deletion docs/development/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ NetBox is maintained as a [GitHub project](https://github.com/netbox-community/n
Communication among developers should always occur via public channels:

* [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.
* [The mailing list](https://groups.google.com/forum/#!forum/netbox-discuss) - The preferred forum for general discussion and support issues. Ideal for shaping a feature request prior to submitting an issue.
* [The mailing list](https://groups.google.com/g/netbox-discuss) - The preferred forum for general discussion and support issues. Ideal for shaping a feature request prior to submitting an issue.
* [#netbox on NetworkToCode](http://slack.networktocode.com/) - Good for quick chats. Avoid any discussion that might need to be referenced later on, as the chat history is not retained long.

## Governance
Expand Down
4 changes: 0 additions & 4 deletions docs/development/release-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,3 @@ On the `develop` branch, update `VERSION` in `settings.py` to point to the next
```
VERSION = 'v2.3.5-dev'
```

### Announce the Release

Announce the release on the [mailing list](https://groups.google.com/forum/#!forum/netbox-discuss). Include a link to the release and the (HTML-formatted) release notes.
Binary file added docs/media/admin_ui_run_permission.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/plugins/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ Plugins can do a lot, including:

However, keep in mind that each piece of functionality is entirely optional. For example, if your plugin merely adds a piece of middleware or an API endpoint for existing data, there's no need to define any new models.

!!! warning
While very powerful, the NetBox plugins API is necessarily limited in its scope. The plugins API is discussed here in its entirety: Any part of the NetBox code base not documented here is _not_ part of the supported plugins API, and should not be employed by a plugin. Internal elements of NetBox are subject to change at any time and without warning. Plugin authors are **strongly** encouraged to develop plugins using only the officially supported components discussed here and those provided by the underlying Django framework so as to avoid breaking changes in future releases.

## Initial Setup

## Plugin Structure
Expand Down
26 changes: 26 additions & 0 deletions docs/release-notes/version-2.9.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
# NetBox v2.9

## v2.9.5 (2020-10-09)

### Enhancements

* [#5202](https://github.com/netbox-community/netbox/issues/5202) - Extend the available context data when rendering custom links

### Bug Fixes

* [#4523](https://github.com/netbox-community/netbox/issues/4523) - Populate site vlan list when bulk editing interfaces under certain circumstances
* [#5174](https://github.com/netbox-community/netbox/issues/5174) - Ensure consistent alignment of rack elevations
* [#5175](https://github.com/netbox-community/netbox/issues/5175) - Fix toggling of rack elevation order
* [#5184](https://github.com/netbox-community/netbox/issues/5184) - Fix missing Power Utilization
* [#5197](https://github.com/netbox-community/netbox/issues/5197) - Limit duplicate IPs shown on IP address view
* [#5199](https://github.com/netbox-community/netbox/issues/5199) - Change default LDAP logging to INFO
* [#5201](https://github.com/netbox-community/netbox/issues/5201) - Fix missing querystring when bulk editing/deleting VLAN Group VLANs when selecting "select all x items matching query"
* [#5206](https://github.com/netbox-community/netbox/issues/5206) - Apply user pagination preferences to all paginated object lists
* [#5211](https://github.com/netbox-community/netbox/issues/5211) - Add missing `has_primary_ip` filter for virtual machines
* [#5217](https://github.com/netbox-community/netbox/issues/5217) - Prevent erroneous removal of prefetched GenericForeignKey data from tables
* [#5218](https://github.com/netbox-community/netbox/issues/5218) - Raise validation error if a power port's `allocated_draw` exceeds its `maximum_draw`
* [#5220](https://github.com/netbox-community/netbox/issues/5220) - Fix API patch request against IP Address endpoint with null assigned_object_type
* [#5221](https://github.com/netbox-community/netbox/issues/5221) - Fix bulk component creation for virtual machines
* [#5224](https://github.com/netbox-community/netbox/issues/5224) - Don't allow a rear port to have fewer positions than the number of mapped front ports
* [#5226](https://github.com/netbox-community/netbox/issues/5226) - Custom choice fields should be blank initially if no default choice has been designated

---

## v2.9.4 (2020-09-23)

**NOTE:** This release removes support for the `DEFAULT_TIMEOUT` parameter under `REDIS` database configuration. Set `RQ_DEFAULT_TIMEOUT` as a global configuration parameter instead.
Expand Down
7 changes: 3 additions & 4 deletions netbox/circuits/views.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from django.conf import settings
from django.contrib import messages
from django.db import transaction
from django.db.models import Count, Prefetch
from django.db.models import Count
from django.shortcuts import get_object_or_404, redirect, render
from django_tables2 import RequestConfig

from extras.models import Graph
from utilities.forms import ConfirmationForm
from utilities.paginator import EnhancedPaginator
from utilities.paginator import EnhancedPaginator, get_paginate_count
from utilities.views import (
BulkDeleteView, BulkEditView, BulkImportView, ObjectView, ObjectDeleteView, ObjectEditView, ObjectListView,
)
Expand Down Expand Up @@ -45,7 +44,7 @@ def get(self, request, slug):

paginate = {
'paginator_class': EnhancedPaginator,
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
'per_page': get_paginate_count(request)
}
RequestConfig(request, paginate).configure(circuits_table)

Expand Down
12 changes: 3 additions & 9 deletions netbox/dcim/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -662,16 +662,10 @@ def search(self, queryset, name, value):
).distinct()

def _has_primary_ip(self, queryset, name, value):
params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False)
if value:
return queryset.filter(
Q(primary_ip4__isnull=False) |
Q(primary_ip6__isnull=False)
)
else:
return queryset.exclude(
Q(primary_ip4__isnull=False) |
Q(primary_ip6__isnull=False)
)
return queryset.filter(params)
return queryset.exclude(params)

def _virtual_chassis_member(self, queryset, name, value):
return queryset.exclude(virtual_chassis__isnull=value)
Expand Down
18 changes: 18 additions & 0 deletions netbox/dcim/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2844,6 +2844,24 @@ def __init__(self, *args, **kwargs):
self.fields['untagged_vlan'].widget.add_query_param('site_id', device.site.pk)
self.fields['tagged_vlans'].widget.add_query_param('site_id', device.site.pk)
else:
# See 4523
if 'pk' in self.initial:
site = None
interfaces = Interface.objects.filter(pk__in=self.initial['pk']).prefetch_related('device__site')

# Check interface sites. First interface should set site, further interfaces will either continue the
# loop or reset back to no site and break the loop.
for interface in interfaces:
if site is None:
site = interface.device.site
elif interface.device.site is not site:
site = None
break

if site is not None:
self.fields['untagged_vlan'].widget.add_query_param('site_id', site.pk)
self.fields['tagged_vlans'].widget.add_query_param('site_id', site.pk)

self.fields['lag'].choices = ()
self.fields['lag'].widget.attrs['disabled'] = True

Expand Down
33 changes: 25 additions & 8 deletions netbox/dcim/models/device_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,14 @@ def to_csv(self):
self.description,
)

def clean(self):

if self.maximum_draw is not None and self.allocated_draw is not None:
if self.allocated_draw > self.maximum_draw:
raise ValidationError({
'allocated_draw': f"Allocated draw cannot exceed the maximum draw ({self.maximum_draw}W)."
})

@property
def connected_endpoint(self):
"""
Expand Down Expand Up @@ -843,17 +851,16 @@ def clean(self):

# Validate rear port assignment
if self.rear_port.device != self.device:
raise ValidationError(
"Rear port ({}) must belong to the same device".format(self.rear_port)
)
raise ValidationError({
"rear_port": f"Rear port ({self.rear_port}) must belong to the same device"
})

# Validate rear port position assignment
if self.rear_port_position > self.rear_port.positions:
raise ValidationError(
"Invalid rear port position ({}); rear port {} has only {} positions".format(
self.rear_port_position, self.rear_port.name, self.rear_port.positions
)
)
raise ValidationError({
"rear_port_position": f"Invalid rear port position ({self.rear_port_position}): Rear port "
f"{self.rear_port.name} has only {self.rear_port.positions} positions"
})


@extras_features('webhooks')
Expand Down Expand Up @@ -883,6 +890,16 @@ class Meta:
def get_absolute_url(self):
return reverse('dcim:rearport', kwargs={'pk': self.pk})

def clean(self):

# Check that positions count is greater than or equal to the number of associated FrontPorts
frontport_count = self.frontports.count()
if self.positions < frontport_count:
raise ValidationError({
"positions": f"The number of positions cannot be less than the number of mapped front ports "
f"({frontport_count})"
})

def to_csv(self):
return (
self.device.identifier,
Expand Down
5 changes: 2 additions & 3 deletions netbox/dcim/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from collections import OrderedDict

from django.conf import settings
from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
from django.core.paginator import EmptyPage, PageNotAnInteger
Expand All @@ -20,7 +19,7 @@
from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable
from secrets.models import Secret
from utilities.forms import ConfirmationForm
from utilities.paginator import EnhancedPaginator
from utilities.paginator import EnhancedPaginator, get_paginate_count
from utilities.permissions import get_permission_for_model
from utilities.utils import csv_format, get_subquery
from utilities.views import (
Expand Down Expand Up @@ -320,7 +319,7 @@ def get(self, request):
racks = racks.reverse()

# Pagination
per_page = request.GET.get('per_page', settings.PAGINATE_COUNT)
per_page = get_paginate_count(request)
page_number = request.GET.get('page', 1)
paginator = EnhancedPaginator(racks, per_page)
try:
Expand Down
9 changes: 4 additions & 5 deletions netbox/extras/models/customfields.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,15 +200,14 @@ def to_form_field(self, set_initial=True, enforce_required=True, for_csv_import=
# Select
elif self.type == CustomFieldTypeChoices.TYPE_SELECT:
choices = [(cfc.pk, cfc.value) for cfc in self.choices.all()]
default_choice = self.choices.filter(value=self.default).first()

if not required:
if not required or default_choice is None:
choices = add_blank_choice(choices)

# Set the initial value to the PK of the default choice, if any
if set_initial:
default_choice = self.choices.filter(value=self.default).first()
if default_choice:
initial = default_choice.pk
if set_initial and default_choice:
initial = default_choice.pk

field_class = CSVChoiceField if for_csv_import else forms.ChoiceField
field = field_class(
Expand Down
4 changes: 1 addition & 3 deletions netbox/extras/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@
"""

OBJECTCHANGE_OBJECT = """
{% if record.action != 3 and record.changed_object.get_absolute_url %}
{% if record.changed_object.get_absolute_url %}
<a href="{{ record.changed_object.get_absolute_url }}">{{ record.object_repr }}</a>
{% elif record.action != 3 and record.related_object.get_absolute_url %}
<a href="{{ record.related_object.get_absolute_url }}">{{ record.object_repr }}</a>
{% else %}
{{ record.object_repr }}
{% endif %}
Expand Down