return type('VCTLocalFileForm', (base_class, ), attributes) if is_installed('firmware'): from firmware.admin import BaseImageInline from firmware.models import BaseImage from firmware.settings import FIRMWARE_BASE_IMAGE_EXTENSIONS if vct_settings.VCT_LOCAL_FILES: BaseImageInline.form = local_files_form_factory( BaseImage, 'image', extensions=FIRMWARE_BASE_IMAGE_EXTENSIONS) # Replace node firmware download for "VM manager" if vct_settings.VCT_VM_MANAGEMENT: insert_change_view_action(Node, vm_management) insertattr(Node, 'actions', vm_management) node_modeladmin = get_modeladmin(Node) old_get_change_view_actions_as_class = node_modeladmin.get_change_view_actions_as_class def get_change_view_actions_as_class(self): actions = old_get_change_view_actions_as_class() return [ action for action in actions if action.url_name != 'firmware' ] type( node_modeladmin ).get_change_view_actions_as_class = get_change_view_actions_as_class # Slices customization if vct_settings.VCT_LOCAL_FILES:
'name', 'description', 'type', '=node_archs', '^node_archs' ] fields = [ 'name', 'description', 'type', 'node_archs', 'image', 'image_sha256', 'is_active' ] readonly_fields = ['image_sha256'] def node_archs_str(self, instance): return ', '.join(instance.node_archs) node_archs_str.short_description = 'Node archs' node_archs_str.admin_order_field = 'node_archs' def formfield_for_dbfield(self, db_field, **kwargs): """ Make description input widget smaller """ if db_field.name == 'description': kwargs['widget'] = forms.Textarea(attrs={'cols': 85, 'rows': 5}) return super(TemplateAdmin, self).formfield_for_dbfield(db_field, **kwargs) admin.site.register(Sliver, SliverAdmin) admin.site.register(Slice, SliceAdmin) admin.site.register(Template, TemplateAdmin) # Monkey-Patching Section insertattr(Node, 'list_display', num_slivers) insertattr(Node, 'inlines', SliverNodeInline, weight=5)
from __future__ import absolute_import from controller.admin.utils import insertattr from nodes.models import Node from permissions.admin import PermissionGenericTabularInline from slices.models import Slice from users.models import User, Group from .models import SfaObject class SfaObjectInline(PermissionGenericTabularInline): fields = ('uuid', 'pubkey') model = SfaObject max_num = 1 verbose_name_plural = 'SFA' def get_readonly_fields(self, request, obj=None): ro_fields = super(SfaObjectInline, self).get_readonly_fields(request, obj=obj) sfa = obj.sfa if obj.sfa is not None and 'uuid' not in ro_fields: return ro_fields + ('uuid', ) return ro_fields # Hook SfaObject support for related models for model in [Slice, User, Group, Node]: insertattr(model, 'inlines', SfaObjectInline)
""" request.user as default host admin """ form = super(HostAdmin, self).get_form(request, *args, **kwargs) if 'owner' in form.base_fields: # ronly forms doesn't have initial user = request.user if not user.is_superuser: ro_widget = ReadOnlyWidget(user.id, user.get_username()) form.base_fields['owner'].widget = ro_widget form.base_fields['owner'].required = False else: form.base_fields['owner'].initial = user return form def queryset(self, request): """ Prevent regular users to see hosts from other users """ qset = super(HostAdmin, self).queryset(request) if request.user.is_superuser: return qset return qset.filter(owner=request.user) admin.site.register(Host, HostAdmin) admin.site.register(TincAddress, TincAddressAdmin) # Monkey-Patching Section insertattr(Node, 'inlines', TincHostInline, weight=-5) insertattr(Server, 'inlines', TincHostInline) insertattr(Island, 'inlines', ReadOnlyTincAddressInline)
'name', 'description', 'type', 'node_archs_str', 'image', 'is_active' ] list_filter = ['is_active', 'type', 'node_archs'] search_fields = ['name', 'description', 'type', '=node_archs', '^node_archs'] fields = [ 'name', 'description', 'type', 'node_archs', 'image', 'image_sha256', 'is_active' ] readonly_fields = ['image_sha256'] def node_archs_str(self, instance): return ', '.join(instance.node_archs) node_archs_str.short_description = 'Node archs' node_archs_str.admin_order_field = 'node_archs' def formfield_for_dbfield(self, db_field, **kwargs): """ Make description input widget smaller """ if db_field.name == 'description': kwargs['widget'] = forms.Textarea(attrs={'cols': 85, 'rows': 5}) return super(TemplateAdmin, self).formfield_for_dbfield(db_field, **kwargs) admin.site.register(Sliver, SliverAdmin) admin.site.register(Slice, SliceAdmin) admin.site.register(Template, TemplateAdmin) # Monkey-Patching Section insertattr(Node, 'list_display', num_slivers) insertattr(Node, 'inlines', SliverNodeInline, weight=5)
disk = extract_disk_available(statejs) # convert to human readable unit = disk['unit'] total = sizeof_fmt(disk['total'], unit) slv_dflt = sizeof_fmt(disk['slv_dflt'], unit) return "%s (%s)" % (total, slv_dflt) disk_available.short_description = mark_safe( '<span class="help-text" ' 'title="Disk available reported by the node:\ntotal (default per sliver)" ' 'style="padding-left:0; padding-right:12px">Disk available</span>') insertattr(Node, 'list_display', disk_available) insertattr(NodeListAdmin, 'list_display', disk_available) insertattr(Node, 'list_display', firmware_version) insertattr(NodeListAdmin, 'list_display', firmware_version) insertattr(Node, 'list_display', state_link) insertattr(NodeListAdmin, 'list_display', state_link) insertattr(Sliver, 'list_display', state_link) insertattr(Node, 'actions', refresh_state) insertattr(Sliver, 'actions', refresh_state) insertattr(Node, 'list_filter', NodeStateListFilter) insertattr(NodeListAdmin, 'list_filter', NodeStateListFilter) insertattr(Sliver, 'list_filter', SliverStateListFilter) insertattr(Node, 'list_filter', FirmwareVersionListFilter) SliverInline.sliver_state = state_link
from __future__ import absolute_import from controller.admin.utils import insertattr from nodes.models import Node from permissions.admin import PermissionGenericTabularInline from slices.models import Slice from users.models import User, Group from .models import SfaObject class SfaObjectInline(PermissionGenericTabularInline): fields = ('uuid', 'pubkey') model = SfaObject max_num = 1 verbose_name_plural = 'SFA' def get_readonly_fields(self, request, obj=None): ro_fields = super(SfaObjectInline, self).get_readonly_fields(request, obj=obj) sfa = obj.sfa if obj.sfa is not None and 'uuid' not in ro_fields: return ro_fields + ('uuid',) return ro_fields # Hook SfaObject support for related models for model in [Slice, User, Group, Node]: insertattr(model, 'inlines', SfaObjectInline)
attributes["__init__"] = __init__ return type("VCTLocalFileForm", (base_class,), attributes) if is_installed("firmware"): from firmware.admin import BaseImageInline from firmware.models import BaseImage from firmware.settings import FIRMWARE_BASE_IMAGE_EXTENSIONS if settings.VCT_LOCAL_FILES: BaseImageInline.form = local_files_form_factory(BaseImage, "image", extensions=FIRMWARE_BASE_IMAGE_EXTENSIONS) # Replace node firmware download for "VM manager" if settings.VCT_VM_MANAGEMENT: insert_change_view_action(Node, vm_management) insertattr(Node, "actions", vm_management) node_modeladmin = get_modeladmin(Node) old_get_change_view_actions_as_class = node_modeladmin.get_change_view_actions_as_class def get_change_view_actions_as_class(self): actions = old_get_change_view_actions_as_class() return [action for action in actions if action.url_name != "firmware"] type(node_modeladmin).get_change_view_actions_as_class = get_change_view_actions_as_class # Slices customization if settings.VCT_LOCAL_FILES: TemplateAdmin.form = local_files_form_factory( Template, "image", extensions=slices_settings.SLICES_TEMPLATE_IMAGE_EXTENSIONS )
from .actions import cache_node_db from .models import CnHost class CnHostInline(PermissionGenericTabularInline): fields = ['app_url', 'cndb_uri', 'cndb_cached'] readonly_fields = ['cndb_cached'] model = CnHost max_num = 1 verbose_name_plural = 'Community host' can_delete = False def cndb_cached(self, instance): date = instance.cndb_cached_on if not date: return 'Never' return date cndb_cached.short_description = 'CNDB cached on' # Monkey-Patching Section app_url_link = link('related_cnhost__app_url', description='CN URL') # NOTE: Disabled as is not finished and there isn't a nodedb instance. # insertattr(Node, 'actions', cache_node_db) # insert_change_view_action(Node, cache_node_db) insertattr(Node, 'inlines', CnHostInline) insertattr(Server, 'inlines', CnHostInline)
return 'No data' disk = extract_disk_available(statejs) # convert to human readable unit = disk['unit'] total = sizeof_fmt(disk['total'], unit) slv_dflt = sizeof_fmt(disk['slv_dflt'], unit) return "%s (%s)" % (total, slv_dflt) disk_available.short_description = mark_safe('<span class="help-text" ' 'title="Disk available reported by the node:\ntotal (default per sliver)" ' 'style="padding-left:0; padding-right:12px">Disk available</span>') insertattr(Node, 'list_display', disk_available) insertattr(NodeListAdmin, 'list_display', disk_available) insertattr(Node, 'list_display', firmware_version) insertattr(NodeListAdmin, 'list_display', firmware_version) insertattr(Node, 'list_display', state_link) insertattr(NodeListAdmin, 'list_display', state_link) insertattr(Sliver, 'list_display', state_link) insertattr(Node, 'actions', refresh_state) insertattr(Sliver, 'actions', refresh_state) insertattr(Node, 'list_filter', NodeStateListFilter) insertattr(Sliver, 'list_filter', SliverStateListFilter) insertattr(Node, 'list_filter', FirmwareVersionListFilter) SliverInline.sliver_state = state_link SliverInline.readonly_fields.append('sliver_state') SliverInline.fields.append('sliver_state')
from . import widgets as map_widgets from .models import Geolocation, NodeGeolocation class GisInline(PermissionTabularInline): """ Base class for create an inline that provides geolocation info. """ fields = ['address', 'geolocation'] model = Geolocation max_num = 1 formfield_overrides = { map_fields.AddressField: { 'widget': map_widgets.OSMAddressWidget(attrs={'id': 'id_address', 'size':'80'})}, map_fields.GeoLocationField: { 'widget': TextInput(attrs={'id': 'id_geolocation'})}, } verbose_name_plural = 'Geolocation' can_delete = False class Media: js = ('gis/js/collapsed_geolocation.js',) class NodeGisInline(GisInline): """ Inline instantiation for node geolocation. """ model = NodeGeolocation # Monkey-Patching Section insertattr(Node, 'inlines', NodeGisInline, weight=9)
css = { "all": ("resources/css/resource-admin.css",) } js = ('resources/js/collapsed_resource_requests.js',) def formfield_for_dbfield(self, db_field, **kwargs): """ Readonly resource name but form input still hidden """ if db_field.name == 'name': kwargs['widget'] = VerboseNameShowTextWidget() return super(ResourceReqAdminInline, self).formfield_for_dbfield(db_field, **kwargs) def get_readonly_fields(self, request, obj=None): """ Remove 'name' from readonly fields because its value is required to call properly Resource.get ResourceReqForm is in charge of mark it as readonly. """ ro_fields = super(ResourceReqAdminInline, self).get_readonly_fields(request, obj=obj) if 'name' in ro_fields: ro_fields.remove('name') return ro_fields for producer_model in ResourcePlugin.get_producers_models(): insertattr(producer_model, 'inlines', ResourceAdminInline) from slices.admin import SliceSliversAdmin for consumer_model in list(ResourcePlugin.get_consumers_models()) + [SliceSliversAdmin]: insertattr(consumer_model, 'inlines', ResourceReqAdminInline, weight=-1)
Only superusers or node admins can view sensible data. """ qs = super(NodeBuildFileInline, self).get_queryset(request) node = qs.first().node if qs.first() else None if (request.user.is_superuser or node and node.group.has_roles( request.user, roles=['group_admin', 'node_admin'])): return qs return qs.none() admin.site.register(Config, ConfigAdmin) admin.site.register(Build, BuildAdmin) # Monkey-Patching Section insertattr(Node, 'inlines', NodeBuildFileInline, weight=4) insertattr(Node, 'actions', get_firmware) node_modeladmin = get_modeladmin(Node) node_modeladmin.set_change_view_action(get_firmware) old_get_urls = node_modeladmin.get_urls def get_urls(self): extra_urls = patterns( "", url("^(?P<node_id>\d+)/firmware/info/$", wrap_admin_view(self, build_info_view), name='nodes_node_firmware_build_info'), url("^(?P<node_id>\d+)/firmware/delete/$", wrap_admin_view(self, delete_build_view),
qs = super(NodeBuildFileInline, self).get_queryset(request) node = qs.first().node if qs.first() else None if (request.user.is_superuser or node and node.group.has_roles(request.user, roles=['group_admin', 'node_admin'])): return qs return qs.none() admin.site.register(Config, ConfigAdmin) admin.site.register(Build, BuildAdmin) # Monkey-Patching Section insertattr(Node, 'inlines', NodeBuildFileInline, weight=4) insertattr(Node, 'actions', get_firmware) node_modeladmin = get_modeladmin(Node) node_modeladmin.set_change_view_action(get_firmware) old_get_urls = node_modeladmin.get_urls def get_urls(self): extra_urls = patterns("", url("^(?P<node_id>\d+)/firmware/info/$", wrap_admin_view(self, build_info_view), name='nodes_node_firmware_build_info'), url("^(?P<node_id>\d+)/firmware/delete/$", wrap_admin_view(self, delete_build_view), name='nodes_node_firmware_delete'), ) return extra_urls + old_get_urls()
def get_form(self, request, *args, **kwargs): """ request.user as default host admin """ form = super(HostAdmin, self).get_form(request, *args, **kwargs) if 'owner' in form.base_fields: # ronly forms doesn't have initial user = request.user if not user.is_superuser: ro_widget = ReadOnlyWidget(user.id, user.get_username()) form.base_fields['owner'].widget = ro_widget form.base_fields['owner'].required = False else: form.base_fields['owner'].initial = user return form def get_queryset(self, request): """ Prevent regular users to see hosts from other users """ qset = super(HostAdmin, self).get_queryset(request) if request.user.is_superuser: return qset return qset.filter(owner=request.user) admin.site.register(Host, HostAdmin) admin.site.register(TincAddress, TincAddressAdmin) # Monkey-Patching Section insertattr(Node, 'inlines', TincHostInline, weight=-5) insertattr(Server, 'inlines', TincHostInline) insertattr(Island, 'inlines', ReadOnlyTincAddressInline)