diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml
index ba3fdd75d..d0ded0e4c 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yaml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yaml
@@ -23,7 +23,7 @@ body:
attributes:
label: NetBox Version
description: What version of NetBox are you currently running?
- placeholder: v3.7.0
+ placeholder: v3.7.1
validations:
required: true
- type: dropdown
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index e6a5e76c2..2ad52023e 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -7,6 +7,9 @@ contact_links:
- name: ❓ Discussion
url: https://github.com/netbox-community/netbox/discussions
about: "If you're just looking for help, try starting a discussion instead."
+ - name: 🌎 Correct a Translation
+ url: https://explore.transifex.com/netbox-community/netbox/
+ about: "Spot an incorrect translation? You can propose a fix on Transifex."
- name: 💡 Plugin Idea
url: https://plugin-ideas.netbox.dev
about: "Have an idea for a plugin? Head over to the ideas board!"
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml
index 73fdaed8f..5c4fc375e 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yaml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yaml
@@ -14,7 +14,7 @@ body:
attributes:
label: NetBox version
description: What version of NetBox are you currently running?
- placeholder: v3.7.0
+ placeholder: v3.7.1
validations:
required: true
- type: dropdown
diff --git a/README.md b/README.md
index 6e50e5687..14881dd13 100644
--- a/README.md
+++ b/README.md
@@ -1,86 +1,129 @@

-
The premier source of truth powering network automation
-

+
The cornerstone of every automated network
+

+

+

+

+

+
-NetBox is the leading solution for modeling and documenting modern networks. By
-combining the traditional disciplines of IP address management (IPAM) and
-datacenter infrastructure management (DCIM) with powerful APIs and extensions,
-NetBox provides the ideal "source of truth" to power network automation.
-Available as open source software under the Apache 2.0 license, NetBox serves
-as the cornerstone for network automation in thousands of organizations.
+NetBox exists to empower network engineers. Since its release in 2016, it has become the go-to solution for modeling and documenting network infrastructure for thousands of organizations worldwide. As a successor to legacy IPAM and DCIM applications, NetBox provides a cohesive, extensive, and accessible data model for all things networked. By providing a single robust user interface and programmable APIs for everything from cable maps to device configurations, NetBox serves as the central source of truth for the modern network.
-* **Physical infrastructure:** Accurately model the physical world, from global regions down to individual racks of gear. Then connect everything - network, console, and power!
-* **Modern IPAM:** All the standard IPAM functionality you expect, plus VRF import/export tracking, VLAN management, and overlay support.
-* **Data circuits:** Confidently manage the delivery of critical circuits from various service providers, modeled seamlessly alongside your own infrastructure.
-* **Power tracking:** Map the distribution of power from upstream sources to individual feeds and outlets.
-* **Organization:** Manage tenant and contact assignments natively.
-* **Powerful search:** Easily find anything you need using a single global search function.
-* **Comprehensive logging:** Leverage both automatic change logging and user-submitted journal entries to track your network's growth over time.
-* **Endless customization:** Custom fields, custom links, tags, export templates, custom validation, reports, scripts, and more!
-* **Flexible permissions:** An advanced permissions systems enables very flexible delegation of permissions.
-* **Integrations:** Easily connect NetBox to your other tooling via its REST & GraphQL APIs.
-* **Plugins:** Not finding what you need in the core application? Try one of many community plugins - or build your own!
+
+ NetBox's Role |
+ Why NetBox? |
+ Getting Started |
+ Get Involved |
+ Project Stats |
+ Screenshots
+
-
+
+
+
+
+## NetBox's Role
+
+NetBox functions as the **source of truth** for your network infrastructure. Its job is to define and validate the _intended state_ of all network components and resources. NetBox does not interact with network nodes directly; rather, it makes this data available programmatically to purpose-built automation, monitoring, and assurance tools. This separation of duties enables the construction of a robust yet flexible automation system.
+
+
+
+
+
+The diagram above illustrates the recommended deployment architecture for an automated network, leveraging NetBox as the central authority for network state. This approach allows your team to swap out individual tools to meet changing needs while retaining a predictable, modular workflow.
+
+## Why NetBox?
+
+### Comprehensive Data Model
+
+Racks, devices, cables, IP addresses, VLANs, circuits, power, VPNs, and lots more: NetBox is built for networks. Its comprehensive and thoroughly inter-linked data model provides for natural and highly structured modeling of myriad network primitives that just isn't possible using general-purpose tools. And there's no need to waste time contemplating how to build out a database: Everything is ready to go upon installation.
+
+### Focused Development
+
+NetBox strives to meet a singular goal: Provide the best available solution for making network infrastructure programmatically accessible. Unlike "all-in-one" tools which awkwardly bolt on half-baked features in an attempt to check every box, NetBox is committed to its core function. NetBox provides the best possible solution for modeling network infrastructure, and provides rich APIs for integrating with tools that excel in other areas of network automation.
+
+### Extensible and Customizable
+
+No two networks are exactly the same. Users are empowered to extend NetBox's native data model with custom fields and tags to best suit their unique needs. You can even write your own plugins to introduce entirely new objects and functionality!
+
+### Flexible Permissions
+
+NetBox includes a fully customizable permission system, which affords administrators incredible granularity when assigning roles to users and groups. Want to restrict certain users to working only with cabling and not be able to change IP addresses? Or maybe each team should have access only to a particular tenant? NetBox enables you to craft roles as you see fit.
+
+### Custom Validation & Protection Rules
+
+The data you put into NetBox is crucial to network operations. In addition to its robust native validation rules, NetBox provides mechanisms for administrators to define their own custom validation rules for objects. Custom validation can be used both to ensure new or modified objects adhere to a set of rules, and to prevent the deletion of objects which don't meet certain criteria. (For example, you might want to prevent the deletion of a device with an "active" status.)
+
+### Device Configuration Rendering
+
+NetBox can render user-created Jinja2 templates to generate device configurations from its own data. Configuration templates can be uploaded individually or pulled automatically from an external source, such as a git repository. Rendered configurations can be retrieved via the REST API for application directly to network devices via a provisioning tool such as Ansible or Salt.
+
+### Custom Scripts
+
+Complex workflows, such as provisioning a new branch office, can be tedious to carry out via the user interface. NetBox allows you to write and upload custom scripts that can be run directly from the UI. Scripts prompt users for input and then automate the necessary tasks to greatly simplify otherwise burdensome processes.
+
+### Automated Events
+
+Users can define event rules to automatically trigger a custom script or outbound webhook in response to a NetBox event. For example, you might want to automatically update a network monitoring service whenever a new device is added to NetBox, or update a DHCP server when an IP range is allocated.
+
+### Comprehensive Change Logging
+
+NetBox automatically logs the creation, modification, and deletion of all managed objects, providing a thorough change history. Changes can be attributed to the executing user, and related changes are grouped automatically by request ID.
+
+> [!NOTE]
+> A complete list of NetBox's myriad features can be found in [the introductory documentation](https://docs.netbox.dev/en/stable/introduction/).
## Getting Started
-
-
- [](https://github.com/netbox-community/netbox)
-
- [](https://github.com/netbox-community/netbox-docker)
-
- [](https://netboxlabs.com/netbox-cloud/)
-
-
-
* Just want to explore? Check out [our public demo](https://demo.netbox.dev/) right now!
* The [official documentation](https://docs.netbox.dev) offers a comprehensive introduction.
* Check out [our wiki](https://github.com/netbox-community/netbox/wiki/Community-Contributions) for even more projects to get the most out of NetBox!
+
+ 
+ Looking for an enterprise solution? Check out NetBox Cloud!
+
+
## Get Involved
* Follow [@NetBoxOfficial](https://twitter.com/NetBoxOfficial) on Twitter!
* Join the conversation on [the discussion forum](https://github.com/netbox-community/netbox/discussions) and [Slack](https://netdev.chat/)!
* Already a power user? You can [suggest a feature](https://github.com/netbox-community/netbox/issues/new?assignees=&labels=type%3A+feature&template=feature_request.yaml) or [report a bug](https://github.com/netbox-community/netbox/issues/new?assignees=&labels=type%3A+bug&template=bug_report.yaml) on GitHub.
* Contributions from the community are encouraged and appreciated! Check out our [contributing guide](CONTRIBUTING.md) to get started.
+* [Share your idea](https://plugin-ideas.netbox.dev/) for a new plugin, or [learn how to build one](https://github.com/netbox-community/netbox-plugin-tutorial) yourself!
## Project Stats
-
-
-## Sponsors
-
-
-
- [](https://netboxlabs.com)
-
- [](https://try.digitalocean.com/developer-cloud)
-
- [](https://sentry.io)
-
- [](https://metal.equinix.com)
-
- [](https://onemindservices.com)
-
-
+
## Screenshots
-")
-
-
-
-
-
-
+
+ NetBox Dashboard (Light Mode)
+
+
+
+ NetBox Dashboard (Dark Mode)
+
+
+
+ Prefixes List
+
+
+
+ Rack View
+
+
+
+ Cable Trace
+
+
diff --git a/docs/administration/authentication/microsoft-azure-ad.md b/docs/administration/authentication/microsoft-azure-ad.md
index ee24e8232..a5e24b0c9 100644
--- a/docs/administration/authentication/microsoft-azure-ad.md
+++ b/docs/administration/authentication/microsoft-azure-ad.md
@@ -73,7 +73,7 @@ You should be redirected to Microsoft's authentication portal. Enter the usernam
If successful, you will be redirected back to the NetBox UI, and will be logged in as the AD user. You can verify this by navigating to your profile (using the button at top right).
-This user account has been replicated locally to NetBox, and can now be assigned groups and permissions within the NetBox admin UI.
+This user account has been replicated locally to NetBox, and can now be assigned groups and permissions by navigating to Admin > Permissions.
## Troubleshooting
diff --git a/docs/administration/authentication/okta.md b/docs/administration/authentication/okta.md
index ff552d730..67c0ea41b 100644
--- a/docs/administration/authentication/okta.md
+++ b/docs/administration/authentication/okta.md
@@ -67,4 +67,4 @@ You should be redirected to Okta's authentication portal. Enter the username/ema
If successful, you will be redirected back to the NetBox UI, and will be logged in as the Okta user. You can verify this by navigating to your profile (using the button at top right).
-This user account has been replicated locally to NetBox, and can now be assigned groups and permissions within the NetBox admin UI.
+This user account has been replicated locally to NetBox, and can now be assigned groups and permissions by navigating to Admin > Permissions.
diff --git a/docs/administration/authentication/overview.md b/docs/administration/authentication/overview.md
index 8a8b8f60b..f81a50c0b 100644
--- a/docs/administration/authentication/overview.md
+++ b/docs/administration/authentication/overview.md
@@ -2,9 +2,9 @@
## Local Authentication
-Local user accounts and groups can be created in NetBox under the "Authentication and Authorization" section of the administrative user interface. This interface is available only to users with the "staff" permission enabled.
+Local user accounts and groups can be created in NetBox under the "Authentication" section in the "Admin" menu. This section is available only to users with the "staff" permission enabled.
-At a minimum, each user account must have a username and password set. User accounts may also denote a first name, last name, and email address. [Permissions](../permissions.md) may also be assigned to users and/or groups within the admin UI.
+At a minimum, each user account must have a username and password set. User accounts may also denote a first name, last name, and email address. [Permissions](../permissions.md) may also be assigned to users and/or groups under Admin > Permissions.
## Remote Authentication
diff --git a/docs/configuration/index.md b/docs/configuration/index.md
index 70466d029..6a2ecdc7f 100644
--- a/docs/configuration/index.md
+++ b/docs/configuration/index.md
@@ -46,4 +46,4 @@ The configuration file may be modified at any time. However, the WSGI service (e
$ sudo systemctl restart netbox
```
-Configuration parameters which are set via the admin UI (those listed under "dynamic settings") take effect immediately.
+Dynamic configuration parameters (those which can be modified via the UI) take effect immediately.
diff --git a/docs/customization/custom-scripts.md b/docs/customization/custom-scripts.md
index 0b1ed11df..e2bc53cfc 100644
--- a/docs/customization/custom-scripts.md
+++ b/docs/customization/custom-scripts.md
@@ -288,9 +288,9 @@ An IPv4 or IPv6 network with a mask. Returns a `netaddr.IPNetwork` object. Two a
## Running Custom Scripts
!!! note
- To run a custom script, a user must be assigned via permissions for `Extras > Script`, `Extras > ScriptModule`, and `Core > ManagedFile` objects. They must also be assigned the `extras.run_script` permission. This is achieved by assigning the user (or group) a permission on the Script object and specifying the `run` action in the admin UI as shown below.
+ To run a custom script, a user must be assigned permissions for `Extras > Script`, `Extras > Script Module`, and `Core > Managed File` objects. They must also be assigned the `extras.run_script` permission. This is achieved by assigning the user (or group) a permission on the Script object and specifying the `run` action in "Permissions" as shown below.
- 
+ 
### Via the Web UI
diff --git a/docs/customization/reports.md b/docs/customization/reports.md
index a821c5da7..8b0fc44f3 100644
--- a/docs/customization/reports.md
+++ b/docs/customization/reports.md
@@ -132,9 +132,9 @@ Once you have created a report, it will appear in the reports list. Initially, r
## Running Reports
!!! note
- To run a report, a user must be assigned via permissions for `Extras > Report`, `Extras > ReportModule`, and `Core > ManagedFile` objects. They must also be assigned the `extras.run_report` permission. This is achieved by assigning the user (or group) a permission on the Report object and specifying the `run` action in the admin UI as shown below.
+ To run a report, a user must be assigned permissions for `Extras > Report`, `Extras > Report Module`, and `Core > Managed File` objects. They must also be assigned the `extras.run_report` permission. This is achieved by assigning the user (or group) a permission on the Report object and specifying the `run` action in "Permissions" as shown below.
- 
+ 
### Via the Web UI
diff --git a/docs/development/release-checklist.md b/docs/development/release-checklist.md
index 68b777111..2af640546 100644
--- a/docs/development/release-checklist.md
+++ b/docs/development/release-checklist.md
@@ -80,6 +80,18 @@ Run the following command to update the device type definition validation schema
This will automatically update the schema file at `contrib/generated_schema.json`.
+### Update & Compile Translations
+
+Log into [Transifex](https://app.transifex.com/netbox-community/netbox/dashboard/) to download the updated string maps. Download the resource (portable object, or `.po`) file for each language and save them to `netbox/translations/$lang/LC_MESSAGES/django.po`, overwriting the current files. (Be sure to click the **Download for use** link.)
+
+
+
+Once the resource files for all languages have been updated, compile the machine object (`.mo`) files using the `compilemessages` management command:
+
+```nohighlight
+./manage.py compilemessages
+```
+
### Update Version and Changelog
* Update the `VERSION` constant in `settings.py` to the new release version.
@@ -90,7 +102,7 @@ Commit these changes to the `develop` branch and push upstream.
### Verify CI Build Status
-Ensure that continuous integration testing on the `develop` branch is completing successfully. If it fails, take action to correct the failure before proceding with the release.
+Ensure that continuous integration testing on the `develop` branch is completing successfully. If it fails, take action to correct the failure before proceeding with the release.
### Submit a Pull Request
diff --git a/docs/development/translations.md b/docs/development/translations.md
new file mode 100644
index 000000000..e40f996c5
--- /dev/null
+++ b/docs/development/translations.md
@@ -0,0 +1,30 @@
+# Translations
+
+NetBox coordinates all translation work using the [Transifex](https://explore.transifex.com/netbox-community/netbox/) platform. Signing up for a Transifex account is free.
+
+All language translations in NetBox are generated from the source file found at `netbox/translations/en/LC_MESSAGES/django.po`. This file contains the original English strings with empty mappings, and is generated as part of NetBox's release process. Transifex updates source strings from this file on a recurring basis, so new translation strings will appear in the platform automatically as it is updated in the code base.
+
+Reviewers log into Transifex and navigate to their designated language(s) to translate strings. The initial translation for most strings will be machine-generated via the AWS Translate service. Human reviewers are responsible for reviewing these translations and making corrections where necessary.
+
+Immediately prior to each NetBox release, the translation maps for all completed languages will be downloaded from Transifex, compiled, and checked into the NetBox code base by a maintainer.
+
+## Updating Translation Sources
+
+To update the English `.po` file from which all translations are derived, use the `makemessages` management command:
+
+```nohighlight
+./manage.py makemessages -l en
+```
+
+Then, commit the change and push to the `develop` branch on GitHub. After some time, any new strings will appear for translation on Transifex automatically.
+
+## Proposing New Languages
+
+If you'd like to add support for a new language to NetBox, the first step is to [submit a GitHub issue](https://github.com/netbox-community/netbox/issues/new?assignees=&labels=type%3A+translation&projects=&template=translation.yaml) to capture the proposal. While we'd like to add as many languages as possible, we do need to limit the rate at which new languages are added. New languages will be selected according to community interest and the number of volunteers who sign up as translators.
+
+Once a proposed language has been approved, a NetBox maintainer will:
+
+* Add it to the Transifex platform
+* Designate one or more reviewers
+* Create the initial machine-generated translations for review
+* Add it to the list of supported languages
diff --git a/docs/features/configuration-rendering.md b/docs/features/configuration-rendering.md
index a87a6eae4..44cacc684 100644
--- a/docs/features/configuration-rendering.md
+++ b/docs/features/configuration-rendering.md
@@ -39,7 +39,7 @@ When rendered for a specific NetBox device, the template's `device` variable wil
### Context Data
-The objet for which the configuration is being rendered is made available as template context as `device` or `virtualmachine` for devices and virtual machines, respectively. Additionally, NetBox model classes can be accessed by the app or plugin in which they reside. For example:
+The object for which the configuration is being rendered is made available as template context as `device` or `virtualmachine` for devices and virtual machines, respectively. Additionally, NetBox model classes can be accessed by the app or plugin in which they reside. For example:
```
There are {{ dcim.Site.objects.count() }} sites.
@@ -70,6 +70,11 @@ This request will trigger resolution of the device's preferred config template i
If no config template has been assigned to any of these three objects, the request will fail.
+The configuration can be rendered as JSON or as plaintext by setting the `Accept:` HTTP header. For example:
+
+* `Accept: application/json`
+* `Accept: text/plain`
+
### General Purpose Use
NetBox config templates can also be rendered without being tied to any specific device, using a separate general purpose REST API endpoint. Any data included with a POST request to this endpoint will be passed as context data for the template.
diff --git a/docs/features/synchronized-data.md b/docs/features/synchronized-data.md
index a070d0ce1..8c95c8779 100644
--- a/docs/features/synchronized-data.md
+++ b/docs/features/synchronized-data.md
@@ -1,6 +1,6 @@
# Synchronized Data
-Several models in NetBox support the automatic synchronization of local data from a designated remote source. For example, [configuration templates](./configuration-rendering.md) defined in NetBox can source their content from text files stored in a remote git repository. This accomplished using the core [data source](../models/core/datasource.md) and [data file](../models/core/datafile.md) models.
+Several models in NetBox support the automatic synchronization of local data from a designated remote source. For example, [configuration templates](./configuration-rendering.md) defined in NetBox can source their content from text files stored in a remote git repository. This is accomplished using the core [data source](../models/core/datasource.md) and [data file](../models/core/datafile.md) models.
To enable remote data synchronization, the NetBox administrator first designates one or more remote data sources. NetBox currently supports the following source types:
diff --git a/docs/index.md b/docs/index.md
index 84334337b..5ef650ca6 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -4,7 +4,7 @@
NetBox is the leading solution for modeling and documenting modern networks. By combining the traditional disciplines of IP address management (IPAM) and datacenter infrastructure management (DCIM) with powerful APIs and extensions, NetBox provides the ideal "source of truth" to power network automation. Read on to discover why thousands of organizations worldwide put NetBox at the heart of their infrastructure.
-[](./media/screenshots/netbox-ui.png)
+[](./media/screenshots/home-light.png)
## :material-server-network: Built for Networks
diff --git a/docs/integrations/webhooks.md b/docs/integrations/webhooks.md
index 8913fd99c..20e9bc8c0 100644
--- a/docs/integrations/webhooks.md
+++ b/docs/integrations/webhooks.md
@@ -106,6 +106,6 @@ Content-Type: application/x-www-form-urlencoded
------------
```
-Note that `webhook_receiver` does not actually _do_ anything with the information received: It merely prints the request headers and body for inspection.
+Note that `webhook_receiver` does not actually _do_ anything with the information received: It merely prints the request headers and body for inspection. If you don't see any output, check that the `rqworker` process is running and that webhook events are being placed into the queue.
-Now, when the NetBox webhook is triggered and processed, you should see its headers and content appear in the terminal where the webhook receiver is listening. If you don't, check that the `rqworker` process is running and that webhook events are being placed into the queue (visible under the NetBox admin UI).
+Webhook results can be found in the NetBox admin UI under the Background Tasks section. You can see any finished or failed runs, as well as the error log for failed webhooks.
diff --git a/docs/media/development/transifex_download.png b/docs/media/development/transifex_download.png
new file mode 100644
index 000000000..99429ce11
Binary files /dev/null and b/docs/media/development/transifex_download.png differ
diff --git a/docs/media/misc/netbox_cloud.png b/docs/media/misc/netbox_cloud.png
new file mode 100644
index 000000000..f9deca674
Binary files /dev/null and b/docs/media/misc/netbox_cloud.png differ
diff --git a/docs/media/misc/reference_architecture.png b/docs/media/misc/reference_architecture.png
new file mode 100644
index 000000000..89ed4478d
Binary files /dev/null and b/docs/media/misc/reference_architecture.png differ
diff --git a/docs/media/admin_ui_run_permission.png b/docs/media/run_permission.png
similarity index 100%
rename from docs/media/admin_ui_run_permission.png
rename to docs/media/run_permission.png
diff --git a/docs/media/screenshots/cable-trace.png b/docs/media/screenshots/cable-trace.png
index b35272016..e228d1786 100644
Binary files a/docs/media/screenshots/cable-trace.png and b/docs/media/screenshots/cable-trace.png differ
diff --git a/docs/media/screenshots/home-dark.png b/docs/media/screenshots/home-dark.png
index 718413445..7b060785f 100644
Binary files a/docs/media/screenshots/home-dark.png and b/docs/media/screenshots/home-dark.png differ
diff --git a/docs/media/screenshots/home-light.png b/docs/media/screenshots/home-light.png
new file mode 100644
index 000000000..1eaca3ef0
Binary files /dev/null and b/docs/media/screenshots/home-light.png differ
diff --git a/docs/media/screenshots/netbox-ui.png b/docs/media/screenshots/netbox-ui.png
deleted file mode 100644
index 70cd77089..000000000
Binary files a/docs/media/screenshots/netbox-ui.png and /dev/null differ
diff --git a/docs/media/screenshots/prefixes-list.png b/docs/media/screenshots/prefixes-list.png
index 927a7a04e..7220a8817 100644
Binary files a/docs/media/screenshots/prefixes-list.png and b/docs/media/screenshots/prefixes-list.png differ
diff --git a/docs/media/screenshots/rack.png b/docs/media/screenshots/rack.png
index dbe9718f7..7179efda3 100644
Binary files a/docs/media/screenshots/rack.png and b/docs/media/screenshots/rack.png differ
diff --git a/docs/release-notes/version-3.7.md b/docs/release-notes/version-3.7.md
index 127e241d7..6dfa699df 100644
--- a/docs/release-notes/version-3.7.md
+++ b/docs/release-notes/version-3.7.md
@@ -1,5 +1,23 @@
# NetBox v3.7
+## v3.7.1 (2024-01-17)
+
+### Bug Fixes
+
+* [#13844](https://github.com/netbox-community/netbox/issues/13844) - Use `available_at_site` filter when filtering VLANs under prefix form
+* [#14663](https://github.com/netbox-community/netbox/issues/14663) - Fix tunnel creation when setting initial termination to a VM interface
+* [#14706](https://github.com/netbox-community/netbox/issues/14706) - Relax one-to-one mapping of tunnel termination to IP address
+* [#14709](https://github.com/netbox-community/netbox/issues/14709) - Fix typo in tunnel termination type choice name
+* [#14749](https://github.com/netbox-community/netbox/issues/14749) - Remove errant translation wrapper from `installed_device` on DeviceBay
+* [#14778](https://github.com/netbox-community/netbox/issues/14778) - Custom field API serializer should accept null values for all optional fields
+* [#14791](https://github.com/netbox-community/netbox/issues/14791) - Hide available prefixes when searching within a parent prefix
+* [#14793](https://github.com/netbox-community/netbox/issues/14793) - Add missing Diffie-Hellman group 15
+* [#14816](https://github.com/netbox-community/netbox/issues/14816) - Ensure default contact assignment ordering is consistent
+* [#14817](https://github.com/netbox-community/netbox/issues/14817) - Relax required fields for IKE & IPSec models on bulk import
+* [#14827](https://github.com/netbox-community/netbox/issues/14827) - Ensure all matching event rules are processed in response to an event
+
+---
+
## v3.7.0 (2023-12-29)
### Breaking Changes
@@ -10,6 +28,7 @@
* The internal ConfigRevision model has moved from `extras` to `core`. Configuration history will be retained throughout the upgrade process.
* The [L2VPN](../models/vpn/l2vpn.md) and [L2VPNTermination](../models/vpn/l2vpntermination.md) models have moved from the `ipam` app to the new `vpn` app. All object data will be retained, however please note that the relevant API endpoints have likewise moved to `/api/vpn/`.
* The `CustomFieldsMixin`, `SavedFiltersMixin`, and `TagsMixin` classes have moved from the `extras.forms.mixins` module to `netbox.forms.mixins`.
+* The `netbox.models.features.WebhooksMixin` class has been renamed to `EventRulesMixin`.
### New Features
diff --git a/mkdocs.yml b/mkdocs.yml
index 5a7e00c2c..e1128578a 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -286,6 +286,7 @@ nav:
- User Preferences: 'development/user-preferences.md'
- Web UI: 'development/web-ui.md'
- Internationalization: 'development/internationalization.md'
+ - Translations: 'development/translations.md'
- Release Checklist: 'development/release-checklist.md'
- git Cheat Sheet: 'development/git-cheat-sheet.md'
- Release Notes:
diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py
index ef235078f..88dddb312 100644
--- a/netbox/dcim/models/device_components.py
+++ b/netbox/dcim/models/device_components.py
@@ -1115,7 +1115,7 @@ class DeviceBay(ComponentModel, TrackingModelMixin):
installed_device = models.OneToOneField(
to='dcim.Device',
on_delete=models.SET_NULL,
- related_name=_('parent_bay'),
+ related_name='parent_bay',
blank=True,
null=True
)
diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py
index 60a30aed2..f5e99b443 100644
--- a/netbox/extras/api/serializers.py
+++ b/netbox/extras/api/serializers.py
@@ -126,11 +126,15 @@ class CustomFieldSerializer(ValidatedModelSerializer):
type = ChoiceField(choices=CustomFieldTypeChoices)
object_type = ContentTypeField(
queryset=ContentType.objects.all(),
- required=False
+ required=False,
+ allow_null=True
)
filter_logic = ChoiceField(choices=CustomFieldFilterLogicChoices, required=False)
data_type = serializers.SerializerMethodField()
- choice_set = NestedCustomFieldChoiceSetSerializer(required=False)
+ choice_set = NestedCustomFieldChoiceSetSerializer(
+ required=False,
+ allow_null=True
+ )
ui_visible = ChoiceField(choices=CustomFieldUIVisibleChoices, required=False)
ui_editable = ChoiceField(choices=CustomFieldUIEditableChoices, required=False)
diff --git a/netbox/extras/events.py b/netbox/extras/events.py
index 6d0654929..90cca83cd 100644
--- a/netbox/extras/events.py
+++ b/netbox/extras/events.py
@@ -81,7 +81,7 @@ def process_event_rules(event_rules, model_name, event, data, username, snapshot
# Evaluate event rule conditions (if any)
if not event_rule.eval_conditions(data):
- return
+ continue
# Webhooks
if event_rule.action_type == EventRuleActionChoices.WEBHOOK:
diff --git a/netbox/ipam/forms/model_forms.py b/netbox/ipam/forms/model_forms.py
index 6c445ef27..34b7c5958 100644
--- a/netbox/ipam/forms/model_forms.py
+++ b/netbox/ipam/forms/model_forms.py
@@ -214,7 +214,7 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
required=False,
selector=True,
query_params={
- 'site_id': '$site',
+ 'available_at_site': '$site',
},
label=_('VLAN'),
)
diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py
index 1598f0321..5ff6d2323 100644
--- a/netbox/ipam/views.py
+++ b/netbox/ipam/views.py
@@ -604,7 +604,7 @@ class PrefixIPAddressesView(generic.ObjectChildrenView):
return parent.get_child_ips().restrict(request.user, 'view').prefetch_related('vrf', 'tenant', 'tenant__group')
def prep_table_data(self, request, queryset, parent):
- if not get_table_ordering(request, self.table):
+ if not request.GET.get('q') and not get_table_ordering(request, self.table):
return add_available_ipaddresses(parent.prefix, queryset, parent.is_pool)
return queryset
diff --git a/netbox/netbox/models/features.py b/netbox/netbox/models/features.py
index 0cba27318..a13b84bed 100644
--- a/netbox/netbox/models/features.py
+++ b/netbox/netbox/models/features.py
@@ -30,13 +30,13 @@ __all__ = (
'CustomFieldsMixin',
'CustomLinksMixin',
'CustomValidationMixin',
+ 'EventRulesMixin',
'ExportTemplatesMixin',
'ImageAttachmentsMixin',
'JobsMixin',
'JournalingMixin',
'SyncedDataMixin',
'TagsMixin',
- 'EventRulesMixin',
)
diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py
index faf372c2c..61d330146 100644
--- a/netbox/netbox/settings.py
+++ b/netbox/netbox/settings.py
@@ -28,7 +28,7 @@ from netbox.plugins import PluginConfig
# Environment setup
#
-VERSION = '3.7.0'
+VERSION = '3.7.1'
# Hostname
HOSTNAME = platform.node()
diff --git a/netbox/tenancy/api/views.py b/netbox/tenancy/api/views.py
index 71a4961c3..25c0ab403 100644
--- a/netbox/tenancy/api/views.py
+++ b/netbox/tenancy/api/views.py
@@ -83,6 +83,6 @@ class ContactViewSet(NetBoxModelViewSet):
class ContactAssignmentViewSet(NetBoxModelViewSet):
- queryset = ContactAssignment.objects.prefetch_related('object', 'contact', 'role')
+ queryset = ContactAssignment.objects.prefetch_related('content_type', 'object', 'contact', 'role', 'tags')
serializer_class = serializers.ContactAssignmentSerializer
filterset_class = filtersets.ContactAssignmentFilterSet
diff --git a/netbox/tenancy/migrations/0014_contactassignment_ordering.py b/netbox/tenancy/migrations/0014_contactassignment_ordering.py
new file mode 100644
index 000000000..66f08aa2a
--- /dev/null
+++ b/netbox/tenancy/migrations/0014_contactassignment_ordering.py
@@ -0,0 +1,17 @@
+# Generated by Django 4.2.8 on 2024-01-17 15:27
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('tenancy', '0013_gfk_indexes'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='contactassignment',
+ options={'ordering': ('contact', 'priority', 'role', 'pk')},
+ ),
+ ]
diff --git a/netbox/tenancy/models/contacts.py b/netbox/tenancy/models/contacts.py
index 81e11a7dd..664fff098 100644
--- a/netbox/tenancy/models/contacts.py
+++ b/netbox/tenancy/models/contacts.py
@@ -140,7 +140,7 @@ class ContactAssignment(CustomFieldsMixin, ExportTemplatesMixin, TagsMixin, Chan
clone_fields = ('content_type', 'object_id', 'role', 'priority')
class Meta:
- ordering = ('priority', 'contact')
+ ordering = ('contact', 'priority', 'role', 'pk')
indexes = (
models.Index(fields=('content_type', 'object_id')),
)
diff --git a/netbox/tenancy/views.py b/netbox/tenancy/views.py
index 27d5750ac..1d2fceb04 100644
--- a/netbox/tenancy/views.py
+++ b/netbox/tenancy/views.py
@@ -25,7 +25,7 @@ class ObjectContactsView(generic.ObjectChildrenView):
return ContactAssignment.objects.restrict(request.user, 'view').filter(
content_type=ContentType.objects.get_for_model(parent),
object_id=parent.pk
- )
+ ).order_by('priority', 'contact', 'role')
def get_table(self, *args, **kwargs):
table = super().get_table(*args, **kwargs)
diff --git a/netbox/translations/fr/LC_MESSAGES/django.mo b/netbox/translations/fr/LC_MESSAGES/django.mo
index daded1363..ff968750c 100644
Binary files a/netbox/translations/fr/LC_MESSAGES/django.mo and b/netbox/translations/fr/LC_MESSAGES/django.mo differ
diff --git a/netbox/translations/fr/LC_MESSAGES/django.po b/netbox/translations/fr/LC_MESSAGES/django.po
index 91740bb5c..8c0de5a65 100644
--- a/netbox/translations/fr/LC_MESSAGES/django.po
+++ b/netbox/translations/fr/LC_MESSAGES/django.po
@@ -5,6 +5,7 @@
#
# Translators:
# Jeremy Stretch, 2023
+# Jonathan Senecal, 2024
#
#, fuzzy
msgid ""
@@ -13,7 +14,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-12-21 17:54+0000\n"
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
-"Last-Translator: Jeremy Stretch, 2023\n"
+"Last-Translator: Jonathan Senecal, 2024\n"
"Language-Team: French (https://app.transifex.com/netbox-community/teams/178115/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -110,7 +111,7 @@ msgstr "Région (ID)"
#: virtualization/filtersets.py:52 virtualization/filtersets.py:179
#: vpn/filtersets.py:325
msgid "Region (slug)"
-msgstr "Région (limace)"
+msgstr "Région (slug)"
#: circuits/filtersets.py:42 circuits/filtersets.py:195 dcim/filtersets.py:194
#: dcim/filtersets.py:269 dcim/filtersets.py:377 dcim/filtersets.py:894
@@ -188,11 +189,11 @@ msgstr "Site"
#: virtualization/filtersets.py:75 virtualization/filtersets.py:202
#: vpn/filtersets.py:335
msgid "Site (slug)"
-msgstr "Site (limace)"
+msgstr "Site (slug)"
#: circuits/filtersets.py:65
msgid "ASN (ID)"
-msgstr "ASN (IDENTIFIANT)"
+msgstr "ASN (ID)"
#: circuits/filtersets.py:86 circuits/filtersets.py:112
#: circuits/filtersets.py:146
@@ -210,7 +211,7 @@ msgstr "Compte fournisseur (ID)"
#: circuits/filtersets.py:162
msgid "Provider network (ID)"
-msgstr "Réseau de fournisseurs (ID)"
+msgstr "Réseau fournisseur (ID)"
#: circuits/filtersets.py:166
msgid "Circuit type (ID)"
@@ -256,7 +257,7 @@ msgstr "Circuit"
#: circuits/filtersets.py:254
msgid "ProviderNetwork (ID)"
-msgstr "Réseau de fournisseurs (ID)"
+msgstr "Réseau fournisseur (ID)"
#: circuits/forms/bulk_edit.py:25 circuits/forms/filtersets.py:56
#: circuits/forms/model_forms.py:26 circuits/tables/providers.py:33
@@ -266,7 +267,7 @@ msgstr "Réseau de fournisseurs (ID)"
#: netbox/navigation/menu.py:160 netbox/navigation/menu.py:163
#: templates/circuits/provider.html:24
msgid "ASNs"
-msgstr "SAN"
+msgstr "Numéros d'AS"
#: circuits/forms/bulk_edit.py:29 circuits/forms/bulk_edit.py:51
#: circuits/forms/bulk_edit.py:78 circuits/forms/bulk_edit.py:99
@@ -363,7 +364,7 @@ msgstr "SAN"
#: vpn/forms/bulk_edit.py:277 wireless/forms/bulk_edit.py:28
#: wireless/forms/bulk_edit.py:81 wireless/forms/bulk_edit.py:128
msgid "Description"
-msgstr "Descriptif"
+msgstr "Description"
#: circuits/forms/bulk_edit.py:46 circuits/forms/bulk_edit.py:68
#: circuits/forms/bulk_edit.py:118 circuits/forms/bulk_import.py:35
@@ -449,7 +450,7 @@ msgstr "Type"
#: circuits/forms/bulk_edit.py:123 circuits/forms/bulk_import.py:82
#: circuits/forms/filtersets.py:139 circuits/forms/model_forms.py:97
msgid "Provider account"
-msgstr "Compte du fournisseur"
+msgstr "Identifiant de compte du prestataire"
#: circuits/forms/bulk_edit.py:131 circuits/forms/bulk_import.py:95
#: circuits/forms/filtersets.py:150 core/forms/filtersets.py:34
@@ -504,7 +505,7 @@ msgstr "Compte du fournisseur"
#: wireless/forms/filtersets.py:82 wireless/tables/wirelesslan.py:52
#: wireless/tables/wirelesslink.py:19
msgid "Status"
-msgstr "État"
+msgstr "Statut"
#: circuits/forms/bulk_edit.py:137 circuits/forms/bulk_import.py:100
#: circuits/forms/filtersets.py:119 dcim/forms/bulk_edit.py:120
@@ -575,7 +576,7 @@ msgstr "Date de résiliation"
#: circuits/forms/bulk_edit.py:153 circuits/forms/filtersets.py:186
msgid "Commit rate (Kbps)"
-msgstr "Taux de validation (Kbits/s)"
+msgstr "Débit engagé (Kbits/s)"
#: circuits/forms/bulk_edit.py:168 circuits/forms/model_forms.py:111
msgid "Service Parameters"
@@ -597,7 +598,7 @@ msgstr "Paramètres du service"
#: vpn/forms/model_forms.py:146 vpn/forms/model_forms.py:404
#: wireless/forms/model_forms.py:55 wireless/forms/model_forms.py:160
msgid "Tenancy"
-msgstr "Location"
+msgstr "Utilisateur"
#: circuits/forms/bulk_import.py:38 circuits/forms/bulk_import.py:53
#: circuits/forms/bulk_import.py:79
@@ -608,11 +609,11 @@ msgstr "Prestataire assigné"
#: dcim/forms/bulk_import.py:380 dcim/forms/bulk_import.py:1092
#: dcim/forms/bulk_import.py:1171 extras/forms/bulk_import.py:229
msgid "RGB color in hexadecimal. Example:"
-msgstr "Couleur RGB en hexadécimal. Exemple :"
+msgstr "Couleur RVB en hexadécimal. Exemple :"
#: circuits/forms/bulk_import.py:85
msgid "Assigned provider account"
-msgstr "Compte fournisseur attribué"
+msgstr "Compte prestataire attribué"
#: circuits/forms/bulk_import.py:92
msgid "Type of circuit"
@@ -1174,7 +1175,7 @@ msgstr "Courir"
#: core/choices.py:58 extras/choices.py:211
msgid "Errored"
-msgstr "Errulé"
+msgstr "En erreur"
#: core/data_backends.py:29 templates/dcim/interface.html:224
msgid "Local"
@@ -1188,7 +1189,7 @@ msgstr "Nom d'utilisateur"
#: core/data_backends.py:49 core/data_backends.py:55
msgid "Only used for cloning with HTTP(S)"
-msgstr "Utilisé uniquement pour le clonage avec HTTP (S)"
+msgstr "Utilisé uniquement pour le clonage avec HTTP(S)"
#: core/data_backends.py:53 templates/account/base.html:17
#: templates/account/password.html:11 users/forms/model_forms.py:171
@@ -1343,7 +1344,7 @@ msgstr "Paramètres du backend"
#: core/forms/model_forms.py:94
msgid "File Upload"
-msgstr "Téléchargement de fichiers"
+msgstr "Téléversement de fichiers"
#: core/forms/model_forms.py:147 templates/core/configrevision.html:43
#: templates/dcim/rack_elevation_list.html:6
@@ -1394,7 +1395,7 @@ msgstr "Divers"
#: core/forms/model_forms.py:158
msgid "Config Revision"
-msgstr "Révision de la configuration"
+msgstr "Révision de configuration"
#: core/forms/model_forms.py:197
msgid "This parameter has been defined statically and cannot be modified."
@@ -1426,7 +1427,7 @@ msgstr "données de configuration"
#: core/models/config.py:36
msgid "config revision"
-msgstr "révision de la configuration"
+msgstr "révision de configuration"
#: core/models/config.py:37
msgid "config revisions"
@@ -7596,7 +7597,7 @@ msgstr "Secondaire"
#: ipam/choices.py:91
msgid "Anycast"
-msgstr "N'importe quel cast"
+msgstr "Anycast"
#: ipam/choices.py:115
msgid "Standard"
@@ -7791,8 +7792,8 @@ msgstr "C'est une piscine"
#: ipam/forms/bulk_edit.py:257 ipam/forms/bulk_edit.py:301
#: ipam/models/ip.py:271 ipam/models/ip.py:538
#, python-format
-msgid "Treat as 100% utilized"
-msgstr "Traiter comme utilisé à 100 %"
+msgid "Treat as 100%% utilized"
+msgstr "Traiter comme utilisé à 100%%"
#: ipam/forms/bulk_edit.py:349 ipam/models/ip.py:771
msgid "DNS name"
@@ -8009,7 +8010,7 @@ msgstr "Famille d'adresses"
#: ipam/forms/filtersets.py:118 templates/ipam/asnrange.html:26
msgid "Range"
-msgstr "Gamme"
+msgstr "Plage"
#: ipam/forms/filtersets.py:127
msgid "Start"
@@ -8029,8 +8030,8 @@ msgstr "Présent en VRF"
#: ipam/forms/filtersets.py:243 ipam/forms/filtersets.py:282
#, python-format
-msgid "Marked as 100% utilized"
-msgstr "Marqué comme étant utilisé à 100 %"
+msgid "Marked as 100%% utilized"
+msgstr "Marqué comme étant utilisé à 100%%"
#: ipam/forms/filtersets.py:297
msgid "Device/VM"
@@ -8094,7 +8095,7 @@ msgstr "Agrégat"
#: ipam/forms/model_forms.py:134 templates/ipam/asnrange.html:12
msgid "ASN Range"
-msgstr "Gamme ASN"
+msgstr "Plage ASN"
#: ipam/forms/model_forms.py:230
msgid "Site/VLAN Assignment"
@@ -8102,7 +8103,7 @@ msgstr "Affectation de site/VLAN"
#: ipam/forms/model_forms.py:256 templates/ipam/iprange.html:11
msgid "IP Range"
-msgstr "Gamme IP"
+msgstr "Plage IP"
#: ipam/forms/model_forms.py:285 ipam/forms/model_forms.py:454
#: templates/ipam/fhrpgroup.html:19 templates/ipam/ipaddress_edit.html:52
@@ -8184,11 +8185,11 @@ msgstr "démarrer"
#: ipam/models/asns.py:51
msgid "ASN range"
-msgstr "Gamme ASN"
+msgstr "Plage ASN"
#: ipam/models/asns.py:52
msgid "ASN ranges"
-msgstr "Gammes ASN"
+msgstr "Plages ASN"
#: ipam/models/asns.py:72
#, python-brace-format
@@ -8380,7 +8381,7 @@ msgstr "plage IP"
#: ipam/models/ip.py:548
msgid "IP ranges"
-msgstr "Gammes IP"
+msgstr "Plages IP"
#: ipam/models/ip.py:564
msgid "Starting and ending IP address versions must match"
@@ -8636,7 +8637,7 @@ msgstr "Utilisation"
#: ipam/tables/ip.py:170 netbox/navigation/menu.py:149
msgid "IP Ranges"
-msgstr "Gammes d'adresses IP"
+msgstr "Plages d'adresses IP"
#: ipam/tables/ip.py:220
msgid "Prefix (Flat)"
@@ -8706,7 +8707,7 @@ msgstr "Préfixes pour enfants"
#: ipam/views.py:571
msgid "Child Ranges"
-msgstr "Gammes pour enfants"
+msgstr "Plages pour enfants"
#: ipam/views.py:868
msgid "Related IPs"
@@ -9050,7 +9051,7 @@ msgstr "Préfixes et rôles VLAN"
#: netbox/navigation/menu.py:162
msgid "ASN Ranges"
-msgstr "Gammes ASN"
+msgstr "Plages ASN"
#: netbox/navigation/menu.py:184
msgid "VLAN Groups"
@@ -9457,7 +9458,7 @@ msgstr "Annuler"
#: utilities/templates/helpers/applied_filters.html:16
#: utilities/templates/helpers/table_config_form.html:40
msgid "Save"
-msgstr "Sauver"
+msgstr "Sauvegarder"
#: templates/account/preferences.html:41
msgid "Table Configurations"
@@ -9598,11 +9599,11 @@ msgid ""
"production system"
msgstr ""
"Les performances peuvent être limitées. Le débogage ne doit jamais être "
-"activé sur un système de production"
+"activé sur un système en production"
#: templates/base/layout.html:83
msgid "Maintenance Mode"
-msgstr "Mode de maintenance"
+msgstr "Mode Maintenance"
#: templates/base/layout.html:134
msgid "Docs"
@@ -9642,16 +9643,16 @@ msgstr "Date de résiliation"
#: templates/circuits/circuit_terminations_swap.html:4
msgid "Swap Circuit Terminations"
-msgstr "Terminaisons du circuit d'échange"
+msgstr "Échanger les terminaisons du circuit"
#: templates/circuits/circuit_terminations_swap.html:8
#, python-format
msgid "Swap these terminations for circuit %(circuit)s?"
-msgstr "Remplacez ces terminaisons par un circuit %(circuit)s?"
+msgstr "Échanger les terminaisons du circuit %(circuit)s?"
#: templates/circuits/circuit_terminations_swap.html:14
msgid "A side"
-msgstr "Un côté"
+msgstr "Coté A"
#: templates/circuits/circuit_terminations_swap.html:22
msgid "Z side"
@@ -9662,11 +9663,11 @@ msgstr "Côté Z"
#: templates/dcim/frontport.html:128 templates/dcim/interface.html:199
#: templates/dcim/rearport.html:118
msgid "Circuit Termination"
-msgstr "Terminaison du circuit"
+msgstr "Terminaison de circuit"
#: templates/circuits/circuittermination_edit.html:41
msgid "Termination Details"
-msgstr "Détails de résiliation"
+msgstr "Détails de terminaison"
#: templates/circuits/circuittype.html:10
msgid "Add Circuit"
diff --git a/netbox/translations/pt/LC_MESSAGES/django.mo b/netbox/translations/pt/LC_MESSAGES/django.mo
index dba8e89f7..c89de5e94 100644
Binary files a/netbox/translations/pt/LC_MESSAGES/django.mo and b/netbox/translations/pt/LC_MESSAGES/django.mo differ
diff --git a/netbox/translations/pt/LC_MESSAGES/django.po b/netbox/translations/pt/LC_MESSAGES/django.po
index 2392a316a..9cae154d8 100644
--- a/netbox/translations/pt/LC_MESSAGES/django.po
+++ b/netbox/translations/pt/LC_MESSAGES/django.po
@@ -4,8 +4,8 @@
# FIRST AUTHOR , YEAR.
#
# Translators:
-# Renato Almeida de Oliveira, 2023
# Jeremy Stretch, 2023
+# Renato Almeida de Oliveira, 2024
#
#, fuzzy
msgid ""
@@ -14,7 +14,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-12-21 17:54+0000\n"
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
-"Last-Translator: Jeremy Stretch, 2023\n"
+"Last-Translator: Renato Almeida de Oliveira, 2024\n"
"Language-Team: Portuguese (https://app.transifex.com/netbox-community/teams/178115/pt/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -30,7 +30,7 @@ msgstr "Chave"
#: account/tables.py:31 users/forms/filtersets.py:133
msgid "Write Enabled"
-msgstr "Gravação ativada"
+msgstr "Escrita permitida"
#: account/tables.py:34 core/tables/jobs.py:29 extras/choices.py:135
#: extras/tables/tables.py:469 templates/account/token.html:44
@@ -2041,7 +2041,7 @@ msgstr "Grupo (ID)"
#: dcim/filtersets.py:138
msgid "Group (slug)"
-msgstr "Grupo (lesma)"
+msgstr "Grupo (slug)"
#: dcim/filtersets.py:144 dcim/filtersets.py:149
msgid "AS (ID)"
@@ -2055,7 +2055,7 @@ msgstr "Localização (ID)"
#: dcim/filtersets.py:224 dcim/filtersets.py:299 dcim/filtersets.py:397
#: dcim/filtersets.py:1219 extras/filtersets.py:447
msgid "Location (slug)"
-msgstr "Localização (lesma)"
+msgstr "Localização (slug)"
#: dcim/filtersets.py:313 dcim/filtersets.py:764 dcim/filtersets.py:854
#: dcim/filtersets.py:1619 ipam/filtersets.py:347 ipam/filtersets.py:459
@@ -2068,7 +2068,7 @@ msgstr "Função (ID)"
#: ipam/filtersets.py:465 ipam/filtersets.py:946
#: virtualization/filtersets.py:215
msgid "Role (slug)"
-msgstr "Papel (lesma)"
+msgstr "Papel (slug)"
#: dcim/filtersets.py:347 dcim/filtersets.py:922 dcim/filtersets.py:1224
#: dcim/filtersets.py:1942
@@ -2095,7 +2095,7 @@ msgstr "Fabricante (ID)"
#: dcim/filtersets.py:811 dcim/filtersets.py:839 dcim/filtersets.py:1122
#: dcim/filtersets.py:1615
msgid "Manufacturer (slug)"
-msgstr "Fabricante (lesma)"
+msgstr "Fabricante (slug)"
#: dcim/filtersets.py:445
msgid "Default platform (ID)"
@@ -2180,7 +2180,7 @@ msgstr "Modelo de configuração (ID)"
#: dcim/filtersets.py:845
msgid "Device type (slug)"
-msgstr "Tipo de dispositivo (lesma)"
+msgstr "Tipo de dispositivo (slug)"
#: dcim/filtersets.py:865
msgid "Parent Device (ID)"
@@ -2193,7 +2193,7 @@ msgstr "Plataforma (ID)"
#: dcim/filtersets.py:875 extras/filtersets.py:474
#: virtualization/filtersets.py:225
msgid "Platform (slug)"
-msgstr "Plataforma (lesma)"
+msgstr "Plataforma (slug)"
#: dcim/filtersets.py:911 dcim/filtersets.py:1208 dcim/filtersets.py:1703
#: dcim/filtersets.py:1875 dcim/filtersets.py:1933
@@ -3634,7 +3634,7 @@ msgstr "Reserva"
#: dcim/forms/model_forms.py:297 dcim/forms/model_forms.py:380
#: utilities/forms/fields/fields.py:47
msgid "Slug"
-msgstr "Lesma"
+msgstr "Slug"
#: dcim/forms/model_forms.py:304 templates/dcim/devicetype.html:12
msgid "Chassis"
@@ -5198,7 +5198,7 @@ msgstr "Já existe uma região de nível superior com esse nome."
#: dcim/models/sites.py:59
msgid "A top-level region with this slug already exists."
-msgstr "Já existe uma região de alto nível com essa lesma."
+msgstr "Já existe uma região de alto nível com essa slug."
#: dcim/models/sites.py:62
msgid "region"
@@ -6029,7 +6029,7 @@ msgstr "Tipo de cluster"
#: extras/filtersets.py:485 virtualization/filtersets.py:95
#: virtualization/filtersets.py:146
msgid "Cluster type (slug)"
-msgstr "Tipo de cluster (lesma)"
+msgstr "Tipo de cluster (slug)"
#: extras/filtersets.py:490 ipam/forms/bulk_edit.py:475
#: ipam/forms/model_forms.py:585 virtualization/forms/filtersets.py:108
@@ -6038,7 +6038,7 @@ msgstr "Grupo de clusters"
#: extras/filtersets.py:496 virtualization/filtersets.py:135
msgid "Cluster group (slug)"
-msgstr "Grupo de clusters (lesma)"
+msgstr "Grupo de clusters (slug)"
#: extras/filtersets.py:506 tenancy/forms/forms.py:16
#: tenancy/forms/forms.py:39
@@ -6056,7 +6056,7 @@ msgstr "Tag"
#: extras/filtersets.py:534
msgid "Tag (slug)"
-msgstr "Tag (lesma)"
+msgstr "Tag (slug)"
#: extras/filtersets.py:594 extras/forms/filtersets.py:438
msgid "Has local config context data"
@@ -7630,7 +7630,7 @@ msgstr "RIR (ID)"
#: ipam/filtersets.py:142 ipam/filtersets.py:181 ipam/filtersets.py:204
msgid "RIR (slug)"
-msgstr "RIR (lesma)"
+msgstr "RIR (slug)"
#: ipam/filtersets.py:251
msgid "Within prefix"
@@ -12175,7 +12175,7 @@ msgstr "Função de contato (ID)"
#: tenancy/filtersets.py:114
msgid "Contact role (slug)"
-msgstr "Função de contato (lesma)"
+msgstr "Função de contato (slug)"
#: tenancy/filtersets.py:146
msgid "Contact group"
@@ -12191,7 +12191,7 @@ msgstr "Grupo de inquilinos (ID)"
#: tenancy/filtersets.py:216
msgid "Tenant Group (slug)"
-msgstr "Grupo de inquilinos (lesma)"
+msgstr "Grupo de inquilinos (slug)"
#: tenancy/forms/bulk_edit.py:65
msgid "Desciption"
@@ -13147,7 +13147,7 @@ msgstr "Grupo de túneis (ID)"
#: vpn/filtersets.py:47
msgid "Tunnel group (slug)"
-msgstr "Grupo de túneis (lesma)"
+msgstr "Grupo de túneis (slug)"
#: vpn/filtersets.py:54
msgid "IPSec profile (ID)"
diff --git a/netbox/translations/ru/LC_MESSAGES/django.mo b/netbox/translations/ru/LC_MESSAGES/django.mo
index 4b4aced04..6ca56e299 100644
Binary files a/netbox/translations/ru/LC_MESSAGES/django.mo and b/netbox/translations/ru/LC_MESSAGES/django.mo differ
diff --git a/netbox/translations/ru/LC_MESSAGES/django.po b/netbox/translations/ru/LC_MESSAGES/django.po
index 7e2932449..1607240c9 100644
--- a/netbox/translations/ru/LC_MESSAGES/django.po
+++ b/netbox/translations/ru/LC_MESSAGES/django.po
@@ -5,6 +5,8 @@
#
# Translators:
# Jeremy Stretch, 2023
+# Vladyslav V. Prodan, 2024
+# Artem Kotik, 2024
#
#, fuzzy
msgid ""
@@ -13,7 +15,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-12-21 17:54+0000\n"
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
-"Last-Translator: Jeremy Stretch, 2023\n"
+"Last-Translator: Artem Kotik, 2024\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"
@@ -110,7 +112,7 @@ msgstr "Регион (ID)"
#: virtualization/filtersets.py:52 virtualization/filtersets.py:179
#: vpn/filtersets.py:325
msgid "Region (slug)"
-msgstr "Регион (пуля)"
+msgstr "Регион (подстрока)"
#: circuits/filtersets.py:42 circuits/filtersets.py:195 dcim/filtersets.py:194
#: dcim/filtersets.py:269 dcim/filtersets.py:377 dcim/filtersets.py:894
@@ -127,7 +129,7 @@ msgstr "Группа сайтов (ID)"
#: ipam/filtersets.py:916 virtualization/filtersets.py:65
#: virtualization/filtersets.py:192
msgid "Site group (slug)"
-msgstr "Группа сайтов (слизень)"
+msgstr "Группа сайтов (подстрока)"
#: circuits/filtersets.py:54 circuits/forms/bulk_import.py:117
#: circuits/forms/filtersets.py:47 circuits/forms/filtersets.py:171
@@ -188,37 +190,37 @@ msgstr "Сайт"
#: virtualization/filtersets.py:75 virtualization/filtersets.py:202
#: vpn/filtersets.py:335
msgid "Site (slug)"
-msgstr "Сайт (слизень)"
+msgstr "Сайт (подстрока)"
#: circuits/filtersets.py:65
msgid "ASN (ID)"
-msgstr "ЯСЕНЬ (РЕБЕНОК)"
+msgstr "ASN (ID)"
#: circuits/filtersets.py:86 circuits/filtersets.py:112
#: circuits/filtersets.py:146
msgid "Provider (ID)"
-msgstr "Поставщик (ID)"
+msgstr "Провайдер (ID)"
#: circuits/filtersets.py:92 circuits/filtersets.py:118
#: circuits/filtersets.py:152
msgid "Provider (slug)"
-msgstr "Поставщик (пуля)"
+msgstr "Провайдер (подстрока)"
#: circuits/filtersets.py:157
msgid "Provider account (ID)"
-msgstr "Учетная запись поставщика (ID)"
+msgstr "Аккаунт провайдера (ID)"
#: circuits/filtersets.py:162
msgid "Provider network (ID)"
-msgstr "Сеть провайдеров (ID)"
+msgstr "Сеть провайдера (ID)"
#: circuits/filtersets.py:166
msgid "Circuit type (ID)"
-msgstr "Тип цепи (ID)"
+msgstr "Тип канала связи (ID)"
#: circuits/filtersets.py:172
msgid "Circuit type (slug)"
-msgstr "Тип цепи (заглушка)"
+msgstr "Тип канала связи (подстрока)"
#: circuits/filtersets.py:207 circuits/filtersets.py:244
#: dcim/filtersets.py:205 dcim/filtersets.py:280 dcim/filtersets.py:352
@@ -252,11 +254,11 @@ msgstr "Поиск"
#: templates/dcim/inc/cable_termination.html:55
#: templates/dcim/trace/circuit.html:4
msgid "Circuit"
-msgstr "Цепь"
+msgstr "Канал связи"
#: circuits/filtersets.py:254
msgid "ProviderNetwork (ID)"
-msgstr "Сеть провайдеров (ID)"
+msgstr "Сеть провайдера (ID)"
#: circuits/forms/bulk_edit.py:25 circuits/forms/filtersets.py:56
#: circuits/forms/model_forms.py:26 circuits/tables/providers.py:33
@@ -266,7 +268,7 @@ msgstr "Сеть провайдеров (ID)"
#: netbox/navigation/menu.py:160 netbox/navigation/menu.py:163
#: templates/circuits/provider.html:24
msgid "ASNs"
-msgstr "SAN"
+msgstr "ASN"
#: circuits/forms/bulk_edit.py:29 circuits/forms/bulk_edit.py:51
#: circuits/forms/bulk_edit.py:78 circuits/forms/bulk_edit.py:99
@@ -379,12 +381,12 @@ msgstr "Описание"
#: templates/circuits/providernetwork.html:23
#: templates/dcim/inc/cable_termination.html:51
msgid "Provider"
-msgstr "Поставщик"
+msgstr "Провайдер"
#: circuits/forms/bulk_edit.py:75 circuits/forms/filtersets.py:91
#: templates/circuits/providernetwork.html:31
msgid "Service ID"
-msgstr "Идентификатор услуги"
+msgstr "Идентификатор сервиса"
#: circuits/forms/bulk_edit.py:95 circuits/forms/filtersets.py:107
#: dcim/forms/bulk_edit.py:204 dcim/forms/bulk_edit.py:500
@@ -449,7 +451,7 @@ msgstr "Тип"
#: circuits/forms/bulk_edit.py:123 circuits/forms/bulk_import.py:82
#: circuits/forms/filtersets.py:139 circuits/forms/model_forms.py:97
msgid "Provider account"
-msgstr "Учетная запись поставщика"
+msgstr "Аккаунт провайдера"
#: circuits/forms/bulk_edit.py:131 circuits/forms/bulk_import.py:95
#: circuits/forms/filtersets.py:150 core/forms/filtersets.py:34
@@ -563,7 +565,7 @@ msgstr "Статус"
#: wireless/forms/bulk_import.py:55 wireless/forms/bulk_import.py:97
#: wireless/forms/filtersets.py:34 wireless/forms/filtersets.py:74
msgid "Tenant"
-msgstr "Арендатор"
+msgstr "Тенант"
#: circuits/forms/bulk_edit.py:142 circuits/forms/filtersets.py:174
msgid "Install date"
@@ -571,7 +573,7 @@ msgstr "Дата установки"
#: circuits/forms/bulk_edit.py:147 circuits/forms/filtersets.py:179
msgid "Termination date"
-msgstr "Дата увольнения"
+msgstr "Дата отключения"
#: circuits/forms/bulk_edit.py:153 circuits/forms/filtersets.py:186
msgid "Commit rate (Kbps)"
@@ -602,7 +604,7 @@ msgstr "Сдача в аренду"
#: circuits/forms/bulk_import.py:38 circuits/forms/bulk_import.py:53
#: circuits/forms/bulk_import.py:79
msgid "Assigned provider"
-msgstr "Назначенный поставщик"
+msgstr "Назначенный провайдер"
#: circuits/forms/bulk_import.py:70 dcim/forms/bulk_import.py:170
#: dcim/forms/bulk_import.py:380 dcim/forms/bulk_import.py:1092
@@ -612,11 +614,11 @@ msgstr "Цвет RGB в шестнадцатеричном формате. Пр
#: circuits/forms/bulk_import.py:85
msgid "Assigned provider account"
-msgstr "Учетная запись назначенного поставщика"
+msgstr "Назначенный аккаунт провайдера"
#: circuits/forms/bulk_import.py:92
msgid "Type of circuit"
-msgstr "Тип схемы"
+msgstr "Тип канала связи"
#: circuits/forms/bulk_import.py:97 dcim/forms/bulk_import.py:89
#: dcim/forms/bulk_import.py:148 dcim/forms/bulk_import.py:196
@@ -626,7 +628,7 @@ msgstr "Тип схемы"
#: ipam/forms/bulk_import.py:460 virtualization/forms/bulk_import.py:56
#: virtualization/forms/bulk_import.py:82 vpn/forms/bulk_import.py:39
msgid "Operational status"
-msgstr "Эксплуатационный статус"
+msgstr "Операционный статус"
#: circuits/forms/bulk_import.py:104 dcim/forms/bulk_import.py:110
#: dcim/forms/bulk_import.py:155 dcim/forms/bulk_import.py:278
@@ -640,12 +642,12 @@ msgstr "Эксплуатационный статус"
#: virtualization/forms/bulk_import.py:119 vpn/forms/bulk_import.py:63
#: wireless/forms/bulk_import.py:59 wireless/forms/bulk_import.py:101
msgid "Assigned tenant"
-msgstr "Назначение арендатора"
+msgstr "Назначенный тенант"
#: circuits/forms/bulk_import.py:123 circuits/forms/filtersets.py:147
#: circuits/forms/model_forms.py:143
msgid "Provider network"
-msgstr "Сеть провайдеров"
+msgstr "Сеть провайдера"
#: circuits/forms/filtersets.py:26 circuits/forms/filtersets.py:118
#: dcim/forms/bulk_edit.py:247 dcim/forms/bulk_edit.py:345
@@ -679,13 +681,13 @@ msgstr "Сеть провайдеров"
#: virtualization/forms/filtersets.py:45 virtualization/forms/filtersets.py:99
#: wireless/forms/model_forms.py:88 wireless/forms/model_forms.py:128
msgid "Location"
-msgstr "Местоположение"
+msgstr "Локация"
#: circuits/forms/filtersets.py:27 ipam/forms/model_forms.py:158
#: ipam/models/asns.py:108 ipam/models/asns.py:125 ipam/tables/asn.py:41
#: templates/ipam/asn.html:20
msgid "ASN"
-msgstr "ЗОЛ"
+msgstr "ASN"
#: circuits/forms/filtersets.py:28 circuits/forms/filtersets.py:120
#: dcim/forms/filtersets.py:136 dcim/forms/filtersets.py:150
@@ -740,7 +742,7 @@ msgstr "Регион"
#: virtualization/forms/filtersets.py:134
#: virtualization/forms/model_forms.py:101
msgid "Site group"
-msgstr "Группа сайта"
+msgstr "Группа сайтов"
#: circuits/forms/filtersets.py:51
msgid "ASN (legacy)"
@@ -784,11 +786,11 @@ msgstr "Аккаунт"
#: templates/circuits/inc/circuit_termination.html:89
#: templates/circuits/providernetwork.html:18
msgid "Provider Network"
-msgstr "Сеть провайдеров"
+msgstr "Сеть провайдера"
#: circuits/forms/model_forms.py:78 templates/circuits/circuittype.html:20
msgid "Circuit Type"
-msgstr "Тип цепи"
+msgstr "Тип канала связи"
#: circuits/models/circuits.py:25 dcim/models/cables.py:67
#: dcim/models/device_component_templates.py:491
@@ -801,19 +803,19 @@ msgstr "цвет"
#: circuits/models/circuits.py:34
msgid "circuit type"
-msgstr "тип схемы"
+msgstr "тип канала связи"
#: circuits/models/circuits.py:35
msgid "circuit types"
-msgstr "типы цепей"
+msgstr "типы каналов связи"
#: circuits/models/circuits.py:46
msgid "circuit ID"
-msgstr "идентификатор цепи"
+msgstr "идентификатор канала связи"
#: circuits/models/circuits.py:47
msgid "Unique circuit ID"
-msgstr "Уникальный идентификатор схемы"
+msgstr "Уникальный идентификатор канала связи"
#: circuits/models/circuits.py:67 core/models/data.py:54
#: core/models/jobs.py:85 dcim/models/cables.py:49 dcim/models/devices.py:641
@@ -829,7 +831,7 @@ msgstr "статус"
#: circuits/models/circuits.py:82
msgid "installed"
-msgstr "установлены"
+msgstr "установлен"
#: circuits/models/circuits.py:87
msgid "terminates"
@@ -845,11 +847,11 @@ msgstr "Подтвержденная ставка"
#: circuits/models/circuits.py:135
msgid "circuit"
-msgstr "схема"
+msgstr "канал связи"
#: circuits/models/circuits.py:136
msgid "circuits"
-msgstr "схемы"
+msgstr "каналы связи"
#: circuits/models/circuits.py:169
msgid "termination"
@@ -861,15 +863,15 @@ msgstr "скорость порта (Кбит/с)"
#: circuits/models/circuits.py:189
msgid "Physical circuit speed"
-msgstr "Физическая скорость цепи"
+msgstr "Физическая скорость канала связи"
#: circuits/models/circuits.py:194
msgid "upstream speed (Kbps)"
-msgstr "скорость восходящего потока (Кбит/с)"
+msgstr "скорость отдачи (Кбит/с)"
#: circuits/models/circuits.py:195
msgid "Upstream speed, if different from port speed"
-msgstr "Скорость восходящего потока, если она отличается от скорости порта"
+msgstr "Скорость отдачи, если она отличается от скорости порта"
#: circuits/models/circuits.py:200
msgid "cross-connect ID"
@@ -881,7 +883,7 @@ msgstr "Идентификатор локального кросс-соедин
#: circuits/models/circuits.py:206
msgid "patch panel/port(s)"
-msgstr "патч-панель/порт (ы)"
+msgstr "патч-панель или порт(ы)"
#: circuits/models/circuits.py:207
msgid "Patch panel ID and port number(s)"
@@ -903,11 +905,11 @@ msgstr "описание"
#: circuits/models/circuits.py:223
msgid "circuit termination"
-msgstr "прекращение цепи"
+msgstr "точка подключение канала связи"
#: circuits/models/circuits.py:224
msgid "circuit terminations"
-msgstr "концевые разъемы"
+msgstr "точки подключения канала связи"
#: circuits/models/providers.py:22 circuits/models/providers.py:66
#: circuits/models/providers.py:104 core/models/data.py:41
@@ -945,11 +947,11 @@ msgstr "Полное имя провайдера"
#: netbox/models/__init__.py:185 tenancy/models/tenants.py:25
#: tenancy/models/tenants.py:49 vpn/models/l2vpn.py:27 wireless/models.py:55
msgid "slug"
-msgstr "слизень"
+msgstr "подстрока"
#: circuits/models/providers.py:42
msgid "provider"
-msgstr "поставщика"
+msgstr "провайдер"
#: circuits/models/providers.py:43
msgid "providers"
@@ -957,15 +959,15 @@ msgstr "провайдеры"
#: circuits/models/providers.py:63
msgid "account ID"
-msgstr "идентификатор учетной записи"
+msgstr "идентификатор аккаунта"
#: circuits/models/providers.py:86
msgid "provider account"
-msgstr "учетная запись провайдера"
+msgstr "аккаунт провайдера"
#: circuits/models/providers.py:87
msgid "provider accounts"
-msgstr "учетные записи поставщиков"
+msgstr "аккаунты провайдера"
#: circuits/models/providers.py:115
msgid "service ID"
@@ -973,11 +975,11 @@ msgstr "идентификатор сервиса"
#: circuits/models/providers.py:126
msgid "provider network"
-msgstr "сеть провайдеров"
+msgstr "сеть провайдера"
#: circuits/models/providers.py:127
msgid "provider networks"
-msgstr "сети провайдеров"
+msgstr "сети провайдера"
#: circuits/tables/circuits.py:29 circuits/tables/providers.py:18
#: circuits/tables/providers.py:69 circuits/tables/providers.py:99
@@ -1073,11 +1075,11 @@ msgstr "Имя"
#: templates/circuits/provideraccount.html:46
#: templates/circuits/providernetwork.html:54
msgid "Circuits"
-msgstr "Схемы"
+msgstr "Каналы связи"
#: circuits/tables/circuits.py:52 templates/circuits/circuit.html:27
msgid "Circuit ID"
-msgstr "Идентификатор цепи"
+msgstr "Идентификатор канала связи"
#: circuits/tables/circuits.py:65 wireless/forms/model_forms.py:157
msgid "Side A"
@@ -1089,7 +1091,7 @@ msgstr "Сторона Z"
#: circuits/tables/circuits.py:72 templates/circuits/circuit.html:56
msgid "Commit Rate"
-msgstr "Процент коммитов"
+msgstr "Гарантированная скорость"
#: circuits/tables/circuits.py:75 circuits/tables/providers.py:48
#: circuits/tables/providers.py:82 circuits/tables/providers.py:107
@@ -1114,11 +1116,11 @@ msgstr "Комментарии"
#: circuits/tables/providers.py:23
msgid "Accounts"
-msgstr "Счета"
+msgstr "Аккаунты"
#: circuits/tables/providers.py:29
msgid "Account Count"
-msgstr "Количество учетных записей"
+msgstr "Количество аккаунтов"
#: circuits/tables/providers.py:39 dcim/tables/sites.py:100
msgid "ASN Count"
@@ -1126,7 +1128,7 @@ msgstr "Количество ASN"
#: core/choices.py:18
msgid "New"
-msgstr "Новое"
+msgstr "Новый"
#: core/choices.py:19
msgid "Queued"
@@ -1134,7 +1136,7 @@ msgstr "В очереди"
#: core/choices.py:20
msgid "Syncing"
-msgstr "Синхронизация"
+msgstr "Синхронизируется"
#: core/choices.py:21 core/choices.py:57 core/tables/jobs.py:41
#: extras/choices.py:210 templates/core/job.html:75
@@ -1145,13 +1147,13 @@ msgstr "Завершено"
#: dcim/choices.py:222 dcim/choices.py:1496 extras/choices.py:212
#: virtualization/choices.py:47
msgid "Failed"
-msgstr "Не удалось"
+msgstr "Потрачено"
#: core/choices.py:35 netbox/navigation/menu.py:330
#: templates/extras/script/base.html:14 templates/extras/script_list.html:6
#: templates/extras/script_list.html:20 templates/extras/script_result.html:18
msgid "Scripts"
-msgstr "Сценарии"
+msgstr "Скрипты"
#: core/choices.py:36 netbox/navigation/menu.py:324
#: templates/extras/report/base.html:13 templates/extras/report_list.html:7
@@ -1170,7 +1172,7 @@ msgstr "Запланировано"
#: core/choices.py:56 extras/choices.py:209
msgid "Running"
-msgstr "Бег"
+msgstr "Исполняется"
#: core/choices.py:58 extras/choices.py:211
msgid "Errored"
@@ -1178,7 +1180,7 @@ msgstr "Ошибка"
#: core/data_backends.py:29 templates/dcim/interface.html:224
msgid "Local"
-msgstr "Местный"
+msgstr "Локальный"
#: core/data_backends.py:47 extras/tables/tables.py:431
#: templates/account/profile.html:16 templates/users/user.html:18
@@ -1227,7 +1229,7 @@ msgstr "Обеспечьте уникальное пространство"
#: vpn/forms/model_forms.py:315 vpn/forms/model_forms.py:329
#: vpn/forms/model_forms.py:350 vpn/forms/model_forms.py:373
msgid "Parameters"
-msgstr "параметры"
+msgstr "Параметры"
#: core/forms/bulk_edit.py:37 templates/core/datasource.html:69
msgid "Ignore rules"
@@ -1277,7 +1279,7 @@ msgstr "Источник данных"
#: core/forms/filtersets.py:64 extras/forms/filtersets.py:449
msgid "Creation"
-msgstr "Творчество"
+msgstr "Создание"
#: core/forms/filtersets.py:70 extras/forms/filtersets.py:473
#: extras/forms/filtersets.py:519 extras/tables/tables.py:474
@@ -1292,23 +1294,23 @@ msgstr "Создано после"
#: core/forms/filtersets.py:85
msgid "Created before"
-msgstr "Создано ранее"
+msgstr "Создано до"
#: core/forms/filtersets.py:90
msgid "Scheduled after"
-msgstr "Запланировано позже"
+msgstr "Запланировано после"
#: core/forms/filtersets.py:95
msgid "Scheduled before"
-msgstr "Запланировано ранее"
+msgstr "Запланировано до"
#: core/forms/filtersets.py:100
msgid "Started after"
-msgstr "Началось после"
+msgstr "Запустилось после"
#: core/forms/filtersets.py:105
msgid "Started before"
-msgstr "Начиналось раньше"
+msgstr "Запустилось до"
#: core/forms/filtersets.py:110
msgid "Completed after"
@@ -1316,7 +1318,7 @@ msgstr "Завершено после"
#: core/forms/filtersets.py:115
msgid "Completed before"
-msgstr "Выполнено ранее"
+msgstr "Завершено до"
#: core/forms/filtersets.py:122 dcim/forms/bulk_edit.py:359
#: dcim/forms/filtersets.py:352 dcim/forms/filtersets.py:396
@@ -1348,7 +1350,7 @@ msgstr "Загрузка файла"
#: core/forms/model_forms.py:147 templates/core/configrevision.html:43
#: templates/dcim/rack_elevation_list.html:6
msgid "Rack Elevations"
-msgstr "Высота стеллажей"
+msgstr "Фасады стоек"
#: core/forms/model_forms.py:148 dcim/choices.py:1407
#: dcim/forms/bulk_edit.py:859 dcim/forms/bulk_edit.py:1242
@@ -1360,14 +1362,14 @@ msgstr "Мощность"
#: core/forms/model_forms.py:149 netbox/navigation/menu.py:142
#: templates/core/configrevision.html:79
msgid "IPAM"
-msgstr "ИПАМ"
+msgstr "IPAM"
#: core/forms/model_forms.py:150 netbox/navigation/menu.py:218
#: templates/core/configrevision.html:95 vpn/forms/bulk_edit.py:76
#: vpn/forms/filtersets.py:42 vpn/forms/model_forms.py:60
#: vpn/forms/model_forms.py:145
msgid "Security"
-msgstr "Охрана"
+msgstr "Безопасность"
#: core/forms/model_forms.py:151 templates/core/configrevision.html:107
msgid "Banners"
@@ -1385,7 +1387,7 @@ msgstr "Валидация"
#: core/forms/model_forms.py:154 templates/account/preferences.html:6
#: templates/core/configrevision.html:175
msgid "User Preferences"
-msgstr "Пользовательские предпочтения"
+msgstr "Пользовательские настройки"
#: core/forms/model_forms.py:155 dcim/forms/filtersets.py:658
#: templates/core/configrevision.html:193 users/forms/model_forms.py:63
@@ -1413,7 +1415,7 @@ msgstr " (по умолчанию)"
#: core/models/jobs.py:50 extras/models/models.py:760
#: netbox/models/features.py:52 users/models.py:248
msgid "created"
-msgstr "созданный"
+msgstr "создан(а)"
#: core/models/config.py:22
msgid "comment"
@@ -1460,7 +1462,7 @@ msgstr "Версия конфигурации #{id}"
#: extras/models/search.py:43 virtualization/models/clusters.py:61
#: vpn/models/l2vpn.py:32
msgid "type"
-msgstr "типа"
+msgstr "тип"
#: core/models/data.py:51 extras/choices.py:34 extras/models/models.py:194
#: templates/core/datasource.html:59
@@ -1511,7 +1513,7 @@ msgstr "последнее обновление"
#: core/models/data.py:273 dcim/models/cables.py:430
msgid "path"
-msgstr "дорожка"
+msgstr "путь"
#: core/models/data.py:276
msgid "File path relative to the data source's root"
@@ -1523,7 +1525,7 @@ msgstr "размер"
#: core/models/data.py:283
msgid "hash"
-msgstr "нарубить"
+msgstr "хэш"
#: core/models/data.py:287
msgid "Length must be 64 hexadecimal characters."
@@ -1531,7 +1533,7 @@ msgstr "Длина должна быть 64 шестнадцатеричных
#: core/models/data.py:289
msgid "SHA256 hash of the file data"
-msgstr "Хэш SHA256 данных файла"
+msgstr "SHA256 хэш данных файла"
#: core/models/data.py:306
msgid "data file"
@@ -1632,7 +1634,7 @@ msgstr "Последнее обновление"
#: netbox/tables/tables.py:184 templates/dcim/virtualchassis_edit.html:53
#: wireless/tables/wirelesslink.py:16
msgid "ID"
-msgstr "ИДЕНТИФИКАТОР"
+msgstr "ID"
#: core/tables/jobs.py:21 extras/choices.py:38 extras/tables/tables.py:236
#: extras/tables/tables.py:350 extras/tables/tables.py:448
@@ -1812,11 +1814,11 @@ msgstr "Смешанный"
#: dcim/choices.py:443 dcim/choices.py:680
msgid "NEMA (Non-locking)"
-msgstr "NEMA (без блокировки)"
+msgstr "NEMA (не блокирующий)"
#: dcim/choices.py:465 dcim/choices.py:702
msgid "NEMA (Locking)"
-msgstr "NEMA (блокировка)"
+msgstr "NEMA (блокирующий)"
#: dcim/choices.py:488 dcim/choices.py:725
msgid "California Style"
@@ -1853,7 +1855,7 @@ msgstr "Виртуальный"
#: dcim/forms/model_forms.py:1190 netbox/navigation/menu.py:128
#: netbox/navigation/menu.py:132 templates/dcim/interface.html:217
msgid "Wireless"
-msgstr "Беспроводная"
+msgstr "Беспроводной"
#: dcim/choices.py:947
msgid "Virtual interfaces"
@@ -1871,11 +1873,11 @@ msgstr "Мост"
#: dcim/choices.py:951
msgid "Link Aggregation Group (LAG)"
-msgstr "Группа агрегации каналов (LAG)"
+msgstr "Группа агрегации линков (LAG)"
#: dcim/choices.py:955
msgid "Ethernet (fixed)"
-msgstr "Ethernet (стационарный)"
+msgstr "Ethernet (фиксированный)"
#: dcim/choices.py:969
msgid "Ethernet (modular)"
@@ -1914,7 +1916,7 @@ msgstr "Полный"
#: dcim/choices.py:1164 wireless/choices.py:480
msgid "Auto"
-msgstr "авто"
+msgstr "Авто"
#: dcim/choices.py:1175
msgid "Access"
@@ -1923,11 +1925,11 @@ msgstr "Доступ"
#: dcim/choices.py:1176 ipam/tables/vlans.py:168 ipam/tables/vlans.py:213
#: templates/dcim/inc/interface_vlans_table.html:7
msgid "Tagged"
-msgstr "Помеченные"
+msgstr "Тегированный"
#: dcim/choices.py:1177
msgid "Tagged (All)"
-msgstr "С метками (все)"
+msgstr "Тегированный (все)"
#: dcim/choices.py:1206
msgid "IEEE Standard"
@@ -1971,7 +1973,7 @@ msgstr "Километры"
#: dcim/choices.py:1438 templates/dcim/cable_trace.html:62
msgid "Meters"
-msgstr "Счетчики"
+msgstr "Метры"
#: dcim/choices.py:1439
msgid "Centimeters"
@@ -1983,7 +1985,7 @@ msgstr "Мили"
#: dcim/choices.py:1441 templates/dcim/cable_trace.html:63
msgid "Feet"
-msgstr "Ноги"
+msgstr "Футы"
#: dcim/choices.py:1457 templates/dcim/device.html:332
#: templates/dcim/rack.html:157
@@ -2024,7 +2026,7 @@ msgstr "Родительский регион (ID)"
#: dcim/filtersets.py:86
msgid "Parent region (slug)"
-msgstr "Родительский регион (пуля)"
+msgstr "Родительский регион (подстрока)"
#: dcim/filtersets.py:97
msgid "Parent site group (ID)"
@@ -2032,7 +2034,7 @@ msgstr "Родительская группа сайтов (ID)"
#: dcim/filtersets.py:103
msgid "Parent site group (slug)"
-msgstr "Родительская группа сайтов (slug)"
+msgstr "Родительская группа сайтов (подстрока)"
#: dcim/filtersets.py:132 ipam/filtersets.py:797 ipam/filtersets.py:930
msgid "Group (ID)"
@@ -2040,39 +2042,39 @@ msgstr "Группа (ID)"
#: dcim/filtersets.py:138
msgid "Group (slug)"
-msgstr "Группа (слизень)"
+msgstr "Группа (подстрока)"
#: dcim/filtersets.py:144 dcim/filtersets.py:149
msgid "AS (ID)"
-msgstr "КАК (ID)"
+msgstr "Автономная система (ID)"
#: dcim/filtersets.py:217 dcim/filtersets.py:292 dcim/filtersets.py:390
#: dcim/filtersets.py:917 dcim/filtersets.py:1213 dcim/filtersets.py:1881
msgid "Location (ID)"
-msgstr "Местонахождение (ID)"
+msgstr "Локация (ID)"
#: dcim/filtersets.py:224 dcim/filtersets.py:299 dcim/filtersets.py:397
#: dcim/filtersets.py:1219 extras/filtersets.py:447
msgid "Location (slug)"
-msgstr "Местоположение (пуля)"
+msgstr "Локация (подстрока)"
#: dcim/filtersets.py:313 dcim/filtersets.py:764 dcim/filtersets.py:854
#: dcim/filtersets.py:1619 ipam/filtersets.py:347 ipam/filtersets.py:459
#: ipam/filtersets.py:940 virtualization/filtersets.py:209
msgid "Role (ID)"
-msgstr "Роль (идентификатор)"
+msgstr "Роль (ID)"
#: dcim/filtersets.py:319 dcim/filtersets.py:770 dcim/filtersets.py:860
#: dcim/filtersets.py:1625 extras/filtersets.py:463 ipam/filtersets.py:353
#: ipam/filtersets.py:465 ipam/filtersets.py:946
#: virtualization/filtersets.py:215
msgid "Role (slug)"
-msgstr "Роль (пуля)"
+msgstr "Роль (подстрока)"
#: dcim/filtersets.py:347 dcim/filtersets.py:922 dcim/filtersets.py:1224
#: dcim/filtersets.py:1942
msgid "Rack (ID)"
-msgstr "Стеллаж (ID)"
+msgstr "Стойка (ID)"
#: dcim/filtersets.py:401 extras/filtersets.py:234 extras/filtersets.py:278
#: extras/filtersets.py:318 extras/filtersets.py:613
@@ -2094,7 +2096,7 @@ msgstr "Производитель (ID)"
#: dcim/filtersets.py:811 dcim/filtersets.py:839 dcim/filtersets.py:1122
#: dcim/filtersets.py:1615
msgid "Manufacturer (slug)"
-msgstr "Производитель (slug)"
+msgstr "Производитель (подстрока)"
#: dcim/filtersets.py:445
msgid "Default platform (ID)"
@@ -2102,7 +2104,7 @@ msgstr "Платформа по умолчанию (ID)"
#: dcim/filtersets.py:451
msgid "Default platform (slug)"
-msgstr "Платформа по умолчанию (slug)"
+msgstr "Платформа по умолчанию (подстрока)"
#: dcim/filtersets.py:454 dcim/forms/filtersets.py:452
msgid "Has a front image"
@@ -2122,7 +2124,7 @@ msgstr "Имеет консольные порты"
#: dcim/forms/filtersets.py:473 dcim/forms/filtersets.py:570
#: dcim/forms/filtersets.py:782
msgid "Has console server ports"
-msgstr "Имеет порты консольного сервера"
+msgstr "Имеет серверные консольные порты"
#: dcim/filtersets.py:471 dcim/filtersets.py:579 dcim/filtersets.py:983
#: dcim/forms/filtersets.py:480 dcim/forms/filtersets.py:577
@@ -2179,7 +2181,7 @@ msgstr "Шаблон конфигурации (ID)"
#: dcim/filtersets.py:845
msgid "Device type (slug)"
-msgstr "Тип устройства (заглушка)"
+msgstr "Тип устройства (подстрока)"
#: dcim/filtersets.py:865
msgid "Parent Device (ID)"
@@ -2192,12 +2194,12 @@ msgstr "Платформа (ID)"
#: dcim/filtersets.py:875 extras/filtersets.py:474
#: virtualization/filtersets.py:225
msgid "Platform (slug)"
-msgstr "Платформа (пуля)"
+msgstr "Платформа (подстрока)"
#: dcim/filtersets.py:911 dcim/filtersets.py:1208 dcim/filtersets.py:1703
#: dcim/filtersets.py:1875 dcim/filtersets.py:1933
msgid "Site name (slug)"
-msgstr "Название сайта (slug)"
+msgstr "Имя сайта (подстрока)"
#: dcim/filtersets.py:926
msgid "VM cluster (ID)"
@@ -2205,7 +2207,7 @@ msgstr "Кластер виртуальных машин (ID)"
#: dcim/filtersets.py:932
msgid "Device model (slug)"
-msgstr "Модель устройства (заглушка)"
+msgstr "Модель устройства (подстрока)"
#: dcim/filtersets.py:943 dcim/forms/bulk_edit.py:421
msgid "Is full depth"
@@ -2235,11 +2237,11 @@ msgstr "Виртуальное шасси (ID)"
#: dcim/filtersets.py:967
msgid "Is a virtual chassis member"
-msgstr "Является виртуальным членом шасси"
+msgstr "Является членом виртуального шасси"
#: dcim/filtersets.py:1008
msgid "OOB IP (ID)"
-msgstr "ПОДГУЗНИК (ID)"
+msgstr "Сервисный порт (ID)"
#: dcim/filtersets.py:1133
msgid "Module type (model)"
@@ -2274,7 +2276,7 @@ msgstr "Роль устройства (ID)"
#: dcim/filtersets.py:1262 dcim/filtersets.py:1285
msgid "Device role (slug)"
-msgstr "Роль устройства (slug)"
+msgstr "Роль устройства (подстрока)"
#: dcim/filtersets.py:1267
msgid "Virtual Chassis (ID)"
@@ -2381,7 +2383,7 @@ msgstr "Мастер (удостоверение личности)"
#: dcim/filtersets.py:1666
msgid "Master (name)"
-msgstr "Мастер (имя)"
+msgstr "Хозяин (имя)"
#: dcim/filtersets.py:1708 tenancy/filtersets.py:220
msgid "Tenant (ID)"
@@ -2389,7 +2391,7 @@ msgstr "Арендатор (ID)"
#: dcim/filtersets.py:1714 extras/filtersets.py:523 tenancy/filtersets.py:226
msgid "Tenant (slug)"
-msgstr "Арендатор (пуля)"
+msgstr "Тенант (подстрока)"
#: dcim/filtersets.py:1749 dcim/forms/filtersets.py:990
msgid "Unterminated"
@@ -3450,7 +3452,7 @@ msgstr "Однофазный или трехфазный"
#: templates/virtualization/vminterface.html:58
#: virtualization/forms/bulk_edit.py:224
msgid "MTU"
-msgstr "МАТУ"
+msgstr "MTU"
#: dcim/forms/common.py:65
#, python-brace-format
@@ -3635,7 +3637,7 @@ msgstr "Резервирование"
#: dcim/forms/model_forms.py:297 dcim/forms/model_forms.py:380
#: utilities/forms/fields/fields.py:47
msgid "Slug"
-msgstr "Пуля"
+msgstr "Подстрока"
#: dcim/forms/model_forms.py:304 templates/dcim/devicetype.html:12
msgid "Chassis"
@@ -5193,7 +5195,7 @@ msgstr "Регион верхнего уровня с таким названи
#: dcim/models/sites.py:59
msgid "A top-level region with this slug already exists."
-msgstr "Регион верхнего уровня с этим слагнем уже существует."
+msgstr "Регион верхнего уровня с этой подстрокой уже существует."
#: dcim/models/sites.py:62
msgid "region"
@@ -5209,7 +5211,7 @@ msgstr "Группа сайтов верхнего уровня с таким и
#: dcim/models/sites.py:112
msgid "A top-level site group with this slug already exists."
-msgstr "Группа сайтов верхнего уровня с этим слайгом уже существует."
+msgstr "Группа сайтов верхнего уровня с этой подстрокой уже существует."
#: dcim/models/sites.py:115
msgid "site group"
@@ -5261,7 +5263,7 @@ msgstr "Местоположение с таким именем уже суще
#: dcim/models/sites.py:313
msgid "A location with this slug already exists within the specified site."
-msgstr "Местоположение с этим слайгом уже существует на указанном сайте."
+msgstr "Локация с этой подстрокой уже существует на указанном сайте."
#: dcim/models/sites.py:316
msgid "location"
@@ -5884,15 +5886,15 @@ msgstr "Удалить"
#: extras/choices.py:280 utilities/choices.py:143 utilities/choices.py:191
msgid "Blue"
-msgstr "голубой"
+msgstr "Синий"
#: extras/choices.py:281 utilities/choices.py:142 utilities/choices.py:192
msgid "Indigo"
-msgstr "Индиго"
+msgstr "Темно-синий"
#: extras/choices.py:282 utilities/choices.py:140 utilities/choices.py:193
msgid "Purple"
-msgstr "Пурпурный"
+msgstr "Фиолетовый"
#: extras/choices.py:283 utilities/choices.py:137 utilities/choices.py:194
msgid "Pink"
@@ -5904,7 +5906,7 @@ msgstr "Красный"
#: extras/choices.py:285 utilities/choices.py:154 utilities/choices.py:196
msgid "Orange"
-msgstr "оранжевый"
+msgstr "Оранжевый"
#: extras/choices.py:286 utilities/choices.py:152 utilities/choices.py:197
msgid "Yellow"
@@ -5916,7 +5918,7 @@ msgstr "Зелёный"
#: extras/choices.py:288 utilities/choices.py:146 utilities/choices.py:199
msgid "Teal"
-msgstr "чирок"
+msgstr "Cине-зеленый"
#: extras/choices.py:289 utilities/choices.py:145 utilities/choices.py:200
msgid "Cyan"
@@ -5932,7 +5934,7 @@ msgstr "Черный"
#: extras/choices.py:292 utilities/choices.py:161 utilities/choices.py:203
msgid "White"
-msgstr "белый"
+msgstr "Белый"
#: extras/choices.py:306 extras/forms/model_forms.py:233
#: extras/forms/model_forms.py:321 templates/extras/webhook.html:11
@@ -6024,7 +6026,7 @@ msgstr "Тип кластера"
#: extras/filtersets.py:485 virtualization/filtersets.py:95
#: virtualization/filtersets.py:146
msgid "Cluster type (slug)"
-msgstr "Тип кластера (слизень)"
+msgstr "Тип кластера (подстрока)"
#: extras/filtersets.py:490 ipam/forms/bulk_edit.py:475
#: ipam/forms/model_forms.py:585 virtualization/forms/filtersets.py:108
@@ -6033,7 +6035,7 @@ msgstr "Кластерная группа"
#: extras/filtersets.py:496 virtualization/filtersets.py:135
msgid "Cluster group (slug)"
-msgstr "Кластерная группа (slug)"
+msgstr "Группа кластеров (подстрока)"
#: extras/filtersets.py:506 tenancy/forms/forms.py:16
#: tenancy/forms/forms.py:39
@@ -6043,7 +6045,7 @@ msgstr "Группа арендаторов"
#: extras/filtersets.py:512 tenancy/filtersets.py:163
#: tenancy/filtersets.py:183
msgid "Tenant group (slug)"
-msgstr "Группа арендаторов (slug)"
+msgstr "Группа тенантов (подстрока)"
#: extras/filtersets.py:528 templates/extras/tag.html:12
msgid "Tag"
@@ -6051,7 +6053,7 @@ msgstr "Тег"
#: extras/filtersets.py:534
msgid "Tag (slug)"
-msgstr "Тег (пуля)"
+msgstr "Тег (подстрока)"
#: extras/filtersets.py:594 extras/forms/filtersets.py:438
msgid "Has local config context data"
@@ -6416,12 +6418,16 @@ msgid ""
"Jinja2 template code for the link text. Reference the object as {{ "
"object }}
. Links which render as empty text will not be displayed."
msgstr ""
+"Код шаблона Jinja2 для текста ссылки. Ссылайтесь на объект как {{ "
+"object }}
. Ссылки с пустым текстом отображаться не будут."
#: extras/forms/model_forms.py:148
msgid ""
"Jinja2 template code for the link URL. Reference the object as {{ "
"object }}
."
msgstr ""
+"Код шаблона Jinja2 для URL-адреса. Ссылайтесь на объект как {{ object "
+"}}
"
#: extras/forms/model_forms.py:158 extras/forms/model_forms.py:500
msgid "Template code"
@@ -6736,7 +6742,7 @@ msgstr ""
#: extras/models/customfields.py:147
msgid "default"
-msgstr "дефолт"
+msgstr "по умолчанию"
#: extras/models/customfields.py:151
msgid ""
@@ -6856,11 +6862,11 @@ msgstr "{type} поля не могут определять тип объект
#: extras/models/customfields.py:434
msgid "True"
-msgstr "Верно"
+msgstr "Истинно"
#: extras/models/customfields.py:435
msgid "False"
-msgstr "Ложь"
+msgstr "Ложно"
#: extras/models/customfields.py:517
#, python-brace-format
@@ -6965,7 +6971,7 @@ msgstr "макет"
#: extras/models/dashboard.py:23
msgid "config"
-msgstr "конфигурации"
+msgstr "конфигурация"
#: extras/models/dashboard.py:28
msgid "dashboard"
@@ -6973,7 +6979,7 @@ msgstr "панель управления"
#: extras/models/dashboard.py:29
msgid "dashboards"
-msgstr "щитки"
+msgstr "панели управления"
#: extras/models/models.py:49
msgid "object types"
@@ -7621,7 +7627,7 @@ msgstr "RIR (ID)"
#: ipam/filtersets.py:142 ipam/filtersets.py:181 ipam/filtersets.py:204
msgid "RIR (slug)"
-msgstr "RIR (пуля)"
+msgstr "RIR (подстрока)"
#: ipam/filtersets.py:251
msgid "Within prefix"
@@ -7755,8 +7761,8 @@ msgstr "Это бассейн"
#: ipam/forms/bulk_edit.py:257 ipam/forms/bulk_edit.py:301
#: ipam/models/ip.py:271 ipam/models/ip.py:538
#, python-format
-msgid "Treat as 100% utilized"
-msgstr "Отнестись к использованию на 100%"
+msgid "Treat as 100%% utilized"
+msgstr "Отнестись к использованию на 100%%"
#: ipam/forms/bulk_edit.py:349 ipam/models/ip.py:771
msgid "DNS name"
@@ -7996,8 +8002,8 @@ msgstr "Присутствует в VRF"
#: ipam/forms/filtersets.py:243 ipam/forms/filtersets.py:282
#, python-format
-msgid "Marked as 100% utilized"
-msgstr "Отмечено как использовано на 100%"
+msgid "Marked as 100%% utilized"
+msgstr "Отмечено как использовано на 100%%"
#: ipam/forms/filtersets.py:297
msgid "Device/VM"
@@ -10134,7 +10140,7 @@ msgstr "Родительский залив"
#: templates/dcim/device_edit.html:48
#: utilities/templates/form_helpers/render_field.html:20
msgid "Regenerate Slug"
-msgstr "Регенерирующий слизень"
+msgstr "Сгенерировать подстроку"
#: templates/dcim/device_edit.html:49 templates/generic/bulk_remove.html:7
#: utilities/templates/helpers/table_config_form.html:23
@@ -11508,7 +11514,7 @@ msgstr "Настроить таблицу"
#: templates/ipam/aggregate.html:15 templates/ipam/ipaddress.html:17
#: templates/ipam/iprange.html:16 templates/ipam/prefix.html:16
msgid "Family"
-msgstr "Семья"
+msgstr "Семейство"
#: templates/ipam/aggregate.html:40
msgid "Date Added"
@@ -11618,7 +11624,7 @@ msgstr "Отмечено как полностью использованное"
#: templates/ipam/prefix.html:112
msgid "Child IPs"
-msgstr "Детские IP-адреса"
+msgstr "Зависимые IP-адреса"
#: templates/ipam/prefix.html:120
msgid "Available IPs"
@@ -11707,7 +11713,7 @@ msgstr "Обычай"
#: templates/ipam/service_edit.html:37
msgid "Port(s)"
-msgstr "Порт (ы)"
+msgstr "Порт(ы)"
#: templates/ipam/vlan.html:95
msgid "Add a Prefix"
@@ -12158,7 +12164,7 @@ msgstr "Контактная группа (ID)"
#: tenancy/filtersets.py:35 tenancy/filtersets.py:62 tenancy/filtersets.py:104
msgid "Contact group (slug)"
-msgstr "Контактная группа (slug)"
+msgstr "Группа контактов (подстрока)"
#: tenancy/filtersets.py:91
msgid "Contact (ID)"
@@ -12170,7 +12176,7 @@ msgstr "Роль контакта (ID)"
#: tenancy/filtersets.py:114
msgid "Contact role (slug)"
-msgstr "Контактная роль (пуля)"
+msgstr "Роль контакта (подстрока)"
#: tenancy/filtersets.py:146
msgid "Contact group"
@@ -12186,7 +12192,7 @@ msgstr "Группа арендаторов (ID)"
#: tenancy/filtersets.py:216
msgid "Tenant Group (slug)"
-msgstr "Группа арендаторов (slug)"
+msgstr "Группа тенантов (подстрока)"
#: tenancy/forms/bulk_edit.py:65
msgid "Desciption"
@@ -12263,7 +12269,7 @@ msgstr "Имя арендатора должно быть уникальным
#: tenancy/models/tenants.py:80
msgid "Tenant slug must be unique per group."
-msgstr "Заголовок арендатора должен быть уникальным для каждой группы."
+msgstr "Подстрока тенанта должна быть уникальной для каждой группы."
#: tenancy/models/tenants.py:88
msgid "tenant"
@@ -12852,7 +12858,7 @@ msgstr "Родительская группа (ID)"
#: virtualization/filtersets.py:85
msgid "Parent group (slug)"
-msgstr "Родительская группа (слизень)"
+msgstr "Родительская группа (подстрока)"
#: virtualization/filtersets.py:89 virtualization/filtersets.py:140
msgid "Cluster type (ID)"
@@ -13140,7 +13146,7 @@ msgstr "Группа туннелей (ID)"
#: vpn/filtersets.py:47
msgid "Tunnel group (slug)"
-msgstr "Туннельная группа (пуля)"
+msgstr "Группа туннелей (подстрока)"
#: vpn/filtersets.py:54
msgid "IPSec profile (ID)"
@@ -13180,7 +13186,7 @@ msgstr "Политика IPsec (имя)"
#: vpn/filtersets.py:320
msgid "L2VPN (slug)"
-msgstr "L2VPN (слаггер)"
+msgstr "L2VPN (подстрока)"
#: vpn/filtersets.py:384
msgid "VM Interface (ID)"
diff --git a/netbox/vpn/choices.py b/netbox/vpn/choices.py
index a272060e9..c4ae67619 100644
--- a/netbox/vpn/choices.py
+++ b/netbox/vpn/choices.py
@@ -38,11 +38,11 @@ class TunnelEncapsulationChoices(ChoiceSet):
class TunnelTerminationTypeChoices(ChoiceSet):
# For TunnelCreateForm
TYPE_DEVICE = 'dcim.device'
- TYPE_VIRUTALMACHINE = 'virtualization.virtualmachine'
+ TYPE_VIRTUALMACHINE = 'virtualization.virtualmachine'
CHOICES = (
(TYPE_DEVICE, _('Device')),
- (TYPE_VIRUTALMACHINE, _('Virtual Machine')),
+ (TYPE_VIRTUALMACHINE, _('Virtual Machine')),
)
@@ -179,6 +179,7 @@ class DHGroupChoices(ChoiceSet):
(GROUP_2, _('Group {n}').format(n=2)),
(GROUP_5, _('Group {n}').format(n=5)),
(GROUP_14, _('Group {n}').format(n=14)),
+ (GROUP_15, _('Group {n}').format(n=15)),
(GROUP_16, _('Group {n}').format(n=16)),
(GROUP_17, _('Group {n}').format(n=17)),
(GROUP_18, _('Group {n}').format(n=18)),
diff --git a/netbox/vpn/forms/bulk_import.py b/netbox/vpn/forms/bulk_import.py
index c5d53eb1d..0f8f43944 100644
--- a/netbox/vpn/forms/bulk_import.py
+++ b/netbox/vpn/forms/bulk_import.py
@@ -151,7 +151,8 @@ class IKEProposalImportForm(NetBoxModelImportForm):
)
authentication_algorithm = CSVChoiceField(
label=_('Authentication algorithm'),
- choices=AuthenticationAlgorithmChoices
+ choices=AuthenticationAlgorithmChoices,
+ required=False
)
group = CSVChoiceField(
label=_('Group'),
@@ -191,11 +192,13 @@ class IKEPolicyImportForm(NetBoxModelImportForm):
class IPSecProposalImportForm(NetBoxModelImportForm):
encryption_algorithm = CSVChoiceField(
label=_('Encryption algorithm'),
- choices=EncryptionAlgorithmChoices
+ choices=EncryptionAlgorithmChoices,
+ required=False
)
authentication_algorithm = CSVChoiceField(
label=_('Authentication algorithm'),
- choices=AuthenticationAlgorithmChoices
+ choices=AuthenticationAlgorithmChoices,
+ required=False
)
class Meta:
@@ -209,7 +212,8 @@ class IPSecProposalImportForm(NetBoxModelImportForm):
class IPSecPolicyImportForm(NetBoxModelImportForm):
pfs_group = CSVChoiceField(
label=_('Diffie-Hellman group for Perfect Forward Secrecy'),
- choices=DHGroupChoices
+ choices=DHGroupChoices,
+ required=False
)
proposals = CSVModelMultipleChoiceField(
queryset=IPSecProposal.objects.all(),
diff --git a/netbox/vpn/forms/model_forms.py b/netbox/vpn/forms/model_forms.py
index 3068bfac2..6d7961e5a 100644
--- a/netbox/vpn/forms/model_forms.py
+++ b/netbox/vpn/forms/model_forms.py
@@ -7,7 +7,7 @@ from ipam.models import IPAddress, RouteTarget, VLAN
from netbox.forms import NetBoxModelForm
from tenancy.forms import TenancyForm
from utilities.forms.fields import CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SlugField
-from utilities.forms.utils import add_blank_choice
+from utilities.forms.utils import add_blank_choice, get_field_value
from utilities.forms.widgets import HTMXSelect
from virtualization.models import VirtualMachine, VMInterface
from vpn.choices import *
@@ -157,7 +157,7 @@ class TunnelCreateForm(TunnelForm):
def __init__(self, *args, initial=None, **kwargs):
super().__init__(*args, initial=initial, **kwargs)
- if initial and initial.get('termination1_type') == TunnelTerminationTypeChoices.TYPE_VIRUTALMACHINE:
+ if get_field_value(self, 'termination1_type') == TunnelTerminationTypeChoices.TYPE_VIRTUALMACHINE:
self.fields['termination1_parent'].label = _('Virtual Machine')
self.fields['termination1_parent'].queryset = VirtualMachine.objects.all()
self.fields['termination1_termination'].queryset = VMInterface.objects.all()
@@ -168,7 +168,7 @@ class TunnelCreateForm(TunnelForm):
'virtual_machine_id': '$termination1_parent',
})
- if initial and initial.get('termination2_type') == TunnelTerminationTypeChoices.TYPE_VIRUTALMACHINE:
+ if get_field_value(self, 'termination2_type') == TunnelTerminationTypeChoices.TYPE_VIRTUALMACHINE:
self.fields['termination2_parent'].label = _('Virtual Machine')
self.fields['termination2_parent'].queryset = VirtualMachine.objects.all()
self.fields['termination2_termination'].queryset = VMInterface.objects.all()
@@ -265,7 +265,7 @@ class TunnelTerminationForm(NetBoxModelForm):
def __init__(self, *args, initial=None, **kwargs):
super().__init__(*args, initial=initial, **kwargs)
- if initial and initial.get('type') == TunnelTerminationTypeChoices.TYPE_VIRUTALMACHINE:
+ if initial and initial.get('type') == TunnelTerminationTypeChoices.TYPE_VIRTUALMACHINE:
self.fields['parent'].label = _('Virtual Machine')
self.fields['parent'].queryset = VirtualMachine.objects.all()
self.fields['termination'].queryset = VMInterface.objects.all()
diff --git a/netbox/vpn/migrations/0003_ipaddress_multiple_tunnel_terminations.py b/netbox/vpn/migrations/0003_ipaddress_multiple_tunnel_terminations.py
new file mode 100644
index 000000000..2747669ae
--- /dev/null
+++ b/netbox/vpn/migrations/0003_ipaddress_multiple_tunnel_terminations.py
@@ -0,0 +1,20 @@
+# Generated by Django 4.2.8 on 2024-01-05 19:31
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ipam', '0069_gfk_indexes'),
+ ('vpn', '0002_move_l2vpn'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='tunneltermination',
+ name='outside_ip',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tunnel_terminations', to='ipam.ipaddress'),
+ ),
+ ]
diff --git a/netbox/vpn/models/tunnels.py b/netbox/vpn/models/tunnels.py
index be1e40142..6f4fa4182 100644
--- a/netbox/vpn/models/tunnels.py
+++ b/netbox/vpn/models/tunnels.py
@@ -129,10 +129,10 @@ class TunnelTermination(CustomFieldsMixin, CustomLinksMixin, TagsMixin, ChangeLo
ct_field='termination_type',
fk_field='termination_id'
)
- outside_ip = models.OneToOneField(
+ outside_ip = models.ForeignKey(
to='ipam.IPAddress',
on_delete=models.PROTECT,
- related_name='tunnel_termination',
+ related_name='tunnel_terminations',
blank=True,
null=True
)
diff --git a/requirements.txt b/requirements.txt
index 7cbc5534c..48cfc4950 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,5 @@
bleach==6.1.0
-Django==4.2.8
+Django==4.2.9
django-cors-headers==4.3.1
django-debug-toolbar==4.2.0
django-filter==23.5
@@ -15,21 +15,21 @@ django-tables2==2.7.0
django-timezone-field==6.1.0
djangorestframework==3.14.0
drf-spectacular==0.27.0
-drf-spectacular-sidecar==2023.12.1
+drf-spectacular-sidecar==2024.1.1
feedparser==6.0.11
graphene-django==3.0.0
gunicorn==21.2.0
-Jinja2==3.1.2
-Markdown==3.5.1
-mkdocs-material==9.5.3
+Jinja2==3.1.3
+Markdown==3.5.2
+mkdocs-material==9.5.4
mkdocstrings[python-legacy]==0.24.0
-netaddr==0.9.0
-Pillow==10.1.0
-psycopg[binary,pool]==3.1.16
+netaddr==0.10.1
+Pillow==10.2.0
+psycopg[binary,pool]==3.1.17
PyYAML==6.0.1
requests==2.31.0
social-auth-app-django==5.4.0
social-auth-core[openidconnect]==4.5.1
svgwrite==1.4.3
tablib==3.5.0
-tzdata==2023.3
+tzdata==2023.4