mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-31 17:47:45 -06:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f845b2cf07 | ||
|
|
2ed4a2b005 | ||
|
|
5b9210dfa5 | ||
|
|
4a13664e0f | ||
|
|
a9f3c74b0c | ||
|
|
50b7f46fc0 | ||
|
|
07ad4c1321 | ||
|
|
4a1fea3504 | ||
|
|
993d8f1480 | ||
|
|
c3efa2149c | ||
|
|
a75fa53d4d | ||
|
|
e75d327f38 | ||
|
|
a79d869bd8 | ||
|
|
32422d1683 | ||
|
|
571f604ce8 | ||
|
|
b12c8c880f | ||
|
|
b11f179527 | ||
|
|
80e1fd02bb | ||
|
|
4090afbf24 | ||
|
|
d04fc11c61 | ||
|
|
f6b8c1966d | ||
|
|
4456c488f1 | ||
|
|
53aa2c8624 | ||
|
|
ffac0974dd | ||
|
|
e518f08604 | ||
|
|
4ae5529362 | ||
|
|
ef6c89ee5d | ||
|
|
9c960c2387 | ||
|
|
ed541220e8 | ||
|
|
14cec518f5 |
15
.github/ISSUE_TEMPLATE/01-feature_request.yaml
vendored
15
.github/ISSUE_TEMPLATE/01-feature_request.yaml
vendored
@@ -14,7 +14,7 @@ body:
|
||||
attributes:
|
||||
label: NetBox version
|
||||
description: What version of NetBox are you currently running?
|
||||
placeholder: v4.2.0
|
||||
placeholder: v4.2.2
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
@@ -27,19 +27,6 @@ body:
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Triage priority
|
||||
description: >
|
||||
Issue triage may be prioritized in some cases. Select whichever of the following
|
||||
conditions applies, if any.
|
||||
options:
|
||||
- I volunteer to perform this work (if approved)
|
||||
- I'm a NetBox Labs customer
|
||||
- N/A
|
||||
default: 2
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Proposed functionality
|
||||
|
||||
15
.github/ISSUE_TEMPLATE/02-bug_report.yaml
vendored
15
.github/ISSUE_TEMPLATE/02-bug_report.yaml
vendored
@@ -22,24 +22,11 @@ body:
|
||||
- Self-hosted
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Triage priority
|
||||
description: >
|
||||
Issue triage may be prioritized in some cases. Select whichever of the following
|
||||
conditions applies, if any.
|
||||
options:
|
||||
- I volunteer to perform this work (if approved)
|
||||
- I'm a NetBox Labs customer
|
||||
- N/A
|
||||
default: 2
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: NetBox Version
|
||||
description: What version of NetBox are you currently running?
|
||||
placeholder: v4.2.0
|
||||
placeholder: v4.2.2
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
|
||||
@@ -8,8 +8,6 @@ django-cors-headers
|
||||
|
||||
# Runtime UI tool for debugging Django
|
||||
# https://github.com/jazzband/django-debug-toolbar/blob/main/docs/changes.rst
|
||||
# Pinned for DNS looukp bug; see https://github.com/netbox-community/netbox/issues/16454
|
||||
# and https://github.com/jazzband/django-debug-toolbar/issues/1927
|
||||
django-debug-toolbar
|
||||
|
||||
# Library for writing reusable URL query filters
|
||||
@@ -134,7 +132,8 @@ strawberry-graphql
|
||||
|
||||
# Strawberry GraphQL Django extension
|
||||
# https://github.com/strawberry-graphql/strawberry-django/releases
|
||||
strawberry-graphql-django
|
||||
# Pinned to v0.52.0 for suspected upstream bug; see #18329
|
||||
strawberry-graphql-django==0.52.0
|
||||
|
||||
# SVG image rendering (used for rack elevations)
|
||||
# https://github.com/mozman/svgwrite/blob/master/NEWS.rst
|
||||
|
||||
@@ -25,7 +25,7 @@ ALLOWED_HOSTS = ['*']
|
||||
|
||||
## DATABASE
|
||||
|
||||
NetBox requires access to a PostgreSQL 12 or later database service to store data. This service can run locally on the NetBox server or on a remote system. The following parameters must be defined within the `DATABASE` dictionary:
|
||||
NetBox requires access to a PostgreSQL 13 or later database service to store data. This service can run locally on the NetBox server or on a remote system. The following parameters must be defined within the `DATABASE` dictionary:
|
||||
|
||||
* `NAME` - Database name
|
||||
* `USER` - PostgreSQL username
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
This section entails the installation and configuration of a local PostgreSQL database. If you already have a PostgreSQL database service in place, skip to [the next section](2-redis.md).
|
||||
|
||||
!!! warning "PostgreSQL 12 or later required"
|
||||
NetBox requires PostgreSQL 12 or later. Please note that MySQL and other relational databases are **not** supported.
|
||||
!!! warning "PostgreSQL 13 or later required"
|
||||
NetBox requires PostgreSQL 13 or later. Please note that MySQL and other relational databases are **not** supported.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -34,7 +34,7 @@ This section entails the installation and configuration of a local PostgreSQL da
|
||||
sudo systemctl enable --now postgresql
|
||||
```
|
||||
|
||||
Before continuing, verify that you have installed PostgreSQL 12 or later:
|
||||
Before continuing, verify that you have installed PostgreSQL 13 or later:
|
||||
|
||||
```no-highlight
|
||||
psql -V
|
||||
|
||||
@@ -21,7 +21,7 @@ The following sections detail how to set up a new instance of NetBox:
|
||||
| Dependency | Supported Versions |
|
||||
|------------|--------------------|
|
||||
| Python | 3.10, 3.11, 3.12 |
|
||||
| PostgreSQL | 12+ |
|
||||
| PostgreSQL | 13+ |
|
||||
| Redis | 4.0+ |
|
||||
|
||||
Below is a simplified overview of the NetBox application stack for reference:
|
||||
|
||||
@@ -20,7 +20,7 @@ NetBox requires the following dependencies:
|
||||
| Dependency | Supported Versions |
|
||||
|------------|--------------------|
|
||||
| Python | 3.10, 3.11, 3.12 |
|
||||
| PostgreSQL | 12+ |
|
||||
| PostgreSQL | 13+ |
|
||||
| Redis | 4.0+ |
|
||||
|
||||
## 3. Install the Latest Release
|
||||
|
||||
@@ -79,5 +79,5 @@ NetBox is built on the [Django](https://djangoproject.com/) Python framework and
|
||||
| HTTP service | nginx or Apache |
|
||||
| WSGI service | gunicorn or uWSGI |
|
||||
| Application | Django/Python |
|
||||
| Database | PostgreSQL 12+ |
|
||||
| Database | PostgreSQL 13+ |
|
||||
| Task queuing | Redis/django-rq |
|
||||
|
||||
@@ -1,10 +1,44 @@
|
||||
# NetBox v4.2
|
||||
|
||||
## v4.2.2 (2025-01-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* [#18336](https://github.com/netbox-community/netbox/issues/18336) - Validate new rack height against installed devices when changing a rack's type
|
||||
* [#18350](https://github.com/netbox-community/netbox/issues/18350) - Fix `FieldDoesNotExist` exception when global search results include a circuit termination
|
||||
* [#18353](https://github.com/netbox-community/netbox/issues/18353) - Disable fetching of plugin catalog data when `ISOLATED_DEPLOYMENT` is enabled
|
||||
* [#18362](https://github.com/netbox-community/netbox/issues/18362) - Avoid transmitting census data on every worker restart
|
||||
* [#18363](https://github.com/netbox-community/netbox/issues/18363) - Fix support for assigning a MAC address to an interface via the REST API
|
||||
* [#18368](https://github.com/netbox-community/netbox/issues/18368) - Restore missing attributes from REST API serializer for MAC addresses (`tags`, `created`, `last_updated`, and custom fields)
|
||||
* [#18369](https://github.com/netbox-community/netbox/issues/18369) - Fix `TypeError` exception when rendering the system configuration view with one or more custom classes defined under `PROTECTION_RULES`
|
||||
* [#18373](https://github.com/netbox-community/netbox/issues/18373) - Fix `AttributeError` exception when attempting to assign host devices to a cluster
|
||||
* [#18376](https://github.com/netbox-community/netbox/issues/18376) - Fix the display of tagged VLANs in interfaces list for Q-in-Q interfaces
|
||||
* [#18379](https://github.com/netbox-community/netbox/issues/18379) - Ensure RSS feed dashboard widget content is sanitized
|
||||
* [#18392](https://github.com/netbox-community/netbox/issues/18392) - Virtual machines should not inherit config contexts assigned to locations
|
||||
* [#18400](https://github.com/netbox-community/netbox/issues/18400) - Fix support for `STORAGE_BACKEND` configuration parameter
|
||||
* [#18406](https://github.com/netbox-community/netbox/issues/18406) - Scope column headers in object lists should not be orderable
|
||||
|
||||
---
|
||||
|
||||
## v4.2.1 (2025-01-08)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* [#18282](https://github.com/netbox-community/netbox/issues/18282) - Fix ordering of prefixes list by assigned VLAN
|
||||
* [#18314](https://github.com/netbox-community/netbox/issues/18314) - Fix KeyError exception when rendering pre-saved dashboard (`requires_internet` missing)
|
||||
* [#18316](https://github.com/netbox-community/netbox/issues/18316) - Fix AttributeError exception when global search results include prefixes and/or clusters
|
||||
* [#18318](https://github.com/netbox-community/netbox/issues/18318) - Correct navigation breadcrumbs for module type UI view
|
||||
* [#18324](https://github.com/netbox-community/netbox/issues/18324) - Correct filtering for certain related object listings
|
||||
* [#18329](https://github.com/netbox-community/netbox/issues/18329) - Address upstream bug in GraphQL API where only one primary IP address is returned within a device/VM list
|
||||
|
||||
---
|
||||
|
||||
## v4.2.0 (2025-01-06)
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Support for the Django admin UI has been completely removed. (The Django admin UI was disabled by default in NetBox v4.0.)
|
||||
* This release drops support for PostgreSQL 12. PostgreSQL 13 or later is required to run this release.
|
||||
* NetBox has adopted collation-based natural ordering for many models. This may alter the order in which some objects are listed by default.
|
||||
* Automatic redirects from pre-v4.1 UI views for virtual disks have been removed.
|
||||
* The `site` and `provider_network` foreign key fields on `circuits.CircuitTermination` have been replaced by the `termination` generic foreign key.
|
||||
|
||||
@@ -34,7 +34,7 @@ class CircuitTerminationIndex(SearchIndex):
|
||||
('port_speed', 2000),
|
||||
('upstream_speed', 2000),
|
||||
)
|
||||
display_attrs = ('circuit', 'site', 'provider_network', 'description')
|
||||
display_attrs = ('circuit', 'termination', 'description')
|
||||
|
||||
|
||||
@register_search
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import logging
|
||||
import requests
|
||||
import sys
|
||||
|
||||
from netbox.jobs import JobRunner
|
||||
from django.conf import settings
|
||||
from netbox.jobs import JobRunner, system_job
|
||||
from netbox.search.backends import search_backend
|
||||
from .choices import DataSourceStatusChoices
|
||||
from .choices import DataSourceStatusChoices, JobIntervalChoices
|
||||
from .exceptions import SyncError
|
||||
from .models import DataSource
|
||||
|
||||
@@ -31,3 +34,44 @@ class SyncDataSourceJob(JobRunner):
|
||||
if type(e) is SyncError:
|
||||
logging.error(e)
|
||||
raise e
|
||||
|
||||
|
||||
@system_job(interval=JobIntervalChoices.INTERVAL_DAILY)
|
||||
class SystemHousekeepingJob(JobRunner):
|
||||
"""
|
||||
Perform daily system housekeeping functions.
|
||||
"""
|
||||
class Meta:
|
||||
name = "System Housekeeping"
|
||||
|
||||
def run(self, *args, **kwargs):
|
||||
# Skip if running in development or test mode
|
||||
if settings.DEBUG or 'test' in sys.argv:
|
||||
return
|
||||
|
||||
# TODO: Migrate other housekeeping functions from the `housekeeping` management command.
|
||||
self.send_census_report()
|
||||
|
||||
@staticmethod
|
||||
def send_census_report():
|
||||
"""
|
||||
Send a census report (if enabled).
|
||||
"""
|
||||
# Skip if census reporting is disabled
|
||||
if settings.ISOLATED_DEPLOYMENT or not settings.CENSUS_REPORTING_ENABLED:
|
||||
return
|
||||
|
||||
census_data = {
|
||||
'version': settings.RELEASE.full_version,
|
||||
'python_version': sys.version.split()[0],
|
||||
'deployment_id': settings.DEPLOYMENT_ID,
|
||||
}
|
||||
try:
|
||||
requests.get(
|
||||
url=settings.CENSUS_URL,
|
||||
params=census_data,
|
||||
timeout=3,
|
||||
proxies=settings.HTTP_PROXIES
|
||||
)
|
||||
except requests.exceptions.RequestException:
|
||||
pass
|
||||
|
||||
@@ -570,8 +570,9 @@ class SystemView(UserPassesTestMixin, View):
|
||||
return response
|
||||
|
||||
# Serialize any CustomValidator classes
|
||||
if hasattr(config, 'CUSTOM_VALIDATORS') and config.CUSTOM_VALIDATORS:
|
||||
config.CUSTOM_VALIDATORS = json.dumps(config.CUSTOM_VALIDATORS, cls=ConfigJSONEncoder, indent=4)
|
||||
for attr in ['CUSTOM_VALIDATORS', 'PROTECTION_RULES']:
|
||||
if hasattr(config, attr) and getattr(config, attr, None):
|
||||
setattr(config, attr, json.dumps(getattr(config, attr), cls=ConfigJSONEncoder, indent=4))
|
||||
|
||||
return render(request, 'core/system.html', {
|
||||
'stats': stats,
|
||||
@@ -594,7 +595,7 @@ class BasePluginView(UserPassesTestMixin, View):
|
||||
catalog_plugins_error = cache.get(self.CACHE_KEY_CATALOG_ERROR, default=False)
|
||||
if not catalog_plugins_error:
|
||||
catalog_plugins = get_catalog_plugins()
|
||||
if not catalog_plugins:
|
||||
if not catalog_plugins and not settings.ISOLATED_DEPLOYMENT:
|
||||
# Cache for 5 minutes to avoid spamming connection
|
||||
cache.set(self.CACHE_KEY_CATALOG_ERROR, True, 300)
|
||||
messages.warning(request, _("Plugins catalog could not be loaded"))
|
||||
|
||||
@@ -170,8 +170,8 @@ class MACAddressSerializer(NetBoxModelSerializer):
|
||||
class Meta:
|
||||
model = MACAddress
|
||||
fields = [
|
||||
'id', 'url', 'display_url', 'display', 'mac_address', 'assigned_object_type', 'assigned_object',
|
||||
'description', 'comments',
|
||||
'id', 'url', 'display_url', 'display', 'mac_address', 'assigned_object_type', 'assigned_object_id',
|
||||
'assigned_object', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
|
||||
]
|
||||
brief_fields = ('id', 'url', 'display', 'mac_address', 'description')
|
||||
|
||||
|
||||
@@ -374,22 +374,27 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, RackBase):
|
||||
if not self._state.adding:
|
||||
mounted_devices = Device.objects.filter(rack=self).exclude(position__isnull=True).order_by('position')
|
||||
|
||||
effective_u_height = self.rack_type.u_height if self.rack_type else self.u_height
|
||||
effective_starting_unit = self.rack_type.starting_unit if self.rack_type else self.starting_unit
|
||||
|
||||
# Validate that Rack is tall enough to house the highest mounted Device
|
||||
if top_device := mounted_devices.last():
|
||||
min_height = top_device.position + top_device.device_type.u_height - self.starting_unit
|
||||
if self.u_height < min_height:
|
||||
min_height = top_device.position + top_device.device_type.u_height - effective_starting_unit
|
||||
if effective_u_height < min_height:
|
||||
field = 'rack_type' if self.rack_type else 'u_height'
|
||||
raise ValidationError({
|
||||
'u_height': _(
|
||||
field: _(
|
||||
"Rack must be at least {min_height}U tall to house currently installed devices."
|
||||
).format(min_height=min_height)
|
||||
})
|
||||
|
||||
# Validate that the Rack's starting unit is less than or equal to the position of the lowest mounted Device
|
||||
if last_device := mounted_devices.first():
|
||||
if self.starting_unit > last_device.position:
|
||||
if effective_starting_unit > last_device.position:
|
||||
field = 'rack_type' if self.rack_type else 'starting_unit'
|
||||
raise ValidationError({
|
||||
'starting_unit': _("Rack unit numbering must begin at {position} or less to house "
|
||||
"currently installed devices.").format(position=last_device.position)
|
||||
field: _("Rack unit numbering must begin at {position} or less to house "
|
||||
"currently installed devices.").format(position=last_device.position)
|
||||
})
|
||||
|
||||
# Validate that Rack was assigned a Location of its same site, if applicable
|
||||
|
||||
@@ -69,16 +69,18 @@ INTERFACE_FHRPGROUPS = """
|
||||
"""
|
||||
|
||||
INTERFACE_TAGGED_VLANS = """
|
||||
{% if record.mode == 'tagged' %}
|
||||
{% load i18n %}
|
||||
{% if record.mode == 'access' %}
|
||||
{% elif record.mode == 'tagged-all' %}
|
||||
{% trans "All" %}
|
||||
{% else %}
|
||||
{% if value.count > 3 %}
|
||||
<a href="{% url 'ipam:vlan_list' %}?{{ record|meta:"model_name" }}_id={{ record.pk }}">{{ value.count }} VLANs</a>
|
||||
{% else %}
|
||||
{% for vlan in value.all %}
|
||||
<a href="{{ vlan.get_absolute_url }}">{{ vlan }}</a><br />
|
||||
<a href="{{ vlan.get_absolute_url }}">{{ vlan }}</a><br />
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% elif record.mode == 'tagged-all' %}
|
||||
All
|
||||
{% endif %}
|
||||
"""
|
||||
|
||||
|
||||
@@ -2447,3 +2447,46 @@ class VirtualDeviceContextTest(APIViewTestCases.APIViewTestCase):
|
||||
# Omit identifier to test uniqueness constraint
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class MACAddressTest(APIViewTestCases.APIViewTestCase):
|
||||
model = MACAddress
|
||||
brief_fields = ['description', 'display', 'id', 'mac_address', 'url']
|
||||
bulk_update_data = {
|
||||
'description': 'New description',
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
device = create_test_device(name='Device 1')
|
||||
interfaces = (
|
||||
Interface(device=device, name='Interface 1', type='1000base-t'),
|
||||
Interface(device=device, name='Interface 2', type='1000base-t'),
|
||||
Interface(device=device, name='Interface 3', type='1000base-t'),
|
||||
Interface(device=device, name='Interface 4', type='1000base-t'),
|
||||
Interface(device=device, name='Interface 5', type='1000base-t'),
|
||||
)
|
||||
Interface.objects.bulk_create(interfaces)
|
||||
|
||||
mac_addresses = (
|
||||
MACAddress(mac_address='00:00:00:00:00:01', assigned_object=interfaces[0]),
|
||||
MACAddress(mac_address='00:00:00:00:00:02', assigned_object=interfaces[1]),
|
||||
MACAddress(mac_address='00:00:00:00:00:03', assigned_object=interfaces[2]),
|
||||
)
|
||||
MACAddress.objects.bulk_create(mac_addresses)
|
||||
|
||||
cls.create_data = [
|
||||
{
|
||||
'mac_address': '00:00:00:00:00:04',
|
||||
'assigned_object_type': 'dcim.interface',
|
||||
'assigned_object_id': interfaces[3].pk,
|
||||
},
|
||||
{
|
||||
'mac_address': '00:00:00:00:00:05',
|
||||
'assigned_object_type': 'dcim.interface',
|
||||
'assigned_object_id': interfaces[4].pk,
|
||||
},
|
||||
{
|
||||
'mac_address': '00:00:00:00:00:06',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -3470,3 +3470,54 @@ class VirtualDeviceContextTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
cls.bulk_edit_data = {
|
||||
'status': VirtualDeviceContextStatusChoices.STATUS_OFFLINE,
|
||||
}
|
||||
|
||||
|
||||
class MACAddressTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
model = MACAddress
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
device = create_test_device(name='Device 1')
|
||||
interfaces = (
|
||||
Interface(device=device, name='Interface 1', type='1000base-t'),
|
||||
Interface(device=device, name='Interface 2', type='1000base-t'),
|
||||
Interface(device=device, name='Interface 3', type='1000base-t'),
|
||||
Interface(device=device, name='Interface 4', type='1000base-t'),
|
||||
Interface(device=device, name='Interface 5', type='1000base-t'),
|
||||
Interface(device=device, name='Interface 6', type='1000base-t'),
|
||||
)
|
||||
Interface.objects.bulk_create(interfaces)
|
||||
|
||||
mac_addresses = (
|
||||
MACAddress(mac_address='00:00:00:00:00:01', assigned_object=interfaces[0]),
|
||||
MACAddress(mac_address='00:00:00:00:00:02', assigned_object=interfaces[1]),
|
||||
MACAddress(mac_address='00:00:00:00:00:03', assigned_object=interfaces[2]),
|
||||
)
|
||||
MACAddress.objects.bulk_create(mac_addresses)
|
||||
|
||||
tags = create_tags('Alpha', 'Bravo', 'Charlie')
|
||||
|
||||
cls.form_data = {
|
||||
'mac_address': EUI('00:00:00:00:00:04'),
|
||||
'description': 'New MAC address',
|
||||
'interface_id': interfaces[3].pk,
|
||||
'tags': [t.pk for t in tags],
|
||||
}
|
||||
|
||||
cls.csv_data = (
|
||||
"mac_address,device,interface",
|
||||
"00:00:00:00:00:04,Device 1,Interface 4",
|
||||
"00:00:00:00:00:05,Device 1,Interface 5",
|
||||
"00:00:00:00:00:06,Device 1,Interface 6",
|
||||
)
|
||||
|
||||
cls.csv_update_data = (
|
||||
"id,mac_address",
|
||||
f"{mac_addresses[0].pk},00:00:00:00:00:0a",
|
||||
f"{mac_addresses[1].pk},00:00:00:00:00:0b",
|
||||
f"{mac_addresses[2].pk},00:00:00:00:00:0c",
|
||||
)
|
||||
|
||||
cls.bulk_edit_data = {
|
||||
'description': 'New description',
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ from jinja2.exceptions import TemplateError
|
||||
|
||||
from circuits.models import Circuit, CircuitTermination
|
||||
from extras.views import ObjectConfigContextView
|
||||
from ipam.models import ASN, IPAddress, VLANGroup
|
||||
from ipam.models import ASN, IPAddress, Prefix, VLANGroup
|
||||
from ipam.tables import InterfaceVLANTable, VLANTranslationRuleTable
|
||||
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
|
||||
from netbox.views import generic
|
||||
@@ -30,8 +30,9 @@ from utilities.views import (
|
||||
)
|
||||
from virtualization.filtersets import VirtualMachineFilterSet
|
||||
from virtualization.forms import VirtualMachineFilterForm
|
||||
from virtualization.models import VirtualMachine
|
||||
from virtualization.models import Cluster, VirtualMachine
|
||||
from virtualization.tables import VirtualMachineTable
|
||||
from wireless.models import WirelessLAN
|
||||
from . import filtersets, forms, tables
|
||||
from .choices import DeviceFaceChoices, InterfaceModeChoices
|
||||
from .models import *
|
||||
@@ -238,6 +239,7 @@ class RegionView(GetRelatedModelsMixin, generic.ObjectView):
|
||||
'related_models': self.get_related_models(
|
||||
request,
|
||||
regions,
|
||||
omit=(Cluster, Prefix, WirelessLAN),
|
||||
extra=(
|
||||
(Location.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'),
|
||||
(Rack.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'),
|
||||
@@ -247,6 +249,11 @@ class RegionView(GetRelatedModelsMixin, generic.ObjectView):
|
||||
).distinct(),
|
||||
'region_id'
|
||||
),
|
||||
|
||||
# Handle these relations manually to avoid erroneous filter name resolution
|
||||
(Cluster.objects.restrict(request.user, 'view').filter(_region__in=regions), 'region_id'),
|
||||
(Prefix.objects.restrict(request.user, 'view').filter(_region__in=regions), 'region_id'),
|
||||
(WirelessLAN.objects.restrict(request.user, 'view').filter(_region__in=regions), 'region_id'),
|
||||
),
|
||||
),
|
||||
}
|
||||
@@ -331,6 +338,7 @@ class SiteGroupView(GetRelatedModelsMixin, generic.ObjectView):
|
||||
'related_models': self.get_related_models(
|
||||
request,
|
||||
groups,
|
||||
omit=(Cluster, Prefix, WirelessLAN),
|
||||
extra=(
|
||||
(Location.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'),
|
||||
(Rack.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'),
|
||||
@@ -340,6 +348,20 @@ class SiteGroupView(GetRelatedModelsMixin, generic.ObjectView):
|
||||
).distinct(),
|
||||
'site_group_id'
|
||||
),
|
||||
|
||||
# Handle these relations manually to avoid erroneous filter name resolution
|
||||
(
|
||||
Cluster.objects.restrict(request.user, 'view').filter(_site_group__in=groups),
|
||||
'site_group_id'
|
||||
),
|
||||
(
|
||||
Prefix.objects.restrict(request.user, 'view').filter(_site_group__in=groups),
|
||||
'site_group_id'
|
||||
),
|
||||
(
|
||||
WirelessLAN.objects.restrict(request.user, 'view').filter(_site_group__in=groups),
|
||||
'site_group_id'
|
||||
),
|
||||
),
|
||||
),
|
||||
}
|
||||
@@ -418,8 +440,8 @@ class SiteView(GetRelatedModelsMixin, generic.ObjectView):
|
||||
'related_models': self.get_related_models(
|
||||
request,
|
||||
instance,
|
||||
[CableTermination, CircuitTermination],
|
||||
(
|
||||
omit=(CableTermination, CircuitTermination, Cluster, Prefix, WirelessLAN),
|
||||
extra=(
|
||||
(VLANGroup.objects.restrict(request.user, 'view').filter(
|
||||
scope_type=ContentType.objects.get_for_model(Site),
|
||||
scope_id=instance.pk
|
||||
@@ -429,6 +451,11 @@ class SiteView(GetRelatedModelsMixin, generic.ObjectView):
|
||||
Circuit.objects.restrict(request.user, 'view').filter(terminations___site=instance).distinct(),
|
||||
'site_id'
|
||||
),
|
||||
|
||||
# Handle these relations manually to avoid erroneous filter name resolution
|
||||
(Cluster.objects.restrict(request.user, 'view').filter(_site=instance), 'site_id'),
|
||||
(Prefix.objects.restrict(request.user, 'view').filter(_site=instance), 'site_id'),
|
||||
(WirelessLAN.objects.restrict(request.user, 'view').filter(_site=instance), 'site_id'),
|
||||
),
|
||||
),
|
||||
}
|
||||
@@ -506,14 +533,19 @@ class LocationView(GetRelatedModelsMixin, generic.ObjectView):
|
||||
'related_models': self.get_related_models(
|
||||
request,
|
||||
locations,
|
||||
[CableTermination],
|
||||
(
|
||||
omit=[CableTermination, Cluster, Prefix, WirelessLAN],
|
||||
extra=(
|
||||
(
|
||||
Circuit.objects.restrict(request.user, 'view').filter(
|
||||
terminations___location=instance
|
||||
).distinct(),
|
||||
'location_id'
|
||||
),
|
||||
|
||||
# Handle these relations manually to avoid erroneous filter name resolution
|
||||
(Cluster.objects.restrict(request.user, 'view').filter(_location=instance), 'location_id'),
|
||||
(Prefix.objects.restrict(request.user, 'view').filter(_location=instance), 'location_id'),
|
||||
(WirelessLAN.objects.restrict(request.user, 'view').filter(_location=instance), 'location_id'),
|
||||
),
|
||||
),
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ class RSSFeedWidget(DashboardWidget):
|
||||
return f'dashboard_rss_{url_checksum}'
|
||||
|
||||
def get_feed(self):
|
||||
if self.config['requires_internet'] and settings.ISOLATED_DEPLOYMENT:
|
||||
if self.config.get('requires_internet') and settings.ISOLATED_DEPLOYMENT:
|
||||
return {
|
||||
'isolated_deployment': True,
|
||||
}
|
||||
|
||||
@@ -120,11 +120,12 @@ class ConfigContextModelQuerySet(RestrictedQuerySet):
|
||||
is_active=True,
|
||||
)
|
||||
|
||||
# Apply Location & DeviceType filters only for VirtualMachines
|
||||
if self.model._meta.model_name == 'device':
|
||||
base_query.add((Q(locations=OuterRef('location')) | Q(locations=None)), Q.AND)
|
||||
base_query.add((Q(device_types=OuterRef('device_type')) | Q(device_types=None)), Q.AND)
|
||||
|
||||
elif self.model._meta.model_name == 'virtualmachine':
|
||||
base_query.add(Q(locations=None), Q.AND)
|
||||
base_query.add(Q(device_types=None), Q.AND)
|
||||
|
||||
base_query.add((Q(roles=OuterRef('role')) | Q(roles=None)), Q.AND)
|
||||
|
||||
@@ -79,7 +79,7 @@ class PrefixIndex(SearchIndex):
|
||||
('description', 500),
|
||||
('comments', 5000),
|
||||
)
|
||||
display_attrs = ('site', 'vrf', 'tenant', 'vlan', 'status', 'role', 'description')
|
||||
display_attrs = ('scope', 'vrf', 'tenant', 'vlan', 'status', 'role', 'description')
|
||||
|
||||
|
||||
@register_search
|
||||
|
||||
@@ -192,7 +192,8 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
|
||||
)
|
||||
scope = tables.Column(
|
||||
verbose_name=_('Scope'),
|
||||
linkify=True
|
||||
linkify=True,
|
||||
orderable=False
|
||||
)
|
||||
vlan_group = tables.Column(
|
||||
accessor='vlan__group',
|
||||
@@ -200,6 +201,7 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
|
||||
verbose_name=_('VLAN Group')
|
||||
)
|
||||
vlan = tables.Column(
|
||||
order_by=('vlan__vid', 'vlan__pk'),
|
||||
linkify=True,
|
||||
verbose_name=_('VLAN')
|
||||
)
|
||||
|
||||
@@ -5,9 +5,7 @@ import os
|
||||
import platform
|
||||
import sys
|
||||
import warnings
|
||||
from urllib.parse import urlencode
|
||||
|
||||
import requests
|
||||
from django.contrib.messages import constants as messages
|
||||
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
||||
from django.core.validators import URLValidator
|
||||
@@ -224,8 +222,18 @@ DATABASES = {
|
||||
# Storage backend
|
||||
#
|
||||
|
||||
# Default STORAGES for Django
|
||||
STORAGES = {
|
||||
"default": {
|
||||
"BACKEND": "django.core.files.storage.FileSystemStorage",
|
||||
},
|
||||
"staticfiles": {
|
||||
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
|
||||
},
|
||||
}
|
||||
|
||||
if STORAGE_BACKEND is not None:
|
||||
DEFAULT_FILE_STORAGE = STORAGE_BACKEND
|
||||
STORAGES['default']['BACKEND'] = STORAGE_BACKEND
|
||||
|
||||
# django-storages
|
||||
if STORAGE_BACKEND.startswith('storages.'):
|
||||
@@ -583,17 +591,6 @@ if SENTRY_ENABLED:
|
||||
# Calculate a unique deployment ID from the secret key
|
||||
DEPLOYMENT_ID = hashlib.sha256(SECRET_KEY.encode('utf-8')).hexdigest()[:16]
|
||||
CENSUS_URL = 'https://census.netbox.oss.netboxlabs.com/api/v1/'
|
||||
CENSUS_PARAMS = {
|
||||
'version': RELEASE.full_version,
|
||||
'python_version': sys.version.split()[0],
|
||||
'deployment_id': DEPLOYMENT_ID,
|
||||
}
|
||||
if CENSUS_REPORTING_ENABLED and not ISOLATED_DEPLOYMENT and not DEBUG and 'test' not in sys.argv:
|
||||
try:
|
||||
# Report anonymous census data
|
||||
requests.get(f'{CENSUS_URL}?{urlencode(CENSUS_PARAMS)}', timeout=3, proxies=HTTP_PROXIES)
|
||||
except requests.exceptions.RequestException:
|
||||
pass
|
||||
|
||||
|
||||
#
|
||||
|
||||
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
@@ -27,10 +27,10 @@
|
||||
"bootstrap": "5.3.3",
|
||||
"clipboard": "2.0.11",
|
||||
"flatpickr": "4.6.13",
|
||||
"gridstack": "11.2.0",
|
||||
"gridstack": "11.3.0",
|
||||
"htmx.org": "1.9.12",
|
||||
"query-string": "9.1.1",
|
||||
"sass": "1.83.1",
|
||||
"sass": "1.83.4",
|
||||
"tom-select": "2.4.1",
|
||||
"typeface-inter": "3.18.1",
|
||||
"typeface-roboto-mono": "1.1.13"
|
||||
|
||||
@@ -1905,10 +1905,10 @@ graphql@16.10.0:
|
||||
resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.10.0.tgz#24c01ae0af6b11ea87bf55694429198aaa8e220c"
|
||||
integrity sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==
|
||||
|
||||
gridstack@11.2.0:
|
||||
version "11.2.0"
|
||||
resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-11.2.0.tgz#8977a6632c521260f064ef171b92c7a8df4f58a9"
|
||||
integrity sha512-ajwUzd9spR8NXDxfJotHWq9WOYoDOV9o6UJR3ksevNz8cvXNxDtI9H/lC+RN6ijM2DexureLlsG0RpYjBZiOtg==
|
||||
gridstack@11.3.0:
|
||||
version "11.3.0"
|
||||
resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-11.3.0.tgz#b110c66bafc64c920fc54933e2c9df4f7b2cfffe"
|
||||
integrity sha512-Z0eRovKcZTRTs3zetJwjO6CNwrgIy845WfOeZGk8ybpeMCE8fMA8tScyKU72Y2M6uGHkjgwnjflglvPiv+RcBQ==
|
||||
|
||||
has-bigints@^1.0.1, has-bigints@^1.0.2:
|
||||
version "1.0.2"
|
||||
@@ -2667,10 +2667,10 @@ safe-regex-test@^1.0.3:
|
||||
es-errors "^1.3.0"
|
||||
is-regex "^1.1.4"
|
||||
|
||||
sass@1.83.1:
|
||||
version "1.83.1"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.83.1.tgz#dee1ab94b47a6f9993d3195d36f556bcbda64846"
|
||||
integrity sha512-EVJbDaEs4Rr3F0glJzFSOvtg2/oy2V/YrGFPqPY24UqcLDWcI9ZY5sN+qyO3c/QCZwzgfirvhXvINiJCE/OLcA==
|
||||
sass@1.83.4:
|
||||
version "1.83.4"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.83.4.tgz#5ccf60f43eb61eeec300b780b8dcb85f16eec6d1"
|
||||
integrity sha512-B1bozCeNQiOgDcLd33e2Cs2U60wZwjUUXzh900ZyQF5qUasvMdDZYbQ566LJu7cqR+sAHlAfO6RMkaID5s6qpA==
|
||||
dependencies:
|
||||
chokidar "^4.0.0"
|
||||
immutable "^5.0.2"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version: "4.2.0"
|
||||
version: "4.2.2"
|
||||
edition: "Community"
|
||||
published: "2025-01-06"
|
||||
published: "2025-01-17"
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
<tr>
|
||||
<th scope="row" class="border-0 ps-3">{% trans "Protection rules" %}</th>
|
||||
{% if config.PROTECTION_RULES %}
|
||||
<td class="border-0"><pre>{{ config.PROTECTION_RULES|json }}</pre></td>
|
||||
<td class="border-0"><pre>{{ config.PROTECTION_RULES }}</pre></td>
|
||||
{% else %}
|
||||
<td class="border-0">{{ ''|placeholder }}</td>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
<li class="breadcrumb-item"><a href="{% url 'dcim:devicetype_list' %}?manufacturer_id={{ object.manufacturer.pk }}">{{ object.manufacturer }}</a></li>
|
||||
@@ -8,7 +8,9 @@
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ block.super }}
|
||||
{% include 'dcim/inc/devicetype_breadcrumbs.html' %}
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{% url 'dcim:moduletype_list' %}?manufacturer_id={{ object.manufacturer.pk }}">{{ object.manufacturer }}</a>
|
||||
</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_controls %}
|
||||
|
||||
@@ -3,13 +3,6 @@
|
||||
{% load helpers %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{{ object.manufacturer }} {{ object.model }}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ block.super }}
|
||||
{% include 'dcim/inc/devicetype_breadcrumbs.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_controls %}
|
||||
{% include 'dcim/inc/moduletype_buttons.html' %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div class="list-group-item px-1 py-2">
|
||||
<a href="{{ entry.link }}" class="text-body">{{ entry.title }}</a>
|
||||
<div class="text-secondary">
|
||||
{{ entry.summary|safe }}
|
||||
{{ entry.summary }}
|
||||
</div>
|
||||
</div>
|
||||
{% empty %}
|
||||
|
||||
Binary file not shown.
@@ -7,15 +7,16 @@
|
||||
# czarnian, 2024
|
||||
# Jeremy Stretch, 2024
|
||||
# Pavel Valach, 2024
|
||||
# Matěj Gordon, 2025
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-12-12 05:02+0000\n"
|
||||
"POT-Creation-Date: 2025-01-04 05:02+0000\n"
|
||||
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
|
||||
"Last-Translator: Pavel Valach, 2024\n"
|
||||
"Last-Translator: Matěj Gordon, 2025\n"
|
||||
"Language-Team: Czech (https://app.transifex.com/netbox-community/teams/178115/cs/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -151,7 +152,7 @@ msgstr "Neaktivní"
|
||||
#: netbox/dcim/filtersets.py:464 netbox/dcim/filtersets.py:1021
|
||||
#: netbox/dcim/filtersets.py:1368 netbox/dcim/filtersets.py:1903
|
||||
#: netbox/dcim/filtersets.py:2146 netbox/dcim/filtersets.py:2204
|
||||
#: netbox/ipam/filtersets.py:339 netbox/ipam/filtersets.py:959
|
||||
#: netbox/ipam/filtersets.py:341 netbox/ipam/filtersets.py:961
|
||||
#: netbox/virtualization/filtersets.py:45
|
||||
#: netbox/virtualization/filtersets.py:173 netbox/vpn/filtersets.py:358
|
||||
msgid "Region (ID)"
|
||||
@@ -163,8 +164,8 @@ msgstr "Region (ID)"
|
||||
#: netbox/dcim/filtersets.py:471 netbox/dcim/filtersets.py:1028
|
||||
#: netbox/dcim/filtersets.py:1375 netbox/dcim/filtersets.py:1910
|
||||
#: netbox/dcim/filtersets.py:2153 netbox/dcim/filtersets.py:2211
|
||||
#: netbox/extras/filtersets.py:509 netbox/ipam/filtersets.py:346
|
||||
#: netbox/ipam/filtersets.py:966 netbox/virtualization/filtersets.py:52
|
||||
#: netbox/extras/filtersets.py:509 netbox/ipam/filtersets.py:348
|
||||
#: netbox/ipam/filtersets.py:968 netbox/virtualization/filtersets.py:52
|
||||
#: netbox/virtualization/filtersets.py:180 netbox/vpn/filtersets.py:353
|
||||
msgid "Region (slug)"
|
||||
msgstr "Region (zkratka)"
|
||||
@@ -174,8 +175,8 @@ msgstr "Region (zkratka)"
|
||||
#: netbox/dcim/filtersets.py:346 netbox/dcim/filtersets.py:477
|
||||
#: netbox/dcim/filtersets.py:1034 netbox/dcim/filtersets.py:1381
|
||||
#: netbox/dcim/filtersets.py:1916 netbox/dcim/filtersets.py:2159
|
||||
#: netbox/dcim/filtersets.py:2217 netbox/ipam/filtersets.py:352
|
||||
#: netbox/ipam/filtersets.py:972 netbox/virtualization/filtersets.py:58
|
||||
#: netbox/dcim/filtersets.py:2217 netbox/ipam/filtersets.py:354
|
||||
#: netbox/ipam/filtersets.py:974 netbox/virtualization/filtersets.py:58
|
||||
#: netbox/virtualization/filtersets.py:186
|
||||
msgid "Site group (ID)"
|
||||
msgstr "Skupina stránek (ID)"
|
||||
@@ -186,7 +187,7 @@ msgstr "Skupina stránek (ID)"
|
||||
#: netbox/dcim/filtersets.py:1041 netbox/dcim/filtersets.py:1388
|
||||
#: netbox/dcim/filtersets.py:1923 netbox/dcim/filtersets.py:2166
|
||||
#: netbox/dcim/filtersets.py:2224 netbox/extras/filtersets.py:515
|
||||
#: netbox/ipam/filtersets.py:359 netbox/ipam/filtersets.py:979
|
||||
#: netbox/ipam/filtersets.py:361 netbox/ipam/filtersets.py:981
|
||||
#: netbox/virtualization/filtersets.py:65
|
||||
#: netbox/virtualization/filtersets.py:193
|
||||
msgid "Site group (slug)"
|
||||
@@ -256,8 +257,8 @@ msgstr "Stránky"
|
||||
#: netbox/circuits/filtersets.py:62 netbox/circuits/filtersets.py:229
|
||||
#: netbox/circuits/filtersets.py:274 netbox/dcim/filtersets.py:242
|
||||
#: netbox/dcim/filtersets.py:363 netbox/dcim/filtersets.py:458
|
||||
#: netbox/extras/filtersets.py:531 netbox/ipam/filtersets.py:238
|
||||
#: netbox/ipam/filtersets.py:369 netbox/ipam/filtersets.py:989
|
||||
#: netbox/extras/filtersets.py:531 netbox/ipam/filtersets.py:240
|
||||
#: netbox/ipam/filtersets.py:371 netbox/ipam/filtersets.py:991
|
||||
#: netbox/virtualization/filtersets.py:75
|
||||
#: netbox/virtualization/filtersets.py:203 netbox/vpn/filtersets.py:363
|
||||
msgid "Site (slug)"
|
||||
@@ -276,13 +277,13 @@ msgstr "ASN"
|
||||
|
||||
#: netbox/circuits/filtersets.py:95 netbox/circuits/filtersets.py:122
|
||||
#: netbox/circuits/filtersets.py:156 netbox/circuits/filtersets.py:283
|
||||
#: netbox/circuits/filtersets.py:325 netbox/ipam/filtersets.py:243
|
||||
#: netbox/circuits/filtersets.py:325 netbox/ipam/filtersets.py:245
|
||||
msgid "Provider (ID)"
|
||||
msgstr "Poskytovatel (ID)"
|
||||
|
||||
#: netbox/circuits/filtersets.py:101 netbox/circuits/filtersets.py:128
|
||||
#: netbox/circuits/filtersets.py:162 netbox/circuits/filtersets.py:289
|
||||
#: netbox/circuits/filtersets.py:331 netbox/ipam/filtersets.py:249
|
||||
#: netbox/circuits/filtersets.py:331 netbox/ipam/filtersets.py:251
|
||||
msgid "Provider (slug)"
|
||||
msgstr "Poskytovatel (slug)"
|
||||
|
||||
@@ -311,8 +312,8 @@ msgstr "Typ okruhu (URL zkratka)"
|
||||
#: netbox/dcim/filtersets.py:452 netbox/dcim/filtersets.py:1045
|
||||
#: netbox/dcim/filtersets.py:1393 netbox/dcim/filtersets.py:1928
|
||||
#: netbox/dcim/filtersets.py:2170 netbox/dcim/filtersets.py:2229
|
||||
#: netbox/ipam/filtersets.py:232 netbox/ipam/filtersets.py:363
|
||||
#: netbox/ipam/filtersets.py:983 netbox/virtualization/filtersets.py:69
|
||||
#: netbox/ipam/filtersets.py:234 netbox/ipam/filtersets.py:365
|
||||
#: netbox/ipam/filtersets.py:985 netbox/virtualization/filtersets.py:69
|
||||
#: netbox/virtualization/filtersets.py:197 netbox/vpn/filtersets.py:368
|
||||
msgid "Site (ID)"
|
||||
msgstr "Stránky (ID)"
|
||||
@@ -666,7 +667,7 @@ msgstr "Účet poskytovatele"
|
||||
#: netbox/dcim/forms/filtersets.py:924 netbox/dcim/forms/filtersets.py:958
|
||||
#: netbox/dcim/forms/filtersets.py:1059 netbox/dcim/forms/filtersets.py:1170
|
||||
#: netbox/dcim/tables/devices.py:140 netbox/dcim/tables/devices.py:817
|
||||
#: netbox/dcim/tables/devices.py:1063 netbox/dcim/tables/modules.py:69
|
||||
#: netbox/dcim/tables/devices.py:1063 netbox/dcim/tables/modules.py:70
|
||||
#: netbox/dcim/tables/power.py:74 netbox/dcim/tables/racks.py:126
|
||||
#: netbox/dcim/tables/sites.py:82 netbox/dcim/tables/sites.py:138
|
||||
#: netbox/ipam/forms/bulk_edit.py:256 netbox/ipam/forms/bulk_edit.py:306
|
||||
@@ -1101,7 +1102,7 @@ msgstr "Přiřazení"
|
||||
#: netbox/circuits/tables/circuits.py:155 netbox/dcim/forms/bulk_edit.py:118
|
||||
#: netbox/dcim/forms/bulk_import.py:100 netbox/dcim/forms/model_forms.py:117
|
||||
#: netbox/dcim/tables/sites.py:89 netbox/extras/forms/filtersets.py:480
|
||||
#: netbox/ipam/filtersets.py:999 netbox/ipam/forms/bulk_edit.py:493
|
||||
#: netbox/ipam/filtersets.py:1001 netbox/ipam/forms/bulk_edit.py:493
|
||||
#: netbox/ipam/forms/bulk_import.py:460 netbox/ipam/forms/model_forms.py:561
|
||||
#: netbox/ipam/tables/fhrp.py:67 netbox/ipam/tables/vlans.py:122
|
||||
#: netbox/ipam/tables/vlans.py:226
|
||||
@@ -1540,7 +1541,7 @@ msgstr "Míra odevzdání"
|
||||
#: netbox/circuits/tables/providers.py:82
|
||||
#: netbox/circuits/tables/providers.py:107 netbox/dcim/tables/devices.py:1036
|
||||
#: netbox/dcim/tables/devicetypes.py:92 netbox/dcim/tables/modules.py:29
|
||||
#: netbox/dcim/tables/modules.py:72 netbox/dcim/tables/power.py:39
|
||||
#: netbox/dcim/tables/modules.py:73 netbox/dcim/tables/power.py:39
|
||||
#: netbox/dcim/tables/power.py:96 netbox/dcim/tables/racks.py:84
|
||||
#: netbox/dcim/tables/racks.py:145 netbox/dcim/tables/racks.py:225
|
||||
#: netbox/dcim/tables/sites.py:108 netbox/extras/tables/tables.py:582
|
||||
@@ -2932,7 +2933,7 @@ msgid "Parent site group (slug)"
|
||||
msgstr "Nadřazená skupina stránek (slimák)"
|
||||
|
||||
#: netbox/dcim/filtersets.py:164 netbox/extras/filtersets.py:364
|
||||
#: netbox/ipam/filtersets.py:841 netbox/ipam/filtersets.py:993
|
||||
#: netbox/ipam/filtersets.py:843 netbox/ipam/filtersets.py:995
|
||||
msgid "Group (ID)"
|
||||
msgstr "Skupina (ID)"
|
||||
|
||||
@@ -2990,15 +2991,15 @@ msgstr "Typ stojanu (ID)"
|
||||
|
||||
#: netbox/dcim/filtersets.py:411 netbox/dcim/filtersets.py:892
|
||||
#: netbox/dcim/filtersets.py:994 netbox/dcim/filtersets.py:1850
|
||||
#: netbox/ipam/filtersets.py:381 netbox/ipam/filtersets.py:493
|
||||
#: netbox/ipam/filtersets.py:1003 netbox/virtualization/filtersets.py:210
|
||||
#: netbox/ipam/filtersets.py:383 netbox/ipam/filtersets.py:495
|
||||
#: netbox/ipam/filtersets.py:1005 netbox/virtualization/filtersets.py:210
|
||||
msgid "Role (ID)"
|
||||
msgstr "Role (ID)"
|
||||
|
||||
#: netbox/dcim/filtersets.py:417 netbox/dcim/filtersets.py:898
|
||||
#: netbox/dcim/filtersets.py:1000 netbox/dcim/filtersets.py:1856
|
||||
#: netbox/extras/filtersets.py:558 netbox/ipam/filtersets.py:387
|
||||
#: netbox/ipam/filtersets.py:499 netbox/ipam/filtersets.py:1009
|
||||
#: netbox/extras/filtersets.py:558 netbox/ipam/filtersets.py:389
|
||||
#: netbox/ipam/filtersets.py:501 netbox/ipam/filtersets.py:1011
|
||||
#: netbox/virtualization/filtersets.py:216
|
||||
msgid "Role (slug)"
|
||||
msgstr "Role (slug)"
|
||||
@@ -3196,7 +3197,7 @@ msgstr "VDC (ID)"
|
||||
msgid "Device model"
|
||||
msgstr "Model zařízení"
|
||||
|
||||
#: netbox/dcim/filtersets.py:1267 netbox/ipam/filtersets.py:632
|
||||
#: netbox/dcim/filtersets.py:1267 netbox/ipam/filtersets.py:634
|
||||
#: netbox/vpn/filtersets.py:102 netbox/vpn/filtersets.py:401
|
||||
msgid "Interface (ID)"
|
||||
msgstr "Rozhraní (ID)"
|
||||
@@ -3210,8 +3211,8 @@ msgid "Module bay (ID)"
|
||||
msgstr "Modulová přihrádka (ID)"
|
||||
|
||||
#: netbox/dcim/filtersets.py:1333 netbox/dcim/filtersets.py:1425
|
||||
#: netbox/ipam/filtersets.py:611 netbox/ipam/filtersets.py:851
|
||||
#: netbox/ipam/filtersets.py:1115 netbox/virtualization/filtersets.py:161
|
||||
#: netbox/ipam/filtersets.py:613 netbox/ipam/filtersets.py:853
|
||||
#: netbox/ipam/filtersets.py:1117 netbox/virtualization/filtersets.py:161
|
||||
#: netbox/vpn/filtersets.py:379
|
||||
msgid "Device (ID)"
|
||||
msgstr "Zařízení (ID)"
|
||||
@@ -3220,8 +3221,8 @@ msgstr "Zařízení (ID)"
|
||||
msgid "Rack (name)"
|
||||
msgstr "Stojan (název)"
|
||||
|
||||
#: netbox/dcim/filtersets.py:1431 netbox/ipam/filtersets.py:606
|
||||
#: netbox/ipam/filtersets.py:846 netbox/ipam/filtersets.py:1121
|
||||
#: netbox/dcim/filtersets.py:1431 netbox/ipam/filtersets.py:608
|
||||
#: netbox/ipam/filtersets.py:848 netbox/ipam/filtersets.py:1123
|
||||
#: netbox/vpn/filtersets.py:374
|
||||
msgid "Device (name)"
|
||||
msgstr "Zařízení (název)"
|
||||
@@ -3273,9 +3274,9 @@ msgstr "Přiřazené VID"
|
||||
#: netbox/dcim/forms/bulk_import.py:913 netbox/dcim/forms/filtersets.py:1428
|
||||
#: netbox/dcim/forms/model_forms.py:1385
|
||||
#: netbox/dcim/models/device_components.py:711
|
||||
#: netbox/dcim/tables/devices.py:626 netbox/ipam/filtersets.py:316
|
||||
#: netbox/ipam/filtersets.py:327 netbox/ipam/filtersets.py:483
|
||||
#: netbox/ipam/filtersets.py:584 netbox/ipam/filtersets.py:595
|
||||
#: netbox/dcim/tables/devices.py:626 netbox/ipam/filtersets.py:318
|
||||
#: netbox/ipam/filtersets.py:329 netbox/ipam/filtersets.py:485
|
||||
#: netbox/ipam/filtersets.py:586 netbox/ipam/filtersets.py:597
|
||||
#: netbox/ipam/forms/bulk_edit.py:242 netbox/ipam/forms/bulk_edit.py:298
|
||||
#: netbox/ipam/forms/bulk_edit.py:340 netbox/ipam/forms/bulk_import.py:157
|
||||
#: netbox/ipam/forms/bulk_import.py:243 netbox/ipam/forms/bulk_import.py:279
|
||||
@@ -3302,19 +3303,19 @@ msgstr "Přiřazené VID"
|
||||
msgid "VRF"
|
||||
msgstr "VRF"
|
||||
|
||||
#: netbox/dcim/filtersets.py:1619 netbox/ipam/filtersets.py:322
|
||||
#: netbox/ipam/filtersets.py:333 netbox/ipam/filtersets.py:489
|
||||
#: netbox/ipam/filtersets.py:590 netbox/ipam/filtersets.py:601
|
||||
#: netbox/dcim/filtersets.py:1619 netbox/ipam/filtersets.py:324
|
||||
#: netbox/ipam/filtersets.py:335 netbox/ipam/filtersets.py:491
|
||||
#: netbox/ipam/filtersets.py:592 netbox/ipam/filtersets.py:603
|
||||
msgid "VRF (RD)"
|
||||
msgstr "VRF (RD)"
|
||||
|
||||
#: netbox/dcim/filtersets.py:1624 netbox/ipam/filtersets.py:1030
|
||||
#: netbox/dcim/filtersets.py:1624 netbox/ipam/filtersets.py:1032
|
||||
#: netbox/vpn/filtersets.py:342
|
||||
msgid "L2VPN (ID)"
|
||||
msgstr "L2VPN (ID)"
|
||||
|
||||
#: netbox/dcim/filtersets.py:1630 netbox/dcim/forms/filtersets.py:1433
|
||||
#: netbox/dcim/tables/devices.py:570 netbox/ipam/filtersets.py:1036
|
||||
#: netbox/dcim/tables/devices.py:570 netbox/ipam/filtersets.py:1038
|
||||
#: netbox/ipam/forms/filtersets.py:518 netbox/ipam/tables/vlans.py:137
|
||||
#: netbox/templates/dcim/interface.html:93 netbox/templates/ipam/vlan.html:66
|
||||
#: netbox/templates/vpn/l2vpntermination.html:12
|
||||
@@ -3476,7 +3477,7 @@ msgstr "Časové pásmo"
|
||||
#: netbox/dcim/forms/object_import.py:187 netbox/dcim/tables/devices.py:96
|
||||
#: netbox/dcim/tables/devices.py:172 netbox/dcim/tables/devices.py:940
|
||||
#: netbox/dcim/tables/devicetypes.py:80 netbox/dcim/tables/devicetypes.py:308
|
||||
#: netbox/dcim/tables/modules.py:20 netbox/dcim/tables/modules.py:60
|
||||
#: netbox/dcim/tables/modules.py:20 netbox/dcim/tables/modules.py:61
|
||||
#: netbox/dcim/tables/racks.py:58 netbox/dcim/tables/racks.py:132
|
||||
#: netbox/templates/dcim/devicetype.html:14
|
||||
#: netbox/templates/dcim/inventoryitem.html:44
|
||||
@@ -3727,7 +3728,7 @@ msgid "Device Type"
|
||||
msgstr "Typ zařízení"
|
||||
|
||||
#: netbox/dcim/forms/bulk_edit.py:598 netbox/dcim/forms/model_forms.py:401
|
||||
#: netbox/dcim/tables/modules.py:17 netbox/dcim/tables/modules.py:65
|
||||
#: netbox/dcim/tables/modules.py:17 netbox/dcim/tables/modules.py:66
|
||||
#: netbox/templates/dcim/module.html:65
|
||||
#: netbox/templates/dcim/modulebay.html:66
|
||||
#: netbox/templates/dcim/moduletype.html:22
|
||||
@@ -3835,7 +3836,7 @@ msgstr "Klastr"
|
||||
#: netbox/dcim/tables/devices.py:697 netbox/dcim/tables/devices.py:754
|
||||
#: netbox/dcim/tables/devices.py:801 netbox/dcim/tables/devices.py:861
|
||||
#: netbox/dcim/tables/devices.py:930 netbox/dcim/tables/devices.py:1057
|
||||
#: netbox/dcim/tables/modules.py:52 netbox/extras/forms/filtersets.py:321
|
||||
#: netbox/dcim/tables/modules.py:53 netbox/extras/forms/filtersets.py:321
|
||||
#: netbox/ipam/forms/bulk_import.py:304 netbox/ipam/forms/bulk_import.py:505
|
||||
#: netbox/ipam/forms/filtersets.py:551 netbox/ipam/forms/model_forms.py:323
|
||||
#: netbox/ipam/forms/model_forms.py:712 netbox/ipam/forms/model_forms.py:745
|
||||
@@ -4087,11 +4088,11 @@ msgstr "Označené VLAN"
|
||||
|
||||
#: netbox/dcim/forms/bulk_edit.py:1511
|
||||
msgid "Add tagged VLANs"
|
||||
msgstr ""
|
||||
msgstr "Přidat označené VLANy"
|
||||
|
||||
#: netbox/dcim/forms/bulk_edit.py:1520
|
||||
msgid "Remove tagged VLANs"
|
||||
msgstr ""
|
||||
msgstr "Odstranit označené VLANy"
|
||||
|
||||
#: netbox/dcim/forms/bulk_edit.py:1536 netbox/dcim/forms/model_forms.py:1348
|
||||
msgid "Wireless LAN group"
|
||||
@@ -4139,7 +4140,7 @@ msgstr "Přepínání 802.1Q"
|
||||
|
||||
#: netbox/dcim/forms/bulk_edit.py:1558
|
||||
msgid "Add/Remove"
|
||||
msgstr ""
|
||||
msgstr "Přidat/Odebrat"
|
||||
|
||||
#: netbox/dcim/forms/bulk_edit.py:1617 netbox/dcim/forms/bulk_edit.py:1619
|
||||
msgid "Interface mode must be specified to assign VLANs"
|
||||
@@ -4217,7 +4218,7 @@ msgstr "Název přiřazené role"
|
||||
|
||||
#: netbox/dcim/forms/bulk_import.py:264
|
||||
msgid "Rack type model"
|
||||
msgstr ""
|
||||
msgstr "Model typu stojanu"
|
||||
|
||||
#: netbox/dcim/forms/bulk_import.py:292 netbox/dcim/forms/bulk_import.py:435
|
||||
#: netbox/dcim/forms/bulk_import.py:605
|
||||
@@ -4226,7 +4227,7 @@ msgstr "Směr proudění vzduchu"
|
||||
|
||||
#: netbox/dcim/forms/bulk_import.py:324
|
||||
msgid "Width must be set if not specifying a rack type."
|
||||
msgstr ""
|
||||
msgstr "Šířka musí být nastavena, pokud není zadán typ stojanu."
|
||||
|
||||
#: netbox/dcim/forms/bulk_import.py:326
|
||||
msgid "U height must be set if not specifying a rack type."
|
||||
@@ -6768,7 +6769,7 @@ msgstr "Modulové pozice"
|
||||
msgid "Inventory items"
|
||||
msgstr "Inventární položky"
|
||||
|
||||
#: netbox/dcim/tables/devices.py:305 netbox/dcim/tables/modules.py:56
|
||||
#: netbox/dcim/tables/devices.py:305 netbox/dcim/tables/modules.py:57
|
||||
#: netbox/templates/dcim/modulebay.html:17
|
||||
msgid "Module Bay"
|
||||
msgstr "Modulová přihrádka"
|
||||
@@ -7490,12 +7491,12 @@ msgstr "Záložky"
|
||||
msgid "Show your personal bookmarks"
|
||||
msgstr "Zobrazit své osobní záložky"
|
||||
|
||||
#: netbox/extras/events.py:147
|
||||
#: netbox/extras/events.py:151
|
||||
#, python-brace-format
|
||||
msgid "Unknown action type for an event rule: {action_type}"
|
||||
msgstr "Neznámý typ akce pro pravidlo události: {action_type}"
|
||||
|
||||
#: netbox/extras/events.py:192
|
||||
#: netbox/extras/events.py:196
|
||||
#, python-brace-format
|
||||
msgid "Cannot import events pipeline {name} error: {error}"
|
||||
msgstr "Nelze importovat kanál událostí {name} chyba: {error}"
|
||||
@@ -9248,129 +9249,129 @@ msgstr "Export L2VPN"
|
||||
msgid "Exporting L2VPN (identifier)"
|
||||
msgstr "Export L2VPN (identifikátor)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:155 netbox/ipam/filtersets.py:281
|
||||
#: netbox/ipam/filtersets.py:155 netbox/ipam/filtersets.py:283
|
||||
#: netbox/ipam/forms/model_forms.py:229 netbox/ipam/tables/ip.py:212
|
||||
#: netbox/templates/ipam/prefix.html:12
|
||||
msgid "Prefix"
|
||||
msgstr "Předpona"
|
||||
|
||||
#: netbox/ipam/filtersets.py:159 netbox/ipam/filtersets.py:198
|
||||
#: netbox/ipam/filtersets.py:221
|
||||
#: netbox/ipam/filtersets.py:223
|
||||
msgid "RIR (ID)"
|
||||
msgstr "RIR (ID)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:165 netbox/ipam/filtersets.py:204
|
||||
#: netbox/ipam/filtersets.py:227
|
||||
#: netbox/ipam/filtersets.py:229
|
||||
msgid "RIR (slug)"
|
||||
msgstr "RIR (slug)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:285
|
||||
#: netbox/ipam/filtersets.py:287
|
||||
msgid "Within prefix"
|
||||
msgstr "V rámci předpony"
|
||||
|
||||
#: netbox/ipam/filtersets.py:289
|
||||
#: netbox/ipam/filtersets.py:291
|
||||
msgid "Within and including prefix"
|
||||
msgstr "V rámci a včetně prefixu"
|
||||
|
||||
#: netbox/ipam/filtersets.py:293
|
||||
#: netbox/ipam/filtersets.py:295
|
||||
msgid "Prefixes which contain this prefix or IP"
|
||||
msgstr "Předpony, které obsahují tuto předponu nebo IP"
|
||||
|
||||
#: netbox/ipam/filtersets.py:304 netbox/ipam/filtersets.py:572
|
||||
#: netbox/ipam/filtersets.py:306 netbox/ipam/filtersets.py:574
|
||||
#: netbox/ipam/forms/bulk_edit.py:343 netbox/ipam/forms/filtersets.py:196
|
||||
#: netbox/ipam/forms/filtersets.py:331
|
||||
msgid "Mask length"
|
||||
msgstr "Délka masky"
|
||||
|
||||
#: netbox/ipam/filtersets.py:373 netbox/vpn/filtersets.py:427
|
||||
#: netbox/ipam/filtersets.py:375 netbox/vpn/filtersets.py:427
|
||||
msgid "VLAN (ID)"
|
||||
msgstr "VLAN (ID)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:377 netbox/vpn/filtersets.py:422
|
||||
#: netbox/ipam/filtersets.py:379 netbox/vpn/filtersets.py:422
|
||||
msgid "VLAN number (1-4094)"
|
||||
msgstr "Číslo VLAN (1-4094)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:471 netbox/ipam/filtersets.py:475
|
||||
#: netbox/ipam/filtersets.py:567 netbox/ipam/forms/model_forms.py:496
|
||||
#: netbox/ipam/filtersets.py:473 netbox/ipam/filtersets.py:477
|
||||
#: netbox/ipam/filtersets.py:569 netbox/ipam/forms/model_forms.py:496
|
||||
#: netbox/templates/tenancy/contact.html:53
|
||||
#: netbox/tenancy/forms/bulk_edit.py:113
|
||||
msgid "Address"
|
||||
msgstr "Adresa"
|
||||
|
||||
#: netbox/ipam/filtersets.py:479
|
||||
#: netbox/ipam/filtersets.py:481
|
||||
msgid "Ranges which contain this prefix or IP"
|
||||
msgstr "Rozsahy, které obsahují tuto předponu nebo IP"
|
||||
|
||||
#: netbox/ipam/filtersets.py:507 netbox/ipam/filtersets.py:563
|
||||
#: netbox/ipam/filtersets.py:509 netbox/ipam/filtersets.py:565
|
||||
msgid "Parent prefix"
|
||||
msgstr "Nadřazená předpona"
|
||||
|
||||
#: netbox/ipam/filtersets.py:616 netbox/ipam/filtersets.py:856
|
||||
#: netbox/ipam/filtersets.py:1131 netbox/vpn/filtersets.py:385
|
||||
#: netbox/ipam/filtersets.py:618 netbox/ipam/filtersets.py:858
|
||||
#: netbox/ipam/filtersets.py:1133 netbox/vpn/filtersets.py:385
|
||||
msgid "Virtual machine (name)"
|
||||
msgstr "Virtuální počítač (název)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:621 netbox/ipam/filtersets.py:861
|
||||
#: netbox/ipam/filtersets.py:1125 netbox/virtualization/filtersets.py:282
|
||||
#: netbox/ipam/filtersets.py:623 netbox/ipam/filtersets.py:863
|
||||
#: netbox/ipam/filtersets.py:1127 netbox/virtualization/filtersets.py:282
|
||||
#: netbox/virtualization/filtersets.py:321 netbox/vpn/filtersets.py:390
|
||||
msgid "Virtual machine (ID)"
|
||||
msgstr "Virtuální počítač (ID)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:627 netbox/vpn/filtersets.py:97
|
||||
#: netbox/ipam/filtersets.py:629 netbox/vpn/filtersets.py:97
|
||||
#: netbox/vpn/filtersets.py:396
|
||||
msgid "Interface (name)"
|
||||
msgstr "Rozhraní (název)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:638 netbox/vpn/filtersets.py:108
|
||||
#: netbox/ipam/filtersets.py:640 netbox/vpn/filtersets.py:108
|
||||
#: netbox/vpn/filtersets.py:407
|
||||
msgid "VM interface (name)"
|
||||
msgstr "Rozhraní virtuálního počítače (název)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:643 netbox/vpn/filtersets.py:113
|
||||
#: netbox/ipam/filtersets.py:645 netbox/vpn/filtersets.py:113
|
||||
msgid "VM interface (ID)"
|
||||
msgstr "Rozhraní virtuálního počítače (ID)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:648
|
||||
#: netbox/ipam/filtersets.py:650
|
||||
msgid "FHRP group (ID)"
|
||||
msgstr "Skupina FHRP (ID)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:652
|
||||
#: netbox/ipam/filtersets.py:654
|
||||
msgid "Is assigned to an interface"
|
||||
msgstr "Je přiřazen k rozhraní"
|
||||
|
||||
#: netbox/ipam/filtersets.py:656
|
||||
#: netbox/ipam/filtersets.py:658
|
||||
msgid "Is assigned"
|
||||
msgstr "Je přiřazen"
|
||||
|
||||
#: netbox/ipam/filtersets.py:668
|
||||
#: netbox/ipam/filtersets.py:670
|
||||
msgid "Service (ID)"
|
||||
msgstr "Služba (ID)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:673
|
||||
#: netbox/ipam/filtersets.py:675
|
||||
msgid "NAT inside IP address (ID)"
|
||||
msgstr "NAT uvnitř IP adresy (ID)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:1041 netbox/ipam/forms/bulk_import.py:322
|
||||
#: netbox/ipam/filtersets.py:1043 netbox/ipam/forms/bulk_import.py:322
|
||||
msgid "Assigned interface"
|
||||
msgstr "Přiřazené rozhraní"
|
||||
|
||||
#: netbox/ipam/filtersets.py:1046
|
||||
#: netbox/ipam/filtersets.py:1048
|
||||
msgid "Assigned VM interface"
|
||||
msgstr "Přiřazené rozhraní virtuálního počítače"
|
||||
|
||||
#: netbox/ipam/filtersets.py:1136
|
||||
#: netbox/ipam/filtersets.py:1138
|
||||
msgid "IP address (ID)"
|
||||
msgstr "IP adresa (ID)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:1142 netbox/ipam/models/ip.py:788
|
||||
#: netbox/ipam/filtersets.py:1144 netbox/ipam/models/ip.py:788
|
||||
msgid "IP address"
|
||||
msgstr "IP adresa"
|
||||
|
||||
#: netbox/ipam/filtersets.py:1167
|
||||
#: netbox/ipam/filtersets.py:1169
|
||||
msgid "Primary IPv4 (ID)"
|
||||
msgstr "Primární IPv4 (ID)"
|
||||
|
||||
#: netbox/ipam/filtersets.py:1172
|
||||
#: netbox/ipam/filtersets.py:1174
|
||||
msgid "Primary IPv6 (ID)"
|
||||
msgstr "Primární IPv6 (ID)"
|
||||
|
||||
@@ -12582,11 +12583,11 @@ msgstr "Ke stažení"
|
||||
#: netbox/templates/dcim/device/render_config.html:64
|
||||
#: netbox/templates/virtualization/virtualmachine/render_config.html:64
|
||||
msgid "Error rendering template"
|
||||
msgstr ""
|
||||
msgstr "Chyba při vykreslování šablony"
|
||||
|
||||
#: netbox/templates/dcim/device/render_config.html:70
|
||||
msgid "No configuration template has been assigned for this device."
|
||||
msgstr ""
|
||||
msgstr "Pro toto zařízení nebyla přiřazena žádná konfigurační šablona."
|
||||
|
||||
#: netbox/templates/dcim/device_edit.html:44
|
||||
msgid "Parent Bay"
|
||||
@@ -13452,7 +13453,7 @@ msgstr "Spustit znovu"
|
||||
#: netbox/templates/extras/script_list.html:133
|
||||
#, python-format
|
||||
msgid "Could not load scripts from module %(module)s"
|
||||
msgstr ""
|
||||
msgstr "Nelze načíst skripty z modulu %(module)s"
|
||||
|
||||
#: netbox/templates/extras/script_list.html:141
|
||||
msgid "No Scripts Found"
|
||||
@@ -14265,6 +14266,7 @@ msgstr "Přidat virtuální disk"
|
||||
#: netbox/templates/virtualization/virtualmachine/render_config.html:70
|
||||
msgid "No configuration template has been assigned for this virtual machine."
|
||||
msgstr ""
|
||||
"Pro tento virtuální počítač nebyla přiřazena žádná konfigurační šablona."
|
||||
|
||||
#: netbox/templates/vpn/ikepolicy.html:10
|
||||
#: netbox/templates/vpn/ipsecprofile.html:33 netbox/vpn/tables/crypto.py:166
|
||||
@@ -15330,12 +15332,12 @@ msgstr "Paměť (MB)"
|
||||
|
||||
#: netbox/virtualization/forms/bulk_edit.py:174
|
||||
msgid "Disk (MB)"
|
||||
msgstr ""
|
||||
msgstr "Disk (MB)"
|
||||
|
||||
#: netbox/virtualization/forms/bulk_edit.py:334
|
||||
#: netbox/virtualization/forms/filtersets.py:251
|
||||
msgid "Size (MB)"
|
||||
msgstr ""
|
||||
msgstr "Velikost (MB)"
|
||||
|
||||
#: netbox/virtualization/forms/bulk_import.py:44
|
||||
msgid "Type of cluster"
|
||||
@@ -15544,19 +15546,19 @@ msgstr "GREE"
|
||||
|
||||
#: netbox/vpn/choices.py:39
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
msgstr "WireGuard"
|
||||
|
||||
#: netbox/vpn/choices.py:40
|
||||
msgid "OpenVPN"
|
||||
msgstr ""
|
||||
msgstr "OpenVPN"
|
||||
|
||||
#: netbox/vpn/choices.py:41
|
||||
msgid "L2TP"
|
||||
msgstr ""
|
||||
msgstr "L2TP"
|
||||
|
||||
#: netbox/vpn/choices.py:42
|
||||
msgid "PPTP"
|
||||
msgstr ""
|
||||
msgstr "PPTP"
|
||||
|
||||
#: netbox/vpn/choices.py:64
|
||||
msgid "Hub"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -12,8 +12,8 @@
|
||||
# Alexander Ryazanov (alryaz) <alryaz@xavux.com>, 2024
|
||||
# Vladyslav V. Prodan, 2024
|
||||
# Jeremy Stretch, 2024
|
||||
# Michail Tatarinov, 2024
|
||||
# Artem Kotik, 2025
|
||||
# Michail Tatarinov, 2025
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
@@ -22,7 +22,7 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-01-04 05:02+0000\n"
|
||||
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
|
||||
"Last-Translator: Artem Kotik, 2025\n"
|
||||
"Last-Translator: Michail Tatarinov, 2025\n"
|
||||
"Language-Team: Russian (https://app.transifex.com/netbox-community/teams/178115/ru/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -6334,7 +6334,7 @@ msgstr "распределительный щит"
|
||||
|
||||
#: netbox/dcim/models/power.py:56
|
||||
msgid "power panels"
|
||||
msgstr "распределительный щиты"
|
||||
msgstr "распределительные щиты"
|
||||
|
||||
#: netbox/dcim/models/power.py:70
|
||||
#, python-brace-format
|
||||
@@ -9256,7 +9256,7 @@ msgstr "SLAAC"
|
||||
|
||||
#: netbox/ipam/choices.py:89
|
||||
msgid "Loopback"
|
||||
msgstr "Обратная петля"
|
||||
msgstr "Loopback"
|
||||
|
||||
#: netbox/ipam/choices.py:91
|
||||
msgid "Anycast"
|
||||
@@ -11185,7 +11185,7 @@ msgstr "Сети провайдеров"
|
||||
|
||||
#: netbox/netbox/navigation/menu.py:298
|
||||
msgid "Power Panels"
|
||||
msgstr "Распределительный щиты"
|
||||
msgstr "Распределительные щиты"
|
||||
|
||||
#: netbox/netbox/navigation/menu.py:309
|
||||
msgid "Configurations"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django import forms
|
||||
from django.apps import apps
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
@@ -143,19 +144,26 @@ class ClusterAddDevicesForm(forms.Form):
|
||||
def clean(self):
|
||||
super().clean()
|
||||
|
||||
# If the Cluster is assigned to a Site, all Devices must be assigned to that Site.
|
||||
if self.cluster.site is not None:
|
||||
# If the Cluster is assigned to a Site or Location, all Devices must be assigned to that same scope.
|
||||
if self.cluster.scope is not None:
|
||||
for device in self.cleaned_data.get('devices', []):
|
||||
if device.site != self.cluster.site:
|
||||
raise ValidationError({
|
||||
'devices': _(
|
||||
"{device} belongs to a different site ({device_site}) than the cluster ({cluster_site})"
|
||||
).format(
|
||||
device=device,
|
||||
device_site=device.site,
|
||||
cluster_site=self.cluster.site
|
||||
)
|
||||
})
|
||||
for scope_field in ['site', 'location']:
|
||||
device_scope = getattr(device, scope_field)
|
||||
if (
|
||||
self.cluster.scope_type.model_class() == apps.get_model('dcim', scope_field)
|
||||
and device_scope != self.cluster.scope
|
||||
):
|
||||
raise ValidationError({
|
||||
'devices': _(
|
||||
"{device} belongs to a different {scope_field} ({device_scope}) than the "
|
||||
"cluster ({cluster_scope})"
|
||||
).format(
|
||||
device=device,
|
||||
scope_field=scope_field,
|
||||
device_scope=device_scope,
|
||||
cluster_scope=self.cluster.scope
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
class ClusterRemoveDevicesForm(ConfirmationForm):
|
||||
|
||||
@@ -10,7 +10,7 @@ class ClusterIndex(SearchIndex):
|
||||
('description', 500),
|
||||
('comments', 5000),
|
||||
)
|
||||
display_attrs = ('type', 'group', 'status', 'tenant', 'site', 'description')
|
||||
display_attrs = ('type', 'group', 'status', 'tenant', 'scope', 'description')
|
||||
|
||||
|
||||
@register_search
|
||||
|
||||
@@ -78,7 +78,8 @@ class ClusterTable(TenancyColumnsMixin, ContactsColumnMixin, NetBoxTable):
|
||||
)
|
||||
scope = tables.Column(
|
||||
verbose_name=_('Scope'),
|
||||
linkify=True
|
||||
linkify=True,
|
||||
orderable=False
|
||||
)
|
||||
device_count = columns.LinkedCountColumn(
|
||||
viewname='dcim:device_list',
|
||||
|
||||
@@ -11,7 +11,7 @@ class WirelessLANIndex(SearchIndex):
|
||||
('auth_psk', 2000),
|
||||
('comments', 5000),
|
||||
)
|
||||
display_attrs = ('group', 'status', 'vlan', 'tenant', 'description')
|
||||
display_attrs = ('group', 'status', 'vlan', 'tenant', 'scope', 'description')
|
||||
|
||||
|
||||
@register_search
|
||||
|
||||
@@ -56,7 +56,8 @@ class WirelessLANTable(TenancyColumnsMixin, NetBoxTable):
|
||||
)
|
||||
scope = tables.Column(
|
||||
verbose_name=_('Scope'),
|
||||
linkify=True
|
||||
linkify=True,
|
||||
orderable=False
|
||||
)
|
||||
interface_count = tables.Column(
|
||||
verbose_name=_('Interfaces')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Django==5.1.4
|
||||
Django==5.1.5
|
||||
django-cors-headers==4.6.0
|
||||
django-debug-toolbar==4.4.6
|
||||
django-debug-toolbar==5.0.1
|
||||
django-filter==24.3
|
||||
django-htmx==1.21.0
|
||||
django-graphiql-debug-toolbar==0.2.0
|
||||
@@ -12,7 +12,7 @@ django-rich==1.13.0
|
||||
django-rq==3.0
|
||||
django-taggit==6.1.0
|
||||
django-tables2==2.7.5
|
||||
django-timezone-field==7.0
|
||||
django-timezone-field==7.1
|
||||
djangorestframework==3.15.2
|
||||
drf-spectacular==0.28.0
|
||||
drf-spectacular-sidecar==2024.12.1
|
||||
@@ -25,14 +25,14 @@ mkdocstrings[python-legacy]==0.27.0
|
||||
netaddr==1.3.0
|
||||
nh3==0.2.20
|
||||
Pillow==11.1.0
|
||||
psycopg[c,pool]==3.2.3
|
||||
psycopg[c,pool]==3.2.4
|
||||
PyYAML==6.0.2
|
||||
requests==2.32.3
|
||||
rq==2.1.0
|
||||
social-auth-app-django==5.4.2
|
||||
social-auth-core==4.5.4
|
||||
strawberry-graphql==0.256.1
|
||||
strawberry-graphql-django==0.53.1
|
||||
strawberry-graphql==0.258.0
|
||||
strawberry-graphql-django==0.52.0
|
||||
svgwrite==1.4.3
|
||||
tablib==3.7.0
|
||||
tzdata==2024.2
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
#!/bin/sh
|
||||
# Create a link to this file at .git/hooks/pre-commit to
|
||||
# force PEP8 validation prior to committing
|
||||
#
|
||||
# Ignored violations:
|
||||
#
|
||||
# W504: Line break after binary operator
|
||||
# E501: Line too long
|
||||
# TODO: Remove this file in NetBox v4.3
|
||||
# This script has been maintained to ease transition to the pre-commit tool.
|
||||
|
||||
exec 1>&2
|
||||
|
||||
@@ -14,48 +9,8 @@ RED='\033[0;31m'
|
||||
YELLOW='\033[0;33m'
|
||||
NOCOLOR='\033[0m'
|
||||
|
||||
printf "${YELLOW}This script is obsolete and will be removed in a future release.\n"
|
||||
printf "Please use pre-commit instead:\n"
|
||||
printf "${YELLOW}The pre-commit hook script is obsolete. Please use pre-commit instead:${NOCOLOR}\n"
|
||||
printf " pip install pre-commit\n"
|
||||
printf " pre-commit install${NOCOLOR}\n"
|
||||
|
||||
if [ -d ./venv/ ]; then
|
||||
VENV="$PWD/venv"
|
||||
if [ -e $VENV/bin/python ]; then
|
||||
PATH=$VENV/bin:$PATH
|
||||
elif [ -e $VENV/Scripts/python.exe ]; then
|
||||
PATH=$VENV/Scripts:$PATH
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ${NOVALIDATE} ]; then
|
||||
echo "${YELLOW}Skipping validation checks${NOCOLOR}"
|
||||
exit $EXIT
|
||||
fi
|
||||
|
||||
echo "Linting with ruff..."
|
||||
ruff check netbox/
|
||||
if [ $? != 0 ]; then
|
||||
EXIT=1
|
||||
fi
|
||||
|
||||
echo "Checking for missing migrations..."
|
||||
python netbox/manage.py makemigrations --dry-run --check
|
||||
if [ $? != 0 ]; then
|
||||
EXIT=1
|
||||
fi
|
||||
|
||||
git diff --cached --name-only | if grep --quiet 'netbox/project-static/'
|
||||
then
|
||||
echo "Checking UI ESLint, TypeScript, and Prettier compliance..."
|
||||
yarn --cwd "$PWD/netbox/project-static" validate
|
||||
if [ $? != 0 ]; then
|
||||
EXIT=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $EXIT != 0 ]; then
|
||||
printf "${RED}COMMIT FAILED${NOCOLOR}\n"
|
||||
fi
|
||||
|
||||
exit $EXIT
|
||||
exit 1
|
||||
|
||||
Reference in New Issue
Block a user