mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-16 12:12:53 -06:00
* Closes #18811: Match full-form IPv6 addresses in global search * Fix typo
This commit is contained in:
parent
b5421f1cd6
commit
f05897d61a
@ -18,9 +18,22 @@ class Empty(Lookup):
|
|||||||
return f"CAST(LENGTH({sql}) AS BOOLEAN) IS TRUE", params
|
return f"CAST(LENGTH({sql}) AS BOOLEAN) IS TRUE", params
|
||||||
|
|
||||||
|
|
||||||
|
class NetHost(Lookup):
|
||||||
|
"""
|
||||||
|
Similar to ipam.lookups.NetHost, but casts the field to INET.
|
||||||
|
"""
|
||||||
|
lookup_name = 'net_host'
|
||||||
|
|
||||||
|
def as_sql(self, qn, connection):
|
||||||
|
lhs, lhs_params = self.process_lhs(qn, connection)
|
||||||
|
rhs, rhs_params = self.process_rhs(qn, connection)
|
||||||
|
params = lhs_params + rhs_params
|
||||||
|
return 'HOST(CAST(%s AS INET)) = HOST(%s)' % (lhs, rhs), params
|
||||||
|
|
||||||
|
|
||||||
class NetContainsOrEquals(Lookup):
|
class NetContainsOrEquals(Lookup):
|
||||||
"""
|
"""
|
||||||
This lookup has the same functionality as the one from the ipam app except lhs is cast to inet
|
Similar to ipam.lookups.NetContainsOrEquals, but casts the field to INET.
|
||||||
"""
|
"""
|
||||||
lookup_name = 'net_contains_or_equals'
|
lookup_name = 'net_contains_or_equals'
|
||||||
|
|
||||||
@ -32,4 +45,5 @@ class NetContainsOrEquals(Lookup):
|
|||||||
|
|
||||||
|
|
||||||
CharField.register_lookup(Empty)
|
CharField.register_lookup(Empty)
|
||||||
|
CachedValueField.register_lookup(NetHost)
|
||||||
CachedValueField.register_lookup(NetContainsOrEquals)
|
CachedValueField.register_lookup(NetContainsOrEquals)
|
||||||
|
@ -162,6 +162,11 @@ class Aggregate(ContactsMixin, GetAvailablePrefixesMixin, PrimaryModel):
|
|||||||
return self.prefix.version
|
return self.prefix.version
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ipv6_full(self):
|
||||||
|
if self.prefix and self.prefix.version == 6:
|
||||||
|
return netaddr.IPAddress(self.prefix).format(netaddr.ipv6_full)
|
||||||
|
|
||||||
def get_child_prefixes(self):
|
def get_child_prefixes(self):
|
||||||
"""
|
"""
|
||||||
Return all Prefixes within this Aggregate
|
Return all Prefixes within this Aggregate
|
||||||
@ -330,6 +335,11 @@ class Prefix(ContactsMixin, GetAvailablePrefixesMixin, CachedScopeMixin, Primary
|
|||||||
def mask_length(self):
|
def mask_length(self):
|
||||||
return self.prefix.prefixlen if self.prefix else None
|
return self.prefix.prefixlen if self.prefix else None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ipv6_full(self):
|
||||||
|
if self.prefix and self.prefix.version == 6:
|
||||||
|
return netaddr.IPAddress(self.prefix).format(netaddr.ipv6_full)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def depth(self):
|
def depth(self):
|
||||||
return self._depth
|
return self._depth
|
||||||
@ -808,6 +818,11 @@ class IPAddress(ContactsMixin, PrimaryModel):
|
|||||||
self._original_assigned_object_id = self.__dict__.get('assigned_object_id')
|
self._original_assigned_object_id = self.__dict__.get('assigned_object_id')
|
||||||
self._original_assigned_object_type_id = self.__dict__.get('assigned_object_type_id')
|
self._original_assigned_object_type_id = self.__dict__.get('assigned_object_type_id')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ipv6_full(self):
|
||||||
|
if self.address and self.address.version == 6:
|
||||||
|
return netaddr.IPAddress(self.address).format(netaddr.ipv6_full)
|
||||||
|
|
||||||
def get_duplicates(self):
|
def get_duplicates(self):
|
||||||
return IPAddress.objects.filter(
|
return IPAddress.objects.filter(
|
||||||
vrf=self.vrf,
|
vrf=self.vrf,
|
||||||
|
@ -115,11 +115,13 @@ class CachedValueSearchBackend(SearchBackend):
|
|||||||
if lookup in (LookupTypes.STARTSWITH, LookupTypes.ENDSWITH):
|
if lookup in (LookupTypes.STARTSWITH, LookupTypes.ENDSWITH):
|
||||||
# "Starts/ends with" matches are valid only on string values
|
# "Starts/ends with" matches are valid only on string values
|
||||||
query_filter &= Q(type=FieldTypes.STRING)
|
query_filter &= Q(type=FieldTypes.STRING)
|
||||||
elif lookup == LookupTypes.PARTIAL:
|
elif lookup in (LookupTypes.PARTIAL, LookupTypes.EXACT):
|
||||||
try:
|
try:
|
||||||
# If the value looks like an IP address, add an extra match for CIDR values
|
# If the value looks like an IP address, add extra filters for CIDR/INET values
|
||||||
address = str(netaddr.IPNetwork(value.strip()).cidr)
|
address = str(netaddr.IPNetwork(value.strip()).cidr)
|
||||||
query_filter |= Q(type=FieldTypes.CIDR) & Q(value__net_contains_or_equals=address)
|
query_filter |= Q(type=FieldTypes.INET) & Q(value__net_host=address)
|
||||||
|
if lookup == LookupTypes.PARTIAL:
|
||||||
|
query_filter |= Q(type=FieldTypes.CIDR) & Q(value__net_contains_or_equals=address)
|
||||||
except (AddrFormatError, ValueError):
|
except (AddrFormatError, ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user