blob: 656ca42eb4381435c06f63225ad3940839c3e1af [file] [log] [blame]
Siobhan Tully30fd4292013-05-10 08:59:56 -04001from core.models import Site
2from core.models import *
3from openstack.manager import OpenStackManager
Tony Macke59a7c82013-04-27 11:08:10 -04004
Tony Mack7130ac32013-03-22 21:58:00 -04005from django.contrib import admin
Siobhan Tully53437282013-04-26 19:30:27 -04006from django.contrib.auth.models import Group
Siobhan Tully4bc09f22013-04-10 21:15:21 -04007from django import forms
Tony Mackd90cdbf2013-04-16 22:48:40 -04008from django.utils.safestring import mark_safe
Tony Mack7130ac32013-03-22 21:58:00 -04009from django.contrib.auth.admin import UserAdmin
Siobhan Tully4bc09f22013-04-10 21:15:21 -040010from django.contrib.admin.widgets import FilteredSelectMultiple
Siobhan Tully53437282013-04-26 19:30:27 -040011from django.contrib.auth.forms import ReadOnlyPasswordHashField
Tony Mack31c2b8f2013-04-26 20:01:42 -040012from django.contrib.auth.signals import user_logged_in
Tony Mack7130ac32013-03-22 21:58:00 -040013
Siobhan Tully4bc09f22013-04-10 21:15:21 -040014
15class ReadonlyTabularInline(admin.TabularInline):
16 can_delete = False
17 extra = 0
18 editable_fields = []
19
20 def get_readonly_fields(self, request, obj=None):
21 fields = []
22 for field in self.model._meta.get_all_field_names():
23 if (not field == 'id'):
24 if (field not in self.editable_fields):
25 fields.append(field)
26 return fields
27
28 def has_add_permission(self, request):
29 return False
30
31class SliverInline(admin.TabularInline):
32 model = Sliver
Tony Mack3777b012013-05-07 21:38:06 -040033 fields = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'key', 'node', 'deploymentNetwork']
Siobhan Tully4bc09f22013-04-10 21:15:21 -040034 extra = 0
Tony Mack3777b012013-05-07 21:38:06 -040035 #readonly_fields = ['ip', 'instance_name', 'image']
36 readonly_fields = ['ip', 'instance_name']
Siobhan Tully4bc09f22013-04-10 21:15:21 -040037
38class SiteInline(admin.TabularInline):
39 model = Site
40 extra = 0
41
Siobhan Tully30fd4292013-05-10 08:59:56 -040042class UserInline(admin.TabularInline):
43 model = User
Siobhan Tully47ae1b52013-05-10 15:53:14 -040044 fields = ['email', 'firstname', 'lastname']
Siobhan Tully30fd4292013-05-10 08:59:56 -040045 extra = 0
46
Tony Mack00d361f2013-04-28 10:28:42 -040047class SliceInline(admin.TabularInline):
48 model = Slice
49 extra = 0
50
Tony Mack00d361f2013-04-28 10:28:42 -040051class RoleInline(admin.TabularInline):
52 model = Role
53 extra = 0
54
Siobhan Tully4bc09f22013-04-10 21:15:21 -040055class NodeInline(admin.TabularInline):
56 model = Node
57 extra = 0
58
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -040059class SitePrivilegeInline(admin.TabularInline):
60 model = SitePrivilege
61 extra = 0
62
63class SliceMembershipInline(admin.TabularInline):
64 model = SliceMembership
65 extra = 0
66
Tony Mack5e71a662013-05-03 23:30:41 -040067class PlainTextWidget(forms.HiddenInput):
68 input_type = 'hidden'
69
70 def render(self, name, value, attrs=None):
71 if value is None:
72 value = ''
Tony Mack1d6b85f2013-05-07 18:49:14 -040073 return mark_safe(str(value) + super(PlainTextWidget, self).render(name, value, attrs))
Tony Mack9bcbe4f2013-04-29 08:13:27 -040074
Siobhan Tully4bc09f22013-04-10 21:15:21 -040075class PlanetStackBaseAdmin(admin.ModelAdmin):
76 save_on_top = False
77
Tony Mackfdd4d802013-04-27 13:02:33 -040078class OSModelAdmin(PlanetStackBaseAdmin):
Tony Mackd685bfa2013-05-02 10:09:51 -040079 """Attach client connection to openstack on delete() and save()"""
Tony Mack79748612013-05-01 14:52:03 -040080
Tony Mackfdd4d802013-04-27 13:02:33 -040081 def save_model(self, request, obj, form, change):
Tony Mack38e247c2013-05-05 11:48:14 -040082 if request.user.site:
83 auth = request.session.get('auth', {})
84 auth['tenant'] = request.user.site.login_base
85 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mackfdd4d802013-04-27 13:02:33 -040086 obj.save()
87
88 def delete_model(self, request, obj):
Tony Mack38e247c2013-05-05 11:48:14 -040089 if request.user.site:
90 auth = request.session.get('auth', {})
91 auth['tenant'] = request.user.site.login_base
92 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mackd685bfa2013-05-02 10:09:51 -040093 obj.delete()
Tony Mack9bcbe4f2013-04-29 08:13:27 -040094
Tony Mackd685bfa2013-05-02 10:09:51 -040095class RoleAdmin(OSModelAdmin):
Tony Mack9bcbe4f2013-04-29 08:13:27 -040096 fieldsets = [
97 ('Role', {'fields': ['role_type']})
98 ]
99 list_display = ('role_type',)
Tony Mackfdd4d802013-04-27 13:02:33 -0400100
Tony Mack02755d42013-05-02 00:00:10 -0400101
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400102class DeploymentNetworkAdminForm(forms.ModelForm):
103 sites = forms.ModelMultipleChoiceField(
104 queryset=Site.objects.all(),
105 required=False,
106 widget=FilteredSelectMultiple(
107 verbose_name=('Sites'), is_stacked=False
108 )
109 )
110 class Meta:
111 model = DeploymentNetwork
112
113 def __init__(self, *args, **kwargs):
114 super(DeploymentNetworkAdminForm, self).__init__(*args, **kwargs)
115
116 if self.instance and self.instance.pk:
117 self.fields['sites'].initial = self.instance.sites.all()
118
119 def save(self, commit=True):
120 deploymentNetwork = super(DeploymentNetworkAdminForm, self).save(commit=False)
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400121 if commit:
122 deploymentNetwork.save()
123
124 if deploymentNetwork.pk:
125 deploymentNetwork.sites = self.cleaned_data['sites']
126 self.save_m2m()
127
128 return deploymentNetwork
129
130class DeploymentNetworkAdmin(PlanetStackBaseAdmin):
131 form = DeploymentNetworkAdminForm
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400132 inlines = [NodeInline,SliverInline]
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400133
Tony Mack5cd13202013-05-01 21:48:38 -0400134 def get_formsets(self, request, obj=None):
135 for inline in self.get_inline_instances(request, obj):
136 # hide MyInline in the add view
137 if obj is None:
138 continue
139 # give inline object access to driver and caller
Tony Macked163d72013-05-02 20:05:42 -0400140 auth = request.session.get('auth', {})
Siobhan Tully73291342013-05-10 10:50:08 -0400141 if request.user.site:
142 auth['tenant'] = request.user.site.login_base
Tony Macked163d72013-05-02 20:05:42 -0400143 inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack5cd13202013-05-01 21:48:38 -0400144 yield inline.get_formset(request, obj)
145
Tony Mackfdd4d802013-04-27 13:02:33 -0400146class SiteAdmin(OSModelAdmin):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400147 fieldsets = [
148 (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base']}),
149 ('Location', {'fields': ['latitude', 'longitude']}),
150 ('Deployment Networks', {'fields': ['deployments']})
151 ]
152 list_display = ('name', 'login_base','site_url', 'enabled')
153 filter_horizontal = ('deployments',)
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400154 inlines = [NodeInline, UserInline, SitePrivilegeInline]
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400155 search_fields = ['name']
156
Tony Mack04062832013-05-10 08:22:44 -0400157 def queryset(self, request):
158 # admins can see all keys. Users can only see sites they belong to.
159 qs = super(SiteAdmin, self).queryset(request)
160 if not request.user.is_admin:
161 valid_sites = [request.user.site.login_base]
162 roles = request.user.get_roles()
163 for tenant_list in roles.values():
164 valid_sites.extend(tenant_list)
165 qs = qs.filter(login_base__in=valid_sites)
166 return qs
167
Tony Mack5cd13202013-05-01 21:48:38 -0400168 def get_formsets(self, request, obj=None):
169 for inline in self.get_inline_instances(request, obj):
170 # hide MyInline in the add view
171 if obj is None:
172 continue
173 # give inline object access to driver and caller
Tony Mack60722062013-05-02 10:57:04 -0400174 auth = request.session.get('auth', {})
Siobhan Tully30fd4292013-05-10 08:59:56 -0400175 #auth['tenant'] = request.user.site.login_base
Tony Mack60722062013-05-02 10:57:04 -0400176 inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack5cd13202013-05-01 21:48:38 -0400177 yield inline.get_formset(request, obj)
178
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400179class SitePrivilegeAdmin(PlanetStackBaseAdmin):
Tony Mack00d361f2013-04-28 10:28:42 -0400180 fieldsets = [
181 (None, {'fields': ['user', 'site', 'role']})
182 ]
183 list_display = ('user', 'site', 'role')
184
Tony Mack04062832013-05-10 08:22:44 -0400185 def queryset(self, request):
186 # admins can see all privileges. Users can only see privileges at sites
187 # where they have the admin role.
188 qs = super(SitePrivilegeAdmin, self).queryset(request)
189 if not request.user.is_admin:
190 roles = request.user.get_roles()
191 tenants = []
192 for (role, tenant_list) in roles:
193 if role == 'admin':
194 tenants.extend(tenant_list)
195 valid_sites = Sites.objects.filter(login_base__in=tenants)
196 qs = qs.filter(site__in=valid_sites)
197 return qs
198
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400199 def save_model(self, request, obj, form, change):
200 # update openstack connection to use this site/tenant
Tony Mack93048c22013-05-02 11:20:26 -0400201 auth = request.session.get('auth', {})
Siobhan Tully30fd4292013-05-10 08:59:56 -0400202 #auth['tenant'] = obj.site.login_base
Tony Mack93048c22013-05-02 11:20:26 -0400203 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400204 obj.save()
205
206 def delete_model(self, request, obj):
207 # update openstack connection to use this site/tenant
Tony Mack93048c22013-05-02 11:20:26 -0400208 auth = request.session.get('auth', {})
Siobhan Tully30fd4292013-05-10 08:59:56 -0400209 #auth['tenant'] = obj.site.login_base
Tony Mack93048c22013-05-02 11:20:26 -0400210 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400211 obj.delete()
212
Tony Mackfdd4d802013-04-27 13:02:33 -0400213class KeyAdmin(OSModelAdmin):
Tony Mack759b57a2013-04-14 21:03:31 -0400214 fieldsets = [
Siobhan Tully73291342013-05-10 10:50:08 -0400215 ('Key', {'fields': ['key', 'type', 'blacklisted']})
Tony Mack759b57a2013-04-14 21:03:31 -0400216 ]
Siobhan Tully73291342013-05-10 10:50:08 -0400217 list_display = ['key', 'type', 'blacklisted']
Tony Mack8484bdb2013-04-14 20:26:03 -0400218
Siobhan Tully73291342013-05-10 10:50:08 -0400219 #def queryset(self, request):
Tony Mackc14de8f2013-05-09 21:44:17 -0400220 # admins can see all keys. Users can only see their own key.
Siobhan Tully73291342013-05-10 10:50:08 -0400221 #if request.user.is_admin:
222 # qs = super(KeyAdmin, self).queryset(request)
223 #else:
224 # qs = Key.objects.filter(user=request.user)
Scott Baker133c9212013-05-17 09:09:11 -0700225 #return qs
226
Tony Mackfdd4d802013-04-27 13:02:33 -0400227class SliceAdmin(OSModelAdmin):
Siobhan Tully30fd4292013-05-10 08:59:56 -0400228 fields = ['name', 'site', 'serviceClass', 'description', 'slice_url']
229 list_display = ('name', 'site','serviceClass', 'slice_url')
Siobhan Tully47ae1b52013-05-10 15:53:14 -0400230 inlines = [SliverInline, SliceMembershipInline]
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400231
Tony Mack04062832013-05-10 08:22:44 -0400232 def queryset(self, request):
233 # admins can see all keys. Users can only see slices they belong to.
234 qs = super(SliceAdmin, self).queryset(request)
235 if not request.user.is_admin:
236 valid_slices = []
237 roles = request.user.get_roles()
238 for tenant_list in roles.values():
239 valid_slices.extend(tenant_list)
240 qs = qs.filter(name__in=valid_slices)
241 return qs
242
Tony Mack79748612013-05-01 14:52:03 -0400243 def get_formsets(self, request, obj=None):
244 for inline in self.get_inline_instances(request, obj):
245 # hide MyInline in the add view
246 if obj is None:
247 continue
248 # give inline object access to driver and caller
Tony Mack93048c22013-05-02 11:20:26 -0400249 auth = request.session.get('auth', {})
250 auth['tenant'] = obj.name # meed to connect using slice's tenant
251 inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack79748612013-05-01 14:52:03 -0400252 yield inline.get_formset(request, obj)
253
Tony Mackfdd4d802013-04-27 13:02:33 -0400254 def get_queryset(self, request):
255 qs = super(SliceAdmin, self).get_queryset(request)
256 if request.user.is_superuser:
257 return qs
258 # users can only see slices at their site
259 return qs.filter(site=request.user.site)
260
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400261class SliceMembershipAdmin(PlanetStackBaseAdmin):
Tony Mack00d361f2013-04-28 10:28:42 -0400262 fieldsets = [
263 (None, {'fields': ['user', 'slice', 'role']})
264 ]
265 list_display = ('user', 'slice', 'role')
Tony Mack00d361f2013-04-28 10:28:42 -0400266
Tony Mack04062832013-05-10 08:22:44 -0400267 def queryset(self, request):
268 # admins can see all memberships. Users can only see memberships of
269 # slices where they have the admin role.
270 qs = super(SliceMembershipAdmin, self).queryset(request)
271 if not request.user.is_admin:
272 roles = request.user.get_roles()
273 tenants = []
274 for (role, tenant_list) in roles:
275 if role == 'admin':
276 tenants.extend(tenant_list)
277 valid_slices = Slice.objects.filter(name__in=tenants)
278 qs = qs.filter(slice__in=valid_slices)
279 return qs
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400280
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400281 def save_model(self, request, obj, form, change):
Tony Mack951dab42013-05-02 19:51:45 -0400282 # update openstack connection to use this site/tenant
283 auth = request.session.get('auth', {})
284 auth['tenant'] = obj.slice.name
285 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400286 obj.save()
287
288 def delete_model(self, request, obj):
Tony Mack951dab42013-05-02 19:51:45 -0400289 # update openstack connection to use this site/tenant
290 auth = request.session.get('auth', {})
291 auth['tenant'] = obj.slice.name
292 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400293 obj.delete()
294
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400295
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400296class ImageAdmin(admin.ModelAdmin):
297 fields = ['image_id', 'name', 'disk_format', 'container_format']
298
299class NodeAdmin(admin.ModelAdmin):
300 list_display = ('name', 'site', 'deploymentNetwork')
301 list_filter = ('deploymentNetwork',)
302
Tony Mackd90cdbf2013-04-16 22:48:40 -0400303
304class SliverForm(forms.ModelForm):
305 class Meta:
Tony Mack1d6b85f2013-05-07 18:49:14 -0400306 model = Sliver
Tony Mackd90cdbf2013-04-16 22:48:40 -0400307 ip = forms.CharField(widget=PlainTextWidget)
Tony Mack18261812013-05-02 16:39:20 -0400308 instance_name = forms.CharField(widget=PlainTextWidget)
Tony Mackd90cdbf2013-04-16 22:48:40 -0400309 widgets = {
310 'ip': PlainTextWidget(),
Tony Mack18261812013-05-02 16:39:20 -0400311 'instance_name': PlainTextWidget(),
Siobhan Tully53437282013-04-26 19:30:27 -0400312 }
Tony Mackd90cdbf2013-04-16 22:48:40 -0400313
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400314class SliverAdmin(PlanetStackBaseAdmin):
Tony Mackd90cdbf2013-04-16 22:48:40 -0400315 form = SliverForm
Tony Mackcdec0902013-04-15 00:38:49 -0400316 fieldsets = [
Tony Mack10082022013-05-06 17:15:00 -0400317 ('Sliver', {'fields': ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'key', 'node', 'deploymentNetwork']})
Tony Mackcdec0902013-04-15 00:38:49 -0400318 ]
Tony Mack10082022013-05-06 17:15:00 -0400319 list_display = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'key', 'node', 'deploymentNetwork']
Tony Mack53106f32013-04-27 16:43:01 -0400320
Tony Mack04062832013-05-10 08:22:44 -0400321 def queryset(self, request):
322 # admins can see all slivers. Users can only see slivers of
323 # the slices they belong to.
324 qs = super(SliverAdmin, self).queryset(request)
325 if not request.user.is_admin:
326 tenants = []
327 roles = request.user.get_roles()
328 for tenant_list in roles.values():
329 tenants.extend(tenant_list)
330 valid_slices = Slice.objects.filter(name__in=tenants)
331 qs = qs.filter(slice__in=valid_slices)
332 return qs
333
Tony Mack1d6b85f2013-05-07 18:49:14 -0400334 def get_formsets(self, request, obj=None):
335 # make some fields read only if we are updating an existing record
336 if obj == None:
337 #self.readonly_fields = ('ip', 'instance_name')
338 self.readonly_fields = ()
339 else:
Tony Mack1e889462013-05-10 21:34:54 -0400340 self.readonly_fields = ()
341 #self.readonly_fields = ('ip', 'instance_name', 'slice', 'image', 'key')
Tony Mack1d6b85f2013-05-07 18:49:14 -0400342
343 for inline in self.get_inline_instances(request, obj):
344 # hide MyInline in the add view
345 if obj is None:
346 continue
347 # give inline object access to driver and caller
348 auth = request.session.get('auth', {})
349 auth['tenant'] = obj.name # meed to connect using slice's tenant
350 inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
351 yield inline.get_formset(request, obj)
Tony Mack53106f32013-04-27 16:43:01 -0400352
353 def save_model(self, request, obj, form, change):
Tony Mack951dab42013-05-02 19:51:45 -0400354 # update openstack connection to use this site/tenant
355 auth = request.session.get('auth', {})
356 auth['tenant'] = obj.slice.name
357 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack53106f32013-04-27 16:43:01 -0400358 obj.save()
359
360 def delete_model(self, request, obj):
Tony Mack951dab42013-05-02 19:51:45 -0400361 # update openstack connection to use this site/tenant
362 auth = request.session.get('auth', {})
363 auth['tenant'] = obj.slice.name
364 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack53106f32013-04-27 16:43:01 -0400365 obj.delete()
Tony Mackcdec0902013-04-15 00:38:49 -0400366
Siobhan Tully53437282013-04-26 19:30:27 -0400367class UserCreationForm(forms.ModelForm):
368 """A form for creating new users. Includes all the required
369 fields, plus a repeated password."""
370 password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
371 password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
372
373 class Meta:
Siobhan Tully30fd4292013-05-10 08:59:56 -0400374 model = User
375 fields = ('email', 'firstname', 'lastname', 'phone', 'key', 'site')
Siobhan Tully53437282013-04-26 19:30:27 -0400376
377 def clean_password2(self):
378 # Check that the two password entries match
379 password1 = self.cleaned_data.get("password1")
380 password2 = self.cleaned_data.get("password2")
381 if password1 and password2 and password1 != password2:
382 raise forms.ValidationError("Passwords don't match")
383 return password2
384
385 def save(self, commit=True):
386 # Save the provided password in hashed format
387 user = super(UserCreationForm, self).save(commit=False)
Tony Mackf9f4afb2013-05-01 21:02:12 -0400388 user.password = self.cleaned_data["password1"]
389 #user.set_password(self.cleaned_data["password1"])
Siobhan Tully53437282013-04-26 19:30:27 -0400390 if commit:
391 user.save()
392 return user
393
394
395class UserChangeForm(forms.ModelForm):
396 """A form for updating users. Includes all the fields on
397 the user, but replaces the password field with admin's
398 password hash display field.
399 """
400 password = ReadOnlyPasswordHashField()
401
402 class Meta:
Siobhan Tully30fd4292013-05-10 08:59:56 -0400403 model = User
Siobhan Tully53437282013-04-26 19:30:27 -0400404
405 def clean_password(self):
406 # Regardless of what the user provides, return the initial value.
407 # This is done here, rather than on the field, because the
408 # field does not have access to the initial value
409 return self.initial["password"]
410
411
Siobhan Tully30fd4292013-05-10 08:59:56 -0400412class UserAdmin(UserAdmin, OSModelAdmin):
Siobhan Tully53437282013-04-26 19:30:27 -0400413 class Meta:
414 app_label = "core"
415
416 # The forms to add and change user instances
417 form = UserChangeForm
418 add_form = UserCreationForm
419
420 # The fields to be used in displaying the User model.
421 # These override the definitions on the base UserAdmin
422 # that reference specific fields on auth.User.
Tony Mack416c0f22013-05-09 16:59:09 -0400423 list_display = ('email', 'site', 'firstname', 'lastname', 'is_admin', 'last_login')
Siobhan Tully53437282013-04-26 19:30:27 -0400424 list_filter = ('site',)
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400425 inlines = [SitePrivilegeInline, SliceMembershipInline]
Siobhan Tully53437282013-04-26 19:30:27 -0400426 fieldsets = (
Tony Mack89f70f12013-05-10 20:20:03 -0400427 (None, {'fields': ('email', 'password', 'site', 'is_admin')}),
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400428 ('Personal info', {'fields': ('firstname','lastname','phone', 'key')}),
Siobhan Tully53437282013-04-26 19:30:27 -0400429 #('Important dates', {'fields': ('last_login',)}),
430 )
431 add_fieldsets = (
432 (None, {
433 'classes': ('wide',),
Tony Mack89f70f12013-05-10 20:20:03 -0400434 'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'key','password1', 'password2', 'is_admin')}
Siobhan Tully53437282013-04-26 19:30:27 -0400435 ),
436 )
437 search_fields = ('email',)
438 ordering = ('email',)
439 filter_horizontal = ()
440
Scott Baker3de3e372013-05-10 16:50:44 -0700441class ServiceResourceInline(admin.TabularInline):
442 model = ServiceResource
443 extra = 0
444
445class ServiceClassAdmin(admin.ModelAdmin):
446 list_display = ('name', 'commitment', 'membershipFee')
447 inlines = [ServiceResourceInline]
448
Scott Baker133c9212013-05-17 09:09:11 -0700449class ReservedResourceInline(admin.TabularInline):
450 model = ReservedResource
451 extra = 0
452
453 def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
454 field = super(ReservedResourceInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
455
456 if db_field.name == 'resource':
457 # restrict resources to those that the slice's service class allows
458 if request._slice is not None:
459 field.queryset = field.queryset.filter(serviceClass = request._slice.serviceClass, calendarReservable=True)
460 if len(field.queryset) > 0:
461 field.initial = field.queryset.all()[0]
462 else:
463 field.queryset = field.queryset.none()
464 elif db_field.name == 'sliver':
465 # restrict slivers to those that belong to the slice
466 if request._slice is not None:
467 field.queryset = field.queryset.filter(slice = request._slice)
468 else:
469 field.queryset = field.queryset.none()
470
471 return field
472
473class ReservationChangeForm(forms.ModelForm):
474 class Meta:
475 model = Reservation
476
477class ReservationAddForm(forms.ModelForm):
478 slice = forms.ModelChoiceField(queryset=Slice.objects.all(), widget=forms.Select(attrs={"onChange":"document.getElementById('id_refresh').value=1; submit()"}))
479 refresh = forms.CharField(widget=forms.HiddenInput())
480
481 class Media:
482 css = {'all': ('planetstack.css',)} # .field-refresh { display: none; }
483
484 def clean_slice(self):
485 slice = self.cleaned_data.get("slice")
486 x = ServiceResource.objects.filter(serviceClass = slice.serviceClass, calendarReservable=True)
487 if len(x) == 0:
488 raise forms.ValidationError("The slice you selected does not have a service class that allows reservations")
489 return slice
490
491 class Meta:
492 model = Reservation
493
494class ReservationAddRefreshForm(ReservationAddForm):
495 """ This form is displayed when the Reservation Form receives an update
496 from the Slice dropdown onChange handler. It doesn't validate the
497 data and doesn't save the data. This will cause the form to be
498 redrawn.
499 """
500
501 """ don't validate anything """
502 def full_clean(self):
503 result = super(ReservationAddForm, self).full_clean()
504 self._errors = forms.util.ErrorDict()
505 return result
506
507 """ don't save anything """
508 def is_valid(self):
509 return False
510
511class ReservationAdmin(admin.ModelAdmin):
512 list_display = ('startTime', 'duration')
513 inlines = [ReservedResourceInline]
514 form = ReservationAddForm
515
516 def add_view(self, request, form_url='', extra_context=None):
517 request._refresh = False
518 request._slice = None
519 if request.method == 'POST':
520 if request.POST.get("refresh","1") == "1":
521 request._refresh = True
522 request.POST["refresh"] = "0"
523 request._slice = request.POST.get("slice",None)
524 if (request._slice is not None):
525 request._slice = Slice.objects.get(id=request._slice)
526
527 result = super(ReservationAdmin, self).add_view(request, form_url, extra_context)
528 return result
529
530 def get_form(self, request, obj=None, **kwargs):
531 request._obj_ = obj
532 if obj is not None:
533 request._slice = obj.slice
534 self.form = ReservationChangeForm
535 else:
536 if getattr(request, "_refresh", False):
537 self.form = ReservationAddRefreshForm
538 else:
539 self.form = ReservationAddForm
540 return super(ReservationAdmin, self).get_form(request, obj, **kwargs)
541
542 def get_readonly_fields(self, request, obj=None):
543 if (obj is not None):
544 # Prevent slice from being changed after the reservation has been
545 # created.
546 return ['slice']
547 else:
548 return []
Scott Baker3de3e372013-05-10 16:50:44 -0700549
Tony Mack31c2b8f2013-04-26 20:01:42 -0400550# register a signal that caches the user's credentials when they log in
551def cache_credentials(sender, user, request, **kwds):
552 auth = {'username': request.POST['username'],
553 'password': request.POST['password']}
554 request.session['auth'] = auth
555user_logged_in.connect(cache_credentials)
556
Siobhan Tully53437282013-04-26 19:30:27 -0400557# Now register the new UserAdmin...
Siobhan Tully30fd4292013-05-10 08:59:56 -0400558admin.site.register(User, UserAdmin)
Siobhan Tully53437282013-04-26 19:30:27 -0400559# ... and, since we're not using Django's builtin permissions,
560# unregister the Group model from admin.
561admin.site.unregister(Group)
562
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400563admin.site.register(Site, SiteAdmin)
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400564admin.site.register(SitePrivilege, SitePrivilegeAdmin)
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400565admin.site.register(Slice, SliceAdmin)
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400566admin.site.register(SliceMembership, SliceMembershipAdmin)
567#admin.site.register(Subnet)
Siobhan Tully73291342013-05-10 10:50:08 -0400568admin.site.register(Image, ImageAdmin)
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400569admin.site.register(Node, NodeAdmin)
Tony Mackcdec0902013-04-15 00:38:49 -0400570admin.site.register(Sliver, SliverAdmin)
Tony Mack759b57a2013-04-14 21:03:31 -0400571admin.site.register(Key, KeyAdmin)
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400572admin.site.register(Role, RoleAdmin)
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400573admin.site.register(DeploymentNetwork, DeploymentNetworkAdmin)
Scott Baker3de3e372013-05-10 16:50:44 -0700574admin.site.register(ServiceClass, ServiceClassAdmin)
Scott Baker133c9212013-05-17 09:09:11 -0700575admin.site.register(Reservation, ReservationAdmin)
Tony Mack7130ac32013-03-22 21:58:00 -0400576