mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-26 15:17:45 -06:00
Merge branch 'develop' into feature
This commit is contained in:
@@ -20,7 +20,7 @@ from utilities.filters import (
|
||||
ContentTypeFilter, MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, MultiValueWWNFilter,
|
||||
NumericArrayFilter, TreeNodeMultipleChoiceFilter,
|
||||
)
|
||||
from virtualization.models import Cluster
|
||||
from virtualization.models import Cluster, ClusterGroup
|
||||
from vpn.models import L2VPN
|
||||
from wireless.choices import WirelessRoleChoices, WirelessChannelChoices
|
||||
from wireless.models import WirelessLAN, WirelessLink
|
||||
@@ -1012,6 +1012,17 @@ class DeviceFilterSet(
|
||||
queryset=Cluster.objects.all(),
|
||||
label=_('VM cluster (ID)'),
|
||||
)
|
||||
cluster_group = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='cluster__group__slug',
|
||||
queryset=ClusterGroup.objects.all(),
|
||||
to_field_name='slug',
|
||||
label=_('Cluster group (slug)'),
|
||||
)
|
||||
cluster_group_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='cluster__group',
|
||||
queryset=ClusterGroup.objects.all(),
|
||||
label=_('Cluster group (ID)'),
|
||||
)
|
||||
model = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='device_type__slug',
|
||||
queryset=DeviceType.objects.all(),
|
||||
|
||||
@@ -174,9 +174,6 @@ class RackRoleImportForm(NetBoxModelImportForm):
|
||||
class Meta:
|
||||
model = RackRole
|
||||
fields = ('name', 'slug', 'color', 'description', 'tags')
|
||||
help_texts = {
|
||||
'color': mark_safe(_('RGB color in hexadecimal. Example:') + ' <code>00ff00</code>'),
|
||||
}
|
||||
|
||||
|
||||
class RackImportForm(NetBoxModelImportForm):
|
||||
@@ -384,9 +381,6 @@ class DeviceRoleImportForm(NetBoxModelImportForm):
|
||||
class Meta:
|
||||
model = DeviceRole
|
||||
fields = ('name', 'slug', 'color', 'vm_role', 'config_template', 'description', 'tags')
|
||||
help_texts = {
|
||||
'color': mark_safe(_('RGB color in hexadecimal. Example:') + ' <code>00ff00</code>'),
|
||||
}
|
||||
|
||||
|
||||
class PlatformImportForm(NetBoxModelImportForm):
|
||||
@@ -1052,7 +1046,7 @@ class InventoryItemImportForm(NetBoxModelImportForm):
|
||||
class Meta:
|
||||
model = InventoryItem
|
||||
fields = (
|
||||
'device', 'name', 'label', 'role', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered',
|
||||
'device', 'name', 'label', 'role', 'manufacturer', 'parent', 'part_id', 'serial', 'asset_tag', 'discovered',
|
||||
'description', 'tags', 'component_type', 'component_name',
|
||||
)
|
||||
|
||||
@@ -1104,9 +1098,6 @@ class InventoryItemRoleImportForm(NetBoxModelImportForm):
|
||||
class Meta:
|
||||
model = InventoryItemRole
|
||||
fields = ('name', 'slug', 'color', 'description')
|
||||
help_texts = {
|
||||
'color': mark_safe(_('RGB color in hexadecimal. Example:') + ' <code>00ff00</code>'),
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
@@ -1183,9 +1174,6 @@ class CableImportForm(NetBoxModelImportForm):
|
||||
'side_a_device', 'side_a_type', 'side_a_name', 'side_b_device', 'side_b_type', 'side_b_name', 'type',
|
||||
'status', 'tenant', 'label', 'color', 'length', 'length_unit', 'description', 'comments', 'tags',
|
||||
]
|
||||
help_texts = {
|
||||
'color': mark_safe(_('RGB color in hexadecimal. Example:') + ' <code>00ff00</code>'),
|
||||
}
|
||||
|
||||
def _clean_side(self, side):
|
||||
"""
|
||||
|
||||
@@ -14,6 +14,7 @@ from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, FilterForm, add_blank_ch
|
||||
from utilities.forms.fields import ColorField, DynamicModelMultipleChoiceField, TagFilterField
|
||||
from utilities.forms.rendering import FieldSet
|
||||
from utilities.forms.widgets import NumberWithOptions
|
||||
from virtualization.models import Cluster, ClusterGroup
|
||||
from vpn.models import L2VPN
|
||||
from wireless.choices import *
|
||||
|
||||
@@ -655,6 +656,7 @@ class DeviceFilterForm(
|
||||
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces', 'pass_through_ports',
|
||||
name=_('Components')
|
||||
),
|
||||
FieldSet('cluster_group_id', 'cluster_id', name=_('Cluster')),
|
||||
FieldSet(
|
||||
'has_primary_ip', 'has_oob_ip', 'virtual_chassis_member', 'config_template_id', 'local_context_data',
|
||||
'has_virtual_device_context',
|
||||
@@ -821,6 +823,16 @@ class DeviceFilterForm(
|
||||
choices=BOOLEAN_WITH_BLANK_CHOICES
|
||||
)
|
||||
)
|
||||
cluster_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Cluster.objects.all(),
|
||||
required=False,
|
||||
label=_('Cluster')
|
||||
)
|
||||
cluster_group_id = DynamicModelMultipleChoiceField(
|
||||
queryset=ClusterGroup.objects.all(),
|
||||
required=False,
|
||||
label=_('Cluster group')
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from ipam.models import ASN, IPAddress, RIR, VRF
|
||||
from netbox.choices import ColorChoices
|
||||
from tenancy.models import Tenant, TenantGroup
|
||||
from utilities.testing import ChangeLoggedFilterSetTests, create_test_device
|
||||
from virtualization.models import Cluster, ClusterType
|
||||
from virtualization.models import Cluster, ClusterType, ClusterGroup
|
||||
from wireless.choices import WirelessChannelChoices, WirelessRoleChoices
|
||||
|
||||
User = get_user_model()
|
||||
@@ -1959,10 +1959,16 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests):
|
||||
Rack.objects.bulk_create(racks)
|
||||
|
||||
cluster_type = ClusterType.objects.create(name='Cluster Type 1', slug='cluster-type-1')
|
||||
cluster_groups = (
|
||||
ClusterGroup(name='Cluster Group 1', slug='cluster-group-1'),
|
||||
ClusterGroup(name='Cluster Group 2', slug='cluster-group-2'),
|
||||
ClusterGroup(name='Cluster Group 3', slug='cluster-group-3'),
|
||||
)
|
||||
ClusterGroup.objects.bulk_create(cluster_groups)
|
||||
clusters = (
|
||||
Cluster(name='Cluster 1', type=cluster_type),
|
||||
Cluster(name='Cluster 2', type=cluster_type),
|
||||
Cluster(name='Cluster 3', type=cluster_type),
|
||||
Cluster(name='Cluster 1', type=cluster_type, group=cluster_groups[0]),
|
||||
Cluster(name='Cluster 2', type=cluster_type, group=cluster_groups[1]),
|
||||
Cluster(name='Cluster 3', type=cluster_type, group=cluster_groups[2]),
|
||||
)
|
||||
Cluster.objects.bulk_create(clusters)
|
||||
|
||||
@@ -2213,6 +2219,13 @@ class DeviceTestCase(TestCase, ChangeLoggedFilterSetTests):
|
||||
params = {'cluster_id': [clusters[0].pk, clusters[1].pk]}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||
|
||||
def test_cluster_group(self):
|
||||
cluster_groups = ClusterGroup.objects.all()[:2]
|
||||
params = {'cluster_group_id': [cluster_groups[0].pk, cluster_groups[1].pk]}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||
params = {'cluster_group': [cluster_groups[0].slug, cluster_groups[1].slug]}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||
|
||||
def test_model(self):
|
||||
params = {'model': ['model-1', 'model-2']}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||
|
||||
@@ -31,6 +31,7 @@ from utilities.views import (
|
||||
GetRelatedModelsMixin, GetReturnURLMixin, ObjectPermissionRequiredMixin, ViewTab, register_model_view
|
||||
)
|
||||
from virtualization.filtersets import VirtualMachineFilterSet
|
||||
from virtualization.forms import VirtualMachineFilterForm
|
||||
from virtualization.models import VirtualMachine
|
||||
from virtualization.tables import VirtualMachineTable
|
||||
from . import filtersets, forms, tables
|
||||
@@ -679,6 +680,7 @@ class RackRackReservationsView(generic.ObjectChildrenView):
|
||||
child_model = RackReservation
|
||||
table = tables.RackReservationTable
|
||||
filterset = filtersets.RackReservationFilterSet
|
||||
filterset_form = forms.RackReservationFilterForm
|
||||
template_name = 'dcim/rack/reservations.html'
|
||||
tab = ViewTab(
|
||||
label=_('Reservations'),
|
||||
@@ -697,6 +699,7 @@ class RackNonRackedView(generic.ObjectChildrenView):
|
||||
child_model = Device
|
||||
table = tables.DeviceTable
|
||||
filterset = filtersets.DeviceFilterSet
|
||||
filterset_form = forms.DeviceFilterForm
|
||||
template_name = 'dcim/rack/non_racked_devices.html'
|
||||
tab = ViewTab(
|
||||
label=_('Non-Racked Devices'),
|
||||
@@ -1835,6 +1838,7 @@ class DeviceConsolePortsView(DeviceComponentsView):
|
||||
child_model = ConsolePort
|
||||
table = tables.DeviceConsolePortTable
|
||||
filterset = filtersets.ConsolePortFilterSet
|
||||
filterset_form = forms.ConsolePortFilterForm
|
||||
template_name = 'dcim/device/consoleports.html',
|
||||
tab = ViewTab(
|
||||
label=_('Console Ports'),
|
||||
@@ -1850,6 +1854,7 @@ class DeviceConsoleServerPortsView(DeviceComponentsView):
|
||||
child_model = ConsoleServerPort
|
||||
table = tables.DeviceConsoleServerPortTable
|
||||
filterset = filtersets.ConsoleServerPortFilterSet
|
||||
filterset_form = forms.ConsoleServerPortFilterForm
|
||||
template_name = 'dcim/device/consoleserverports.html'
|
||||
tab = ViewTab(
|
||||
label=_('Console Server Ports'),
|
||||
@@ -1865,6 +1870,7 @@ class DevicePowerPortsView(DeviceComponentsView):
|
||||
child_model = PowerPort
|
||||
table = tables.DevicePowerPortTable
|
||||
filterset = filtersets.PowerPortFilterSet
|
||||
filterset_form = forms.PowerPortFilterForm
|
||||
template_name = 'dcim/device/powerports.html'
|
||||
tab = ViewTab(
|
||||
label=_('Power Ports'),
|
||||
@@ -1880,6 +1886,7 @@ class DevicePowerOutletsView(DeviceComponentsView):
|
||||
child_model = PowerOutlet
|
||||
table = tables.DevicePowerOutletTable
|
||||
filterset = filtersets.PowerOutletFilterSet
|
||||
filterset_form = forms.PowerOutletFilterForm
|
||||
template_name = 'dcim/device/poweroutlets.html'
|
||||
tab = ViewTab(
|
||||
label=_('Power Outlets'),
|
||||
@@ -1895,6 +1902,7 @@ class DeviceInterfacesView(DeviceComponentsView):
|
||||
child_model = Interface
|
||||
table = tables.DeviceInterfaceTable
|
||||
filterset = filtersets.InterfaceFilterSet
|
||||
filterset_form = forms.InterfaceFilterForm
|
||||
template_name = 'dcim/device/interfaces.html'
|
||||
tab = ViewTab(
|
||||
label=_('Interfaces'),
|
||||
@@ -1916,6 +1924,7 @@ class DeviceFrontPortsView(DeviceComponentsView):
|
||||
child_model = FrontPort
|
||||
table = tables.DeviceFrontPortTable
|
||||
filterset = filtersets.FrontPortFilterSet
|
||||
filterset_form = forms.FrontPortFilterForm
|
||||
template_name = 'dcim/device/frontports.html'
|
||||
tab = ViewTab(
|
||||
label=_('Front Ports'),
|
||||
@@ -1931,6 +1940,7 @@ class DeviceRearPortsView(DeviceComponentsView):
|
||||
child_model = RearPort
|
||||
table = tables.DeviceRearPortTable
|
||||
filterset = filtersets.RearPortFilterSet
|
||||
filterset_form = forms.RearPortFilterForm
|
||||
template_name = 'dcim/device/rearports.html'
|
||||
tab = ViewTab(
|
||||
label=_('Rear Ports'),
|
||||
@@ -1946,6 +1956,7 @@ class DeviceModuleBaysView(DeviceComponentsView):
|
||||
child_model = ModuleBay
|
||||
table = tables.DeviceModuleBayTable
|
||||
filterset = filtersets.ModuleBayFilterSet
|
||||
filterset_form = forms.ModuleBayFilterForm
|
||||
template_name = 'dcim/device/modulebays.html'
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
@@ -1965,6 +1976,7 @@ class DeviceDeviceBaysView(DeviceComponentsView):
|
||||
child_model = DeviceBay
|
||||
table = tables.DeviceDeviceBayTable
|
||||
filterset = filtersets.DeviceBayFilterSet
|
||||
filterset_form = forms.DeviceBayFilterForm
|
||||
template_name = 'dcim/device/devicebays.html'
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
@@ -1984,6 +1996,7 @@ class DeviceInventoryView(DeviceComponentsView):
|
||||
child_model = InventoryItem
|
||||
table = tables.DeviceInventoryItemTable
|
||||
filterset = filtersets.InventoryItemFilterSet
|
||||
filterset_form = forms.InventoryItemFilterForm
|
||||
template_name = 'dcim/device/inventory.html'
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
@@ -2062,6 +2075,7 @@ class DeviceVirtualMachinesView(generic.ObjectChildrenView):
|
||||
child_model = VirtualMachine
|
||||
table = VirtualMachineTable
|
||||
filterset = VirtualMachineFilterSet
|
||||
filterset_form = VirtualMachineFilterForm
|
||||
tab = ViewTab(
|
||||
label=_('Virtual Machines'),
|
||||
badge=lambda obj: VirtualMachine.objects.filter(cluster=obj.cluster, device=obj).count(),
|
||||
@@ -2944,6 +2958,7 @@ class InventoryItemChildrenView(generic.ObjectChildrenView):
|
||||
child_model = InventoryItem
|
||||
table = tables.InventoryItemTable
|
||||
filterset = filtersets.InventoryItemFilterSet
|
||||
filterset_form = forms.InventoryItemFilterForm
|
||||
tab = ViewTab(
|
||||
label=_('Children'),
|
||||
badge=lambda obj: obj.child_items.count(),
|
||||
|
||||
Reference in New Issue
Block a user