from core.models import Site
from core.models import *
from openstack.manager import OpenStackManager

from django.contrib import admin
from django.contrib.auth.models import Group
from django import forms
from django.utils.safestring import mark_safe
from django.contrib.auth.admin import UserAdmin
from django.contrib.admin.widgets import FilteredSelectMultiple
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.signals import user_logged_in
from django.utils import timezone
from django.contrib.contenttypes import generic
from suit.widgets import LinkedSelect
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse, NoReverseMatch

import django_evolution 

class ReadOnlyAwareAdmin(admin.ModelAdmin):

    def has_add_permission(self, request, obj=None):
        return (not self.__user_is_readonly(request))
 
    def has_delete_permission(self, request, obj=None):
        return (not self.__user_is_readonly(request))

    def save_model(self, request, obj, form, change):
        if self.__user_is_readonly(request):
            raise PermissionDenied
            #pass
        else:
            return super(ReadOnlyAwareAdmin, self).save_model(request, obj, form, change)

    def get_actions(self,request):
        actions = super(ReadOnlyAwareAdmin,self).get_actions(request)

        if self.__user_is_readonly(request):
            if 'delete_selected' in actions:
                del actions['delete_selected']

        return actions

    def change_view(self,request,object_id, extra_context=None):
        if self.__user_is_readonly(request):
            if not hasattr(self, "readonly_save"):
                # save the original readonly fields
                self.readonly_save = self.readonly_fields
                self.inlines_save = self.inlines
            self.readonly_fields=self.user_readonly_fields
            self.inlines = self.user_readonly_inlines
        else:
            if hasattr(self, "readonly_save"):
                # restore the original readonly fields
                self.readonly_fields = self.readonly_save
                self.inlines = self.inlines_save

        try:
            return super(ReadOnlyAwareAdmin, self).change_view(request, object_id, extra_context=extra_context)
        except PermissionDenied:
            pass
        if request.method == 'POST':
            raise PermissionDenied
        request.readonly = True
        return super(ReadOnlyAwareAdmin, self).change_view(request, object_id, extra_context=extra_context)

    def __user_is_readonly(self, request):
        return request.user.isReadOnlyUser()

class SingletonAdmin (admin.ModelAdmin):
    def has_add_permission(self, request):
        num_objects = self.model.objects.count()
        if num_objects >= 1:
            return False
        else:
            return True


class PlStackTabularInline(admin.TabularInline):
    def __init__(self, *args, **kwargs):
        super(PlStackTabularInline, self).__init__(*args, **kwargs)

        # InlineModelAdmin as no get_fields() method, so in order to add
        # the selflink field, we override __init__ to modify self.fields and
        # self.readonly_fields.

        self.setup_selflink()

    def get_change_url(self, model, id):
        """ Get the URL to a change form in the admin for this model """
        reverse_path = "admin:%s_change" % (model._meta.db_table)
        try:
            url = reverse(reverse_path, args=(id,))
        except NoReverseMatch:
            return None

        return url

    def setup_selflink(self):
        if hasattr(self, "selflink_fieldname"):
            """ self.selflink_model can be defined to punch through a relation
                to its target object. For example, in SliceNetworkInline, set
                selflink_model = "network", and the URL will lead to the Network
                object instead of trying to bring up a change view of the
                SliceNetwork object.
            """
            self.selflink_model = getattr(self.model,self.selflink_fieldname).field.rel.to
        else:
            self.selflink_model = self.model

        url = self.get_change_url(self.selflink_model, 0)

        # We don't have an admin for this object, so don't create the
        # selflink.
        if (url == None):
            return

        # Since we need to add "selflink" to the field list, we need to create
        # self.fields if it is None.
        if (self.fields is None):
            self.fields = []
            for f in self.model._meta.fields:
                if f.editable and f.name != "id":
                    self.fields.append(f.name)

        self.fields = tuple(self.fields) + ("selflink", )

        if self.readonly_fields is None:
            self.readonly_fields = ()

        self.readonly_fields = tuple(self.readonly_fields) + ("selflink", )

    def selflink(self, obj):
        if hasattr(self, "selflink_fieldname"):
            obj = getattr(obj, self.selflink_fieldname)

        if obj.id:
            url = self.get_change_url(self.selflink_model, obj.id)
            return "<a href='%s'>Details</a>" % str(url)
        else:
            return "Not present"

    selflink.allow_tags = True
    selflink.short_description = "Details"

class ReadOnlyTabularInline(PlStackTabularInline):
    can_delete = False

    def get_readonly_fields(self, request, obj=None):
        return self.fields

    def has_add_permission(self, request):
        return False

class ReservationROInline(ReadOnlyTabularInline):
    model = Reservation
    extra = 0
    suit_classes = 'suit-tab suit-tab-reservations'
    fields = ['startTime','slice','duration']

class ReservationInline(PlStackTabularInline):
    model = Reservation
    extra = 0
    suit_classes = 'suit-tab suit-tab-reservations'
        
    def queryset(self, request):
        return Reservation.select_by_user(request.user)

class TagROInline(generic.GenericTabularInline):
    model = Tag
    extra = 0
    suit_classes = 'suit-tab suit-tab-tags'
    can_delete = False
    fields = ['service', 'name', 'value']

    def get_readonly_fields(self, request, obj=None):
        return self.fields

    def has_add_permission(self, request):
        return False


class TagInline(generic.GenericTabularInline):
    model = Tag
    extra = 0
    suit_classes = 'suit-tab suit-tab-tags'
    fields = ['service', 'name', 'value']

    def queryset(self, request):
        return Tag.select_by_user(request.user)

class NetworkLookerUpper:
    """ This is a callable that looks up a network name in a sliver and returns
        the ip address for that network.
    """

    def __init__(self, name):
        self.short_description = name
        self.__name__ = name
        self.network_name = name

    def __call__(self, obj):
        if obj is not None:
            for nbs in obj.networksliver_set.all():
                if (nbs.network.name == self.network_name):
                    return nbs.ip
        return ""

    def __str__(self):
        return self.network_name

class SliverROInline(ReadOnlyTabularInline):
    model = Sliver
    fields = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
    suit_classes = 'suit-tab suit-tab-slivers'

class SliverInline(PlStackTabularInline):
    model = Sliver
    fields = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
    extra = 0
    readonly_fields = ['ip', 'instance_name']
    suit_classes = 'suit-tab suit-tab-slivers'

    def queryset(self, request):
        return Sliver.select_by_user(request.user)

# Note this is breaking in the admin.py when trying to use an inline to add a node/image 
#    def _declared_fieldsets(self):
#        # Return None so django will call get_fieldsets and we can insert our
#        # dynamic fields
#        return None
#
#    def get_readonly_fields(self, request, obj=None):
#        readonly_fields = super(SliverInline, self).get_readonly_fields(request, obj)
#
#        # Lookup the networks that are bound to the slivers, and add those
#        # network names to the list of readonly fields.
#
#        for sliver in obj.slivers.all():
#            for nbs in sliver.networksliver_set.all():
#                if nbs.ip:
#                    network_name = nbs.network.name
#                    if network_name not in [str(x) for x in readonly_fields]:
#                        readonly_fields.append(NetworkLookerUpper(network_name))
#
#        return readonly_fields
#
#    def get_fieldsets(self, request, obj=None):
#        form = self.get_formset(request, obj).form
#        # fields = the read/write files + the read-only fields
#        fields = self.fields
#        for fieldName in self.get_readonly_fields(request,obj):
#            if not fieldName in fields:
#                fields.append(fieldName)
#
#        return [(None, {'fields': fields})]

    

class SiteROInline(ReadOnlyTabularInline):
    model = Site
    extra = 0
    fields = ['name', 'login_base', 'site_url', 'enabled'] 
    suit_classes = 'suit-tab suit-tab-sites'

class SiteInline(PlStackTabularInline):
    model = Site
    extra = 0
    suit_classes = 'suit-tab suit-tab-sites'

    def queryset(self, request):
        return Site.select_by_user(request.user)

class UserROInline(ReadOnlyTabularInline):
    model = User
    fields = ['email', 'firstname', 'lastname']
    extra = 0
    suit_classes = 'suit-tab suit-tab-users'

class UserInline(PlStackTabularInline):
    model = User
    fields = ['email', 'firstname', 'lastname']
    extra = 0
    suit_classes = 'suit-tab suit-tab-users'

    def queryset(self, request):
        return User.select_by_user(request.user)

class SliceROInline(ReadOnlyTabularInline):
    model = Slice
    suit_classes = 'suit-tab suit-tab-slices'
    fields = ['name','site', 'serviceClass', 'service']

class SliceInline(PlStackTabularInline):
    model = Slice
    fields = ['name','site', 'serviceClass', 'service']
    extra = 0
    suit_classes = 'suit-tab suit-tab-slices'

    def queryset(self, request):
        return Slice.select_by_user(request.user)

class NodeROInline(ReadOnlyTabularInline):
    model = Node
    extra = 0
    suit_classes = 'suit-tab suit-tab-nodes'
    fields = ['name','deployment']

class NodeInline(PlStackTabularInline):
    model = Node
    extra = 0
    suit_classes = 'suit-tab suit-tab-nodes'
    fields = ['name','deployment']

class DeploymentPrivilegeROInline(ReadOnlyTabularInline):
    model = DeploymentPrivilege
    extra = 0
    suit_classes = 'suit-tab suit-tab-deploymentprivileges'
    fields = ['user','role']

class DeploymentPrivilegeInline(PlStackTabularInline):
    model = DeploymentPrivilege
    extra = 0
    suit_classes = 'suit-tab suit-tab-deploymentprivileges'
    fields = ['user','role']

    def queryset(self, request):
        return DeploymentPrivilege.select_by_user(request.user)

#CLEANUP DOUBLE SitePrivilegeInline
class SitePrivilegeROInline(ReadOnlyTabularInline):
    model = SitePrivilege
    extra = 0
    suit_classes = 'suit-tab suit-tab-siteprivileges'
    fields = ['user','site', 'role']

class SitePrivilegeInline(PlStackTabularInline):
    model = SitePrivilege
    extra = 0
    suit_classes = 'suit-tab suit-tab-siteprivileges'
    fields = ['user','site', 'role']

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'site':
            kwargs['queryset'] = Site.select_by_user(request.user)

        if db_field.name == 'user':
            kwargs['queryset'] = User.select_by_user(request.user)
        return super(SitePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        return SitePrivilege.select_by_user(request.user)

class SiteDeploymentROInline(ReadOnlyTabularInline):
    model = SiteDeployments
    #model = Site.deployments.through
    extra = 0
    suit_classes = 'suit-tab suit-tab-sitedeployments'
    fields = ['deployment','site']

class SiteDeploymentInline(PlStackTabularInline):
    model = SiteDeployments
    #model = Site.deployments.through
    extra = 0
    suit_classes = 'suit-tab suit-tab-deployments'
    fields = ['deployment','site']

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'site':
            kwargs['queryset'] = Site.select_by_user(request.user)

        if db_field.name == 'deployment':
            kwargs['queryset'] = Deployment.select_by_user(request.user)
        return super(SiteDeploymentInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        return SiteDeployments.select_by_user(request.user)


class SlicePrivilegeROInline(ReadOnlyTabularInline):
    model = SlicePrivilege
    extra = 0
    suit_classes = 'suit-tab suit-tab-sliceprivileges'
    fields = ['user', 'slice', 'role']

class SlicePrivilegeInline(PlStackTabularInline):
    model = SlicePrivilege
    suit_classes = 'suit-tab suit-tab-sliceprivileges'
    extra = 0
    fields = ('user', 'slice','role')

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'slice':
           kwargs['queryset'] = Slice.select_by_user(request.user) 
        if db_field.name == 'user':
           kwargs['queryset'] = User.select_by_user(request.user) 

        return super(SlicePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        return SlicePrivilege.select_by_user(request.user)

class SliceNetworkROInline(ReadOnlyTabularInline):
    model = Network.slices.through
    extra = 0
    verbose_name = "Network Connection"
    verbose_name_plural = "Network Connections"
    suit_classes = 'suit-tab suit-tab-slicenetworks'
    fields = ['network']

class SliceNetworkInline(PlStackTabularInline):
    model = Network.slices.through
    selflink_fieldname = "network"
    extra = 0
    verbose_name = "Network Connection"
    verbose_name_plural = "Network Connections"
    suit_classes = 'suit-tab suit-tab-slicenetworks'

class PlainTextWidget(forms.HiddenInput):
    input_type = 'hidden'

    def render(self, name, value, attrs=None):
        if value is None:
            value = ''
        return mark_safe(str(value) + super(PlainTextWidget, self).render(name, value, attrs))

class PlanetStackBaseAdmin(ReadOnlyAwareAdmin):
    save_on_top = False
    
    def save_model(self, request, obj, form, change):
        obj.caller = request.user
        # update openstack connection to use this site/tenant
        obj.save_by_user(request.user)

    def delete_model(self, request, obj):
        obj.delete_by_user(request.user)

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for instance in instances:
            instance.save_by_user(request.user)
        formset.save_m2m()

class SliceRoleAdmin(PlanetStackBaseAdmin):
    model = SliceRole
    pass

class SiteRoleAdmin(PlanetStackBaseAdmin):
    model = SiteRole
    pass

class DeploymentAdminForm(forms.ModelForm):
    sites = forms.ModelMultipleChoiceField(
        queryset=Site.objects.all(),
        required=False,
        widget=FilteredSelectMultiple(
            verbose_name=('Sites'), is_stacked=False
        )
    )
    class Meta:
        model = Deployment

    def __init__(self, *args, **kwargs):
      super(DeploymentAdminForm, self).__init__(*args, **kwargs)

      if self.instance and self.instance.pk:
        self.fields['sites'].initial = [x.site for x in self.instance.sitedeployments_set.all()]

    def save(self, commit=True):
      deployment = super(DeploymentAdminForm, self).save(commit=False)

      if commit:
        deployment.save()

      if deployment.pk:
        # save_m2m() doesn't seem to work with 'through' relations. So we
        #    create/destroy the through models ourselves. There has to be
        #    a better way...

        sites = self.cleaned_data['sites']

        existing_sites = []
        for sdp in list(deployment.sitedeployments_set.all()):
            if sdp.site not in sites:
                #print "deleting site", sdp.site
                sdp.delete()
            else:
                existing_sites.append(sdp.site)

        for site in sites:
            if site not in existing_sites:
                #print "adding site", site
                sdp = SiteDeployments(site=site, deployment=deployment)
                sdp.save()

        self.save_m2m()

      return deployment

class DeploymentAdminROForm(DeploymentAdminForm):
    def save(self, commit=True):
        raise PermissionDenied

class SiteAssocInline(PlStackTabularInline):
    model = Site.deployments.through
    extra = 0
    suit_classes = 'suit-tab suit-tab-sites'

class DeploymentAdmin(PlanetStackBaseAdmin):
    #form = DeploymentAdminForm
    model = Deployment
    fieldList = ['name','sites']
    fieldsets = [(None, {'fields': fieldList, 'classes':['suit-tab suit-tab-sites']})]
    inlines = [DeploymentPrivilegeInline,NodeInline,TagInline]

    user_readonly_inlines = [DeploymentPrivilegeROInline,NodeROInline,TagROInline]
    user_readonly_fields = ['name']

    suit_form_tabs =(('sites','Deployment Details'),('nodes','Nodes'),('deploymentprivileges','Privileges'),('tags','Tags'))

    def get_form(self, request, obj=None, **kwargs):
        if request.user.isReadOnlyUser():
            kwargs["form"] = DeploymentAdminROForm
        else:
            kwargs["form"] = DeploymentAdminForm
        return super(DeploymentAdmin,self).get_form(request, obj, **kwargs)

class ServiceAttrAsTabROInline(ReadOnlyTabularInline):
    model = ServiceAttribute
    fields = ['name','value']
    extra = 0
    suit_classes = 'suit-tab suit-tab-serviceattrs'

class ServiceAttrAsTabInline(PlStackTabularInline):
    model = ServiceAttribute
    fields = ['name','value']
    extra = 0
    suit_classes = 'suit-tab suit-tab-serviceattrs'

class ServiceAdmin(PlanetStackBaseAdmin):
    list_display = ("name","description","versionNumber","enabled","published")
    fieldList = ["name","description","versionNumber","enabled","published"]
    fieldsets = [(None, {'fields': fieldList, 'classes':['suit-tab suit-tab-general']})]
    inlines = [ServiceAttrAsTabInline,SliceInline]

    user_readonly_fields = fieldList
    user_readonly_inlines = [ServiceAttrAsTabROInline,SliceROInline]

    suit_form_tabs =(('general', 'Service Details'),
        ('slices','Slices'),
        ('serviceattrs','Additional Attributes'),
    )

class SiteAdmin(PlanetStackBaseAdmin):
    fieldList = ['name', 'site_url', 'enabled', 'is_public', 'login_base', 'accountLink','location']
    fieldsets = [
        (None, {'fields': fieldList, 'classes':['suit-tab suit-tab-general']}),
        #('Deployment Networks', {'fields': ['deployments'], 'classes':['suit-tab suit-tab-deployments']}),
    ]
    suit_form_tabs =(('general', 'Site Details'),
        ('users','Users'),
        ('siteprivileges','Privileges'),
        ('deployments','Deployments'),
        ('slices','Slices'),
        ('nodes','Nodes'), 
        ('tags','Tags'),
    )
    readonly_fields = ['accountLink']

    user_readonly_fields = ['name', 'deployments','site_url', 'enabled', 'is_public', 'login_base', 'accountLink']
    user_readonly_inlines = [SliceROInline,UserROInline,TagROInline, NodeROInline, SitePrivilegeROInline,SiteDeploymentROInline]

    list_display = ('name', 'login_base','site_url', 'enabled')
    filter_horizontal = ('deployments',)
    inlines = [SliceInline,UserInline,TagInline, NodeInline, SitePrivilegeInline, SiteDeploymentInline]
    search_fields = ['name']

    def queryset(self, request):
        #print dir(UserInline)
        return Site.select_by_user(request.user)

    def get_formsets(self, request, obj=None):
        for inline in self.get_inline_instances(request, obj):
            # hide MyInline in the add view
            if obj is None:
                continue
            if isinstance(inline, SliceInline):
                inline.model.caller = request.user
            yield inline.get_formset(request, obj)

    def get_formsets(self, request, obj=None):
        for inline in self.get_inline_instances(request, obj):
            # hide MyInline in the add view
            if obj is None:
                continue
            if isinstance(inline, SliverInline):
                inline.model.caller = request.user
            yield inline.get_formset(request, obj)

    def accountLink(self, obj):
        link_obj = obj.accounts.all()
        if link_obj:
            reverse_path = "admin:core_account_change"
            url = reverse(reverse_path, args =(link_obj[0].id,))
            return "<a href='%s'>%s</a>" % (url, "view billing details")
        else:
            return "no billing data for this site"
    accountLink.allow_tags = True
    accountLink.short_description = "Billing"

    def save_model(self, request, obj, form, change):
        # update openstack connection to use this site/tenant
        obj.save_by_user(request.user) 

    def delete_model(self, request, obj):
        obj.delete_by_user(request.user)
        

class SitePrivilegeAdmin(PlanetStackBaseAdmin):
    fieldList = ['user', 'site', 'role']
    fieldsets = [
        (None, {'fields': fieldList, 'classes':['collapse']})
    ]
    list_display = ('user', 'site', 'role')
    user_readonly_fields = fieldList
    user_readonly_inlines = []

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'site':
            if not request.user.is_admin:
                # only show sites where user is an admin or pi
                sites = set()
                for site_privilege in SitePrivilege.objects.filer(user=request.user):
                    if site_privilege.role.role_type in ['admin', 'pi']:
                        sites.add(site_privilege.site)
                kwargs['queryset'] = Site.objects.filter(site__in=list(sites))

        if db_field.name == 'user':
            if not request.user.is_admin:
                # only show users from sites where caller has admin or pi role
                roles = Role.objects.filter(role_type__in=['admin', 'pi'])
                site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
                sites = [site_privilege.site for site_privilege in site_privileges]
                site_privileges = SitePrivilege.objects.filter(site__in=sites)
                emails = [site_privilege.user.email for site_privilege in site_privileges]
                users = User.objects.filter(email__in=emails)
                kwargs['queryset'] = users

        return super(SitePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        # admins can see all privileges. Users can only see privileges at sites
        # where they have the admin role or pi role.
        qs = super(SitePrivilegeAdmin, self).queryset(request)
        #if not request.user.is_admin:
        #    roles = Role.objects.filter(role_type__in=['admin', 'pi'])
        #    site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
        #    login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
        #    sites = Site.objects.filter(login_base__in=login_bases)
        #    qs = qs.filter(site__in=sites)
        return qs

class SliceForm(forms.ModelForm):
    class Meta:
        model = Slice
        widgets = {
            'service': LinkedSelect 
        }

class SliceAdmin(PlanetStackBaseAdmin):
    form = SliceForm
    fieldList = ['name', 'site', 'serviceClass', 'enabled','description', 'service', 'slice_url', 'max_slivers']
    fieldsets = [('Slice Details', {'fields': fieldList, 'classes':['suit-tab suit-tab-general']}),]
    list_display = ('name', 'site','serviceClass', 'slice_url', 'max_slivers')
    inlines = [SlicePrivilegeInline,SliverInline, TagInline, ReservationInline,SliceNetworkInline]

    user_readonly_fields = fieldList
    user_readonly_inlines = [SlicePrivilegeROInline,SliverROInline,TagROInline, ReservationROInline, SliceNetworkROInline]

    suit_form_tabs =(('general', 'Slice Details'),
        ('slicenetworks','Networks'),
        ('sliceprivileges','Privileges'),
        ('slivers','Slivers'),
        ('tags','Tags'),
        ('reservations','Reservations'),
    )

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'site':
            kwargs['queryset'] = Site.select_by_user(request.user)
                
        return super(SliceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        # admins can see all keys. Users can only see slices they belong to.
        return Slice.select_by_user(request.user)

    def get_formsets(self, request, obj=None):
        for inline in self.get_inline_instances(request, obj):
            # hide MyInline in the add view
            if obj is None:
                continue
            if isinstance(inline, SliverInline):
                inline.model.caller = request.user
            yield inline.get_formset(request, obj)


class SlicePrivilegeAdmin(PlanetStackBaseAdmin):
    fieldsets = [
        (None, {'fields': ['user', 'slice', 'role']})
    ]
    list_display = ('user', 'slice', 'role')

    user_readonly_fields = ['user', 'slice', 'role']
    user_readonly_inlines = []

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'slice':
            kwargs['queryset'] = Slice.select_by_user(request.user)
        
        if db_field.name == 'user':
            kwargs['queryset'] = User.select_by_user(request.user)

        return super(SlicePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        # admins can see all memberships. Users can only see memberships of
        # slices where they have the admin role.
        return SlicePrivilege.select_by_user(request.user)

    def save_model(self, request, obj, form, change):
        # update openstack connection to use this site/tenant
        auth = request.session.get('auth', {})
        auth['tenant'] = obj.slice.name
        obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
        obj.save()

    def delete_model(self, request, obj):
        # update openstack connection to use this site/tenant
        auth = request.session.get('auth', {})
        auth['tenant'] = obj.slice.name
        obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
        obj.delete()


class ImageAdmin(PlanetStackBaseAdmin):

    fieldsets = [('Image Details', 
                   {'fields': ['name', 'disk_format', 'container_format'], 
                    'classes': ['suit-tab suit-tab-general']})
               ]

    suit_form_tabs =(('general','Image Details'),('slivers','Slivers'))

    inlines = [SliverInline]
    
    user_readonly_fields = ['name', 'disk_format', 'container_format']
    user_readonly_inlines = [SliverROInline]
    
class NodeForm(forms.ModelForm):
    class Meta:
        widgets = {
            'site': LinkedSelect,
            'deployment': LinkedSelect
        }

class NodeAdmin(PlanetStackBaseAdmin):
    form = NodeForm
    list_display = ('name', 'site', 'deployment')
    list_filter = ('deployment',)

    inlines = [TagInline,SliverInline]
    fieldsets = [('Node Details', {'fields': ['name','site','deployment'], 'classes':['suit-tab suit-tab-details']})]

    user_readonly_fields = ['name','site','deployment']
    user_readonly_inlines = [TagInline,SliverInline]

    suit_form_tabs =(('details','Node Details'),('slivers','Slivers'),('tags','Tags'))


class SliverForm(forms.ModelForm):
    class Meta:
        model = Sliver
        ip = forms.CharField(widget=PlainTextWidget)
        instance_name = forms.CharField(widget=PlainTextWidget)
        widgets = {
            'ip': PlainTextWidget(),
            'instance_name': PlainTextWidget(),
            'slice': LinkedSelect,
            'deploymentNetwork': LinkedSelect,
            'node': LinkedSelect,
            'image': LinkedSelect
        }

class TagAdmin(PlanetStackBaseAdmin):
    list_display = ['service', 'name', 'value', 'content_type', 'content_object',]
    user_readonly_fields = ['service', 'name', 'value', 'content_type', 'content_object',]
    user_readonly_inlines = []

class SliverAdmin(PlanetStackBaseAdmin):
    form = SliverForm
    fieldsets = [
        ('Sliver Details', {'fields': ['slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'numberCores', 'image', ], 'classes': ['suit-tab suit-tab-general'], })
    ]
    list_display = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']

    suit_form_tabs =(('general', 'Sliver Details'),
        ('tags','Tags'),
    )

    inlines = [TagInline]

    user_readonly_fields = ['slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'numberCores', 'image']
    user_readonly_inlines = [TagROInline]

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'slice':
            kwargs['queryset'] = Slice.select_by_user(request.user)

        return super(SliverAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        # admins can see all slivers. Users can only see slivers of 
        # the slices they belong to.
        return Sliver.select_by_user(request.user)


    def get_formsets(self, request, obj=None):
        # make some fields read only if we are updating an existing record
        if obj == None:
            #self.readonly_fields = ('ip', 'instance_name') 
            self.readonly_fields = () 
        else:
            self.readonly_fields = () 
            #self.readonly_fields = ('ip', 'instance_name', 'slice', 'image', 'key') 

        for inline in self.get_inline_instances(request, obj):
            # hide MyInline in the add view
            if obj is None:
                continue
            if isinstance(inline, SliverInline):
                inline.model.caller = request.user
            yield inline.get_formset(request, obj)

    #def save_model(self, request, obj, form, change):
    #    # update openstack connection to use this site/tenant
    #    auth = request.session.get('auth', {})
    #    auth['tenant'] = obj.slice.name
    #    obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
    #    obj.creator = request.user
    #    obj.save()

    #def delete_model(self, request, obj):
    #    # update openstack connection to use this site/tenant
    #    auth = request.session.get('auth', {})
    #    auth['tenant'] = obj.slice.name
    #    obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
    #    obj.delete()

class UserCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ('email', 'firstname', 'lastname', 'phone', 'public_key')

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserCreationForm, self).save(commit=False)
        user.password = self.cleaned_data["password1"]
        #user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    """A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    password hash display field.
    """
    password = ReadOnlyPasswordHashField(label='Password',
                   help_text= '<a href=\"password/\">Change Password</a>.')

    class Meta:
        model = User

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]

class UserDashboardViewInline(PlStackTabularInline):
    model = UserDashboardView
    extra = 0
    suit_classes = 'suit-tab suit-tab-dashboards'
    fields = ['user', 'dashboardView', 'order']

class UserDashboardViewROInline(ReadOnlyTabularInline):
    model = UserDashboardView
    extra = 0
    suit_classes = 'suit-tab suit-tab-dashboards'
    fields = ['user', 'dashboardView', 'order']

class UserAdmin(UserAdmin):
    class Meta:
        app_label = "core"

    # The forms to add and change user instances
    form = UserChangeForm
    add_form = UserCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ('email', 'firstname', 'lastname', 'site', 'last_login')
    #list_display = ('email', 'username','firstname', 'lastname', 'is_admin', 'last_login')
    list_filter = ('site',)
    inlines = [SlicePrivilegeInline,SitePrivilegeInline,DeploymentPrivilegeInline,UserDashboardViewInline]

    fieldListLoginDetails = ['email','site','password','is_readonly','is_amin','public_key']
    fieldListContactInfo = ['firstname','lastname','phone','timezone']

    fieldsets = (
        ('Login Details', {'fields': ['email', 'site','password', 'is_readonly', 'is_admin', 'public_key'], 'classes':['suit-tab suit-tab-general']}),
        ('Contact Information', {'fields': ('firstname','lastname','phone', 'timezone'), 'classes':['suit-tab suit-tab-contact']}),
        #('Dashboard Views', {'fields': ('dashboards',), 'classes':['suit-tab suit-tab-dashboards']}),
        #('Important dates', {'fields': ('last_login',)}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'firstname', 'lastname', 'is_readonly', 'phone', 'public_key','password1', 'password2')}
        ),
    )
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()

    user_readonly_fields = fieldListLoginDetails
    user_readonly_inlines = [SlicePrivilegeROInline,SitePrivilegeROInline,DeploymentPrivilegeROInline,UserDashboardViewROInline]

    suit_form_tabs =(('general','Login Details'),
                     ('contact','Contact Information'),
                     ('sliceprivileges','Slice Privileges'),
                     ('siteprivileges','Site Privileges'),
                     ('deploymentprivileges','Deployment Privileges'),
                     ('dashboards','Dashboard Views'))

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'site':
            kwargs['queryset'] = Site.select_by_user(request.user)

        return super(UserAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def has_add_permission(self, request, obj=None):
        return (not self.__user_is_readonly(request))

    def has_delete_permission(self, request, obj=None):
        return (not self.__user_is_readonly(request))

    def get_actions(self,request):
        actions = super(UserAdmin,self).get_actions(request)

        if self.__user_is_readonly(request):
            if 'delete_selected' in actions:
                del actions['delete_selected']

        return actions

    def change_view(self,request,object_id, extra_context=None):

        if self.__user_is_readonly(request):
            self.readonly_fields=self.user_readonly_fields
            self.inlines = self.user_readonly_inlines
        try:
            return super(UserAdmin, self).change_view(request, object_id, extra_context=extra_context)
        except PermissionDenied:
            pass
        if request.method == 'POST':
            raise PermissionDenied
        request.readonly = True
        return super(UserAdmin, self).change_view(request, object_id, extra_context=extra_context)

    def __user_is_readonly(self, request):
        #groups = [x.name for x in request.user.groups.all() ]
        #return "readonly" in groups
        return request.user.isReadOnlyUser()

    def queryset(self, request):
        return User.select_by_user(request.user)

class DashboardViewAdmin(PlanetStackBaseAdmin):
    fieldsets = [('Dashboard View Details',
                   {'fields': ['name', 'url'],
                    'classes': ['suit-tab suit-tab-general']})
               ]

    suit_form_tabs =(('general','Dashboard View Details'),)

class ServiceResourceROInline(ReadOnlyTabularInline):
    model = ServiceResource
    extra = 0
    fields = ['serviceClass', 'name', 'maxUnitsDeployment', 'maxUnitsNode', 'maxDuration', 'bucketInRate', 'bucketMaxSize', 'cost', 'calendarReservable']

class ServiceResourceInline(PlStackTabularInline):
    model = ServiceResource
    extra = 0

class ServiceClassAdmin(PlanetStackBaseAdmin):
    list_display = ('name', 'commitment', 'membershipFee')
    inlines = [ServiceResourceInline]

    user_readonly_fields = ['name', 'commitment', 'membershipFee']
    user_readonly_inlines = []

class ReservedResourceROInline(ReadOnlyTabularInline):
    model = ReservedResource
    extra = 0
    fields = ['sliver', 'resource','quantity','reservationSet']
    suit_classes = 'suit-tab suit-tab-reservedresources'

class ReservedResourceInline(PlStackTabularInline):
    model = ReservedResource
    extra = 0
    suit_classes = 'suit-tab suit-tab-reservedresources'

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        field = super(ReservedResourceInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

        if db_field.name == 'resource':
            # restrict resources to those that the slice's service class allows
            if request._slice is not None:
                field.queryset = field.queryset.filter(serviceClass = request._slice.serviceClass, calendarReservable=True)
                if len(field.queryset) > 0:
                    field.initial = field.queryset.all()[0]
            else:
                field.queryset = field.queryset.none()
        elif db_field.name == 'sliver':
            # restrict slivers to those that belong to the slice
            if request._slice is not None:
                field.queryset = field.queryset.filter(slice = request._slice)
            else:
                field.queryset = field.queryset.none()

        return field

    def queryset(self, request):
        return ReservedResource.select_by_user(request.user)

class ReservationChangeForm(forms.ModelForm):
    class Meta:
        model = Reservation
        widgets = {
            'slice' : LinkedSelect
        }

class ReservationAddForm(forms.ModelForm):
    slice = forms.ModelChoiceField(queryset=Slice.objects.all(), widget=forms.Select(attrs={"onChange":"document.getElementById('id_refresh').value=1; submit()"}))
    refresh = forms.CharField(widget=forms.HiddenInput())

    class Media:
       css = {'all': ('planetstack.css',)}   # .field-refresh { display: none; }

    def clean_slice(self):
        slice = self.cleaned_data.get("slice")
        x = ServiceResource.objects.filter(serviceClass = slice.serviceClass, calendarReservable=True)
        if len(x) == 0:
            raise forms.ValidationError("The slice you selected does not have a service class that allows reservations")
        return slice

    class Meta:
        model = Reservation
        widgets = {
            'slice' : LinkedSelect
        }


class ReservationAddRefreshForm(ReservationAddForm):
    """ This form is displayed when the Reservation Form receives an update
        from the Slice dropdown onChange handler. It doesn't validate the
        data and doesn't save the data. This will cause the form to be
        redrawn.
    """

    """ don't validate anything other than slice """
    dont_validate_fields = ("startTime", "duration")

    def full_clean(self):
        result = super(ReservationAddForm, self).full_clean()

        for fieldname in self.dont_validate_fields:
            if fieldname in self._errors:
                del self._errors[fieldname]

        return result

    """ don't save anything """
    def is_valid(self):
        return False

class ReservationAdmin(PlanetStackBaseAdmin):
    fieldList = ['slice', 'startTime', 'duration']
    fieldsets = [('Reservation Details', {'fields': fieldList, 'classes': ['suit-tab suit-tab-general']})]
    list_display = ('startTime', 'duration')
    form = ReservationAddForm

    suit_form_tabs = (('general','Reservation Details'), ('reservedresources','Reserved Resources'))

    inlines = [ReservedResourceInline]
    user_readonly_inlines = [ReservedResourceROInline]
    user_readonly_fields = fieldList

    def add_view(self, request, form_url='', extra_context=None):
        timezone.activate(request.user.timezone)
        request._refresh = False
        request._slice = None
        if request.method == 'POST':
            # "refresh" will be set to "1" if the form was submitted due to
            # a change in the Slice dropdown.
            if request.POST.get("refresh","1") == "1":
                request._refresh = True
                request.POST["refresh"] = "0"

            # Keep track of the slice that was selected, so the
            # reservedResource inline can filter items for the slice.
            request._slice = request.POST.get("slice",None)
            if (request._slice is not None):
                request._slice = Slice.objects.get(id=request._slice)

        result =  super(ReservationAdmin, self).add_view(request, form_url, extra_context)
        return result

    def changelist_view(self, request, extra_context = None):
        timezone.activate(request.user.timezone)
        return super(ReservationAdmin, self).changelist_view(request, extra_context)

    def get_form(self, request, obj=None, **kwargs):
        request._obj_ = obj
        if obj is not None:
            # For changes, set request._slice to the slice already set in the
            # object.
            request._slice = obj.slice
            self.form = ReservationChangeForm
        else:
            if getattr(request, "_refresh", False):
                self.form = ReservationAddRefreshForm
            else:
                self.form = ReservationAddForm
        return super(ReservationAdmin, self).get_form(request, obj, **kwargs)

    def get_readonly_fields(self, request, obj=None):
        if (obj is not None):
            # Prevent slice from being changed after the reservation has been
            # created.
            return ['slice']
        else:
            return []

    def queryset(self, request):
        return Reservation.select_by_user(request.user)

class NetworkParameterTypeAdmin(PlanetStackBaseAdmin):
    list_display = ("name", )
    user_readonly_fields = ['name']
    user_readonly_inlines = []

class RouterAdmin(PlanetStackBaseAdmin):
    list_display = ("name", )
    user_readonly_fields = ['name']
    user_readonly_inlines = []

class RouterROInline(ReadOnlyTabularInline):
    model = Router.networks.through
    extra = 0
    verbose_name_plural = "Routers"
    verbose_name = "Router"
    suit_classes = 'suit-tab suit-tab-routers'

    fields = ['name', 'owner', 'permittedNetworks', 'networks']

class RouterInline(PlStackTabularInline):
    model = Router.networks.through
    extra = 0
    verbose_name_plural = "Routers"
    verbose_name = "Router"
    suit_classes = 'suit-tab suit-tab-routers'

class NetworkParameterROInline(ReadOnlyTabularInline):
    model = NetworkParameter
    extra = 1
    verbose_name_plural = "Parameters"
    verbose_name = "Parameter"
    suit_classes = 'suit-tab suit-tab-netparams'
    fields = ['parameter', 'value', 'content_type', 'object_id', 'content_object']

class NetworkParameterInline(generic.GenericTabularInline):
    model = NetworkParameter
    extra = 1
    verbose_name_plural = "Parameters"
    verbose_name = "Parameter"
    suit_classes = 'suit-tab suit-tab-netparams'

class NetworkSliversROInline(ReadOnlyTabularInline):
    fields = ['network', 'sliver', 'ip', 'port_id']
    model = NetworkSliver
    extra = 0
    verbose_name_plural = "Slivers"
    verbose_name = "Sliver"
    suit_classes = 'suit-tab suit-tab-networkslivers'

class NetworkSliversInline(PlStackTabularInline):
    readonly_fields = ("ip", )
    model = NetworkSliver
    selflink_fieldname = "sliver"
    extra = 0
    verbose_name_plural = "Slivers"
    verbose_name = "Sliver"
    suit_classes = 'suit-tab suit-tab-networkslivers'

class NetworkSlicesROInline(ReadOnlyTabularInline):
    model = NetworkSlice
    extra = 0
    verbose_name_plural = "Slices"
    verbose_name = "Slice"
    suit_classes = 'suit-tab suit-tab-networkslices'
    fields = ['network','slice']

class NetworkSlicesInline(PlStackTabularInline):
    model = NetworkSlice
    selflink_fieldname = "slice"
    extra = 0
    verbose_name_plural = "Slices"
    verbose_name = "Slice"
    suit_classes = 'suit-tab suit-tab-networkslices'

class NetworkAdmin(PlanetStackBaseAdmin):
    list_display = ("name", "subnet", "ports", "labels")
    readonly_fields = ("subnet", )

    inlines = [NetworkParameterInline, NetworkSliversInline, NetworkSlicesInline, RouterInline]

    fieldsets = [
        (None, {'fields': ['name','template','ports','labels','owner','guaranteedBandwidth', 'permitAllSlices','permittedSlices','network_id','router_id','subnet_id','subnet'], 'classes':['suit-tab suit-tab-general']}),]

    user_readonly_fields = ['name','template','ports','labels','owner','guaranteedBandwidth', 'permitAllSlices','permittedSlices','network_id','router_id','subnet_id','subnet']
    user_readonly_inlines = [NetworkParameterROInline, NetworkSliversROInline, NetworkSlicesROInline, RouterROInline]

    suit_form_tabs =(
        ('general','Network Details'),
        ('netparams', 'Parameters'),
        ('networkslivers','Slivers'),
        ('networkslices','Slices'),
        ('routers','Routers'),
    )
class NetworkTemplateAdmin(PlanetStackBaseAdmin):
    list_display = ("name", "guaranteedBandwidth", "visibility")
    user_readonly_fields = ["name", "guaranteedBandwidth", "visibility"]
    user_readonly_inlines = []

# register a signal that caches the user's credentials when they log in
def cache_credentials(sender, user, request, **kwds):
    auth = {'username': request.POST['username'],
            'password': request.POST['password']}
    request.session['auth'] = auth
user_logged_in.connect(cache_credentials)

def dollar_field(fieldName, short_description):
    def newFunc(self, obj):
        try:
            x= "$ %0.2f" % float(getattr(obj, fieldName, 0.0))
        except:
            x=getattr(obj, fieldName, 0.0)
        return x
    newFunc.short_description = short_description
    return newFunc

def right_dollar_field(fieldName, short_description):
    def newFunc(self, obj):
        try:
            #x= '<div align=right style="width:6em">$ %0.2f</div>' % float(getattr(obj, fieldName, 0.0))
            x= '<div align=right>$ %0.2f</div>' % float(getattr(obj, fieldName, 0.0))
        except:
            x=getattr(obj, fieldName, 0.0)
        return x
    newFunc.short_description = short_description
    newFunc.allow_tags = True
    return newFunc

class InvoiceChargeInline(PlStackTabularInline):
    model = Charge
    extra = 0
    verbose_name_plural = "Charges"
    verbose_name = "Charge"
    exclude = ['account']
    fields = ["date", "kind", "state", "object", "coreHours", "dollar_amount", "slice"]
    readonly_fields = ["date", "kind", "state", "object", "coreHours", "dollar_amount", "slice"]
    can_delete = False
    max_num = 0

    dollar_amount = right_dollar_field("amount", "Amount")

class InvoiceAdmin(admin.ModelAdmin):
    list_display = ("date", "account")

    inlines = [InvoiceChargeInline]

    fields = ["date", "account", "dollar_amount"]
    readonly_fields = ["date", "account", "dollar_amount"]

    dollar_amount = dollar_field("amount", "Amount")

class InvoiceInline(PlStackTabularInline):
    model = Invoice
    extra = 0
    verbose_name_plural = "Invoices"
    verbose_name = "Invoice"
    fields = ["date", "dollar_amount"]
    readonly_fields = ["date", "dollar_amount"]
    suit_classes = 'suit-tab suit-tab-accountinvoice'
    can_delete=False
    max_num=0

    dollar_amount = right_dollar_field("amount", "Amount")

class PendingChargeInline(PlStackTabularInline):
    model = Charge
    extra = 0
    verbose_name_plural = "Charges"
    verbose_name = "Charge"
    exclude = ["invoice"]
    fields = ["date", "kind", "state", "object", "coreHours", "dollar_amount", "slice"]
    readonly_fields = ["date", "kind", "state", "object", "coreHours", "dollar_amount", "slice"]
    suit_classes = 'suit-tab suit-tab-accountpendingcharges'
    can_delete=False
    max_num=0

    def queryset(self, request):
        qs = super(PendingChargeInline, self).queryset(request)
        qs = qs.filter(state="pending")
        return qs

    dollar_amount = right_dollar_field("amount", "Amount")

class PaymentInline(PlStackTabularInline):
    model=Payment
    extra = 1
    verbose_name_plural = "Payments"
    verbose_name = "Payment"
    fields = ["date", "dollar_amount"]
    readonly_fields = ["date", "dollar_amount"]
    suit_classes = 'suit-tab suit-tab-accountpayments'
    can_delete=False
    max_num=0

    dollar_amount = right_dollar_field("amount", "Amount")

class AccountAdmin(admin.ModelAdmin):
    list_display = ("site", "balance_due")

    inlines = [InvoiceInline, PaymentInline, PendingChargeInline]

    fieldsets = [
        (None, {'fields': ['site', 'dollar_balance_due', 'dollar_total_invoices', 'dollar_total_payments'],'classes':['suit-tab suit-tab-general']}),]

    readonly_fields = ['site', 'dollar_balance_due', 'dollar_total_invoices', 'dollar_total_payments']

    suit_form_tabs =(
        ('general','Account Details'),
        ('accountinvoice', 'Invoices'),
        ('accountpayments', 'Payments'),
        ('accountpendingcharges','Pending Charges'),
    )

    dollar_balance_due = dollar_field("balance_due", "Balance Due")
    dollar_total_invoices = dollar_field("total_invoices", "Total Invoices")
    dollar_total_payments = dollar_field("total_payments", "Total Payments")


# Now register the new UserAdmin...
admin.site.register(User, UserAdmin)
# ... and, since we're not using Django's builtin permissions,
# unregister the Group model from admin.
#admin.site.unregister(Group)

#Do not show django evolution in the admin interface
from django_evolution.models import Version, Evolution
#admin.site.unregister(Version)
#admin.site.unregister(Evolution)


# When debugging it is often easier to see all the classes, but for regular use 
# only the top-levels should be displayed
showAll = False

admin.site.register(Deployment, DeploymentAdmin)
admin.site.register(Site, SiteAdmin)
admin.site.register(Slice, SliceAdmin)
admin.site.register(Service, ServiceAdmin)
admin.site.register(Reservation, ReservationAdmin)
admin.site.register(Network, NetworkAdmin)
admin.site.register(Router, RouterAdmin)
admin.site.register(NetworkTemplate, NetworkTemplateAdmin)
admin.site.register(Account, AccountAdmin)
admin.site.register(Invoice, InvoiceAdmin)

if True:
    admin.site.register(NetworkParameterType, NetworkParameterTypeAdmin)
    admin.site.register(ServiceClass, ServiceClassAdmin)
    #admin.site.register(PlanetStack)
    admin.site.register(Tag, TagAdmin)
    admin.site.register(DeploymentRole)
    admin.site.register(SiteRole)
    admin.site.register(SliceRole)
    admin.site.register(PlanetStackRole)
    admin.site.register(Node, NodeAdmin)
    #admin.site.register(SlicePrivilege, SlicePrivilegeAdmin)
    #admin.site.register(SitePrivilege, SitePrivilegeAdmin)
    admin.site.register(Sliver, SliverAdmin)
    admin.site.register(Image, ImageAdmin)
    admin.site.register(DashboardView, DashboardViewAdmin)

