Merge branch 'main' into feature

This commit is contained in:
Jeremy Stretch
2025-04-22 16:36:17 -04:00
79 changed files with 12134 additions and 12015 deletions

View File

@@ -1,10 +1,11 @@
from django import forms
from django.utils.translation import gettext_lazy as _
from dcim.choices import *
from dcim.models import Device, DeviceRole, Location, Platform, Region, Site, SiteGroup
from extras.forms import LocalConfigContextFilterForm
from extras.models import ConfigTemplate
from ipam.models import VRF
from ipam.models import VRF, VLANTranslationPolicy
from netbox.forms import NetBoxModelFilterSetForm
from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES
@@ -200,7 +201,9 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
fieldsets = (
FieldSet('q', 'filter_id', 'tag'),
FieldSet('cluster_id', 'virtual_machine_id', name=_('Virtual Machine')),
FieldSet('enabled', 'mac_address', 'vrf_id', 'l2vpn_id', name=_('Attributes')),
FieldSet('enabled', name=_('Attributes')),
FieldSet('vrf_id', 'l2vpn_id', 'mac_address', name=_('Addressing')),
FieldSet('mode', 'vlan_translation_policy_id', name=_('802.1Q Switching')),
)
selector_fields = ('filter_id', 'q', 'virtual_machine_id')
cluster_id = DynamicModelMultipleChoiceField(
@@ -237,6 +240,16 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
required=False,
label=_('L2VPN')
)
mode = forms.MultipleChoiceField(
choices=InterfaceModeChoices,
required=False,
label=_('802.1Q mode')
)
vlan_translation_policy_id = DynamicModelMultipleChoiceField(
queryset=VLANTranslationPolicy.objects.all(),
required=False,
label=_('VLAN Translation Policy')
)
tag = TagFilterField(model)

View File

@@ -606,6 +606,7 @@ class VMInterfaceTestCase(TestCase, ChangeLoggedFilterSetTests):
mtu=100,
vrf=vrfs[0],
description='foobar1',
mode=InterfaceModeChoices.MODE_ACCESS,
vlan_translation_policy=vlan_translation_policies[0],
),
VMInterface(
@@ -615,6 +616,7 @@ class VMInterfaceTestCase(TestCase, ChangeLoggedFilterSetTests):
mtu=200,
vrf=vrfs[1],
description='foobar2',
mode=InterfaceModeChoices.MODE_TAGGED,
vlan_translation_policy=vlan_translation_policies[0],
),
VMInterface(
@@ -700,6 +702,10 @@ class VMInterfaceTestCase(TestCase, ChangeLoggedFilterSetTests):
params = {'description': ['foobar1', 'foobar2']}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
def test_mode(self):
params = {'mode': [InterfaceModeChoices.MODE_ACCESS]}
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
def test_vlan(self):
vlan = VLAN.objects.filter(qinq_role=VLANQinQRoleChoices.ROLE_SERVICE).first()
params = {'vlan_id': vlan.pk}

View File

@@ -1,4 +1,5 @@
from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
from django.db import transaction
from django.db.models import Prefetch, Sum
from django.shortcuts import get_object_or_404, redirect, render
@@ -10,7 +11,7 @@ from dcim.forms import DeviceFilterForm
from dcim.models import Device
from dcim.tables import DeviceTable
from extras.views import ObjectConfigContextView, ObjectRenderConfigView
from ipam.models import IPAddress
from ipam.models import IPAddress, VLANGroup
from ipam.tables import InterfaceVLANTable, VLANTranslationRuleTable
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
from netbox.views import generic
@@ -102,7 +103,17 @@ class ClusterGroupView(GetRelatedModelsMixin, generic.ObjectView):
def get_extra_context(self, request, instance):
return {
'related_models': self.get_related_models(request, instance),
'related_models': self.get_related_models(
request,
instance,
extra=(
(
VLANGroup.objects.restrict(request.user, 'view').filter(
scope_type=ContentType.objects.get_for_model(ClusterGroup),
scope_id=instance.pk
), 'cluster_group'),
),
),
}
@@ -162,15 +173,28 @@ class ClusterListView(generic.ObjectListView):
@register_model_view(Cluster)
class ClusterView(generic.ObjectView):
class ClusterView(GetRelatedModelsMixin, generic.ObjectView):
queryset = Cluster.objects.all()
def get_extra_context(self, request, instance):
return instance.virtual_machines.aggregate(
vcpus_sum=Sum('vcpus'),
memory_sum=Sum('memory'),
disk_sum=Sum('disk')
)
return {
**instance.virtual_machines.aggregate(
vcpus_sum=Sum('vcpus'),
memory_sum=Sum('memory'),
disk_sum=Sum('disk')
),
'related_models': self.get_related_models(
request,
instance,
omit=(),
extra=(
(VLANGroup.objects.restrict(request.user, 'view').filter(
scope_type=ContentType.objects.get_for_model(Cluster),
scope_id=instance.pk
), 'cluster'),
)
),
}
@register_model_view(Cluster, 'virtualmachines', path='virtual-machines')