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):
48 suit_classes = 'suit-tab suit-tab-tags'
50 class NetworkLookerUpper:
51 """ This is a callable that looks up a network name in a sliver and returns
\r
52 the ip address for that network.
\r
55 def __init__(self, name):
\r
56 self.short_description = name
\r
57 self.__name__ = name
\r
58 self.network_name = name
\r
60 def __call__(self, obj):
\r
62 for nbs in obj.networksliver_set.all():
\r
63 if (nbs.network.name == self.network_name):
\r
68 return self.network_name
70 class SliverInline(PlStackTabularInline):
72 fields = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
74 readonly_fields = ['ip', 'instance_name']
75 suit_classes = 'suit-tab suit-tab-slivers'
77 # Note this is breaking in the admin.py when trying to use an inline to add a node/image
78 # def _declared_fieldsets(self):
79 # # Return None so django will call get_fieldsets and we can insert our
83 # def get_readonly_fields(self, request, obj=None):
84 # readonly_fields = super(SliverInline, self).get_readonly_fields(request, obj)
86 # # Lookup the networks that are bound to the slivers, and add those
87 # # network names to the list of readonly fields.
89 # for sliver in obj.slivers.all():
90 # for nbs in sliver.networksliver_set.all():
92 # network_name = nbs.network.name
93 # if network_name not in [str(x) for x in readonly_fields]:
94 # readonly_fields.append(NetworkLookerUpper(network_name))
96 # return readonly_fields
98 # def get_fieldsets(self, request, obj=None):
99 # form = self.get_formset(request, obj).form
100 # # fields = the read/write files + the read-only fields
101 # fields = self.fields
102 # for fieldName in self.get_readonly_fields(request,obj):
103 # if not fieldName in fields:
104 # fields.append(fieldName)
106 # return [(None, {'fields': fields})]
110 class SiteInline(PlStackTabularInline):
113 suit_classes = 'suit-tab suit-tab-sites'
115 class UserInline(PlStackTabularInline):
117 fields = ['email', 'firstname', 'lastname']
119 suit_classes = 'suit-tab suit-tab-users'
121 class SliceInline(PlStackTabularInline):
123 fields = ['name','enabled','description','slice_url']
125 suit_classes = 'suit-tab suit-tab-slices'
128 class RoleInline(PlStackTabularInline):
131 suit_classes = 'suit-tab suit-tab-roles'
133 class NodeInline(PlStackTabularInline):
136 suit_classes = 'suit-tab suit-tab-nodes'
138 class SlicePrivilegeInline(PlStackTabularInline):
139 model = SlicePrivilege
141 suit_classes = 'suit-tab suit-tab-sliceprivileges'
143 class DeploymentPrivilegeInline(PlStackTabularInline):
144 model = DeploymentPrivilege
146 suit_classes = 'suit-tab suit-tab-deploymentprivileges'
148 class SitePrivilegeInline(PlStackTabularInline):
149 model = SitePrivilege
151 suit_classes = 'suit-tab suit-tab-siteprivileges'
153 def formfield_for_foreignkey(self, db_field, request, **kwargs):
154 if db_field.name == 'site':
155 if not request.user.is_admin:
156 # only show sites where user is an admin or pi
157 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
158 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
159 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
160 sites = Site.objects.filter(login_base__in=login_bases)
161 kwargs['queryset'] = sites
163 if db_field.name == 'user':
164 if not request.user.is_admin:
165 # only show users from sites where caller has admin or pi role
166 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
167 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
168 sites = [site_privilege.site for site_privilege in site_privileges]
169 site_privileges = SitePrivilege.objects.filter(site__in=sites)
170 emails = [site_privilege.user.email for site_privilege in site_privileges]
171 users = User.objects.filter(email__in=emails)
172 kwargs['queryset'] = users
173 return super(SitePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
175 class SitePrivilegeInline(PlStackTabularInline):
176 model = SitePrivilege
177 suit_classes = 'suit-tab suit-tab-siteprivileges'
179 fields = ('user', 'site','role')
181 class SlicePrivilegeInline(PlStackTabularInline):
182 model = SlicePrivilege
183 suit_classes = 'suit-tab suit-tab-sliceprivileges'
185 fields = ('user', 'slice','role')
187 def formfield_for_foreignkey(self, db_field, request, **kwargs):
188 if db_field.name == 'slice':
189 if not request.user.is_admin:
190 # only show slices at sites where caller has admin or pi role
191 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
192 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
193 sites = [site_privilege.site for site_privilege in site_privileges]
194 slices = Slice.objects.filter(site__in=sites)
195 kwargs['queryset'] = slices
196 if db_field.name == 'user':
197 if not request.user.is_admin:
198 # only show users from sites where caller has admin or pi role
199 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
200 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
201 sites = [site_privilege.site for site_privilege in site_privileges]
202 site_privileges = SitePrivilege.objects.filter(site__in=sites)
203 emails = [site_privilege.user.email for site_privilege in site_privileges]
204 users = User.objects.filter(email__in=emails)
205 kwargs['queryset'] = list(users)
207 return super(SlicePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
209 class SliceNetworkInline(PlStackTabularInline):
210 model = Network.slices.through
212 verbose_name = "Network Connection"
213 verbose_name_plural = "Network Connections"
214 suit_classes = 'suit-tab suit-tab-slicenetworks'
216 class SliceTagInline(PlStackTabularInline):
220 class PlainTextWidget(forms.HiddenInput):
221 input_type = 'hidden'
223 def render(self, name, value, attrs=None):
226 return mark_safe(str(value) + super(PlainTextWidget, self).render(name, value, attrs))
228 class PlanetStackBaseAdmin(admin.ModelAdmin):
230 exclude = ['enacted']
232 class SliceRoleAdmin(PlanetStackBaseAdmin):
236 class SiteRoleAdmin(PlanetStackBaseAdmin):
240 class DeploymentAdminForm(forms.ModelForm):
241 sites = forms.ModelMultipleChoiceField(
242 queryset=Site.objects.all(),
244 widget=FilteredSelectMultiple(
245 verbose_name=('Sites'), is_stacked=False
252 class DeploymentAdmin(PlanetStackBaseAdmin):
253 form = DeploymentAdminForm
254 inlines = [DeploymentPrivilegeInline,NodeInline,TagInline]
256 (None, {'fields': ['sites'], 'classes':['suit-tab suit-tab-sites']}),]
257 suit_form_tabs =(('sites', 'Sites'),('nodes','Nodes'),('deploymentprivileges','Privileges'),('tags','Tags'))
259 class SiteAdmin(PlanetStackBaseAdmin):
261 (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base', 'location'], 'classes':['suit-tab suit-tab-general']}),
262 ('Deployment Networks', {'fields': ['deployments'], 'classes':['suit-tab suit-tab-deployments']}),
264 suit_form_tabs =(('general', 'Site Details'),
266 ('siteprivileges','Privileges'),
267 ('deployments','Deployments'),
272 list_display = ('name', 'login_base','site_url', 'enabled')
273 filter_horizontal = ('deployments',)
274 inlines = [SliceInline,UserInline,TagInline, NodeInline, SitePrivilegeInline]
275 search_fields = ['name']
277 def queryset(self, request):
278 # admins can see all keys. Users can only see sites they belong to.
279 qs = super(SiteAdmin, self).queryset(request)
280 if not request.user.is_admin:
281 valid_sites = [request.user.site.login_base]
282 roles = request.user.get_roles()
283 for tenant_list in roles.values():
284 valid_sites.extend(tenant_list)
285 qs = qs.filter(login_base__in=valid_sites)
288 def get_formsets(self, request, obj=None):
289 for inline in self.get_inline_instances(request, obj):
290 # hide MyInline in the add view
293 if isinstance(inline, SliceInline):
294 inline.model.caller = request.user
295 yield inline.get_formset(request, obj)
297 def get_formsets(self, request, obj=None):
298 for inline in self.get_inline_instances(request, obj):
299 # hide MyInline in the add view
302 if isinstance(inline, SliverInline):
303 inline.model.caller = request.user
304 yield inline.get_formset(request, obj)
306 class SitePrivilegeAdmin(PlanetStackBaseAdmin):
308 (None, {'fields': ['user', 'site', 'role'], 'classes':['collapse']})
310 list_display = ('user', 'site', 'role')
312 def formfield_for_foreignkey(self, db_field, request, **kwargs):
313 if db_field.name == 'site':
314 if not request.user.is_admin:
315 # only show sites where user is an admin or pi
317 for site_privilege in SitePrivilege.objects.filer(user=request.user):
318 if site_privilege.role.role_type in ['admin', 'pi']:
319 sites.add(site_privilege.site)
320 kwargs['queryset'] = Site.objects.filter(site__in=list(sites))
322 if db_field.name == 'user':
323 if not request.user.is_admin:
324 # only show users from sites where caller has admin or pi role
325 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
326 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
327 sites = [site_privilege.site for site_privilege in site_privileges]
328 site_privileges = SitePrivilege.objects.filter(site__in=sites)
329 emails = [site_privilege.user.email for site_privilege in site_privileges]
330 users = User.objects.filter(email__in=emails)
331 kwargs['queryset'] = users
333 return super(SitePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
335 def queryset(self, request):
336 # admins can see all privileges. Users can only see privileges at sites
337 # where they have the admin role or pi role.
338 qs = super(SitePrivilegeAdmin, self).queryset(request)
339 if not request.user.is_admin:
340 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
341 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
342 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
343 sites = Site.objects.filter(login_base__in=login_bases)
344 qs = qs.filter(site__in=sites)
347 class SliceAdmin(PlanetStackBaseAdmin):
348 fieldsets = [('Slice Details', {'fields': ['name', 'site', 'serviceClass', 'description', 'slice_url'], 'classes':['suit-tab suit-tab-general']}),]
349 list_display = ('name', 'site','serviceClass', 'slice_url')
350 inlines = [SlicePrivilegeInline,SliverInline, TagInline, ReservationInline,SliceNetworkInline]
353 #inlines = [SliverInline, SliceMembershipInline, TagInline, SliceTagInline, SliceNetworkInline]
354 suit_form_tabs =(('general', 'Slice Details'),
355 ('slicenetworks','Networks'),
356 ('sliceprivileges','Privileges'),
357 ('slivers','Slivers'),
359 ('reservations','Reservations'),
362 def formfield_for_foreignkey(self, db_field, request, **kwargs):
363 if db_field.name == 'site':
364 if not request.user.is_admin:
365 # only show sites where user is a pi or admin
366 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
367 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
368 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
369 sites = Site.objects.filter(login_base__in=login_bases)
370 kwargs['queryset'] = sites
372 return super(SliceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
374 def queryset(self, request):
375 # admins can see all keys. Users can only see slices they belong to.
376 qs = super(SliceAdmin, self).queryset(request)
377 if not request.user.is_admin:
379 roles = request.user.get_roles()
380 for tenant_list in roles.values():
381 valid_slices.extend(tenant_list)
382 qs = qs.filter(name__in=valid_slices)
385 def get_formsets(self, request, obj=None):
386 for inline in self.get_inline_instances(request, obj):
387 # hide MyInline in the add view
390 if isinstance(inline, SliverInline):
391 inline.model.caller = request.user
392 yield inline.get_formset(request, obj)
394 def get_queryset(self, request):
395 qs = super(SliceAdmin, self).get_queryset(request)
396 if request.user.is_superuser:
398 # users can only see slices at their site
399 return qs.filter(site=request.user.site)
401 def save_model(self, request, obj, form, change):
402 # update openstack connection to use this site/tenant
403 obj.caller = request.user
406 class SlicePrivilegeAdmin(PlanetStackBaseAdmin):
408 (None, {'fields': ['user', 'slice', 'role']})
410 list_display = ('user', 'slice', 'role')
412 def formfield_for_foreignkey(self, db_field, request, **kwargs):
413 if db_field.name == 'slice':
414 if not request.user.is_admin:
415 # only show slices at sites where caller has admin or pi role
416 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
417 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
418 sites = [site_privilege.site for site_privilege in site_privileges]
419 slices = Slice.objects.filter(site__in=sites)
420 kwargs['queryset'] = slices
422 if db_field.name == 'user':
423 if not request.user.is_admin:
424 # only show users from sites where caller has admin or pi role
425 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
426 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
427 sites = [site_privilege.site for site_privilege in site_privileges]
428 site_privileges = SitePrivilege.objects.filter(site__in=sites)
429 emails = [site_privilege.user.email for site_privilege in site_privileges]
430 users = User.objects.filter(email__in=emails)
431 kwargs['queryset'] = users
433 return super(SlicePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
435 def queryset(self, request):
436 # admins can see all memberships. Users can only see memberships of
437 # slices where they have the admin role.
438 qs = super(SlicePrivilegeAdmin, self).queryset(request)
439 if not request.user.is_admin:
440 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
441 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
442 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
443 sites = Site.objects.filter(login_base__in=login_bases)
444 slices = Slice.objects.filter(site__in=sites)
445 qs = qs.filter(slice__in=slices)
448 def save_model(self, request, obj, form, change):
449 # update openstack connection to use this site/tenant
450 auth = request.session.get('auth', {})
451 auth['tenant'] = obj.slice.name
452 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
455 def delete_model(self, request, obj):
456 # update openstack connection to use this site/tenant
457 auth = request.session.get('auth', {})
458 auth['tenant'] = obj.slice.name
459 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
463 class ImageAdmin(PlanetStackBaseAdmin):
465 fieldsets = [('Image Details',
466 {'fields': ['image_id', 'name', 'disk_format', 'container_format'],
467 'classes': ['suit-tab suit-tab-general']})
470 suit_form_tabs =(('general','Image Details'),('slivers','Slivers'))
472 inlines = [SliverInline]
474 class NodeForm(forms.ModelForm):
477 'site': LinkedSelect,
478 'deployment': LinkedSelect
481 class NodeAdmin(admin.ModelAdmin):
483 exclude = ['enacted']
484 list_display = ('name', 'site', 'deployment')
485 list_filter = ('deployment',)
486 inlines = [TagInline,SliverInline]
487 fieldsets = [('Node Details', {'fields': ['name','site','deployment'], 'classes':['suit-tab suit-tab-details']})]
489 suit_form_tabs =(('details','Node Details'),('slivers','Slivers'),('tags','Tags'))
492 class SliverForm(forms.ModelForm):
495 ip = forms.CharField(widget=PlainTextWidget)
496 instance_name = forms.CharField(widget=PlainTextWidget)
498 'ip': PlainTextWidget(),
499 'instance_name': PlainTextWidget(),
500 'slice': LinkedSelect,
501 'deploymentNetwork': LinkedSelect,
502 'node': LinkedSelect,
503 'image': LinkedSelect
506 class ProjectAdmin(admin.ModelAdmin):
507 exclude = ['enacted']
508 inlines = [TagInline]
510 class MemberAdmin(admin.ModelAdmin):
511 exclude = ['enacted']
512 list_display = ['role', 'rightContent_type', 'content_type', 'content_object',]
514 class TagAdmin(admin.ModelAdmin):
515 exclude = ['enacted']
516 list_display = ['project', 'name', 'value', 'content_type', 'content_object',]
518 class SliverAdmin(PlanetStackBaseAdmin):
521 ('Sliver Details', {'fields': ['slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'numberCores', 'image', ], 'classes': ['suit-tab suit-tab-general'], })
523 list_display = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
525 suit_form_tabs =(('general', 'Sliver Details'),
529 inlines = [TagInline]
531 def formfield_for_foreignkey(self, db_field, request, **kwargs):
532 if db_field.name == 'slice':
533 if not request.user.is_admin:
534 slices = set([sm.slice.name for sm in SlicePrivilege.objects.filter(user=request.user)])
535 kwargs['queryset'] = Slice.objects.filter(name__in=list(slices))
537 return super(SliverAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
539 def queryset(self, request):
540 # admins can see all slivers. Users can only see slivers of
541 # the slices they belong to.
542 qs = super(SliverAdmin, self).queryset(request)
543 if not request.user.is_admin:
545 roles = request.user.get_roles()
546 for tenant_list in roles.values():
547 tenants.extend(tenant_list)
548 valid_slices = Slice.objects.filter(name__in=tenants)
549 qs = qs.filter(slice__in=valid_slices)
552 def get_formsets(self, request, obj=None):
553 # make some fields read only if we are updating an existing record
555 #self.readonly_fields = ('ip', 'instance_name')
556 self.readonly_fields = ()
558 self.readonly_fields = ()
559 #self.readonly_fields = ('ip', 'instance_name', 'slice', 'image', 'key')
561 for inline in self.get_inline_instances(request, obj):
562 # hide MyInline in the add view
565 # give inline object access to driver and caller
566 auth = request.session.get('auth', {})
567 auth['tenant'] = obj.name # meed to connect using slice's tenant
568 inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
569 yield inline.get_formset(request, obj)
571 def save_model(self, request, obj, form, change):
572 # update openstack connection to use this site/tenant
573 auth = request.session.get('auth', {})
574 auth['tenant'] = obj.slice.name
575 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
576 obj.creator = request.user
579 def delete_model(self, request, obj):
580 # update openstack connection to use this site/tenant
581 auth = request.session.get('auth', {})
582 auth['tenant'] = obj.slice.name
583 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
586 class UserCreationForm(forms.ModelForm):
587 """A form for creating new users. Includes all the required
588 fields, plus a repeated password."""
589 password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
590 password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
594 fields = ('email', 'firstname', 'lastname', 'phone', 'public_key')
596 def clean_password2(self):
597 # Check that the two password entries match
598 password1 = self.cleaned_data.get("password1")
599 password2 = self.cleaned_data.get("password2")
600 if password1 and password2 and password1 != password2:
601 raise forms.ValidationError("Passwords don't match")
604 def save(self, commit=True):
605 # Save the provided password in hashed format
606 user = super(UserCreationForm, self).save(commit=False)
607 user.password = self.cleaned_data["password1"]
608 #user.set_password(self.cleaned_data["password1"])
614 class UserChangeForm(forms.ModelForm):
615 """A form for updating users. Includes all the fields on
616 the user, but replaces the password field with admin's
617 password hash display field.
619 password = ReadOnlyPasswordHashField()
624 def clean_password(self):
625 # Regardless of what the user provides, return the initial value.
626 # This is done here, rather than on the field, because the
627 # field does not have access to the initial value
628 return self.initial["password"]
631 class UserAdmin(UserAdmin):
635 # The forms to add and change user instances
636 form = UserChangeForm
637 add_form = UserCreationForm
639 # The fields to be used in displaying the User model.
640 # These override the definitions on the base UserAdmin
641 # that reference specific fields on auth.User.
642 list_display = ('email', 'username','firstname', 'lastname', 'is_admin', 'last_login')
644 inlines = [SlicePrivilegeInline,SitePrivilegeInline,DeploymentPrivilegeInline]
646 ('Login Details', {'fields': ('email', 'username','site','password', 'is_admin', 'public_key'), 'classes':['suit-tab suit-tab-general']}),
647 ('Contact Information', {'fields': ('firstname','lastname','phone', 'timezone'), 'classes':['suit-tab suit-tab-contact']}),
648 #('Important dates', {'fields': ('last_login',)}),
652 'classes': ('wide',),
653 'fields': ('email', 'username','firstname', 'lastname', 'phone', 'public_key','password1', 'password2')}
656 search_fields = ('email',)
657 ordering = ('email',)
658 filter_horizontal = ()
660 suit_form_tabs =(('general','Login Details'),('contact','Contact Information'),('sliceprivileges','Slice Privileges'),('siteprivileges','Site Privileges'),('deploymentprivileges','Deployment Privileges'))
662 def formfield_for_foreignkey(self, db_field, request, **kwargs):
663 if db_field.name == 'site':
664 if not request.user.is_admin:
665 # show sites where caller is an admin or pi
667 for site_privilege in SitePrivilege.objects.filer(user=request.user):
668 if site_privilege.role.role_type in ['admin', 'pi']:
669 sites.append(site_privilege.site.login_base)
670 kwargs['queryset'] = Site.objects.filter(login_base__in(list(sites)))
672 return super(UserAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
674 class ServiceResourceInline(admin.TabularInline):
675 exclude = ['enacted']
676 model = ServiceResource
679 class ServiceClassAdmin(admin.ModelAdmin):
680 exclude = ['enacted']
681 list_display = ('name', 'commitment', 'membershipFee')
682 inlines = [ServiceResourceInline]
684 class ReservedResourceInline(admin.TabularInline):
685 exclude = ['enacted']
686 model = ReservedResource
688 suit_classes = 'suit-tab suit-tab-reservedresources'
690 def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
691 field = super(ReservedResourceInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
693 if db_field.name == 'resource':
694 # restrict resources to those that the slice's service class allows
695 if request._slice is not None:
696 field.queryset = field.queryset.filter(serviceClass = request._slice.serviceClass, calendarReservable=True)
697 if len(field.queryset) > 0:
698 field.initial = field.queryset.all()[0]
700 field.queryset = field.queryset.none()
\r
701 elif db_field.name == 'sliver':
\r
702 # restrict slivers to those that belong to the slice
\r
703 if request._slice is not None:
\r
704 field.queryset = field.queryset.filter(slice = request._slice)
706 field.queryset = field.queryset.none()
\r
710 class ReservationChangeForm(forms.ModelForm):
714 'slice' : LinkedSelect
717 class ReservationAddForm(forms.ModelForm):
718 slice = forms.ModelChoiceField(queryset=Slice.objects.all(), widget=forms.Select(attrs={"onChange":"document.getElementById('id_refresh').value=1; submit()"}))
719 refresh = forms.CharField(widget=forms.HiddenInput())
722 css = {'all': ('planetstack.css',)} # .field-refresh { display: none; }
724 def clean_slice(self):
725 slice = self.cleaned_data.get("slice")
726 x = ServiceResource.objects.filter(serviceClass = slice.serviceClass, calendarReservable=True)
728 raise forms.ValidationError("The slice you selected does not have a service class that allows reservations")
734 'slice' : LinkedSelect
738 class ReservationAddRefreshForm(ReservationAddForm):
739 """ This form is displayed when the Reservation Form receives an update
740 from the Slice dropdown onChange handler. It doesn't validate the
741 data and doesn't save the data. This will cause the form to be
745 """ don't validate anything other than slice """
746 dont_validate_fields = ("startTime", "duration")
748 def full_clean(self):
749 result = super(ReservationAddForm, self).full_clean()
751 for fieldname in self.dont_validate_fields:
752 if fieldname in self._errors:
753 del self._errors[fieldname]
757 """ don't save anything """
761 class ReservationAdmin(admin.ModelAdmin):
762 exclude = ['enacted']
763 fieldsets = [('Reservation Details', {'fields': ['startTime', 'duration','slice'], 'classes': ['suit-tab suit-tab-general']})]
764 list_display = ('startTime', 'duration')
765 form = ReservationAddForm
767 suit_form_tabs = (('general','Reservation Details'), ('reservedresources','Reserved Resources'))
769 inlines = [ReservedResourceInline]
771 def add_view(self, request, form_url='', extra_context=None):
772 timezone.activate(request.user.timezone)
773 request._refresh = False
774 request._slice = None
775 if request.method == 'POST':
776 # "refresh" will be set to "1" if the form was submitted due to
777 # a change in the Slice dropdown.
778 if request.POST.get("refresh","1") == "1":
779 request._refresh = True
780 request.POST["refresh"] = "0"
782 # Keep track of the slice that was selected, so the
783 # reservedResource inline can filter items for the slice.
784 request._slice = request.POST.get("slice",None)
785 if (request._slice is not None):
786 request._slice = Slice.objects.get(id=request._slice)
788 result = super(ReservationAdmin, self).add_view(request, form_url, extra_context)
791 def changelist_view(self, request, extra_context = None):
792 timezone.activate(request.user.timezone)
793 return super(ReservationAdmin, self).changelist_view(request, extra_context)
795 def get_form(self, request, obj=None, **kwargs):
798 # For changes, set request._slice to the slice already set in the
800 request._slice = obj.slice
801 self.form = ReservationChangeForm
803 if getattr(request, "_refresh", False):
804 self.form = ReservationAddRefreshForm
806 self.form = ReservationAddForm
807 return super(ReservationAdmin, self).get_form(request, obj, **kwargs)
809 def get_readonly_fields(self, request, obj=None):
810 if (obj is not None):
811 # Prevent slice from being changed after the reservation has been
817 class NetworkParameterTypeAdmin(admin.ModelAdmin):
818 exclude = ['enacted']
819 list_display = ("name", )
821 class RouterAdmin(admin.ModelAdmin):
822 exclude = ['enacted']
823 list_display = ("name", )
825 class RouterInline(admin.TabularInline):
826 # exclude = ['enacted']
827 model = Router.networks.through
829 verbose_name_plural = "Routers"
830 verbose_name = "Router"
831 suit_classes = 'suit-tab suit-tab-routers'
833 class NetworkParameterInline(generic.GenericTabularInline):
834 exclude = ['enacted']
835 model = NetworkParameter
837 verbose_name_plural = "Parameters"
838 verbose_name = "Parameter"
839 suit_classes = 'suit-tab suit-tab-netparams'
841 class NetworkSliversInline(admin.TabularInline):
842 exclude = ['enacted']
843 readonly_fields = ("ip", )
844 model = NetworkSliver
846 verbose_name_plural = "Slivers"
847 verbose_name = "Sliver"
848 suit_classes = 'suit-tab suit-tab-networkslivers'
850 class NetworkSlicesInline(admin.TabularInline):
851 exclude = ['enacted']
854 verbose_name_plural = "Slices"
855 verbose_name = "Slice"
856 suit_classes = 'suit-tab suit-tab-networkslices'
858 class NetworkAdmin(admin.ModelAdmin):
859 exclude = ['enacted']
860 list_display = ("name", "subnet", "ports", "labels")
861 readonly_fields = ("subnet", )
863 inlines = [NetworkParameterInline, NetworkSliversInline, NetworkSlicesInline, RouterInline]
866 (None, {'fields': ['name','template','ports','labels','owner','guaranteedBandwidth', 'permitAllSlices','permittedSlices','network_id','router_id','subnet_id','subnet'], 'classes':['suit-tab suit-tab-general']}),]
869 ('general','Network Details'),
870 ('netparams', 'Parameters'),
871 ('networkslivers','Slivers'),
872 ('networkslices','Slices'),
873 ('routers','Routers'),
875 class NetworkTemplateAdmin(admin.ModelAdmin):
876 exclude = ['enacted']
877 list_display = ("name", "guaranteedBandwidth", "visibility")
879 # register a signal that caches the user's credentials when they log in
880 def cache_credentials(sender, user, request, **kwds):
881 auth = {'username': request.POST['username'],
882 'password': request.POST['password']}
883 request.session['auth'] = auth
884 user_logged_in.connect(cache_credentials)
886 # Now register the new UserAdmin...
887 admin.site.register(User, UserAdmin)
888 # ... and, since we're not using Django's builtin permissions,
889 # unregister the Group model from admin.
890 admin.site.unregister(Group)
892 #Do not show django evolution in the admin interface
893 from django_evolution.models import Version, Evolution
894 admin.site.unregister(Version)
895 admin.site.unregister(Evolution)
898 # When debugging it is often easier to see all the classes, but for regular use
899 # only the top-levels should be displayed
902 admin.site.register(Deployment, DeploymentAdmin)
903 admin.site.register(Site, SiteAdmin)
904 admin.site.register(Slice, SliceAdmin)
905 admin.site.register(Project, ProjectAdmin)
906 admin.site.register(ServiceClass, ServiceClassAdmin)
907 admin.site.register(Reservation, ReservationAdmin)
908 admin.site.register(Network, NetworkAdmin)
909 admin.site.register(Router, RouterAdmin)
910 admin.site.register(NetworkParameterType, NetworkParameterTypeAdmin)
911 admin.site.register(NetworkTemplate, NetworkTemplateAdmin)
914 #admin.site.register(PlanetStack)
915 admin.site.register(Tag, TagAdmin)
916 admin.site.register(Node, NodeAdmin)
917 #admin.site.register(SlicePrivilege, SlicePrivilegeAdmin)
918 #admin.site.register(SitePrivilege, SitePrivilegeAdmin)
919 admin.site.register(Member, MemberAdmin)
920 admin.site.register(Sliver, SliverAdmin)
921 admin.site.register(Image, ImageAdmin)