mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 01:41:22 -06:00
Merge branch 'develop' into feature
This commit is contained in:
commit
a12fdd6e2d
2
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@ -26,7 +26,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: NetBox Version
|
label: NetBox Version
|
||||||
description: What version of NetBox are you currently running?
|
description: What version of NetBox are you currently running?
|
||||||
placeholder: v4.0.7
|
placeholder: v4.0.8
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
|
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
@ -14,7 +14,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: NetBox version
|
label: NetBox version
|
||||||
description: What version of NetBox are you currently running?
|
description: What version of NetBox are you currently running?
|
||||||
placeholder: v4.0.7
|
placeholder: v4.0.8
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
|
2
.github/workflows/auto-assign-issue.yml
vendored
2
.github/workflows/auto-assign-issue.yml
vendored
@ -16,6 +16,6 @@ jobs:
|
|||||||
if: "contains(github.event.issue.labels.*.name, 'status: needs triage')"
|
if: "contains(github.event.issue.labels.*.name, 'status: needs triage')"
|
||||||
with:
|
with:
|
||||||
# Weighted assignments
|
# Weighted assignments
|
||||||
assignees: arthanson:3, jeffgdotorg:3, jeremystretch:3, DanSheps
|
assignees: arthanson:3, jeremystretch:3, DanSheps
|
||||||
numOfAssignee: 1
|
numOfAssignee: 1
|
||||||
abortIfPreviousAssignees: true
|
abortIfPreviousAssignees: true
|
||||||
|
@ -40,7 +40,7 @@ NetBox users are welcome to participate in either role, on stage or in the crowd
|
|||||||
|
|
||||||
* First, ensure that you're running the [latest stable version](https://github.com/netbox-community/netbox/releases) of NetBox. If you're running an older version, it's likely that the bug has already been fixed.
|
* First, ensure that you're running the [latest stable version](https://github.com/netbox-community/netbox/releases) of NetBox. If you're running an older version, it's likely that the bug has already been fixed.
|
||||||
|
|
||||||
* Next, search our [issues list](https://github.com/netbox-community/netbox/issues?q=is%3Aissue) to see if the bug you've found has already been reported. If you come across a bug report that seems to match, please click "add a reaction" in the top right corner of the issue and add a thumbs up (:thumbsup:). This will help draw more attention to it. Any comments you can add to provide additional information or context would also be much appreciated.
|
* Next, search our [issues list](https://github.com/netbox-community/netbox/issues?q=is%3Aissue) to see if the bug you've found has already been reported. If you come across a bug report that seems to match, please click "add a reaction" in the bottom left corner of the issue and add a thumbs up (:thumbsup:). This will help draw more attention to it. Any comments you can add to provide additional information or context would also be much appreciated.
|
||||||
|
|
||||||
* If you can't find any existing issues (open or closed) that seem to match yours, you're welcome to [submit a new bug report](https://github.com/netbox-community/netbox/issues/new?label=type%3A+bug&template=bug_report.yaml). Be sure to complete the entire report template, including detailed steps that someone triaging your issue can follow to confirm the reported behavior. (If we're not able to replicate the bug based on the information provided, we'll ask for additional detail.)
|
* If you can't find any existing issues (open or closed) that seem to match yours, you're welcome to [submit a new bug report](https://github.com/netbox-community/netbox/issues/new?label=type%3A+bug&template=bug_report.yaml). Be sure to complete the entire report template, including detailed steps that someone triaging your issue can follow to confirm the reported behavior. (If we're not able to replicate the bug based on the information provided, we'll ask for additional detail.)
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<a href="https://github.com/netbox-community/netbox/blob/master/LICENSE.txt"><img src="https://img.shields.io/badge/license-Apache_2.0-blue.svg" alt="License" /></a>
|
<a href="https://github.com/netbox-community/netbox/blob/master/LICENSE.txt"><img src="https://img.shields.io/badge/license-Apache_2.0-blue.svg" alt="License" /></a>
|
||||||
<a href="https://github.com/netbox-community/netbox/graphs/contributors"><img src="https://img.shields.io/github/contributors/netbox-community/netbox?color=blue" alt="Contributors" /></a>
|
<a href="https://github.com/netbox-community/netbox/graphs/contributors"><img src="https://img.shields.io/github/contributors/netbox-community/netbox?color=blue" alt="Contributors" /></a>
|
||||||
<a href="https://github.com/netbox-community/netbox/stargazers"><img src="https://img.shields.io/github/stars/netbox-community/netbox?style=flat" alt="GitHub stars" /></a>
|
<a href="https://github.com/netbox-community/netbox/stargazers"><img src="https://img.shields.io/github/stars/netbox-community/netbox?style=flat" alt="GitHub stars" /></a>
|
||||||
<a href="https://explore.transifex.com/netbox-community/netbox/"><img src="https://img.shields.io/badge/languages-10-blue" alt="Languages supported" /></a>
|
<a href="https://explore.transifex.com/netbox-community/netbox/"><img src="https://img.shields.io/badge/languages-15-blue" alt="Languages supported" /></a>
|
||||||
<a href="https://github.com/netbox-community/netbox/actions/workflows/ci.yml"><img src="https://github.com/netbox-community/netbox/workflows/CI/badge.svg?branch=master" alt="CI status" /></a>
|
<a href="https://github.com/netbox-community/netbox/actions/workflows/ci.yml"><img src="https://github.com/netbox-community/netbox/workflows/CI/badge.svg?branch=master" alt="CI status" /></a>
|
||||||
<p></p>
|
<p></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,7 +16,7 @@ Administrators are encouraged to adhere to industry best practices concerning th
|
|||||||
|
|
||||||
## Reporting a Suspected Vulnerability
|
## Reporting a Suspected Vulnerability
|
||||||
|
|
||||||
If you believe you've uncovered a security vulnerability and wish to report it confidentially, you may do so via email. Please note that any reported vulnerabilities **MUST** meet all the following conditions:
|
If you believe you've uncovered a security vulnerability and wish to report it confidentially, you may do so by emailing `security@netboxlabs.com`. Please ensure that your report meets all the following conditions:
|
||||||
|
|
||||||
* Affects the most recent stable release of NetBox, or a current beta release
|
* Affects the most recent stable release of NetBox, or a current beta release
|
||||||
* Affects a NetBox instance installed and configured per the official documentation
|
* Affects a NetBox instance installed and configured per the official documentation
|
||||||
@ -24,7 +24,7 @@ If you believe you've uncovered a security vulnerability and wish to report it c
|
|||||||
|
|
||||||
Please note that we **DO NOT** accept reports generated by automated tooling which merely suggest that a file or file(s) _may_ be vulnerable under certain conditions, as these are most often innocuous.
|
Please note that we **DO NOT** accept reports generated by automated tooling which merely suggest that a file or file(s) _may_ be vulnerable under certain conditions, as these are most often innocuous.
|
||||||
|
|
||||||
If you believe that you've found a vulnerability which meets all of these conditions, please [submit a draft security advisory](https://github.com/netbox-community/netbox/security/advisories/new) on GitHub. For any security concerns regarding NetBox deployed via Docker, please see the [netbox-docker](https://github.com/netbox-community/netbox-docker) project.
|
For any security concerns regarding the community-maintained Docker image for NetBox, please see the [netbox-docker](https://github.com/netbox-community/netbox-docker) project.
|
||||||
|
|
||||||
### Bug Bounties
|
### Bug Bounties
|
||||||
|
|
||||||
|
@ -40,3 +40,22 @@ REMOTE_AUTH_BACKEND = 'social_core.backends.google.GoogleOAuth2'
|
|||||||
NetBox supports single sign-on authentication via the [python-social-auth](https://github.com/python-social-auth) library. To enable SSO, specify the path to the desired authentication backend within the `social_core` Python package. Please see the complete list of [supported authentication backends](https://github.com/python-social-auth/social-core/tree/master/social_core/backends) for the available options.
|
NetBox supports single sign-on authentication via the [python-social-auth](https://github.com/python-social-auth) library. To enable SSO, specify the path to the desired authentication backend within the `social_core` Python package. Please see the complete list of [supported authentication backends](https://github.com/python-social-auth/social-core/tree/master/social_core/backends) for the available options.
|
||||||
|
|
||||||
Most remote authentication backends require some additional configuration through settings prefixed with `SOCIAL_AUTH_`. These will be automatically imported from NetBox's `configuration.py` file. Additionally, the [authentication pipeline](https://python-social-auth.readthedocs.io/en/latest/pipeline.html) can be customized via the `SOCIAL_AUTH_PIPELINE` parameter. (NetBox's default pipeline is defined in `netbox/settings.py` for your reference.)
|
Most remote authentication backends require some additional configuration through settings prefixed with `SOCIAL_AUTH_`. These will be automatically imported from NetBox's `configuration.py` file. Additionally, the [authentication pipeline](https://python-social-auth.readthedocs.io/en/latest/pipeline.html) can be customized via the `SOCIAL_AUTH_PIPELINE` parameter. (NetBox's default pipeline is defined in `netbox/settings.py` for your reference.)
|
||||||
|
|
||||||
|
#### Configuring the SSO module's appearance
|
||||||
|
|
||||||
|
The way a remote authentication backend is displayed to the user on the login
|
||||||
|
page may be adjusted via the `SOCIAL_AUTH_BACKEND_ATTRS` parameter, defaulting
|
||||||
|
to an empty dictionary. This dictionary maps a `social_core` module's name (ie.
|
||||||
|
`REMOTE_AUTH_BACKEND.name`) to a couple of parameters, `(display_name, icon)`.
|
||||||
|
|
||||||
|
The `display_name` is the name displayed to the user on the login page. The
|
||||||
|
icon may either be the URL of an icon; refer to a [Material Design
|
||||||
|
Icons](https://github.com/google/material-design-icons) icon's name; or be
|
||||||
|
`None` for no icon.
|
||||||
|
|
||||||
|
For instance, the OIDC backend may be customized with
|
||||||
|
```python
|
||||||
|
SOCIAL_AUTH_BACKEND_ATTRS = {
|
||||||
|
'oidc': ("My awesome SSO", "login"),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -113,7 +113,7 @@ Create a [new release](https://github.com/netbox-community/netbox/releases/new)
|
|||||||
* **Tag:** Current version (e.g. `v3.3.1`)
|
* **Tag:** Current version (e.g. `v3.3.1`)
|
||||||
* **Target:** `master`
|
* **Target:** `master`
|
||||||
* **Title:** Version and date (e.g. `v3.3.1 - 2022-08-25`)
|
* **Title:** Version and date (e.g. `v3.3.1 - 2022-08-25`)
|
||||||
* **Description:** Copy from the pull request body
|
* **Description:** Copy from the pull request body, then promote the `###` headers to `##` ones
|
||||||
|
|
||||||
Once created, the release will become available for users to install.
|
Once created, the release will become available for users to install.
|
||||||
|
|
||||||
@ -135,6 +135,6 @@ First, run the `build-site` action, by navigating to Actions > build-site > Run
|
|||||||
|
|
||||||
Once the documentation files have been compiled, they must be published by running the `deploy-kinsta` action. Select the desired deployment environment (staging or production) and specify `latest` as the deploy tag.
|
Once the documentation files have been compiled, they must be published by running the `deploy-kinsta` action. Select the desired deployment environment (staging or production) and specify `latest` as the deploy tag.
|
||||||
|
|
||||||
Clear the CDN cache from the [Kinsta](https://my.kinsta.com/) portal. Navigate to _Sites_ / _NetBox Labs_ / _Live_, select _CDN_ in the left-nav, click the _Clear CDN cache_ button, and confirm the clear operation.
|
Clear the CDN cache from the [Kinsta](https://my.kinsta.com/) portal. Navigate to _Sites_ / _NetBox Labs_ / _Live_, select _Cache_ in the left-nav, click the _Clear Cache_ button, and confirm the clear operation.
|
||||||
|
|
||||||
Finally, verify that the documentation at <https://netboxlabs.com/docs/netbox/en/stable/> has been updated.
|
Finally, verify that the documentation at <https://netboxlabs.com/docs/netbox/en/stable/> has been updated.
|
||||||
|
@ -20,6 +20,8 @@ Then, commit the change and push to the `develop` branch on GitHub. Any new stri
|
|||||||
|
|
||||||
Typically, translated strings need to be updated only as part of the NetBox [release process](./release-checklist.md).
|
Typically, translated strings need to be updated only as part of the NetBox [release process](./release-checklist.md).
|
||||||
|
|
||||||
|
Check the Transifex dashboard for languages that are not marked _ready for use_, being sure to click _Show all languages_ if it appears at the bottom of the list. Use machine translation to round out any not-ready languages. It's not necessary to review the machine translation immediately as the translation teams will handle that aspect; the goal at this stage is to get translations included in the Transifex pull request.
|
||||||
|
|
||||||
To update translated strings, start by initiating a sync from Transifex. From the Transifex dashboard, navigate to Settings > Integrations > GitHub > Manage, and click the **Manual Sync** button at top right.
|
To update translated strings, start by initiating a sync from Transifex. From the Transifex dashboard, navigate to Settings > Integrations > GitHub > Manage, and click the **Manual Sync** button at top right.
|
||||||
|
|
||||||

|

|
||||||
|
@ -80,11 +80,11 @@ To create a viewset for a plugin model, subclass `NetBoxModelViewSet` in `api/vi
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
# api/views.py
|
# api/views.py
|
||||||
from netbox.api.viewsets import ModelViewSet
|
from netbox.api.viewsets import NetBoxModelViewSet
|
||||||
from my_plugin.models import MyModel
|
from my_plugin.models import MyModel
|
||||||
from .serializers import MyModelSerializer
|
from .serializers import MyModelSerializer
|
||||||
|
|
||||||
class MyModelViewSet(ModelViewSet):
|
class MyModelViewSet(NetBoxModelViewSet):
|
||||||
queryset = MyModel.objects.all()
|
queryset = MyModel.objects.all()
|
||||||
serializer_class = MyModelSerializer
|
serializer_class = MyModelSerializer
|
||||||
```
|
```
|
||||||
|
@ -1,6 +1,34 @@
|
|||||||
# NetBox v4.0
|
# NetBox v4.0
|
||||||
|
|
||||||
## v4.0.8 (FUTURE)
|
## v4.0.9 (FUTURE)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v4.0.8 (2024-07-26)
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
* [#14640](https://github.com/netbox-community/netbox/issues/14640) - Add Dutch language support
|
||||||
|
* [#14792](https://github.com/netbox-community/netbox/issues/14792) - Add Polish language support
|
||||||
|
* [#15375](https://github.com/netbox-community/netbox/issues/15375) - Enable customization of SSO backend name & icon
|
||||||
|
* [#15660](https://github.com/netbox-community/netbox/issues/15660) - Add Czech language support
|
||||||
|
* [#15696](https://github.com/netbox-community/netbox/issues/15696) - Add Danish language support
|
||||||
|
* [#16793](https://github.com/netbox-community/netbox/issues/16793) - Add Italian language support
|
||||||
|
* [#16933](https://github.com/netbox-community/netbox/issues/16933) - Enable toggling true/false marks on BooleanColumn
|
||||||
|
* [#16943](https://github.com/netbox-community/netbox/issues/16943) - Expand navigation breadcrumbs on job view to include the parent object
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* [#16357](https://github.com/netbox-community/netbox/issues/16357) - Replicate assigned type & tenant for cable when clicking "create an add another"
|
||||||
|
* [#16402](https://github.com/netbox-community/netbox/issues/16402) - Remove inoperative links from report result view
|
||||||
|
* [#16536](https://github.com/netbox-community/netbox/issues/16536) - Revert `role` & `role_id` filters for device components to `device_role` & `device_role_id` to avoid conflict with inventory item `role` field
|
||||||
|
* [#16624](https://github.com/netbox-community/netbox/issues/16624) - Correct OpenAPI schema definitions for several fields
|
||||||
|
* [#16760](https://github.com/netbox-community/netbox/issues/16760) - Fix data source syncing using git via a local path
|
||||||
|
* [#16819](https://github.com/netbox-community/netbox/issues/16819) - Highlight parent device in rack when viewing child device
|
||||||
|
* [#16838](https://github.com/netbox-community/netbox/issues/16838) - ActionsColumn should render extra buttons even when no stock actions are enabled
|
||||||
|
* [#16867](https://github.com/netbox-community/netbox/issues/16867) - Fix exception when a dashboard list widget references a model which has been removed
|
||||||
|
* [#16963](https://github.com/netbox-community/netbox/issues/16963) - Fix filtering of "accounts" link under providers list
|
||||||
|
* [#16964](https://github.com/netbox-community/netbox/issues/16964) - Ensure configured password validators are enforced
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -46,10 +46,20 @@ class LoginView(View):
|
|||||||
return super().dispatch(*args, **kwargs)
|
return super().dispatch(*args, **kwargs)
|
||||||
|
|
||||||
def gen_auth_data(self, name, url, params):
|
def gen_auth_data(self, name, url, params):
|
||||||
display_name, icon_name = get_auth_backend_display(name)
|
display_name, icon_source = get_auth_backend_display(name)
|
||||||
|
|
||||||
|
icon_name = None
|
||||||
|
icon_img = None
|
||||||
|
if icon_source:
|
||||||
|
if '://' in icon_source:
|
||||||
|
icon_img = icon_source
|
||||||
|
else:
|
||||||
|
icon_name = icon_source
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'display_name': display_name,
|
'display_name': display_name,
|
||||||
'icon_name': icon_name,
|
'icon_name': icon_name,
|
||||||
|
'icon_img': icon_img,
|
||||||
'url': f'{url}?{urlencode(params)}',
|
'url': f'{url}?{urlencode(params)}',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ class ProviderTable(ContactsColumnMixin, NetBoxTable):
|
|||||||
account_count = columns.LinkedCountColumn(
|
account_count = columns.LinkedCountColumn(
|
||||||
accessor=tables.A('accounts__count'),
|
accessor=tables.A('accounts__count'),
|
||||||
viewname='circuits:provideraccount_list',
|
viewname='circuits:provideraccount_list',
|
||||||
url_params={'account_id': 'pk'},
|
url_params={'provider_id': 'pk'},
|
||||||
verbose_name=_('Account Count')
|
verbose_name=_('Account Count')
|
||||||
)
|
)
|
||||||
asns = columns.ManyToManyColumn(
|
asns = columns.ManyToManyColumn(
|
||||||
|
@ -84,9 +84,7 @@ class GitBackend(DataBackend):
|
|||||||
clone_args = {
|
clone_args = {
|
||||||
"branch": self.params.get('branch'),
|
"branch": self.params.get('branch'),
|
||||||
"config": self.config,
|
"config": self.config,
|
||||||
"depth": 1,
|
|
||||||
"errstream": porcelain.NoneStream(),
|
"errstream": porcelain.NoneStream(),
|
||||||
"quiet": True,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.url_scheme in ('http', 'https'):
|
if self.url_scheme in ('http', 'https'):
|
||||||
@ -97,6 +95,9 @@ class GitBackend(DataBackend):
|
|||||||
"password": self.params.get('password'),
|
"password": self.params.get('password'),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
if self.url_scheme:
|
||||||
|
clone_args["quiet"] = True
|
||||||
|
clone_args["depth"] = 1
|
||||||
|
|
||||||
logger.debug(f"Cloning git repo: {self.url}")
|
logger.debug(f"Cloning git repo: {self.url}")
|
||||||
try:
|
try:
|
||||||
|
@ -19,6 +19,7 @@ REVISION_BUTTONS = """
|
|||||||
class ConfigRevisionTable(NetBoxTable):
|
class ConfigRevisionTable(NetBoxTable):
|
||||||
is_active = columns.BooleanColumn(
|
is_active = columns.BooleanColumn(
|
||||||
verbose_name=_('Is Active'),
|
verbose_name=_('Is Active'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
actions = columns.ActionsColumn(
|
actions = columns.ActionsColumn(
|
||||||
actions=('delete',),
|
actions=('delete',),
|
||||||
|
@ -13,7 +13,7 @@ class ConnectedEndpointsSerializer(serializers.ModelSerializer):
|
|||||||
"""
|
"""
|
||||||
Legacy serializer for pre-v3.3 connections
|
Legacy serializer for pre-v3.3 connections
|
||||||
"""
|
"""
|
||||||
connected_endpoints_type = serializers.SerializerMethodField(read_only=True)
|
connected_endpoints_type = serializers.SerializerMethodField(read_only=True, allow_null=True)
|
||||||
connected_endpoints = serializers.SerializerMethodField(read_only=True)
|
connected_endpoints = serializers.SerializerMethodField(read_only=True)
|
||||||
connected_endpoints_reachable = serializers.SerializerMethodField(read_only=True)
|
connected_endpoints_reachable = serializers.SerializerMethodField(read_only=True)
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ class ConnectedEndpointsSerializer(serializers.ModelSerializer):
|
|||||||
if endpoints := obj.connected_endpoints:
|
if endpoints := obj.connected_endpoints:
|
||||||
return f'{endpoints[0]._meta.app_label}.{endpoints[0]._meta.model_name}'
|
return f'{endpoints[0]._meta.app_label}.{endpoints[0]._meta.model_name}'
|
||||||
|
|
||||||
@extend_schema_field(serializers.ListField)
|
@extend_schema_field(serializers.ListField(allow_null=True))
|
||||||
def get_connected_endpoints(self, obj):
|
def get_connected_endpoints(self, obj):
|
||||||
"""
|
"""
|
||||||
Return the appropriate serializer for the type of connected object.
|
Return the appropriate serializer for the type of connected object.
|
||||||
|
@ -89,7 +89,7 @@ class CablePathSerializer(serializers.ModelSerializer):
|
|||||||
class CabledObjectSerializer(serializers.ModelSerializer):
|
class CabledObjectSerializer(serializers.ModelSerializer):
|
||||||
cable = CableSerializer(nested=True, read_only=True, allow_null=True)
|
cable = CableSerializer(nested=True, read_only=True, allow_null=True)
|
||||||
cable_end = serializers.CharField(read_only=True)
|
cable_end = serializers.CharField(read_only=True)
|
||||||
link_peers_type = serializers.SerializerMethodField(read_only=True)
|
link_peers_type = serializers.SerializerMethodField(read_only=True, allow_null=True)
|
||||||
link_peers = serializers.SerializerMethodField(read_only=True)
|
link_peers = serializers.SerializerMethodField(read_only=True)
|
||||||
_occupied = serializers.SerializerMethodField(read_only=True)
|
_occupied = serializers.SerializerMethodField(read_only=True)
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ class DeviceSerializer(NetBoxModelSerializer):
|
|||||||
]
|
]
|
||||||
brief_fields = ('id', 'url', 'display', 'name', 'description')
|
brief_fields = ('id', 'url', 'display', 'name', 'description')
|
||||||
|
|
||||||
@extend_schema_field(NestedDeviceSerializer)
|
@extend_schema_field(NestedDeviceSerializer(allow_null=True))
|
||||||
def get_parent_device(self, obj):
|
def get_parent_device(self, obj):
|
||||||
try:
|
try:
|
||||||
device_bay = obj.parent_bay
|
device_bay = obj.parent_bay
|
||||||
|
@ -1430,12 +1430,12 @@ class DeviceComponentFilterSet(django_filters.FilterSet):
|
|||||||
to_field_name='model',
|
to_field_name='model',
|
||||||
label=_('Device type (model)'),
|
label=_('Device type (model)'),
|
||||||
)
|
)
|
||||||
role_id = django_filters.ModelMultipleChoiceFilter(
|
device_role_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='device__role',
|
field_name='device__role',
|
||||||
queryset=DeviceRole.objects.all(),
|
queryset=DeviceRole.objects.all(),
|
||||||
label=_('Device role (ID)'),
|
label=_('Device role (ID)'),
|
||||||
)
|
)
|
||||||
role = django_filters.ModelMultipleChoiceFilter(
|
device_role = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='device__role__slug',
|
field_name='device__role__slug',
|
||||||
queryset=DeviceRole.objects.all(),
|
queryset=DeviceRole.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
|
@ -88,6 +88,8 @@ class Cable(PrimaryModel):
|
|||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
clone_fields = ('tenant', 'type',)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('pk',)
|
ordering = ('pk',)
|
||||||
verbose_name = _('cable')
|
verbose_name = _('cable')
|
||||||
|
@ -63,7 +63,10 @@ class DeviceRoleTable(NetBoxTable):
|
|||||||
verbose_name=_('VMs')
|
verbose_name=_('VMs')
|
||||||
)
|
)
|
||||||
color = columns.ColorColumn()
|
color = columns.ColorColumn()
|
||||||
vm_role = columns.BooleanColumn()
|
vm_role = columns.BooleanColumn(
|
||||||
|
verbose_name=_('VM role'),
|
||||||
|
false_mark=None
|
||||||
|
)
|
||||||
config_template = tables.Column(
|
config_template = tables.Column(
|
||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
@ -329,6 +332,7 @@ class CableTerminationTable(NetBoxTable):
|
|||||||
)
|
)
|
||||||
mark_connected = columns.BooleanColumn(
|
mark_connected = columns.BooleanColumn(
|
||||||
verbose_name=_('Mark Connected'),
|
verbose_name=_('Mark Connected'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -586,7 +590,8 @@ class InterfaceTable(ModularDeviceComponentTable, BaseInterfaceTable, PathEndpoi
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
mgmt_only = columns.BooleanColumn(
|
mgmt_only = columns.BooleanColumn(
|
||||||
verbose_name=_('Management Only')
|
verbose_name=_('Management Only'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
speed_formatted = columns.TemplateColumn(
|
speed_formatted = columns.TemplateColumn(
|
||||||
template_code='{% load helpers %}{{ value|humanize_speed }}',
|
template_code='{% load helpers %}{{ value|humanize_speed }}',
|
||||||
@ -913,6 +918,7 @@ class InventoryItemTable(DeviceComponentTable):
|
|||||||
)
|
)
|
||||||
discovered = columns.BooleanColumn(
|
discovered = columns.BooleanColumn(
|
||||||
verbose_name=_('Discovered'),
|
verbose_name=_('Discovered'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
parent = tables.Column(
|
parent = tables.Column(
|
||||||
linkify=True,
|
linkify=True,
|
||||||
|
@ -86,7 +86,8 @@ class DeviceTypeTable(NetBoxTable):
|
|||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
is_full_depth = columns.BooleanColumn(
|
is_full_depth = columns.BooleanColumn(
|
||||||
verbose_name=_('Full Depth')
|
verbose_name=_('Full Depth'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
comments = columns.MarkdownColumn(
|
comments = columns.MarkdownColumn(
|
||||||
verbose_name=_('Comments'),
|
verbose_name=_('Comments'),
|
||||||
@ -98,7 +99,10 @@ class DeviceTypeTable(NetBoxTable):
|
|||||||
verbose_name=_('U Height'),
|
verbose_name=_('U Height'),
|
||||||
template_code='{{ value|floatformat }}'
|
template_code='{{ value|floatformat }}'
|
||||||
)
|
)
|
||||||
exclude_from_utilization = columns.BooleanColumn()
|
exclude_from_utilization = columns.BooleanColumn(
|
||||||
|
verbose_name=_('Exclude from utilization'),
|
||||||
|
false_mark=None
|
||||||
|
)
|
||||||
weight = columns.TemplateColumn(
|
weight = columns.TemplateColumn(
|
||||||
verbose_name=_('Weight'),
|
verbose_name=_('Weight'),
|
||||||
template_code=WEIGHT,
|
template_code=WEIGHT,
|
||||||
@ -221,7 +225,8 @@ class InterfaceTemplateTable(ComponentTemplateTable):
|
|||||||
verbose_name=_('Enabled'),
|
verbose_name=_('Enabled'),
|
||||||
)
|
)
|
||||||
mgmt_only = columns.BooleanColumn(
|
mgmt_only = columns.BooleanColumn(
|
||||||
verbose_name=_('Management Only')
|
verbose_name=_('Management Only'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
actions = columns.ActionsColumn(
|
actions = columns.ActionsColumn(
|
||||||
actions=('edit', 'delete'),
|
actions=('edit', 'delete'),
|
||||||
|
@ -32,11 +32,11 @@ class DeviceComponentFilterSetTests:
|
|||||||
params = {'device_type': [device_types[0].model, device_types[1].model]}
|
params = {'device_type': [device_types[0].model, device_types[1].model]}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
def test_role(self):
|
def test_device_role(self):
|
||||||
role = DeviceRole.objects.all()[:2]
|
role = DeviceRole.objects.all()[:2]
|
||||||
params = {'role_id': [role[0].pk, role[1].pk]}
|
params = {'device_role_id': [role[0].pk, role[1].pk]}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
params = {'role': [role[0].slug, role[1].slug]}
|
params = {'device_role': [role[0].slug, role[1].slug]}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||||
|
|
||||||
|
|
||||||
@ -4693,6 +4693,13 @@ class InventoryItemTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||||||
params = {'device_type': [device_types[0].model, device_types[1].model]}
|
params = {'device_type': [device_types[0].model, device_types[1].model]}
|
||||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
|
||||||
|
|
||||||
|
def test_device_role(self):
|
||||||
|
role = DeviceRole.objects.all()[:2]
|
||||||
|
params = {'device_role_id': [role[0].pk, role[1].pk]}
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
|
||||||
|
params = {'device_role': [role[0].slug, role[1].slug]}
|
||||||
|
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 4)
|
||||||
|
|
||||||
def test_role(self):
|
def test_role(self):
|
||||||
role = DeviceRole.objects.all()[:2]
|
role = DeviceRole.objects.all()[:2]
|
||||||
params = {'role_id': [role[0].pk, role[1].pk]}
|
params = {'role_id': [role[0].pk, role[1].pk]}
|
||||||
|
@ -38,7 +38,7 @@ class ScriptSerializer(ValidatedModelSerializer):
|
|||||||
def get_display(self, obj):
|
def get_display(self, obj):
|
||||||
return f'{obj.name} ({obj.module})'
|
return f'{obj.name} ({obj.module})'
|
||||||
|
|
||||||
@extend_schema_field(serializers.CharField())
|
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||||
def get_description(self, obj):
|
def get_description(self, obj):
|
||||||
if obj.python_class:
|
if obj.python_class:
|
||||||
return obj.python_class().description
|
return obj.python_class().description
|
||||||
|
@ -251,6 +251,10 @@ class ObjectListWidget(DashboardWidget):
|
|||||||
def render(self, request):
|
def render(self, request):
|
||||||
app_label, model_name = self.config['model'].split('.')
|
app_label, model_name = self.config['model'].split('.')
|
||||||
model = ObjectType.objects.get_by_natural_key(app_label, model_name).model_class()
|
model = ObjectType.objects.get_by_natural_key(app_label, model_name).model_class()
|
||||||
|
if not model:
|
||||||
|
logger.debug(f"Dashboard Widget model_class not found: {app_label}:{model_name}")
|
||||||
|
return
|
||||||
|
|
||||||
viewname = get_viewname(model, action='list')
|
viewname = get_viewname(model, action='list')
|
||||||
|
|
||||||
# Evaluate user's permission. Note that this controls only whether the HTMX element is
|
# Evaluate user's permission. Note that this controls only whether the HTMX element is
|
||||||
|
@ -54,7 +54,8 @@ class CustomFieldTable(NetBoxTable):
|
|||||||
verbose_name=_('Object Types')
|
verbose_name=_('Object Types')
|
||||||
)
|
)
|
||||||
required = columns.BooleanColumn(
|
required = columns.BooleanColumn(
|
||||||
verbose_name=_('Required')
|
verbose_name=_('Required'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
ui_visible = columns.ChoiceFieldColumn(
|
ui_visible = columns.ChoiceFieldColumn(
|
||||||
verbose_name=_('Visible')
|
verbose_name=_('Visible')
|
||||||
@ -79,6 +80,7 @@ class CustomFieldTable(NetBoxTable):
|
|||||||
)
|
)
|
||||||
is_cloneable = columns.BooleanColumn(
|
is_cloneable = columns.BooleanColumn(
|
||||||
verbose_name=_('Is Cloneable'),
|
verbose_name=_('Is Cloneable'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
validation_minimum = tables.Column(
|
validation_minimum = tables.Column(
|
||||||
verbose_name=_('Minimum Value'),
|
verbose_name=_('Minimum Value'),
|
||||||
@ -125,6 +127,7 @@ class CustomFieldChoiceSetTable(NetBoxTable):
|
|||||||
)
|
)
|
||||||
order_alphabetically = columns.BooleanColumn(
|
order_alphabetically = columns.BooleanColumn(
|
||||||
verbose_name=_('Order Alphabetically'),
|
verbose_name=_('Order Alphabetically'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(NetBoxTable.Meta):
|
class Meta(NetBoxTable.Meta):
|
||||||
@ -149,6 +152,7 @@ class CustomLinkTable(NetBoxTable):
|
|||||||
)
|
)
|
||||||
new_window = columns.BooleanColumn(
|
new_window = columns.BooleanColumn(
|
||||||
verbose_name=_('New Window'),
|
verbose_name=_('New Window'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(NetBoxTable.Meta):
|
class Meta(NetBoxTable.Meta):
|
||||||
@ -170,6 +174,7 @@ class ExportTemplateTable(NetBoxTable):
|
|||||||
)
|
)
|
||||||
as_attachment = columns.BooleanColumn(
|
as_attachment = columns.BooleanColumn(
|
||||||
verbose_name=_('As Attachment'),
|
verbose_name=_('As Attachment'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
data_source = tables.Column(
|
data_source = tables.Column(
|
||||||
verbose_name=_('Data Source'),
|
verbose_name=_('Data Source'),
|
||||||
@ -238,6 +243,7 @@ class SavedFilterTable(NetBoxTable):
|
|||||||
)
|
)
|
||||||
shared = columns.BooleanColumn(
|
shared = columns.BooleanColumn(
|
||||||
verbose_name=_('Shared'),
|
verbose_name=_('Shared'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
|
|
||||||
def value_parameters(self, value):
|
def value_parameters(self, value):
|
||||||
|
@ -86,7 +86,8 @@ class RIRTable(NetBoxTable):
|
|||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
is_private = columns.BooleanColumn(
|
is_private = columns.BooleanColumn(
|
||||||
verbose_name=_('Private')
|
verbose_name=_('Private'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
aggregate_count = columns.LinkedCountColumn(
|
aggregate_count = columns.LinkedCountColumn(
|
||||||
viewname='ipam:aggregate_list',
|
viewname='ipam:aggregate_list',
|
||||||
@ -258,10 +259,12 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
is_pool = columns.BooleanColumn(
|
is_pool = columns.BooleanColumn(
|
||||||
verbose_name=_('Pool')
|
verbose_name=_('Pool'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
mark_utilized = columns.BooleanColumn(
|
mark_utilized = columns.BooleanColumn(
|
||||||
verbose_name=_('Marked Utilized')
|
verbose_name=_('Marked Utilized'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
utilization = PrefixUtilizationColumn(
|
utilization = PrefixUtilizationColumn(
|
||||||
verbose_name=_('Utilization'),
|
verbose_name=_('Utilization'),
|
||||||
@ -314,7 +317,8 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
linkify=True
|
linkify=True
|
||||||
)
|
)
|
||||||
mark_utilized = columns.BooleanColumn(
|
mark_utilized = columns.BooleanColumn(
|
||||||
verbose_name=_('Marked Utilized')
|
verbose_name=_('Marked Utilized'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
utilization = columns.UtilizationColumn(
|
utilization = columns.UtilizationColumn(
|
||||||
verbose_name=_('Utilization'),
|
verbose_name=_('Utilization'),
|
||||||
@ -386,7 +390,8 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
assigned = columns.BooleanColumn(
|
assigned = columns.BooleanColumn(
|
||||||
accessor='assigned_object_id',
|
accessor='assigned_object_id',
|
||||||
linkify=lambda record: record.assigned_object.get_absolute_url(),
|
linkify=lambda record: record.assigned_object.get_absolute_url(),
|
||||||
verbose_name=_('Assigned')
|
verbose_name=_('Assigned'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
comments = columns.MarkdownColumn(
|
comments = columns.MarkdownColumn(
|
||||||
verbose_name=_('Comments'),
|
verbose_name=_('Comments'),
|
||||||
|
@ -215,6 +215,7 @@ class InterfaceVLANTable(NetBoxTable):
|
|||||||
)
|
)
|
||||||
tagged = columns.BooleanColumn(
|
tagged = columns.BooleanColumn(
|
||||||
verbose_name=_('Tagged'),
|
verbose_name=_('Tagged'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
site = tables.Column(
|
site = tables.Column(
|
||||||
verbose_name=_('Site'),
|
verbose_name=_('Site'),
|
||||||
|
@ -30,7 +30,8 @@ class VRFTable(TenancyColumnsMixin, NetBoxTable):
|
|||||||
verbose_name=_('RD')
|
verbose_name=_('RD')
|
||||||
)
|
)
|
||||||
enforce_unique = columns.BooleanColumn(
|
enforce_unique = columns.BooleanColumn(
|
||||||
verbose_name=_('Unique')
|
verbose_name=_('Unique'),
|
||||||
|
false_mark=None
|
||||||
)
|
)
|
||||||
import_targets = columns.TemplateColumn(
|
import_targets = columns.TemplateColumn(
|
||||||
verbose_name=_('Import Targets'),
|
verbose_name=_('Import Targets'),
|
||||||
|
@ -49,12 +49,15 @@ AUTH_BACKEND_ATTRS = {
|
|||||||
'okta-openidconnect': ('Okta (OIDC)', None),
|
'okta-openidconnect': ('Okta (OIDC)', None),
|
||||||
'salesforce-oauth2': ('Salesforce', 'salesforce'),
|
'salesforce-oauth2': ('Salesforce', 'salesforce'),
|
||||||
}
|
}
|
||||||
|
# Override with potential user configuration
|
||||||
|
AUTH_BACKEND_ATTRS.update(getattr(settings, 'SOCIAL_AUTH_BACKEND_ATTRS', {}))
|
||||||
|
|
||||||
|
|
||||||
def get_auth_backend_display(name):
|
def get_auth_backend_display(name):
|
||||||
"""
|
"""
|
||||||
Return the user-friendly name and icon name for a remote authentication backend, if known. Defaults to the
|
Return the user-friendly name and icon name for a remote authentication backend, if
|
||||||
raw backend name and no icon.
|
known. Obtained from the defaults dictionary AUTH_BACKEND_ATTRS, overridden by the
|
||||||
|
setting `SOCIAL_AUTH_BACKEND_ATTRS`. Defaults to the raw backend name and no icon.
|
||||||
"""
|
"""
|
||||||
return AUTH_BACKEND_ATTRS.get(name, (name, None))
|
return AUTH_BACKEND_ATTRS.get(name, (name, None))
|
||||||
|
|
||||||
|
@ -742,11 +742,16 @@ RQ_QUEUES.update({
|
|||||||
|
|
||||||
# Supported translation languages
|
# Supported translation languages
|
||||||
LANGUAGES = (
|
LANGUAGES = (
|
||||||
|
('cs', _('Czech')),
|
||||||
|
('da', _('Danish')),
|
||||||
('de', _('German')),
|
('de', _('German')),
|
||||||
('en', _('English')),
|
('en', _('English')),
|
||||||
('es', _('Spanish')),
|
('es', _('Spanish')),
|
||||||
('fr', _('French')),
|
('fr', _('French')),
|
||||||
|
('it', _('Italian')),
|
||||||
('ja', _('Japanese')),
|
('ja', _('Japanese')),
|
||||||
|
('nl', _('Dutch')),
|
||||||
|
('pl', _('Polish')),
|
||||||
('pt', _('Portuguese')),
|
('pt', _('Portuguese')),
|
||||||
('ru', _('Russian')),
|
('ru', _('Russian')),
|
||||||
('tr', _('Turkish')),
|
('tr', _('Turkish')),
|
||||||
|
@ -194,14 +194,23 @@ class BooleanColumn(tables.Column):
|
|||||||
Custom implementation of BooleanColumn to render a nicely-formatted checkmark or X icon instead of a Unicode
|
Custom implementation of BooleanColumn to render a nicely-formatted checkmark or X icon instead of a Unicode
|
||||||
character.
|
character.
|
||||||
"""
|
"""
|
||||||
|
TRUE_MARK = mark_safe('<span class="text-success"><i class="mdi mdi-check-bold"></i></span>')
|
||||||
|
FALSE_MARK = mark_safe('<span class="text-danger"><i class="mdi mdi-close-thick"></i></span>')
|
||||||
|
EMPTY_MARK = mark_safe('<span class="text-muted">—</span>') # Placeholder
|
||||||
|
|
||||||
|
def __init__(self, *args, true_mark=TRUE_MARK, false_mark=FALSE_MARK, **kwargs):
|
||||||
|
self.true_mark = true_mark
|
||||||
|
self.false_mark = false_mark
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def render(self, value):
|
def render(self, value):
|
||||||
if value:
|
if value is None:
|
||||||
rendered = '<span class="text-success"><i class="mdi mdi-check-bold"></i></span>'
|
return self.EMPTY_MARK
|
||||||
elif value is None:
|
if value and self.true_mark:
|
||||||
rendered = '<span class="text-muted">—</span>'
|
return self.true_mark
|
||||||
else:
|
if not value and self.false_mark:
|
||||||
rendered = '<span class="text-danger"><i class="mdi mdi-close-thick"></i></span>'
|
return self.false_mark
|
||||||
return mark_safe(rendered)
|
return self.EMPTY_MARK
|
||||||
|
|
||||||
def value(self, value):
|
def value(self, value):
|
||||||
return str(value)
|
return str(value)
|
||||||
@ -249,7 +258,7 @@ class ActionsColumn(tables.Column):
|
|||||||
|
|
||||||
def render(self, record, table, **kwargs):
|
def render(self, record, table, **kwargs):
|
||||||
# Skip dummy records (e.g. available VLANs) or those with no actions
|
# Skip dummy records (e.g. available VLANs) or those with no actions
|
||||||
if not getattr(record, 'pk', None) or not self.actions:
|
if not getattr(record, 'pk', None) or not (self.actions or self.extra_buttons):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
model = table.Meta.model
|
model = table.Meta.model
|
||||||
|
BIN
netbox/project-static/dist/netbox.js
vendored
BIN
netbox/project-static/dist/netbox.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox.js.map
vendored
BIN
netbox/project-static/dist/netbox.js.map
vendored
Binary file not shown.
@ -27,10 +27,10 @@
|
|||||||
"bootstrap": "5.3.3",
|
"bootstrap": "5.3.3",
|
||||||
"clipboard": "2.0.11",
|
"clipboard": "2.0.11",
|
||||||
"flatpickr": "4.6.13",
|
"flatpickr": "4.6.13",
|
||||||
"gridstack": "10.3.0",
|
"gridstack": "10.3.1",
|
||||||
"htmx.org": "1.9.12",
|
"htmx.org": "1.9.12",
|
||||||
"query-string": "9.0.0",
|
"query-string": "9.1.0",
|
||||||
"sass": "1.77.6",
|
"sass": "1.77.8",
|
||||||
"tom-select": "2.3.1",
|
"tom-select": "2.3.1",
|
||||||
"typeface-inter": "3.18.1",
|
"typeface-inter": "3.18.1",
|
||||||
"typeface-roboto-mono": "1.1.13"
|
"typeface-roboto-mono": "1.1.13"
|
||||||
|
@ -1754,10 +1754,10 @@ graphql@16.8.1:
|
|||||||
resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.1.tgz#1930a965bef1170603702acdb68aedd3f3cf6f07"
|
resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.1.tgz#1930a965bef1170603702acdb68aedd3f3cf6f07"
|
||||||
integrity sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==
|
integrity sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==
|
||||||
|
|
||||||
gridstack@10.3.0:
|
gridstack@10.3.1:
|
||||||
version "10.3.0"
|
version "10.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-10.3.0.tgz#8fa065f896d0a880c5c54c24d189f3197184488a"
|
resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-10.3.1.tgz#4ed704279c40094fc1b9e3318f20b573f2fe9f40"
|
||||||
integrity sha512-eGKsmU2TppV4coyDu9IIdIkm4qjgLLdjlEOFwQyQMuSwfOpzSfLdPc8du0HuebGr7CvAIrJxN4lBOmGrWSBg9g==
|
integrity sha512-Ra82k/88gdeiu3ZP40COS4bI4sGhNQlZAaAQ6szfPfr68zVpsXxiyLKr5zYcTpKX4jjcwyNsNNdcV1tDJc71fA==
|
||||||
|
|
||||||
has-bigints@^1.0.1, has-bigints@^1.0.2:
|
has-bigints@^1.0.1, has-bigints@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
@ -2346,10 +2346,10 @@ punycode@^2.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
|
||||||
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
|
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
|
||||||
|
|
||||||
query-string@9.0.0:
|
query-string@9.1.0:
|
||||||
version "9.0.0"
|
version "9.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-9.0.0.tgz#1fe177cd95545600f0deab93f5fb02fd4e3e7273"
|
resolved "https://registry.yarnpkg.com/query-string/-/query-string-9.1.0.tgz#5f12a4653a4ba56021e113b5cf58e56581823e7a"
|
||||||
integrity sha512-4EWwcRGsO2H+yzq6ddHcVqkCQ2EFUSfDMEjF8ryp8ReymyZhIuaFRGLomeOQLkrzacMHoyky2HW0Qe30UbzkKw==
|
integrity sha512-t6dqMECpCkqfyv2FfwVS1xcB6lgXW/0XZSaKdsCNGYkqMO76AFiJEg4vINzoDKcZa6MS7JX+OHIjwh06K5vczw==
|
||||||
dependencies:
|
dependencies:
|
||||||
decode-uri-component "^0.4.1"
|
decode-uri-component "^0.4.1"
|
||||||
filter-obj "^5.1.0"
|
filter-obj "^5.1.0"
|
||||||
@ -2482,10 +2482,10 @@ safe-regex-test@^1.0.3:
|
|||||||
es-errors "^1.3.0"
|
es-errors "^1.3.0"
|
||||||
is-regex "^1.1.4"
|
is-regex "^1.1.4"
|
||||||
|
|
||||||
sass@1.77.6:
|
sass@1.77.8:
|
||||||
version "1.77.6"
|
version "1.77.8"
|
||||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.6.tgz#898845c1348078c2e6d1b64f9ee06b3f8bd489e4"
|
resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.8.tgz#9f18b449ea401759ef7ec1752a16373e296b52bd"
|
||||||
integrity sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==
|
integrity sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar ">=3.0.0 <4.0.0"
|
chokidar ">=3.0.0 <4.0.0"
|
||||||
immutable "^4.0.0"
|
immutable "^4.0.0"
|
||||||
|
@ -7,7 +7,11 @@
|
|||||||
<html
|
<html
|
||||||
lang="en"
|
lang="en"
|
||||||
data-netbox-url-name="{{ request.resolver_match.url_name }}"
|
data-netbox-url-name="{{ request.resolver_match.url_name }}"
|
||||||
data-netbox-base-path="{{ settings.BASE_PATH }}"
|
data-netbox-version="{{ settings.VERSION }}"
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
data-netbox-user-name="{{ request.user.username }}"
|
||||||
|
data-netbox-user-id="{{ request.user.pk }}"
|
||||||
|
{% endif %}
|
||||||
>
|
>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
@ -4,6 +4,18 @@
|
|||||||
{% load perms %}
|
{% load perms %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block breadcrumbs %}
|
||||||
|
{{ block.super }}
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="{% url 'core:job_list' %}?object_type={{ object.object_type_id }}">{{ object.object|meta:"verbose_name_plural"|bettertitle }}</a>
|
||||||
|
</li>
|
||||||
|
{% with parent_jobs_viewname=object.object|viewname:"jobs" %}
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="{% url parent_jobs_viewname pk=object.object.pk %}">{{ object.object }}</a>
|
||||||
|
</li>
|
||||||
|
{% endwith %}
|
||||||
|
{% endblock breadcrumbs %}
|
||||||
|
|
||||||
{% block control-buttons %}
|
{% block control-buttons %}
|
||||||
{% if request.user|can_delete:object %}
|
{% if request.user|can_delete:object %}
|
||||||
{% delete_button object %}
|
{% delete_button object %}
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<td class="d-flex justify-content-between align-items-start">
|
<td class="d-flex justify-content-between align-items-start">
|
||||||
{% if object.rack %}
|
{% if object.rack %}
|
||||||
{{ object.rack|linkify }}
|
{{ object.rack|linkify }}
|
||||||
<a href="{{ object.rack.get_absolute_url }}?device={{ object.pk }}" class="btn btn-primary btn-sm d-print-none" title="{% trans "Highlight device in rack" %}">
|
<a href="{{ object.rack.get_absolute_url }}?device={% firstof object.parent_bay.device.pk object.pk %}" class="btn btn-primary btn-sm d-print-none" title="{% trans "Highlight device in rack" %}">
|
||||||
<i class="mdi mdi-view-day-outline"></i>
|
<i class="mdi mdi-view-day-outline"></i>
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<table class="table table-hover">
|
<table class="table table-hover">
|
||||||
{% for test, data in tests.items %}
|
{% for test, data in tests.items %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="font-monospace"><a href="#{{ test }}">{{ test }}</a></td>
|
<td class="font-monospace">{{ test }}</td>
|
||||||
<td class="text-end report-stats">
|
<td class="text-end report-stats">
|
||||||
<span class="badge text-bg-success">{{ data.success }}</span>
|
<span class="badge text-bg-success">{{ data.success }}</span>
|
||||||
<span class="badge text-bg-info">{{ data.info }}</span>
|
<span class="badge text-bg-info">{{ data.info }}</span>
|
||||||
|
@ -78,7 +78,8 @@
|
|||||||
{% for backend in auth_backends %}
|
{% for backend in auth_backends %}
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<a href="{{ backend.url }}" class="btn w-100">
|
<a href="{{ backend.url }}" class="btn w-100">
|
||||||
{% if backend.icon_name %}<i class="mdi mdi-{{ backend.icon_name }}"></i>{% endif %}
|
{% if backend.icon_name %}<i class="mdi mdi-{{ backend.icon_name }}"></i>
|
||||||
|
{% elif backend.icon_img %}<img src="{{ backend.icon_img }}" height="24" class="me-2" />{% endif %}
|
||||||
{{ backend.display_name }}
|
{{ backend.display_name }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
15295
netbox/translations/cs/LC_MESSAGES/django.po
Normal file
15295
netbox/translations/cs/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
15310
netbox/translations/da/LC_MESSAGES/django.po
Normal file
15310
netbox/translations/da/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -6,21 +6,21 @@
|
|||||||
# Translators:
|
# Translators:
|
||||||
# Quentin Laurent, 2024
|
# Quentin Laurent, 2024
|
||||||
# Xavier W, 2024
|
# Xavier W, 2024
|
||||||
# Jeremy Stretch, 2024
|
|
||||||
# Jonathan Senecal, 2024
|
# Jonathan Senecal, 2024
|
||||||
# Lou Lecrivain, 2024
|
# Lou Lecrivain, 2024
|
||||||
# Jean Benoit <jean@unistra.fr>, 2024
|
# Jean Benoit <jean@unistra.fr>, 2024
|
||||||
# thomas rivemale, 2024
|
# thomas rivemale, 2024
|
||||||
# Jeff Gehlbach, 2024
|
# Jeff Gehlbach, 2024
|
||||||
|
# Jeremy Stretch, 2024
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-07-09 05:02+0000\n"
|
"POT-Creation-Date: 2024-07-11 05:01+0000\n"
|
||||||
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
|
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
|
||||||
"Last-Translator: Jeff Gehlbach, 2024\n"
|
"Last-Translator: Jeremy Stretch, 2024\n"
|
||||||
"Language-Team: French (https://app.transifex.com/netbox-community/teams/178115/fr/)\n"
|
"Language-Team: French (https://app.transifex.com/netbox-community/teams/178115/fr/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@ -69,7 +69,7 @@ msgstr "Dernière utilisation"
|
|||||||
msgid "Allowed IPs"
|
msgid "Allowed IPs"
|
||||||
msgstr "IP autorisées"
|
msgstr "IP autorisées"
|
||||||
|
|
||||||
#: netbox/account/views.py:204
|
#: netbox/account/views.py:214
|
||||||
msgid "Your preferences have been updated."
|
msgid "Your preferences have been updated."
|
||||||
msgstr "Vos préférences ont été mises à jour."
|
msgstr "Vos préférences ont été mises à jour."
|
||||||
|
|
||||||
@ -1519,16 +1519,16 @@ msgstr "Mot de passe"
|
|||||||
msgid "Branch"
|
msgid "Branch"
|
||||||
msgstr "Branche"
|
msgstr "Branche"
|
||||||
|
|
||||||
#: netbox/core/data_backends.py:105
|
#: netbox/core/data_backends.py:106
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Fetching remote data failed ({name}): {error}"
|
msgid "Fetching remote data failed ({name}): {error}"
|
||||||
msgstr "La récupération des données distantes a échoué ({name}) : {error}"
|
msgstr "La récupération des données distantes a échoué ({name}) : {error}"
|
||||||
|
|
||||||
#: netbox/core/data_backends.py:118
|
#: netbox/core/data_backends.py:119
|
||||||
msgid "AWS access key ID"
|
msgid "AWS access key ID"
|
||||||
msgstr "ID de clé d'accès AWS"
|
msgstr "ID de clé d'accès AWS"
|
||||||
|
|
||||||
#: netbox/core/data_backends.py:122
|
#: netbox/core/data_backends.py:123
|
||||||
msgid "AWS secret access key"
|
msgid "AWS secret access key"
|
||||||
msgstr "Clé d'accès secrète AWS"
|
msgstr "Clé d'accès secrète AWS"
|
||||||
|
|
||||||
@ -1877,7 +1877,7 @@ msgstr ""
|
|||||||
msgid "last updated"
|
msgid "last updated"
|
||||||
msgstr "dernière mise à jour"
|
msgstr "dernière mise à jour"
|
||||||
|
|
||||||
#: netbox/core/models/data.py:296 netbox/dcim/models/cables.py:442
|
#: netbox/core/models/data.py:296 netbox/dcim/models/cables.py:444
|
||||||
msgid "path"
|
msgid "path"
|
||||||
msgstr "chemin"
|
msgstr "chemin"
|
||||||
|
|
||||||
@ -4656,53 +4656,53 @@ msgstr "longueur"
|
|||||||
msgid "length unit"
|
msgid "length unit"
|
||||||
msgstr "unité de longueur"
|
msgstr "unité de longueur"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:93
|
#: netbox/dcim/models/cables.py:95
|
||||||
msgid "cable"
|
msgid "cable"
|
||||||
msgstr "câble"
|
msgstr "câble"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:94
|
#: netbox/dcim/models/cables.py:96
|
||||||
msgid "cables"
|
msgid "cables"
|
||||||
msgstr "câbles"
|
msgstr "câbles"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:163
|
#: netbox/dcim/models/cables.py:165
|
||||||
msgid "Must specify a unit when setting a cable length"
|
msgid "Must specify a unit when setting a cable length"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Vous devez spécifier une unité lors du réglage de la longueur du câble"
|
"Vous devez spécifier une unité lors du réglage de la longueur du câble"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:166
|
#: netbox/dcim/models/cables.py:168
|
||||||
msgid "Must define A and B terminations when creating a new cable."
|
msgid "Must define A and B terminations when creating a new cable."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Vous devez définir les terminaisons A et B lors de la création d'un nouveau "
|
"Vous devez définir les terminaisons A et B lors de la création d'un nouveau "
|
||||||
"câble."
|
"câble."
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:173
|
#: netbox/dcim/models/cables.py:175
|
||||||
msgid "Cannot connect different termination types to same end of cable."
|
msgid "Cannot connect different termination types to same end of cable."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Impossible de connecter différents types de terminaisons à la même extrémité"
|
"Impossible de connecter différents types de terminaisons à la même extrémité"
|
||||||
" du câble."
|
" du câble."
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:181
|
#: netbox/dcim/models/cables.py:183
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Incompatible termination types: {type_a} and {type_b}"
|
msgid "Incompatible termination types: {type_a} and {type_b}"
|
||||||
msgstr "Types de terminaison incompatibles : {type_a} et {type_b}"
|
msgstr "Types de terminaison incompatibles : {type_a} et {type_b}"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:191
|
#: netbox/dcim/models/cables.py:193
|
||||||
msgid "A and B terminations cannot connect to the same object."
|
msgid "A and B terminations cannot connect to the same object."
|
||||||
msgstr "Les terminaisons A et B ne peuvent pas se connecter au même objet."
|
msgstr "Les terminaisons A et B ne peuvent pas se connecter au même objet."
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:258 netbox/ipam/models/asns.py:37
|
#: netbox/dcim/models/cables.py:260 netbox/ipam/models/asns.py:37
|
||||||
msgid "end"
|
msgid "end"
|
||||||
msgstr "fin"
|
msgstr "fin"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:311
|
#: netbox/dcim/models/cables.py:313
|
||||||
msgid "cable termination"
|
msgid "cable termination"
|
||||||
msgstr "terminaison de câble"
|
msgstr "terminaison de câble"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:312
|
#: netbox/dcim/models/cables.py:314
|
||||||
msgid "cable terminations"
|
msgid "cable terminations"
|
||||||
msgstr "terminaisons de câble"
|
msgstr "terminaisons de câble"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:331
|
#: netbox/dcim/models/cables.py:333
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Duplicate termination found for {app_label}.{model} {termination_id}: cable "
|
"Duplicate termination found for {app_label}.{model} {termination_id}: cable "
|
||||||
@ -4711,34 +4711,34 @@ msgstr ""
|
|||||||
"Un doublon de terminaison a été trouvé pour {app_label}.{model} "
|
"Un doublon de terminaison a été trouvé pour {app_label}.{model} "
|
||||||
"{termination_id}: câble {cable_pk}"
|
"{termination_id}: câble {cable_pk}"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:341
|
#: netbox/dcim/models/cables.py:343
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Cables cannot be terminated to {type_display} interfaces"
|
msgid "Cables cannot be terminated to {type_display} interfaces"
|
||||||
msgstr "Les câbles ne peuvent pas être raccordés à {type_display} interfaces"
|
msgstr "Les câbles ne peuvent pas être raccordés à {type_display} interfaces"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:348
|
#: netbox/dcim/models/cables.py:350
|
||||||
msgid "Circuit terminations attached to a provider network may not be cabled."
|
msgid "Circuit terminations attached to a provider network may not be cabled."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Les terminaisons de circuit connectées au réseau d'un fournisseur peuvent ne"
|
"Les terminaisons de circuit connectées au réseau d'un fournisseur peuvent ne"
|
||||||
" pas être câblées."
|
" pas être câblées."
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:446 netbox/extras/models/configs.py:50
|
#: netbox/dcim/models/cables.py:448 netbox/extras/models/configs.py:50
|
||||||
msgid "is active"
|
msgid "is active"
|
||||||
msgstr "est actif"
|
msgstr "est actif"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:450
|
#: netbox/dcim/models/cables.py:452
|
||||||
msgid "is complete"
|
msgid "is complete"
|
||||||
msgstr "est terminé"
|
msgstr "est terminé"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:454
|
#: netbox/dcim/models/cables.py:456
|
||||||
msgid "is split"
|
msgid "is split"
|
||||||
msgstr "est divisé"
|
msgstr "est divisé"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:462
|
#: netbox/dcim/models/cables.py:464
|
||||||
msgid "cable path"
|
msgid "cable path"
|
||||||
msgstr "chemin de câble"
|
msgstr "chemin de câble"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:463
|
#: netbox/dcim/models/cables.py:465
|
||||||
msgid "cable paths"
|
msgid "cable paths"
|
||||||
msgstr "chemins de câbles"
|
msgstr "chemins de câbles"
|
||||||
|
|
||||||
@ -6983,43 +6983,43 @@ msgstr ""
|
|||||||
"Format non valide. Les paramètres d'URL doivent être transmis sous forme de "
|
"Format non valide. Les paramètres d'URL doivent être transmis sous forme de "
|
||||||
"dictionnaire."
|
"dictionnaire."
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:284
|
#: netbox/extras/dashboard/widgets.py:288
|
||||||
msgid "RSS Feed"
|
msgid "RSS Feed"
|
||||||
msgstr "Fil RSS"
|
msgstr "Fil RSS"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:289
|
#: netbox/extras/dashboard/widgets.py:293
|
||||||
msgid "Embed an RSS feed from an external website."
|
msgid "Embed an RSS feed from an external website."
|
||||||
msgstr "Intégrez un flux RSS provenant d'un site Web externe."
|
msgstr "Intégrez un flux RSS provenant d'un site Web externe."
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:296
|
#: netbox/extras/dashboard/widgets.py:300
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
msgstr "URL du flux"
|
msgstr "URL du flux"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:301
|
#: netbox/extras/dashboard/widgets.py:305
|
||||||
msgid "The maximum number of objects to display"
|
msgid "The maximum number of objects to display"
|
||||||
msgstr "Le nombre maximum d'objets à afficher"
|
msgstr "Le nombre maximum d'objets à afficher"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:306
|
#: netbox/extras/dashboard/widgets.py:310
|
||||||
msgid "How long to stored the cached content (in seconds)"
|
msgid "How long to stored the cached content (in seconds)"
|
||||||
msgstr "Durée de conservation du contenu mis en cache (en secondes)"
|
msgstr "Durée de conservation du contenu mis en cache (en secondes)"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:358
|
#: netbox/extras/dashboard/widgets.py:362
|
||||||
#: netbox/templates/account/base.html:10
|
#: netbox/templates/account/base.html:10
|
||||||
#: netbox/templates/account/bookmarks.html:7
|
#: netbox/templates/account/bookmarks.html:7
|
||||||
#: netbox/templates/inc/user_menu.html:30
|
#: netbox/templates/inc/user_menu.html:30
|
||||||
msgid "Bookmarks"
|
msgid "Bookmarks"
|
||||||
msgstr "Signets"
|
msgstr "Signets"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:362
|
#: netbox/extras/dashboard/widgets.py:366
|
||||||
msgid "Show your personal bookmarks"
|
msgid "Show your personal bookmarks"
|
||||||
msgstr "Afficher vos favoris personnels"
|
msgstr "Afficher vos favoris personnels"
|
||||||
|
|
||||||
#: netbox/extras/events.py:134
|
#: netbox/extras/events.py:137
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Unknown action type for an event rule: {action_type}"
|
msgid "Unknown action type for an event rule: {action_type}"
|
||||||
msgstr "Type d'action inconnu pour une règle d'événement : {action_type}"
|
msgstr "Type d'action inconnu pour une règle d'événement : {action_type}"
|
||||||
|
|
||||||
#: netbox/extras/events.py:182
|
#: netbox/extras/events.py:185
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Cannot import events pipeline {name} error: {error}"
|
msgid "Cannot import events pipeline {name} error: {error}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -10048,7 +10048,7 @@ msgstr ""
|
|||||||
"Valeur non valide. Spécifiez un type de contenu comme "
|
"Valeur non valide. Spécifiez un type de contenu comme "
|
||||||
"«<app_label>.<model_name>'."
|
"«<app_label>.<model_name>'."
|
||||||
|
|
||||||
#: netbox/netbox/authentication/__init__.py:138
|
#: netbox/netbox/authentication/__init__.py:141
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Invalid permission {permission} for model {model}"
|
msgid "Invalid permission {permission} for model {model}"
|
||||||
msgstr "Autorisation non valide {permission} pour modèle {model}"
|
msgstr "Autorisation non valide {permission} pour modèle {model}"
|
||||||
@ -10357,7 +10357,7 @@ msgstr "Type (s) d'objet"
|
|||||||
|
|
||||||
#: netbox/netbox/forms/__init__.py:40
|
#: netbox/netbox/forms/__init__.py:40
|
||||||
msgid "Lookup"
|
msgid "Lookup"
|
||||||
msgstr ""
|
msgstr "Chercher"
|
||||||
|
|
||||||
#: netbox/netbox/forms/base.py:88
|
#: netbox/netbox/forms/base.py:88
|
||||||
msgid ""
|
msgid ""
|
||||||
@ -10906,43 +10906,43 @@ msgstr "Impossible d'ajouter des magasins au registre après l'initialisation"
|
|||||||
msgid "Cannot delete stores from registry"
|
msgid "Cannot delete stores from registry"
|
||||||
msgstr "Impossible de supprimer des magasins du registre"
|
msgstr "Impossible de supprimer des magasins du registre"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:741
|
#: netbox/netbox/settings.py:742
|
||||||
msgid "German"
|
msgid "German"
|
||||||
msgstr "allemand"
|
msgstr "allemand"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:742
|
#: netbox/netbox/settings.py:743
|
||||||
msgid "English"
|
msgid "English"
|
||||||
msgstr "Anglais"
|
msgstr "Anglais"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:743
|
#: netbox/netbox/settings.py:744
|
||||||
msgid "Spanish"
|
msgid "Spanish"
|
||||||
msgstr "espagnol"
|
msgstr "espagnol"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:744
|
#: netbox/netbox/settings.py:745
|
||||||
msgid "French"
|
msgid "French"
|
||||||
msgstr "français"
|
msgstr "français"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:745
|
#: netbox/netbox/settings.py:746
|
||||||
msgid "Japanese"
|
msgid "Japanese"
|
||||||
msgstr "japonais"
|
msgstr "japonais"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:746
|
#: netbox/netbox/settings.py:747
|
||||||
msgid "Portuguese"
|
msgid "Portuguese"
|
||||||
msgstr "portugais"
|
msgstr "portugais"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:747
|
#: netbox/netbox/settings.py:748
|
||||||
msgid "Russian"
|
msgid "Russian"
|
||||||
msgstr "russe"
|
msgstr "russe"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:748
|
#: netbox/netbox/settings.py:749
|
||||||
msgid "Turkish"
|
msgid "Turkish"
|
||||||
msgstr "Turc"
|
msgstr "Turc"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:749
|
#: netbox/netbox/settings.py:750
|
||||||
msgid "Ukrainian"
|
msgid "Ukrainian"
|
||||||
msgstr "Ukrainien"
|
msgstr "Ukrainien"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:750
|
#: netbox/netbox/settings.py:751
|
||||||
msgid "Chinese"
|
msgid "Chinese"
|
||||||
msgstr "chinois"
|
msgstr "chinois"
|
||||||
|
|
||||||
|
15483
netbox/translations/it/LC_MESSAGES/django.po
Normal file
15483
netbox/translations/it/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
15480
netbox/translations/nl/LC_MESSAGES/django.po
Normal file
15480
netbox/translations/nl/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
15393
netbox/translations/pl/LC_MESSAGES/django.po
Normal file
15393
netbox/translations/pl/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-07-09 05:02+0000\n"
|
"POT-Creation-Date: 2024-07-11 05:01+0000\n"
|
||||||
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
|
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
|
||||||
"Last-Translator: Artem Kotik, 2024\n"
|
"Last-Translator: Artem Kotik, 2024\n"
|
||||||
"Language-Team: Russian (https://app.transifex.com/netbox-community/teams/178115/ru/)\n"
|
"Language-Team: Russian (https://app.transifex.com/netbox-community/teams/178115/ru/)\n"
|
||||||
@ -70,7 +70,7 @@ msgstr "Последнее использование"
|
|||||||
msgid "Allowed IPs"
|
msgid "Allowed IPs"
|
||||||
msgstr "Разрешенные IP-адреса"
|
msgstr "Разрешенные IP-адреса"
|
||||||
|
|
||||||
#: netbox/account/views.py:204
|
#: netbox/account/views.py:214
|
||||||
msgid "Your preferences have been updated."
|
msgid "Your preferences have been updated."
|
||||||
msgstr "Ваши настройки были обновлены."
|
msgstr "Ваши настройки были обновлены."
|
||||||
|
|
||||||
@ -263,7 +263,7 @@ msgstr "Аккаунт провайдера (ID)"
|
|||||||
|
|
||||||
#: netbox/circuits/filtersets.py:171
|
#: netbox/circuits/filtersets.py:171
|
||||||
msgid "Provider account (account)"
|
msgid "Provider account (account)"
|
||||||
msgstr "Учетная запись провайдера (учетная запись)"
|
msgstr "Учетная запись провайдера"
|
||||||
|
|
||||||
#: netbox/circuits/filtersets.py:176
|
#: netbox/circuits/filtersets.py:176
|
||||||
msgid "Provider network (ID)"
|
msgid "Provider network (ID)"
|
||||||
@ -1520,16 +1520,16 @@ msgstr "Пароль"
|
|||||||
msgid "Branch"
|
msgid "Branch"
|
||||||
msgstr "Ветка"
|
msgstr "Ветка"
|
||||||
|
|
||||||
#: netbox/core/data_backends.py:105
|
#: netbox/core/data_backends.py:106
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Fetching remote data failed ({name}): {error}"
|
msgid "Fetching remote data failed ({name}): {error}"
|
||||||
msgstr "Не удалось получить удаленные данные ({name}): {error}"
|
msgstr "Не удалось получить удаленные данные ({name}): {error}"
|
||||||
|
|
||||||
#: netbox/core/data_backends.py:118
|
#: netbox/core/data_backends.py:119
|
||||||
msgid "AWS access key ID"
|
msgid "AWS access key ID"
|
||||||
msgstr "ID ключа доступа AWS"
|
msgstr "ID ключа доступа AWS"
|
||||||
|
|
||||||
#: netbox/core/data_backends.py:122
|
#: netbox/core/data_backends.py:123
|
||||||
msgid "AWS secret access key"
|
msgid "AWS secret access key"
|
||||||
msgstr "Секретный ключ доступа AWS"
|
msgstr "Секретный ключ доступа AWS"
|
||||||
|
|
||||||
@ -1872,7 +1872,7 @@ msgstr ""
|
|||||||
msgid "last updated"
|
msgid "last updated"
|
||||||
msgstr "последнее обновление"
|
msgstr "последнее обновление"
|
||||||
|
|
||||||
#: netbox/core/models/data.py:296 netbox/dcim/models/cables.py:442
|
#: netbox/core/models/data.py:296 netbox/dcim/models/cables.py:444
|
||||||
msgid "path"
|
msgid "path"
|
||||||
msgstr "путь"
|
msgstr "путь"
|
||||||
|
|
||||||
@ -4652,50 +4652,50 @@ msgstr "Длина"
|
|||||||
msgid "length unit"
|
msgid "length unit"
|
||||||
msgstr "длина единицы"
|
msgstr "длина единицы"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:93
|
#: netbox/dcim/models/cables.py:95
|
||||||
msgid "cable"
|
msgid "cable"
|
||||||
msgstr "кабель"
|
msgstr "кабель"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:94
|
#: netbox/dcim/models/cables.py:96
|
||||||
msgid "cables"
|
msgid "cables"
|
||||||
msgstr "кабели"
|
msgstr "кабели"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:163
|
#: netbox/dcim/models/cables.py:165
|
||||||
msgid "Must specify a unit when setting a cable length"
|
msgid "Must specify a unit when setting a cable length"
|
||||||
msgstr "При настройке длины кабеля необходимо указать единицу измерения"
|
msgstr "При настройке длины кабеля необходимо указать единицу измерения"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:166
|
#: netbox/dcim/models/cables.py:168
|
||||||
msgid "Must define A and B terminations when creating a new cable."
|
msgid "Must define A and B terminations when creating a new cable."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"При создании нового кабеля необходимо определить концевые разъемы A и B."
|
"При создании нового кабеля необходимо определить концевые разъемы A и B."
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:173
|
#: netbox/dcim/models/cables.py:175
|
||||||
msgid "Cannot connect different termination types to same end of cable."
|
msgid "Cannot connect different termination types to same end of cable."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Невозможно подключить разные типы разъемов к одному и тому же концу кабеля."
|
"Невозможно подключить разные типы разъемов к одному и тому же концу кабеля."
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:181
|
#: netbox/dcim/models/cables.py:183
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Incompatible termination types: {type_a} and {type_b}"
|
msgid "Incompatible termination types: {type_a} and {type_b}"
|
||||||
msgstr "Несовместимые типы терминации: {type_a} а также {type_b}"
|
msgstr "Несовместимые типы терминации: {type_a} а также {type_b}"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:191
|
#: netbox/dcim/models/cables.py:193
|
||||||
msgid "A and B terminations cannot connect to the same object."
|
msgid "A and B terminations cannot connect to the same object."
|
||||||
msgstr "Окончания A и B не могут подключаться к одному и тому же объекту."
|
msgstr "Окончания A и B не могут подключаться к одному и тому же объекту."
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:258 netbox/ipam/models/asns.py:37
|
#: netbox/dcim/models/cables.py:260 netbox/ipam/models/asns.py:37
|
||||||
msgid "end"
|
msgid "end"
|
||||||
msgstr "конец"
|
msgstr "конец"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:311
|
#: netbox/dcim/models/cables.py:313
|
||||||
msgid "cable termination"
|
msgid "cable termination"
|
||||||
msgstr "кабельный терминатор"
|
msgstr "кабельный терминатор"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:312
|
#: netbox/dcim/models/cables.py:314
|
||||||
msgid "cable terminations"
|
msgid "cable terminations"
|
||||||
msgstr "кабельные терминаторы"
|
msgstr "кабельные терминаторы"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:331
|
#: netbox/dcim/models/cables.py:333
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Duplicate termination found for {app_label}.{model} {termination_id}: cable "
|
"Duplicate termination found for {app_label}.{model} {termination_id}: cable "
|
||||||
@ -4704,34 +4704,34 @@ msgstr ""
|
|||||||
"Обнаружен дубликат увольнения для {app_label}.{model} {termination_id}: "
|
"Обнаружен дубликат увольнения для {app_label}.{model} {termination_id}: "
|
||||||
"кабель {cable_pk}"
|
"кабель {cable_pk}"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:341
|
#: netbox/dcim/models/cables.py:343
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Cables cannot be terminated to {type_display} interfaces"
|
msgid "Cables cannot be terminated to {type_display} interfaces"
|
||||||
msgstr "Кабели не могут быть подключены к {type_display} интерфейсов"
|
msgstr "Кабели не могут быть подключены к {type_display} интерфейсов"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:348
|
#: netbox/dcim/models/cables.py:350
|
||||||
msgid "Circuit terminations attached to a provider network may not be cabled."
|
msgid "Circuit terminations attached to a provider network may not be cabled."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Концевые разъемы, подключенные к сети провайдера, могут не подключаться к "
|
"Концевые разъемы, подключенные к сети провайдера, могут не подключаться к "
|
||||||
"кабелям."
|
"кабелям."
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:446 netbox/extras/models/configs.py:50
|
#: netbox/dcim/models/cables.py:448 netbox/extras/models/configs.py:50
|
||||||
msgid "is active"
|
msgid "is active"
|
||||||
msgstr "активен"
|
msgstr "активен"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:450
|
#: netbox/dcim/models/cables.py:452
|
||||||
msgid "is complete"
|
msgid "is complete"
|
||||||
msgstr "завершен"
|
msgstr "завершен"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:454
|
#: netbox/dcim/models/cables.py:456
|
||||||
msgid "is split"
|
msgid "is split"
|
||||||
msgstr "разделен"
|
msgstr "разделен"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:462
|
#: netbox/dcim/models/cables.py:464
|
||||||
msgid "cable path"
|
msgid "cable path"
|
||||||
msgstr "кабельная трасса"
|
msgstr "кабельная трасса"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:463
|
#: netbox/dcim/models/cables.py:465
|
||||||
msgid "cable paths"
|
msgid "cable paths"
|
||||||
msgstr "кабельные трассы"
|
msgstr "кабельные трассы"
|
||||||
|
|
||||||
@ -5274,11 +5274,11 @@ msgstr "Нанесенное на карту положение на соотв
|
|||||||
|
|
||||||
#: netbox/dcim/models/device_components.py:1007
|
#: netbox/dcim/models/device_components.py:1007
|
||||||
msgid "front port"
|
msgid "front port"
|
||||||
msgstr "передний порт"
|
msgstr "фронтальный порт"
|
||||||
|
|
||||||
#: netbox/dcim/models/device_components.py:1008
|
#: netbox/dcim/models/device_components.py:1008
|
||||||
msgid "front ports"
|
msgid "front ports"
|
||||||
msgstr "передние порты"
|
msgstr "фронтальные порты"
|
||||||
|
|
||||||
#: netbox/dcim/models/device_components.py:1022
|
#: netbox/dcim/models/device_components.py:1022
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@ -5541,7 +5541,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: netbox/dcim/models/devices.py:517
|
#: netbox/dcim/models/devices.py:517
|
||||||
msgid "platform"
|
msgid "platform"
|
||||||
msgstr "платформ"
|
msgstr "платформа"
|
||||||
|
|
||||||
#: netbox/dcim/models/devices.py:518
|
#: netbox/dcim/models/devices.py:518
|
||||||
msgid "platforms"
|
msgid "platforms"
|
||||||
@ -5604,7 +5604,7 @@ msgstr "широта"
|
|||||||
#: netbox/dcim/models/devices.py:711 netbox/dcim/models/devices.py:719
|
#: netbox/dcim/models/devices.py:711 netbox/dcim/models/devices.py:719
|
||||||
#: netbox/dcim/models/sites.py:212 netbox/dcim/models/sites.py:220
|
#: netbox/dcim/models/sites.py:212 netbox/dcim/models/sites.py:220
|
||||||
msgid "GPS coordinate in decimal format (xx.yyyyyy)"
|
msgid "GPS coordinate in decimal format (xx.yyyyyy)"
|
||||||
msgstr "Координата GPS в десятичном формате (xx.yyyyyy)"
|
msgstr "GPS координата в десятичном формате (xx.yyyyyy)"
|
||||||
|
|
||||||
#: netbox/dcim/models/devices.py:714 netbox/dcim/models/sites.py:215
|
#: netbox/dcim/models/devices.py:714 netbox/dcim/models/sites.py:215
|
||||||
msgid "longitude"
|
msgid "longitude"
|
||||||
@ -6059,15 +6059,15 @@ msgstr "Группа сайтов верхнего уровня с этой по
|
|||||||
|
|
||||||
#: netbox/dcim/models/sites.py:115
|
#: netbox/dcim/models/sites.py:115
|
||||||
msgid "site group"
|
msgid "site group"
|
||||||
msgstr "группа мест"
|
msgstr "группа сайта"
|
||||||
|
|
||||||
#: netbox/dcim/models/sites.py:116
|
#: netbox/dcim/models/sites.py:116
|
||||||
msgid "site groups"
|
msgid "site groups"
|
||||||
msgstr "группы мест"
|
msgstr "группы сайтов"
|
||||||
|
|
||||||
#: netbox/dcim/models/sites.py:141
|
#: netbox/dcim/models/sites.py:141
|
||||||
msgid "Full name of the site"
|
msgid "Full name of the site"
|
||||||
msgstr "Полное название сайта"
|
msgstr "Полное имя сайта"
|
||||||
|
|
||||||
#: netbox/dcim/models/sites.py:181 netbox/dcim/models/sites.py:279
|
#: netbox/dcim/models/sites.py:181 netbox/dcim/models/sites.py:279
|
||||||
msgid "facility"
|
msgid "facility"
|
||||||
@ -6095,11 +6095,11 @@ msgstr "Если отличается от физического адреса"
|
|||||||
|
|
||||||
#: netbox/dcim/models/sites.py:238
|
#: netbox/dcim/models/sites.py:238
|
||||||
msgid "site"
|
msgid "site"
|
||||||
msgstr "место"
|
msgstr "сайт"
|
||||||
|
|
||||||
#: netbox/dcim/models/sites.py:239
|
#: netbox/dcim/models/sites.py:239
|
||||||
msgid "sites"
|
msgid "sites"
|
||||||
msgstr "Сайты"
|
msgstr "сайты"
|
||||||
|
|
||||||
#: netbox/dcim/models/sites.py:309
|
#: netbox/dcim/models/sites.py:309
|
||||||
msgid "A location with this name already exists within the specified site."
|
msgid "A location with this name already exists within the specified site."
|
||||||
@ -6137,7 +6137,7 @@ msgstr "Устройство A"
|
|||||||
|
|
||||||
#: netbox/dcim/tables/cables.py:72 netbox/wireless/tables/wirelesslink.py:31
|
#: netbox/dcim/tables/cables.py:72 netbox/wireless/tables/wirelesslink.py:31
|
||||||
msgid "Device B"
|
msgid "Device B"
|
||||||
msgstr "Устройство B"
|
msgstr "Устройство Б"
|
||||||
|
|
||||||
#: netbox/dcim/tables/cables.py:78
|
#: netbox/dcim/tables/cables.py:78
|
||||||
msgid "Location A"
|
msgid "Location A"
|
||||||
@ -6145,7 +6145,7 @@ msgstr "Локация A"
|
|||||||
|
|
||||||
#: netbox/dcim/tables/cables.py:84
|
#: netbox/dcim/tables/cables.py:84
|
||||||
msgid "Location B"
|
msgid "Location B"
|
||||||
msgstr "Локация B"
|
msgstr "Локация Б"
|
||||||
|
|
||||||
#: netbox/dcim/tables/cables.py:90
|
#: netbox/dcim/tables/cables.py:90
|
||||||
msgid "Rack A"
|
msgid "Rack A"
|
||||||
@ -6153,7 +6153,7 @@ msgstr "Стойка A"
|
|||||||
|
|
||||||
#: netbox/dcim/tables/cables.py:96
|
#: netbox/dcim/tables/cables.py:96
|
||||||
msgid "Rack B"
|
msgid "Rack B"
|
||||||
msgstr "Стойка B"
|
msgstr "Стойка Б"
|
||||||
|
|
||||||
#: netbox/dcim/tables/cables.py:102
|
#: netbox/dcim/tables/cables.py:102
|
||||||
msgid "Site A"
|
msgid "Site A"
|
||||||
@ -6161,7 +6161,7 @@ msgstr "Сайт A"
|
|||||||
|
|
||||||
#: netbox/dcim/tables/cables.py:108
|
#: netbox/dcim/tables/cables.py:108
|
||||||
msgid "Site B"
|
msgid "Site B"
|
||||||
msgstr "Сайт B"
|
msgstr "Сайт Б"
|
||||||
|
|
||||||
#: netbox/dcim/tables/connections.py:31 netbox/dcim/tables/connections.py:50
|
#: netbox/dcim/tables/connections.py:31 netbox/dcim/tables/connections.py:50
|
||||||
#: netbox/dcim/tables/connections.py:71
|
#: netbox/dcim/tables/connections.py:71
|
||||||
@ -6224,11 +6224,11 @@ msgstr "Адрес IPv6"
|
|||||||
|
|
||||||
#: netbox/dcim/tables/devices.py:207
|
#: netbox/dcim/tables/devices.py:207
|
||||||
msgid "VC Position"
|
msgid "VC Position"
|
||||||
msgstr "Позиция VC"
|
msgstr "Позиция в шасси"
|
||||||
|
|
||||||
#: netbox/dcim/tables/devices.py:210
|
#: netbox/dcim/tables/devices.py:210
|
||||||
msgid "VC Priority"
|
msgid "VC Priority"
|
||||||
msgstr "Приоритет VC"
|
msgstr "Приоритет шасси"
|
||||||
|
|
||||||
#: netbox/dcim/tables/devices.py:217 netbox/templates/dcim/device_edit.html:38
|
#: netbox/dcim/tables/devices.py:217 netbox/templates/dcim/device_edit.html:38
|
||||||
#: netbox/templates/dcim/devicebay_populate.html:16
|
#: netbox/templates/dcim/devicebay_populate.html:16
|
||||||
@ -6275,7 +6275,7 @@ msgstr "Интерфейсы"
|
|||||||
|
|
||||||
#: netbox/dcim/tables/devices.py:246
|
#: netbox/dcim/tables/devices.py:246
|
||||||
msgid "Front ports"
|
msgid "Front ports"
|
||||||
msgstr "Передние порты"
|
msgstr "Фронтальные порты"
|
||||||
|
|
||||||
#: netbox/dcim/tables/devices.py:252
|
#: netbox/dcim/tables/devices.py:252
|
||||||
msgid "Device bays"
|
msgid "Device bays"
|
||||||
@ -6472,7 +6472,7 @@ msgstr "Розетки питания"
|
|||||||
#: netbox/templates/dcim/module.html:37
|
#: netbox/templates/dcim/module.html:37
|
||||||
#: netbox/templates/dcim/moduletype/base.html:37
|
#: netbox/templates/dcim/moduletype/base.html:37
|
||||||
msgid "Front Ports"
|
msgid "Front Ports"
|
||||||
msgstr "Передние порты"
|
msgstr "Фронтальные порты"
|
||||||
|
|
||||||
#: netbox/dcim/tables/devicetypes.py:131 netbox/dcim/views.py:1018
|
#: netbox/dcim/tables/devicetypes.py:131 netbox/dcim/views.py:1018
|
||||||
#: netbox/dcim/views.py:1257 netbox/dcim/views.py:1946
|
#: netbox/dcim/views.py:1257 netbox/dcim/views.py:1946
|
||||||
@ -6957,43 +6957,43 @@ msgstr "Количество отображаемых объектов по ум
|
|||||||
msgid "Invalid format. URL parameters must be passed as a dictionary."
|
msgid "Invalid format. URL parameters must be passed as a dictionary."
|
||||||
msgstr "Неверный формат. Параметры URL должны быть переданы в виде словаря."
|
msgstr "Неверный формат. Параметры URL должны быть переданы в виде словаря."
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:284
|
#: netbox/extras/dashboard/widgets.py:288
|
||||||
msgid "RSS Feed"
|
msgid "RSS Feed"
|
||||||
msgstr "RSS-канал"
|
msgstr "RSS-канал"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:289
|
#: netbox/extras/dashboard/widgets.py:293
|
||||||
msgid "Embed an RSS feed from an external website."
|
msgid "Embed an RSS feed from an external website."
|
||||||
msgstr "Вставьте RSS-канал с внешнего веб-сайта."
|
msgstr "Вставьте RSS-канал с внешнего веб-сайта."
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:296
|
#: netbox/extras/dashboard/widgets.py:300
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
msgstr "URL-адрес ленты"
|
msgstr "URL-адрес ленты"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:301
|
#: netbox/extras/dashboard/widgets.py:305
|
||||||
msgid "The maximum number of objects to display"
|
msgid "The maximum number of objects to display"
|
||||||
msgstr "Максимальное количество отображаемых объектов"
|
msgstr "Максимальное количество отображаемых объектов"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:306
|
#: netbox/extras/dashboard/widgets.py:310
|
||||||
msgid "How long to stored the cached content (in seconds)"
|
msgid "How long to stored the cached content (in seconds)"
|
||||||
msgstr "Как долго хранить кэшированный контент (в секундах)"
|
msgstr "Как долго хранить кэшированный контент (в секундах)"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:358
|
#: netbox/extras/dashboard/widgets.py:362
|
||||||
#: netbox/templates/account/base.html:10
|
#: netbox/templates/account/base.html:10
|
||||||
#: netbox/templates/account/bookmarks.html:7
|
#: netbox/templates/account/bookmarks.html:7
|
||||||
#: netbox/templates/inc/user_menu.html:30
|
#: netbox/templates/inc/user_menu.html:30
|
||||||
msgid "Bookmarks"
|
msgid "Bookmarks"
|
||||||
msgstr "Закладки"
|
msgstr "Закладки"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:362
|
#: netbox/extras/dashboard/widgets.py:366
|
||||||
msgid "Show your personal bookmarks"
|
msgid "Show your personal bookmarks"
|
||||||
msgstr "Покажите свои личные закладки"
|
msgstr "Покажите свои личные закладки"
|
||||||
|
|
||||||
#: netbox/extras/events.py:134
|
#: netbox/extras/events.py:137
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Unknown action type for an event rule: {action_type}"
|
msgid "Unknown action type for an event rule: {action_type}"
|
||||||
msgstr "Неизвестный тип действия для правила события: {action_type}"
|
msgstr "Неизвестный тип действия для правила события: {action_type}"
|
||||||
|
|
||||||
#: netbox/extras/events.py:182
|
#: netbox/extras/events.py:185
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Cannot import events pipeline {name} error: {error}"
|
msgid "Cannot import events pipeline {name} error: {error}"
|
||||||
msgstr "Невозможно импортировать конвейер событий {name} ошибка: {error}"
|
msgstr "Невозможно импортировать конвейер событий {name} ошибка: {error}"
|
||||||
@ -9975,7 +9975,7 @@ msgid "Invalid value. Specify a content type as '<app_label>.<model_name>'."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Неверное значение. Укажите тип контента как '<app_label>.<model_name>'."
|
"Неверное значение. Укажите тип контента как '<app_label>.<model_name>'."
|
||||||
|
|
||||||
#: netbox/netbox/authentication/__init__.py:138
|
#: netbox/netbox/authentication/__init__.py:141
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Invalid permission {permission} for model {model}"
|
msgid "Invalid permission {permission} for model {model}"
|
||||||
msgstr "Неверное разрешение {permission} для модели {model}"
|
msgstr "Неверное разрешение {permission} для модели {model}"
|
||||||
@ -10826,43 +10826,43 @@ msgstr "Невозможно добавить магазины в реестр
|
|||||||
msgid "Cannot delete stores from registry"
|
msgid "Cannot delete stores from registry"
|
||||||
msgstr "Невозможно удалить магазины из реестра"
|
msgstr "Невозможно удалить магазины из реестра"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:741
|
#: netbox/netbox/settings.py:742
|
||||||
msgid "German"
|
msgid "German"
|
||||||
msgstr "Немецкий"
|
msgstr "Немецкий"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:742
|
#: netbox/netbox/settings.py:743
|
||||||
msgid "English"
|
msgid "English"
|
||||||
msgstr "Английский"
|
msgstr "Английский"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:743
|
#: netbox/netbox/settings.py:744
|
||||||
msgid "Spanish"
|
msgid "Spanish"
|
||||||
msgstr "Испанский"
|
msgstr "Испанский"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:744
|
#: netbox/netbox/settings.py:745
|
||||||
msgid "French"
|
msgid "French"
|
||||||
msgstr "Французский"
|
msgstr "Французский"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:745
|
#: netbox/netbox/settings.py:746
|
||||||
msgid "Japanese"
|
msgid "Japanese"
|
||||||
msgstr "Японский"
|
msgstr "Японский"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:746
|
#: netbox/netbox/settings.py:747
|
||||||
msgid "Portuguese"
|
msgid "Portuguese"
|
||||||
msgstr "Португальский"
|
msgstr "Португальский"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:747
|
#: netbox/netbox/settings.py:748
|
||||||
msgid "Russian"
|
msgid "Russian"
|
||||||
msgstr "Русский"
|
msgstr "Русский"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:748
|
#: netbox/netbox/settings.py:749
|
||||||
msgid "Turkish"
|
msgid "Turkish"
|
||||||
msgstr "Турецкий"
|
msgstr "Турецкий"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:749
|
#: netbox/netbox/settings.py:750
|
||||||
msgid "Ukrainian"
|
msgid "Ukrainian"
|
||||||
msgstr "украинский"
|
msgstr "украинский"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:750
|
#: netbox/netbox/settings.py:751
|
||||||
msgid "Chinese"
|
msgid "Chinese"
|
||||||
msgstr "Китайский"
|
msgstr "Китайский"
|
||||||
|
|
||||||
|
@ -5,17 +5,17 @@
|
|||||||
#
|
#
|
||||||
# Translators:
|
# Translators:
|
||||||
# Burak Senturk, 2024
|
# Burak Senturk, 2024
|
||||||
# Jeremy Stretch, 2024
|
|
||||||
# Hamdi Suat Aknar, 2024
|
# Hamdi Suat Aknar, 2024
|
||||||
|
# Jeremy Stretch, 2024
|
||||||
#
|
#
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-07-09 05:02+0000\n"
|
"POT-Creation-Date: 2024-07-11 05:01+0000\n"
|
||||||
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
|
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
|
||||||
"Last-Translator: Hamdi Suat Aknar, 2024\n"
|
"Last-Translator: Jeremy Stretch, 2024\n"
|
||||||
"Language-Team: Turkish (https://app.transifex.com/netbox-community/teams/178115/tr/)\n"
|
"Language-Team: Turkish (https://app.transifex.com/netbox-community/teams/178115/tr/)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@ -64,7 +64,7 @@ msgstr "Son Kullanım"
|
|||||||
msgid "Allowed IPs"
|
msgid "Allowed IPs"
|
||||||
msgstr "İzin verilen IP'ler"
|
msgstr "İzin verilen IP'ler"
|
||||||
|
|
||||||
#: netbox/account/views.py:204
|
#: netbox/account/views.py:214
|
||||||
msgid "Your preferences have been updated."
|
msgid "Your preferences have been updated."
|
||||||
msgstr "Tercihleriniz güncellendi."
|
msgstr "Tercihleriniz güncellendi."
|
||||||
|
|
||||||
@ -1510,16 +1510,16 @@ msgstr "Şifre"
|
|||||||
msgid "Branch"
|
msgid "Branch"
|
||||||
msgstr "Şube"
|
msgstr "Şube"
|
||||||
|
|
||||||
#: netbox/core/data_backends.py:105
|
#: netbox/core/data_backends.py:106
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Fetching remote data failed ({name}): {error}"
|
msgid "Fetching remote data failed ({name}): {error}"
|
||||||
msgstr "Uzaktan veri getirilemedi ({name}): {error}"
|
msgstr "Uzaktan veri getirilemedi ({name}): {error}"
|
||||||
|
|
||||||
#: netbox/core/data_backends.py:118
|
#: netbox/core/data_backends.py:119
|
||||||
msgid "AWS access key ID"
|
msgid "AWS access key ID"
|
||||||
msgstr "AWS erişim anahtarı kimliği"
|
msgstr "AWS erişim anahtarı kimliği"
|
||||||
|
|
||||||
#: netbox/core/data_backends.py:122
|
#: netbox/core/data_backends.py:123
|
||||||
msgid "AWS secret access key"
|
msgid "AWS secret access key"
|
||||||
msgstr "AWS gizli erişim anahtarı"
|
msgstr "AWS gizli erişim anahtarı"
|
||||||
|
|
||||||
@ -1863,7 +1863,7 @@ msgstr ""
|
|||||||
msgid "last updated"
|
msgid "last updated"
|
||||||
msgstr "son güncellendi"
|
msgstr "son güncellendi"
|
||||||
|
|
||||||
#: netbox/core/models/data.py:296 netbox/dcim/models/cables.py:442
|
#: netbox/core/models/data.py:296 netbox/dcim/models/cables.py:444
|
||||||
msgid "path"
|
msgid "path"
|
||||||
msgstr "yol"
|
msgstr "yol"
|
||||||
|
|
||||||
@ -4636,48 +4636,48 @@ msgstr "uzunluk"
|
|||||||
msgid "length unit"
|
msgid "length unit"
|
||||||
msgstr "uzunluk birimi"
|
msgstr "uzunluk birimi"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:93
|
#: netbox/dcim/models/cables.py:95
|
||||||
msgid "cable"
|
msgid "cable"
|
||||||
msgstr "kablo"
|
msgstr "kablo"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:94
|
#: netbox/dcim/models/cables.py:96
|
||||||
msgid "cables"
|
msgid "cables"
|
||||||
msgstr "kablolar"
|
msgstr "kablolar"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:163
|
#: netbox/dcim/models/cables.py:165
|
||||||
msgid "Must specify a unit when setting a cable length"
|
msgid "Must specify a unit when setting a cable length"
|
||||||
msgstr "Kablo uzunluğu ayarlarken bir birim belirtmeniz gerekir"
|
msgstr "Kablo uzunluğu ayarlarken bir birim belirtmeniz gerekir"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:166
|
#: netbox/dcim/models/cables.py:168
|
||||||
msgid "Must define A and B terminations when creating a new cable."
|
msgid "Must define A and B terminations when creating a new cable."
|
||||||
msgstr "Yeni bir kablo oluştururken A ve B sonlandırmalarını tanımlamalıdır."
|
msgstr "Yeni bir kablo oluştururken A ve B sonlandırmalarını tanımlamalıdır."
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:173
|
#: netbox/dcim/models/cables.py:175
|
||||||
msgid "Cannot connect different termination types to same end of cable."
|
msgid "Cannot connect different termination types to same end of cable."
|
||||||
msgstr "Farklı sonlandırma türleri kablonun aynı ucuna bağlanamaz."
|
msgstr "Farklı sonlandırma türleri kablonun aynı ucuna bağlanamaz."
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:181
|
#: netbox/dcim/models/cables.py:183
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Incompatible termination types: {type_a} and {type_b}"
|
msgid "Incompatible termination types: {type_a} and {type_b}"
|
||||||
msgstr "Uyumsuz sonlandırma türleri: {type_a} ve {type_b}"
|
msgstr "Uyumsuz sonlandırma türleri: {type_a} ve {type_b}"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:191
|
#: netbox/dcim/models/cables.py:193
|
||||||
msgid "A and B terminations cannot connect to the same object."
|
msgid "A and B terminations cannot connect to the same object."
|
||||||
msgstr "A ve B sonlandırmaları aynı nesneye bağlanamaz."
|
msgstr "A ve B sonlandırmaları aynı nesneye bağlanamaz."
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:258 netbox/ipam/models/asns.py:37
|
#: netbox/dcim/models/cables.py:260 netbox/ipam/models/asns.py:37
|
||||||
msgid "end"
|
msgid "end"
|
||||||
msgstr "son"
|
msgstr "son"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:311
|
#: netbox/dcim/models/cables.py:313
|
||||||
msgid "cable termination"
|
msgid "cable termination"
|
||||||
msgstr "kablo sonlandırma"
|
msgstr "kablo sonlandırma"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:312
|
#: netbox/dcim/models/cables.py:314
|
||||||
msgid "cable terminations"
|
msgid "cable terminations"
|
||||||
msgstr "kablo sonlandırmaları"
|
msgstr "kablo sonlandırmaları"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:331
|
#: netbox/dcim/models/cables.py:333
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Duplicate termination found for {app_label}.{model} {termination_id}: cable "
|
"Duplicate termination found for {app_label}.{model} {termination_id}: cable "
|
||||||
@ -4686,32 +4686,32 @@ msgstr ""
|
|||||||
"Yinelenen sonlandırma bulundu {app_label}.{model} {termination_id}: kablo "
|
"Yinelenen sonlandırma bulundu {app_label}.{model} {termination_id}: kablo "
|
||||||
"{cable_pk}"
|
"{cable_pk}"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:341
|
#: netbox/dcim/models/cables.py:343
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Cables cannot be terminated to {type_display} interfaces"
|
msgid "Cables cannot be terminated to {type_display} interfaces"
|
||||||
msgstr "Kablolar sonlandırılamaz {type_display} arayüzleri"
|
msgstr "Kablolar sonlandırılamaz {type_display} arayüzleri"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:348
|
#: netbox/dcim/models/cables.py:350
|
||||||
msgid "Circuit terminations attached to a provider network may not be cabled."
|
msgid "Circuit terminations attached to a provider network may not be cabled."
|
||||||
msgstr "Bir sağlayıcı ağına bağlı devre sonlandırmaları kablolanmayabilir."
|
msgstr "Bir sağlayıcı ağına bağlı devre sonlandırmaları kablolanmayabilir."
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:446 netbox/extras/models/configs.py:50
|
#: netbox/dcim/models/cables.py:448 netbox/extras/models/configs.py:50
|
||||||
msgid "is active"
|
msgid "is active"
|
||||||
msgstr "aktiftir"
|
msgstr "aktiftir"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:450
|
#: netbox/dcim/models/cables.py:452
|
||||||
msgid "is complete"
|
msgid "is complete"
|
||||||
msgstr "tamamlandı"
|
msgstr "tamamlandı"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:454
|
#: netbox/dcim/models/cables.py:456
|
||||||
msgid "is split"
|
msgid "is split"
|
||||||
msgstr "bölünmüş"
|
msgstr "bölünmüş"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:462
|
#: netbox/dcim/models/cables.py:464
|
||||||
msgid "cable path"
|
msgid "cable path"
|
||||||
msgstr "kablo yolu"
|
msgstr "kablo yolu"
|
||||||
|
|
||||||
#: netbox/dcim/models/cables.py:463
|
#: netbox/dcim/models/cables.py:465
|
||||||
msgid "cable paths"
|
msgid "cable paths"
|
||||||
msgstr "kablo yolları"
|
msgstr "kablo yolları"
|
||||||
|
|
||||||
@ -6639,11 +6639,11 @@ msgstr "En eski"
|
|||||||
|
|
||||||
#: netbox/extras/choices.py:126
|
#: netbox/extras/choices.py:126
|
||||||
msgid "Alphabetical (A-Z)"
|
msgid "Alphabetical (A-Z)"
|
||||||
msgstr ""
|
msgstr "Alfabetik (A-Z)"
|
||||||
|
|
||||||
#: netbox/extras/choices.py:127
|
#: netbox/extras/choices.py:127
|
||||||
msgid "Alphabetical (Z-A)"
|
msgid "Alphabetical (Z-A)"
|
||||||
msgstr ""
|
msgstr "Alfabetik (Z-A)"
|
||||||
|
|
||||||
#: netbox/extras/choices.py:143 netbox/templates/generic/object.html:61
|
#: netbox/extras/choices.py:143 netbox/templates/generic/object.html:61
|
||||||
msgid "Updated"
|
msgid "Updated"
|
||||||
@ -6831,10 +6831,12 @@ msgstr "Kural seti bir sözlük olmalı, değil {ruleset}."
|
|||||||
#: netbox/extras/conditions.py:142
|
#: netbox/extras/conditions.py:142
|
||||||
msgid "Invalid logic type: must be 'AND' or 'OR'. Please check documentation."
|
msgid "Invalid logic type: must be 'AND' or 'OR'. Please check documentation."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Geçersiz mantık türü: 'AND' veya 'OR' olmalıdır. Lütfen belgeleri kontrol "
|
||||||
|
"edin."
|
||||||
|
|
||||||
#: netbox/extras/conditions.py:154
|
#: netbox/extras/conditions.py:154
|
||||||
msgid "Incorrect key(s) informed. Please check documentation."
|
msgid "Incorrect key(s) informed. Please check documentation."
|
||||||
msgstr ""
|
msgstr "Yanlış anahtar (ler) bilgilendirildi. Lütfen belgeleri kontrol edin."
|
||||||
|
|
||||||
#: netbox/extras/dashboard/forms.py:38
|
#: netbox/extras/dashboard/forms.py:38
|
||||||
msgid "Widget type"
|
msgid "Widget type"
|
||||||
@ -6894,44 +6896,44 @@ msgstr "Görüntülenecek nesnelerin varsayılan sayısı"
|
|||||||
msgid "Invalid format. URL parameters must be passed as a dictionary."
|
msgid "Invalid format. URL parameters must be passed as a dictionary."
|
||||||
msgstr "Geçersiz biçim. URL parametreleri sözlük olarak iletilmelidir."
|
msgstr "Geçersiz biçim. URL parametreleri sözlük olarak iletilmelidir."
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:284
|
#: netbox/extras/dashboard/widgets.py:288
|
||||||
msgid "RSS Feed"
|
msgid "RSS Feed"
|
||||||
msgstr "RSS Beslemesi"
|
msgstr "RSS Beslemesi"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:289
|
#: netbox/extras/dashboard/widgets.py:293
|
||||||
msgid "Embed an RSS feed from an external website."
|
msgid "Embed an RSS feed from an external website."
|
||||||
msgstr "Harici bir web sitesinden bir RSS beslemesi ekleyin."
|
msgstr "Harici bir web sitesinden bir RSS beslemesi ekleyin."
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:296
|
#: netbox/extras/dashboard/widgets.py:300
|
||||||
msgid "Feed URL"
|
msgid "Feed URL"
|
||||||
msgstr "Akış URL'si"
|
msgstr "Akış URL'si"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:301
|
#: netbox/extras/dashboard/widgets.py:305
|
||||||
msgid "The maximum number of objects to display"
|
msgid "The maximum number of objects to display"
|
||||||
msgstr "Görüntülenecek maksimum nesne sayısı"
|
msgstr "Görüntülenecek maksimum nesne sayısı"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:306
|
#: netbox/extras/dashboard/widgets.py:310
|
||||||
msgid "How long to stored the cached content (in seconds)"
|
msgid "How long to stored the cached content (in seconds)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Önbelleğe alınan içeriğin ne kadar süre saklanacağı (saniye cinsinden)"
|
"Önbelleğe alınan içeriğin ne kadar süre saklanacağı (saniye cinsinden)"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:358
|
#: netbox/extras/dashboard/widgets.py:362
|
||||||
#: netbox/templates/account/base.html:10
|
#: netbox/templates/account/base.html:10
|
||||||
#: netbox/templates/account/bookmarks.html:7
|
#: netbox/templates/account/bookmarks.html:7
|
||||||
#: netbox/templates/inc/user_menu.html:30
|
#: netbox/templates/inc/user_menu.html:30
|
||||||
msgid "Bookmarks"
|
msgid "Bookmarks"
|
||||||
msgstr "Yer İşaretleri"
|
msgstr "Yer İşaretleri"
|
||||||
|
|
||||||
#: netbox/extras/dashboard/widgets.py:362
|
#: netbox/extras/dashboard/widgets.py:366
|
||||||
msgid "Show your personal bookmarks"
|
msgid "Show your personal bookmarks"
|
||||||
msgstr "Kişisel yer imlerinizi gösterin"
|
msgstr "Kişisel yer imlerinizi gösterin"
|
||||||
|
|
||||||
#: netbox/extras/events.py:134
|
#: netbox/extras/events.py:137
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Unknown action type for an event rule: {action_type}"
|
msgid "Unknown action type for an event rule: {action_type}"
|
||||||
msgstr "Bir olay kuralı için bilinmeyen eylem türü: {action_type}"
|
msgstr "Bir olay kuralı için bilinmeyen eylem türü: {action_type}"
|
||||||
|
|
||||||
#: netbox/extras/events.py:182
|
#: netbox/extras/events.py:185
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Cannot import events pipeline {name} error: {error}"
|
msgid "Cannot import events pipeline {name} error: {error}"
|
||||||
msgstr "Olaylar boru hattı içe aktarılamıyor {name} hata: {error}"
|
msgstr "Olaylar boru hattı içe aktarılamıyor {name} hata: {error}"
|
||||||
@ -9893,7 +9895,7 @@ msgid "Invalid value. Specify a content type as '<app_label>.<model_name>'."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Geçersiz değer. İçerik türünü 'olarak belirtin<app_label>.<model_name>'."
|
"Geçersiz değer. İçerik türünü 'olarak belirtin<app_label>.<model_name>'."
|
||||||
|
|
||||||
#: netbox/netbox/authentication/__init__.py:138
|
#: netbox/netbox/authentication/__init__.py:141
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Invalid permission {permission} for model {model}"
|
msgid "Invalid permission {permission} for model {model}"
|
||||||
msgstr "Geçersiz izin {permission} model için {model}"
|
msgstr "Geçersiz izin {permission} model için {model}"
|
||||||
@ -10198,7 +10200,7 @@ msgstr "Nesne türü (ler)"
|
|||||||
|
|
||||||
#: netbox/netbox/forms/__init__.py:40
|
#: netbox/netbox/forms/__init__.py:40
|
||||||
msgid "Lookup"
|
msgid "Lookup"
|
||||||
msgstr ""
|
msgstr "Aramak"
|
||||||
|
|
||||||
#: netbox/netbox/forms/base.py:88
|
#: netbox/netbox/forms/base.py:88
|
||||||
msgid ""
|
msgid ""
|
||||||
@ -10741,43 +10743,43 @@ msgstr "Başlatıldıktan sonra kayıt defterine mağazalar eklenemiyor"
|
|||||||
msgid "Cannot delete stores from registry"
|
msgid "Cannot delete stores from registry"
|
||||||
msgstr "Mağazalar kayıt defterinden silinemiyor"
|
msgstr "Mağazalar kayıt defterinden silinemiyor"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:741
|
#: netbox/netbox/settings.py:742
|
||||||
msgid "German"
|
msgid "German"
|
||||||
msgstr "Alman"
|
msgstr "Alman"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:742
|
#: netbox/netbox/settings.py:743
|
||||||
msgid "English"
|
msgid "English"
|
||||||
msgstr "İngilizce"
|
msgstr "İngilizce"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:743
|
#: netbox/netbox/settings.py:744
|
||||||
msgid "Spanish"
|
msgid "Spanish"
|
||||||
msgstr "İspanyolca"
|
msgstr "İspanyolca"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:744
|
#: netbox/netbox/settings.py:745
|
||||||
msgid "French"
|
msgid "French"
|
||||||
msgstr "Fransızca"
|
msgstr "Fransızca"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:745
|
#: netbox/netbox/settings.py:746
|
||||||
msgid "Japanese"
|
msgid "Japanese"
|
||||||
msgstr "Japonca"
|
msgstr "Japonca"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:746
|
#: netbox/netbox/settings.py:747
|
||||||
msgid "Portuguese"
|
msgid "Portuguese"
|
||||||
msgstr "Portekizce"
|
msgstr "Portekizce"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:747
|
#: netbox/netbox/settings.py:748
|
||||||
msgid "Russian"
|
msgid "Russian"
|
||||||
msgstr "Rusça"
|
msgstr "Rusça"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:748
|
#: netbox/netbox/settings.py:749
|
||||||
msgid "Turkish"
|
msgid "Turkish"
|
||||||
msgstr "Türkçe"
|
msgstr "Türkçe"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:749
|
#: netbox/netbox/settings.py:750
|
||||||
msgid "Ukrainian"
|
msgid "Ukrainian"
|
||||||
msgstr "Ukraynalı"
|
msgstr "Ukraynalı"
|
||||||
|
|
||||||
#: netbox/netbox/settings.py:750
|
#: netbox/netbox/settings.py:751
|
||||||
msgid "Chinese"
|
msgid "Chinese"
|
||||||
msgstr "Çince"
|
msgstr "Çince"
|
||||||
|
|
||||||
@ -13083,11 +13085,11 @@ msgstr "Veriler yukarı akış dosyasıyla senkronize değil"
|
|||||||
|
|
||||||
#: netbox/templates/inc/table_controls_htmx.html:7
|
#: netbox/templates/inc/table_controls_htmx.html:7
|
||||||
msgid "Quick search"
|
msgid "Quick search"
|
||||||
msgstr ""
|
msgstr "Hızlı arama"
|
||||||
|
|
||||||
#: netbox/templates/inc/table_controls_htmx.html:20
|
#: netbox/templates/inc/table_controls_htmx.html:20
|
||||||
msgid "Saved filter"
|
msgid "Saved filter"
|
||||||
msgstr ""
|
msgstr "Kaydedilen filtre"
|
||||||
|
|
||||||
#: netbox/templates/inc/user_menu.html:23
|
#: netbox/templates/inc/user_menu.html:23
|
||||||
msgid "Django Admin"
|
msgid "Django Admin"
|
||||||
@ -14163,7 +14165,7 @@ msgstr "50'den fazla"
|
|||||||
|
|
||||||
#: netbox/utilities/fields.py:30
|
#: netbox/utilities/fields.py:30
|
||||||
msgid "RGB color in hexadecimal. Example: "
|
msgid "RGB color in hexadecimal. Example: "
|
||||||
msgstr ""
|
msgstr "Onaltılık olarak RGB rengi. Örnek: "
|
||||||
|
|
||||||
#: netbox/utilities/fields.py:159
|
#: netbox/utilities/fields.py:159
|
||||||
#, python-format
|
#, python-format
|
||||||
@ -14477,11 +14479,11 @@ msgstr "Aşağı hareket et"
|
|||||||
|
|
||||||
#: netbox/utilities/templates/navigation/menu.html:14
|
#: netbox/utilities/templates/navigation/menu.html:14
|
||||||
msgid "Search…"
|
msgid "Search…"
|
||||||
msgstr ""
|
msgstr "Arama..."
|
||||||
|
|
||||||
#: netbox/utilities/templates/navigation/menu.html:14
|
#: netbox/utilities/templates/navigation/menu.html:14
|
||||||
msgid "Search NetBox"
|
msgid "Search NetBox"
|
||||||
msgstr ""
|
msgstr "Arama NetBox"
|
||||||
|
|
||||||
#: netbox/utilities/templates/widgets/apiselect.html:7
|
#: netbox/utilities/templates/widgets/apiselect.html:7
|
||||||
msgid "Open selector"
|
msgid "Open selector"
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model, password_validation
|
||||||
from drf_spectacular.types import OpenApiTypes
|
from drf_spectacular.types import OpenApiTypes
|
||||||
from drf_spectacular.utils import extend_schema_field
|
from drf_spectacular.utils import extend_schema_field
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
@ -59,6 +59,14 @@ class UserSerializer(ValidatedModelSerializer):
|
|||||||
'password': {'write_only': True}
|
'password': {'write_only': True}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def validate(self, data):
|
||||||
|
|
||||||
|
# Enforce password validation rules (if configured)
|
||||||
|
if not self.nested and data.get('password'):
|
||||||
|
password_validation.validate_password(data['password'], self.instance)
|
||||||
|
|
||||||
|
return super().validate(data)
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
"""
|
"""
|
||||||
Extract the password from validated data and set it separately to ensure proper hash generation.
|
Extract the password from validated data and set it separately to ensure proper hash generation.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model, password_validation
|
||||||
from django.contrib.postgres.forms import SimpleArrayField
|
from django.contrib.postgres.forms import SimpleArrayField
|
||||||
from django.core.exceptions import FieldError
|
from django.core.exceptions import FieldError
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
@ -227,6 +227,10 @@ class UserForm(forms.ModelForm):
|
|||||||
if self.cleaned_data['password'] and self.cleaned_data['password'] != self.cleaned_data['confirm_password']:
|
if self.cleaned_data['password'] and self.cleaned_data['password'] != self.cleaned_data['confirm_password']:
|
||||||
raise forms.ValidationError(_("Passwords do not match! Please check your input and try again."))
|
raise forms.ValidationError(_("Passwords do not match! Please check your input and try again."))
|
||||||
|
|
||||||
|
# Enforce password validation rules (if configured)
|
||||||
|
if self.cleaned_data['password']:
|
||||||
|
password_validation.validate_password(self.cleaned_data['password'], self.instance)
|
||||||
|
|
||||||
|
|
||||||
class GroupForm(forms.ModelForm):
|
class GroupForm(forms.ModelForm):
|
||||||
users = DynamicModelMultipleChoiceField(
|
users = DynamicModelMultipleChoiceField(
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.test import override_settings
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from core.models import ObjectType
|
from core.models import ObjectType
|
||||||
@ -93,6 +94,31 @@ class UserTest(APIViewTestCases.APIViewTestCase):
|
|||||||
user.refresh_from_db()
|
user.refresh_from_db()
|
||||||
self.assertTrue(user.check_password(data['password']))
|
self.assertTrue(user.check_password(data['password']))
|
||||||
|
|
||||||
|
@override_settings(AUTH_PASSWORD_VALIDATORS=[{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||||
|
'OPTIONS': {'min_length': 8}
|
||||||
|
}])
|
||||||
|
def test_password_validation_enforced(self):
|
||||||
|
"""
|
||||||
|
Test that any configured password validation rules (AUTH_PASSWORD_VALIDATORS) are enforced.
|
||||||
|
"""
|
||||||
|
self.add_permissions('users.add_user')
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'username': 'new_user',
|
||||||
|
'password': 'foo',
|
||||||
|
}
|
||||||
|
url = reverse('users-api:user-list')
|
||||||
|
|
||||||
|
# Password too short
|
||||||
|
response = self.client.post(url, data, format='json', **self.header)
|
||||||
|
self.assertEqual(response.status_code, 400)
|
||||||
|
|
||||||
|
# Password long enough
|
||||||
|
data['password'] = 'foobar123'
|
||||||
|
response = self.client.post(url, data, format='json', **self.header)
|
||||||
|
self.assertEqual(response.status_code, 201)
|
||||||
|
|
||||||
|
|
||||||
class GroupTest(APIViewTestCases.APIViewTestCase):
|
class GroupTest(APIViewTestCases.APIViewTestCase):
|
||||||
model = Group
|
model = Group
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
from django.test import override_settings
|
||||||
|
|
||||||
from core.models import ObjectType
|
from core.models import ObjectType
|
||||||
from users.models import *
|
from users.models import *
|
||||||
from utilities.testing import ViewTestCases, create_test_user
|
from utilities.testing import ViewTestCases, create_test_user, extract_form_failures
|
||||||
|
|
||||||
|
|
||||||
class UserTestCase(
|
class UserTestCase(
|
||||||
@ -58,6 +60,34 @@ class UserTestCase(
|
|||||||
'last_name': 'newlastname',
|
'last_name': 'newlastname',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override_settings(AUTH_PASSWORD_VALIDATORS=[{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||||
|
'OPTIONS': {'min_length': 8}
|
||||||
|
}])
|
||||||
|
def test_password_validation_enforced(self):
|
||||||
|
"""
|
||||||
|
Test that any configured password validation rules (AUTH_PASSWORD_VALIDATORS) are enforced.
|
||||||
|
"""
|
||||||
|
self.add_permissions('users.add_user')
|
||||||
|
data = {
|
||||||
|
'username': 'new_user',
|
||||||
|
'password': 'foo',
|
||||||
|
'confirm_password': 'foo',
|
||||||
|
}
|
||||||
|
|
||||||
|
# Password too short
|
||||||
|
request = {
|
||||||
|
'path': self._get_url('add'),
|
||||||
|
'data': data,
|
||||||
|
}
|
||||||
|
response = self.client.post(**request)
|
||||||
|
self.assertHttpStatus(response, 200)
|
||||||
|
|
||||||
|
# Password long enough
|
||||||
|
data['password'] = 'foobar123'
|
||||||
|
data['confirm_password'] = 'foobar123'
|
||||||
|
self.assertHttpStatus(self.client.post(**request), 302)
|
||||||
|
|
||||||
|
|
||||||
class GroupTestCase(
|
class GroupTestCase(
|
||||||
ViewTestCases.GetObjectViewTestCase,
|
ViewTestCases.GetObjectViewTestCase,
|
||||||
|
@ -9,9 +9,9 @@ from django.test import override_settings
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.test import APIClient
|
from rest_framework.test import APIClient
|
||||||
from strawberry.lazy_type import LazyType
|
from strawberry.types.base import StrawberryList, StrawberryOptional
|
||||||
from strawberry.type import StrawberryList, StrawberryOptional
|
from strawberry.types.lazy_type import LazyType
|
||||||
from strawberry.union import StrawberryUnion
|
from strawberry.types.union import StrawberryUnion
|
||||||
|
|
||||||
from core.choices import ObjectChangeActionChoices
|
from core.choices import ObjectChangeActionChoices
|
||||||
from core.models import ObjectChange, ObjectType
|
from core.models import ObjectChange, ObjectType
|
||||||
|
@ -20,18 +20,18 @@ feedparser==6.0.11
|
|||||||
gunicorn==22.0.0
|
gunicorn==22.0.0
|
||||||
Jinja2==3.1.4
|
Jinja2==3.1.4
|
||||||
Markdown==3.6
|
Markdown==3.6
|
||||||
mkdocs-material==9.5.28
|
mkdocs-material==9.5.30
|
||||||
mkdocstrings[python-legacy]==0.25.1
|
mkdocstrings[python-legacy]==0.25.2
|
||||||
netaddr==1.3.0
|
netaddr==1.3.0
|
||||||
nh3==0.2.18
|
nh3==0.2.18
|
||||||
Pillow==10.4.0
|
Pillow==10.4.0
|
||||||
psycopg[c,pool]==3.2.1
|
psycopg[c,pool]==3.2.1
|
||||||
PyYAML==6.0.1
|
PyYAML==6.0.1
|
||||||
requests==2.32.3
|
requests==2.32.3
|
||||||
social-auth-app-django==5.4.1
|
social-auth-app-django==5.4.2
|
||||||
social-auth-core==4.5.4
|
social-auth-core==4.5.4
|
||||||
strawberry-graphql==0.235.2
|
strawberry-graphql==0.237.2
|
||||||
strawberry-graphql-django==0.46.1
|
strawberry-graphql-django==0.47.1
|
||||||
svgwrite==1.4.3
|
svgwrite==1.4.3
|
||||||
tablib==3.6.1
|
tablib==3.6.1
|
||||||
tzdata==2024.1
|
tzdata==2024.1
|
||||||
|
Loading…
Reference in New Issue
Block a user