Compare commits

..

34 Commits

Author SHA1 Message Date
Jeremy Stretch
10f8a94399 Merge pull request #9039 from netbox-community/develop
Release v3.1.11
2022-04-05 14:45:41 -04:00
jeremystretch
631de20a8d Release v3.1.11 2022-04-05 14:35:27 -04:00
jeremystretch
0f5fe746e0 Add warning for legacy ASN field on site 2022-04-05 10:22:42 -04:00
jeremystretch
a7fc8621a8 Closes #9036: Add bulk edit capability for site contact fields 2022-04-05 10:18:20 -04:00
jeremystretch
e575279738 Changelog for #8365 2022-04-04 15:58:54 -04:00
Jeremy Stretch
796f7258cc Merge pull request #9018 from stephanblanke/8365-filering-for-child-devices-by-parent-device
Closes #8365: Filtering for child devices by parent device
2022-04-04 15:18:20 -04:00
Stephan Blanke
8126087b3e Merge branch 'netbox-community:develop' into 8365-filering-for-child-devices-by-parent-device 2022-04-02 18:10:12 +02:00
Stephan Blanke
780459d2bf Closes #8365: Filtering for child devices by parent device 2022-04-02 18:08:48 +02:00
jeremystretch
99a01207bc Closes #9012: Linkify circuits count in providers list 2022-04-01 09:06:44 -04:00
Jeremy Stretch
6d6457ad18 Merge pull request #9010 from kkthxbye-code/fix-9009
Annotate rack search queryset with device count
2022-04-01 08:43:22 -04:00
jeremystretch
35f3a42e7f Remove 2022 survey announcement 2022-04-01 08:31:53 -04:00
kkthxbye
a84ae88214 Annotate rack search queryset with device count 2022-04-01 09:34:16 +02:00
jeremystretch
58e4d08bb0 Closes #8790: Include site and prefixes columns in VLAN group VLANs table 2022-03-30 15:51:12 -04:00
jeremystretch
91e8f57afb Change log & cleanup for #8163, #8866 2022-03-30 15:39:28 -04:00
Jeremy Stretch
e3d0628a06 Merge pull request #8870 from minitriga/issue_8866
APISelect JavaScript only perform fetch if Django substitutes have been replaced.
2022-03-30 15:37:14 -04:00
Jeremy Stretch
9fca9ca7ec Merge pull request #8983 from stephanblanke/8163-bridge-members-panel-in-interface-view
Closes #8163: Add bridge members panel to interface view
2022-03-30 15:27:37 -04:00
jeremystretch
2d09a40663 Closes #8601: Include group when displaying tenant assigned to cluster 2022-03-30 15:04:13 -04:00
jeremystretch
1eaf55c555 Closes #8336: Add note about referening object in custom link template 2022-03-30 14:14:49 -04:00
jeremystretch
db535e6453 Closes #8436: Update token permissions documentation 2022-03-30 14:05:27 -04:00
jeremystretch
dadec9d3cb Add instruction for checking out an older release 2022-03-30 13:03:08 -04:00
jeremystretch
ff780177d0 Clean up exception templates 2022-03-29 16:01:10 -04:00
Stephan Blanke
b7e2ea1ca5 Closes #8163: Add bridge members panel to interface view 2022-03-28 20:37:00 +02:00
jeremystretch
894665b067 Changelog for #8785, #8830 2022-03-28 10:35:49 -04:00
jeremystretch
48b7294ff1 #8785: Tweak regex validator to avoid creating no-op migration file 2022-03-28 10:35:00 -04:00
Jeremy Stretch
cde8ff282d Merge pull request #8962 from apellini/patch-2
#8830 Adding ClusterXL
2022-03-28 10:06:50 -04:00
Jeremy Stretch
0b44a595e2 Merge pull request #8945 from fmlshai/develop
Fix #8785 - allow wildcard dns records
2022-03-28 10:04:33 -04:00
Jeremy Stretch
37781bd208 Fix parentheses 2022-03-28 09:37:33 -04:00
fmlshai
e0344e9251 Update validators.py
Updated DNSValidator regex
2022-03-28 15:20:19 +02:00
jeremystretch
a1808a54a4 Fixes #8974: Use monospace font for text areas in config revision form 2022-03-28 09:13:15 -04:00
neope
1cef513f6c Adding ClusterXL as FHRPGroupProtocolChoices
Adding in choices group standard, checkpoint and cisco and ungroupped other.
2022-03-25 19:41:35 +01:00
jeremystretch
57759aa4a3 PRVB 2022-03-25 10:29:44 -04:00
neope
934493bf5f #8830 Adding ClusterXL
Adding ClusterCL Choice to FHRP Group
2022-03-25 08:35:57 +01:00
fmlshai
f45e64c756 Fix #8785 - allow wildcard dns records
Added * to the DNSValidator regex to allow wildcard domains like *.example.com
2022-03-23 14:38:26 +01:00
Alex Gittings
3edff89a4d Fixes: #8866 - Does not perform API Select Search if a django peramiter has not been replaced 2022-03-14 17:57:33 +00:00
31 changed files with 218 additions and 115 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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 |
|------------|-----------------|
@@ -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:

View File

@@ -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:
@@ -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.

View File

@@ -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.

View File

@@ -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

View File

@@ -2,7 +2,9 @@ import django_tables2 as tables
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 *
@@ -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()

View File

@@ -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)',

View File

@@ -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
@@ -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',
]

View File

@@ -762,6 +762,10 @@ class Interface(ComponentModel, BaseInterface, LinkTermination, PathEndpoint):
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

View File

@@ -1776,6 +1776,14 @@ class InterfaceView(generic.ObjectView):
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(
@@ -1800,6 +1808,7 @@ class InterfaceView(generic.ObjectView):
return {
'ipaddress_table': ipaddress_table,
'bridge_interfaces_table': bridge_interfaces_tables,
'child_interfaces_table': child_interfaces_tables,
'vlan_table': vlan_table,
}

View File

@@ -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'),

View File

@@ -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'),
)

View File

@@ -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={

View File

@@ -24,7 +24,7 @@ class MinPrefixLengthValidator(BaseValidator):
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'
)

View File

@@ -795,7 +795,7 @@ class VLANGroupView(generic.ObjectView):
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)

View File

@@ -22,7 +22,9 @@ PARAMS = (
default='',
description="Additional content to display on the login page",
field_kwargs={
'widget': forms.Textarea(),
'widget': forms.Textarea(
attrs={'class': 'vLargeTextField'}
),
},
),
ConfigParam(
@@ -31,7 +33,9 @@ PARAMS = (
default='',
description="Additional content to display at the top of every page",
field_kwargs={
'widget': forms.Textarea(),
'widget': forms.Textarea(
attrs={'class': 'vLargeTextField'}
),
},
),
ConfigParam(
@@ -40,7 +44,9 @@ PARAMS = (
default='',
description="Additional content to display at the bottom of every page",
field_kwargs={
'widget': forms.Textarea(),
'widget': forms.Textarea(
attrs={'class': 'vLargeTextField'}
),
},
),
@@ -109,7 +115,12 @@ PARAMS = (
label='Custom validators',
default={},
description="Custom validation rules (JSON)",
field=forms.JSONField
field=forms.JSONField,
field_kwargs={
'widget': forms.Textarea(
attrs={'class': 'vLargeTextField'}
),
},
),
# NAPALM
@@ -137,7 +148,12 @@ PARAMS = (
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

View File

@@ -65,7 +65,9 @@ DCIM_TYPES = OrderedDict(
'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',

View File

@@ -19,7 +19,7 @@ from netbox.config import PARAMS
# Environment setup
#
VERSION = '3.1.10'
VERSION = '3.1.11'
# Hostname
HOSTNAME = platform.node()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -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;
}
/**

View File

@@ -467,6 +467,13 @@
{% 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" %}

View File

@@ -80,7 +80,14 @@
</tr>
<tr>
<th scope="row">AS Number</th>
<td>{{ object.asn|placeholder }}</td>
<td>
{% if object.asn %}
<div class="float-end text-warning">
<i class="mdi mdi-alert" title="This field will be removed in NetBox v3.2. Please migrate this data to ASN objects."></i>
</div>
{% endif %}
{{ object.asn|placeholder }}
</td>
</tr>
<tr>
<th scope="row">Time Zone</th>
@@ -128,50 +135,44 @@
</td>
</tr>
{# Legacy contact fields #}
{% with deprecation_warning="This field will be removed in a future release. Please migrate this data to contact objects." %}
{% if object.contact_name %}
<tr>
<th scope="row">Contact Name</th>
<td>
{% if object.contact_name %}
<div class="float-end text-warning">
<i class="mdi mdi-alert" title="{{ deprecation_warning }}"></i>
</div>
{% endif %}
{{ object.contact_name|placeholder }}
</td>
</tr>
{% endif %}
{% if object.contact_phone %}
<tr>
<th scope="row">Contact Phone</th>
<td>
{% if object.contact_phone %}
<div class="float-end text-warning">
<i class="mdi mdi-alert" title="{{ deprecation_warning }}"></i>
</div>
<a href="tel:{{ object.contact_phone }}">{{ object.contact_phone }}</a>
{% else %}
<span class="text-muted">&mdash;</span>
{% endif %}
</td>
</tr>
{% endif %}
{% if object.contact_email %}
<tr>
<th scope="row">Contact E-Mail</th>
<td>
{% if object.contact_email %}
<div class="float-end text-warning">
<i class="mdi mdi-alert" title="{{ deprecation_warning }}"></i>
</div>
<a href="mailto:{{ object.contact_email }}">{{ object.contact_email }}</a>
{% else %}
<span class="text-muted">&mdash;</span>
{% endif %}
</td>
</tr>
{% endif %}
{% with deprecation_warning="This field will be removed in NetBox v3.2. Please migrate this data to contact objects." %}
<tr>
<th scope="row">Contact Name</th>
<td>
{% if object.contact_name %}
<div class="float-end text-warning">
<i class="mdi mdi-alert" title="{{ deprecation_warning }}"></i>
</div>
{% endif %}
{{ object.contact_name|placeholder }}
</td>
</tr>
<tr>
<th scope="row">Contact Phone</th>
<td>
{% if object.contact_phone %}
<div class="float-end text-warning">
<i class="mdi mdi-alert" title="{{ deprecation_warning }}"></i>
</div>
<a href="tel:{{ object.contact_phone }}">{{ object.contact_phone }}</a>
{% else %}
<span class="text-muted">&mdash;</span>
{% endif %}
</td>
</tr>
<tr>
<th scope="row">Contact E-Mail</th>
<td>
{% if object.contact_email %}
<div class="float-end text-warning">
<i class="mdi mdi-alert" title="{{ deprecation_warning }}"></i>
</div>
<a href="mailto:{{ object.contact_email }}">{{ object.contact_email }}</a>
{% else %}
<span class="text-muted">&mdash;</span>
{% endif %}
</td>
</tr>
{% endwith %}
</table>
</div>

View File

@@ -1,19 +1,19 @@
{% extends '500.html' %}
{% block message %}
<p>
A module import error occurred during this request. Common causes include the following:
</p>
<p>
<i class="mdi mdi-alert"></i> <strong>Missing required packages</strong> - This installation of NetBox might be
missing one or more required Python packages. These packages are listed in <code>requirements.txt</code> and
<code>local_requirements.txt</code>, and are normally installed as part of the installation or upgrade process.
To verify installed packages, run <code>pip freeze</code> from the console and compare the output to the list of
required packages.
</p>
<p>
<i class="mdi mdi-alert"></i> <strong>WSGI service not restarted after upgrade</strong> - If this installation
has recently been upgraded, check that the WSGI service (e.g. gunicorn or uWSGI) has been restarted. This
ensures that the new code is running.
</p>
<p>
A module import error occurred during this request. Common causes include the following:
</p>
<p>
<i class="mdi mdi-alert"></i> <strong>Missing required packages</strong> - This installation of NetBox might be
missing one or more required Python packages. These packages are listed in <code>requirements.txt</code> and
<code>local_requirements.txt</code>, and are normally installed as part of the installation or upgrade process. To
verify installed packages, run <code>pip freeze</code> from the console and compare the output to the list of
required packages.
</p>
<p>
<i class="mdi mdi-alert"></i> <strong>WSGI service not restarted after upgrade</strong> - If this installation has
recently been upgraded, check that the WSGI service (e.g. gunicorn or uWSGI) has been restarted. This ensures that
the new code is running.
</p>
{% endblock message %}

View File

@@ -1,12 +1,12 @@
{% extends '500.html' %}
{% block message %}
<p>
A file permission error was detected while processing this request. Common causes include the following:
</p>
<p>
<i class="mdi mdi-alert"></i> <strong>Insufficient write permission to the media root</strong> - The configured
media root is <code>{{ settings.MEDIA_ROOT }}</code>. Ensure that the user NetBox runs as has access to write
files to all locations within this path.
</p>
<p>
A file permission error was detected while processing this request. Common causes include the following:
</p>
<p>
<i class="mdi mdi-alert"></i> <strong>Insufficient write permission to the media root</strong> - The configured
media root is <code>{{ settings.MEDIA_ROOT }}</code>. Ensure that the user NetBox runs as has access to write files
to all locations within this path.
</p>
{% endblock message %}

View File

@@ -1,17 +1,17 @@
{% extends '500.html' %}
{% block message %}
<p>
A database programming error was detected while processing this request. Common causes include the following:
</p>
<p>
<i class="mdi mdi-alert"></i> <strong>Database migrations missing</strong> - When upgrading to a new NetBox release, the upgrade script must
be run to apply any new database migrations. You can run migrations manually by executing
<code>python3 manage.py migrate</code> from the command line.
</p>
<p>
<i class="mdi mdi-alert"></i> <strong>Unsupported PostgreSQL version</strong> - Ensure that PostgreSQL version 9.6 or higher is in use. You
can check this by connecting to the database using NetBox's credentials and issuing a query for
<code>SELECT VERSION()</code>.
</p>
<p>
A database programming error was detected while processing this request. Common causes include the following:
</p>
<p>
<i class="mdi mdi-alert"></i> <strong>Database migrations missing</strong> - When upgrading to a new NetBox release,
the upgrade script must be run to apply any new database migrations. You can run migrations manually by executing
<code>python3 manage.py migrate</code> from the command line.
</p>
<p>
<i class="mdi mdi-alert"></i> <strong>Unsupported PostgreSQL version</strong> - Ensure that PostgreSQL version 10
or later is in use. You can check this by connecting to the database using NetBox's credentials and issuing a query
for <code>SELECT VERSION()</code>.
</p>
{% endblock message %}

View File

@@ -33,6 +33,9 @@
<th scope="row">Tenant</th>
<td>
{% if object.tenant %}
{% if object.tenant.group %}
<a href="{{ object.tenant.group.get_absolute_url }}">{{ object.tenant.group }}</a> /
{% endif %}
<a href="{{ object.tenant.get_absolute_url }}">{{ object.tenant }}</a>
{% else %}
<span class="text-muted">None</span>

View File

@@ -18,7 +18,7 @@ gunicorn==20.1.0
Jinja2==3.0.3
Markdown==3.3.6
markdown-include==0.6.0
mkdocs-material==8.2.7
mkdocs-material==8.2.8
netaddr==0.8.0
Pillow==9.0.1
psycopg2-binary==2.9.3