mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-26 18:38:38 -06:00
19217 merge main
This commit is contained in:
commit
c69bea4a44
@ -15,7 +15,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: NetBox version
|
label: NetBox version
|
||||||
description: What version of NetBox are you currently running?
|
description: What version of NetBox are you currently running?
|
||||||
placeholder: v4.2.7
|
placeholder: v4.2.8
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
|
2
.github/ISSUE_TEMPLATE/02-bug_report.yaml
vendored
2
.github/ISSUE_TEMPLATE/02-bug_report.yaml
vendored
@ -27,7 +27,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: NetBox Version
|
label: NetBox Version
|
||||||
description: What version of NetBox are you currently running?
|
description: What version of NetBox are you currently running?
|
||||||
placeholder: v4.2.7
|
placeholder: v4.2.8
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
|
@ -8,9 +8,6 @@ django-cors-headers
|
|||||||
|
|
||||||
# Runtime UI tool for debugging Django
|
# Runtime UI tool for debugging Django
|
||||||
# https://github.com/jazzband/django-debug-toolbar/blob/main/docs/changes.rst
|
# https://github.com/jazzband/django-debug-toolbar/blob/main/docs/changes.rst
|
||||||
# See: https://django-debug-toolbar.readthedocs.io/en/latest/changes.html#id1
|
|
||||||
# "Wrap SHOW_TOOLBAR_CALLBACK function with sync_to_async or async_to_sync to allow sync/async
|
|
||||||
# compatibility." breaks stawberry-graphql-django at version 0.52.0 (current)
|
|
||||||
django-debug-toolbar
|
django-debug-toolbar
|
||||||
|
|
||||||
# Library for writing reusable URL query filters
|
# Library for writing reusable URL query filters
|
||||||
@ -135,8 +132,7 @@ strawberry-graphql
|
|||||||
|
|
||||||
# Strawberry GraphQL Django extension
|
# Strawberry GraphQL Django extension
|
||||||
# https://github.com/strawberry-graphql/strawberry-django/releases
|
# https://github.com/strawberry-graphql/strawberry-django/releases
|
||||||
# Pinned to v0.52.0 for suspected upstream bug; see #18329
|
strawberry-graphql-django
|
||||||
strawberry-graphql-django==0.52.0
|
|
||||||
|
|
||||||
# SVG image rendering (used for rack elevations)
|
# SVG image rendering (used for rack elevations)
|
||||||
# https://github.com/mozman/svgwrite/blob/master/NEWS.rst
|
# https://github.com/mozman/svgwrite/blob/master/NEWS.rst
|
||||||
|
@ -246,7 +246,7 @@ Once NetBox has been configured, we're ready to proceed with the actual installa
|
|||||||
|
|
||||||
* Create a Python virtual environment
|
* Create a Python virtual environment
|
||||||
* Installs all required Python packages
|
* Installs all required Python packages
|
||||||
* Run database schema migrations
|
* Run database schema migrations (skip with `--readonly`)
|
||||||
* Builds the documentation locally (for offline use)
|
* Builds the documentation locally (for offline use)
|
||||||
* Aggregate static resource files on disk
|
* Aggregate static resource files on disk
|
||||||
|
|
||||||
@ -266,6 +266,9 @@ sudo PYTHON=/usr/bin/python3.10 /opt/netbox/upgrade.sh
|
|||||||
!!! note
|
!!! note
|
||||||
Upon completion, the upgrade script may warn that no existing virtual environment was detected. As this is a new installation, this warning can be safely ignored.
|
Upon completion, the upgrade script may warn that no existing virtual environment was detected. As this is a new installation, this warning can be safely ignored.
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
To run the script on a node connected to a database in read-only mode, include the `--readonly` parameter. This will skip the application of any database migrations.
|
||||||
|
|
||||||
## Create a Super User
|
## Create a Super User
|
||||||
|
|
||||||
NetBox does not come with any predefined user accounts. You'll need to create a super user (administrative account) to be able to log into NetBox. First, enter the Python virtual environment created by the upgrade script:
|
NetBox does not come with any predefined user accounts. You'll need to create a super user (administrative account) to be able to log into NetBox. First, enter the Python virtual environment created by the upgrade script:
|
||||||
|
@ -124,17 +124,19 @@ sudo cp /opt/netbox-$OLDVER/gunicorn.py /opt/netbox/
|
|||||||
|
|
||||||
### Option B: Check Out a Git Release
|
### Option B: Check Out a Git Release
|
||||||
|
|
||||||
This guide assumes that NetBox is installed at `/opt/netbox`. First, determine the latest release either by visiting our [releases page](https://github.com/netbox-community/netbox/releases) or by running the following `git` commands:
|
This guide assumes that NetBox is installed at `/opt/netbox`. First, determine the latest release either by visiting our [releases page](https://github.com/netbox-community/netbox/releases) or by running the following command:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo git fetch --tags
|
git ls-remote --tags https://github.com/netbox-community/netbox.git \
|
||||||
git describe --tags $(git rev-list --tags --max-count=1)
|
| grep -o 'refs/tags/v[0-9]*\.[0-9]*\.[0-9]*$' \
|
||||||
|
| tail -n 1 \
|
||||||
|
| sed 's|refs/tags/||'
|
||||||
```
|
```
|
||||||
|
|
||||||
Check out the desired release by specifying its tag:
|
Check out the desired release by specifying its tag. For example:
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo git checkout v4.2.0
|
sudo git checkout v4.2.7
|
||||||
```
|
```
|
||||||
|
|
||||||
## 4. Run the Upgrade Script
|
## 4. Run the Upgrade Script
|
||||||
@ -152,6 +154,9 @@ sudo ./upgrade.sh
|
|||||||
sudo PYTHON=/usr/bin/python3.10 ./upgrade.sh
|
sudo PYTHON=/usr/bin/python3.10 ./upgrade.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
To run the script on a node connected to a database in read-only mode, include the `--readonly` parameter. This will skip the application of any database migrations.
|
||||||
|
|
||||||
This script performs the following actions:
|
This script performs the following actions:
|
||||||
|
|
||||||
* Destroys and rebuilds the Python virtual environment
|
* Destroys and rebuilds the Python virtual environment
|
||||||
|
@ -1,5 +1,35 @@
|
|||||||
# NetBox v4.2
|
# NetBox v4.2
|
||||||
|
|
||||||
|
## v4.2.8 (2025-04-22)
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
* [#17136](https://github.com/netbox-community/netbox/issues/17136) - Introduce the `--readonly` flag on upgrade script
|
||||||
|
* [#17908](https://github.com/netbox-community/netbox/issues/17908) - Add trace buttons to terminations under cable view
|
||||||
|
* [#18879](https://github.com/netbox-community/netbox/issues/18879) - Enable filtering prefixes by group of assigned VLAN
|
||||||
|
* [#18976](https://github.com/netbox-community/netbox/issues/18976) - Include FHRP group name on interface lists
|
||||||
|
* [#18978](https://github.com/netbox-community/netbox/issues/18978) - Add 802.1Q mode to interface filter form
|
||||||
|
* [#19038](https://github.com/netbox-community/netbox/issues/19038) - Show count of related VLAN groups under cluster view
|
||||||
|
* [#19040](https://github.com/netbox-community/netbox/issues/19040) - Add "copy to clipboard" button for rendered config
|
||||||
|
* [#19056](https://github.com/netbox-community/netbox/issues/19056) - Enable filtering devices by location slug
|
||||||
|
* [#19196](https://github.com/netbox-community/netbox/issues/19196) - Add filtering by VLAN translation policy to interface filter forms
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* [#18500](https://github.com/netbox-community/netbox/issues/18500) - `prepare_cloned_fields()` should validate cloning support on model
|
||||||
|
* [#18669](https://github.com/netbox-community/netbox/issues/18669) - Ensure default custom field values are respected when creating objects via the REST API
|
||||||
|
* [#18881](https://github.com/netbox-community/netbox/issues/18881) - Include missing related object counts under certain views
|
||||||
|
* [#18955](https://github.com/netbox-community/netbox/issues/18955) - Omit "clear" button on required choice fields
|
||||||
|
* [#18959](https://github.com/netbox-community/netbox/issues/18959) - Preserve ordering of terminations in cable traces
|
||||||
|
* [#18961](https://github.com/netbox-community/netbox/issues/18961) - Virtual chassis form should exclude members of other VCs when adding members
|
||||||
|
* [#19166](https://github.com/netbox-community/netbox/issues/19166) - Fix custom field choices bulk import support for `base_choices`
|
||||||
|
* [#19189](https://github.com/netbox-community/netbox/issues/19189) - The `load_yaml()` convenience method on BaseScript should use SafeLoader
|
||||||
|
* [#19195](https://github.com/netbox-community/netbox/issues/19195) - Language cookie should respect `SESSION_COOKIE_SECURE` value
|
||||||
|
* [#19230](https://github.com/netbox-community/netbox/issues/19230) - Allow label reuse when creating multiple components from a pattern
|
||||||
|
* [#19268](https://github.com/netbox-community/netbox/issues/19268) - Restore editing conflict protection for several object forms
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v4.2.7 (2025-04-10)
|
## v4.2.7 (2025-04-10)
|
||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
@ -28,6 +28,7 @@ from netbox.config import get_config
|
|||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
from users import forms, tables
|
from users import forms, tables
|
||||||
from users.models import UserConfig
|
from users.models import UserConfig
|
||||||
|
from utilities.string import remove_linebreaks
|
||||||
from utilities.views import register_model_view
|
from utilities.views import register_model_view
|
||||||
|
|
||||||
|
|
||||||
@ -133,7 +134,8 @@ class LoginView(View):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.debug(f"Login form validation failed for username: {form['username'].value()}")
|
username = form['username'].value()
|
||||||
|
logger.debug(f"Login form validation failed for username: {remove_linebreaks(username)}")
|
||||||
|
|
||||||
return render(request, self.template_name, {
|
return render(request, self.template_name, {
|
||||||
'form': form,
|
'form': form,
|
||||||
@ -145,10 +147,10 @@ class LoginView(View):
|
|||||||
redirect_url = data.get('next', settings.LOGIN_REDIRECT_URL)
|
redirect_url = data.get('next', settings.LOGIN_REDIRECT_URL)
|
||||||
|
|
||||||
if redirect_url and url_has_allowed_host_and_scheme(redirect_url, allowed_hosts=None):
|
if redirect_url and url_has_allowed_host_and_scheme(redirect_url, allowed_hosts=None):
|
||||||
logger.debug(f"Redirecting user to {redirect_url}")
|
logger.debug(f"Redirecting user to {remove_linebreaks(redirect_url)}")
|
||||||
else:
|
else:
|
||||||
if redirect_url:
|
if redirect_url:
|
||||||
logger.warning(f"Ignoring unsafe 'next' URL passed to login form: {redirect_url}")
|
logger.warning(f"Ignoring unsafe 'next' URL passed to login form: {remove_linebreaks(redirect_url)}")
|
||||||
redirect_url = reverse('home')
|
redirect_url = reverse('home')
|
||||||
|
|
||||||
return HttpResponseRedirect(redirect_url)
|
return HttpResponseRedirect(redirect_url)
|
||||||
|
@ -55,19 +55,23 @@ class ComponentCreateForm(forms.Form):
|
|||||||
def clean(self):
|
def clean(self):
|
||||||
super().clean()
|
super().clean()
|
||||||
|
|
||||||
# Validate that all replication fields generate an equal number of values
|
# Validate that all replication fields generate an equal number of values (or a single value)
|
||||||
if not (patterns := self.cleaned_data.get(self.replication_fields[0])):
|
if not (patterns := self.cleaned_data.get(self.replication_fields[0])):
|
||||||
return
|
return
|
||||||
|
|
||||||
pattern_count = len(patterns)
|
pattern_count = len(patterns)
|
||||||
for field_name in self.replication_fields:
|
for field_name in self.replication_fields:
|
||||||
value_count = len(self.cleaned_data[field_name])
|
value_count = len(self.cleaned_data[field_name])
|
||||||
if self.cleaned_data[field_name] and value_count != pattern_count:
|
if self.cleaned_data[field_name]:
|
||||||
raise forms.ValidationError({
|
if value_count == 1:
|
||||||
field_name: _(
|
# If the field resolves to a single value (because no pattern was used), multiply it by the number
|
||||||
"The provided pattern specifies {value_count} values, but {pattern_count} are expected."
|
# of expected values. This allows us to reuse the same label when creating multiple components.
|
||||||
).format(value_count=value_count, pattern_count=pattern_count)
|
self.cleaned_data[field_name] = self.cleaned_data[field_name] * pattern_count
|
||||||
}, code='label_pattern_mismatch')
|
elif value_count != pattern_count:
|
||||||
|
raise forms.ValidationError({
|
||||||
|
field_name: _(
|
||||||
|
"The provided pattern specifies {value_count} values, but {pattern_count} are expected."
|
||||||
|
).format(value_count=value_count, pattern_count=pattern_count)
|
||||||
|
}, code='label_pattern_mismatch')
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -404,6 +408,7 @@ class VirtualChassisCreateForm(NetBoxModelForm):
|
|||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
query_params={
|
query_params={
|
||||||
|
'virtual_chassis_id': 'null',
|
||||||
'site_id': '$site',
|
'site_id': '$site',
|
||||||
'rack_id': '$rack',
|
'rack_id': '$rack',
|
||||||
}
|
}
|
||||||
|
@ -225,8 +225,7 @@ class CableTraceSVG:
|
|||||||
"""
|
"""
|
||||||
nodes_height = 0
|
nodes_height = 0
|
||||||
nodes = []
|
nodes = []
|
||||||
# Sort them by name to make renders more readable
|
for i, term in enumerate(terminations):
|
||||||
for i, term in enumerate(sorted(terminations, key=lambda x: str(x))):
|
|
||||||
node = Node(
|
node = Node(
|
||||||
position=(offset_x + i * width, self.cursor),
|
position=(offset_x + i * width, self.cursor),
|
||||||
width=width,
|
width=width,
|
||||||
|
@ -64,7 +64,7 @@ INTERFACE_IPADDRESSES = """
|
|||||||
|
|
||||||
INTERFACE_FHRPGROUPS = """
|
INTERFACE_FHRPGROUPS = """
|
||||||
{% for assignment in value.all %}
|
{% for assignment in value.all %}
|
||||||
<a href="{{ assignment.group.get_absolute_url }}">{{ assignment.group.get_protocol_display }}: {{ assignment.group.group_id }}</a>
|
<a href="{{ assignment.group.get_absolute_url }}">{{ assignment.group }}</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ class CustomFieldChoiceSetImportForm(CSVModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = CustomFieldChoiceSet
|
model = CustomFieldChoiceSet
|
||||||
fields = (
|
fields = (
|
||||||
'name', 'description', 'extra_choices', 'order_alphabetically',
|
'name', 'description', 'base_choices', 'extra_choices', 'order_alphabetically',
|
||||||
)
|
)
|
||||||
|
|
||||||
def clean_extra_choices(self):
|
def clean_extra_choices(self):
|
||||||
|
BIN
netbox/project-static/dist/netbox.css
vendored
BIN
netbox/project-static/dist/netbox.css
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox.js
vendored
BIN
netbox/project-static/dist/netbox.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox.js.map
vendored
BIN
netbox/project-static/dist/netbox.js.map
vendored
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "netbox",
|
"name": "netbox",
|
||||||
"version": "4.1.0",
|
"version": "4.2.8",
|
||||||
"main": "dist/netbox.js",
|
"main": "dist/netbox.js",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
@ -24,13 +24,13 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mdi/font": "7.4.47",
|
"@mdi/font": "7.4.47",
|
||||||
"@tabler/core": "1.0.0-beta21",
|
"@tabler/core": "1.0.0-beta21",
|
||||||
"bootstrap": "5.3.3",
|
"bootstrap": "5.3.5",
|
||||||
"clipboard": "2.0.11",
|
"clipboard": "2.0.11",
|
||||||
"flatpickr": "4.6.13",
|
"flatpickr": "4.6.13",
|
||||||
"gridstack": "11.5.0",
|
"gridstack": "11.5.0",
|
||||||
"htmx.org": "1.9.12",
|
"htmx.org": "1.9.12",
|
||||||
"query-string": "9.1.1",
|
"query-string": "9.1.1",
|
||||||
"sass": "1.86.0",
|
"sass": "1.87.0",
|
||||||
"tom-select": "2.4.3",
|
"tom-select": "2.4.3",
|
||||||
"typeface-inter": "3.18.1",
|
"typeface-inter": "3.18.1",
|
||||||
"typeface-roboto-mono": "1.1.13"
|
"typeface-roboto-mono": "1.1.13"
|
||||||
|
@ -1066,6 +1066,11 @@ bootstrap@5.3.3:
|
|||||||
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.3.tgz#de35e1a765c897ac940021900fcbb831602bac38"
|
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.3.tgz#de35e1a765c897ac940021900fcbb831602bac38"
|
||||||
integrity sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==
|
integrity sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==
|
||||||
|
|
||||||
|
bootstrap@5.3.5:
|
||||||
|
version "5.3.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.5.tgz#be42cfe0d580e97ee1abb7d38ce94f5c393c9bb6"
|
||||||
|
integrity sha512-ct1CHKtiobRimyGzmsSldEtM03E8fcEX4Tb3dGXz1V8faRwM50+vfHwTzOxB3IlKO7m+9vTH3s/3C6T2EAPeTA==
|
||||||
|
|
||||||
brace-expansion@^1.1.7:
|
brace-expansion@^1.1.7:
|
||||||
version "1.1.11"
|
version "1.1.11"
|
||||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||||
@ -2673,10 +2678,10 @@ safe-regex-test@^1.0.3:
|
|||||||
es-errors "^1.3.0"
|
es-errors "^1.3.0"
|
||||||
is-regex "^1.1.4"
|
is-regex "^1.1.4"
|
||||||
|
|
||||||
sass@1.86.0:
|
sass@1.87.0:
|
||||||
version "1.86.0"
|
version "1.87.0"
|
||||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.86.0.tgz#f49464fb6237a903a93f4e8760ef6e37a5030114"
|
resolved "https://registry.yarnpkg.com/sass/-/sass-1.87.0.tgz#8cceb36fa63fb48a8d5d7f2f4c13b49c524b723e"
|
||||||
integrity sha512-zV8vGUld/+mP4KbMLJMX7TyGCuUp7hnkOScgCMsWuHtns8CWBoz+vmEhoGMXsaJrbUP8gj+F1dLvVe79sK8UdA==
|
integrity sha512-d0NoFH4v6SjEK7BoX810Jsrhj7IQSYHAHLi/iSpgqKc7LaIDshFRlSg5LOymf9FqQhxEHs2W5ZQXlvy0KD45Uw==
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar "^4.0.0"
|
chokidar "^4.0.0"
|
||||||
immutable "^5.0.2"
|
immutable "^5.0.2"
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
version: "4.2.7"
|
version: "4.2.8"
|
||||||
edition: "Community"
|
edition: "Community"
|
||||||
published: "2025-04-10"
|
published: "2025-04-22"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{% extends 'generic/object_edit.html' %}
|
{% extends 'generic/object_edit.html' %}
|
||||||
|
|
||||||
{% block form %}
|
{% block form %}
|
||||||
{% include 'dcim/htmx/cable_edit.html' %}
|
{% include 'dcim/htmx/cable_edit.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block form %}
|
{% block form %}
|
||||||
{% render_errors form %}
|
{% for field in form.hidden_fields %}
|
||||||
|
{{ field }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
<div class="field-group my-5">
|
<div class="field-group my-5">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
{% load form_helpers %}
|
{% load form_helpers %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% for field in form.hidden_fields %}
|
||||||
|
{{ field }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
{# A side termination #}
|
{# A side termination #}
|
||||||
<div class="field-group mb-5">
|
<div class="field-group mb-5">
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block form %}
|
{% block form %}
|
||||||
|
{% for field in form.hidden_fields %}
|
||||||
|
{{ field }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
<div class="field-group my-5">
|
<div class="field-group my-5">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h2 class="col-9 offset-3">{% trans "Virtual Chassis" %}</h2>
|
<h2 class="col-9 offset-3">{% trans "Virtual Chassis" %}</h2>
|
||||||
|
@ -12,11 +12,15 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="tab-pane show active" id="edit-form" role="tabpanel" aria-labelledby="object-list-tab">
|
<div class="tab-pane show active" id="edit-form" role="tabpanel" aria-labelledby="object-list-tab">
|
||||||
<form action="" method="post" enctype="multipart/form-data" class="object-edit">
|
<form action="" method="post" enctype="multipart/form-data" class="object-edit">
|
||||||
|
{% render_errors vc_form %}
|
||||||
{% for form in formset %}
|
{% for form in formset %}
|
||||||
{% render_errors form %}
|
{% render_errors form %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
{% for field in vc_form.hidden_fields %}
|
||||||
|
{{ field }}
|
||||||
|
{% endfor %}
|
||||||
{{ pk_form.pk }}
|
{{ pk_form.pk }}
|
||||||
{{ formset.management_form }}
|
{{ formset.management_form }}
|
||||||
<div class="field-group my-5">
|
<div class="field-group my-5">
|
||||||
|
@ -5,6 +5,10 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block form %}
|
{% block form %}
|
||||||
|
{% for field in form.hidden_fields %}
|
||||||
|
{{ field }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
<div class="field-group my-5">
|
<div class="field-group my-5">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h2 class="col-9 offset-3">{% trans "VLAN" %}</h2>
|
<h2 class="col-9 offset-3">{% trans "VLAN" %}</h2>
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-04-16 05:02+0000\n"
|
"POT-Creation-Date: 2025-04-22 05:01+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -1981,12 +1981,12 @@ msgstr ""
|
|||||||
msgid "Device"
|
msgid "Device"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/circuits/views.py:356
|
#: netbox/circuits/views.py:361
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "No terminations have been defined for circuit {circuit}."
|
msgid "No terminations have been defined for circuit {circuit}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/circuits/views.py:405
|
#: netbox/circuits/views.py:410
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Swapped terminations for circuit {circuit}."
|
msgid "Swapped terminations for circuit {circuit}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -7069,7 +7069,7 @@ msgstr ""
|
|||||||
#: netbox/netbox/navigation/menu.py:75
|
#: netbox/netbox/navigation/menu.py:75
|
||||||
#: netbox/virtualization/forms/model_forms.py:122
|
#: netbox/virtualization/forms/model_forms.py:122
|
||||||
#: netbox/virtualization/tables/clusters.py:87
|
#: netbox/virtualization/tables/clusters.py:87
|
||||||
#: netbox/virtualization/views.py:230
|
#: netbox/virtualization/views.py:240
|
||||||
msgid "Devices"
|
msgid "Devices"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -7143,8 +7143,8 @@ msgid "Power outlets"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/devices.py:256 netbox/dcim/tables/devices.py:1112
|
#: netbox/dcim/tables/devices.py:256 netbox/dcim/tables/devices.py:1112
|
||||||
#: netbox/dcim/tables/devicetypes.py:133 netbox/dcim/views.py:1153
|
#: netbox/dcim/tables/devicetypes.py:133 netbox/dcim/views.py:1203
|
||||||
#: netbox/dcim/views.py:1397 netbox/dcim/views.py:2148
|
#: netbox/dcim/views.py:1447 netbox/dcim/views.py:2198
|
||||||
#: netbox/netbox/navigation/menu.py:94 netbox/netbox/navigation/menu.py:258
|
#: netbox/netbox/navigation/menu.py:94 netbox/netbox/navigation/menu.py:258
|
||||||
#: netbox/templates/dcim/device/base.html:37
|
#: netbox/templates/dcim/device/base.html:37
|
||||||
#: netbox/templates/dcim/device_list.html:43
|
#: netbox/templates/dcim/device_list.html:43
|
||||||
@ -7156,7 +7156,7 @@ msgstr ""
|
|||||||
#: netbox/templates/virtualization/virtualmachine/base.html:27
|
#: netbox/templates/virtualization/virtualmachine/base.html:27
|
||||||
#: netbox/templates/virtualization/virtualmachine_list.html:14
|
#: netbox/templates/virtualization/virtualmachine_list.html:14
|
||||||
#: netbox/virtualization/tables/virtualmachines.py:71
|
#: netbox/virtualization/tables/virtualmachines.py:71
|
||||||
#: netbox/virtualization/views.py:395 netbox/wireless/tables/wirelesslan.py:63
|
#: netbox/virtualization/views.py:405 netbox/wireless/tables/wirelesslan.py:63
|
||||||
msgid "Interfaces"
|
msgid "Interfaces"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -7182,8 +7182,8 @@ msgid "Module Bay"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/devices.py:327 netbox/dcim/tables/devicetypes.py:52
|
#: netbox/dcim/tables/devices.py:327 netbox/dcim/tables/devicetypes.py:52
|
||||||
#: netbox/dcim/tables/devicetypes.py:148 netbox/dcim/views.py:1228
|
#: netbox/dcim/tables/devicetypes.py:148 netbox/dcim/views.py:1278
|
||||||
#: netbox/dcim/views.py:2246 netbox/netbox/navigation/menu.py:103
|
#: netbox/dcim/views.py:2296 netbox/netbox/navigation/menu.py:103
|
||||||
#: netbox/templates/dcim/device/base.html:52
|
#: netbox/templates/dcim/device/base.html:52
|
||||||
#: netbox/templates/dcim/device_list.html:71
|
#: netbox/templates/dcim/device_list.html:71
|
||||||
#: netbox/templates/dcim/devicetype/base.html:49
|
#: netbox/templates/dcim/devicetype/base.html:49
|
||||||
@ -7317,8 +7317,8 @@ msgstr ""
|
|||||||
msgid "Instances"
|
msgid "Instances"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/devicetypes.py:121 netbox/dcim/views.py:1093
|
#: netbox/dcim/tables/devicetypes.py:121 netbox/dcim/views.py:1143
|
||||||
#: netbox/dcim/views.py:1337 netbox/dcim/views.py:2084
|
#: netbox/dcim/views.py:1387 netbox/dcim/views.py:2134
|
||||||
#: netbox/netbox/navigation/menu.py:97
|
#: netbox/netbox/navigation/menu.py:97
|
||||||
#: netbox/templates/dcim/device/base.html:25
|
#: netbox/templates/dcim/device/base.html:25
|
||||||
#: netbox/templates/dcim/device_list.html:15
|
#: netbox/templates/dcim/device_list.html:15
|
||||||
@ -7328,8 +7328,8 @@ msgstr ""
|
|||||||
msgid "Console Ports"
|
msgid "Console Ports"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/devicetypes.py:124 netbox/dcim/views.py:1108
|
#: netbox/dcim/tables/devicetypes.py:124 netbox/dcim/views.py:1158
|
||||||
#: netbox/dcim/views.py:1352 netbox/dcim/views.py:2100
|
#: netbox/dcim/views.py:1402 netbox/dcim/views.py:2150
|
||||||
#: netbox/netbox/navigation/menu.py:98
|
#: netbox/netbox/navigation/menu.py:98
|
||||||
#: netbox/templates/dcim/device/base.html:28
|
#: netbox/templates/dcim/device/base.html:28
|
||||||
#: netbox/templates/dcim/device_list.html:22
|
#: netbox/templates/dcim/device_list.html:22
|
||||||
@ -7339,8 +7339,8 @@ msgstr ""
|
|||||||
msgid "Console Server Ports"
|
msgid "Console Server Ports"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/devicetypes.py:127 netbox/dcim/views.py:1123
|
#: netbox/dcim/tables/devicetypes.py:127 netbox/dcim/views.py:1173
|
||||||
#: netbox/dcim/views.py:1367 netbox/dcim/views.py:2116
|
#: netbox/dcim/views.py:1417 netbox/dcim/views.py:2166
|
||||||
#: netbox/netbox/navigation/menu.py:99
|
#: netbox/netbox/navigation/menu.py:99
|
||||||
#: netbox/templates/dcim/device/base.html:31
|
#: netbox/templates/dcim/device/base.html:31
|
||||||
#: netbox/templates/dcim/device_list.html:29
|
#: netbox/templates/dcim/device_list.html:29
|
||||||
@ -7350,8 +7350,8 @@ msgstr ""
|
|||||||
msgid "Power Ports"
|
msgid "Power Ports"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/devicetypes.py:130 netbox/dcim/views.py:1138
|
#: netbox/dcim/tables/devicetypes.py:130 netbox/dcim/views.py:1188
|
||||||
#: netbox/dcim/views.py:1382 netbox/dcim/views.py:2132
|
#: netbox/dcim/views.py:1432 netbox/dcim/views.py:2182
|
||||||
#: netbox/netbox/navigation/menu.py:100
|
#: netbox/netbox/navigation/menu.py:100
|
||||||
#: netbox/templates/dcim/device/base.html:34
|
#: netbox/templates/dcim/device/base.html:34
|
||||||
#: netbox/templates/dcim/device_list.html:36
|
#: netbox/templates/dcim/device_list.html:36
|
||||||
@ -7361,8 +7361,8 @@ msgstr ""
|
|||||||
msgid "Power Outlets"
|
msgid "Power Outlets"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/devicetypes.py:136 netbox/dcim/views.py:1168
|
#: netbox/dcim/tables/devicetypes.py:136 netbox/dcim/views.py:1218
|
||||||
#: netbox/dcim/views.py:1412 netbox/dcim/views.py:2170
|
#: netbox/dcim/views.py:1462 netbox/dcim/views.py:2220
|
||||||
#: netbox/netbox/navigation/menu.py:95
|
#: netbox/netbox/navigation/menu.py:95
|
||||||
#: netbox/templates/dcim/device/base.html:40
|
#: netbox/templates/dcim/device/base.html:40
|
||||||
#: netbox/templates/dcim/devicetype/base.html:37
|
#: netbox/templates/dcim/devicetype/base.html:37
|
||||||
@ -7371,8 +7371,8 @@ msgstr ""
|
|||||||
msgid "Front Ports"
|
msgid "Front Ports"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/devicetypes.py:139 netbox/dcim/views.py:1183
|
#: netbox/dcim/tables/devicetypes.py:139 netbox/dcim/views.py:1233
|
||||||
#: netbox/dcim/views.py:1427 netbox/dcim/views.py:2186
|
#: netbox/dcim/views.py:1477 netbox/dcim/views.py:2236
|
||||||
#: netbox/netbox/navigation/menu.py:96
|
#: netbox/netbox/navigation/menu.py:96
|
||||||
#: netbox/templates/dcim/device/base.html:43
|
#: netbox/templates/dcim/device/base.html:43
|
||||||
#: netbox/templates/dcim/device_list.html:50
|
#: netbox/templates/dcim/device_list.html:50
|
||||||
@ -7382,16 +7382,16 @@ msgstr ""
|
|||||||
msgid "Rear Ports"
|
msgid "Rear Ports"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/devicetypes.py:142 netbox/dcim/views.py:1213
|
#: netbox/dcim/tables/devicetypes.py:142 netbox/dcim/views.py:1263
|
||||||
#: netbox/dcim/views.py:2226 netbox/netbox/navigation/menu.py:102
|
#: netbox/dcim/views.py:2276 netbox/netbox/navigation/menu.py:102
|
||||||
#: netbox/templates/dcim/device/base.html:49
|
#: netbox/templates/dcim/device/base.html:49
|
||||||
#: netbox/templates/dcim/device_list.html:57
|
#: netbox/templates/dcim/device_list.html:57
|
||||||
#: netbox/templates/dcim/devicetype/base.html:46
|
#: netbox/templates/dcim/devicetype/base.html:46
|
||||||
msgid "Device Bays"
|
msgid "Device Bays"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/devicetypes.py:145 netbox/dcim/views.py:1198
|
#: netbox/dcim/tables/devicetypes.py:145 netbox/dcim/views.py:1248
|
||||||
#: netbox/dcim/views.py:1442 netbox/dcim/views.py:2206
|
#: netbox/dcim/views.py:1492 netbox/dcim/views.py:2256
|
||||||
#: netbox/netbox/navigation/menu.py:101
|
#: netbox/netbox/navigation/menu.py:101
|
||||||
#: netbox/templates/dcim/device/base.html:46
|
#: netbox/templates/dcim/device/base.html:46
|
||||||
#: netbox/templates/dcim/device_list.html:64
|
#: netbox/templates/dcim/device_list.html:64
|
||||||
@ -7465,57 +7465,57 @@ msgstr ""
|
|||||||
msgid "Disconnected {count} {type}"
|
msgid "Disconnected {count} {type}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/views.py:834 netbox/netbox/navigation/menu.py:51
|
#: netbox/dcim/views.py:884 netbox/netbox/navigation/menu.py:51
|
||||||
msgid "Reservations"
|
msgid "Reservations"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/views.py:853 netbox/templates/dcim/location.html:90
|
#: netbox/dcim/views.py:903 netbox/templates/dcim/location.html:90
|
||||||
#: netbox/templates/dcim/site.html:140
|
#: netbox/templates/dcim/site.html:140
|
||||||
msgid "Non-Racked Devices"
|
msgid "Non-Racked Devices"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/views.py:2259 netbox/extras/forms/model_forms.py:591
|
#: netbox/dcim/views.py:2309 netbox/extras/forms/model_forms.py:591
|
||||||
#: netbox/templates/extras/configcontext.html:10
|
#: netbox/templates/extras/configcontext.html:10
|
||||||
#: netbox/virtualization/forms/model_forms.py:232
|
#: netbox/virtualization/forms/model_forms.py:232
|
||||||
#: netbox/virtualization/views.py:436
|
#: netbox/virtualization/views.py:446
|
||||||
msgid "Config Context"
|
msgid "Config Context"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/views.py:2269 netbox/virtualization/views.py:446
|
#: netbox/dcim/views.py:2319 netbox/virtualization/views.py:456
|
||||||
msgid "Render Config"
|
msgid "Render Config"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/views.py:2282 netbox/extras/tables/tables.py:553
|
#: netbox/dcim/views.py:2332 netbox/extras/tables/tables.py:553
|
||||||
#: netbox/netbox/navigation/menu.py:255 netbox/netbox/navigation/menu.py:257
|
#: netbox/netbox/navigation/menu.py:255 netbox/netbox/navigation/menu.py:257
|
||||||
#: netbox/virtualization/views.py:204
|
#: netbox/virtualization/views.py:214
|
||||||
msgid "Virtual Machines"
|
msgid "Virtual Machines"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/views.py:3115
|
#: netbox/dcim/views.py:3165
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Installed device {device} in bay {device_bay}."
|
msgid "Installed device {device} in bay {device_bay}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/views.py:3156
|
#: netbox/dcim/views.py:3206
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Removed device {device} from bay {device_bay}."
|
msgid "Removed device {device} from bay {device_bay}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/views.py:3272 netbox/ipam/tables/ip.py:180
|
#: netbox/dcim/views.py:3322 netbox/ipam/tables/ip.py:180
|
||||||
msgid "Children"
|
msgid "Children"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/views.py:3739
|
#: netbox/dcim/views.py:3789
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Added member <a href=\"{url}\">{device}</a>"
|
msgid "Added member <a href=\"{url}\">{device}</a>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/views.py:3788
|
#: netbox/dcim/views.py:3838
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Unable to remove master device {device} from the virtual chassis."
|
msgid "Unable to remove master device {device} from the virtual chassis."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/views.py:3801
|
#: netbox/dcim/views.py:3851
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Removed {device} from virtual chassis {chassis}"
|
msgid "Removed {device} from virtual chassis {chassis}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -11388,7 +11388,7 @@ msgstr ""
|
|||||||
#: netbox/templates/virtualization/virtualmachine/base.html:32
|
#: netbox/templates/virtualization/virtualmachine/base.html:32
|
||||||
#: netbox/templates/virtualization/virtualmachine_list.html:21
|
#: netbox/templates/virtualization/virtualmachine_list.html:21
|
||||||
#: netbox/virtualization/tables/virtualmachines.py:74
|
#: netbox/virtualization/tables/virtualmachines.py:74
|
||||||
#: netbox/virtualization/views.py:417
|
#: netbox/virtualization/views.py:427
|
||||||
msgid "Virtual Disks"
|
msgid "Virtual Disks"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -15790,12 +15790,12 @@ msgstr ""
|
|||||||
msgid "virtual disks"
|
msgid "virtual disks"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/virtualization/views.py:303
|
#: netbox/virtualization/views.py:313
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Added {count} devices to cluster {cluster}"
|
msgid "Added {count} devices to cluster {cluster}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/virtualization/views.py:338
|
#: netbox/virtualization/views.py:348
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Removed {count} devices from cluster {cluster}"
|
msgid "Removed {count} devices from cluster {cluster}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@ from urllib.parse import urlencode
|
|||||||
|
|
||||||
from django.http import QueryDict
|
from django.http import QueryDict
|
||||||
from django.utils.datastructures import MultiValueDict
|
from django.utils.datastructures import MultiValueDict
|
||||||
|
from netbox.models import CloningMixin
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'dict_to_querydict',
|
'dict_to_querydict',
|
||||||
@ -46,7 +47,7 @@ def prepare_cloned_fields(instance):
|
|||||||
Generate a QueryDict comprising attributes from an object's clone() method.
|
Generate a QueryDict comprising attributes from an object's clone() method.
|
||||||
"""
|
"""
|
||||||
# Generate the clone attributes from the instance
|
# Generate the clone attributes from the instance
|
||||||
if not hasattr(instance, 'clone'):
|
if not issubclass(type(instance), CloningMixin):
|
||||||
return QueryDict(mutable=True)
|
return QueryDict(mutable=True)
|
||||||
attrs = instance.clone()
|
attrs = instance.clone()
|
||||||
|
|
||||||
|
@ -1,9 +1,17 @@
|
|||||||
__all__ = (
|
__all__ = (
|
||||||
|
'remove_linebreaks',
|
||||||
'title',
|
'title',
|
||||||
'trailing_slash',
|
'trailing_slash',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def remove_linebreaks(value):
|
||||||
|
"""
|
||||||
|
Remove all line breaks from a string and return the result. Useful for log sanitization purposes.
|
||||||
|
"""
|
||||||
|
return value.replace('\n', '').replace('\r', '')
|
||||||
|
|
||||||
|
|
||||||
def title(value):
|
def title(value):
|
||||||
"""
|
"""
|
||||||
Improved implementation of str.title(); retains all existing uppercase letters.
|
Improved implementation of str.title(); retains all existing uppercase letters.
|
||||||
|
@ -19,20 +19,20 @@ drf-spectacular-sidecar==2025.4.1
|
|||||||
feedparser==6.0.11
|
feedparser==6.0.11
|
||||||
gunicorn==23.0.0
|
gunicorn==23.0.0
|
||||||
Jinja2==3.1.6
|
Jinja2==3.1.6
|
||||||
Markdown==3.7
|
Markdown==3.8
|
||||||
mkdocs-material==9.6.11
|
mkdocs-material==9.6.12
|
||||||
mkdocstrings[python]==0.29.1
|
mkdocstrings[python]==0.29.1
|
||||||
netaddr==1.3.0
|
netaddr==1.3.0
|
||||||
nh3==0.2.21
|
nh3==0.2.21
|
||||||
Pillow==11.1.0
|
Pillow==11.2.1
|
||||||
psycopg[c,pool]==3.2.6
|
psycopg[c,pool]==3.2.6
|
||||||
PyYAML==6.0.2
|
PyYAML==6.0.2
|
||||||
requests==2.32.3
|
requests==2.32.3
|
||||||
rq==2.1.0
|
rq==2.3.2
|
||||||
social-auth-app-django==5.4.3
|
social-auth-app-django==5.4.3
|
||||||
social-auth-core==4.5.6
|
social-auth-core==4.5.6
|
||||||
strawberry-graphql==0.263.2
|
strawberry-graphql==0.266.0
|
||||||
strawberry-graphql-django==0.52.0
|
strawberry-graphql-django==0.58.0
|
||||||
svgwrite==1.4.3
|
svgwrite==1.4.3
|
||||||
tablib==3.8.0
|
tablib==3.8.0
|
||||||
tzdata==2025.2
|
tzdata==2025.2
|
||||||
|
18
upgrade.sh
18
upgrade.sh
@ -6,6 +6,13 @@
|
|||||||
# variable (if set), or fall back to "python3". Note that NetBox v4.0+ requires
|
# variable (if set), or fall back to "python3". Note that NetBox v4.0+ requires
|
||||||
# Python 3.10 or later.
|
# Python 3.10 or later.
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
if [[ "$1" == "--readonly" ]]; then
|
||||||
|
READONLY_MODE=true
|
||||||
|
else
|
||||||
|
READONLY_MODE=false
|
||||||
|
fi
|
||||||
|
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
NETBOX_VERSION="$(grep ^version netbox/release.yaml | cut -d \" -f2)"
|
NETBOX_VERSION="$(grep ^version netbox/release.yaml | cut -d \" -f2)"
|
||||||
@ -83,9 +90,14 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Apply any database migrations
|
# Apply any database migrations
|
||||||
COMMAND="python3 netbox/manage.py migrate"
|
if [ "$READONLY_MODE" = true ]; then
|
||||||
echo "Applying database migrations ($COMMAND)..."
|
echo "Skipping database migrations (read-only mode)"
|
||||||
eval $COMMAND || exit 1
|
exit 0
|
||||||
|
else
|
||||||
|
COMMAND="python3 netbox/manage.py migrate"
|
||||||
|
echo "Applying database migrations ($COMMAND)..."
|
||||||
|
eval $COMMAND || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Trace any missing cable paths (not typically needed)
|
# Trace any missing cable paths (not typically needed)
|
||||||
COMMAND="python3 netbox/manage.py trace_paths --no-input"
|
COMMAND="python3 netbox/manage.py trace_paths --no-input"
|
||||||
|
Loading…
Reference in New Issue
Block a user