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