Merge branch 'develop' of https://github.com/PieterL75/netbox into develop

This commit is contained in:
Pieter Lambrecht 2022-03-18 09:49:12 +01:00
commit 14fbebfc24
4 changed files with 229 additions and 199 deletions

View File

@ -83,7 +83,7 @@ markdown-include
mkdocs-material mkdocs-material
# Library for manipulating IP prefixes and addresses # Library for manipulating IP prefixes and addresses
# https://github.com/drkjam/netaddr # https://github.com/netaddr/netaddr
netaddr netaddr
# Fork of PIL (Python Imaging Library) for image processing # Fork of PIL (Python Imaging Library) for image processing

View File

@ -4,7 +4,8 @@
### Enhancements ### Enhancements
* [#8233](https://github.com/netbox-community/netbox/issues/8233) - Restrict API key usage by source IP * [#8233](https://github.com/netbox-community/netbox/issues/8233) - Restrict API key usage by source IP
* [#8553](https://github.com/netbox-community/netbox/issues/8553) - Add missing object types to global search form
### Bug Fixes ### Bug Fixes

View File

@ -1,4 +1,5 @@
from collections import OrderedDict from collections import OrderedDict
from typing import Dict
from circuits.filtersets import CircuitFilterSet, ProviderFilterSet, ProviderNetworkFilterSet from circuits.filtersets import CircuitFilterSet, ProviderFilterSet, ProviderNetworkFilterSet
from circuits.models import Circuit, ProviderNetwork, Provider from circuits.models import Circuit, ProviderNetwork, Provider
@ -26,169 +27,212 @@ from virtualization.models import Cluster, VirtualMachine
from virtualization.tables import ClusterTable, VirtualMachineTable from virtualization.tables import ClusterTable, VirtualMachineTable
SEARCH_MAX_RESULTS = 15 SEARCH_MAX_RESULTS = 15
SEARCH_TYPES = OrderedDict((
# Circuits CIRCUIT_TYPES = OrderedDict(
('provider', { (
'queryset': Provider.objects.annotate( ('provider', {
count_circuits=count_related(Circuit, 'provider') 'queryset': Provider.objects.annotate(
), count_circuits=count_related(Circuit, 'provider')
'filterset': ProviderFilterSet,
'table': ProviderTable,
'url': 'circuits:provider_list',
}),
('circuit', {
'queryset': Circuit.objects.prefetch_related(
'type', 'provider', 'tenant', 'terminations__site'
),
'filterset': CircuitFilterSet,
'table': CircuitTable,
'url': 'circuits:circuit_list',
}),
('providernetwork', {
'queryset': ProviderNetwork.objects.prefetch_related('provider'),
'filterset': ProviderNetworkFilterSet,
'table': ProviderNetworkTable,
'url': 'circuits:providernetwork_list',
}),
# DCIM
('site', {
'queryset': Site.objects.prefetch_related('region', 'tenant'),
'filterset': SiteFilterSet,
'table': SiteTable,
'url': 'dcim:site_list',
}),
('rack', {
'queryset': Rack.objects.prefetch_related('site', 'location', 'tenant', 'role'),
'filterset': RackFilterSet,
'table': RackTable,
'url': 'dcim:rack_list',
}),
('rackreservation', {
'queryset': RackReservation.objects.prefetch_related('site', 'rack', 'user'),
'filterset': RackReservationFilterSet,
'table': RackReservationTable,
'url': 'dcim:rackreservation_list',
}),
('location', {
'queryset': Location.objects.add_related_count(
Location.objects.add_related_count(
Location.objects.all(),
Device,
'location',
'device_count',
cumulative=True
), ),
Rack, 'filterset': ProviderFilterSet,
'location', 'table': ProviderTable,
'rack_count', 'url': 'circuits:provider_list',
cumulative=True }),
).prefetch_related('site'), ('circuit', {
'filterset': LocationFilterSet, 'queryset': Circuit.objects.prefetch_related(
'table': LocationTable, 'type', 'provider', 'tenant', 'terminations__site'
'url': 'dcim:location_list', ),
}), 'filterset': CircuitFilterSet,
('devicetype', { 'table': CircuitTable,
'queryset': DeviceType.objects.prefetch_related('manufacturer').annotate( 'url': 'circuits:circuit_list',
instance_count=count_related(Device, 'device_type') }),
), ('providernetwork', {
'filterset': DeviceTypeFilterSet, 'queryset': ProviderNetwork.objects.prefetch_related('provider'),
'table': DeviceTypeTable, 'filterset': ProviderNetworkFilterSet,
'url': 'dcim:devicetype_list', 'table': ProviderNetworkTable,
}), 'url': 'circuits:providernetwork_list',
('device', { }),
'queryset': Device.objects.prefetch_related( )
'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6', )
),
'filterset': DeviceFilterSet,
'table': DeviceTable, DCIM_TYPES = OrderedDict(
'url': 'dcim:device_list', (
}), ('site', {
('virtualchassis', { 'queryset': Site.objects.prefetch_related('region', 'tenant'),
'queryset': VirtualChassis.objects.prefetch_related('master').annotate( 'filterset': SiteFilterSet,
member_count=count_related(Device, 'virtual_chassis') 'table': SiteTable,
), 'url': 'dcim:site_list',
'filterset': VirtualChassisFilterSet, }),
'table': VirtualChassisTable, ('rack', {
'url': 'dcim:virtualchassis_list', 'queryset': Rack.objects.prefetch_related('site', 'location', 'tenant', 'role'),
}), 'filterset': RackFilterSet,
('cable', { 'table': RackTable,
'queryset': Cable.objects.all(), 'url': 'dcim:rack_list',
'filterset': CableFilterSet, }),
'table': CableTable, ('rackreservation', {
'url': 'dcim:cable_list', 'queryset': RackReservation.objects.prefetch_related('site', 'rack', 'user'),
}), 'filterset': RackReservationFilterSet,
('powerfeed', { 'table': RackReservationTable,
'queryset': PowerFeed.objects.all(), 'url': 'dcim:rackreservation_list',
'filterset': PowerFeedFilterSet, }),
'table': PowerFeedTable, ('location', {
'url': 'dcim:powerfeed_list', 'queryset': Location.objects.add_related_count(
}), Location.objects.add_related_count(
# Virtualization Location.objects.all(),
('cluster', { Device,
'queryset': Cluster.objects.prefetch_related('type', 'group').annotate( 'location',
device_count=count_related(Device, 'cluster'), 'device_count',
vm_count=count_related(VirtualMachine, 'cluster') cumulative=True
), ),
'filterset': ClusterFilterSet, Rack,
'table': ClusterTable, 'location',
'url': 'virtualization:cluster_list', 'rack_count',
}), cumulative=True
('virtualmachine', { ).prefetch_related('site'),
'queryset': VirtualMachine.objects.prefetch_related( 'filterset': LocationFilterSet,
'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6', 'table': LocationTable,
), 'url': 'dcim:location_list',
'filterset': VirtualMachineFilterSet, }),
'table': VirtualMachineTable, ('devicetype', {
'url': 'virtualization:virtualmachine_list', 'queryset': DeviceType.objects.prefetch_related('manufacturer').annotate(
}), instance_count=count_related(Device, 'device_type')
# IPAM ),
('vrf', { 'filterset': DeviceTypeFilterSet,
'queryset': VRF.objects.prefetch_related('tenant'), 'table': DeviceTypeTable,
'filterset': VRFFilterSet, 'url': 'dcim:devicetype_list',
'table': VRFTable, }),
'url': 'ipam:vrf_list', ('device', {
}), 'queryset': Device.objects.prefetch_related(
('aggregate', { 'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6',
'queryset': Aggregate.objects.prefetch_related('rir'), ),
'filterset': AggregateFilterSet, 'filterset': DeviceFilterSet,
'table': AggregateTable, 'table': DeviceTable,
'url': 'ipam:aggregate_list', 'url': 'dcim:device_list',
}), }),
('prefix', { ('virtualchassis', {
'queryset': Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role'), 'queryset': VirtualChassis.objects.prefetch_related('master').annotate(
'filterset': PrefixFilterSet, member_count=count_related(Device, 'virtual_chassis')
'table': PrefixTable, ),
'url': 'ipam:prefix_list', 'filterset': VirtualChassisFilterSet,
}), 'table': VirtualChassisTable,
('ipaddress', { 'url': 'dcim:virtualchassis_list',
'queryset': IPAddress.objects.prefetch_related('vrf__tenant', 'tenant'), }),
'filterset': IPAddressFilterSet, ('cable', {
'table': IPAddressTable, 'queryset': Cable.objects.all(),
'url': 'ipam:ipaddress_list', 'filterset': CableFilterSet,
}), 'table': CableTable,
('vlan', { 'url': 'dcim:cable_list',
'queryset': VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role'), }),
'filterset': VLANFilterSet, ('powerfeed', {
'table': VLANTable, 'queryset': PowerFeed.objects.all(),
'url': 'ipam:vlan_list', 'filterset': PowerFeedFilterSet,
}), 'table': PowerFeedTable,
('asn', { 'url': 'dcim:powerfeed_list',
'queryset': ASN.objects.prefetch_related('rir', 'tenant'), }),
'filterset': ASNFilterSet, )
'table': ASNTable, )
'url': 'ipam:asn_list',
}), IPAM_TYPES = OrderedDict(
# Tenancy (
('tenant', { ('vrf', {
'queryset': Tenant.objects.prefetch_related('group'), 'queryset': VRF.objects.prefetch_related('tenant'),
'filterset': TenantFilterSet, 'filterset': VRFFilterSet,
'table': TenantTable, 'table': VRFTable,
'url': 'tenancy:tenant_list', 'url': 'ipam:vrf_list',
}), }),
('contact', { ('aggregate', {
'queryset': Contact.objects.prefetch_related('group', 'assignments').annotate(assignment_count=count_related(ContactAssignment, 'contact')), 'queryset': Aggregate.objects.prefetch_related('rir'),
'filterset': ContactFilterSet, 'filterset': AggregateFilterSet,
'table': ContactTable, 'table': AggregateTable,
'url': 'tenancy:contact_list', 'url': 'ipam:aggregate_list',
}), }),
)) ('prefix', {
'queryset': Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role'),
'filterset': PrefixFilterSet,
'table': PrefixTable,
'url': 'ipam:prefix_list',
}),
('ipaddress', {
'queryset': IPAddress.objects.prefetch_related('vrf__tenant', 'tenant'),
'filterset': IPAddressFilterSet,
'table': IPAddressTable,
'url': 'ipam:ipaddress_list',
}),
('vlan', {
'queryset': VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role'),
'filterset': VLANFilterSet,
'table': VLANTable,
'url': 'ipam:vlan_list',
}),
('asn', {
'queryset': ASN.objects.prefetch_related('rir', 'tenant'),
'filterset': ASNFilterSet,
'table': ASNTable,
'url': 'ipam:asn_list',
}),
)
)
TENANCY_TYPES = OrderedDict(
(
('tenant', {
'queryset': Tenant.objects.prefetch_related('group'),
'filterset': TenantFilterSet,
'table': TenantTable,
'url': 'tenancy:tenant_list',
}),
('contact', {
'queryset': Contact.objects.prefetch_related('group', 'assignments').annotate(
assignment_count=count_related(ContactAssignment, 'contact')),
'filterset': ContactFilterSet,
'table': ContactTable,
'url': 'tenancy:contact_list',
}),
)
)
VIRTUALIZATION_TYPES = OrderedDict(
(
('cluster', {
'queryset': Cluster.objects.prefetch_related('type', 'group').annotate(
device_count=count_related(Device, 'cluster'),
vm_count=count_related(VirtualMachine, 'cluster')
),
'filterset': ClusterFilterSet,
'table': ClusterTable,
'url': 'virtualization:cluster_list',
}),
('virtualmachine', {
'queryset': VirtualMachine.objects.prefetch_related(
'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6',
),
'filterset': VirtualMachineFilterSet,
'table': VirtualMachineTable,
'url': 'virtualization:virtualmachine_list',
}),
)
)
SEARCH_TYPE_HIERARCHY = OrderedDict(
(
("Circuits", CIRCUIT_TYPES),
("DCIM", DCIM_TYPES),
("IPAM", IPAM_TYPES),
("Tenancy", TENANCY_TYPES),
("Virtualization", VIRTUALIZATION_TYPES),
)
)
def build_search_types() -> Dict[str, Dict]:
result = dict()
for app_types in SEARCH_TYPE_HIERARCHY.values():
for name, items in app_types.items():
result[name] = items
return result
SEARCH_TYPES = build_search_types()

View File

@ -1,39 +1,24 @@
from django import forms from django import forms
from utilities.forms import BootstrapMixin from utilities.forms import BootstrapMixin
from netbox.constants import SEARCH_TYPE_HIERARCHY
OBJ_TYPE_CHOICES = (
('', 'All Objects'), def build_search_choices():
('Circuits', ( result = list()
('provider', 'Providers'), result.append(('', 'All Objects'))
('circuit', 'Circuits'), for category, items in SEARCH_TYPE_HIERARCHY.items():
)), subcategories = list()
('DCIM', ( for slug, obj in items.items():
('site', 'Sites'), name = obj['queryset'].model._meta.verbose_name_plural
('rack', 'Racks'), name = name[0].upper() + name[1:]
('rackreservation', 'Rack reservations'), subcategories.append((slug, name))
('location', 'Locations'), result.append((category, tuple(subcategories)))
('devicetype', 'Device Types'),
('device', 'Devices'), return tuple(result)
('virtualchassis', 'Virtual chassis'),
('cable', 'Cables'),
('powerfeed', 'Power feeds'), OBJ_TYPE_CHOICES = build_search_choices()
)),
('IPAM', (
('vrf', 'VRFs'),
('aggregate', 'Aggregates'),
('prefix', 'Prefixes'),
('ipaddress', 'IP Addresses'),
('vlan', 'VLANs'),
)),
('Tenancy', (
('tenant', 'Tenants'),
)),
('Virtualization', (
('cluster', 'Clusters'),
('virtualmachine', 'Virtual Machines'),
)),
)
def build_options(): def build_options():