Skip to content

Commit

Permalink
Merge pull request #9039 from netbox-community/develop
Browse files Browse the repository at this point in the history
Release v3.1.11
  • Loading branch information
jeremystretch authored Apr 5, 2022
2 parents d50148f + 631de20 commit 10f8a94
Show file tree
Hide file tree
Showing 31 changed files with 218 additions and 115 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 @@ -14,7 +14,7 @@ body:
attributes:
label: NetBox version
description: What version of NetBox are you currently running?
placeholder: v3.1.10
placeholder: v3.1.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: v3.1.10
placeholder: v3.1.11
validations:
required: true
- type: dropdown
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
<img src="https://raw.githubusercontent.com/netbox-community/netbox/develop/docs/netbox_logo.svg" width="400" alt="NetBox logo" />
</div>

:loudspeaker: The **[2022 NetBox community survey](https://forms.gle/KR8YbR8GiJ9EYXM28)** is now open! We collect this feedback and demographic data from NetBox users around the world to help shape the project's long-term development goals. Please take a few minutes to share your responses!

![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
Expand Down
2 changes: 0 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
![NetBox](netbox_logo.svg "NetBox logo"){style="height: 100px; margin-bottom: 3em"}

:loudspeaker: The **[2022 NetBox community survey](https://forms.gle/KR8YbR8GiJ9EYXM28)** is now open! We collect this feedback and demographic data from NetBox users around the world to help shape the project's long-term development goals. Please take a few minutes to share your responses!

# What is NetBox?

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:
Expand Down
7 changes: 6 additions & 1 deletion docs/installation/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Prior to upgrading your NetBox instance, be sure to carefully review all [releas

## Update Dependencies to Required Versions

NetBox v3.0 and later requires the following:
NetBox v3.0 and later require the following:

| Dependency | Minimum Version |
|------------|-----------------|
Expand Down Expand Up @@ -67,6 +67,11 @@ sudo git checkout master
sudo git pull origin master
```

!!! info "Checking out an older release"
If you need to upgrade to an older version rather than the current stable release, you can check out any valid [git tag](https://github.com/netbox-community/netbox/tags), each of which represents a release. For example, to checkout the code for NetBox v2.11.11, do:

sudo git checkout v2.11.11

## Run the Upgrade Script

Once the new code is in place, verify that any optional Python packages required by your deployment (e.g. `napalm` or `django-auth-ldap`) are listed in `local_requirements.txt`. Then, run the upgrade script:
Expand Down
6 changes: 5 additions & 1 deletion docs/models/extras/customlink.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Custom links allow users to display arbitrary hyperlinks to external content within NetBox object views. These are helpful for cross-referencing related records in systems outside NetBox. For example, you might create a custom link on the device view which links to the current device in a Network Monitoring System (NMS).

Custom links are created by navigating to Customization > Custom Links. Each link is associated with a particular NetBox object type (site, device, prefix, etc.) and will be displayed on relevant views. Each link has display text and a URL, and data from the Netbox item being viewed can be included in the link using [Jinja2 template code](https://jinja2docs.readthedocs.io/en/stable/) through the variable `obj`, and custom fields through `obj.cf`.
Custom links are created by navigating to Customization > Custom Links. Each link is associated with a particular NetBox object type (site, device, prefix, etc.) and will be displayed on relevant views. Each link has display text and a URL, and data from the NetBox item being viewed can be included in the link using [Jinja2 template code](https://jinja2docs.readthedocs.io/en/stable/) through the variable `obj`, and custom fields through `obj.cf`.

For example, you might define a link like this:

Expand Down Expand Up @@ -32,6 +32,10 @@ The following context data is available within the template when rendering a cus
| `user` | The current user (if authenticated) |
| `perms` | The [permissions](https://docs.djangoproject.com/en/stable/topics/auth/default/#permissions) assigned to the user |

While most of the context variables listed above will have consistent attributes, the object will be an instance of the specific object being viewed when the link is rendered. Different models have different fields and properties, so you may need to some research to determine the attributes available for use within your template for a specific object type.

Checking the REST API representation of an object is generally a convenient way to determine what attributes are available. You can also reference the NetBox source code directly for a comprehensive list.

## 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
2 changes: 1 addition & 1 deletion docs/models/users/token.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
A token is a unique identifier mapped to a NetBox user account. Each user may have one or more tokens which he or she can use for authentication when making REST API requests. To create a token, navigate to the API tokens page under your user profile.

!!! note
The creation and modification of API tokens can be restricted per user by an administrator. If you don't see an option to create an API token, ask an administrator to grant you access.
All users can create and manage REST API tokens under the user control panel in the UI. The ability to view, add, change, or delete tokens via the REST API itself is controlled by the relevant model permissions, assigned to users and/or groups in the admin UI. These permissions should be used with great care to avoid accidentally permitting a user to create tokens for other user accounts.

Each token contains a 160-bit key represented as 40 hexadecimal characters. When creating a token, you'll typically leave the key field blank so that a random key will be automatically generated. However, NetBox allows you to specify a key in case you need to restore a previously deleted token to operation.

Expand Down
20 changes: 20 additions & 0 deletions docs/release-notes/version-3.1.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# NetBox v3.1

## v3.1.11 (2022-04-05)

### Enhancements

* [#8163](https://github.com/netbox-community/netbox/issues/8163) - Show bridge interface members under interface view
* [#8365](https://github.com/netbox-community/netbox/issues/8365) - Enable filtering child devices by parent device ID
* [#8785](https://github.com/netbox-community/netbox/issues/8785) - Permit wildcard values in IP address DNS names
* [#8790](https://github.com/netbox-community/netbox/issues/8790) - Include site and prefixes columns in VLAN group VLANs table
* [#8830](https://github.com/netbox-community/netbox/issues/8830) - Add Checkpoint ClusterXL protocol for FHRP groups
* [#8974](https://github.com/netbox-community/netbox/issues/8974) - Use monospace font for text areas in config revision form
* [#9012](https://github.com/netbox-community/netbox/issues/9012) - Linkify circuits count in providers list
* [#9036](https://github.com/netbox-community/netbox/issues/9036) - Add bulk edit capability for site contact fields

### Bug Fixes

* [#8866](https://github.com/netbox-community/netbox/issues/8866) - Prevent exception when searching for a rack position with no rack specified under device edit view
* [#9009](https://github.com/netbox-community/netbox/issues/9009) - Fix device count for racks in global search results

---

## v3.1.10 (2022-03-25)

### Enhancements
Expand Down
8 changes: 6 additions & 2 deletions netbox/circuits/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
from django_tables2.utils import Accessor

from tenancy.tables import TenantColumn
from utilities.tables import BaseTable, ButtonsColumn, ChoiceFieldColumn, MarkdownColumn, TagColumn, ToggleColumn
from utilities.tables import (
BaseTable, ButtonsColumn, ChoiceFieldColumn, LinkedCountColumn, MarkdownColumn, TagColumn, ToggleColumn,
)
from .models import *


Expand Down Expand Up @@ -53,8 +55,10 @@ class ProviderTable(BaseTable):
name = tables.Column(
linkify=True
)
circuit_count = tables.Column(
circuit_count = LinkedCountColumn(
accessor=Accessor('count_circuits'),
viewname='circuits:circuit_list',
url_params={'provider_id': 'pk'},
verbose_name='Circuits'
)
comments = MarkdownColumn()
Expand Down
5 changes: 5 additions & 0 deletions netbox/dcim/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,11 @@ class DeviceFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilte
to_field_name='slug',
label='Role (slug)',
)
parent_device_id = django_filters.ModelMultipleChoiceFilter(
field_name='parent_bay__device',
queryset=Device.objects.all(),
label='Parent Device (ID)',
)
platform_id = django_filters.ModelMultipleChoiceFilter(
queryset=Platform.objects.all(),
label='Platform (ID)',
Expand Down
15 changes: 14 additions & 1 deletion netbox/dcim/forms/bulk_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,18 @@ class SiteBulkEditForm(AddRemoveTagsForm, CustomFieldModelBulkEditForm):
label=_('ASNs'),
required=False
)
contact_name = forms.CharField(
max_length=50,
required=False
)
contact_phone = forms.CharField(
max_length=20,
required=False
)
contact_email = forms.EmailField(
required=False,
label='Contact E-mail'
)
description = forms.CharField(
max_length=100,
required=False
Expand All @@ -134,7 +146,8 @@ class SiteBulkEditForm(AddRemoveTagsForm, CustomFieldModelBulkEditForm):

class Meta:
nullable_fields = [
'region', 'group', 'tenant', 'asn', 'asns', 'description', 'time_zone',
'region', 'group', 'tenant', 'asn', 'asns', 'contact_name', 'contact_phone', 'contact_email', 'description',
'time_zone',
]


Expand Down
4 changes: 4 additions & 0 deletions netbox/dcim/models/device_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,10 @@ def is_wireless(self):
def is_lag(self):
return self.type == InterfaceTypeChoices.TYPE_LAG

@property
def is_bridge(self):
return self.type == InterfaceTypeChoices.TYPE_BRIDGE

@property
def link(self):
return self.cable or self.wireless_link
Expand Down
9 changes: 9 additions & 0 deletions netbox/dcim/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,14 @@ def get_extra_context(self, request, instance):
orderable=False
)

# Get bridge interfaces
bridge_interfaces = Interface.objects.restrict(request.user, 'view').filter(bridge=instance)
bridge_interfaces_tables = tables.InterfaceTable(
bridge_interfaces,
exclude=('device', 'parent'),
orderable=False
)

# Get child interfaces
child_interfaces = Interface.objects.restrict(request.user, 'view').filter(parent=instance)
child_interfaces_tables = tables.InterfaceTable(
Expand All @@ -1800,6 +1808,7 @@ def get_extra_context(self, request, instance):

return {
'ipaddress_table': ipaddress_table,
'bridge_interfaces_table': bridge_interfaces_tables,
'child_interfaces_table': child_interfaces_tables,
'vlan_table': vlan_table,
}
Expand Down
3 changes: 3 additions & 0 deletions netbox/extras/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ class ConfigRevisionAdmin(admin.ModelAdmin):
}),
('Banners', {
'fields': ('BANNER_LOGIN', 'BANNER_TOP', 'BANNER_BOTTOM'),
'classes': ('monospace',),
}),
('Pagination', {
'fields': ('PAGINATE_COUNT', 'MAX_PAGE_SIZE'),
}),
('Validation', {
'fields': ('CUSTOM_VALIDATORS',),
'classes': ('monospace',),
}),
('NAPALM', {
'fields': ('NAPALM_USERNAME', 'NAPALM_PASSWORD', 'NAPALM_TIMEOUT', 'NAPALM_ARGS'),
'classes': ('monospace',),
}),
('Miscellaneous', {
'fields': ('MAINTENANCE_MODE', 'GRAPHQL_ENABLED', 'CHANGELOG_RETENTION', 'MAPS_URL'),
Expand Down
18 changes: 13 additions & 5 deletions netbox/ipam/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,22 @@ class FHRPGroupProtocolChoices(ChoiceSet):
PROTOCOL_HSRP = 'hsrp'
PROTOCOL_GLBP = 'glbp'
PROTOCOL_CARP = 'carp'
PROTOCOL_CLUSTERXL = 'clusterxl'
PROTOCOL_OTHER = 'other'

CHOICES = (
(PROTOCOL_VRRP2, 'VRRPv2'),
(PROTOCOL_VRRP3, 'VRRPv3'),
(PROTOCOL_HSRP, 'HSRP'),
(PROTOCOL_GLBP, 'GLBP'),
(PROTOCOL_CARP, 'CARP'),
('Standard', (
(PROTOCOL_VRRP2, 'VRRPv2'),
(PROTOCOL_VRRP3, 'VRRPv3'),
(PROTOCOL_CARP, 'CARP'),
)),
('CheckPoint', (
(PROTOCOL_CLUSTERXL, 'ClusterXL'),
)),
('Cisco', (
(PROTOCOL_HSRP, 'HSRP'),
(PROTOCOL_GLBP, 'GLBP'),
)),
(PROTOCOL_OTHER, 'Other'),
)

Expand Down
2 changes: 1 addition & 1 deletion netbox/ipam/migrations/0001_squashed.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Migration(migrations.Migration):
('status', models.CharField(default='active', max_length=50)),
('role', models.CharField(blank=True, max_length=50)),
('assigned_object_id', models.PositiveIntegerField(blank=True, null=True)),
('dns_name', models.CharField(blank=True, max_length=255, validators=[django.core.validators.RegexValidator(code='invalid', message='Only alphanumeric characters, hyphens, periods, and underscores are allowed in DNS names', regex='^[0-9A-Za-z._-]+$')])),
('dns_name', models.CharField(blank=True, max_length=255, validators=[django.core.validators.RegexValidator(code='invalid', message='Only alphanumeric characters, asterisks, hyphens, periods, and underscores are allowed in DNS names', regex='^([0-9A-Za-z_-]+|\\*)(\\.[0-9A-Za-z_-]+)*\\.?$')])),
('description', models.CharField(blank=True, max_length=200)),
],
options={
Expand Down
4 changes: 2 additions & 2 deletions netbox/ipam/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def compare(self, a, b):


DNSValidator = RegexValidator(
regex='^[0-9A-Za-z._-]+$',
message='Only alphanumeric characters, hyphens, periods, and underscores are allowed in DNS names',
regex=r'^([0-9A-Za-z_-]+|\*)(\.[0-9A-Za-z_-]+)*\.?$',
message='Only alphanumeric characters, asterisks, hyphens, periods, and underscores are allowed in DNS names',
code='invalid'
)
2 changes: 1 addition & 1 deletion netbox/ipam/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ def get_extra_context(self, request, instance):
vlans_count = vlans.count()
vlans = add_available_vlans(vlans, vlan_group=instance)

vlans_table = tables.VLANTable(vlans, exclude=('site', 'group', 'prefixes'))
vlans_table = tables.VLANTable(vlans, exclude=('group',))
if request.user.has_perm('ipam.change_vlan') or request.user.has_perm('ipam.delete_vlan'):
vlans_table.columns.show('pk')
paginate_table(vlans_table, request)
Expand Down
26 changes: 21 additions & 5 deletions netbox/netbox/config/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ def __init__(self, name, label, default, description='', field=None, field_kwarg
default='',
description="Additional content to display on the login page",
field_kwargs={
'widget': forms.Textarea(),
'widget': forms.Textarea(
attrs={'class': 'vLargeTextField'}
),
},
),
ConfigParam(
Expand All @@ -31,7 +33,9 @@ def __init__(self, name, label, default, description='', field=None, field_kwarg
default='',
description="Additional content to display at the top of every page",
field_kwargs={
'widget': forms.Textarea(),
'widget': forms.Textarea(
attrs={'class': 'vLargeTextField'}
),
},
),
ConfigParam(
Expand All @@ -40,7 +44,9 @@ def __init__(self, name, label, default, description='', field=None, field_kwarg
default='',
description="Additional content to display at the bottom of every page",
field_kwargs={
'widget': forms.Textarea(),
'widget': forms.Textarea(
attrs={'class': 'vLargeTextField'}
),
},
),

Expand Down Expand Up @@ -109,7 +115,12 @@ def __init__(self, name, label, default, description='', field=None, field_kwarg
label='Custom validators',
default={},
description="Custom validation rules (JSON)",
field=forms.JSONField
field=forms.JSONField,
field_kwargs={
'widget': forms.Textarea(
attrs={'class': 'vLargeTextField'}
),
},
),

# NAPALM
Expand Down Expand Up @@ -137,7 +148,12 @@ def __init__(self, name, label, default, description='', field=None, field_kwarg
label='NAPALM arguments',
default={},
description="Additional arguments to pass when invoking a NAPALM driver (as JSON data)",
field=forms.JSONField
field=forms.JSONField,
field_kwargs={
'widget': forms.Textarea(
attrs={'class': 'vLargeTextField'}
),
},
),

# Miscellaneous
Expand Down
4 changes: 3 additions & 1 deletion netbox/netbox/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@
'url': 'dcim:site_list',
}),
('rack', {
'queryset': Rack.objects.prefetch_related('site', 'location', 'tenant', 'role'),
'queryset': Rack.objects.prefetch_related('site', 'location', 'tenant', 'role').annotate(
device_count=count_related(Device, 'rack')
),
'filterset': RackFilterSet,
'table': RackTable,
'url': 'dcim:rack_list',
Expand Down
2 changes: 1 addition & 1 deletion netbox/netbox/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# Environment setup
#

VERSION = '3.1.10'
VERSION = '3.1.11'

# Hostname
HOSTNAME = platform.node()
Expand Down
2 changes: 1 addition & 1 deletion netbox/project-static/dist/netbox.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion netbox/project-static/dist/netbox.js.map

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions netbox/project-static/src/select/api/apiSelect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,9 +557,12 @@ export class APISelect {
private async handleSearch(event: Event) {
const { value: q } = event.target as HTMLInputElement;
const url = queryString.stringifyUrl({ url: this.queryUrl, query: { q } });
await this.fetchOptions(url, 'merge');
this.slim.data.search(q);
this.slim.render();
if (!url.includes(`{{`)) {
await this.fetchOptions(url, 'merge');
this.slim.data.search(q);
this.slim.render();
}
return;
}

/**
Expand Down
7 changes: 7 additions & 0 deletions netbox/templates/dcim/interface.html
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,13 @@ <h5 class="card-header">
{% include 'inc/panel_table.html' with table=vlan_table heading="VLANs" %}
</div>
</div>
{% if object.is_bridge %}
<div class="row mb-3">
<div class="col col-md-12">
{% include 'inc/panel_table.html' with table=bridge_interfaces_table heading="Bridge Interfaces" %}
</div>
</div>
{% endif %}
<div class="row mb-3">
<div class="col col-md-12">
{% include 'inc/panel_table.html' with table=child_interfaces_table heading="Child Interfaces" %}
Expand Down
Loading

0 comments on commit 10f8a94

Please sign in to comment.