mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-20 10:38:44 -06:00
Compare commits
1 Commits
main
...
15801-vlan
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f468b4bbf |
@@ -40,7 +40,6 @@
|
|||||||
* [#20912](https://github.com/netbox-community/netbox/issues/20912) - Fix inconsistent clearing of `module` field on ModuleBay
|
* [#20912](https://github.com/netbox-community/netbox/issues/20912) - Fix inconsistent clearing of `module` field on ModuleBay
|
||||||
* [#20944](https://github.com/netbox-community/netbox/issues/20944) - Ensure cached scope is updated on child objects when a parent region/site/location is changed
|
* [#20944](https://github.com/netbox-community/netbox/issues/20944) - Ensure cached scope is updated on child objects when a parent region/site/location is changed
|
||||||
* [#20948](https://github.com/netbox-community/netbox/issues/20948) - Handle the deletion of related objects with `on_delete=RESTRICT` the same as `CASCADE`
|
* [#20948](https://github.com/netbox-community/netbox/issues/20948) - Handle the deletion of related objects with `on_delete=RESTRICT` the same as `CASCADE`
|
||||||
* [#20966](https://github.com/netbox-community/netbox/issues/20966) - Fix UI rendering issue when scrolling list of object types in permissions form
|
|
||||||
* [#20969](https://github.com/netbox-community/netbox/issues/20969) - Fix querying of front port templates by `rear_port_id`
|
* [#20969](https://github.com/netbox-community/netbox/issues/20969) - Fix querying of front port templates by `rear_port_id`
|
||||||
* [#21011](https://github.com/netbox-community/netbox/issues/21011) - Avoid writing to the database when loading active ConfigRevision
|
* [#21011](https://github.com/netbox-community/netbox/issues/21011) - Avoid writing to the database when loading active ConfigRevision
|
||||||
* [#21032](https://github.com/netbox-community/netbox/issues/21032) - Avoid SQL subquery in RestrictedQuerySet where unnecessary
|
* [#21032](https://github.com/netbox-community/netbox/issues/21032) - Avoid SQL subquery in RestrictedQuerySet where unnecessary
|
||||||
|
|||||||
@@ -35,10 +35,6 @@ class ObjectTypeQuerySet(models.QuerySet):
|
|||||||
|
|
||||||
class ObjectTypeManager(models.Manager):
|
class ObjectTypeManager(models.Manager):
|
||||||
|
|
||||||
# TODO: Remove this in NetBox v5.0
|
|
||||||
# Cache the result of introspection to avoid repeated queries.
|
|
||||||
_table_exists = False
|
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return ObjectTypeQuerySet(self.model, using=self._db)
|
return ObjectTypeQuerySet(self.model, using=self._db)
|
||||||
|
|
||||||
@@ -73,12 +69,10 @@ class ObjectTypeManager(models.Manager):
|
|||||||
# TODO: Remove this in NetBox v5.0
|
# TODO: Remove this in NetBox v5.0
|
||||||
# If the ObjectType table has not yet been provisioned (e.g. because we're in a pre-v4.4 migration),
|
# If the ObjectType table has not yet been provisioned (e.g. because we're in a pre-v4.4 migration),
|
||||||
# fall back to ContentType.
|
# fall back to ContentType.
|
||||||
if not ObjectTypeManager._table_exists:
|
|
||||||
if 'core_objecttype' not in connection.introspection.table_names():
|
if 'core_objecttype' not in connection.introspection.table_names():
|
||||||
ct = ContentType.objects.get_for_model(model, for_concrete_model=for_concrete_model)
|
ct = ContentType.objects.get_for_model(model, for_concrete_model=for_concrete_model)
|
||||||
ct.features = get_model_features(ct.model_class())
|
ct.features = get_model_features(ct.model_class())
|
||||||
return ct
|
return ct
|
||||||
ObjectTypeManager._table_exists = True
|
|
||||||
|
|
||||||
if not inspect.isclass(model):
|
if not inspect.isclass(model):
|
||||||
model = model.__class__
|
model = model.__class__
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ if TYPE_CHECKING:
|
|||||||
from netbox.graphql.filter_lookups import IntegerLookup
|
from netbox.graphql.filter_lookups import IntegerLookup
|
||||||
from extras.graphql.filters import ConfigTemplateFilter
|
from extras.graphql.filters import ConfigTemplateFilter
|
||||||
from ipam.graphql.filters import VLANFilter, VLANTranslationPolicyFilter
|
from ipam.graphql.filters import VLANFilter, VLANTranslationPolicyFilter
|
||||||
from dcim.graphql.filters import LocationFilter, RegionFilter, SiteFilter, SiteGroupFilter
|
|
||||||
from .filters import *
|
from .filters import *
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@@ -36,20 +35,6 @@ class ScopedFilterMixin:
|
|||||||
)
|
)
|
||||||
scope_id: ID | None = strawberry_django.filter_field()
|
scope_id: ID | None = strawberry_django.filter_field()
|
||||||
|
|
||||||
# Cached relations
|
|
||||||
_location: Annotated['LocationFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
|
|
||||||
strawberry_django.filter_field(name='location')
|
|
||||||
)
|
|
||||||
_region: Annotated['RegionFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
|
|
||||||
strawberry_django.filter_field(name='region')
|
|
||||||
)
|
|
||||||
_site_group: Annotated['SiteGroupFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
|
|
||||||
strawberry_django.filter_field(name='site_group')
|
|
||||||
)
|
|
||||||
_site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
|
|
||||||
strawberry_django.filter_field(name='site')
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ComponentModelFilterMixin:
|
class ComponentModelFilterMixin:
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class RackDimensionsPanel(panels.ObjectAttributesPanel):
|
|||||||
outer_width = attrs.NumericAttr('outer_width', unit_accessor='get_outer_unit_display')
|
outer_width = attrs.NumericAttr('outer_width', unit_accessor='get_outer_unit_display')
|
||||||
outer_height = attrs.NumericAttr('outer_height', unit_accessor='get_outer_unit_display')
|
outer_height = attrs.NumericAttr('outer_height', unit_accessor='get_outer_unit_display')
|
||||||
outer_depth = attrs.NumericAttr('outer_depth', unit_accessor='get_outer_unit_display')
|
outer_depth = attrs.NumericAttr('outer_depth', unit_accessor='get_outer_unit_display')
|
||||||
mounting_depth = attrs.TextAttr('mounting_depth', format_string=_('{} millimeters'))
|
mounting_depth = attrs.TextAttr('mounting_depth', format_string='{} mm')
|
||||||
|
|
||||||
|
|
||||||
class RackNumberingPanel(panels.ObjectAttributesPanel):
|
class RackNumberingPanel(panels.ObjectAttributesPanel):
|
||||||
|
|||||||
@@ -4,17 +4,6 @@ from extras.choices import LogLevelChoices
|
|||||||
# Custom fields
|
# Custom fields
|
||||||
CUSTOMFIELD_EMPTY_VALUES = (None, '', [])
|
CUSTOMFIELD_EMPTY_VALUES = (None, '', [])
|
||||||
|
|
||||||
# ImageAttachment
|
|
||||||
IMAGE_ATTACHMENT_IMAGE_FORMATS = {
|
|
||||||
'avif': 'image/avif',
|
|
||||||
'bmp': 'image/bmp',
|
|
||||||
'gif': 'image/gif',
|
|
||||||
'jpeg': 'image/jpeg',
|
|
||||||
'jpg': 'image/jpeg',
|
|
||||||
'png': 'image/png',
|
|
||||||
'webp': 'image/webp',
|
|
||||||
}
|
|
||||||
|
|
||||||
# Template Export
|
# Template Export
|
||||||
DEFAULT_MIME_TYPE = 'text/plain; charset=utf-8'
|
DEFAULT_MIME_TYPE = 'text/plain; charset=utf-8'
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
from core.forms.mixins import SyncedDataMixin
|
from core.forms.mixins import SyncedDataMixin
|
||||||
from core.models import ObjectType
|
from core.models import ObjectType
|
||||||
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
|
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
|
||||||
from extras.constants import IMAGE_ATTACHMENT_IMAGE_FORMATS
|
|
||||||
from extras.choices import *
|
from extras.choices import *
|
||||||
from extras.models import *
|
from extras.models import *
|
||||||
from netbox.events import get_event_type_choices
|
from netbox.events import get_event_type_choices
|
||||||
@@ -785,11 +784,8 @@ class ImageAttachmentForm(forms.ModelForm):
|
|||||||
fields = [
|
fields = [
|
||||||
'image', 'name', 'description',
|
'image', 'name', 'description',
|
||||||
]
|
]
|
||||||
# Explicitly set 'image/avif' to support AVIF selection in Firefox
|
help_texts = {
|
||||||
widgets = {
|
'name': _("If no name is specified, the file name will be used.")
|
||||||
'image': forms.ClearableFileInput(
|
|
||||||
attrs={'accept': ','.join(sorted(set(IMAGE_ATTACHMENT_IMAGE_FORMATS.values())))}
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ from taggit.managers import _TaggableManager
|
|||||||
|
|
||||||
from netbox.context import current_request
|
from netbox.context import current_request
|
||||||
|
|
||||||
from .constants import IMAGE_ATTACHMENT_IMAGE_FORMATS
|
|
||||||
from .validators import CustomValidator
|
from .validators import CustomValidator
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@@ -79,7 +78,7 @@ def image_upload(instance, filename):
|
|||||||
"""
|
"""
|
||||||
upload_dir = 'image-attachments'
|
upload_dir = 'image-attachments'
|
||||||
default_filename = 'unnamed'
|
default_filename = 'unnamed'
|
||||||
allowed_img_extensions = IMAGE_ATTACHMENT_IMAGE_FORMATS.keys()
|
allowed_img_extensions = ('bmp', 'gif', 'jpeg', 'jpg', 'png', 'webp')
|
||||||
|
|
||||||
# Normalize Windows paths and create a Path object.
|
# Normalize Windows paths and create a Path object.
|
||||||
normalized_filename = str(filename).replace('\\', '/')
|
normalized_filename = str(filename).replace('\\', '/')
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ from ..field_serializers import IPAddressField, IPNetworkField
|
|||||||
__all__ = (
|
__all__ = (
|
||||||
'AggregateSerializer',
|
'AggregateSerializer',
|
||||||
'AvailableIPSerializer',
|
'AvailableIPSerializer',
|
||||||
'AvailableIPRequestSerializer',
|
|
||||||
'AvailablePrefixSerializer',
|
'AvailablePrefixSerializer',
|
||||||
'IPAddressSerializer',
|
'IPAddressSerializer',
|
||||||
'IPRangeSerializer',
|
'IPRangeSerializer',
|
||||||
@@ -148,43 +147,6 @@ class IPRangeSerializer(PrimaryModelSerializer):
|
|||||||
# IP addresses
|
# IP addresses
|
||||||
#
|
#
|
||||||
|
|
||||||
class AvailableIPRequestSerializer(serializers.Serializer):
|
|
||||||
"""
|
|
||||||
Request payload for creating IP addresses from the available-ips endpoint.
|
|
||||||
"""
|
|
||||||
prefix_length = serializers.IntegerField(required=False)
|
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
|
||||||
data = super().to_internal_value(data)
|
|
||||||
|
|
||||||
prefix_length = data.get('prefix_length')
|
|
||||||
if prefix_length is None:
|
|
||||||
# No override requested; the parent prefix/range mask length will be used.
|
|
||||||
return data
|
|
||||||
|
|
||||||
parent = self.context.get('parent')
|
|
||||||
if parent is None:
|
|
||||||
return data
|
|
||||||
|
|
||||||
# Validate the requested prefix length
|
|
||||||
if prefix_length < parent.mask_length:
|
|
||||||
raise serializers.ValidationError({
|
|
||||||
'prefix_length': 'Prefix length must be greater than or equal to the parent mask length ({})'.format(
|
|
||||||
parent.mask_length
|
|
||||||
)
|
|
||||||
})
|
|
||||||
elif parent.family == 4 and prefix_length > 32:
|
|
||||||
raise serializers.ValidationError({
|
|
||||||
'prefix_length': 'Invalid prefix length ({}) for IPv6'.format(prefix_length)
|
|
||||||
})
|
|
||||||
elif parent.family == 6 and prefix_length > 128:
|
|
||||||
raise serializers.ValidationError({
|
|
||||||
'prefix_length': 'Invalid prefix length ({}) for IPv4'.format(prefix_length)
|
|
||||||
})
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
class IPAddressSerializer(PrimaryModelSerializer):
|
class IPAddressSerializer(PrimaryModelSerializer):
|
||||||
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
|
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
|
||||||
address = IPAddressField()
|
address = IPAddressField()
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ class AvailablePrefixesView(AvailableObjectsView):
|
|||||||
class AvailableIPAddressesView(AvailableObjectsView):
|
class AvailableIPAddressesView(AvailableObjectsView):
|
||||||
queryset = IPAddress.objects.all()
|
queryset = IPAddress.objects.all()
|
||||||
read_serializer_class = serializers.AvailableIPSerializer
|
read_serializer_class = serializers.AvailableIPSerializer
|
||||||
write_serializer_class = serializers.AvailableIPRequestSerializer
|
write_serializer_class = serializers.AvailableIPSerializer
|
||||||
advisory_lock_key = 'available-ips'
|
advisory_lock_key = 'available-ips'
|
||||||
|
|
||||||
def get_available_objects(self, parent, limit=None):
|
def get_available_objects(self, parent, limit=None):
|
||||||
@@ -421,9 +421,8 @@ class AvailableIPAddressesView(AvailableObjectsView):
|
|||||||
def prep_object_data(self, requested_objects, available_objects, parent):
|
def prep_object_data(self, requested_objects, available_objects, parent):
|
||||||
available_ips = iter(available_objects)
|
available_ips = iter(available_objects)
|
||||||
for i, request_data in enumerate(requested_objects):
|
for i, request_data in enumerate(requested_objects):
|
||||||
prefix_length = request_data.pop('prefix_length', None) or parent.mask_length
|
|
||||||
request_data.update({
|
request_data.update({
|
||||||
'address': f'{next(available_ips)}/{prefix_length}',
|
'address': f'{next(available_ips)}/{parent.mask_length}',
|
||||||
'vrf': parent.vrf.pk if parent.vrf else None,
|
'vrf': parent.vrf.pk if parent.vrf else None,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -436,7 +435,7 @@ class AvailableIPAddressesView(AvailableObjectsView):
|
|||||||
@extend_schema(
|
@extend_schema(
|
||||||
methods=["post"],
|
methods=["post"],
|
||||||
responses={201: serializers.IPAddressSerializer(many=True)},
|
responses={201: serializers.IPAddressSerializer(many=True)},
|
||||||
request=serializers.AvailableIPRequestSerializer(many=True),
|
request=serializers.IPAddressSerializer(many=True),
|
||||||
)
|
)
|
||||||
def post(self, request, pk):
|
def post(self, request, pk):
|
||||||
return super().post(request, pk)
|
return super().post(request, pk)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin
|
|||||||
from virtualization.models import VMInterface
|
from virtualization.models import VMInterface
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from netbox.graphql.filter_lookups import BigIntegerLookup, IntegerLookup, IntegerRangeArrayLookup
|
from netbox.graphql.filter_lookups import IntegerLookup, IntegerRangeArrayLookup
|
||||||
from circuits.graphql.filters import ProviderFilter
|
from circuits.graphql.filters import ProviderFilter
|
||||||
from core.graphql.filters import ContentTypeFilter
|
from core.graphql.filters import ContentTypeFilter
|
||||||
from dcim.graphql.filters import SiteFilter
|
from dcim.graphql.filters import SiteFilter
|
||||||
@@ -53,7 +53,7 @@ __all__ = (
|
|||||||
class ASNFilter(TenancyFilterMixin, PrimaryModelFilter):
|
class ASNFilter(TenancyFilterMixin, PrimaryModelFilter):
|
||||||
rir: Annotated['RIRFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
|
rir: Annotated['RIRFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
|
||||||
rir_id: ID | None = strawberry_django.filter_field()
|
rir_id: ID | None = strawberry_django.filter_field()
|
||||||
asn: Annotated['BigIntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
asn: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||||
strawberry_django.filter_field()
|
strawberry_django.filter_field()
|
||||||
)
|
)
|
||||||
sites: (
|
sites: (
|
||||||
@@ -70,10 +70,10 @@ class ASNRangeFilter(TenancyFilterMixin, OrganizationalModelFilter):
|
|||||||
slug: FilterLookup[str] | None = strawberry_django.filter_field()
|
slug: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||||
rir: Annotated['RIRFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
|
rir: Annotated['RIRFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
|
||||||
rir_id: ID | None = strawberry_django.filter_field()
|
rir_id: ID | None = strawberry_django.filter_field()
|
||||||
start: Annotated['BigIntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
start: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||||
strawberry_django.filter_field()
|
strawberry_django.filter_field()
|
||||||
)
|
)
|
||||||
end: Annotated['BigIntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
end: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||||
strawberry_django.filter_field()
|
strawberry_django.filter_field()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
from django_tables2.utils import Accessor
|
from django_tables2.utils import Accessor
|
||||||
|
|
||||||
from dcim.models import Interface
|
from dcim.models import Interface
|
||||||
|
from dcim.tables.template_code import INTERFACE_LINKTERMINATION, LINKTERMINATION
|
||||||
from ipam.models import *
|
from ipam.models import *
|
||||||
from netbox.tables import NetBoxTable, OrganizationalModelTable, PrimaryModelTable, columns
|
from netbox.tables import NetBoxTable, OrganizationalModelTable, PrimaryModelTable, columns
|
||||||
from tenancy.tables import TenancyColumnsMixin, TenantColumn
|
from tenancy.tables import TenancyColumnsMixin, TenantColumn
|
||||||
@@ -159,10 +160,25 @@ class VLANDevicesTable(VLANMembersTable):
|
|||||||
actions = columns.ActionsColumn(
|
actions = columns.ActionsColumn(
|
||||||
actions=('edit',)
|
actions=('edit',)
|
||||||
)
|
)
|
||||||
|
link_peer = columns.TemplateColumn(
|
||||||
|
accessor='link_peers',
|
||||||
|
template_code=LINKTERMINATION,
|
||||||
|
orderable=False,
|
||||||
|
verbose_name=_('Link Peers'),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Override PathEndpointTable.connection to accommodate virtual circuits
|
||||||
|
connection = columns.TemplateColumn(
|
||||||
|
accessor='_path__destinations',
|
||||||
|
template_code=INTERFACE_LINKTERMINATION,
|
||||||
|
orderable=False,
|
||||||
|
verbose_name=_('Connection'),
|
||||||
|
)
|
||||||
|
|
||||||
class Meta(NetBoxTable.Meta):
|
class Meta(NetBoxTable.Meta):
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = ('device', 'name', 'tagged', 'actions')
|
fields = ('device', 'name', 'link_peer', 'connection', 'tagged', 'actions')
|
||||||
|
default_columns = ('device', 'name', 'connection', 'tagged', 'actions')
|
||||||
exclude = ('id',)
|
exclude = ('id',)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -595,31 +595,6 @@ class PrefixTest(APIViewTestCases.APIViewTestCase):
|
|||||||
self.assertHttpStatus(response, status.HTTP_201_CREATED)
|
self.assertHttpStatus(response, status.HTTP_201_CREATED)
|
||||||
self.assertEqual(len(response.data), 8)
|
self.assertEqual(len(response.data), 8)
|
||||||
|
|
||||||
def test_create_available_ip_with_mask(self):
|
|
||||||
"""
|
|
||||||
Test the creation of an available IP address with a specific prefix length.
|
|
||||||
"""
|
|
||||||
prefix = Prefix.objects.create(prefix=IPNetwork('192.0.2.0/24'))
|
|
||||||
url = reverse('ipam-api:prefix-available-ips', kwargs={'pk': prefix.pk})
|
|
||||||
self.add_permissions('ipam.view_prefix', 'ipam.add_ipaddress')
|
|
||||||
|
|
||||||
# Create an available IP with a specific prefix length
|
|
||||||
data = {
|
|
||||||
'prefix_length': 32,
|
|
||||||
'description': 'Test IP 1',
|
|
||||||
}
|
|
||||||
response = self.client.post(url, data, format='json', **self.header)
|
|
||||||
self.assertHttpStatus(response, status.HTTP_201_CREATED)
|
|
||||||
self.assertEqual(response.data['address'], '192.0.2.1/32')
|
|
||||||
self.assertEqual(response.data['description'], data['description'])
|
|
||||||
|
|
||||||
# Attempt to create an available IP with a prefix length less than its parent prefix
|
|
||||||
data = {
|
|
||||||
'prefix_length': 23, # Prefix is a /24
|
|
||||||
}
|
|
||||||
response = self.client.post(url, data, format='json', **self.header)
|
|
||||||
self.assertHttpStatus(response, status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
@tag('regression')
|
@tag('regression')
|
||||||
def test_graphql_tenant_prefixes_contains_nested_skips_invalid(self):
|
def test_graphql_tenant_prefixes_contains_nested_skips_invalid(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -19,11 +19,8 @@ from strawberry_django import (
|
|||||||
process_filters,
|
process_filters,
|
||||||
)
|
)
|
||||||
|
|
||||||
from netbox.graphql.scalars import BigInt
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ArrayLookup',
|
'ArrayLookup',
|
||||||
'BigIntegerLookup',
|
|
||||||
'FloatArrayLookup',
|
'FloatArrayLookup',
|
||||||
'FloatLookup',
|
'FloatLookup',
|
||||||
'IntegerArrayLookup',
|
'IntegerArrayLookup',
|
||||||
@@ -81,29 +78,6 @@ class IntegerLookup:
|
|||||||
return process_filters(filters=filters, queryset=queryset, info=info, prefix=prefix)
|
return process_filters(filters=filters, queryset=queryset, info=info, prefix=prefix)
|
||||||
|
|
||||||
|
|
||||||
@strawberry.input(one_of=True, description='Lookup for BigInteger fields. Only one of the lookup fields can be set.')
|
|
||||||
class BigIntegerLookup:
|
|
||||||
filter_lookup: FilterLookup[BigInt] | None = strawberry_django.filter_field()
|
|
||||||
range_lookup: RangeLookup[BigInt] | None = strawberry_django.filter_field()
|
|
||||||
comparison_lookup: ComparisonFilterLookup[BigInt] | None = strawberry_django.filter_field()
|
|
||||||
|
|
||||||
def get_filter(self):
|
|
||||||
for field in self.__strawberry_definition__.fields:
|
|
||||||
value = getattr(self, field.name, None)
|
|
||||||
if value is not strawberry.UNSET:
|
|
||||||
return value
|
|
||||||
return None
|
|
||||||
|
|
||||||
@strawberry_django.filter_field
|
|
||||||
def filter(self, info: Info, queryset: QuerySet, prefix: DirectiveValue[str] = '') -> Tuple[QuerySet, Q]:
|
|
||||||
filters = self.get_filter()
|
|
||||||
|
|
||||||
if not filters:
|
|
||||||
return queryset, Q()
|
|
||||||
|
|
||||||
return process_filters(filters=filters, queryset=queryset, info=info, prefix=prefix)
|
|
||||||
|
|
||||||
|
|
||||||
@strawberry.input(one_of=True, description='Lookup for Float fields. Only one of the lookup fields can be set.')
|
@strawberry.input(one_of=True, description='Lookup for Float fields. Only one of the lookup fields can be set.')
|
||||||
class FloatLookup:
|
class FloatLookup:
|
||||||
filter_lookup: FilterLookup[float] | None = strawberry_django.filter_field()
|
filter_lookup: FilterLookup[float] | None = strawberry_django.filter_field()
|
||||||
|
|||||||
@@ -8,7 +8,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: 2026-01-20 05:07+0000\n"
|
"POT-Creation-Date: 2026-01-17 05:02+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@@ -1279,7 +1279,7 @@ msgid "Term Side"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/circuits/forms/filtersets.py:287 netbox/dcim/forms/bulk_edit.py:1537
|
#: netbox/circuits/forms/filtersets.py:287 netbox/dcim/forms/bulk_edit.py:1537
|
||||||
#: netbox/extras/forms/model_forms.py:697 netbox/ipam/forms/filtersets.py:149
|
#: netbox/extras/forms/model_forms.py:696 netbox/ipam/forms/filtersets.py:149
|
||||||
#: netbox/ipam/forms/filtersets.py:627 netbox/ipam/forms/model_forms.py:326
|
#: netbox/ipam/forms/filtersets.py:627 netbox/ipam/forms/model_forms.py:326
|
||||||
#: netbox/templates/dcim/macaddress.html:25
|
#: netbox/templates/dcim/macaddress.html:25
|
||||||
#: netbox/templates/extras/configcontext.html:36
|
#: netbox/templates/extras/configcontext.html:36
|
||||||
@@ -2172,7 +2172,7 @@ msgstr ""
|
|||||||
msgid "Sync interval"
|
msgid "Sync interval"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/core/forms/bulk_edit.py:33 netbox/extras/forms/model_forms.py:307
|
#: netbox/core/forms/bulk_edit.py:33 netbox/extras/forms/model_forms.py:306
|
||||||
#: netbox/templates/extras/savedfilter.html:56
|
#: netbox/templates/extras/savedfilter.html:56
|
||||||
#: netbox/vpn/forms/filtersets.py:102 netbox/vpn/forms/filtersets.py:132
|
#: netbox/vpn/forms/filtersets.py:102 netbox/vpn/forms/filtersets.py:132
|
||||||
#: netbox/vpn/forms/filtersets.py:156 netbox/vpn/forms/filtersets.py:175
|
#: netbox/vpn/forms/filtersets.py:156 netbox/vpn/forms/filtersets.py:175
|
||||||
@@ -2187,10 +2187,10 @@ msgid "Ignore rules"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/core/forms/filtersets.py:30 netbox/core/forms/model_forms.py:100
|
#: netbox/core/forms/filtersets.py:30 netbox/core/forms/model_forms.py:100
|
||||||
#: netbox/extras/forms/model_forms.py:268
|
#: netbox/extras/forms/model_forms.py:267
|
||||||
#: netbox/extras/forms/model_forms.py:604
|
#: netbox/extras/forms/model_forms.py:603
|
||||||
#: netbox/extras/forms/model_forms.py:693
|
#: netbox/extras/forms/model_forms.py:692
|
||||||
#: netbox/extras/forms/model_forms.py:746 netbox/extras/tables/tables.py:218
|
#: netbox/extras/forms/model_forms.py:745 netbox/extras/tables/tables.py:218
|
||||||
#: netbox/extras/tables/tables.py:588 netbox/extras/tables/tables.py:618
|
#: netbox/extras/tables/tables.py:588 netbox/extras/tables/tables.py:618
|
||||||
#: netbox/extras/tables/tables.py:660 netbox/templates/core/datasource.html:31
|
#: netbox/extras/tables/tables.py:660 netbox/templates/core/datasource.html:31
|
||||||
#: netbox/templates/core/inc/datafile_panel.html:7
|
#: netbox/templates/core/inc/datafile_panel.html:7
|
||||||
@@ -2290,7 +2290,7 @@ msgid "Before"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/core/forms/filtersets.py:155 netbox/core/tables/change_logging.py:29
|
#: netbox/core/forms/filtersets.py:155 netbox/core/tables/change_logging.py:29
|
||||||
#: netbox/extras/forms/model_forms.py:477
|
#: netbox/extras/forms/model_forms.py:476
|
||||||
#: netbox/templates/core/objectchange.html:46
|
#: netbox/templates/core/objectchange.html:46
|
||||||
#: netbox/templates/extras/eventrule.html:71
|
#: netbox/templates/extras/eventrule.html:71
|
||||||
msgid "Action"
|
msgid "Action"
|
||||||
@@ -2360,8 +2360,8 @@ msgid "Pagination"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/core/forms/model_forms.py:166 netbox/extras/forms/bulk_edit.py:96
|
#: netbox/core/forms/model_forms.py:166 netbox/extras/forms/bulk_edit.py:96
|
||||||
#: netbox/extras/forms/filtersets.py:49 netbox/extras/forms/model_forms.py:122
|
#: netbox/extras/forms/filtersets.py:49 netbox/extras/forms/model_forms.py:121
|
||||||
#: netbox/extras/forms/model_forms.py:135
|
#: netbox/extras/forms/model_forms.py:134
|
||||||
#: netbox/templates/core/inc/config_data.html:93
|
#: netbox/templates/core/inc/config_data.html:93
|
||||||
msgid "Validation"
|
msgid "Validation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -4176,9 +4176,9 @@ msgid "Power panel (ID)"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/forms/bulk_create.py:40 netbox/extras/forms/filtersets.py:515
|
#: netbox/dcim/forms/bulk_create.py:40 netbox/extras/forms/filtersets.py:515
|
||||||
#: netbox/extras/forms/model_forms.py:597
|
#: netbox/extras/forms/model_forms.py:596
|
||||||
#: netbox/extras/forms/model_forms.py:682
|
#: netbox/extras/forms/model_forms.py:681
|
||||||
#: netbox/extras/forms/model_forms.py:734 netbox/extras/ui/panels.py:69
|
#: netbox/extras/forms/model_forms.py:733 netbox/extras/ui/panels.py:69
|
||||||
#: netbox/netbox/forms/bulk_import.py:26 netbox/netbox/forms/mixins.py:113
|
#: netbox/netbox/forms/bulk_import.py:26 netbox/netbox/forms/mixins.py:113
|
||||||
#: netbox/netbox/tables/columns.py:490
|
#: netbox/netbox/tables/columns.py:490
|
||||||
#: netbox/templates/circuits/inc/circuit_termination.html:29
|
#: netbox/templates/circuits/inc/circuit_termination.html:29
|
||||||
@@ -4319,7 +4319,7 @@ msgstr ""
|
|||||||
#: netbox/extras/forms/bulk_edit.py:315 netbox/extras/forms/bulk_edit.py:341
|
#: netbox/extras/forms/bulk_edit.py:315 netbox/extras/forms/bulk_edit.py:341
|
||||||
#: netbox/extras/forms/bulk_import.py:275 netbox/extras/forms/filtersets.py:71
|
#: netbox/extras/forms/bulk_import.py:275 netbox/extras/forms/filtersets.py:71
|
||||||
#: netbox/extras/forms/filtersets.py:175 netbox/extras/forms/filtersets.py:279
|
#: netbox/extras/forms/filtersets.py:175 netbox/extras/forms/filtersets.py:279
|
||||||
#: netbox/extras/forms/filtersets.py:315 netbox/extras/forms/model_forms.py:575
|
#: netbox/extras/forms/filtersets.py:315 netbox/extras/forms/model_forms.py:574
|
||||||
#: netbox/ipam/forms/bulk_edit.py:159 netbox/templates/dcim/moduletype.html:51
|
#: netbox/ipam/forms/bulk_edit.py:159 netbox/templates/dcim/moduletype.html:51
|
||||||
#: netbox/templates/extras/configcontext.html:17
|
#: netbox/templates/extras/configcontext.html:17
|
||||||
#: netbox/templates/extras/customlink.html:25
|
#: netbox/templates/extras/customlink.html:25
|
||||||
@@ -4455,7 +4455,7 @@ msgid "Device Type"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/forms/bulk_edit.py:540 netbox/dcim/forms/model_forms.py:400
|
#: netbox/dcim/forms/bulk_edit.py:540 netbox/dcim/forms/model_forms.py:400
|
||||||
#: netbox/dcim/views.py:1578 netbox/extras/forms/model_forms.py:592
|
#: netbox/dcim/views.py:1578 netbox/extras/forms/model_forms.py:591
|
||||||
msgid "Schema"
|
msgid "Schema"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -4464,7 +4464,7 @@ msgstr ""
|
|||||||
#: netbox/dcim/forms/bulk_import.py:1452 netbox/dcim/forms/filtersets.py:679
|
#: netbox/dcim/forms/bulk_import.py:1452 netbox/dcim/forms/filtersets.py:679
|
||||||
#: netbox/dcim/forms/filtersets.py:1197 netbox/dcim/forms/model_forms.py:406
|
#: netbox/dcim/forms/filtersets.py:1197 netbox/dcim/forms/model_forms.py:406
|
||||||
#: netbox/dcim/forms/model_forms.py:419 netbox/dcim/tables/modules.py:42
|
#: netbox/dcim/forms/model_forms.py:419 netbox/dcim/tables/modules.py:42
|
||||||
#: netbox/extras/forms/filtersets.py:437 netbox/extras/forms/model_forms.py:617
|
#: netbox/extras/forms/filtersets.py:437 netbox/extras/forms/model_forms.py:616
|
||||||
#: netbox/extras/tables/tables.py:615 netbox/templates/account/base.html:7
|
#: netbox/extras/tables/tables.py:615 netbox/templates/account/base.html:7
|
||||||
#: netbox/templates/dcim/cable.html:23 netbox/templates/dcim/moduletype.html:27
|
#: netbox/templates/dcim/cable.html:23 netbox/templates/dcim/moduletype.html:27
|
||||||
#: netbox/templates/extras/configcontext.html:21
|
#: netbox/templates/extras/configcontext.html:21
|
||||||
@@ -5600,7 +5600,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: netbox/dcim/forms/filtersets.py:1572 netbox/extras/forms/bulk_edit.py:421
|
#: netbox/dcim/forms/filtersets.py:1572 netbox/extras/forms/bulk_edit.py:421
|
||||||
#: netbox/extras/forms/bulk_import.py:298 netbox/extras/forms/filtersets.py:616
|
#: netbox/extras/forms/bulk_import.py:298 netbox/extras/forms/filtersets.py:616
|
||||||
#: netbox/extras/forms/model_forms.py:798 netbox/extras/tables/tables.py:743
|
#: netbox/extras/forms/model_forms.py:794 netbox/extras/tables/tables.py:743
|
||||||
#: netbox/templates/extras/journalentry.html:30
|
#: netbox/templates/extras/journalentry.html:30
|
||||||
msgid "Kind"
|
msgid "Kind"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -5745,7 +5745,7 @@ msgid ""
|
|||||||
"hyphen."
|
"hyphen."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/forms/model_forms.py:402 netbox/extras/forms/model_forms.py:594
|
#: netbox/dcim/forms/model_forms.py:402 netbox/extras/forms/model_forms.py:593
|
||||||
msgid "Enter a valid JSON schema to define supported attributes."
|
msgid "Enter a valid JSON schema to define supported attributes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -7610,7 +7610,7 @@ msgid "VMs"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/devices.py:103 netbox/dcim/tables/devices.py:223
|
#: netbox/dcim/tables/devices.py:103 netbox/dcim/tables/devices.py:223
|
||||||
#: netbox/extras/forms/model_forms.py:745
|
#: netbox/extras/forms/model_forms.py:744
|
||||||
#: netbox/templates/dcim/devicerole.html:48
|
#: netbox/templates/dcim/devicerole.html:48
|
||||||
#: netbox/templates/dcim/platform.html:45
|
#: netbox/templates/dcim/platform.html:45
|
||||||
#: netbox/templates/extras/configtemplate.html:10
|
#: netbox/templates/extras/configtemplate.html:10
|
||||||
@@ -7842,7 +7842,7 @@ msgid "Module Types"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/devicetypes.py:57 netbox/extras/forms/filtersets.py:485
|
#: netbox/dcim/tables/devicetypes.py:57 netbox/extras/forms/filtersets.py:485
|
||||||
#: netbox/extras/forms/model_forms.py:652 netbox/extras/tables/tables.py:703
|
#: netbox/extras/forms/model_forms.py:651 netbox/extras/tables/tables.py:703
|
||||||
#: netbox/netbox/navigation/menu.py:78
|
#: netbox/netbox/navigation/menu.py:78
|
||||||
msgid "Platforms"
|
msgid "Platforms"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -8000,7 +8000,7 @@ msgid "Space"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/tables/sites.py:21 netbox/dcim/tables/sites.py:40
|
#: netbox/dcim/tables/sites.py:21 netbox/dcim/tables/sites.py:40
|
||||||
#: netbox/extras/forms/filtersets.py:465 netbox/extras/forms/model_forms.py:632
|
#: netbox/extras/forms/filtersets.py:465 netbox/extras/forms/model_forms.py:631
|
||||||
#: netbox/ipam/forms/bulk_edit.py:112 netbox/ipam/forms/model_forms.py:154
|
#: netbox/ipam/forms/bulk_edit.py:112 netbox/ipam/forms/model_forms.py:154
|
||||||
#: netbox/ipam/tables/asn.py:76 netbox/netbox/navigation/menu.py:15
|
#: netbox/ipam/tables/asn.py:76 netbox/netbox/navigation/menu.py:15
|
||||||
#: netbox/netbox/navigation/menu.py:19
|
#: netbox/netbox/navigation/menu.py:19
|
||||||
@@ -8015,10 +8015,6 @@ msgstr ""
|
|||||||
msgid "Test case must set peer_termination_type"
|
msgid "Test case must set peer_termination_type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/ui/panels.py:34
|
|
||||||
msgid "{} millimeters"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: netbox/dcim/ui/panels.py:53 netbox/dcim/ui/panels.py:96
|
#: netbox/dcim/ui/panels.py:53 netbox/dcim/ui/panels.py:96
|
||||||
#: netbox/virtualization/forms/filtersets.py:198
|
#: netbox/virtualization/forms/filtersets.py:198
|
||||||
msgid "Serial number"
|
msgid "Serial number"
|
||||||
@@ -8083,7 +8079,7 @@ msgid "Application Services"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/dcim/views.py:2677 netbox/extras/forms/filtersets.py:427
|
#: netbox/dcim/views.py:2677 netbox/extras/forms/filtersets.py:427
|
||||||
#: netbox/extras/forms/model_forms.py:692
|
#: netbox/extras/forms/model_forms.py:691
|
||||||
#: netbox/templates/extras/configcontext.html:10
|
#: netbox/templates/extras/configcontext.html:10
|
||||||
#: netbox/virtualization/forms/model_forms.py:225
|
#: netbox/virtualization/forms/model_forms.py:225
|
||||||
#: netbox/virtualization/views.py:399
|
#: netbox/virtualization/views.py:399
|
||||||
@@ -8319,13 +8315,13 @@ msgstr ""
|
|||||||
msgid "White"
|
msgid "White"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/choices.py:249 netbox/extras/forms/model_forms.py:434
|
#: netbox/extras/choices.py:249 netbox/extras/forms/model_forms.py:433
|
||||||
#: netbox/extras/forms/model_forms.py:511
|
#: netbox/extras/forms/model_forms.py:510
|
||||||
#: netbox/templates/extras/webhook.html:10
|
#: netbox/templates/extras/webhook.html:10
|
||||||
msgid "Webhook"
|
msgid "Webhook"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/choices.py:250 netbox/extras/forms/model_forms.py:499
|
#: netbox/extras/choices.py:250 netbox/extras/forms/model_forms.py:498
|
||||||
#: netbox/templates/extras/script/base.html:29
|
#: netbox/templates/extras/script/base.html:29
|
||||||
msgid "Script"
|
msgid "Script"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -8505,7 +8501,7 @@ msgstr ""
|
|||||||
msgid "Tenant group (slug)"
|
msgid "Tenant group (slug)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/filtersets.py:779 netbox/extras/forms/model_forms.py:580
|
#: netbox/extras/filtersets.py:779 netbox/extras/forms/model_forms.py:579
|
||||||
#: netbox/templates/extras/tag.html:11
|
#: netbox/templates/extras/tag.html:11
|
||||||
msgid "Tag"
|
msgid "Tag"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -8562,7 +8558,7 @@ msgid "Validation regex"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/bulk_edit.py:95 netbox/extras/forms/filtersets.py:48
|
#: netbox/extras/forms/bulk_edit.py:95 netbox/extras/forms/filtersets.py:48
|
||||||
#: netbox/extras/forms/model_forms.py:82
|
#: netbox/extras/forms/model_forms.py:81
|
||||||
#: netbox/templates/extras/customfield.html:70
|
#: netbox/templates/extras/customfield.html:70
|
||||||
msgid "Behavior"
|
msgid "Behavior"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -8627,7 +8623,7 @@ msgid "CA file path"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/bulk_edit.py:289 netbox/extras/forms/bulk_import.py:231
|
#: netbox/extras/forms/bulk_edit.py:289 netbox/extras/forms/bulk_import.py:231
|
||||||
#: netbox/extras/forms/model_forms.py:458
|
#: netbox/extras/forms/model_forms.py:457
|
||||||
msgid "Event types"
|
msgid "Event types"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -8646,12 +8642,12 @@ msgstr ""
|
|||||||
#: netbox/extras/forms/bulk_import.py:225
|
#: netbox/extras/forms/bulk_import.py:225
|
||||||
#: netbox/extras/forms/bulk_import.py:279 netbox/extras/forms/filtersets.py:54
|
#: netbox/extras/forms/bulk_import.py:279 netbox/extras/forms/filtersets.py:54
|
||||||
#: netbox/extras/forms/filtersets.py:156 netbox/extras/forms/filtersets.py:260
|
#: netbox/extras/forms/filtersets.py:156 netbox/extras/forms/filtersets.py:260
|
||||||
#: netbox/extras/forms/filtersets.py:296 netbox/extras/forms/model_forms.py:53
|
#: netbox/extras/forms/filtersets.py:296 netbox/extras/forms/model_forms.py:52
|
||||||
#: netbox/extras/forms/model_forms.py:225
|
#: netbox/extras/forms/model_forms.py:224
|
||||||
#: netbox/extras/forms/model_forms.py:257
|
#: netbox/extras/forms/model_forms.py:256
|
||||||
#: netbox/extras/forms/model_forms.py:300
|
#: netbox/extras/forms/model_forms.py:299
|
||||||
#: netbox/extras/forms/model_forms.py:453
|
#: netbox/extras/forms/model_forms.py:452
|
||||||
#: netbox/extras/forms/model_forms.py:570 netbox/users/forms/model_forms.py:323
|
#: netbox/extras/forms/model_forms.py:569 netbox/users/forms/model_forms.py:323
|
||||||
msgid "Object types"
|
msgid "Object types"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -8669,9 +8665,9 @@ msgid "Field data type (e.g. text, integer, etc.)"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/bulk_import.py:48 netbox/extras/forms/filtersets.py:243
|
#: netbox/extras/forms/bulk_import.py:48 netbox/extras/forms/filtersets.py:243
|
||||||
#: netbox/extras/forms/filtersets.py:356 netbox/extras/forms/model_forms.py:326
|
#: netbox/extras/forms/filtersets.py:356 netbox/extras/forms/model_forms.py:325
|
||||||
#: netbox/extras/forms/model_forms.py:385
|
#: netbox/extras/forms/model_forms.py:384
|
||||||
#: netbox/extras/forms/model_forms.py:422
|
#: netbox/extras/forms/model_forms.py:421
|
||||||
#: netbox/tenancy/forms/filtersets.py:111
|
#: netbox/tenancy/forms/filtersets.py:111
|
||||||
msgid "Object type"
|
msgid "Object type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -8737,8 +8733,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/bulk_import.py:195
|
#: netbox/extras/forms/bulk_import.py:195
|
||||||
#: netbox/extras/forms/model_forms.py:292
|
#: netbox/extras/forms/model_forms.py:291
|
||||||
#: netbox/extras/forms/model_forms.py:773
|
#: netbox/extras/forms/model_forms.py:772
|
||||||
msgid "Must specify either local content or a data file"
|
msgid "Must specify either local content or a data file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -8783,7 +8779,7 @@ msgid "Comments"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/bulk_import.py:316
|
#: netbox/extras/forms/bulk_import.py:316
|
||||||
#: netbox/extras/forms/model_forms.py:401 netbox/netbox/navigation/menu.py:414
|
#: netbox/extras/forms/model_forms.py:400 netbox/netbox/navigation/menu.py:414
|
||||||
#: netbox/templates/extras/notificationgroup.html:41
|
#: netbox/templates/extras/notificationgroup.html:41
|
||||||
#: netbox/templates/users/group.html:29 netbox/templates/users/owner.html:46
|
#: netbox/templates/users/group.html:29 netbox/templates/users/owner.html:46
|
||||||
#: netbox/users/forms/filtersets.py:181 netbox/users/forms/model_forms.py:262
|
#: netbox/users/forms/filtersets.py:181 netbox/users/forms/model_forms.py:262
|
||||||
@@ -8798,7 +8794,7 @@ msgid "User names separated by commas, encased with double quotes"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/bulk_import.py:323
|
#: netbox/extras/forms/bulk_import.py:323
|
||||||
#: netbox/extras/forms/model_forms.py:396 netbox/netbox/navigation/menu.py:295
|
#: netbox/extras/forms/model_forms.py:395 netbox/netbox/navigation/menu.py:295
|
||||||
#: netbox/netbox/navigation/menu.py:434
|
#: netbox/netbox/navigation/menu.py:434
|
||||||
#: netbox/templates/extras/notificationgroup.html:31
|
#: netbox/templates/extras/notificationgroup.html:31
|
||||||
#: netbox/templates/tenancy/contact.html:21
|
#: netbox/templates/tenancy/contact.html:21
|
||||||
@@ -8820,7 +8816,7 @@ msgstr ""
|
|||||||
msgid "Type Options"
|
msgid "Type Options"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:59 netbox/extras/forms/model_forms.py:62
|
#: netbox/extras/forms/filtersets.py:59 netbox/extras/forms/model_forms.py:61
|
||||||
msgid "Related object type"
|
msgid "Related object type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -8828,7 +8824,7 @@ msgstr ""
|
|||||||
msgid "Field type"
|
msgid "Field type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:133 netbox/extras/forms/model_forms.py:163
|
#: netbox/extras/forms/filtersets.py:133 netbox/extras/forms/model_forms.py:162
|
||||||
#: netbox/extras/tables/tables.py:97
|
#: netbox/extras/tables/tables.py:97
|
||||||
#: netbox/templates/generic/bulk_import.html:185
|
#: netbox/templates/generic/bulk_import.html:185
|
||||||
msgid "Choices"
|
msgid "Choices"
|
||||||
@@ -8836,14 +8832,14 @@ msgstr ""
|
|||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:189 netbox/extras/forms/filtersets.py:406
|
#: netbox/extras/forms/filtersets.py:189 netbox/extras/forms/filtersets.py:406
|
||||||
#: netbox/extras/forms/filtersets.py:428 netbox/extras/forms/filtersets.py:528
|
#: netbox/extras/forms/filtersets.py:428 netbox/extras/forms/filtersets.py:528
|
||||||
#: netbox/extras/forms/model_forms.py:687 netbox/templates/core/job.html:69
|
#: netbox/extras/forms/model_forms.py:686 netbox/templates/core/job.html:69
|
||||||
#: netbox/templates/extras/eventrule.html:84
|
#: netbox/templates/extras/eventrule.html:84
|
||||||
msgid "Data"
|
msgid "Data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:190 netbox/extras/forms/filtersets.py:529
|
#: netbox/extras/forms/filtersets.py:190 netbox/extras/forms/filtersets.py:529
|
||||||
#: netbox/extras/forms/model_forms.py:270
|
#: netbox/extras/forms/model_forms.py:269
|
||||||
#: netbox/extras/forms/model_forms.py:748
|
#: netbox/extras/forms/model_forms.py:747
|
||||||
msgid "Rendering"
|
msgid "Rendering"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -8871,37 +8867,37 @@ msgstr ""
|
|||||||
msgid "Allowed object type"
|
msgid "Allowed object type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:455 netbox/extras/forms/model_forms.py:622
|
#: netbox/extras/forms/filtersets.py:455 netbox/extras/forms/model_forms.py:621
|
||||||
#: netbox/netbox/navigation/menu.py:17
|
#: netbox/netbox/navigation/menu.py:17
|
||||||
msgid "Regions"
|
msgid "Regions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:460 netbox/extras/forms/model_forms.py:627
|
#: netbox/extras/forms/filtersets.py:460 netbox/extras/forms/model_forms.py:626
|
||||||
msgid "Site groups"
|
msgid "Site groups"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:470 netbox/extras/forms/model_forms.py:637
|
#: netbox/extras/forms/filtersets.py:470 netbox/extras/forms/model_forms.py:636
|
||||||
#: netbox/netbox/navigation/menu.py:20
|
#: netbox/netbox/navigation/menu.py:20
|
||||||
msgid "Locations"
|
msgid "Locations"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:475 netbox/extras/forms/model_forms.py:642
|
#: netbox/extras/forms/filtersets.py:475 netbox/extras/forms/model_forms.py:641
|
||||||
msgid "Device types"
|
msgid "Device types"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:480 netbox/extras/forms/model_forms.py:647
|
#: netbox/extras/forms/filtersets.py:480 netbox/extras/forms/model_forms.py:646
|
||||||
msgid "Roles"
|
msgid "Roles"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:490 netbox/extras/forms/model_forms.py:657
|
#: netbox/extras/forms/filtersets.py:490 netbox/extras/forms/model_forms.py:656
|
||||||
msgid "Cluster types"
|
msgid "Cluster types"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:495 netbox/extras/forms/model_forms.py:662
|
#: netbox/extras/forms/filtersets.py:495 netbox/extras/forms/model_forms.py:661
|
||||||
msgid "Cluster groups"
|
msgid "Cluster groups"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:500 netbox/extras/forms/model_forms.py:667
|
#: netbox/extras/forms/filtersets.py:500 netbox/extras/forms/model_forms.py:666
|
||||||
#: netbox/netbox/navigation/menu.py:264 netbox/netbox/navigation/menu.py:266
|
#: netbox/netbox/navigation/menu.py:264 netbox/netbox/navigation/menu.py:266
|
||||||
#: netbox/templates/virtualization/clustertype.html:30
|
#: netbox/templates/virtualization/clustertype.html:30
|
||||||
#: netbox/virtualization/tables/clusters.py:23
|
#: netbox/virtualization/tables/clusters.py:23
|
||||||
@@ -8909,179 +8905,183 @@ msgstr ""
|
|||||||
msgid "Clusters"
|
msgid "Clusters"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/filtersets.py:505 netbox/extras/forms/model_forms.py:672
|
#: netbox/extras/forms/filtersets.py:505 netbox/extras/forms/model_forms.py:671
|
||||||
msgid "Tenant groups"
|
msgid "Tenant groups"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:55
|
#: netbox/extras/forms/model_forms.py:54
|
||||||
msgid "The type(s) of object that have this custom field"
|
msgid "The type(s) of object that have this custom field"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:58
|
#: netbox/extras/forms/model_forms.py:57
|
||||||
msgid "Default value"
|
msgid "Default value"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:64
|
#: netbox/extras/forms/model_forms.py:63
|
||||||
msgid "Type of the related object (for object/multi-object fields only)"
|
msgid "Type of the related object (for object/multi-object fields only)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:67
|
#: netbox/extras/forms/model_forms.py:66
|
||||||
#: netbox/templates/extras/customfield.html:60
|
#: netbox/templates/extras/customfield.html:60
|
||||||
msgid "Related object filter"
|
msgid "Related object filter"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:69
|
#: netbox/extras/forms/model_forms.py:68
|
||||||
msgid "Specify query parameters as a JSON object."
|
msgid "Specify query parameters as a JSON object."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:79
|
#: netbox/extras/forms/model_forms.py:78
|
||||||
#: netbox/templates/extras/customfield.html:10
|
#: netbox/templates/extras/customfield.html:10
|
||||||
msgid "Custom Field"
|
msgid "Custom Field"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:91
|
#: netbox/extras/forms/model_forms.py:90
|
||||||
msgid ""
|
msgid ""
|
||||||
"The type of data stored in this field. For object/multi-object fields, "
|
"The type of data stored in this field. For object/multi-object fields, "
|
||||||
"select the related object type below."
|
"select the related object type below."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:94
|
#: netbox/extras/forms/model_forms.py:93
|
||||||
msgid ""
|
msgid ""
|
||||||
"This will be displayed as help text for the form field. Markdown is "
|
"This will be displayed as help text for the form field. Markdown is "
|
||||||
"supported."
|
"supported."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:149
|
#: netbox/extras/forms/model_forms.py:148
|
||||||
msgid "Related Object"
|
msgid "Related Object"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:176
|
#: netbox/extras/forms/model_forms.py:175
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enter one choice per line. An optional label may be specified for each "
|
"Enter one choice per line. An optional label may be specified for each "
|
||||||
"choice by appending it with a colon. Example:"
|
"choice by appending it with a colon. Example:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:232
|
#: netbox/extras/forms/model_forms.py:231
|
||||||
#: netbox/templates/extras/customlink.html:10
|
#: netbox/templates/extras/customlink.html:10
|
||||||
msgid "Custom Link"
|
msgid "Custom Link"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:234
|
#: netbox/extras/forms/model_forms.py:233
|
||||||
msgid "Templates"
|
msgid "Templates"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:246
|
#: netbox/extras/forms/model_forms.py:245
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Jinja2 template code for the link text. Reference the object as {example}. "
|
"Jinja2 template code for the link text. Reference the object as {example}. "
|
||||||
"Links which render as empty text will not be displayed."
|
"Links which render as empty text will not be displayed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:250
|
#: netbox/extras/forms/model_forms.py:249
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Jinja2 template code for the link URL. Reference the object as {example}."
|
"Jinja2 template code for the link URL. Reference the object as {example}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:261
|
#: netbox/extras/forms/model_forms.py:260
|
||||||
#: netbox/extras/forms/model_forms.py:739
|
#: netbox/extras/forms/model_forms.py:738
|
||||||
msgid "Template code"
|
msgid "Template code"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:267
|
#: netbox/extras/forms/model_forms.py:266
|
||||||
#: netbox/templates/extras/exporttemplate.html:12
|
#: netbox/templates/extras/exporttemplate.html:12
|
||||||
msgid "Export Template"
|
msgid "Export Template"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:285
|
#: netbox/extras/forms/model_forms.py:284
|
||||||
#: netbox/extras/forms/model_forms.py:766
|
#: netbox/extras/forms/model_forms.py:765
|
||||||
msgid "Template content is populated from the remote source selected below."
|
msgid "Template content is populated from the remote source selected below."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:306 netbox/netbox/forms/mixins.py:92
|
#: netbox/extras/forms/model_forms.py:305 netbox/netbox/forms/mixins.py:92
|
||||||
#: netbox/templates/extras/savedfilter.html:10
|
#: netbox/templates/extras/savedfilter.html:10
|
||||||
msgid "Saved Filter"
|
msgid "Saved Filter"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:332
|
#: netbox/extras/forms/model_forms.py:331
|
||||||
#: netbox/templates/account/preferences.html:50
|
#: netbox/templates/account/preferences.html:50
|
||||||
#: netbox/templates/extras/tableconfig.html:62
|
#: netbox/templates/extras/tableconfig.html:62
|
||||||
msgid "Ordering"
|
msgid "Ordering"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:334
|
#: netbox/extras/forms/model_forms.py:333
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enter a comma-separated list of column names. Prepend a name with a hyphen "
|
"Enter a comma-separated list of column names. Prepend a name with a hyphen "
|
||||||
"to reverse the order."
|
"to reverse the order."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:343 netbox/utilities/forms/forms.py:164
|
#: netbox/extras/forms/model_forms.py:342 netbox/utilities/forms/forms.py:164
|
||||||
msgid "Available Columns"
|
msgid "Available Columns"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:350 netbox/utilities/forms/forms.py:172
|
#: netbox/extras/forms/model_forms.py:349 netbox/utilities/forms/forms.py:172
|
||||||
msgid "Selected Columns"
|
msgid "Selected Columns"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:415
|
#: netbox/extras/forms/model_forms.py:414
|
||||||
msgid "A notification group specify at least one user or group."
|
msgid "A notification group specify at least one user or group."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:437
|
#: netbox/extras/forms/model_forms.py:436
|
||||||
#: netbox/templates/extras/webhook.html:23
|
#: netbox/templates/extras/webhook.html:23
|
||||||
msgid "HTTP Request"
|
msgid "HTTP Request"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:439
|
#: netbox/extras/forms/model_forms.py:438
|
||||||
#: netbox/templates/extras/webhook.html:44
|
#: netbox/templates/extras/webhook.html:44
|
||||||
msgid "SSL"
|
msgid "SSL"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:461
|
#: netbox/extras/forms/model_forms.py:460
|
||||||
msgid "Action choice"
|
msgid "Action choice"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:466
|
#: netbox/extras/forms/model_forms.py:465
|
||||||
msgid "Enter conditions in <a href=\"https://json.org/\">JSON</a> format."
|
msgid "Enter conditions in <a href=\"https://json.org/\">JSON</a> format."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:470
|
#: netbox/extras/forms/model_forms.py:469
|
||||||
msgid ""
|
msgid ""
|
||||||
"Enter parameters to pass to the action in <a href=\"https://json.org/"
|
"Enter parameters to pass to the action in <a href=\"https://json.org/"
|
||||||
"\">JSON</a> format."
|
"\">JSON</a> format."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:475
|
#: netbox/extras/forms/model_forms.py:474
|
||||||
#: netbox/templates/extras/eventrule.html:10
|
#: netbox/templates/extras/eventrule.html:10
|
||||||
msgid "Event Rule"
|
msgid "Event Rule"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:476
|
#: netbox/extras/forms/model_forms.py:475
|
||||||
msgid "Triggers"
|
msgid "Triggers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:523
|
#: netbox/extras/forms/model_forms.py:522
|
||||||
msgid "Notification group"
|
msgid "Notification group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:603
|
#: netbox/extras/forms/model_forms.py:602
|
||||||
#: netbox/templates/extras/configcontextprofile.html:10
|
#: netbox/templates/extras/configcontextprofile.html:10
|
||||||
msgid "Config Context Profile"
|
msgid "Config Context Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:677 netbox/netbox/navigation/menu.py:26
|
#: netbox/extras/forms/model_forms.py:676 netbox/netbox/navigation/menu.py:26
|
||||||
#: netbox/tenancy/tables/tenants.py:18
|
#: netbox/tenancy/tables/tenants.py:18
|
||||||
msgid "Tenants"
|
msgid "Tenants"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:721
|
#: netbox/extras/forms/model_forms.py:720
|
||||||
msgid "Data is populated from the remote source selected below."
|
msgid "Data is populated from the remote source selected below."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/model_forms.py:727
|
#: netbox/extras/forms/model_forms.py:726
|
||||||
msgid "Must specify either local data or a data file"
|
msgid "Must specify either local data or a data file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: netbox/extras/forms/model_forms.py:788
|
||||||
|
msgid "If no name is specified, the file name will be used."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: netbox/extras/forms/reports.py:17 netbox/extras/forms/scripts.py:25
|
#: netbox/extras/forms/reports.py:17 netbox/extras/forms/scripts.py:25
|
||||||
msgid "Schedule at"
|
msgid "Schedule at"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ import string
|
|||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
|
|
||||||
OBJECTPERMISSION_OBJECT_TYPES = (
|
OBJECTPERMISSION_OBJECT_TYPES = Q(
|
||||||
(Q(public=True) & ~Q(app_label='core', model='objecttype'))
|
~Q(app_label__in=['account', 'admin', 'auth', 'contenttypes', 'sessions', 'taggit', 'users']) |
|
||||||
| Q(app_label='core', model__in=['managedfile'])
|
Q(app_label='users', model__in=['objectpermission', 'token', 'group', 'user', 'owner'])
|
||||||
| Q(app_label='extras', model__in=['scriptmodule', 'taggeditem'])
|
|
||||||
)
|
)
|
||||||
|
|
||||||
CONSTRAINT_TOKEN_USER = '$user'
|
CONSTRAINT_TOKEN_USER = '$user'
|
||||||
|
|||||||
@@ -5,11 +5,9 @@ from django.conf import settings
|
|||||||
from django.contrib.auth.mixins import AccessMixin
|
from django.contrib.auth.mixins import AccessMixin
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db.models import QuerySet
|
from django.db.models import QuerySet
|
||||||
from django.http import HttpResponseForbidden
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.urls.exceptions import NoReverseMatch
|
from django.urls.exceptions import NoReverseMatch
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from rest_framework.exceptions import AuthenticationFailed
|
|
||||||
|
|
||||||
from netbox.api.authentication import TokenAuthentication
|
from netbox.api.authentication import TokenAuthentication
|
||||||
from netbox.plugins import PluginConfig
|
from netbox.plugins import PluginConfig
|
||||||
@@ -52,12 +50,10 @@ class TokenConditionalLoginRequiredMixin(ConditionalLoginRequiredMixin):
|
|||||||
# Attempt to authenticate the user using a DRF token, if provided
|
# Attempt to authenticate the user using a DRF token, if provided
|
||||||
if settings.LOGIN_REQUIRED and not request.user.is_authenticated:
|
if settings.LOGIN_REQUIRED and not request.user.is_authenticated:
|
||||||
authenticator = TokenAuthentication()
|
authenticator = TokenAuthentication()
|
||||||
try:
|
auth_info = authenticator.authenticate(request)
|
||||||
if (auth_info := authenticator.authenticate(request)) is not None:
|
if auth_info is not None:
|
||||||
request.user = auth_info[0] # User object
|
request.user = auth_info[0] # User object
|
||||||
request.auth = auth_info[1]
|
request.auth = auth_info[1]
|
||||||
except AuthenticationFailed:
|
|
||||||
return HttpResponseForbidden("Invalid token")
|
|
||||||
|
|
||||||
return super().dispatch(request, *args, **kwargs)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from vpn import models
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from core.graphql.filters import ContentTypeFilter
|
from core.graphql.filters import ContentTypeFilter
|
||||||
from ipam.graphql.filters import IPAddressFilter, RouteTargetFilter
|
from ipam.graphql.filters import IPAddressFilter, RouteTargetFilter
|
||||||
from netbox.graphql.filter_lookups import BigIntegerLookup, IntegerLookup
|
from netbox.graphql.filter_lookups import IntegerLookup
|
||||||
from .enums import *
|
from .enums import *
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@@ -75,7 +75,7 @@ class TunnelFilter(TenancyFilterMixin, PrimaryModelFilter):
|
|||||||
ipsec_profile: Annotated['IPSecProfileFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
|
ipsec_profile: Annotated['IPSecProfileFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
|
||||||
strawberry_django.filter_field()
|
strawberry_django.filter_field()
|
||||||
)
|
)
|
||||||
tunnel_id: Annotated['BigIntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
tunnel_id: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||||
strawberry_django.filter_field()
|
strawberry_django.filter_field()
|
||||||
)
|
)
|
||||||
terminations: Annotated['TunnelTerminationFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
|
terminations: Annotated['TunnelTerminationFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
|
||||||
@@ -187,7 +187,7 @@ class L2VPNFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilter):
|
|||||||
type: BaseFilterLookup[Annotated['L2VPNTypeEnum', strawberry.lazy('vpn.graphql.enums')]] | None = (
|
type: BaseFilterLookup[Annotated['L2VPNTypeEnum', strawberry.lazy('vpn.graphql.enums')]] | None = (
|
||||||
strawberry_django.filter_field()
|
strawberry_django.filter_field()
|
||||||
)
|
)
|
||||||
identifier: Annotated['BigIntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
identifier: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||||
strawberry_django.filter_field()
|
strawberry_django.filter_field()
|
||||||
)
|
)
|
||||||
import_targets: Annotated['RouteTargetFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
|
import_targets: Annotated['RouteTargetFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
|
||||||
|
|||||||
Reference in New Issue
Block a user