mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-21 11:37:21 -06:00
* Merge actions and action_perms into a single mapping * Update obsolete permission maps * Update obsolete action lists * Normalize empty permission mappings * Cleanup * Add deprecation warnings * Introduce DEFAULT_ACTION_PERMISSIONS constant
This commit is contained in:
parent
3f40ee5501
commit
450790ab4a
@ -100,7 +100,9 @@ class DataFileListView(generic.ObjectListView):
|
||||
filterset = filtersets.DataFileFilterSet
|
||||
filterset_form = forms.DataFileFilterForm
|
||||
table = tables.DataFileTable
|
||||
actions = ('bulk_delete',)
|
||||
actions = {
|
||||
'bulk_delete': {'delete'},
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(DataFile)
|
||||
@ -128,7 +130,10 @@ class JobListView(generic.ObjectListView):
|
||||
filterset = filtersets.JobFilterSet
|
||||
filterset_form = forms.JobFilterForm
|
||||
table = tables.JobTable
|
||||
actions = ('export', 'delete', 'bulk_delete')
|
||||
actions = {
|
||||
'export': {'view'},
|
||||
'bulk_delete': {'delete'},
|
||||
}
|
||||
|
||||
|
||||
class JobView(generic.ObjectView):
|
||||
|
@ -20,6 +20,7 @@ from circuits.models import Circuit, CircuitTermination
|
||||
from extras.views import ObjectConfigContextView
|
||||
from ipam.models import ASN, IPAddress, Prefix, VLAN, VLANGroup
|
||||
from ipam.tables import InterfaceVLANTable
|
||||
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
|
||||
from netbox.views import generic
|
||||
from tenancy.views import ObjectContactsView
|
||||
from utilities.forms import ConfirmationForm
|
||||
@ -46,15 +47,11 @@ CABLE_TERMINATION_TYPES = {
|
||||
|
||||
|
||||
class DeviceComponentsView(generic.ObjectChildrenView):
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename', 'bulk_disconnect')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
'bulk_disconnect': {'change'},
|
||||
})
|
||||
}
|
||||
queryset = Device.objects.all()
|
||||
|
||||
def get_children(self, request, parent):
|
||||
@ -1977,7 +1974,10 @@ class DeviceModuleBaysView(DeviceComponentsView):
|
||||
table = tables.DeviceModuleBayTable
|
||||
filterset = filtersets.ModuleBayFilterSet
|
||||
template_name = 'dcim/device/modulebays.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
}
|
||||
tab = ViewTab(
|
||||
label=_('Module Bays'),
|
||||
badge=lambda obj: obj.module_bay_count,
|
||||
@ -1993,7 +1993,10 @@ class DeviceDeviceBaysView(DeviceComponentsView):
|
||||
table = tables.DeviceDeviceBayTable
|
||||
filterset = filtersets.DeviceBayFilterSet
|
||||
template_name = 'dcim/device/devicebays.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
}
|
||||
tab = ViewTab(
|
||||
label=_('Device Bays'),
|
||||
badge=lambda obj: obj.device_bay_count,
|
||||
@ -2005,11 +2008,14 @@ class DeviceDeviceBaysView(DeviceComponentsView):
|
||||
|
||||
@register_model_view(Device, 'inventory')
|
||||
class DeviceInventoryView(DeviceComponentsView):
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
child_model = InventoryItem
|
||||
table = tables.DeviceInventoryItemTable
|
||||
filterset = filtersets.InventoryItemFilterSet
|
||||
template_name = 'dcim/device/inventory.html'
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
}
|
||||
tab = ViewTab(
|
||||
label=_('Inventory Items'),
|
||||
badge=lambda obj: obj.inventory_item_count,
|
||||
@ -2187,14 +2193,10 @@ class ConsolePortListView(generic.ObjectListView):
|
||||
filterset_form = forms.ConsolePortFilterForm
|
||||
table = tables.ConsolePortTable
|
||||
template_name = 'dcim/component_list.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(ConsolePort)
|
||||
@ -2259,14 +2261,10 @@ class ConsoleServerPortListView(generic.ObjectListView):
|
||||
filterset_form = forms.ConsoleServerPortFilterForm
|
||||
table = tables.ConsoleServerPortTable
|
||||
template_name = 'dcim/component_list.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(ConsoleServerPort)
|
||||
@ -2331,14 +2329,10 @@ class PowerPortListView(generic.ObjectListView):
|
||||
filterset_form = forms.PowerPortFilterForm
|
||||
table = tables.PowerPortTable
|
||||
template_name = 'dcim/component_list.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(PowerPort)
|
||||
@ -2403,14 +2397,10 @@ class PowerOutletListView(generic.ObjectListView):
|
||||
filterset_form = forms.PowerOutletFilterForm
|
||||
table = tables.PowerOutletTable
|
||||
template_name = 'dcim/component_list.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(PowerOutlet)
|
||||
@ -2475,14 +2465,10 @@ class InterfaceListView(generic.ObjectListView):
|
||||
filterset_form = forms.InterfaceFilterForm
|
||||
table = tables.InterfaceTable
|
||||
template_name = 'dcim/component_list.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(Interface)
|
||||
@ -2595,14 +2581,10 @@ class FrontPortListView(generic.ObjectListView):
|
||||
filterset_form = forms.FrontPortFilterForm
|
||||
table = tables.FrontPortTable
|
||||
template_name = 'dcim/component_list.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(FrontPort)
|
||||
@ -2667,14 +2649,10 @@ class RearPortListView(generic.ObjectListView):
|
||||
filterset_form = forms.RearPortFilterForm
|
||||
table = tables.RearPortTable
|
||||
template_name = 'dcim/component_list.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(RearPort)
|
||||
@ -2739,14 +2717,10 @@ class ModuleBayListView(generic.ObjectListView):
|
||||
filterset_form = forms.ModuleBayFilterForm
|
||||
table = tables.ModuleBayTable
|
||||
template_name = 'dcim/component_list.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(ModuleBay)
|
||||
@ -2803,14 +2777,10 @@ class DeviceBayListView(generic.ObjectListView):
|
||||
filterset_form = forms.DeviceBayFilterForm
|
||||
table = tables.DeviceBayTable
|
||||
template_name = 'dcim/component_list.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(DeviceBay)
|
||||
@ -2936,14 +2906,10 @@ class InventoryItemListView(generic.ObjectListView):
|
||||
filterset_form = forms.InventoryItemFilterForm
|
||||
table = tables.InventoryItemTable
|
||||
template_name = 'dcim/component_list.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(InventoryItem)
|
||||
@ -3175,7 +3141,12 @@ class CableListView(generic.ObjectListView):
|
||||
filterset = filtersets.CableFilterSet
|
||||
filterset_form = forms.CableFilterForm
|
||||
table = tables.CableTable
|
||||
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
|
||||
actions = {
|
||||
'import': {'add'},
|
||||
'export': {'view'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(Cable)
|
||||
@ -3269,7 +3240,9 @@ class ConsoleConnectionsListView(generic.ObjectListView):
|
||||
filterset_form = forms.ConsoleConnectionFilterForm
|
||||
table = tables.ConsoleConnectionTable
|
||||
template_name = 'dcim/connections_list.html'
|
||||
actions = ('export',)
|
||||
actions = {
|
||||
'export': {'view'},
|
||||
}
|
||||
|
||||
def get_extra_context(self, request):
|
||||
return {
|
||||
@ -3283,7 +3256,9 @@ class PowerConnectionsListView(generic.ObjectListView):
|
||||
filterset_form = forms.PowerConnectionFilterForm
|
||||
table = tables.PowerConnectionTable
|
||||
template_name = 'dcim/connections_list.html'
|
||||
actions = ('export',)
|
||||
actions = {
|
||||
'export': {'view'},
|
||||
}
|
||||
|
||||
def get_extra_context(self, request):
|
||||
return {
|
||||
@ -3297,7 +3272,9 @@ class InterfaceConnectionsListView(generic.ObjectListView):
|
||||
filterset_form = forms.InterfaceConnectionFilterForm
|
||||
table = tables.InterfaceConnectionTable
|
||||
template_name = 'dcim/connections_list.html'
|
||||
actions = ('export',)
|
||||
actions = {
|
||||
'export': {'view'},
|
||||
}
|
||||
|
||||
def get_extra_context(self, request):
|
||||
return {
|
||||
|
@ -16,6 +16,7 @@ from core.tables import JobTable
|
||||
from extras.dashboard.forms import DashboardWidgetAddForm, DashboardWidgetForm
|
||||
from extras.dashboard.utils import get_widget_class
|
||||
from netbox.config import get_config, PARAMS
|
||||
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
|
||||
from netbox.views import generic
|
||||
from utilities.forms import ConfirmationForm, get_field_value
|
||||
from utilities.htmx import is_htmx
|
||||
@ -210,7 +211,10 @@ class ExportTemplateListView(generic.ObjectListView):
|
||||
filterset_form = forms.ExportTemplateFilterForm
|
||||
table = tables.ExportTemplateTable
|
||||
template_name = 'extras/exporttemplate_list.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_sync')
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_sync': {'sync'},
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(ExportTemplate)
|
||||
@ -472,7 +476,12 @@ class ConfigContextListView(generic.ObjectListView):
|
||||
filterset_form = forms.ConfigContextFilterForm
|
||||
table = tables.ConfigContextTable
|
||||
template_name = 'extras/configcontext_list.html'
|
||||
actions = ('add', 'bulk_edit', 'bulk_delete', 'bulk_sync')
|
||||
actions = {
|
||||
'add': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
'bulk_sync': {'sync'},
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(ConfigContext)
|
||||
@ -576,7 +585,10 @@ class ConfigTemplateListView(generic.ObjectListView):
|
||||
filterset_form = forms.ConfigTemplateFilterForm
|
||||
table = tables.ConfigTemplateTable
|
||||
template_name = 'extras/configtemplate_list.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_sync')
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_sync': {'sync'},
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(ConfigTemplate)
|
||||
@ -627,7 +639,9 @@ class ObjectChangeListView(generic.ObjectListView):
|
||||
filterset_form = forms.ObjectChangeFilterForm
|
||||
table = tables.ObjectChangeTable
|
||||
template_name = 'extras/objectchange_list.html'
|
||||
actions = ('export',)
|
||||
actions = {
|
||||
'export': {'view'},
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(ObjectChange)
|
||||
@ -693,7 +707,9 @@ class ImageAttachmentListView(generic.ObjectListView):
|
||||
filterset = filtersets.ImageAttachmentFilterSet
|
||||
filterset_form = forms.ImageAttachmentFilterForm
|
||||
table = tables.ImageAttachmentTable
|
||||
actions = ('export',)
|
||||
actions = {
|
||||
'export': {'view'},
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(ImageAttachment, 'edit')
|
||||
@ -736,7 +752,12 @@ class JournalEntryListView(generic.ObjectListView):
|
||||
filterset = filtersets.JournalEntryFilterSet
|
||||
filterset_form = forms.JournalEntryFilterForm
|
||||
table = tables.JournalEntryTable
|
||||
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
|
||||
actions = {
|
||||
'import': {'add'},
|
||||
'export': {'view'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(JournalEntry)
|
||||
|
@ -27,3 +27,12 @@ ADVISORY_LOCK_KEYS = {
|
||||
'inventoryitem': 105700,
|
||||
'inventoryitemtemplate': 105800,
|
||||
}
|
||||
|
||||
# Default view action permission mapping
|
||||
DEFAULT_ACTION_PERMISSIONS = {
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'export': {'view'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
from collections import defaultdict
|
||||
import warnings
|
||||
|
||||
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
|
||||
from utilities.permissions import get_permission_for_model
|
||||
|
||||
__all__ = (
|
||||
@ -9,13 +10,15 @@ __all__ = (
|
||||
|
||||
|
||||
class ActionsMixin:
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
})
|
||||
"""
|
||||
Maps action names to the set of required permissions for each. Object list views reference this mapping to
|
||||
determine whether to render the applicable button for each action: The button will be rendered only if the user
|
||||
possesses the specified permission(s).
|
||||
|
||||
Standard actions include: add, import, export, bulk_edit, and bulk_delete. Some views extend this default map
|
||||
with custom actions, such as bulk_sync.
|
||||
"""
|
||||
actions = DEFAULT_ACTION_PERMISSIONS
|
||||
|
||||
def get_permitted_actions(self, user, model=None):
|
||||
"""
|
||||
@ -23,11 +26,43 @@ class ActionsMixin:
|
||||
"""
|
||||
model = model or self.queryset.model
|
||||
|
||||
return [
|
||||
action for action in self.actions if user.has_perms([
|
||||
get_permission_for_model(model, name) for name in self.action_perms[action]
|
||||
])
|
||||
]
|
||||
# TODO: Remove backward compatibility in Netbox v4.0
|
||||
# Determine how permissions are being mapped to actions for the view
|
||||
if hasattr(self, 'action_perms'):
|
||||
# Backward compatibility for <3.7
|
||||
permissions_map = self.action_perms
|
||||
warnings.warn(
|
||||
"Setting action_perms on views is deprecated and will be removed in NetBox v4.0. Use actions instead.",
|
||||
DeprecationWarning
|
||||
)
|
||||
elif type(self.actions) is dict:
|
||||
# New actions format (3.7+)
|
||||
permissions_map = self.actions
|
||||
else:
|
||||
# actions is still defined as a list or tuple (<3.7) but no custom mapping is defined; use the old
|
||||
# default mapping
|
||||
permissions_map = {
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
}
|
||||
warnings.warn(
|
||||
"View actions should be defined as a dictionary mapping. Support for the legacy list format will be "
|
||||
"removed in NetBox v4.0.",
|
||||
DeprecationWarning
|
||||
)
|
||||
|
||||
# Resolve required permissions for each action
|
||||
permitted_actions = []
|
||||
for action in self.actions:
|
||||
required_permissions = [
|
||||
get_permission_for_model(model, name) for name in permissions_map.get(action, set())
|
||||
]
|
||||
if not required_permissions or user.has_perms(required_permissions):
|
||||
permitted_actions.append(action)
|
||||
|
||||
return permitted_actions
|
||||
|
||||
|
||||
class TableMixin:
|
||||
|
@ -386,7 +386,11 @@ class ContactAssignmentListView(generic.ObjectListView):
|
||||
filterset = filtersets.ContactAssignmentFilterSet
|
||||
filterset_form = forms.ContactAssignmentFilterForm
|
||||
table = tables.ContactAssignmentTable
|
||||
actions = ('export', 'bulk_edit', 'bulk_delete')
|
||||
actions = {
|
||||
'export': {'view'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
}
|
||||
|
||||
|
||||
@register_model_view(ContactAssignment, 'edit')
|
||||
|
@ -16,6 +16,7 @@ from dcim.tables import DeviceTable
|
||||
from extras.views import ObjectConfigContextView
|
||||
from ipam.models import IPAddress
|
||||
from ipam.tables import InterfaceVLANTable
|
||||
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
|
||||
from netbox.views import generic
|
||||
from tenancy.views import ObjectContactsView
|
||||
from utilities.utils import count_related
|
||||
@ -199,13 +200,13 @@ class ClusterDevicesView(generic.ObjectChildrenView):
|
||||
table = DeviceTable
|
||||
filterset = DeviceFilterSet
|
||||
template_name = 'virtualization/cluster/devices.html'
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_remove_devices')
|
||||
action_perms = defaultdict(set, **{
|
||||
actions = {
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'export': {'view'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_remove_devices': {'change'},
|
||||
})
|
||||
}
|
||||
tab = ViewTab(
|
||||
label=_('Devices'),
|
||||
badge=lambda obj: obj.devices.count(),
|
||||
@ -359,20 +360,16 @@ class VirtualMachineInterfacesView(generic.ObjectChildrenView):
|
||||
table = tables.VirtualMachineVMInterfaceTable
|
||||
filterset = filtersets.VMInterfaceFilterSet
|
||||
template_name = 'virtualization/virtualmachine/interfaces.html'
|
||||
actions = {
|
||||
**DEFAULT_ACTION_PERMISSIONS,
|
||||
'bulk_rename': {'change'},
|
||||
}
|
||||
tab = ViewTab(
|
||||
label=_('Interfaces'),
|
||||
badge=lambda obj: obj.interface_count,
|
||||
permission='virtualization.view_vminterface',
|
||||
weight=500
|
||||
)
|
||||
actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename')
|
||||
action_perms = defaultdict(set, **{
|
||||
'add': {'add'},
|
||||
'import': {'add'},
|
||||
'bulk_edit': {'change'},
|
||||
'bulk_delete': {'delete'},
|
||||
'bulk_rename': {'change'},
|
||||
})
|
||||
|
||||
def get_children(self, request, parent):
|
||||
return parent.interfaces.restrict(request.user, 'view').prefetch_related(
|
||||
|
Loading…
Reference in New Issue
Block a user