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:
|
||||
label: NetBox Version
|
||||
description: What version of NetBox are you currently running?
|
||||
placeholder: v4.0.7
|
||||
placeholder: v4.0.8
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
|
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
@ -14,7 +14,7 @@ body:
|
||||
attributes:
|
||||
label: NetBox version
|
||||
description: What version of NetBox are you currently running?
|
||||
placeholder: v4.0.7
|
||||
placeholder: v4.0.8
|
||||
validations:
|
||||
required: true
|
||||
- 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')"
|
||||
with:
|
||||
# Weighted assignments
|
||||
assignees: arthanson:3, jeffgdotorg:3, jeremystretch:3, DanSheps
|
||||
assignees: arthanson:3, jeremystretch:3, DanSheps
|
||||
numOfAssignee: 1
|
||||
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.
|
||||
|
||||
* 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.)
|
||||
|
||||
|
@ -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/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://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>
|
||||
<p></p>
|
||||
</div>
|
||||
|
@ -16,7 +16,7 @@ Administrators are encouraged to adhere to industry best practices concerning th
|
||||
|
||||
## 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 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.
|
||||
|
||||
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
|
||||
|
||||
|
@ -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.
|
||||
|
||||
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`)
|
||||
* **Target:** `master`
|
||||
* **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.
|
||||
|
||||
@ -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.
|
||||
|
||||
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.
|
||||
|
@ -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).
|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
@ -80,11 +80,11 @@ To create a viewset for a plugin model, subclass `NetBoxModelViewSet` in `api/vi
|
||||
|
||||
```python
|
||||
# api/views.py
|
||||
from netbox.api.viewsets import ModelViewSet
|
||||
from netbox.api.viewsets import NetBoxModelViewSet
|
||||
from my_plugin.models import MyModel
|
||||
from .serializers import MyModelSerializer
|
||||
|
||||
class MyModelViewSet(ModelViewSet):
|
||||
class MyModelViewSet(NetBoxModelViewSet):
|
||||
queryset = MyModel.objects.all()
|
||||
serializer_class = MyModelSerializer
|
||||
```
|
||||
|
@ -1,6 +1,34 @@
|
||||
# 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)
|
||||
|
||||
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 {
|
||||
'display_name': display_name,
|
||||
'icon_name': icon_name,
|
||||
'icon_img': icon_img,
|
||||
'url': f'{url}?{urlencode(params)}',
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ class ProviderTable(ContactsColumnMixin, NetBoxTable):
|
||||
account_count = columns.LinkedCountColumn(
|
||||
accessor=tables.A('accounts__count'),
|
||||
viewname='circuits:provideraccount_list',
|
||||
url_params={'account_id': 'pk'},
|
||||
url_params={'provider_id': 'pk'},
|
||||
verbose_name=_('Account Count')
|
||||
)
|
||||
asns = columns.ManyToManyColumn(
|
||||
|
@ -84,9 +84,7 @@ class GitBackend(DataBackend):
|
||||
clone_args = {
|
||||
"branch": self.params.get('branch'),
|
||||
"config": self.config,
|
||||
"depth": 1,
|
||||
"errstream": porcelain.NoneStream(),
|
||||
"quiet": True,
|
||||
}
|
||||
|
||||
if self.url_scheme in ('http', 'https'):
|
||||
@ -97,6 +95,9 @@ class GitBackend(DataBackend):
|
||||
"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}")
|
||||
try:
|
||||
|
@ -19,6 +19,7 @@ REVISION_BUTTONS = """
|
||||
class ConfigRevisionTable(NetBoxTable):
|
||||
is_active = columns.BooleanColumn(
|
||||
verbose_name=_('Is Active'),
|
||||
false_mark=None
|
||||
)
|
||||
actions = columns.ActionsColumn(
|
||||
actions=('delete',),
|
||||
|
@ -13,7 +13,7 @@ class ConnectedEndpointsSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
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_reachable = serializers.SerializerMethodField(read_only=True)
|
||||
|
||||
@ -22,7 +22,7 @@ class ConnectedEndpointsSerializer(serializers.ModelSerializer):
|
||||
if endpoints := obj.connected_endpoints:
|
||||
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):
|
||||
"""
|
||||
Return the appropriate serializer for the type of connected object.
|
||||
|
@ -89,7 +89,7 @@ class CablePathSerializer(serializers.ModelSerializer):
|
||||
class CabledObjectSerializer(serializers.ModelSerializer):
|
||||
cable = CableSerializer(nested=True, read_only=True, allow_null=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)
|
||||
_occupied = serializers.SerializerMethodField(read_only=True)
|
||||
|
||||
|
@ -87,7 +87,7 @@ class DeviceSerializer(NetBoxModelSerializer):
|
||||
]
|
||||
brief_fields = ('id', 'url', 'display', 'name', 'description')
|
||||
|
||||
@extend_schema_field(NestedDeviceSerializer)
|
||||
@extend_schema_field(NestedDeviceSerializer(allow_null=True))
|
||||
def get_parent_device(self, obj):
|
||||
try:
|
||||
device_bay = obj.parent_bay
|
||||
|
@ -1430,12 +1430,12 @@ class DeviceComponentFilterSet(django_filters.FilterSet):
|
||||
to_field_name='model',
|
||||
label=_('Device type (model)'),
|
||||
)
|
||||
role_id = django_filters.ModelMultipleChoiceFilter(
|
||||
device_role_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='device__role',
|
||||
queryset=DeviceRole.objects.all(),
|
||||
label=_('Device role (ID)'),
|
||||
)
|
||||
role = django_filters.ModelMultipleChoiceFilter(
|
||||
device_role = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='device__role__slug',
|
||||
queryset=DeviceRole.objects.all(),
|
||||
to_field_name='slug',
|
||||
|
@ -88,6 +88,8 @@ class Cable(PrimaryModel):
|
||||
null=True
|
||||
)
|
||||
|
||||
clone_fields = ('tenant', 'type',)
|
||||
|
||||
class Meta:
|
||||
ordering = ('pk',)
|
||||
verbose_name = _('cable')
|
||||
|
@ -63,7 +63,10 @@ class DeviceRoleTable(NetBoxTable):
|
||||
verbose_name=_('VMs')
|
||||
)
|
||||
color = columns.ColorColumn()
|
||||
vm_role = columns.BooleanColumn()
|
||||
vm_role = columns.BooleanColumn(
|
||||
verbose_name=_('VM role'),
|
||||
false_mark=None
|
||||
)
|
||||
config_template = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
@ -329,6 +332,7 @@ class CableTerminationTable(NetBoxTable):
|
||||
)
|
||||
mark_connected = columns.BooleanColumn(
|
||||
verbose_name=_('Mark Connected'),
|
||||
false_mark=None
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@ -586,7 +590,8 @@ class InterfaceTable(ModularDeviceComponentTable, BaseInterfaceTable, PathEndpoi
|
||||
}
|
||||
)
|
||||
mgmt_only = columns.BooleanColumn(
|
||||
verbose_name=_('Management Only')
|
||||
verbose_name=_('Management Only'),
|
||||
false_mark=None
|
||||
)
|
||||
speed_formatted = columns.TemplateColumn(
|
||||
template_code='{% load helpers %}{{ value|humanize_speed }}',
|
||||
@ -913,6 +918,7 @@ class InventoryItemTable(DeviceComponentTable):
|
||||
)
|
||||
discovered = columns.BooleanColumn(
|
||||
verbose_name=_('Discovered'),
|
||||
false_mark=None
|
||||
)
|
||||
parent = tables.Column(
|
||||
linkify=True,
|
||||
|
@ -86,7 +86,8 @@ class DeviceTypeTable(NetBoxTable):
|
||||
linkify=True
|
||||
)
|
||||
is_full_depth = columns.BooleanColumn(
|
||||
verbose_name=_('Full Depth')
|
||||
verbose_name=_('Full Depth'),
|
||||
false_mark=None
|
||||
)
|
||||
comments = columns.MarkdownColumn(
|
||||
verbose_name=_('Comments'),
|
||||
@ -98,7 +99,10 @@ class DeviceTypeTable(NetBoxTable):
|
||||
verbose_name=_('U Height'),
|
||||
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(
|
||||
verbose_name=_('Weight'),
|
||||
template_code=WEIGHT,
|
||||
@ -221,7 +225,8 @@ class InterfaceTemplateTable(ComponentTemplateTable):
|
||||
verbose_name=_('Enabled'),
|
||||
)
|
||||
mgmt_only = columns.BooleanColumn(
|
||||
verbose_name=_('Management Only')
|
||||
verbose_name=_('Management Only'),
|
||||
false_mark=None
|
||||
)
|
||||
actions = columns.ActionsColumn(
|
||||
actions=('edit', 'delete'),
|
||||
|
@ -32,11 +32,11 @@ class DeviceComponentFilterSetTests:
|
||||
params = {'device_type': [device_types[0].model, device_types[1].model]}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||
|
||||
def test_role(self):
|
||||
def test_device_role(self):
|
||||
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)
|
||||
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)
|
||||
|
||||
|
||||
@ -4693,6 +4693,13 @@ class InventoryItemTestCase(TestCase, ChangeLoggedFilterSetTests):
|
||||
params = {'device_type': [device_types[0].model, device_types[1].model]}
|
||||
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):
|
||||
role = DeviceRole.objects.all()[:2]
|
||||
params = {'role_id': [role[0].pk, role[1].pk]}
|
||||
|
@ -38,7 +38,7 @@ class ScriptSerializer(ValidatedModelSerializer):
|
||||
def get_display(self, obj):
|
||||
return f'{obj.name} ({obj.module})'
|
||||
|
||||
@extend_schema_field(serializers.CharField())
|
||||
@extend_schema_field(serializers.CharField(allow_null=True))
|
||||
def get_description(self, obj):
|
||||
if obj.python_class:
|
||||
return obj.python_class().description
|
||||
|
@ -251,6 +251,10 @@ class ObjectListWidget(DashboardWidget):
|
||||
def render(self, request):
|
||||
app_label, model_name = self.config['model'].split('.')
|
||||
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')
|
||||
|
||||
# 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')
|
||||
)
|
||||
required = columns.BooleanColumn(
|
||||
verbose_name=_('Required')
|
||||
verbose_name=_('Required'),
|
||||
false_mark=None
|
||||
)
|
||||
ui_visible = columns.ChoiceFieldColumn(
|
||||
verbose_name=_('Visible')
|
||||
@ -79,6 +80,7 @@ class CustomFieldTable(NetBoxTable):
|
||||
)
|
||||
is_cloneable = columns.BooleanColumn(
|
||||
verbose_name=_('Is Cloneable'),
|
||||
false_mark=None
|
||||
)
|
||||
validation_minimum = tables.Column(
|
||||
verbose_name=_('Minimum Value'),
|
||||
@ -125,6 +127,7 @@ class CustomFieldChoiceSetTable(NetBoxTable):
|
||||
)
|
||||
order_alphabetically = columns.BooleanColumn(
|
||||
verbose_name=_('Order Alphabetically'),
|
||||
false_mark=None
|
||||
)
|
||||
|
||||
class Meta(NetBoxTable.Meta):
|
||||
@ -149,6 +152,7 @@ class CustomLinkTable(NetBoxTable):
|
||||
)
|
||||
new_window = columns.BooleanColumn(
|
||||
verbose_name=_('New Window'),
|
||||
false_mark=None
|
||||
)
|
||||
|
||||
class Meta(NetBoxTable.Meta):
|
||||
@ -170,6 +174,7 @@ class ExportTemplateTable(NetBoxTable):
|
||||
)
|
||||
as_attachment = columns.BooleanColumn(
|
||||
verbose_name=_('As Attachment'),
|
||||
false_mark=None
|
||||
)
|
||||
data_source = tables.Column(
|
||||
verbose_name=_('Data Source'),
|
||||
@ -238,6 +243,7 @@ class SavedFilterTable(NetBoxTable):
|
||||
)
|
||||
shared = columns.BooleanColumn(
|
||||
verbose_name=_('Shared'),
|
||||
false_mark=None
|
||||
)
|
||||
|
||||
def value_parameters(self, value):
|
||||
|
@ -86,7 +86,8 @@ class RIRTable(NetBoxTable):
|
||||
linkify=True
|
||||
)
|
||||
is_private = columns.BooleanColumn(
|
||||
verbose_name=_('Private')
|
||||
verbose_name=_('Private'),
|
||||
false_mark=None
|
||||
)
|
||||
aggregate_count = columns.LinkedCountColumn(
|
||||
viewname='ipam:aggregate_list',
|
||||
@ -258,10 +259,12 @@ class PrefixTable(TenancyColumnsMixin, NetBoxTable):
|
||||
linkify=True
|
||||
)
|
||||
is_pool = columns.BooleanColumn(
|
||||
verbose_name=_('Pool')
|
||||
verbose_name=_('Pool'),
|
||||
false_mark=None
|
||||
)
|
||||
mark_utilized = columns.BooleanColumn(
|
||||
verbose_name=_('Marked Utilized')
|
||||
verbose_name=_('Marked Utilized'),
|
||||
false_mark=None
|
||||
)
|
||||
utilization = PrefixUtilizationColumn(
|
||||
verbose_name=_('Utilization'),
|
||||
@ -314,7 +317,8 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
|
||||
linkify=True
|
||||
)
|
||||
mark_utilized = columns.BooleanColumn(
|
||||
verbose_name=_('Marked Utilized')
|
||||
verbose_name=_('Marked Utilized'),
|
||||
false_mark=None
|
||||
)
|
||||
utilization = columns.UtilizationColumn(
|
||||
verbose_name=_('Utilization'),
|
||||
@ -386,7 +390,8 @@ class IPAddressTable(TenancyColumnsMixin, NetBoxTable):
|
||||
assigned = columns.BooleanColumn(
|
||||
accessor='assigned_object_id',
|
||||
linkify=lambda record: record.assigned_object.get_absolute_url(),
|
||||
verbose_name=_('Assigned')
|
||||
verbose_name=_('Assigned'),
|
||||
false_mark=None
|
||||
)
|
||||
comments = columns.MarkdownColumn(
|
||||
verbose_name=_('Comments'),
|
||||
|
@ -215,6 +215,7 @@ class InterfaceVLANTable(NetBoxTable):
|
||||
)
|
||||
tagged = columns.BooleanColumn(
|
||||
verbose_name=_('Tagged'),
|
||||
false_mark=None
|
||||
)
|
||||
site = tables.Column(
|
||||
verbose_name=_('Site'),
|
||||
|
@ -30,7 +30,8 @@ class VRFTable(TenancyColumnsMixin, NetBoxTable):
|
||||
verbose_name=_('RD')
|
||||
)
|
||||
enforce_unique = columns.BooleanColumn(
|
||||
verbose_name=_('Unique')
|
||||
verbose_name=_('Unique'),
|
||||
false_mark=None
|
||||
)
|
||||
import_targets = columns.TemplateColumn(
|
||||
verbose_name=_('Import Targets'),
|
||||
|
@ -49,12 +49,15 @@ AUTH_BACKEND_ATTRS = {
|
||||
'okta-openidconnect': ('Okta (OIDC)', None),
|
||||
'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):
|
||||
"""
|
||||
Return the user-friendly name and icon name for a remote authentication backend, if known. Defaults to the
|
||||
raw backend name and no icon.
|
||||
Return the user-friendly name and icon name for a remote authentication backend, if
|
||||
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))
|
||||
|
||||
|
@ -742,11 +742,16 @@ RQ_QUEUES.update({
|
||||
|
||||
# Supported translation languages
|
||||
LANGUAGES = (
|
||||
('cs', _('Czech')),
|
||||
('da', _('Danish')),
|
||||
('de', _('German')),
|
||||
('en', _('English')),
|
||||
('es', _('Spanish')),
|
||||
('fr', _('French')),
|
||||
('it', _('Italian')),
|
||||
('ja', _('Japanese')),
|
||||
('nl', _('Dutch')),
|
||||
('pl', _('Polish')),
|
||||
('pt', _('Portuguese')),
|
||||
('ru', _('Russian')),
|
||||
('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
|
||||
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):
|
||||
if value:
|
||||
rendered = '<span class="text-success"><i class="mdi mdi-check-bold"></i></span>'
|
||||
elif value is None:
|
||||
rendered = '<span class="text-muted">—</span>'
|
||||
else:
|
||||
rendered = '<span class="text-danger"><i class="mdi mdi-close-thick"></i></span>'
|
||||
return mark_safe(rendered)
|
||||
if value is None:
|
||||
return self.EMPTY_MARK
|
||||
if value and self.true_mark:
|
||||
return self.true_mark
|
||||
if not value and self.false_mark:
|
||||
return self.false_mark
|
||||
return self.EMPTY_MARK
|
||||
|
||||
def value(self, value):
|
||||
return str(value)
|
||||
@ -249,7 +258,7 @@ class ActionsColumn(tables.Column):
|
||||
|
||||
def render(self, record, table, **kwargs):
|
||||
# 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 ''
|
||||
|
||||
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",
|
||||
"clipboard": "2.0.11",
|
||||
"flatpickr": "4.6.13",
|
||||
"gridstack": "10.3.0",
|
||||
"gridstack": "10.3.1",
|
||||
"htmx.org": "1.9.12",
|
||||
"query-string": "9.0.0",
|
||||
"sass": "1.77.6",
|
||||
"query-string": "9.1.0",
|
||||
"sass": "1.77.8",
|
||||
"tom-select": "2.3.1",
|
||||
"typeface-inter": "3.18.1",
|
||||
"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"
|
||||
integrity sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==
|
||||
|
||||
gridstack@10.3.0:
|
||||
version "10.3.0"
|
||||
resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-10.3.0.tgz#8fa065f896d0a880c5c54c24d189f3197184488a"
|
||||
integrity sha512-eGKsmU2TppV4coyDu9IIdIkm4qjgLLdjlEOFwQyQMuSwfOpzSfLdPc8du0HuebGr7CvAIrJxN4lBOmGrWSBg9g==
|
||||
gridstack@10.3.1:
|
||||
version "10.3.1"
|
||||
resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-10.3.1.tgz#4ed704279c40094fc1b9e3318f20b573f2fe9f40"
|
||||
integrity sha512-Ra82k/88gdeiu3ZP40COS4bI4sGhNQlZAaAQ6szfPfr68zVpsXxiyLKr5zYcTpKX4jjcwyNsNNdcV1tDJc71fA==
|
||||
|
||||
has-bigints@^1.0.1, has-bigints@^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"
|
||||
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
|
||||
|
||||
query-string@9.0.0:
|
||||
version "9.0.0"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-9.0.0.tgz#1fe177cd95545600f0deab93f5fb02fd4e3e7273"
|
||||
integrity sha512-4EWwcRGsO2H+yzq6ddHcVqkCQ2EFUSfDMEjF8ryp8ReymyZhIuaFRGLomeOQLkrzacMHoyky2HW0Qe30UbzkKw==
|
||||
query-string@9.1.0:
|
||||
version "9.1.0"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-9.1.0.tgz#5f12a4653a4ba56021e113b5cf58e56581823e7a"
|
||||
integrity sha512-t6dqMECpCkqfyv2FfwVS1xcB6lgXW/0XZSaKdsCNGYkqMO76AFiJEg4vINzoDKcZa6MS7JX+OHIjwh06K5vczw==
|
||||
dependencies:
|
||||
decode-uri-component "^0.4.1"
|
||||
filter-obj "^5.1.0"
|
||||
@ -2482,10 +2482,10 @@ safe-regex-test@^1.0.3:
|
||||
es-errors "^1.3.0"
|
||||
is-regex "^1.1.4"
|
||||
|
||||
sass@1.77.6:
|
||||
version "1.77.6"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.6.tgz#898845c1348078c2e6d1b64f9ee06b3f8bd489e4"
|
||||
integrity sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==
|
||||
sass@1.77.8:
|
||||
version "1.77.8"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.8.tgz#9f18b449ea401759ef7ec1752a16373e296b52bd"
|
||||
integrity sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
|
@ -7,7 +7,11 @@
|
||||
<html
|
||||
lang="en"
|
||||
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>
|
||||
<meta charset="UTF-8" />
|
||||
|
@ -4,6 +4,18 @@
|
||||
{% load perms %}
|
||||
{% 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 %}
|
||||
{% if request.user|can_delete:object %}
|
||||
{% delete_button object %}
|
||||
|
@ -31,7 +31,7 @@
|
||||
<td class="d-flex justify-content-between align-items-start">
|
||||
{% if object.rack %}
|
||||
{{ 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>
|
||||
</a>
|
||||
{% else %}
|
||||
|
@ -24,7 +24,7 @@
|
||||
<table class="table table-hover">
|
||||
{% for test, data in tests.items %}
|
||||
<tr>
|
||||
<td class="font-monospace"><a href="#{{ test }}">{{ test }}</a></td>
|
||||
<td class="font-monospace">{{ test }}</td>
|
||||
<td class="text-end report-stats">
|
||||
<span class="badge text-bg-success">{{ data.success }}</span>
|
||||
<span class="badge text-bg-info">{{ data.info }}</span>
|
||||
|
@ -78,7 +78,8 @@
|
||||
{% for backend in auth_backends %}
|
||||
<div class="col">
|
||||
<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 }}
|
||||
</a>
|
||||
</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:
|
||||
# Quentin Laurent, 2024
|
||||
# Xavier W, 2024
|
||||
# Jeremy Stretch, 2024
|
||||
# Jonathan Senecal, 2024
|
||||
# Lou Lecrivain, 2024
|
||||
# Jean Benoit <jean@unistra.fr>, 2024
|
||||
# thomas rivemale, 2024
|
||||
# Jeff Gehlbach, 2024
|
||||
# Jeremy Stretch, 2024
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\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"
|
||||
"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"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -69,7 +69,7 @@ msgstr "Dernière utilisation"
|
||||
msgid "Allowed IPs"
|
||||
msgstr "IP autorisées"
|
||||
|
||||
#: netbox/account/views.py:204
|
||||
#: netbox/account/views.py:214
|
||||
msgid "Your preferences have been updated."
|
||||
msgstr "Vos préférences ont été mises à jour."
|
||||
|
||||
@ -1519,16 +1519,16 @@ msgstr "Mot de passe"
|
||||
msgid "Branch"
|
||||
msgstr "Branche"
|
||||
|
||||
#: netbox/core/data_backends.py:105
|
||||
#: netbox/core/data_backends.py:106
|
||||
#, python-brace-format
|
||||
msgid "Fetching remote data failed ({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"
|
||||
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"
|
||||
msgstr "Clé d'accès secrète AWS"
|
||||
|
||||
@ -1877,7 +1877,7 @@ msgstr ""
|
||||
msgid "last updated"
|
||||
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"
|
||||
msgstr "chemin"
|
||||
|
||||
@ -4656,53 +4656,53 @@ msgstr "longueur"
|
||||
msgid "length unit"
|
||||
msgstr "unité de longueur"
|
||||
|
||||
#: netbox/dcim/models/cables.py:93
|
||||
#: netbox/dcim/models/cables.py:95
|
||||
msgid "cable"
|
||||
msgstr "câble"
|
||||
|
||||
#: netbox/dcim/models/cables.py:94
|
||||
#: netbox/dcim/models/cables.py:96
|
||||
msgid "cables"
|
||||
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"
|
||||
msgstr ""
|
||||
"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."
|
||||
msgstr ""
|
||||
"Vous devez définir les terminaisons A et B lors de la création d'un nouveau "
|
||||
"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."
|
||||
msgstr ""
|
||||
"Impossible de connecter différents types de terminaisons à la même extrémité"
|
||||
" du câble."
|
||||
|
||||
#: netbox/dcim/models/cables.py:181
|
||||
#: netbox/dcim/models/cables.py:183
|
||||
#, python-brace-format
|
||||
msgid "Incompatible termination types: {type_a} and {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."
|
||||
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"
|
||||
msgstr "fin"
|
||||
|
||||
#: netbox/dcim/models/cables.py:311
|
||||
#: netbox/dcim/models/cables.py:313
|
||||
msgid "cable termination"
|
||||
msgstr "terminaison de câble"
|
||||
|
||||
#: netbox/dcim/models/cables.py:312
|
||||
#: netbox/dcim/models/cables.py:314
|
||||
msgid "cable terminations"
|
||||
msgstr "terminaisons de câble"
|
||||
|
||||
#: netbox/dcim/models/cables.py:331
|
||||
#: netbox/dcim/models/cables.py:333
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"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} "
|
||||
"{termination_id}: câble {cable_pk}"
|
||||
|
||||
#: netbox/dcim/models/cables.py:341
|
||||
#: netbox/dcim/models/cables.py:343
|
||||
#, python-brace-format
|
||||
msgid "Cables cannot be terminated to {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."
|
||||
msgstr ""
|
||||
"Les terminaisons de circuit connectées au réseau d'un fournisseur peuvent ne"
|
||||
" 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"
|
||||
msgstr "est actif"
|
||||
|
||||
#: netbox/dcim/models/cables.py:450
|
||||
#: netbox/dcim/models/cables.py:452
|
||||
msgid "is complete"
|
||||
msgstr "est terminé"
|
||||
|
||||
#: netbox/dcim/models/cables.py:454
|
||||
#: netbox/dcim/models/cables.py:456
|
||||
msgid "is split"
|
||||
msgstr "est divisé"
|
||||
|
||||
#: netbox/dcim/models/cables.py:462
|
||||
#: netbox/dcim/models/cables.py:464
|
||||
msgid "cable path"
|
||||
msgstr "chemin de câble"
|
||||
|
||||
#: netbox/dcim/models/cables.py:463
|
||||
#: netbox/dcim/models/cables.py:465
|
||||
msgid "cable paths"
|
||||
msgstr "chemins de câbles"
|
||||
|
||||
@ -6983,43 +6983,43 @@ msgstr ""
|
||||
"Format non valide. Les paramètres d'URL doivent être transmis sous forme de "
|
||||
"dictionnaire."
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:284
|
||||
#: netbox/extras/dashboard/widgets.py:288
|
||||
msgid "RSS Feed"
|
||||
msgstr "Fil RSS"
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:289
|
||||
#: netbox/extras/dashboard/widgets.py:293
|
||||
msgid "Embed an RSS feed from an external website."
|
||||
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"
|
||||
msgstr "URL du flux"
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:301
|
||||
#: netbox/extras/dashboard/widgets.py:305
|
||||
msgid "The maximum number of objects to display"
|
||||
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)"
|
||||
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/bookmarks.html:7
|
||||
#: netbox/templates/inc/user_menu.html:30
|
||||
msgid "Bookmarks"
|
||||
msgstr "Signets"
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:362
|
||||
#: netbox/extras/dashboard/widgets.py:366
|
||||
msgid "Show your personal bookmarks"
|
||||
msgstr "Afficher vos favoris personnels"
|
||||
|
||||
#: netbox/extras/events.py:134
|
||||
#: netbox/extras/events.py:137
|
||||
#, python-brace-format
|
||||
msgid "Unknown action type for an event rule: {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
|
||||
msgid "Cannot import events pipeline {name} error: {error}"
|
||||
msgstr ""
|
||||
@ -10048,7 +10048,7 @@ msgstr ""
|
||||
"Valeur non valide. Spécifiez un type de contenu comme "
|
||||
"«<app_label>.<model_name>'."
|
||||
|
||||
#: netbox/netbox/authentication/__init__.py:138
|
||||
#: netbox/netbox/authentication/__init__.py:141
|
||||
#, python-brace-format
|
||||
msgid "Invalid permission {permission} for model {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
|
||||
msgid "Lookup"
|
||||
msgstr ""
|
||||
msgstr "Chercher"
|
||||
|
||||
#: netbox/netbox/forms/base.py:88
|
||||
msgid ""
|
||||
@ -10906,43 +10906,43 @@ msgstr "Impossible d'ajouter des magasins au registre après l'initialisation"
|
||||
msgid "Cannot delete stores from registry"
|
||||
msgstr "Impossible de supprimer des magasins du registre"
|
||||
|
||||
#: netbox/netbox/settings.py:741
|
||||
#: netbox/netbox/settings.py:742
|
||||
msgid "German"
|
||||
msgstr "allemand"
|
||||
|
||||
#: netbox/netbox/settings.py:742
|
||||
#: netbox/netbox/settings.py:743
|
||||
msgid "English"
|
||||
msgstr "Anglais"
|
||||
|
||||
#: netbox/netbox/settings.py:743
|
||||
#: netbox/netbox/settings.py:744
|
||||
msgid "Spanish"
|
||||
msgstr "espagnol"
|
||||
|
||||
#: netbox/netbox/settings.py:744
|
||||
#: netbox/netbox/settings.py:745
|
||||
msgid "French"
|
||||
msgstr "français"
|
||||
|
||||
#: netbox/netbox/settings.py:745
|
||||
#: netbox/netbox/settings.py:746
|
||||
msgid "Japanese"
|
||||
msgstr "japonais"
|
||||
|
||||
#: netbox/netbox/settings.py:746
|
||||
#: netbox/netbox/settings.py:747
|
||||
msgid "Portuguese"
|
||||
msgstr "portugais"
|
||||
|
||||
#: netbox/netbox/settings.py:747
|
||||
#: netbox/netbox/settings.py:748
|
||||
msgid "Russian"
|
||||
msgstr "russe"
|
||||
|
||||
#: netbox/netbox/settings.py:748
|
||||
#: netbox/netbox/settings.py:749
|
||||
msgid "Turkish"
|
||||
msgstr "Turc"
|
||||
|
||||
#: netbox/netbox/settings.py:749
|
||||
#: netbox/netbox/settings.py:750
|
||||
msgid "Ukrainian"
|
||||
msgstr "Ukrainien"
|
||||
|
||||
#: netbox/netbox/settings.py:750
|
||||
#: netbox/netbox/settings.py:751
|
||||
msgid "Chinese"
|
||||
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 ""
|
||||
"Project-Id-Version: PACKAGE VERSION\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"
|
||||
"Last-Translator: Artem Kotik, 2024\n"
|
||||
"Language-Team: Russian (https://app.transifex.com/netbox-community/teams/178115/ru/)\n"
|
||||
@ -70,7 +70,7 @@ msgstr "Последнее использование"
|
||||
msgid "Allowed IPs"
|
||||
msgstr "Разрешенные IP-адреса"
|
||||
|
||||
#: netbox/account/views.py:204
|
||||
#: netbox/account/views.py:214
|
||||
msgid "Your preferences have been updated."
|
||||
msgstr "Ваши настройки были обновлены."
|
||||
|
||||
@ -263,7 +263,7 @@ msgstr "Аккаунт провайдера (ID)"
|
||||
|
||||
#: netbox/circuits/filtersets.py:171
|
||||
msgid "Provider account (account)"
|
||||
msgstr "Учетная запись провайдера (учетная запись)"
|
||||
msgstr "Учетная запись провайдера"
|
||||
|
||||
#: netbox/circuits/filtersets.py:176
|
||||
msgid "Provider network (ID)"
|
||||
@ -1520,16 +1520,16 @@ msgstr "Пароль"
|
||||
msgid "Branch"
|
||||
msgstr "Ветка"
|
||||
|
||||
#: netbox/core/data_backends.py:105
|
||||
#: netbox/core/data_backends.py:106
|
||||
#, python-brace-format
|
||||
msgid "Fetching remote data failed ({name}): {error}"
|
||||
msgstr "Не удалось получить удаленные данные ({name}): {error}"
|
||||
|
||||
#: netbox/core/data_backends.py:118
|
||||
#: netbox/core/data_backends.py:119
|
||||
msgid "AWS access key ID"
|
||||
msgstr "ID ключа доступа AWS"
|
||||
|
||||
#: netbox/core/data_backends.py:122
|
||||
#: netbox/core/data_backends.py:123
|
||||
msgid "AWS secret access key"
|
||||
msgstr "Секретный ключ доступа AWS"
|
||||
|
||||
@ -1872,7 +1872,7 @@ msgstr ""
|
||||
msgid "last updated"
|
||||
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"
|
||||
msgstr "путь"
|
||||
|
||||
@ -4652,50 +4652,50 @@ msgstr "Длина"
|
||||
msgid "length unit"
|
||||
msgstr "длина единицы"
|
||||
|
||||
#: netbox/dcim/models/cables.py:93
|
||||
#: netbox/dcim/models/cables.py:95
|
||||
msgid "cable"
|
||||
msgstr "кабель"
|
||||
|
||||
#: netbox/dcim/models/cables.py:94
|
||||
#: netbox/dcim/models/cables.py:96
|
||||
msgid "cables"
|
||||
msgstr "кабели"
|
||||
|
||||
#: netbox/dcim/models/cables.py:163
|
||||
#: netbox/dcim/models/cables.py:165
|
||||
msgid "Must specify a unit when setting a cable length"
|
||||
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."
|
||||
msgstr ""
|
||||
"При создании нового кабеля необходимо определить концевые разъемы 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."
|
||||
msgstr ""
|
||||
"Невозможно подключить разные типы разъемов к одному и тому же концу кабеля."
|
||||
|
||||
#: netbox/dcim/models/cables.py:181
|
||||
#: netbox/dcim/models/cables.py:183
|
||||
#, python-brace-format
|
||||
msgid "Incompatible termination types: {type_a} and {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."
|
||||
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"
|
||||
msgstr "конец"
|
||||
|
||||
#: netbox/dcim/models/cables.py:311
|
||||
#: netbox/dcim/models/cables.py:313
|
||||
msgid "cable termination"
|
||||
msgstr "кабельный терминатор"
|
||||
|
||||
#: netbox/dcim/models/cables.py:312
|
||||
#: netbox/dcim/models/cables.py:314
|
||||
msgid "cable terminations"
|
||||
msgstr "кабельные терминаторы"
|
||||
|
||||
#: netbox/dcim/models/cables.py:331
|
||||
#: netbox/dcim/models/cables.py:333
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Duplicate termination found for {app_label}.{model} {termination_id}: cable "
|
||||
@ -4704,34 +4704,34 @@ msgstr ""
|
||||
"Обнаружен дубликат увольнения для {app_label}.{model} {termination_id}: "
|
||||
"кабель {cable_pk}"
|
||||
|
||||
#: netbox/dcim/models/cables.py:341
|
||||
#: netbox/dcim/models/cables.py:343
|
||||
#, python-brace-format
|
||||
msgid "Cables cannot be terminated to {type_display} interfaces"
|
||||
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."
|
||||
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"
|
||||
msgstr "активен"
|
||||
|
||||
#: netbox/dcim/models/cables.py:450
|
||||
#: netbox/dcim/models/cables.py:452
|
||||
msgid "is complete"
|
||||
msgstr "завершен"
|
||||
|
||||
#: netbox/dcim/models/cables.py:454
|
||||
#: netbox/dcim/models/cables.py:456
|
||||
msgid "is split"
|
||||
msgstr "разделен"
|
||||
|
||||
#: netbox/dcim/models/cables.py:462
|
||||
#: netbox/dcim/models/cables.py:464
|
||||
msgid "cable path"
|
||||
msgstr "кабельная трасса"
|
||||
|
||||
#: netbox/dcim/models/cables.py:463
|
||||
#: netbox/dcim/models/cables.py:465
|
||||
msgid "cable paths"
|
||||
msgstr "кабельные трассы"
|
||||
|
||||
@ -5274,11 +5274,11 @@ msgstr "Нанесенное на карту положение на соотв
|
||||
|
||||
#: netbox/dcim/models/device_components.py:1007
|
||||
msgid "front port"
|
||||
msgstr "передний порт"
|
||||
msgstr "фронтальный порт"
|
||||
|
||||
#: netbox/dcim/models/device_components.py:1008
|
||||
msgid "front ports"
|
||||
msgstr "передние порты"
|
||||
msgstr "фронтальные порты"
|
||||
|
||||
#: netbox/dcim/models/device_components.py:1022
|
||||
#, python-brace-format
|
||||
@ -5541,7 +5541,7 @@ msgstr ""
|
||||
|
||||
#: netbox/dcim/models/devices.py:517
|
||||
msgid "platform"
|
||||
msgstr "платформ"
|
||||
msgstr "платформа"
|
||||
|
||||
#: netbox/dcim/models/devices.py:518
|
||||
msgid "platforms"
|
||||
@ -5604,7 +5604,7 @@ msgstr "широта"
|
||||
#: netbox/dcim/models/devices.py:711 netbox/dcim/models/devices.py:719
|
||||
#: netbox/dcim/models/sites.py:212 netbox/dcim/models/sites.py:220
|
||||
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
|
||||
msgid "longitude"
|
||||
@ -6059,15 +6059,15 @@ msgstr "Группа сайтов верхнего уровня с этой по
|
||||
|
||||
#: netbox/dcim/models/sites.py:115
|
||||
msgid "site group"
|
||||
msgstr "группа мест"
|
||||
msgstr "группа сайта"
|
||||
|
||||
#: netbox/dcim/models/sites.py:116
|
||||
msgid "site groups"
|
||||
msgstr "группы мест"
|
||||
msgstr "группы сайтов"
|
||||
|
||||
#: netbox/dcim/models/sites.py:141
|
||||
msgid "Full name of the site"
|
||||
msgstr "Полное название сайта"
|
||||
msgstr "Полное имя сайта"
|
||||
|
||||
#: netbox/dcim/models/sites.py:181 netbox/dcim/models/sites.py:279
|
||||
msgid "facility"
|
||||
@ -6095,11 +6095,11 @@ msgstr "Если отличается от физического адреса"
|
||||
|
||||
#: netbox/dcim/models/sites.py:238
|
||||
msgid "site"
|
||||
msgstr "место"
|
||||
msgstr "сайт"
|
||||
|
||||
#: netbox/dcim/models/sites.py:239
|
||||
msgid "sites"
|
||||
msgstr "Сайты"
|
||||
msgstr "сайты"
|
||||
|
||||
#: netbox/dcim/models/sites.py:309
|
||||
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
|
||||
msgid "Device B"
|
||||
msgstr "Устройство B"
|
||||
msgstr "Устройство Б"
|
||||
|
||||
#: netbox/dcim/tables/cables.py:78
|
||||
msgid "Location A"
|
||||
@ -6145,7 +6145,7 @@ msgstr "Локация A"
|
||||
|
||||
#: netbox/dcim/tables/cables.py:84
|
||||
msgid "Location B"
|
||||
msgstr "Локация B"
|
||||
msgstr "Локация Б"
|
||||
|
||||
#: netbox/dcim/tables/cables.py:90
|
||||
msgid "Rack A"
|
||||
@ -6153,7 +6153,7 @@ msgstr "Стойка A"
|
||||
|
||||
#: netbox/dcim/tables/cables.py:96
|
||||
msgid "Rack B"
|
||||
msgstr "Стойка B"
|
||||
msgstr "Стойка Б"
|
||||
|
||||
#: netbox/dcim/tables/cables.py:102
|
||||
msgid "Site A"
|
||||
@ -6161,7 +6161,7 @@ msgstr "Сайт A"
|
||||
|
||||
#: netbox/dcim/tables/cables.py:108
|
||||
msgid "Site B"
|
||||
msgstr "Сайт B"
|
||||
msgstr "Сайт Б"
|
||||
|
||||
#: netbox/dcim/tables/connections.py:31 netbox/dcim/tables/connections.py:50
|
||||
#: netbox/dcim/tables/connections.py:71
|
||||
@ -6224,11 +6224,11 @@ msgstr "Адрес IPv6"
|
||||
|
||||
#: netbox/dcim/tables/devices.py:207
|
||||
msgid "VC Position"
|
||||
msgstr "Позиция VC"
|
||||
msgstr "Позиция в шасси"
|
||||
|
||||
#: netbox/dcim/tables/devices.py:210
|
||||
msgid "VC Priority"
|
||||
msgstr "Приоритет VC"
|
||||
msgstr "Приоритет шасси"
|
||||
|
||||
#: netbox/dcim/tables/devices.py:217 netbox/templates/dcim/device_edit.html:38
|
||||
#: netbox/templates/dcim/devicebay_populate.html:16
|
||||
@ -6275,7 +6275,7 @@ msgstr "Интерфейсы"
|
||||
|
||||
#: netbox/dcim/tables/devices.py:246
|
||||
msgid "Front ports"
|
||||
msgstr "Передние порты"
|
||||
msgstr "Фронтальные порты"
|
||||
|
||||
#: netbox/dcim/tables/devices.py:252
|
||||
msgid "Device bays"
|
||||
@ -6472,7 +6472,7 @@ msgstr "Розетки питания"
|
||||
#: netbox/templates/dcim/module.html:37
|
||||
#: netbox/templates/dcim/moduletype/base.html:37
|
||||
msgid "Front Ports"
|
||||
msgstr "Передние порты"
|
||||
msgstr "Фронтальные порты"
|
||||
|
||||
#: netbox/dcim/tables/devicetypes.py:131 netbox/dcim/views.py:1018
|
||||
#: 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."
|
||||
msgstr "Неверный формат. Параметры URL должны быть переданы в виде словаря."
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:284
|
||||
#: netbox/extras/dashboard/widgets.py:288
|
||||
msgid "RSS Feed"
|
||||
msgstr "RSS-канал"
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:289
|
||||
#: netbox/extras/dashboard/widgets.py:293
|
||||
msgid "Embed an RSS feed from an external website."
|
||||
msgstr "Вставьте RSS-канал с внешнего веб-сайта."
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:296
|
||||
#: netbox/extras/dashboard/widgets.py:300
|
||||
msgid "Feed URL"
|
||||
msgstr "URL-адрес ленты"
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:301
|
||||
#: netbox/extras/dashboard/widgets.py:305
|
||||
msgid "The maximum number of objects to display"
|
||||
msgstr "Максимальное количество отображаемых объектов"
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:306
|
||||
#: netbox/extras/dashboard/widgets.py:310
|
||||
msgid "How long to stored the cached content (in seconds)"
|
||||
msgstr "Как долго хранить кэшированный контент (в секундах)"
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:358
|
||||
#: netbox/extras/dashboard/widgets.py:362
|
||||
#: netbox/templates/account/base.html:10
|
||||
#: netbox/templates/account/bookmarks.html:7
|
||||
#: netbox/templates/inc/user_menu.html:30
|
||||
msgid "Bookmarks"
|
||||
msgstr "Закладки"
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:362
|
||||
#: netbox/extras/dashboard/widgets.py:366
|
||||
msgid "Show your personal bookmarks"
|
||||
msgstr "Покажите свои личные закладки"
|
||||
|
||||
#: netbox/extras/events.py:134
|
||||
#: netbox/extras/events.py:137
|
||||
#, python-brace-format
|
||||
msgid "Unknown action type for an event rule: {action_type}"
|
||||
msgstr "Неизвестный тип действия для правила события: {action_type}"
|
||||
|
||||
#: netbox/extras/events.py:182
|
||||
#: netbox/extras/events.py:185
|
||||
#, python-brace-format
|
||||
msgid "Cannot import events pipeline {name} error: {error}"
|
||||
msgstr "Невозможно импортировать конвейер событий {name} ошибка: {error}"
|
||||
@ -9975,7 +9975,7 @@ msgid "Invalid value. Specify a content type as '<app_label>.<model_name>'."
|
||||
msgstr ""
|
||||
"Неверное значение. Укажите тип контента как '<app_label>.<model_name>'."
|
||||
|
||||
#: netbox/netbox/authentication/__init__.py:138
|
||||
#: netbox/netbox/authentication/__init__.py:141
|
||||
#, python-brace-format
|
||||
msgid "Invalid permission {permission} for model {model}"
|
||||
msgstr "Неверное разрешение {permission} для модели {model}"
|
||||
@ -10826,43 +10826,43 @@ msgstr "Невозможно добавить магазины в реестр
|
||||
msgid "Cannot delete stores from registry"
|
||||
msgstr "Невозможно удалить магазины из реестра"
|
||||
|
||||
#: netbox/netbox/settings.py:741
|
||||
#: netbox/netbox/settings.py:742
|
||||
msgid "German"
|
||||
msgstr "Немецкий"
|
||||
|
||||
#: netbox/netbox/settings.py:742
|
||||
#: netbox/netbox/settings.py:743
|
||||
msgid "English"
|
||||
msgstr "Английский"
|
||||
|
||||
#: netbox/netbox/settings.py:743
|
||||
#: netbox/netbox/settings.py:744
|
||||
msgid "Spanish"
|
||||
msgstr "Испанский"
|
||||
|
||||
#: netbox/netbox/settings.py:744
|
||||
#: netbox/netbox/settings.py:745
|
||||
msgid "French"
|
||||
msgstr "Французский"
|
||||
|
||||
#: netbox/netbox/settings.py:745
|
||||
#: netbox/netbox/settings.py:746
|
||||
msgid "Japanese"
|
||||
msgstr "Японский"
|
||||
|
||||
#: netbox/netbox/settings.py:746
|
||||
#: netbox/netbox/settings.py:747
|
||||
msgid "Portuguese"
|
||||
msgstr "Португальский"
|
||||
|
||||
#: netbox/netbox/settings.py:747
|
||||
#: netbox/netbox/settings.py:748
|
||||
msgid "Russian"
|
||||
msgstr "Русский"
|
||||
|
||||
#: netbox/netbox/settings.py:748
|
||||
#: netbox/netbox/settings.py:749
|
||||
msgid "Turkish"
|
||||
msgstr "Турецкий"
|
||||
|
||||
#: netbox/netbox/settings.py:749
|
||||
#: netbox/netbox/settings.py:750
|
||||
msgid "Ukrainian"
|
||||
msgstr "украинский"
|
||||
|
||||
#: netbox/netbox/settings.py:750
|
||||
#: netbox/netbox/settings.py:751
|
||||
msgid "Chinese"
|
||||
msgstr "Китайский"
|
||||
|
||||
|
@ -5,17 +5,17 @@
|
||||
#
|
||||
# Translators:
|
||||
# Burak Senturk, 2024
|
||||
# Jeremy Stretch, 2024
|
||||
# Hamdi Suat Aknar, 2024
|
||||
# Jeremy Stretch, 2024
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\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"
|
||||
"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"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -64,7 +64,7 @@ msgstr "Son Kullanım"
|
||||
msgid "Allowed IPs"
|
||||
msgstr "İzin verilen IP'ler"
|
||||
|
||||
#: netbox/account/views.py:204
|
||||
#: netbox/account/views.py:214
|
||||
msgid "Your preferences have been updated."
|
||||
msgstr "Tercihleriniz güncellendi."
|
||||
|
||||
@ -1510,16 +1510,16 @@ msgstr "Şifre"
|
||||
msgid "Branch"
|
||||
msgstr "Şube"
|
||||
|
||||
#: netbox/core/data_backends.py:105
|
||||
#: netbox/core/data_backends.py:106
|
||||
#, python-brace-format
|
||||
msgid "Fetching remote data failed ({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"
|
||||
msgstr "AWS erişim anahtarı kimliği"
|
||||
|
||||
#: netbox/core/data_backends.py:122
|
||||
#: netbox/core/data_backends.py:123
|
||||
msgid "AWS secret access key"
|
||||
msgstr "AWS gizli erişim anahtarı"
|
||||
|
||||
@ -1863,7 +1863,7 @@ msgstr ""
|
||||
msgid "last updated"
|
||||
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"
|
||||
msgstr "yol"
|
||||
|
||||
@ -4636,48 +4636,48 @@ msgstr "uzunluk"
|
||||
msgid "length unit"
|
||||
msgstr "uzunluk birimi"
|
||||
|
||||
#: netbox/dcim/models/cables.py:93
|
||||
#: netbox/dcim/models/cables.py:95
|
||||
msgid "cable"
|
||||
msgstr "kablo"
|
||||
|
||||
#: netbox/dcim/models/cables.py:94
|
||||
#: netbox/dcim/models/cables.py:96
|
||||
msgid "cables"
|
||||
msgstr "kablolar"
|
||||
|
||||
#: netbox/dcim/models/cables.py:163
|
||||
#: netbox/dcim/models/cables.py:165
|
||||
msgid "Must specify a unit when setting a cable length"
|
||||
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."
|
||||
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."
|
||||
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
|
||||
msgid "Incompatible termination types: {type_a} and {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."
|
||||
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"
|
||||
msgstr "son"
|
||||
|
||||
#: netbox/dcim/models/cables.py:311
|
||||
#: netbox/dcim/models/cables.py:313
|
||||
msgid "cable termination"
|
||||
msgstr "kablo sonlandırma"
|
||||
|
||||
#: netbox/dcim/models/cables.py:312
|
||||
#: netbox/dcim/models/cables.py:314
|
||||
msgid "cable terminations"
|
||||
msgstr "kablo sonlandırmaları"
|
||||
|
||||
#: netbox/dcim/models/cables.py:331
|
||||
#: netbox/dcim/models/cables.py:333
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"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 "
|
||||
"{cable_pk}"
|
||||
|
||||
#: netbox/dcim/models/cables.py:341
|
||||
#: netbox/dcim/models/cables.py:343
|
||||
#, python-brace-format
|
||||
msgid "Cables cannot be terminated to {type_display} interfaces"
|
||||
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."
|
||||
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"
|
||||
msgstr "aktiftir"
|
||||
|
||||
#: netbox/dcim/models/cables.py:450
|
||||
#: netbox/dcim/models/cables.py:452
|
||||
msgid "is complete"
|
||||
msgstr "tamamlandı"
|
||||
|
||||
#: netbox/dcim/models/cables.py:454
|
||||
#: netbox/dcim/models/cables.py:456
|
||||
msgid "is split"
|
||||
msgstr "bölünmüş"
|
||||
|
||||
#: netbox/dcim/models/cables.py:462
|
||||
#: netbox/dcim/models/cables.py:464
|
||||
msgid "cable path"
|
||||
msgstr "kablo yolu"
|
||||
|
||||
#: netbox/dcim/models/cables.py:463
|
||||
#: netbox/dcim/models/cables.py:465
|
||||
msgid "cable paths"
|
||||
msgstr "kablo yolları"
|
||||
|
||||
@ -6639,11 +6639,11 @@ msgstr "En eski"
|
||||
|
||||
#: netbox/extras/choices.py:126
|
||||
msgid "Alphabetical (A-Z)"
|
||||
msgstr ""
|
||||
msgstr "Alfabetik (A-Z)"
|
||||
|
||||
#: netbox/extras/choices.py:127
|
||||
msgid "Alphabetical (Z-A)"
|
||||
msgstr ""
|
||||
msgstr "Alfabetik (Z-A)"
|
||||
|
||||
#: netbox/extras/choices.py:143 netbox/templates/generic/object.html:61
|
||||
msgid "Updated"
|
||||
@ -6831,10 +6831,12 @@ msgstr "Kural seti bir sözlük olmalı, değil {ruleset}."
|
||||
#: netbox/extras/conditions.py:142
|
||||
msgid "Invalid logic type: must be 'AND' or 'OR'. Please check documentation."
|
||||
msgstr ""
|
||||
"Geçersiz mantık türü: 'AND' veya 'OR' olmalıdır. Lütfen belgeleri kontrol "
|
||||
"edin."
|
||||
|
||||
#: netbox/extras/conditions.py:154
|
||||
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
|
||||
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."
|
||||
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"
|
||||
msgstr "RSS Beslemesi"
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:289
|
||||
#: netbox/extras/dashboard/widgets.py:293
|
||||
msgid "Embed an RSS feed from an external website."
|
||||
msgstr "Harici bir web sitesinden bir RSS beslemesi ekleyin."
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:296
|
||||
#: netbox/extras/dashboard/widgets.py:300
|
||||
msgid "Feed URL"
|
||||
msgstr "Akış URL'si"
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:301
|
||||
#: netbox/extras/dashboard/widgets.py:305
|
||||
msgid "The maximum number of objects to display"
|
||||
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)"
|
||||
msgstr ""
|
||||
"Ö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/bookmarks.html:7
|
||||
#: netbox/templates/inc/user_menu.html:30
|
||||
msgid "Bookmarks"
|
||||
msgstr "Yer İşaretleri"
|
||||
|
||||
#: netbox/extras/dashboard/widgets.py:362
|
||||
#: netbox/extras/dashboard/widgets.py:366
|
||||
msgid "Show your personal bookmarks"
|
||||
msgstr "Kişisel yer imlerinizi gösterin"
|
||||
|
||||
#: netbox/extras/events.py:134
|
||||
#: netbox/extras/events.py:137
|
||||
#, python-brace-format
|
||||
msgid "Unknown action type for an event rule: {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
|
||||
msgid "Cannot import events pipeline {name} error: {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 ""
|
||||
"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
|
||||
msgid "Invalid permission {permission} for model {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
|
||||
msgid "Lookup"
|
||||
msgstr ""
|
||||
msgstr "Aramak"
|
||||
|
||||
#: netbox/netbox/forms/base.py:88
|
||||
msgid ""
|
||||
@ -10741,43 +10743,43 @@ msgstr "Başlatıldıktan sonra kayıt defterine mağazalar eklenemiyor"
|
||||
msgid "Cannot delete stores from registry"
|
||||
msgstr "Mağazalar kayıt defterinden silinemiyor"
|
||||
|
||||
#: netbox/netbox/settings.py:741
|
||||
#: netbox/netbox/settings.py:742
|
||||
msgid "German"
|
||||
msgstr "Alman"
|
||||
|
||||
#: netbox/netbox/settings.py:742
|
||||
#: netbox/netbox/settings.py:743
|
||||
msgid "English"
|
||||
msgstr "İngilizce"
|
||||
|
||||
#: netbox/netbox/settings.py:743
|
||||
#: netbox/netbox/settings.py:744
|
||||
msgid "Spanish"
|
||||
msgstr "İspanyolca"
|
||||
|
||||
#: netbox/netbox/settings.py:744
|
||||
#: netbox/netbox/settings.py:745
|
||||
msgid "French"
|
||||
msgstr "Fransızca"
|
||||
|
||||
#: netbox/netbox/settings.py:745
|
||||
#: netbox/netbox/settings.py:746
|
||||
msgid "Japanese"
|
||||
msgstr "Japonca"
|
||||
|
||||
#: netbox/netbox/settings.py:746
|
||||
#: netbox/netbox/settings.py:747
|
||||
msgid "Portuguese"
|
||||
msgstr "Portekizce"
|
||||
|
||||
#: netbox/netbox/settings.py:747
|
||||
#: netbox/netbox/settings.py:748
|
||||
msgid "Russian"
|
||||
msgstr "Rusça"
|
||||
|
||||
#: netbox/netbox/settings.py:748
|
||||
#: netbox/netbox/settings.py:749
|
||||
msgid "Turkish"
|
||||
msgstr "Türkçe"
|
||||
|
||||
#: netbox/netbox/settings.py:749
|
||||
#: netbox/netbox/settings.py:750
|
||||
msgid "Ukrainian"
|
||||
msgstr "Ukraynalı"
|
||||
|
||||
#: netbox/netbox/settings.py:750
|
||||
#: netbox/netbox/settings.py:751
|
||||
msgid "Chinese"
|
||||
msgstr "Çince"
|
||||
|
||||
@ -13083,11 +13085,11 @@ msgstr "Veriler yukarı akış dosyasıyla senkronize değil"
|
||||
|
||||
#: netbox/templates/inc/table_controls_htmx.html:7
|
||||
msgid "Quick search"
|
||||
msgstr ""
|
||||
msgstr "Hızlı arama"
|
||||
|
||||
#: netbox/templates/inc/table_controls_htmx.html:20
|
||||
msgid "Saved filter"
|
||||
msgstr ""
|
||||
msgstr "Kaydedilen filtre"
|
||||
|
||||
#: netbox/templates/inc/user_menu.html:23
|
||||
msgid "Django Admin"
|
||||
@ -14163,7 +14165,7 @@ msgstr "50'den fazla"
|
||||
|
||||
#: netbox/utilities/fields.py:30
|
||||
msgid "RGB color in hexadecimal. Example: "
|
||||
msgstr ""
|
||||
msgstr "Onaltılık olarak RGB rengi. Örnek: "
|
||||
|
||||
#: netbox/utilities/fields.py:159
|
||||
#, python-format
|
||||
@ -14477,11 +14479,11 @@ msgstr "Aşağı hareket et"
|
||||
|
||||
#: netbox/utilities/templates/navigation/menu.html:14
|
||||
msgid "Search…"
|
||||
msgstr ""
|
||||
msgstr "Arama..."
|
||||
|
||||
#: netbox/utilities/templates/navigation/menu.html:14
|
||||
msgid "Search NetBox"
|
||||
msgstr ""
|
||||
msgstr "Arama NetBox"
|
||||
|
||||
#: netbox/utilities/templates/widgets/apiselect.html:7
|
||||
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.utils import extend_schema_field
|
||||
from rest_framework import serializers
|
||||
@ -59,6 +59,14 @@ class UserSerializer(ValidatedModelSerializer):
|
||||
'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):
|
||||
"""
|
||||
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.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.core.exceptions import FieldError
|
||||
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']:
|
||||
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):
|
||||
users = DynamicModelMultipleChoiceField(
|
||||
|
@ -1,4 +1,5 @@
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import override_settings
|
||||
from django.urls import reverse
|
||||
|
||||
from core.models import ObjectType
|
||||
@ -93,6 +94,31 @@ class UserTest(APIViewTestCases.APIViewTestCase):
|
||||
user.refresh_from_db()
|
||||
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):
|
||||
model = Group
|
||||
|
@ -1,6 +1,8 @@
|
||||
from django.test import override_settings
|
||||
|
||||
from core.models import ObjectType
|
||||
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(
|
||||
@ -58,6 +60,34 @@ class UserTestCase(
|
||||
'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(
|
||||
ViewTestCases.GetObjectViewTestCase,
|
||||
|
@ -9,9 +9,9 @@ from django.test import override_settings
|
||||
from django.urls import reverse
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APIClient
|
||||
from strawberry.lazy_type import LazyType
|
||||
from strawberry.type import StrawberryList, StrawberryOptional
|
||||
from strawberry.union import StrawberryUnion
|
||||
from strawberry.types.base import StrawberryList, StrawberryOptional
|
||||
from strawberry.types.lazy_type import LazyType
|
||||
from strawberry.types.union import StrawberryUnion
|
||||
|
||||
from core.choices import ObjectChangeActionChoices
|
||||
from core.models import ObjectChange, ObjectType
|
||||
|
@ -20,18 +20,18 @@ feedparser==6.0.11
|
||||
gunicorn==22.0.0
|
||||
Jinja2==3.1.4
|
||||
Markdown==3.6
|
||||
mkdocs-material==9.5.28
|
||||
mkdocstrings[python-legacy]==0.25.1
|
||||
mkdocs-material==9.5.30
|
||||
mkdocstrings[python-legacy]==0.25.2
|
||||
netaddr==1.3.0
|
||||
nh3==0.2.18
|
||||
Pillow==10.4.0
|
||||
psycopg[c,pool]==3.2.1
|
||||
PyYAML==6.0.1
|
||||
requests==2.32.3
|
||||
social-auth-app-django==5.4.1
|
||||
social-auth-app-django==5.4.2
|
||||
social-auth-core==4.5.4
|
||||
strawberry-graphql==0.235.2
|
||||
strawberry-graphql-django==0.46.1
|
||||
strawberry-graphql==0.237.2
|
||||
strawberry-graphql-django==0.47.1
|
||||
svgwrite==1.4.3
|
||||
tablib==3.6.1
|
||||
tzdata==2024.1
|
||||
|
Loading…
Reference in New Issue
Block a user