observer for sites, slices and users
[plstackapi.git] / planetstack / core / admin.py
1 from core.models import Site
2 from core.models import *
3 from openstack.manager import OpenStackManager
4
5 from django.contrib import admin
6 from django.contrib.auth.models import Group
7 from django import forms
8 from django.utils.safestring import mark_safe
9 from django.contrib.auth.admin import UserAdmin
10 from django.contrib.admin.widgets import FilteredSelectMultiple
11 from django.contrib.auth.forms import ReadOnlyPasswordHashField
12 from django.contrib.auth.signals import user_logged_in
13 from django.utils import timezone
14 import django_evolution 
15
16
17 class ReadonlyTabularInline(admin.TabularInline):
18     can_delete = False
19     extra = 0
20     editable_fields = []
21
22     def get_readonly_fields(self, request, obj=None):
23         fields = []
24         for field in self.model._meta.get_all_field_names():
25             if (not field == 'id'):
26                 if (field not in self.editable_fields):
27                     fields.append(field)
28         return fields
29
30     def has_add_permission(self, request):
31         return False
32
33 class SliverInline(admin.TabularInline):
34     model = Sliver
35     fields = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
36     extra = 0
37     #readonly_fields = ['ip', 'instance_name', 'image']
38     readonly_fields = ['ip', 'instance_name']
39     
40
41 class SiteInline(admin.TabularInline):
42     model = Site
43     extra = 0
44
45 class UserInline(admin.TabularInline):
46     model = User
47     fields = ['email', 'firstname', 'lastname']
48     extra = 0
49
50 class SliceInline(admin.TabularInline):
51     model = Slice
52     extra = 0
53
54 class RoleInline(admin.TabularInline):
55     model = Role
56     extra = 0 
57
58 class NodeInline(admin.TabularInline):
59     model = Node
60     extra = 0
61
62 class SitePrivilegeInline(admin.TabularInline):
63     model = SitePrivilege
64     extra = 0
65
66     def formfield_for_foreignkey(self, db_field, request, **kwargs):
67         if db_field.name == 'site':
68             if not request.user.is_admin:
69                 # only show sites where user is an admin or pi
70                 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
71                 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
72                 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
73                 sites = Site.objects.filter(login_base__in=login_bases)
74                 kwargs['queryset'] = sites
75
76         if db_field.name == 'user':
77             if not request.user.is_admin:
78                 # only show users from sites where caller has admin or pi role
79                 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
80                 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
81                 sites = [site_privilege.site for site_privilege in site_privileges]
82                 site_privileges = SitePrivilege.objects.filter(site__in=sites)
83                 emails = [site_privilege.user.email for site_privilege in site_privileges]
84                 users = User.objects.filter(email__in=emails)
85                 kwargs['queryset'] = users
86         return super(SitePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
87
88 class SliceMembershipInline(admin.TabularInline):
89     model = SliceMembership
90     extra = 0
91
92     def formfield_for_foreignkey(self, db_field, request, **kwargs):
93         if db_field.name == 'slice':
94             if not request.user.is_admin:
95                 # only show slices at sites where caller has admin or pi role
96                 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
97                 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
98                 sites = [site_privilege.site for site_privilege in site_privileges]
99                 slices = Slice.objects.filter(site__in=sites)
100                 kwargs['queryset'] = slices 
101         if db_field.name == 'user':
102             if not request.user.is_admin:
103                 # only show users from sites where caller has admin or pi role
104                 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
105                 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
106                 sites = [site_privilege.site for site_privilege in site_privileges]
107                 site_privileges = SitePrivilege.objects.filter(site__in=sites)
108                 emails = [site_privilege.user.email for site_privilege in site_privileges]   
109                 users = User.objects.filter(email__in=emails) 
110                 kwargs['queryset'] = list(users)
111
112         return super(SliceMembershipInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
113
114 class SliceTagInline(admin.TabularInline):
115     model = SliceTag
116     extra = 0
117
118 class PlainTextWidget(forms.HiddenInput):
119     input_type = 'hidden'
120
121     def render(self, name, value, attrs=None):
122         if value is None:
123             value = ''
124         return mark_safe(str(value) + super(PlainTextWidget, self).render(name, value, attrs))
125
126 class PlanetStackBaseAdmin(admin.ModelAdmin):
127     save_on_top = False
128
129 class RoleAdmin(PlanetStackBaseAdmin):
130     fieldsets = [
131         ('Role', {'fields': ['role_type']})
132     ]
133     list_display = ('role_type',)
134
135
136 class DeploymentAdminForm(forms.ModelForm):
137     sites = forms.ModelMultipleChoiceField(
138         queryset=Site.objects.all(),
139         required=False,
140         widget=FilteredSelectMultiple(
141             verbose_name=('Sites'), is_stacked=False
142         )
143     )
144     class Meta:
145         model = Deployment
146
147     def __init__(self, *args, **kwargs):
148         super(DeploymentAdminForm, self).__init__(*args, **kwargs)
149
150         if self.instance and self.instance.pk:
151             self.fields['sites'].initial = self.instance.sites.all()
152
153     def save(self, commit=True):
154         deploymentNetwork = super(DeploymentAdminForm, self).save(commit=False)
155         if commit:
156             deploymentNetwork.save()
157
158         if deploymentNetwork.pk:
159             deploymentNetwork.sites = self.cleaned_data['sites']
160             self.save_m2m()
161
162         return deploymentNetwork
163
164 class DeploymentAdmin(PlanetStackBaseAdmin):
165     form = DeploymentAdminForm
166     inlines = [NodeInline,SliverInline]
167
168     def get_formsets(self, request, obj=None):
169         for inline in self.get_inline_instances(request, obj):
170             # hide MyInline in the add view
171             if obj is None:
172                 continue
173             # give inline object access to driver and caller
174             auth = request.session.get('auth', {})
175             if request.user.site:
176                 auth['tenant'] = request.user.site.login_base
177             inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
178             yield inline.get_formset(request, obj)
179
180 class SiteAdmin(PlanetStackBaseAdmin):
181     fieldsets = [
182         (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base']}),
183         ('Location', {'fields': ['latitude', 'longitude']}),
184         ('Deployment Networks', {'fields': ['deployments']})
185     ]
186     list_display = ('name', 'login_base','site_url', 'enabled')
187     filter_horizontal = ('deployments',)
188     inlines = [NodeInline, UserInline, SitePrivilegeInline]
189     search_fields = ['name']
190
191     def queryset(self, request):
192         # admins can see all keys. Users can only see sites they belong to.
193         qs = super(SiteAdmin, self).queryset(request)
194         if not request.user.is_admin:
195             valid_sites = [request.user.site.login_base]
196             roles = request.user.get_roles()
197             for tenant_list in roles.values():
198                 valid_sites.extend(tenant_list)
199             qs = qs.filter(login_base__in=valid_sites)
200         return qs
201
202     def get_formsets(self, request, obj=None):
203         for inline in self.get_inline_instances(request, obj):
204             # hide MyInline in the add view
205             if obj is None:
206                 continue
207             yield inline.get_formset(request, obj)
208
209 class SitePrivilegeAdmin(PlanetStackBaseAdmin):
210     fieldsets = [
211         (None, {'fields': ['user', 'site', 'role']})
212     ]
213     list_display = ('user', 'site', 'role')
214
215     def formfield_for_foreignkey(self, db_field, request, **kwargs):
216         if db_field.name == 'site':
217             if not request.user.is_admin:
218                 # only show sites where user is an admin or pi
219                 sites = set()
220                 for site_privilege in SitePrivilege.objects.filer(user=request.user):
221                     if site_privilege.role.role_type in ['admin', 'pi']:
222                         sites.add(site_privilege.site)
223                 kwargs['queryset'] = Site.objects.filter(site__in=list(sites))
224
225         if db_field.name == 'user':
226             if not request.user.is_admin:
227                 # only show users from sites where caller has admin or pi role
228                 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
229                 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
230                 sites = [site_privilege.site for site_privilege in site_privileges]
231                 site_privileges = SitePrivilege.objects.filter(site__in=sites)
232                 emails = [site_privilege.user.email for site_privilege in site_privileges]
233                 users = User.objects.filter(email__in=emails)
234                 kwargs['queryset'] = users
235
236         return super(SitePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
237
238     def queryset(self, request):
239         # admins can see all privileges. Users can only see privileges at sites
240         # where they have the admin role or pi role.
241         qs = super(SitePrivilegeAdmin, self).queryset(request)
242         if not request.user.is_admin:
243             roles = Role.objects.filter(role_type__in=['admin', 'pi'])
244             site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
245             login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
246             sites = Site.objects.filter(login_base__in=login_bases)
247             qs = qs.filter(site__in=sites)
248         return qs
249
250 class SliceAdmin(OSModelAdmin):
251     fields = ['name', 'site', 'serviceClass', 'description', 'slice_url']
252     list_display = ('name', 'site','serviceClass', 'slice_url')
253     inlines = [SliverInline, SliceMembershipInline, SliceTagInline]
254
255     def formfield_for_foreignkey(self, db_field, request, **kwargs):
256         if db_field.name == 'site':
257             if not request.user.is_admin:
258                 # only show sites where user is a pi or admin 
259                 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
260                 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
261                 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
262                 sites = Site.objects.filter(login_base__in=login_bases)
263                 kwargs['queryset'] = sites
264
265         return super(SliceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
266
267     def queryset(self, request):
268         # admins can see all keys. Users can only see slices they belong to.
269         qs = super(SliceAdmin, self).queryset(request)
270         if not request.user.is_admin:
271             valid_slices = []
272             roles = request.user.get_roles()
273             for tenant_list in roles.values():
274                 valid_slices.extend(tenant_list)
275             qs = qs.filter(name__in=valid_slices)
276         return qs
277
278     def get_formsets(self, request, obj=None):
279         for inline in self.get_inline_instances(request, obj):
280             # hide MyInline in the add view
281             if obj is None:
282                 continue
283             # give inline object access to driver and caller
284             auth = request.session.get('auth', {})
285             auth['tenant'] = obj.name       # meed to connect using slice's tenant
286             inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
287             inline.model.creator = request.user
288             yield inline.get_formset(request, obj)
289
290     def get_queryset(self, request):
291         qs = super(SliceAdmin, self).get_queryset(request)
292         if request.user.is_superuser:
293             return qs
294         # users can only see slices at their site
295         return qs.filter(site=request.user.site) 
296
297 class SliceMembershipAdmin(PlanetStackBaseAdmin):
298     fieldsets = [
299         (None, {'fields': ['user', 'slice', 'role']})
300     ]
301     list_display = ('user', 'slice', 'role')
302
303     def formfield_for_foreignkey(self, db_field, request, **kwargs):
304         if db_field.name == 'slice':
305             if not request.user.is_admin:
306                 # only show slices at sites where caller has admin or pi role
307                 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
308                 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
309                 sites = [site_privilege.site for site_privilege in site_privileges]
310                 slices = Slice.objects.filter(site__in=sites)
311                 kwargs['queryset'] = slices
312         
313         if db_field.name == 'user':
314             if not request.user.is_admin:
315                 # only show users from sites where caller has admin or pi role
316                 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
317                 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
318                 sites = [site_privilege.site for site_privilege in site_privileges]
319                 site_privileges = SitePrivilege.objects.filter(site__in=sites)
320                 emails = [site_privilege.user.email for site_privilege in site_privileges]
321                 users = User.objects.filter(email__in=emails)
322                 kwargs['queryset'] = users
323
324         return super(SliceMembershipAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
325
326     def queryset(self, request):
327         # admins can see all memberships. Users can only see memberships of
328         # slices where they have the admin role.
329         qs = super(SliceMembershipAdmin, self).queryset(request)
330         if not request.user.is_admin:
331             roles = Role.objects.filter(role_type__in=['admin', 'pi'])
332             site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
333             login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
334             sites = Site.objects.filter(login_base__in=login_bases)
335             slices = Slice.objects.filter(site__in=sites)
336             qs = qs.filter(slice__in=slices)
337         return qs
338
339     def save_model(self, request, obj, form, change):
340         # update openstack connection to use this site/tenant
341         auth = request.session.get('auth', {})
342         auth['tenant'] = obj.slice.name
343         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
344         obj.save()
345
346     def delete_model(self, request, obj):
347         # update openstack connection to use this site/tenant
348         auth = request.session.get('auth', {})
349         auth['tenant'] = obj.slice.name
350         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
351         obj.delete()
352
353
354 class ImageAdmin(admin.ModelAdmin):
355     fields = ['image_id', 'name', 'disk_format', 'container_format']
356
357 class NodeAdmin(admin.ModelAdmin):
358     list_display = ('name', 'site', 'deployment')
359     list_filter = ('deployment',)
360
361
362 class SliverForm(forms.ModelForm):
363     class Meta:
364         model = Sliver
365         ip = forms.CharField(widget=PlainTextWidget)
366         instance_name = forms.CharField(widget=PlainTextWidget)
367         widgets = {
368             'ip': PlainTextWidget(),
369             'instance_name': PlainTextWidget(),
370         }
371
372 class SliverAdmin(PlanetStackBaseAdmin):
373     form = SliverForm
374     fieldsets = [
375         ('Sliver', {'fields': ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'key', 'node', 'deploymentNetwork']})
376     ]
377     list_display = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'key', 'node', 'deploymentNetwork']
378
379     def formfield_for_foreignkey(self, db_field, request, **kwargs):
380         if db_field.name == 'slice':
381             if not request.user.is_admin:
382                 slices = set([sm.slice.name for sm in SliceMembership.objects.filter(user=request.user)]) 
383                 kwargs['queryset'] = Slice.objects.filter(name__in=list(slices))
384
385         return super(SliverAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
386
387     def queryset(self, request):
388         # admins can see all slivers. Users can only see slivers of 
389         # the slices they belong to.
390         qs = super(SliverAdmin, self).queryset(request)
391         if not request.user.is_admin:
392             tenants = []
393             roles = request.user.get_roles()
394             for tenant_list in roles.values():
395                 tenants.extend(tenant_list)
396             valid_slices = Slice.objects.filter(name__in=tenants)
397             qs = qs.filter(slice__in=valid_slices)
398         return qs
399
400     def get_formsets(self, request, obj=None):
401         # make some fields read only if we are updating an existing record
402         if obj == None:
403             #self.readonly_fields = ('ip', 'instance_name') 
404             self.readonly_fields = () 
405         else:
406             self.readonly_fields = () 
407             #self.readonly_fields = ('ip', 'instance_name', 'slice', 'image', 'key') 
408
409         for inline in self.get_inline_instances(request, obj):
410             # hide MyInline in the add view
411             if obj is None:
412                 continue
413             # give inline object access to driver and caller
414             auth = request.session.get('auth', {})
415             auth['tenant'] = obj.name       # meed to connect using slice's tenant
416             inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
417             yield inline.get_formset(request, obj)
418
419     def save_model(self, request, obj, form, change):
420         # update openstack connection to use this site/tenant
421         auth = request.session.get('auth', {})
422         auth['tenant'] = obj.slice.name
423         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
424         obj.creator = request.user
425         obj.save()
426
427     def delete_model(self, request, obj):
428         # update openstack connection to use this site/tenant
429         auth = request.session.get('auth', {})
430         auth['tenant'] = obj.slice.name
431         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
432         obj.delete()
433
434 class UserCreationForm(forms.ModelForm):
435     """A form for creating new users. Includes all the required
436     fields, plus a repeated password."""
437     password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
438     password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
439
440     class Meta:
441         model = User
442         fields = ('email', 'firstname', 'lastname', 'phone', 'public_key', 'site')
443
444     def clean_password2(self):
445         # Check that the two password entries match
446         password1 = self.cleaned_data.get("password1")
447         password2 = self.cleaned_data.get("password2")
448         if password1 and password2 and password1 != password2:
449             raise forms.ValidationError("Passwords don't match")
450         return password2
451
452     def save(self, commit=True):
453         # Save the provided password in hashed format
454         user = super(UserCreationForm, self).save(commit=False)
455         user.password = self.cleaned_data["password1"]
456         #user.set_password(self.cleaned_data["password1"])
457         if commit:
458             user.save()
459         return user
460
461
462 class UserChangeForm(forms.ModelForm):
463     """A form for updating users. Includes all the fields on
464     the user, but replaces the password field with admin's
465     password hash display field.
466     """
467     password = ReadOnlyPasswordHashField()
468
469     class Meta:
470         model = User
471
472     def clean_password(self):
473         # Regardless of what the user provides, return the initial value.
474         # This is done here, rather than on the field, because the
475         # field does not have access to the initial value
476         return self.initial["password"]
477
478
479 class UserAdmin(UserAdmin, OSModelAdmin):
480     class Meta:
481         app_label = "core"
482
483     # The forms to add and change user instances
484     form = UserChangeForm
485     add_form = UserCreationForm
486
487     # The fields to be used in displaying the User model.
488     # These override the definitions on the base UserAdmin
489     # that reference specific fields on auth.User.
490     list_display = ('email', 'site', 'firstname', 'lastname', 'is_admin', 'last_login')
491     list_filter = ('site',)
492     inlines = [SitePrivilegeInline, SliceMembershipInline]
493     fieldsets = (
494         (None, {'fields': ('email', 'password', 'site', 'is_admin', 'timezone')}),
495         ('Personal info', {'fields': ('firstname','lastname','phone', 'public_key')}),
496         #('Important dates', {'fields': ('last_login',)}),
497     )
498     add_fieldsets = (
499         (None, {
500             'classes': ('wide',),
501             'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'public_key','password1', 'password2', 'is_admin')}
502         ),
503     )
504     search_fields = ('email',)
505     ordering = ('email',)
506     filter_horizontal = ()
507
508     def formfield_for_foreignkey(self, db_field, request, **kwargs):
509         if db_field.name == 'site':
510             if not request.user.is_admin:
511                 # show sites where caller is an admin or pi 
512                 sites = []
513                 for site_privilege in SitePrivilege.objects.filer(user=request.user):
514                     if site_privilege.role.role_type in ['admin', 'pi']:
515                         sites.append(site_privilege.site.login_base)  
516                 kwargs['queryset'] = Site.objects.filter(login_base__in(list(sites)))
517
518         return super(UserAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
519
520 class ServiceResourceInline(admin.TabularInline):
521     model = ServiceResource
522     extra = 0
523
524 class ServiceClassAdmin(admin.ModelAdmin):
525     list_display = ('name', 'commitment', 'membershipFee')
526     inlines = [ServiceResourceInline]
527
528 class ReservedResourceInline(admin.TabularInline):
529     model = ReservedResource
530     extra = 0
531
532     def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
533         field = super(ReservedResourceInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
534
535         if db_field.name == 'resource':
536             # restrict resources to those that the slice's service class allows
537             if request._slice is not None:
538                 field.queryset = field.queryset.filter(serviceClass = request._slice.serviceClass, calendarReservable=True)
539                 if len(field.queryset) > 0:
540                     field.initial = field.queryset.all()[0]
541             else:\r
542                 field.queryset = field.queryset.none()\r
543         elif db_field.name == 'sliver':\r
544             # restrict slivers to those that belong to the slice\r
545             if request._slice is not None:\r
546                 field.queryset = field.queryset.filter(slice = request._slice)
547             else:
548                 field.queryset = field.queryset.none()\r
549 \r
550         return field
551
552 class ReservationChangeForm(forms.ModelForm):
553     class Meta:
554         model = Reservation
555
556 class ReservationAddForm(forms.ModelForm):
557     slice = forms.ModelChoiceField(queryset=Slice.objects.all(), widget=forms.Select(attrs={"onChange":"document.getElementById('id_refresh').value=1; submit()"}))
558     refresh = forms.CharField(widget=forms.HiddenInput())
559
560     class Media:
561        css = {'all': ('planetstack.css',)}   # .field-refresh { display: none; }
562
563     def clean_slice(self):
564         slice = self.cleaned_data.get("slice")
565         x = ServiceResource.objects.filter(serviceClass = slice.serviceClass, calendarReservable=True)
566         if len(x) == 0:
567             raise forms.ValidationError("The slice you selected does not have a service class that allows reservations")
568         return slice
569
570     class Meta:
571         model = Reservation
572
573 class ReservationAddRefreshForm(ReservationAddForm):
574     """ This form is displayed when the Reservation Form receives an update
575         from the Slice dropdown onChange handler. It doesn't validate the
576         data and doesn't save the data. This will cause the form to be
577         redrawn.
578     """
579
580     """ don't validate anything other than slice """
581     dont_validate_fields = ("startTime", "duration")
582
583     def full_clean(self):
584         result = super(ReservationAddForm, self).full_clean()
585
586         for fieldname in self.dont_validate_fields:
587             if fieldname in self._errors:
588                 del self._errors[fieldname]
589
590         return result
591
592     """ don't save anything """
593     def is_valid(self):
594         return False
595
596 class ReservationAdmin(admin.ModelAdmin):
597     list_display = ('startTime', 'duration')
598     inlines = [ReservedResourceInline]
599     form = ReservationAddForm
600
601     def add_view(self, request, form_url='', extra_context=None):
602         timezone.activate(request.user.timezone)
603         request._refresh = False
604         request._slice = None
605         if request.method == 'POST':
606             # "refresh" will be set to "1" if the form was submitted due to
607             # a change in the Slice dropdown.
608             if request.POST.get("refresh","1") == "1":
609                 request._refresh = True
610                 request.POST["refresh"] = "0"
611
612             # Keep track of the slice that was selected, so the
613             # reservedResource inline can filter items for the slice.
614             request._slice = request.POST.get("slice",None)
615             if (request._slice is not None):
616                 request._slice = Slice.objects.get(id=request._slice)
617
618         result =  super(ReservationAdmin, self).add_view(request, form_url, extra_context)
619         return result
620
621     def changelist_view(self, request, extra_context = None):
622         timezone.activate(request.user.timezone)
623         return super(ReservationAdmin, self).changelist_view(request, extra_context)
624
625     def get_form(self, request, obj=None, **kwargs):
626         request._obj_ = obj\r
627         if obj is not None:\r
628             # For changes, set request._slice to the slice already set in the\r
629             # object.\r
630             request._slice = obj.slice\r
631             self.form = ReservationChangeForm\r
632         else:\r
633             if getattr(request, "_refresh", False):\r
634                 self.form = ReservationAddRefreshForm\r
635             else:\r
636                 self.form = ReservationAddForm\r
637         return super(ReservationAdmin, self).get_form(request, obj, **kwargs)\r
638 \r
639     def get_readonly_fields(self, request, obj=None):
640         if (obj is not None):\r
641             # Prevent slice from being changed after the reservation has been\r
642             # created.\r
643             return ['slice']\r
644         else:\r
645             return []
646
647 # register a signal that caches the user's credentials when they log in
648 def cache_credentials(sender, user, request, **kwds):
649     auth = {'username': request.POST['username'],
650             'password': request.POST['password']}
651     request.session['auth'] = auth
652 user_logged_in.connect(cache_credentials)
653
654 # Now register the new UserAdmin...
655 admin.site.register(User, UserAdmin)
656 # ... and, since we're not using Django's builtin permissions,
657 # unregister the Group model from admin.
658 admin.site.unregister(Group)
659
660 #Do not show django evolution in the admin interface
661 from django_evolution.models import Version, Evolution
662 admin.site.unregister(Version)
663 admin.site.unregister(Evolution)
664
665
666 # When debugging it is often easier to see all the classes, but for regular use 
667 # only the top-levels should be displayed
668 showAll = False
669
670 admin.site.register(Deployment, DeploymentAdmin)
671 admin.site.register(Site, SiteAdmin)
672 admin.site.register(Slice, SliceAdmin)
673 #admin.site.register(Subnet)
674
675
676 if showAll:
677     admin.site.register(Node, NodeAdmin)
678     admin.site.register(SliceMembership, SliceMembershipAdmin)
679     admin.site.register(SitePrivilege, SitePrivilegeAdmin)
680     admin.site.register(Role, RoleAdmin)
681     admin.site.register(Sliver, SliverAdmin)
682     admin.site.register(ServiceClass, ServiceClassAdmin)
683     admin.site.register(Reservation, ReservationAdmin)
684     admin.site.register(Image, ImageAdmin)
685