Merge branch 'main' into feature

This commit is contained in:
Jeremy Stretch
2025-08-12 16:03:45 -04:00
103 changed files with 9682 additions and 8351 deletions

View File

@@ -22,7 +22,7 @@ from utilities.forms.utils import get_field_value
from utilities.forms.widgets import DatePicker, HTMXSelect
from django.utils.safestring import mark_safe
from utilities.templatetags.builtins.filters import bettertitle
from virtualization.models import VMInterface
from virtualization.models import VMInterface, VirtualMachine
__all__ = (
'AggregateForm',
@@ -792,10 +792,6 @@ class ServiceForm(NetBoxModelForm):
queryset=IPAddress.objects.all(),
required=False,
label=_('IP Addresses'),
query_params={
'device_id': '$device',
'virtual_machine_id': '$virtual_machine',
}
)
comments = CommentField()
@@ -824,10 +820,22 @@ class ServiceForm(NetBoxModelForm):
super().__init__(*args, **kwargs)
if (parent_object_type_id := get_field_value(self, 'parent_object_type')):
if parent_object_type_id := get_field_value(self, 'parent_object_type'):
try:
parent_type = ContentType.objects.get(pk=parent_object_type_id)
model = parent_type.model_class()
if model == Device:
self.fields['ipaddresses'].widget.add_query_params({
'device_id': '$parent',
})
elif model == VirtualMachine:
self.fields['ipaddresses'].widget.add_query_params({
'virtual_machine_id': '$parent',
})
elif model == FHRPGroup:
self.fields['ipaddresses'].widget.add_query_params({
'fhrpgroup_id': '$parent',
})
self.fields['parent'].queryset = model.objects.all()
self.fields['parent'].widget.attrs['selector'] = model._meta.label_lower
self.fields['parent'].disabled = False

View File

@@ -222,6 +222,19 @@ class IPRangeFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilterMi
return Q()
return q
@strawberry_django.filter_field()
def contains(self, value: list[str], prefix) -> Q:
if not value:
return Q()
q = Q()
for subnet in value:
net = netaddr.IPNetwork(subnet.strip())
q |= Q(
start_address__host__inet__lte=str(netaddr.IPAddress(net.first)),
end_address__host__inet__gte=str(netaddr.IPAddress(net.last)),
)
return q
@strawberry_django.filter_type(models.Prefix, lookups=True)
class PrefixFilter(ContactFilterMixin, ScopedFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin):
@@ -238,6 +251,16 @@ class PrefixFilter(ContactFilterMixin, ScopedFilterMixin, TenancyFilterMixin, Pr
is_pool: FilterLookup[bool] | None = strawberry_django.filter_field()
mark_utilized: FilterLookup[bool] | None = strawberry_django.filter_field()
@strawberry_django.filter_field()
def contains(self, value: list[str], prefix) -> Q:
if not value:
return Q()
q = Q()
for subnet in value:
query = str(netaddr.IPNetwork(subnet.strip()).cidr)
q |= Q(prefix__net_contains=query)
return q
@strawberry_django.filter_type(models.RIR, lookups=True)
class RIRFilter(OrganizationalModelFilterMixin):

View File

@@ -0,0 +1,20 @@
from django.contrib.postgres.indexes import GistIndex
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('dcim', '0210_macaddress_ordering'),
('extras', '0129_fix_script_paths'),
('ipam', '0081_remove_service_device_virtual_machine_add_parent_gfk_index'),
('tenancy', '0020_remove_contactgroupmembership'),
]
operations = [
migrations.AddIndex(
model_name='prefix',
index=GistIndex(fields=['prefix'], name='ipam_prefix_gist_idx', opclasses=['inet_ops']),
),
]

View File

@@ -1,6 +1,7 @@
import netaddr
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.indexes import GistIndex
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import F
@@ -281,6 +282,13 @@ class Prefix(ContactsMixin, GetAvailablePrefixesMixin, CachedScopeMixin, Primary
ordering = (F('vrf').asc(nulls_first=True), 'prefix', 'pk') # (vrf, prefix) may be non-unique
verbose_name = _('prefix')
verbose_name_plural = _('prefixes')
indexes = [
GistIndex(
fields=['prefix'],
name='ipam_prefix_gist_idx',
opclasses=['inet_ops'],
),
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)