1 from core.models import Site
2 from core.models import *
3 from openstack.manager import OpenStackManager
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 from suit.widgets import LinkedSelect
17 import django_evolution
19 class PlStackTabularInline(admin.TabularInline):
22 class ReservationInline(PlStackTabularInline):
25 suit_classes = 'suit-tab suit-tab-reservations'
28 class ReadonlyTabularInline(PlStackTabularInline):
33 def get_readonly_fields(self, request, obj=None):
35 for field in self.model._meta.get_all_field_names():
36 if (not field == 'id'):
37 if (field not in self.editable_fields):
41 def has_add_permission(self, request):
44 class TagInline(generic.GenericTabularInline):
47 suit_classes = 'suit-tab suit-tab-tags'
49 class NetworkLookerUpper:
50 """ This is a callable that looks up a network name in a sliver and returns
51 the ip address for that network.
54 def __init__(self, name):
55 self.short_description = name
57 self.network_name = name
59 def __call__(self, obj):
61 for nbs in obj.networksliver_set.all():
62 if (nbs.network.name == self.network_name):
67 return self.network_name
69 class SliverInline(PlStackTabularInline):
71 fields = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
73 readonly_fields = ['ip', 'instance_name']
74 suit_classes = 'suit-tab suit-tab-slivers'
76 # Note this is breaking in the admin.py when trying to use an inline to add a node/image
77 # def _declared_fieldsets(self):
78 # # Return None so django will call get_fieldsets and we can insert our
82 # def get_readonly_fields(self, request, obj=None):
83 # readonly_fields = super(SliverInline, self).get_readonly_fields(request, obj)
85 # # Lookup the networks that are bound to the slivers, and add those
86 # # network names to the list of readonly fields.
88 # for sliver in obj.slivers.all():
89 # for nbs in sliver.networksliver_set.all():
91 # network_name = nbs.network.name
92 # if network_name not in [str(x) for x in readonly_fields]:
93 # readonly_fields.append(NetworkLookerUpper(network_name))
95 # return readonly_fields
97 # def get_fieldsets(self, request, obj=None):
98 # form = self.get_formset(request, obj).form
99 # # fields = the read/write files + the read-only fields
100 # fields = self.fields
101 # for fieldName in self.get_readonly_fields(request,obj):
102 # if not fieldName in fields:
103 # fields.append(fieldName)
105 # return [(None, {'fields': fields})]
109 class SiteInline(PlStackTabularInline):
112 suit_classes = 'suit-tab suit-tab-sites'
114 class UserInline(PlStackTabularInline):
116 fields = ['email', 'firstname', 'lastname']
118 suit_classes = 'suit-tab suit-tab-users'
120 class SliceInline(PlStackTabularInline):
122 fields = ['name','enabled','description','slice_url']
124 suit_classes = 'suit-tab suit-tab-slices'
127 class RoleInline(PlStackTabularInline):
130 suit_classes = 'suit-tab suit-tab-roles'
132 class NodeInline(PlStackTabularInline):
135 suit_classes = 'suit-tab suit-tab-nodes'
137 class SlicePrivilegeInline(PlStackTabularInline):
138 model = SlicePrivilege
140 suit_classes = 'suit-tab suit-tab-sliceprivileges'
142 class DeploymentPrivilegeInline(PlStackTabularInline):
143 model = DeploymentPrivilege
145 suit_classes = 'suit-tab suit-tab-deploymentprivileges'
147 class SitePrivilegeInline(PlStackTabularInline):
148 model = SitePrivilege
150 suit_classes = 'suit-tab suit-tab-siteprivileges'
152 def formfield_for_foreignkey(self, db_field, request, **kwargs):
153 if db_field.name == 'site':
154 if not request.user.is_admin:
155 # only show sites where user is an admin or pi
156 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
157 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
158 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
159 sites = Site.objects.filter(login_base__in=login_bases)
160 kwargs['queryset'] = sites
162 if db_field.name == 'user':
163 if not request.user.is_admin:
164 # only show users from sites where caller has admin or pi role
165 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
166 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
167 sites = [site_privilege.site for site_privilege in site_privileges]
168 site_privileges = SitePrivilege.objects.filter(site__in=sites)
169 emails = [site_privilege.user.email for site_privilege in site_privileges]
170 users = User.objects.filter(email__in=emails)
171 kwargs['queryset'] = users
172 return super(SitePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
174 class SitePrivilegeInline(PlStackTabularInline):
175 model = SitePrivilege
176 suit_classes = 'suit-tab suit-tab-siteprivileges'
178 fields = ('user', 'site','role')
180 class SlicePrivilegeInline(PlStackTabularInline):
181 model = SlicePrivilege
182 suit_classes = 'suit-tab suit-tab-sliceprivileges'
184 fields = ('user', 'slice','role')
186 def formfield_for_foreignkey(self, db_field, request, **kwargs):
187 if db_field.name == 'slice':
188 if not request.user.is_admin:
189 # only show slices at sites where caller has admin or pi role
190 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
191 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
192 sites = [site_privilege.site for site_privilege in site_privileges]
193 slices = Slice.objects.filter(site__in=sites)
194 kwargs['queryset'] = slices
195 if db_field.name == 'user':
196 if not request.user.is_admin:
197 # only show users from sites where caller has admin or pi role
198 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
199 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
200 sites = [site_privilege.site for site_privilege in site_privileges]
201 site_privileges = SitePrivilege.objects.filter(site__in=sites)
202 emails = [site_privilege.user.email for site_privilege in site_privileges]
203 users = User.objects.filter(email__in=emails)
204 kwargs['queryset'] = list(users)
206 return super(SlicePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
208 class SliceNetworkInline(PlStackTabularInline):
209 model = Network.slices.through
211 verbose_name = "Network Connection"
212 verbose_name_plural = "Network Connections"
213 suit_classes = 'suit-tab suit-tab-slicenetworks'
215 class SliceTagInline(PlStackTabularInline):
219 class PlainTextWidget(forms.HiddenInput):
220 input_type = 'hidden'
222 def render(self, name, value, attrs=None):
225 return mark_safe(str(value) + super(PlainTextWidget, self).render(name, value, attrs))
227 class PlanetStackBaseAdmin(admin.ModelAdmin):
230 class SliceRoleAdmin(PlanetStackBaseAdmin):
234 class SiteRoleAdmin(PlanetStackBaseAdmin):
238 class DeploymentAdminForm(forms.ModelForm):
239 sites = forms.ModelMultipleChoiceField(
240 queryset=Site.objects.all(),
242 widget=FilteredSelectMultiple(
243 verbose_name=('Sites'), is_stacked=False
250 class DeploymentAdmin(PlanetStackBaseAdmin):
251 form = DeploymentAdminForm
252 inlines = [DeploymentPrivilegeInline,NodeInline,TagInline]
254 (None, {'fields': ['sites'], 'classes':['suit-tab suit-tab-sites']}),]
255 suit_form_tabs =(('sites', 'Sites'),('nodes','Nodes'),('deploymentprivileges','Privileges'),('tags','Tags'))
257 class SiteAdmin(PlanetStackBaseAdmin):
259 (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base', 'location'], 'classes':['suit-tab suit-tab-general']}),
260 ('Deployment Networks', {'fields': ['deployments'], 'classes':['suit-tab suit-tab-deployments']}),
262 suit_form_tabs =(('general', 'Site Details'),
264 ('siteprivileges','Privileges'),
265 ('deployments','Deployments'),
270 list_display = ('name', 'login_base','site_url', 'enabled')
271 filter_horizontal = ('deployments',)
272 inlines = [SliceInline,UserInline,TagInline, NodeInline, SitePrivilegeInline]
273 search_fields = ['name']
275 def queryset(self, request):
276 # admins can see all keys. Users can only see sites they belong to.
277 qs = super(SiteAdmin, self).queryset(request)
278 if not request.user.is_admin:
279 valid_sites = [request.user.site.login_base]
280 roles = request.user.get_roles()
281 for tenant_list in roles.values():
282 valid_sites.extend(tenant_list)
283 qs = qs.filter(login_base__in=valid_sites)
286 def get_formsets(self, request, obj=None):
287 for inline in self.get_inline_instances(request, obj):
288 # hide MyInline in the add view
291 if isinstance(inline, SliceInline):
292 inline.model.caller = request.user
293 yield inline.get_formset(request, obj)
295 def get_formsets(self, request, obj=None):
296 for inline in self.get_inline_instances(request, obj):
297 # hide MyInline in the add view
300 if isinstance(inline, SliverInline):
301 inline.model.caller = request.user
302 yield inline.get_formset(request, obj)
304 class SitePrivilegeAdmin(PlanetStackBaseAdmin):
306 (None, {'fields': ['user', 'site', 'role'], 'classes':['collapse']})
308 list_display = ('user', 'site', 'role')
310 def formfield_for_foreignkey(self, db_field, request, **kwargs):
311 if db_field.name == 'site':
312 if not request.user.is_admin:
313 # only show sites where user is an admin or pi
315 for site_privilege in SitePrivilege.objects.filer(user=request.user):
316 if site_privilege.role.role_type in ['admin', 'pi']:
317 sites.add(site_privilege.site)
318 kwargs['queryset'] = Site.objects.filter(site__in=list(sites))
320 if db_field.name == 'user':
321 if not request.user.is_admin:
322 # only show users from sites where caller has admin or pi role
323 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
324 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
325 sites = [site_privilege.site for site_privilege in site_privileges]
326 site_privileges = SitePrivilege.objects.filter(site__in=sites)
327 emails = [site_privilege.user.email for site_privilege in site_privileges]
328 users = User.objects.filter(email__in=emails)
329 kwargs['queryset'] = users
331 return super(SitePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
333 def queryset(self, request):
334 # admins can see all privileges. Users can only see privileges at sites
335 # where they have the admin role or pi role.
336 qs = super(SitePrivilegeAdmin, self).queryset(request)
337 if not request.user.is_admin:
338 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
339 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
340 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
341 sites = Site.objects.filter(login_base__in=login_bases)
342 qs = qs.filter(site__in=sites)
345 class SliceAdmin(PlanetStackBaseAdmin):
346 fieldsets = [('Slice Details', {'fields': ['name', 'site', 'serviceClass', 'description', 'slice_url'], 'classes':['suit-tab suit-tab-general']}),]
347 list_display = ('name', 'site','serviceClass', 'slice_url')
348 inlines = [SlicePrivilegeInline,SliverInline, TagInline, ReservationInline,SliceNetworkInline]
351 #inlines = [SliverInline, SliceMembershipInline, TagInline, SliceTagInline, SliceNetworkInline]
352 suit_form_tabs =(('general', 'Slice Details'),
353 ('slicenetworks','Networks'),
354 ('sliceprivileges','Privileges'),
355 ('slivers','Slivers'),
357 ('reservations','Reservations'),
360 def formfield_for_foreignkey(self, db_field, request, **kwargs):
361 if db_field.name == 'site':
362 if not request.user.is_admin:
363 # only show sites where user is a pi or admin
364 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
365 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
366 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
367 sites = Site.objects.filter(login_base__in=login_bases)
368 kwargs['queryset'] = sites
370 return super(SliceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
372 def queryset(self, request):
373 # admins can see all keys. Users can only see slices they belong to.
374 qs = super(SliceAdmin, self).queryset(request)
375 if not request.user.is_admin:
377 roles = request.user.get_roles()
378 for tenant_list in roles.values():
379 valid_slices.extend(tenant_list)
380 qs = qs.filter(name__in=valid_slices)
383 def get_formsets(self, request, obj=None):
384 for inline in self.get_inline_instances(request, obj):
385 # hide MyInline in the add view
388 if isinstance(inline, SliverInline):
389 inline.model.caller = request.user
390 yield inline.get_formset(request, obj)
392 def get_queryset(self, request):
393 qs = super(SliceAdmin, self).get_queryset(request)
394 if request.user.is_superuser:
396 # users can only see slices at their site
397 return qs.filter(site=request.user.site)
399 def save_model(self, request, obj, form, change):
400 # update openstack connection to use this site/tenant
401 obj.caller = request.user
404 class SlicePrivilegeAdmin(PlanetStackBaseAdmin):
406 (None, {'fields': ['user', 'slice', 'role']})
408 list_display = ('user', 'slice', 'role')
410 def formfield_for_foreignkey(self, db_field, request, **kwargs):
411 if db_field.name == 'slice':
412 if not request.user.is_admin:
413 # only show slices at sites where caller has admin or pi role
414 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
415 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
416 sites = [site_privilege.site for site_privilege in site_privileges]
417 slices = Slice.objects.filter(site__in=sites)
418 kwargs['queryset'] = slices
420 if db_field.name == 'user':
421 if not request.user.is_admin:
422 # only show users from sites where caller has admin or pi role
423 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
424 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
425 sites = [site_privilege.site for site_privilege in site_privileges]
426 site_privileges = SitePrivilege.objects.filter(site__in=sites)
427 emails = [site_privilege.user.email for site_privilege in site_privileges]
428 users = User.objects.filter(email__in=emails)
429 kwargs['queryset'] = users
431 return super(SlicePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
433 def queryset(self, request):
434 # admins can see all memberships. Users can only see memberships of
435 # slices where they have the admin role.
436 qs = super(SlicePrivilegeAdmin, self).queryset(request)
437 if not request.user.is_admin:
438 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
439 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
440 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
441 sites = Site.objects.filter(login_base__in=login_bases)
442 slices = Slice.objects.filter(site__in=sites)
443 qs = qs.filter(slice__in=slices)
446 def save_model(self, request, obj, form, change):
447 # update openstack connection to use this site/tenant
448 auth = request.session.get('auth', {})
449 auth['tenant'] = obj.slice.name
450 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
453 def delete_model(self, request, obj):
454 # update openstack connection to use this site/tenant
455 auth = request.session.get('auth', {})
456 auth['tenant'] = obj.slice.name
457 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
461 class ImageAdmin(PlanetStackBaseAdmin):
463 fieldsets = [('Image Details',
464 {'fields': ['image_id', 'name', 'disk_format', 'container_format'],
465 'classes': ['suit-tab suit-tab-general']})
468 suit_form_tabs =(('general','Image Details'),('slivers','Slivers'))
470 inlines = [SliverInline]
472 class NodeForm(forms.ModelForm):
475 'site': LinkedSelect,
476 'deployment': LinkedSelect
479 class NodeAdmin(admin.ModelAdmin):
481 list_display = ('name', 'site', 'deployment')
482 list_filter = ('deployment',)
483 inlines = [TagInline,SliverInline]
484 fieldsets = [('Node Details', {'fields': ['name','site','deployment'], 'classes':['suit-tab suit-tab-details']})]
486 suit_form_tabs =(('details','Node Details'),('slivers','Slivers'),('tags','Tags'))
489 class SliverForm(forms.ModelForm):
492 ip = forms.CharField(widget=PlainTextWidget)
493 instance_name = forms.CharField(widget=PlainTextWidget)
495 'ip': PlainTextWidget(),
496 'instance_name': PlainTextWidget(),
497 'slice': LinkedSelect,
498 'deploymentNetwork': LinkedSelect,
499 'node': LinkedSelect,
500 'image': LinkedSelect
503 class ProjectAdmin(admin.ModelAdmin):
504 inlines = [TagInline]
506 class TagAdmin(admin.ModelAdmin):
507 list_display = ['project', 'name', 'value', 'content_type', 'content_object',]
509 class SliverAdmin(PlanetStackBaseAdmin):
512 ('Sliver Details', {'fields': ['slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'numberCores', 'image', ], 'classes': ['suit-tab suit-tab-general'], })
514 list_display = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
516 suit_form_tabs =(('general', 'Sliver Details'),
520 inlines = [TagInline]
522 def formfield_for_foreignkey(self, db_field, request, **kwargs):
523 if db_field.name == 'slice':
524 if not request.user.is_admin:
525 slices = set([sm.slice.name for sm in SlicePrivilege.objects.filter(user=request.user)])
526 kwargs['queryset'] = Slice.objects.filter(name__in=list(slices))
528 return super(SliverAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
530 def queryset(self, request):
531 # admins can see all slivers. Users can only see slivers of
532 # the slices they belong to.
533 qs = super(SliverAdmin, self).queryset(request)
534 if not request.user.is_admin:
536 roles = request.user.get_roles()
537 for tenant_list in roles.values():
538 tenants.extend(tenant_list)
539 valid_slices = Slice.objects.filter(name__in=tenants)
540 qs = qs.filter(slice__in=valid_slices)
543 def get_formsets(self, request, obj=None):
544 # make some fields read only if we are updating an existing record
546 #self.readonly_fields = ('ip', 'instance_name')
547 self.readonly_fields = ()
549 self.readonly_fields = ()
550 #self.readonly_fields = ('ip', 'instance_name', 'slice', 'image', 'key')
552 for inline in self.get_inline_instances(request, obj):
553 # hide MyInline in the add view
556 # give inline object access to driver and caller
557 auth = request.session.get('auth', {})
558 auth['tenant'] = obj.name # meed to connect using slice's tenant
559 inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
560 yield inline.get_formset(request, obj)
562 def save_model(self, request, obj, form, change):
563 # update openstack connection to use this site/tenant
564 auth = request.session.get('auth', {})
565 auth['tenant'] = obj.slice.name
566 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
567 obj.creator = request.user
570 def delete_model(self, request, obj):
571 # update openstack connection to use this site/tenant
572 auth = request.session.get('auth', {})
573 auth['tenant'] = obj.slice.name
574 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
577 class UserCreationForm(forms.ModelForm):
578 """A form for creating new users. Includes all the required
579 fields, plus a repeated password."""
580 password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
581 password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
585 fields = ('email', 'firstname', 'lastname', 'phone', 'public_key')
587 def clean_password2(self):
588 # Check that the two password entries match
589 password1 = self.cleaned_data.get("password1")
590 password2 = self.cleaned_data.get("password2")
591 if password1 and password2 and password1 != password2:
592 raise forms.ValidationError("Passwords don't match")
595 def save(self, commit=True):
596 # Save the provided password in hashed format
597 user = super(UserCreationForm, self).save(commit=False)
598 user.password = self.cleaned_data["password1"]
599 #user.set_password(self.cleaned_data["password1"])
605 class UserChangeForm(forms.ModelForm):
606 """A form for updating users. Includes all the fields on
607 the user, but replaces the password field with admin's
608 password hash display field.
610 password = ReadOnlyPasswordHashField()
615 def clean_password(self):
616 # Regardless of what the user provides, return the initial value.
617 # This is done here, rather than on the field, because the
618 # field does not have access to the initial value
619 return self.initial["password"]
622 class UserAdmin(UserAdmin):
626 # The forms to add and change user instances
627 form = UserChangeForm
628 add_form = UserCreationForm
630 # The fields to be used in displaying the User model.
631 # These override the definitions on the base UserAdmin
632 # that reference specific fields on auth.User.
633 list_display = ('email', 'firstname', 'lastname', 'is_admin', 'last_login')
635 inlines = [SlicePrivilegeInline,SitePrivilegeInline,DeploymentPrivilegeInline]
637 ('Login Details', {'fields': ('email', 'site','password', 'is_admin', 'public_key'), 'classes':['suit-tab suit-tab-general']}),
638 ('Contact Information', {'fields': ('firstname','lastname','phone', 'timezone'), 'classes':['suit-tab suit-tab-contact']}),
639 #('Important dates', {'fields': ('last_login',)}),
643 'classes': ('wide',),
644 'fields': ('email', 'firstname', 'lastname', 'phone', 'public_key','password1', 'password2')}
647 search_fields = ('email',)
648 ordering = ('email',)
649 filter_horizontal = ()
651 suit_form_tabs =(('general','Login Details'),('contact','Contact Information'),('sliceprivileges','Slice Privileges'),('siteprivileges','Site Privileges'),('deploymentprivileges','Deployment Privileges'))
653 def formfield_for_foreignkey(self, db_field, request, **kwargs):
654 if db_field.name == 'site':
655 if not request.user.is_admin:
656 # show sites where caller is an admin or pi
658 for site_privilege in SitePrivilege.objects.filer(user=request.user):
659 if site_privilege.role.role_type in ['admin', 'pi']:
660 sites.append(site_privilege.site.login_base)
661 kwargs['queryset'] = Site.objects.filter(login_base__in(list(sites)))
663 return super(UserAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
665 class ServiceResourceInline(admin.TabularInline):
666 model = ServiceResource
669 class ServiceClassAdmin(admin.ModelAdmin):
670 list_display = ('name', 'commitment', 'membershipFee')
671 inlines = [ServiceResourceInline]
673 class ReservedResourceInline(admin.TabularInline):
674 model = ReservedResource
676 suit_classes = 'suit-tab suit-tab-reservedresources'
678 def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
679 field = super(ReservedResourceInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
681 if db_field.name == 'resource':
682 # restrict resources to those that the slice's service class allows
683 if request._slice is not None:
684 field.queryset = field.queryset.filter(serviceClass = request._slice.serviceClass, calendarReservable=True)
685 if len(field.queryset) > 0:
686 field.initial = field.queryset.all()[0]
688 field.queryset = field.queryset.none()
\r
689 elif db_field.name == 'sliver':
\r
690 # restrict slivers to those that belong to the slice
\r
691 if request._slice is not None:
\r
692 field.queryset = field.queryset.filter(slice = request._slice)
694 field.queryset = field.queryset.none()
\r
698 class ReservationChangeForm(forms.ModelForm):
702 'slice' : LinkedSelect
705 class ReservationAddForm(forms.ModelForm):
706 slice = forms.ModelChoiceField(queryset=Slice.objects.all(), widget=forms.Select(attrs={"onChange":"document.getElementById('id_refresh').value=1; submit()"}))
707 refresh = forms.CharField(widget=forms.HiddenInput())
710 css = {'all': ('planetstack.css',)} # .field-refresh { display: none; }
712 def clean_slice(self):
713 slice = self.cleaned_data.get("slice")
714 x = ServiceResource.objects.filter(serviceClass = slice.serviceClass, calendarReservable=True)
716 raise forms.ValidationError("The slice you selected does not have a service class that allows reservations")
722 'slice' : LinkedSelect
726 class ReservationAddRefreshForm(ReservationAddForm):
727 """ This form is displayed when the Reservation Form receives an update
728 from the Slice dropdown onChange handler. It doesn't validate the
729 data and doesn't save the data. This will cause the form to be
733 """ don't validate anything other than slice """
734 dont_validate_fields = ("startTime", "duration")
736 def full_clean(self):
737 result = super(ReservationAddForm, self).full_clean()
739 for fieldname in self.dont_validate_fields:
740 if fieldname in self._errors:
741 del self._errors[fieldname]
745 """ don't save anything """
749 class ReservationAdmin(admin.ModelAdmin):
750 fieldsets = [('Reservation Details', {'fields': ['startTime', 'duration','slice'], 'classes': ['suit-tab suit-tab-general']})]
751 list_display = ('startTime', 'duration')
752 form = ReservationAddForm
754 suit_form_tabs = (('general','Reservation Details'), ('reservedresources','Reserved Resources'))
756 inlines = [ReservedResourceInline]
758 def add_view(self, request, form_url='', extra_context=None):
759 timezone.activate(request.user.timezone)
760 request._refresh = False
761 request._slice = None
762 if request.method == 'POST':
763 # "refresh" will be set to "1" if the form was submitted due to
764 # a change in the Slice dropdown.
765 if request.POST.get("refresh","1") == "1":
766 request._refresh = True
767 request.POST["refresh"] = "0"
769 # Keep track of the slice that was selected, so the
770 # reservedResource inline can filter items for the slice.
771 request._slice = request.POST.get("slice",None)
772 if (request._slice is not None):
773 request._slice = Slice.objects.get(id=request._slice)
775 result = super(ReservationAdmin, self).add_view(request, form_url, extra_context)
778 def changelist_view(self, request, extra_context = None):
779 timezone.activate(request.user.timezone)
780 return super(ReservationAdmin, self).changelist_view(request, extra_context)
782 def get_form(self, request, obj=None, **kwargs):
785 # For changes, set request._slice to the slice already set in the
787 request._slice = obj.slice
788 self.form = ReservationChangeForm
790 if getattr(request, "_refresh", False):
791 self.form = ReservationAddRefreshForm
793 self.form = ReservationAddForm
794 return super(ReservationAdmin, self).get_form(request, obj, **kwargs)
796 def get_readonly_fields(self, request, obj=None):
797 if (obj is not None):
798 # Prevent slice from being changed after the reservation has been
804 class NetworkParameterTypeAdmin(admin.ModelAdmin):
805 list_display = ("name", )
807 class RouterAdmin(admin.ModelAdmin):
808 list_display = ("name", )
810 class RouterInline(admin.TabularInline):
811 model = Router.networks.through
813 verbose_name_plural = "Routers"
814 verbose_name = "Router"
815 suit_classes = 'suit-tab suit-tab-routers'
817 class NetworkParameterInline(generic.GenericTabularInline):
818 model = NetworkParameter
820 verbose_name_plural = "Parameters"
821 verbose_name = "Parameter"
822 suit_classes = 'suit-tab suit-tab-netparams'
824 class NetworkSliversInline(admin.TabularInline):
825 readonly_fields = ("ip", )
826 model = NetworkSliver
828 verbose_name_plural = "Slivers"
829 verbose_name = "Sliver"
830 suit_classes = 'suit-tab suit-tab-networkslivers'
832 class NetworkSlicesInline(admin.TabularInline):
835 verbose_name_plural = "Slices"
836 verbose_name = "Slice"
837 suit_classes = 'suit-tab suit-tab-networkslices'
839 class NetworkAdmin(admin.ModelAdmin):
840 list_display = ("name", "subnet", "ports", "labels")
841 readonly_fields = ("subnet", )
843 inlines = [NetworkParameterInline, NetworkSliversInline, NetworkSlicesInline, RouterInline]
846 (None, {'fields': ['name','template','ports','labels','owner','guaranteedBandwidth', 'permitAllSlices','permittedSlices','network_id','router_id','subnet_id','subnet'], 'classes':['suit-tab suit-tab-general']}),]
849 ('general','Network Details'),
850 ('netparams', 'Parameters'),
851 ('networkslivers','Slivers'),
852 ('networkslices','Slices'),
853 ('routers','Routers'),
855 class NetworkTemplateAdmin(admin.ModelAdmin):
856 list_display = ("name", "guaranteedBandwidth", "visibility")
858 # register a signal that caches the user's credentials when they log in
859 def cache_credentials(sender, user, request, **kwds):
860 auth = {'username': request.POST['username'],
861 'password': request.POST['password']}
862 request.session['auth'] = auth
863 user_logged_in.connect(cache_credentials)
865 # Now register the new UserAdmin...
866 admin.site.register(User, UserAdmin)
867 # ... and, since we're not using Django's builtin permissions,
868 # unregister the Group model from admin.
869 admin.site.unregister(Group)
871 #Do not show django evolution in the admin interface
872 from django_evolution.models import Version, Evolution
873 admin.site.unregister(Version)
874 admin.site.unregister(Evolution)
877 # When debugging it is often easier to see all the classes, but for regular use
878 # only the top-levels should be displayed
881 admin.site.register(Deployment, DeploymentAdmin)
882 admin.site.register(Site, SiteAdmin)
883 admin.site.register(Slice, SliceAdmin)
884 admin.site.register(Project, ProjectAdmin)
885 admin.site.register(ServiceClass, ServiceClassAdmin)
886 admin.site.register(Reservation, ReservationAdmin)
887 admin.site.register(Network, NetworkAdmin)
888 admin.site.register(Router, RouterAdmin)
889 admin.site.register(NetworkParameterType, NetworkParameterTypeAdmin)
890 admin.site.register(NetworkTemplate, NetworkTemplateAdmin)
893 #admin.site.register(PlanetStack)
894 admin.site.register(Tag, TagAdmin)
895 admin.site.register(Node, NodeAdmin)
896 #admin.site.register(SlicePrivilege, SlicePrivilegeAdmin)
897 #admin.site.register(SitePrivilege, SitePrivilegeAdmin)
898 admin.site.register(Sliver, SliverAdmin)
899 admin.site.register(Image, ImageAdmin)