mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-12 06:42:16 -06:00
Compare commits
7 Commits
2a27e475e4
...
v4.3.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6eeb382512 | ||
|
|
e5d6c71171 | ||
|
|
f777bfee2e | ||
|
|
8b63eb64c1 | ||
|
|
cff29f9551 | ||
|
|
a5c0cae112 | ||
|
|
23cc4f1c41 |
@@ -15,7 +15,7 @@ body:
|
||||
attributes:
|
||||
label: NetBox version
|
||||
description: What version of NetBox are you currently running?
|
||||
placeholder: v4.3.3
|
||||
placeholder: v4.3.4
|
||||
validations:
|
||||
required: true
|
||||
- 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:
|
||||
label: NetBox Version
|
||||
description: What version of NetBox are you currently running?
|
||||
placeholder: v4.3.3
|
||||
placeholder: v4.3.4
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
|
||||
@@ -14,6 +14,10 @@ django-debug-toolbar
|
||||
# https://github.com/carltongibson/django-filter/blob/main/CHANGES.rst
|
||||
django-filter
|
||||
|
||||
# Django Debug Toolbar extension for GraphiQL
|
||||
# https://github.com/flavors/django-graphiql-debug-toolbar/blob/main/CHANGES.rst
|
||||
django-graphiql-debug-toolbar
|
||||
|
||||
# HTMX utilities for Django
|
||||
# https://django-htmx.readthedocs.io/en/latest/changelog.html
|
||||
django-htmx
|
||||
@@ -108,6 +112,7 @@ nh3
|
||||
|
||||
# Fork of PIL (Python Imaging Library) for image processing
|
||||
# https://github.com/python-pillow/Pillow/releases
|
||||
# https://pillow.readthedocs.io/en/stable/releasenotes/
|
||||
Pillow
|
||||
|
||||
# PostgreSQL database adapter for Python
|
||||
@@ -126,14 +131,14 @@ requests
|
||||
# https://github.com/rq/rq/blob/master/CHANGES.md
|
||||
rq
|
||||
|
||||
# Social authentication framework
|
||||
# https://github.com/python-social-auth/social-core/blob/master/CHANGELOG.md
|
||||
social-auth-core
|
||||
|
||||
# Django app for social-auth-core
|
||||
# https://github.com/python-social-auth/social-app-django/blob/master/CHANGELOG.md
|
||||
social-auth-app-django
|
||||
|
||||
# Social authentication framework
|
||||
# https://github.com/python-social-auth/social-core/blob/master/CHANGELOG.md
|
||||
social-auth-core
|
||||
|
||||
# Strawberry GraphQL
|
||||
# https://github.com/strawberry-graphql/strawberry/blob/main/CHANGELOG.md
|
||||
strawberry-graphql
|
||||
|
||||
@@ -158,6 +158,7 @@ LOGGING = {
|
||||
* `netbox.<app>.<model>` - Generic form for model-specific log messages
|
||||
* `netbox.auth.*` - Authentication events
|
||||
* `netbox.api.views.*` - Views which handle business logic for the REST API
|
||||
* `netbox.event_rules` - Event rules
|
||||
* `netbox.reports.*` - Report execution (`module.name`)
|
||||
* `netbox.scripts.*` - Custom script execution (`module.name`)
|
||||
* `netbox.views.*` - Views which handle business logic for the web UI
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# NetBox v4.3
|
||||
|
||||
## v4.3.4 (2025-07-15)
|
||||
|
||||
### Enhancements
|
||||
|
||||
* [#18811](https://github.com/netbox-community/netbox/issues/18811) - Match expanded form IPv6 addresses in global search
|
||||
* [#19550](https://github.com/netbox-community/netbox/issues/19550) - Enable lazy loading for rack elevations
|
||||
* [#19571](https://github.com/netbox-community/netbox/issues/19571) - Add a default module type profile for expansion cards
|
||||
* [#19793](https://github.com/netbox-community/netbox/issues/19793) - Support custom dynamic navigation menu links
|
||||
* [#19828](https://github.com/netbox-community/netbox/issues/19828) - Expose L2VPN termination in interface GraphQL response
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* [#19413](https://github.com/netbox-community/netbox/issues/19413) - Custom fields should be grouped in filter forms
|
||||
* [#19633](https://github.com/netbox-community/netbox/issues/19633) - Introduce InvalidCondition exception and log all evaluations of invalid event rule conditions
|
||||
* [#19800](https://github.com/netbox-community/netbox/issues/19800) - Module type bulk import should support profile assignment
|
||||
* [#19806](https://github.com/netbox-community/netbox/issues/19806) - Introduce JobFailed exception to allow marking background jobs as failed
|
||||
* [#19827](https://github.com/netbox-community/netbox/issues/19827) - Enforce uniqueness for device role names & slugs
|
||||
* [#19839](https://github.com/netbox-community/netbox/issues/19839) - Enable export of parent assignment for recursively nested objects
|
||||
* [#19876](https://github.com/netbox-community/netbox/issues/19876) - Remove Markdown rendering from CustomFieldChoiceSet description field
|
||||
|
||||
---
|
||||
|
||||
## v4.3.3 (2025-06-26)
|
||||
|
||||
### Enhancements
|
||||
|
||||
@@ -63,6 +63,10 @@ class DeviceRoleTable(NetBoxTable):
|
||||
verbose_name=_('Name'),
|
||||
linkify=True
|
||||
)
|
||||
parent = tables.Column(
|
||||
verbose_name=_('Parent'),
|
||||
linkify=True,
|
||||
)
|
||||
device_count = columns.LinkedCountColumn(
|
||||
viewname='dcim:device_list',
|
||||
url_params={'role_id': 'pk'},
|
||||
@@ -88,8 +92,8 @@ class DeviceRoleTable(NetBoxTable):
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = models.DeviceRole
|
||||
fields = (
|
||||
'pk', 'id', 'name', 'device_count', 'vm_count', 'color', 'vm_role', 'config_template', 'description',
|
||||
'slug', 'tags', 'actions', 'created', 'last_updated',
|
||||
'pk', 'id', 'name', 'parent', 'device_count', 'vm_count', 'color', 'vm_role', 'config_template',
|
||||
'description', 'slug', 'tags', 'actions', 'created', 'last_updated',
|
||||
)
|
||||
default_columns = ('pk', 'name', 'device_count', 'vm_count', 'color', 'vm_role', 'description')
|
||||
|
||||
|
||||
@@ -24,6 +24,10 @@ class RegionTable(ContactsColumnMixin, NetBoxTable):
|
||||
verbose_name=_('Name'),
|
||||
linkify=True
|
||||
)
|
||||
parent = tables.Column(
|
||||
verbose_name=_('Parent'),
|
||||
linkify=True,
|
||||
)
|
||||
site_count = columns.LinkedCountColumn(
|
||||
viewname='dcim:site_list',
|
||||
url_params={'region_id': 'pk'},
|
||||
@@ -39,7 +43,7 @@ class RegionTable(ContactsColumnMixin, NetBoxTable):
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = Region
|
||||
fields = (
|
||||
'pk', 'id', 'name', 'slug', 'site_count', 'description', 'comments', 'contacts', 'tags',
|
||||
'pk', 'id', 'name', 'parent', 'slug', 'site_count', 'description', 'comments', 'contacts', 'tags',
|
||||
'created', 'last_updated', 'actions',
|
||||
)
|
||||
default_columns = ('pk', 'name', 'site_count', 'description')
|
||||
@@ -54,6 +58,10 @@ class SiteGroupTable(ContactsColumnMixin, NetBoxTable):
|
||||
verbose_name=_('Name'),
|
||||
linkify=True
|
||||
)
|
||||
parent = tables.Column(
|
||||
verbose_name=_('Parent'),
|
||||
linkify=True,
|
||||
)
|
||||
site_count = columns.LinkedCountColumn(
|
||||
viewname='dcim:site_list',
|
||||
url_params={'group_id': 'pk'},
|
||||
@@ -69,7 +77,7 @@ class SiteGroupTable(ContactsColumnMixin, NetBoxTable):
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = SiteGroup
|
||||
fields = (
|
||||
'pk', 'id', 'name', 'slug', 'site_count', 'description', 'comments', 'contacts', 'tags',
|
||||
'pk', 'id', 'name', 'parent', 'slug', 'site_count', 'description', 'comments', 'contacts', 'tags',
|
||||
'created', 'last_updated', 'actions',
|
||||
)
|
||||
default_columns = ('pk', 'name', 'site_count', 'description')
|
||||
@@ -135,6 +143,10 @@ class LocationTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||
verbose_name=_('Name'),
|
||||
linkify=True
|
||||
)
|
||||
parent = tables.Column(
|
||||
verbose_name=_('Parent'),
|
||||
linkify=True,
|
||||
)
|
||||
site = tables.Column(
|
||||
verbose_name=_('Site'),
|
||||
linkify=True
|
||||
@@ -170,8 +182,8 @@ class LocationTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = Location
|
||||
fields = (
|
||||
'pk', 'id', 'name', 'site', 'status', 'facility', 'tenant', 'tenant_group', 'rack_count', 'device_count',
|
||||
'description', 'slug', 'comments', 'contacts', 'tags', 'actions', 'created', 'last_updated',
|
||||
'pk', 'id', 'name', 'parent', 'site', 'status', 'facility', 'tenant', 'tenant_group', 'rack_count',
|
||||
'device_count', 'description', 'slug', 'comments', 'contacts', 'tags', 'actions', 'created', 'last_updated',
|
||||
'vlangroup_count',
|
||||
)
|
||||
default_columns = (
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import functools
|
||||
import operator
|
||||
import re
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
__all__ = (
|
||||
'Condition',
|
||||
'ConditionSet',
|
||||
'InvalidCondition',
|
||||
)
|
||||
|
||||
|
||||
AND = 'and'
|
||||
OR = 'or'
|
||||
|
||||
@@ -19,6 +20,10 @@ def is_ruleset(data):
|
||||
return type(data) is dict and len(data) == 1 and list(data.keys())[0] in (AND, OR)
|
||||
|
||||
|
||||
class InvalidCondition(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Condition:
|
||||
"""
|
||||
An individual conditional rule that evaluates a single attribute and its value.
|
||||
@@ -61,6 +66,7 @@ class Condition:
|
||||
|
||||
self.attr = attr
|
||||
self.value = value
|
||||
self.op = op
|
||||
self.eval_func = getattr(self, f'eval_{op}')
|
||||
self.negate = negate
|
||||
|
||||
@@ -70,16 +76,17 @@ class Condition:
|
||||
"""
|
||||
def _get(obj, key):
|
||||
if isinstance(obj, list):
|
||||
return [dict.get(i, key) for i in obj]
|
||||
|
||||
return dict.get(obj, key)
|
||||
return [operator.getitem(item or {}, key) for item in obj]
|
||||
return operator.getitem(obj or {}, key)
|
||||
|
||||
try:
|
||||
value = functools.reduce(_get, self.attr.split('.'), data)
|
||||
except TypeError:
|
||||
# Invalid key path
|
||||
value = None
|
||||
result = self.eval_func(value)
|
||||
except KeyError:
|
||||
raise InvalidCondition(f"Invalid key path: {self.attr}")
|
||||
try:
|
||||
result = self.eval_func(value)
|
||||
except TypeError as e:
|
||||
raise InvalidCondition(f"Invalid data type at '{self.attr}' for '{self.op}' evaluation: {e}")
|
||||
|
||||
if self.negate:
|
||||
return not result
|
||||
|
||||
@@ -192,5 +192,5 @@ def flush_events(events):
|
||||
try:
|
||||
func = import_string(name)
|
||||
func(events)
|
||||
except Exception as e:
|
||||
except ImportError as e:
|
||||
logger.error(_("Cannot import events pipeline {name} error: {error}").format(name=name, error=e))
|
||||
|
||||
@@ -13,7 +13,7 @@ from rest_framework.utils.encoders import JSONEncoder
|
||||
|
||||
from core.models import ObjectType
|
||||
from extras.choices import *
|
||||
from extras.conditions import ConditionSet
|
||||
from extras.conditions import ConditionSet, InvalidCondition
|
||||
from extras.constants import *
|
||||
from extras.utils import image_upload
|
||||
from extras.models.mixins import RenderTemplateMixin
|
||||
@@ -142,7 +142,15 @@ class EventRule(CustomFieldsMixin, ExportTemplatesMixin, TagsMixin, ChangeLogged
|
||||
if not self.conditions:
|
||||
return True
|
||||
|
||||
return ConditionSet(self.conditions).eval(data)
|
||||
logger = logging.getLogger('netbox.event_rules')
|
||||
|
||||
try:
|
||||
result = ConditionSet(self.conditions).eval(data)
|
||||
logger.debug(f'{self.name}: Evaluated as {result}')
|
||||
return result
|
||||
except InvalidCondition as e:
|
||||
logger.error(f"{self.name}: Evaluation failed. {e}")
|
||||
return False
|
||||
|
||||
|
||||
class Webhook(CustomFieldsMixin, ExportTemplatesMixin, TagsMixin, ChangeLoggedModel):
|
||||
|
||||
@@ -4,7 +4,7 @@ from django.test import TestCase
|
||||
from core.events import *
|
||||
from dcim.choices import SiteStatusChoices
|
||||
from dcim.models import Site
|
||||
from extras.conditions import Condition, ConditionSet
|
||||
from extras.conditions import Condition, ConditionSet, InvalidCondition
|
||||
from extras.events import serialize_for_event
|
||||
from extras.forms import EventRuleForm
|
||||
from extras.models import EventRule, Webhook
|
||||
@@ -12,16 +12,11 @@ from extras.models import EventRule, Webhook
|
||||
|
||||
class ConditionTestCase(TestCase):
|
||||
|
||||
def test_dotted_path_access(self):
|
||||
c = Condition('a.b.c', 1, 'eq')
|
||||
self.assertTrue(c.eval({'a': {'b': {'c': 1}}}))
|
||||
self.assertFalse(c.eval({'a': {'b': {'c': 2}}}))
|
||||
self.assertFalse(c.eval({'a': {'b': {'x': 1}}}))
|
||||
|
||||
def test_undefined_attr(self):
|
||||
c = Condition('x', 1, 'eq')
|
||||
self.assertFalse(c.eval({}))
|
||||
self.assertTrue(c.eval({'x': 1}))
|
||||
with self.assertRaises(InvalidCondition):
|
||||
c.eval({})
|
||||
|
||||
#
|
||||
# Validation tests
|
||||
@@ -37,10 +32,13 @@ class ConditionTestCase(TestCase):
|
||||
# dict type is unsupported
|
||||
Condition('x', 1, dict())
|
||||
|
||||
def test_invalid_op_type(self):
|
||||
def test_invalid_op_types(self):
|
||||
with self.assertRaises(ValueError):
|
||||
# 'gt' supports only numeric values
|
||||
Condition('x', 'foo', 'gt')
|
||||
with self.assertRaises(ValueError):
|
||||
# 'in' supports only iterable values
|
||||
Condition('x', 123, 'in')
|
||||
|
||||
#
|
||||
# Nested attrs tests
|
||||
@@ -50,7 +48,10 @@ class ConditionTestCase(TestCase):
|
||||
c = Condition('x.y.z', 1)
|
||||
self.assertTrue(c.eval({'x': {'y': {'z': 1}}}))
|
||||
self.assertFalse(c.eval({'x': {'y': {'z': 2}}}))
|
||||
self.assertFalse(c.eval({'a': {'b': {'c': 1}}}))
|
||||
with self.assertRaises(InvalidCondition):
|
||||
c.eval({'x': {'y': None}})
|
||||
with self.assertRaises(InvalidCondition):
|
||||
c.eval({'x': {'y': {'a': 1}}})
|
||||
|
||||
#
|
||||
# Operator tests
|
||||
@@ -74,23 +75,31 @@ class ConditionTestCase(TestCase):
|
||||
c = Condition('x', 1, 'gt')
|
||||
self.assertTrue(c.eval({'x': 2}))
|
||||
self.assertFalse(c.eval({'x': 1}))
|
||||
with self.assertRaises(InvalidCondition):
|
||||
c.eval({'x': 'foo'}) # Invalid type
|
||||
|
||||
def test_gte(self):
|
||||
c = Condition('x', 1, 'gte')
|
||||
self.assertTrue(c.eval({'x': 2}))
|
||||
self.assertTrue(c.eval({'x': 1}))
|
||||
self.assertFalse(c.eval({'x': 0}))
|
||||
with self.assertRaises(InvalidCondition):
|
||||
c.eval({'x': 'foo'}) # Invalid type
|
||||
|
||||
def test_lt(self):
|
||||
c = Condition('x', 2, 'lt')
|
||||
self.assertTrue(c.eval({'x': 1}))
|
||||
self.assertFalse(c.eval({'x': 2}))
|
||||
with self.assertRaises(InvalidCondition):
|
||||
c.eval({'x': 'foo'}) # Invalid type
|
||||
|
||||
def test_lte(self):
|
||||
c = Condition('x', 2, 'lte')
|
||||
self.assertTrue(c.eval({'x': 1}))
|
||||
self.assertTrue(c.eval({'x': 2}))
|
||||
self.assertFalse(c.eval({'x': 3}))
|
||||
with self.assertRaises(InvalidCondition):
|
||||
c.eval({'x': 'foo'}) # Invalid type
|
||||
|
||||
def test_in(self):
|
||||
c = Condition('x', [1, 2, 3], 'in')
|
||||
@@ -106,6 +115,8 @@ class ConditionTestCase(TestCase):
|
||||
c = Condition('x', 1, 'contains')
|
||||
self.assertTrue(c.eval({'x': [1, 2, 3]}))
|
||||
self.assertFalse(c.eval({'x': [2, 3, 4]}))
|
||||
with self.assertRaises(InvalidCondition):
|
||||
c.eval({'x': 123}) # Invalid type
|
||||
|
||||
def test_contains_negated(self):
|
||||
c = Condition('x', 1, 'contains', negate=True)
|
||||
|
||||
2
netbox/project-static/dist/netbox.css
vendored
2
netbox/project-static/dist/netbox.css
vendored
File diff suppressed because one or more lines are too long
10
netbox/project-static/dist/netbox.js
vendored
10
netbox/project-static/dist/netbox.js
vendored
File diff suppressed because one or more lines are too long
4
netbox/project-static/dist/netbox.js.map
vendored
4
netbox/project-static/dist/netbox.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -23,13 +23,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@mdi/font": "7.4.47",
|
||||
"@tabler/core": "1.3.2",
|
||||
"@tabler/core": "1.4.0",
|
||||
"bootstrap": "5.3.7",
|
||||
"clipboard": "2.0.11",
|
||||
"flatpickr": "4.6.13",
|
||||
"gridstack": "12.2.1",
|
||||
"htmx.org": "2.0.5",
|
||||
"query-string": "9.2.1",
|
||||
"gridstack": "12.2.2",
|
||||
"htmx.org": "2.0.6",
|
||||
"query-string": "9.2.2",
|
||||
"sass": "1.89.2",
|
||||
"tom-select": "2.4.3",
|
||||
"typeface-inter": "3.18.1",
|
||||
@@ -39,15 +39,15 @@
|
||||
"@types/bootstrap": "5.2.10",
|
||||
"@types/cookie": "^0.6.0",
|
||||
"@types/node": "^22.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.1.0",
|
||||
"@typescript-eslint/parser": "^8.1.0",
|
||||
"esbuild": "^0.25.3",
|
||||
"@typescript-eslint/eslint-plugin": "^8.37.0",
|
||||
"@typescript-eslint/parser": "^8.37.0",
|
||||
"esbuild": "^0.25.6",
|
||||
"esbuild-sass-plugin": "^3.3.1",
|
||||
"eslint": "<9.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.3",
|
||||
"eslint-plugin-import": "^2.30.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-prettier": "^5.5.1",
|
||||
"prettier": "^3.3.3",
|
||||
"typescript": "<5.5"
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,3 @@
|
||||
version: "4.3.3"
|
||||
version: "4.3.4"
|
||||
edition: "Community"
|
||||
published: "2025-06-26"
|
||||
published: "2025-07-15"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Description</th>
|
||||
<td>{{ object.description|markdown|placeholder }}</td>
|
||||
<td>{{ object.description|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Base Choices</th>
|
||||
|
||||
@@ -29,11 +29,7 @@
|
||||
<div class="hr-text">
|
||||
<span>{% trans "Custom Fields" %}</span>
|
||||
</div>
|
||||
{% for name in filter_form.custom_fields %}
|
||||
{% with field=filter_form|get_item:name %}
|
||||
{% render_field field %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
{% render_custom_fields filter_form %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,10 @@ class ContactGroupTable(NetBoxTable):
|
||||
verbose_name=_('Name'),
|
||||
linkify=True
|
||||
)
|
||||
parent = tables.Column(
|
||||
verbose_name=_('Parent'),
|
||||
linkify=True,
|
||||
)
|
||||
contact_count = columns.LinkedCountColumn(
|
||||
viewname='tenancy:contact_list',
|
||||
url_params={'group_id': 'pk'},
|
||||
@@ -34,7 +38,7 @@ class ContactGroupTable(NetBoxTable):
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = ContactGroup
|
||||
fields = (
|
||||
'pk', 'name', 'contact_count', 'description', 'comments', 'slug', 'tags', 'created',
|
||||
'pk', 'name', 'parent', 'contact_count', 'description', 'comments', 'slug', 'tags', 'created',
|
||||
'last_updated', 'actions',
|
||||
)
|
||||
default_columns = ('pk', 'name', 'contact_count', 'description')
|
||||
|
||||
@@ -16,6 +16,10 @@ class TenantGroupTable(NetBoxTable):
|
||||
verbose_name=_('Name'),
|
||||
linkify=True
|
||||
)
|
||||
parent = tables.Column(
|
||||
verbose_name=_('Parent'),
|
||||
linkify=True,
|
||||
)
|
||||
tenant_count = columns.LinkedCountColumn(
|
||||
viewname='tenancy:tenant_list',
|
||||
url_params={'group_id': 'pk'},
|
||||
@@ -31,7 +35,7 @@ class TenantGroupTable(NetBoxTable):
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = TenantGroup
|
||||
fields = (
|
||||
'pk', 'id', 'name', 'tenant_count', 'description', 'comments', 'slug', 'tags', 'created',
|
||||
'pk', 'id', 'name', 'parent', 'tenant_count', 'description', 'comments', 'slug', 'tags', 'created',
|
||||
'last_updated', 'actions',
|
||||
)
|
||||
default_columns = ('pk', 'name', 'tenant_count', 'description')
|
||||
|
||||
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 ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-07-09 05:04+0000\n"
|
||||
"POT-Creation-Date: 2025-07-15 05:05+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -1461,11 +1461,11 @@ msgstr ""
|
||||
#: netbox/core/models/jobs.py:87 netbox/dcim/models/cables.py:49
|
||||
#: netbox/dcim/models/device_components.py:456
|
||||
#: netbox/dcim/models/device_components.py:1294
|
||||
#: netbox/dcim/models/devices.py:533 netbox/dcim/models/devices.py:1138
|
||||
#: netbox/dcim/models/devices.py:555 netbox/dcim/models/devices.py:1160
|
||||
#: netbox/dcim/models/modules.py:221 netbox/dcim/models/power.py:94
|
||||
#: netbox/dcim/models/racks.py:294 netbox/dcim/models/sites.py:154
|
||||
#: netbox/dcim/models/sites.py:270 netbox/ipam/models/ip.py:237
|
||||
#: netbox/ipam/models/ip.py:511 netbox/ipam/models/ip.py:740
|
||||
#: netbox/dcim/models/sites.py:270 netbox/ipam/models/ip.py:242
|
||||
#: netbox/ipam/models/ip.py:521 netbox/ipam/models/ip.py:750
|
||||
#: netbox/ipam/models/vlans.py:217 netbox/virtualization/models/clusters.py:70
|
||||
#: netbox/virtualization/models/virtualmachines.py:79
|
||||
#: netbox/vpn/models/l2vpn.py:36 netbox/vpn/models/tunnels.py:38
|
||||
@@ -1592,8 +1592,8 @@ msgstr ""
|
||||
#: netbox/circuits/models/providers.py:98 netbox/core/models/data.py:39
|
||||
#: netbox/core/models/jobs.py:48
|
||||
#: netbox/dcim/models/device_component_templates.py:43
|
||||
#: netbox/dcim/models/device_components.py:52 netbox/dcim/models/devices.py:477
|
||||
#: netbox/dcim/models/devices.py:1070 netbox/dcim/models/devices.py:1133
|
||||
#: netbox/dcim/models/device_components.py:52 netbox/dcim/models/devices.py:499
|
||||
#: netbox/dcim/models/devices.py:1092 netbox/dcim/models/devices.py:1155
|
||||
#: netbox/dcim/models/modules.py:32 netbox/dcim/models/power.py:38
|
||||
#: netbox/dcim/models/power.py:89 netbox/dcim/models/racks.py:263
|
||||
#: netbox/dcim/models/sites.py:142 netbox/extras/models/configs.py:33
|
||||
@@ -1683,8 +1683,8 @@ msgstr ""
|
||||
msgid "virtual circuits"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/circuits/models/virtual_circuits.py:133 netbox/ipam/models/ip.py:194
|
||||
#: netbox/ipam/models/ip.py:747 netbox/vpn/models/tunnels.py:109
|
||||
#: netbox/circuits/models/virtual_circuits.py:133 netbox/ipam/models/ip.py:199
|
||||
#: netbox/ipam/models/ip.py:757 netbox/vpn/models/tunnels.py:109
|
||||
msgid "role"
|
||||
msgstr ""
|
||||
|
||||
@@ -2636,7 +2636,7 @@ msgstr ""
|
||||
msgid "File path relative to the data source's root"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/core/models/data.py:290 netbox/ipam/models/ip.py:492
|
||||
#: netbox/core/models/data.py:290 netbox/ipam/models/ip.py:502
|
||||
msgid "size"
|
||||
msgstr ""
|
||||
|
||||
@@ -3645,7 +3645,7 @@ msgstr ""
|
||||
#: netbox/dcim/filtersets.py:1164 netbox/dcim/forms/filtersets.py:838
|
||||
#: netbox/dcim/forms/filtersets.py:1463 netbox/dcim/forms/filtersets.py:1669
|
||||
#: netbox/dcim/forms/filtersets.py:1674 netbox/dcim/forms/model_forms.py:1887
|
||||
#: netbox/dcim/models/devices.py:1234 netbox/dcim/models/devices.py:1254
|
||||
#: netbox/dcim/models/devices.py:1256 netbox/dcim/models/devices.py:1276
|
||||
#: netbox/virtualization/filtersets.py:198
|
||||
#: netbox/virtualization/filtersets.py:270
|
||||
#: netbox/virtualization/forms/filtersets.py:178
|
||||
@@ -3806,8 +3806,8 @@ msgstr ""
|
||||
#: netbox/ipam/forms/model_forms.py:208 netbox/ipam/forms/model_forms.py:256
|
||||
#: netbox/ipam/forms/model_forms.py:310 netbox/ipam/forms/model_forms.py:474
|
||||
#: netbox/ipam/forms/model_forms.py:488 netbox/ipam/forms/model_forms.py:502
|
||||
#: netbox/ipam/models/ip.py:217 netbox/ipam/models/ip.py:501
|
||||
#: netbox/ipam/models/ip.py:730 netbox/ipam/models/vrfs.py:61
|
||||
#: netbox/ipam/models/ip.py:222 netbox/ipam/models/ip.py:511
|
||||
#: netbox/ipam/models/ip.py:740 netbox/ipam/models/vrfs.py:61
|
||||
#: netbox/ipam/tables/ip.py:189 netbox/ipam/tables/ip.py:262
|
||||
#: netbox/ipam/tables/ip.py:318 netbox/ipam/tables/ip.py:418
|
||||
#: netbox/templates/dcim/interface.html:152
|
||||
@@ -5417,7 +5417,7 @@ msgstr ""
|
||||
msgid "Device Role"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/forms/model_forms.py:594 netbox/dcim/models/devices.py:523
|
||||
#: netbox/dcim/forms/model_forms.py:594 netbox/dcim/models/devices.py:545
|
||||
msgid "The lowest-numbered unit occupied by the device"
|
||||
msgstr ""
|
||||
|
||||
@@ -6391,14 +6391,14 @@ msgid "inventory item roles"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/device_components.py:1321
|
||||
#: netbox/dcim/models/devices.py:486 netbox/dcim/models/modules.py:229
|
||||
#: netbox/dcim/models/devices.py:508 netbox/dcim/models/modules.py:229
|
||||
#: netbox/dcim/models/racks.py:310
|
||||
#: netbox/virtualization/models/virtualmachines.py:125
|
||||
msgid "serial number"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/device_components.py:1329
|
||||
#: netbox/dcim/models/devices.py:494 netbox/dcim/models/modules.py:236
|
||||
#: netbox/dcim/models/devices.py:516 netbox/dcim/models/modules.py:236
|
||||
#: netbox/dcim/models/racks.py:317
|
||||
msgid "asset tag"
|
||||
msgstr ""
|
||||
@@ -6494,7 +6494,7 @@ msgid ""
|
||||
"device type is neither a parent nor a child."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:131 netbox/dcim/models/devices.py:539
|
||||
#: netbox/dcim/models/devices.py:131 netbox/dcim/models/devices.py:561
|
||||
#: netbox/dcim/models/modules.py:95 netbox/dcim/models/racks.py:321
|
||||
msgid "airflow"
|
||||
msgstr ""
|
||||
@@ -6539,261 +6539,269 @@ msgstr ""
|
||||
msgid "Virtual machines may be assigned to this role"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:401
|
||||
#: netbox/dcim/models/devices.py:410
|
||||
msgid "A top-level device role with this name already exists."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:420
|
||||
msgid "A top-level device role with this slug already exists."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:423
|
||||
msgid "device role"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:402
|
||||
#: netbox/dcim/models/devices.py:424
|
||||
msgid "device roles"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:416
|
||||
#: netbox/dcim/models/devices.py:438
|
||||
msgid "Optionally limit this platform to devices of a certain manufacturer"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:428
|
||||
#: netbox/dcim/models/devices.py:450
|
||||
msgid "platform"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:429
|
||||
#: netbox/dcim/models/devices.py:451
|
||||
msgid "platforms"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:460
|
||||
#: netbox/dcim/models/devices.py:482
|
||||
msgid "The function this device serves"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:487
|
||||
#: netbox/dcim/models/devices.py:509
|
||||
msgid "Chassis serial number, assigned by the manufacturer"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:495 netbox/dcim/models/modules.py:237
|
||||
#: netbox/dcim/models/devices.py:517 netbox/dcim/models/modules.py:237
|
||||
msgid "A unique tag used to identify this device"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:522
|
||||
#: netbox/dcim/models/devices.py:544
|
||||
msgid "position (U)"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:530
|
||||
#: netbox/dcim/models/devices.py:552
|
||||
msgid "rack face"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:551 netbox/dcim/models/devices.py:1154
|
||||
#: netbox/dcim/models/devices.py:573 netbox/dcim/models/devices.py:1176
|
||||
#: netbox/virtualization/models/virtualmachines.py:94
|
||||
msgid "primary IPv4"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:559 netbox/dcim/models/devices.py:1162
|
||||
#: netbox/dcim/models/devices.py:581 netbox/dcim/models/devices.py:1184
|
||||
#: netbox/virtualization/models/virtualmachines.py:102
|
||||
msgid "primary IPv6"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:567
|
||||
#: netbox/dcim/models/devices.py:589
|
||||
msgid "out-of-band IP"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:584
|
||||
#: netbox/dcim/models/devices.py:606
|
||||
msgid "VC position"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:587
|
||||
#: netbox/dcim/models/devices.py:609
|
||||
msgid "Virtual chassis position"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:590
|
||||
#: netbox/dcim/models/devices.py:612
|
||||
msgid "VC priority"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:594
|
||||
#: netbox/dcim/models/devices.py:616
|
||||
msgid "Virtual chassis master election priority"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:597 netbox/dcim/models/sites.py:208
|
||||
#: netbox/dcim/models/devices.py:619 netbox/dcim/models/sites.py:208
|
||||
msgid "latitude"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:602 netbox/dcim/models/devices.py:610
|
||||
#: netbox/dcim/models/devices.py:624 netbox/dcim/models/devices.py:632
|
||||
#: netbox/dcim/models/sites.py:213 netbox/dcim/models/sites.py:221
|
||||
msgid "GPS coordinate in decimal format (xx.yyyyyy)"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:605 netbox/dcim/models/sites.py:216
|
||||
#: netbox/dcim/models/devices.py:627 netbox/dcim/models/sites.py:216
|
||||
msgid "longitude"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:684
|
||||
#: netbox/dcim/models/devices.py:706
|
||||
msgid "Device name must be unique per site."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:695
|
||||
#: netbox/dcim/models/devices.py:717
|
||||
msgid "device"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:696
|
||||
#: netbox/dcim/models/devices.py:718
|
||||
msgid "devices"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:715
|
||||
#: netbox/dcim/models/devices.py:737
|
||||
#, python-brace-format
|
||||
msgid "Rack {rack} does not belong to site {site}."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:720
|
||||
#: netbox/dcim/models/devices.py:742
|
||||
#, python-brace-format
|
||||
msgid "Location {location} does not belong to site {site}."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:726
|
||||
#: netbox/dcim/models/devices.py:748
|
||||
#, python-brace-format
|
||||
msgid "Rack {rack} does not belong to location {location}."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:733
|
||||
#: netbox/dcim/models/devices.py:755
|
||||
msgid "Cannot select a rack face without assigning a rack."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:737
|
||||
#: netbox/dcim/models/devices.py:759
|
||||
msgid "Cannot select a rack position without assigning a rack."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:743
|
||||
#: netbox/dcim/models/devices.py:765
|
||||
msgid "Position must be in increments of 0.5 rack units."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:747
|
||||
#: netbox/dcim/models/devices.py:769
|
||||
msgid "Must specify rack face when defining rack position."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:755
|
||||
#: netbox/dcim/models/devices.py:777
|
||||
#, python-brace-format
|
||||
msgid "A 0U device type ({device_type}) cannot be assigned to a rack position."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:766
|
||||
#: netbox/dcim/models/devices.py:788
|
||||
msgid ""
|
||||
"Child device types cannot be assigned to a rack face. This is an attribute "
|
||||
"of the parent device."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:773
|
||||
#: netbox/dcim/models/devices.py:795
|
||||
msgid ""
|
||||
"Child device types cannot be assigned to a rack position. This is an "
|
||||
"attribute of the parent device."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:787
|
||||
#: netbox/dcim/models/devices.py:809
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"U{position} is already occupied or does not have sufficient space to "
|
||||
"accommodate this device type: {device_type} ({u_height}U)"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:802
|
||||
#: netbox/dcim/models/devices.py:824
|
||||
#, python-brace-format
|
||||
msgid "{ip} is not an IPv4 address."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:814 netbox/dcim/models/devices.py:832
|
||||
#: netbox/dcim/models/devices.py:836 netbox/dcim/models/devices.py:854
|
||||
#, python-brace-format
|
||||
msgid "The specified IP address ({ip}) is not assigned to this device."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:820
|
||||
#: netbox/dcim/models/devices.py:842
|
||||
#, python-brace-format
|
||||
msgid "{ip} is not an IPv6 address."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:850
|
||||
#: netbox/dcim/models/devices.py:872
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"The assigned platform is limited to {platform_manufacturer} device types, "
|
||||
"but this device's type belongs to {devicetype_manufacturer}."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:861
|
||||
#: netbox/dcim/models/devices.py:883
|
||||
#, python-brace-format
|
||||
msgid "The assigned cluster belongs to a different site ({site})"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:868
|
||||
#: netbox/dcim/models/devices.py:890
|
||||
#, python-brace-format
|
||||
msgid "The assigned cluster belongs to a different location ({location})"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:876
|
||||
#: netbox/dcim/models/devices.py:898
|
||||
msgid "A device assigned to a virtual chassis must have its position defined."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:882
|
||||
#: netbox/dcim/models/devices.py:904
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Device cannot be removed from virtual chassis {virtual_chassis} because it "
|
||||
"is currently designated as its master."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1075
|
||||
#: netbox/dcim/models/devices.py:1097
|
||||
msgid "domain"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1088 netbox/dcim/models/devices.py:1089
|
||||
#: netbox/dcim/models/devices.py:1110 netbox/dcim/models/devices.py:1111
|
||||
msgid "virtual chassis"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1101
|
||||
#: netbox/dcim/models/devices.py:1123
|
||||
#, python-brace-format
|
||||
msgid "The selected master ({master}) is not assigned to this virtual chassis."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1117
|
||||
#: netbox/dcim/models/devices.py:1139
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Unable to delete virtual chassis {self}. There are member interfaces which "
|
||||
"form a cross-chassis LAG interfaces."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1143 netbox/vpn/models/l2vpn.py:42
|
||||
#: netbox/dcim/models/devices.py:1165 netbox/vpn/models/l2vpn.py:42
|
||||
msgid "identifier"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1144
|
||||
#: netbox/dcim/models/devices.py:1166
|
||||
msgid "Numeric identifier unique to the parent device"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1172 netbox/extras/models/customfields.py:227
|
||||
#: netbox/dcim/models/devices.py:1194 netbox/extras/models/customfields.py:227
|
||||
#: netbox/extras/models/models.py:109 netbox/extras/models/models.py:767
|
||||
#: netbox/netbox/models/__init__.py:120 netbox/netbox/models/__init__.py:155
|
||||
msgid "comments"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1188
|
||||
#: netbox/dcim/models/devices.py:1210
|
||||
msgid "virtual device context"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1189
|
||||
#: netbox/dcim/models/devices.py:1211
|
||||
msgid "virtual device contexts"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1218
|
||||
#: netbox/dcim/models/devices.py:1240
|
||||
#, python-brace-format
|
||||
msgid "{ip} is not an IPv{family} address."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1224
|
||||
#: netbox/dcim/models/devices.py:1246
|
||||
msgid "Primary IP address must belong to an interface on the assigned device."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1255
|
||||
#: netbox/dcim/models/devices.py:1277
|
||||
msgid "MAC addresses"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1287
|
||||
#: netbox/dcim/models/devices.py:1309
|
||||
msgid ""
|
||||
"Cannot unassign MAC Address while it is designated as the primary MAC for an "
|
||||
"object"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:1291
|
||||
#: netbox/dcim/models/devices.py:1313
|
||||
msgid ""
|
||||
"Cannot reassign MAC Address while it is designated as the primary MAC for an "
|
||||
"object"
|
||||
@@ -8656,7 +8664,7 @@ msgstr ""
|
||||
#: netbox/extras/models/configs.py:38 netbox/extras/models/models.py:315
|
||||
#: netbox/extras/models/models.py:480 netbox/extras/models/models.py:559
|
||||
#: netbox/extras/models/search.py:48 netbox/extras/models/tags.py:44
|
||||
#: netbox/ipam/models/ip.py:188 netbox/netbox/models/mixins.py:16
|
||||
#: netbox/ipam/models/ip.py:193 netbox/netbox/models/mixins.py:16
|
||||
msgid "weight"
|
||||
msgstr ""
|
||||
|
||||
@@ -9903,7 +9911,7 @@ msgstr ""
|
||||
msgid "IP address (ID)"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/filtersets.py:1205 netbox/ipam/models/ip.py:798
|
||||
#: netbox/ipam/filtersets.py:1205 netbox/ipam/models/ip.py:808
|
||||
msgid "IP address"
|
||||
msgstr ""
|
||||
|
||||
@@ -10012,7 +10020,7 @@ msgstr ""
|
||||
|
||||
#: netbox/ipam/forms/bulk_edit.py:257 netbox/ipam/forms/bulk_edit.py:307
|
||||
#: netbox/ipam/forms/filtersets.py:258 netbox/ipam/forms/filtersets.py:316
|
||||
#: netbox/ipam/models/ip.py:256
|
||||
#: netbox/ipam/models/ip.py:261
|
||||
msgid "Treat as fully utilized"
|
||||
msgstr ""
|
||||
|
||||
@@ -10025,7 +10033,7 @@ msgstr ""
|
||||
msgid "Treat as populated"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/forms/bulk_edit.py:355 netbox/ipam/models/ip.py:782
|
||||
#: netbox/ipam/forms/bulk_edit.py:355 netbox/ipam/models/ip.py:792
|
||||
msgid "DNS name"
|
||||
msgstr ""
|
||||
|
||||
@@ -10532,185 +10540,185 @@ msgid ""
|
||||
"({aggregate})."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:195
|
||||
#: netbox/ipam/models/ip.py:200
|
||||
msgid "roles"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:208 netbox/ipam/models/ip.py:277
|
||||
#: netbox/ipam/models/ip.py:213 netbox/ipam/models/ip.py:282
|
||||
msgid "prefix"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:209
|
||||
#: netbox/ipam/models/ip.py:214
|
||||
msgid "IPv4 or IPv6 network with mask"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:238
|
||||
#: netbox/ipam/models/ip.py:243
|
||||
msgid "Operational status of this prefix"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:246
|
||||
#: netbox/ipam/models/ip.py:251
|
||||
msgid "The primary function of this prefix"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:249
|
||||
#: netbox/ipam/models/ip.py:254
|
||||
msgid "is a pool"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:251
|
||||
#: netbox/ipam/models/ip.py:256
|
||||
msgid "All IP addresses within this prefix are considered usable"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:254 netbox/ipam/models/ip.py:531
|
||||
#: netbox/ipam/models/ip.py:259 netbox/ipam/models/ip.py:541
|
||||
msgid "mark utilized"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:278
|
||||
#: netbox/ipam/models/ip.py:283
|
||||
msgid "prefixes"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:298
|
||||
#: netbox/ipam/models/ip.py:303
|
||||
msgid "Cannot create prefix with /0 mask."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:305 netbox/ipam/models/ip.py:881
|
||||
#: netbox/ipam/models/ip.py:310 netbox/ipam/models/ip.py:896
|
||||
#, python-brace-format
|
||||
msgid "VRF {vrf}"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:305 netbox/ipam/models/ip.py:881
|
||||
#: netbox/ipam/models/ip.py:310 netbox/ipam/models/ip.py:896
|
||||
msgid "global table"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:307
|
||||
#: netbox/ipam/models/ip.py:312
|
||||
#, python-brace-format
|
||||
msgid "Duplicate prefix found in {table}: {prefix}"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:484
|
||||
#: netbox/ipam/models/ip.py:494
|
||||
msgid "start address"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:485 netbox/ipam/models/ip.py:489
|
||||
#: netbox/ipam/models/ip.py:722
|
||||
#: netbox/ipam/models/ip.py:495 netbox/ipam/models/ip.py:499
|
||||
#: netbox/ipam/models/ip.py:732
|
||||
msgid "IPv4 or IPv6 address (with mask)"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:488
|
||||
#: netbox/ipam/models/ip.py:498
|
||||
msgid "end address"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:515
|
||||
#: netbox/ipam/models/ip.py:525
|
||||
msgid "Operational status of this range"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:523
|
||||
#: netbox/ipam/models/ip.py:533
|
||||
msgid "The primary function of this range"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:526
|
||||
#: netbox/ipam/models/ip.py:536
|
||||
msgid "mark populated"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:528
|
||||
#: netbox/ipam/models/ip.py:538
|
||||
msgid "Prevent the creation of IP addresses within this range"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:533
|
||||
#: netbox/ipam/models/ip.py:543
|
||||
#, python-format
|
||||
msgid "Report space as 100% utilized"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:542
|
||||
#: netbox/ipam/models/ip.py:552
|
||||
msgid "IP range"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:543
|
||||
#: netbox/ipam/models/ip.py:553
|
||||
msgid "IP ranges"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:556
|
||||
#: netbox/ipam/models/ip.py:566
|
||||
msgid "Starting and ending IP address versions must match"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:562
|
||||
#: netbox/ipam/models/ip.py:572
|
||||
msgid "Starting and ending IP address masks must match"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:569
|
||||
#: netbox/ipam/models/ip.py:579
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Ending address must be greater than the starting address ({start_address})"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:597
|
||||
#: netbox/ipam/models/ip.py:607
|
||||
#, python-brace-format
|
||||
msgid "Defined addresses overlap with range {overlapping_range} in VRF {vrf}"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:606
|
||||
#: netbox/ipam/models/ip.py:616
|
||||
#, python-brace-format
|
||||
msgid "Defined range exceeds maximum supported size ({max_size})"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:721 netbox/tenancy/models/contacts.py:76
|
||||
#: netbox/ipam/models/ip.py:731 netbox/tenancy/models/contacts.py:76
|
||||
msgid "address"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:744
|
||||
#: netbox/ipam/models/ip.py:754
|
||||
msgid "The operational status of this IP"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:752
|
||||
#: netbox/ipam/models/ip.py:762
|
||||
msgid "The functional role of this IP"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:775 netbox/templates/ipam/ipaddress.html:72
|
||||
#: netbox/ipam/models/ip.py:785 netbox/templates/ipam/ipaddress.html:72
|
||||
msgid "NAT (inside)"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:776
|
||||
#: netbox/ipam/models/ip.py:786
|
||||
msgid "The IP for which this address is the \"outside\" IP"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:783
|
||||
#: netbox/ipam/models/ip.py:793
|
||||
msgid "Hostname or FQDN (not case-sensitive)"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:799 netbox/ipam/models/services.py:86
|
||||
#: netbox/ipam/models/ip.py:809 netbox/ipam/models/services.py:86
|
||||
msgid "IP addresses"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:852
|
||||
#: netbox/ipam/models/ip.py:867
|
||||
msgid "Cannot create IP address with /0 mask."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:858
|
||||
#: netbox/ipam/models/ip.py:873
|
||||
#, python-brace-format
|
||||
msgid "{ip} is a network ID, which may not be assigned to an interface."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:869
|
||||
#: netbox/ipam/models/ip.py:884
|
||||
#, python-brace-format
|
||||
msgid "{ip} is a broadcast address, which may not be assigned to an interface."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:883
|
||||
#: netbox/ipam/models/ip.py:898
|
||||
#, python-brace-format
|
||||
msgid "Duplicate IP address found in {table}: {ipaddress}"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:899
|
||||
#: netbox/ipam/models/ip.py:914
|
||||
#, python-brace-format
|
||||
msgid "Cannot create IP address {ip} inside range {range}."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:920
|
||||
#: netbox/ipam/models/ip.py:935
|
||||
msgid ""
|
||||
"Cannot reassign IP address while it is designated as the primary IP for the "
|
||||
"parent object"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/ipam/models/ip.py:926
|
||||
#: netbox/ipam/models/ip.py:941
|
||||
msgid "Only IPv6 addresses can be assigned SLAAC status"
|
||||
msgstr ""
|
||||
|
||||
@@ -11863,16 +11871,16 @@ msgstr ""
|
||||
msgid "Background Tasks"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/netbox/plugins/navigation.py:48
|
||||
#: netbox/netbox/plugins/navigation.py:70
|
||||
#: netbox/netbox/plugins/navigation.py:55
|
||||
#: netbox/netbox/plugins/navigation.py:88
|
||||
msgid "Permissions must be passed as a tuple or list."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/netbox/plugins/navigation.py:52
|
||||
#: netbox/netbox/plugins/navigation.py:59
|
||||
msgid "Buttons must be passed as a tuple or list."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/netbox/plugins/navigation.py:74
|
||||
#: netbox/netbox/plugins/navigation.py:92
|
||||
msgid "Button color must be a choice within ButtonColorChoices."
|
||||
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
@@ -18,6 +18,10 @@ class WirelessLANGroupTable(NetBoxTable):
|
||||
verbose_name=_('Name'),
|
||||
linkify=True
|
||||
)
|
||||
parent = tables.Column(
|
||||
verbose_name=_('Parent'),
|
||||
linkify=True,
|
||||
)
|
||||
wirelesslan_count = columns.LinkedCountColumn(
|
||||
viewname='wireless:wirelesslan_list',
|
||||
url_params={'group_id': 'pk'},
|
||||
@@ -33,8 +37,8 @@ class WirelessLANGroupTable(NetBoxTable):
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = WirelessLANGroup
|
||||
fields = (
|
||||
'pk', 'name', 'wirelesslan_count', 'slug', 'description', 'comments', 'tags', 'created', 'last_updated',
|
||||
'actions',
|
||||
'pk', 'name', 'parent', 'slug', 'description', 'comments', 'tags', 'wirelesslan_count', 'created',
|
||||
'last_updated', 'actions',
|
||||
)
|
||||
default_columns = ('pk', 'name', 'wirelesslan_count', 'description')
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[project]
|
||||
name = "netbox"
|
||||
version = "4.3.3"
|
||||
version = "4.3.4"
|
||||
requires-python = ">=3.10"
|
||||
authors = [
|
||||
{ name = "NetBox Community" }
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Django==5.2.3
|
||||
Django==5.2.4
|
||||
django-cors-headers==4.7.0
|
||||
django-debug-toolbar==5.2.0
|
||||
django-filter==25.1
|
||||
django-htmx==1.23.1
|
||||
django-graphiql-debug-toolbar==0.2.0
|
||||
django-htmx==1.23.2
|
||||
django-mptt==0.17.0
|
||||
django-pglocks==1.0.4
|
||||
django-prometheus==2.4.1
|
||||
@@ -11,29 +11,29 @@ django-redis==6.0.0
|
||||
django-rich==2.0.0
|
||||
django-rq==3.0.1
|
||||
django-storages==1.14.6
|
||||
django-taggit==6.1.0
|
||||
django-tables2==2.7.5
|
||||
django-taggit==6.1.0
|
||||
django-timezone-field==7.1
|
||||
djangorestframework==3.16.0
|
||||
drf-spectacular==0.28.0
|
||||
drf-spectacular-sidecar==2025.6.1
|
||||
drf-spectacular-sidecar==2025.7.1
|
||||
feedparser==6.0.11
|
||||
gunicorn==23.0.0
|
||||
Jinja2==3.1.6
|
||||
jsonschema==4.24.0
|
||||
Markdown==3.8.2
|
||||
mkdocs-material==9.6.14
|
||||
mkdocs-material==9.6.15
|
||||
mkdocstrings[python]==0.29.1
|
||||
netaddr==1.3.0
|
||||
nh3==0.2.21
|
||||
Pillow==11.2.1
|
||||
nh3==0.2.22
|
||||
Pillow==11.3.0
|
||||
psycopg[c,pool]==3.2.9
|
||||
PyYAML==6.0.2
|
||||
requests==2.32.4
|
||||
rq==2.4.0
|
||||
social-auth-app-django==5.4.3
|
||||
social-auth-core==4.6.1
|
||||
strawberry-graphql==0.275.4
|
||||
social-auth-app-django==5.5.1
|
||||
social-auth-core==4.7.0
|
||||
strawberry-graphql==0.276.0
|
||||
strawberry-graphql-django==0.60.0
|
||||
svgwrite==1.4.3
|
||||
tablib==3.8.0
|
||||
|
||||
Reference in New Issue
Block a user