blob: 713dfdda4180c925966eb2263061da5ed68b0bff [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
Scott Bakeracd45142013-05-19 16:19:16 -070012from django.contrib.auth.signals import user_logged_in
13from django.utils import timezone
Siobhan Tullyde5450d2013-06-21 11:35:33 -040014from django.contrib.contenttypes import generic
Siobhan Tullybfd11dc2013-09-03 12:59:24 -040015from suit.widgets import LinkedSelect
Tony Mack7130ac32013-03-22 21:58:00 -040016
Siobhan Tullyde5450d2013-06-21 11:35:33 -040017import django_evolution
Siobhan Tully4bc09f22013-04-10 21:15:21 -040018
Siobhan Tullyce652d02013-10-08 21:52:35 -040019class SingletonAdmin (admin.ModelAdmin):
20 def has_add_permission(self, request):
21 num_objects = self.model.objects.count()
22 if num_objects >= 1:
23 return False
24 else:
25 return True
26
27
Siobhan Tullyd3515752013-06-21 16:34:53 -040028class PlStackTabularInline(admin.TabularInline):
Siobhan Tully2c780ad2013-09-06 11:22:40 -040029 pass
Siobhan Tullyd3515752013-06-21 16:34:53 -040030
Siobhan Tullybfd11dc2013-09-03 12:59:24 -040031class ReservationInline(PlStackTabularInline):
32 model = Reservation
33 extra = 0
34 suit_classes = 'suit-tab suit-tab-reservations'
35
36
Siobhan Tullyd3515752013-06-21 16:34:53 -040037class ReadonlyTabularInline(PlStackTabularInline):
Siobhan Tully4bc09f22013-04-10 21:15:21 -040038 can_delete = False
39 extra = 0
40 editable_fields = []
41
42 def get_readonly_fields(self, request, obj=None):
43 fields = []
44 for field in self.model._meta.get_all_field_names():
45 if (not field == 'id'):
46 if (field not in self.editable_fields):
47 fields.append(field)
48 return fields
49
50 def has_add_permission(self, request):
51 return False
52
Siobhan Tullyde5450d2013-06-21 11:35:33 -040053class TagInline(generic.GenericTabularInline):
54 model = Tag
Siobhan Tullybfd11dc2013-09-03 12:59:24 -040055 extra = 0
56 suit_classes = 'suit-tab suit-tab-tags'
Siobhan Tullyde5450d2013-06-21 11:35:33 -040057
Scott Baker74d8e622013-07-29 16:04:22 -070058class NetworkLookerUpper:
Siobhan Tully2c780ad2013-09-06 11:22:40 -040059 """ This is a callable that looks up a network name in a sliver and returns
60 the ip address for that network.
61 """
62
63 def __init__(self, name):
64 self.short_description = name
65 self.__name__ = name
66 self.network_name = name
67
68 def __call__(self, obj):
69 if obj is not None:
70 for nbs in obj.networksliver_set.all():
71 if (nbs.network.name == self.network_name):
72 return nbs.ip
Scott Baker74d8e622013-07-29 16:04:22 -070073 return ""
74
75 def __str__(self):
76 return self.network_name
77
Siobhan Tullyd3515752013-06-21 16:34:53 -040078class SliverInline(PlStackTabularInline):
Siobhan Tully4bc09f22013-04-10 21:15:21 -040079 model = Sliver
Tony Mackb0d97422013-06-10 09:57:45 -040080 fields = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
Siobhan Tully4bc09f22013-04-10 21:15:21 -040081 extra = 0
Tony Mack3777b012013-05-07 21:38:06 -040082 readonly_fields = ['ip', 'instance_name']
Siobhan Tullybfd11dc2013-09-03 12:59:24 -040083 suit_classes = 'suit-tab suit-tab-slivers'
Scott Baker74d8e622013-07-29 16:04:22 -070084
Siobhan Tully2d95e482013-09-06 10:56:06 -040085# Note this is breaking in the admin.py when trying to use an inline to add a node/image
86# def _declared_fieldsets(self):
87# # Return None so django will call get_fieldsets and we can insert our
88# # dynamic fields
89# return None
90#
91# def get_readonly_fields(self, request, obj=None):
92# readonly_fields = super(SliverInline, self).get_readonly_fields(request, obj)
93#
94# # Lookup the networks that are bound to the slivers, and add those
95# # network names to the list of readonly fields.
96#
97# for sliver in obj.slivers.all():
98# for nbs in sliver.networksliver_set.all():
99# if nbs.ip:
100# network_name = nbs.network.name
101# if network_name not in [str(x) for x in readonly_fields]:
102# readonly_fields.append(NetworkLookerUpper(network_name))
103#
104# return readonly_fields
105#
106# def get_fieldsets(self, request, obj=None):
107# form = self.get_formset(request, obj).form
108# # fields = the read/write files + the read-only fields
109# fields = self.fields
110# for fieldName in self.get_readonly_fields(request,obj):
111# if not fieldName in fields:
112# fields.append(fieldName)
113#
114# return [(None, {'fields': fields})]
Scott Baker74d8e622013-07-29 16:04:22 -0700115
Tony Mackc2835a92013-05-28 09:18:49 -0400116
Siobhan Tully567e3e62013-06-21 18:03:16 -0400117
Siobhan Tullyd3515752013-06-21 16:34:53 -0400118class SiteInline(PlStackTabularInline):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400119 model = Site
120 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400121 suit_classes = 'suit-tab suit-tab-sites'
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400122
Siobhan Tullyd3515752013-06-21 16:34:53 -0400123class UserInline(PlStackTabularInline):
Siobhan Tully30fd4292013-05-10 08:59:56 -0400124 model = User
Siobhan Tully47ae1b52013-05-10 15:53:14 -0400125 fields = ['email', 'firstname', 'lastname']
Siobhan Tully30fd4292013-05-10 08:59:56 -0400126 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400127 suit_classes = 'suit-tab suit-tab-users'
Siobhan Tully30fd4292013-05-10 08:59:56 -0400128
Siobhan Tullyd3515752013-06-21 16:34:53 -0400129class SliceInline(PlStackTabularInline):
Tony Mack00d361f2013-04-28 10:28:42 -0400130 model = Slice
Siobhan Tullyce652d02013-10-08 21:52:35 -0400131 fields = ['name','site', 'serviceClass', 'service']
Tony Mack00d361f2013-04-28 10:28:42 -0400132 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400133 suit_classes = 'suit-tab suit-tab-slices'
134
Tony Mack00d361f2013-04-28 10:28:42 -0400135
Siobhan Tullyd3515752013-06-21 16:34:53 -0400136class RoleInline(PlStackTabularInline):
Tony Mack00d361f2013-04-28 10:28:42 -0400137 model = Role
138 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400139 suit_classes = 'suit-tab suit-tab-roles'
Tony Mack00d361f2013-04-28 10:28:42 -0400140
Siobhan Tullyd3515752013-06-21 16:34:53 -0400141class NodeInline(PlStackTabularInline):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400142 model = Node
143 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400144 suit_classes = 'suit-tab suit-tab-nodes'
145
146class SlicePrivilegeInline(PlStackTabularInline):
147 model = SlicePrivilege
148 extra = 0
149 suit_classes = 'suit-tab suit-tab-sliceprivileges'
150
151class DeploymentPrivilegeInline(PlStackTabularInline):
152 model = DeploymentPrivilege
153 extra = 0
154 suit_classes = 'suit-tab suit-tab-deploymentprivileges'
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400155
Siobhan Tullyd3515752013-06-21 16:34:53 -0400156class SitePrivilegeInline(PlStackTabularInline):
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400157 model = SitePrivilege
158 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400159 suit_classes = 'suit-tab suit-tab-siteprivileges'
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400160
Tony Mackc2835a92013-05-28 09:18:49 -0400161 def formfield_for_foreignkey(self, db_field, request, **kwargs):
162 if db_field.name == 'site':
163 if not request.user.is_admin:
164 # only show sites where user is an admin or pi
165 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
166 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
167 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
168 sites = Site.objects.filter(login_base__in=login_bases)
169 kwargs['queryset'] = sites
170
171 if db_field.name == 'user':
172 if not request.user.is_admin:
173 # only show users from sites where caller has admin or pi role
174 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
175 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
176 sites = [site_privilege.site for site_privilege in site_privileges]
177 site_privileges = SitePrivilege.objects.filter(site__in=sites)
178 emails = [site_privilege.user.email for site_privilege in site_privileges]
179 users = User.objects.filter(email__in=emails)
180 kwargs['queryset'] = users
181 return super(SitePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
182
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400183class SitePrivilegeInline(PlStackTabularInline):
184 model = SitePrivilege
185 suit_classes = 'suit-tab suit-tab-siteprivileges'
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400186 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400187 fields = ('user', 'site','role')
188
189class SlicePrivilegeInline(PlStackTabularInline):
190 model = SlicePrivilege
191 suit_classes = 'suit-tab suit-tab-sliceprivileges'
192 extra = 0
193 fields = ('user', 'slice','role')
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400194
Tony Mackc2835a92013-05-28 09:18:49 -0400195 def formfield_for_foreignkey(self, db_field, request, **kwargs):
196 if db_field.name == 'slice':
197 if not request.user.is_admin:
198 # only show slices at 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 slices = Slice.objects.filter(site__in=sites)
203 kwargs['queryset'] = slices
204 if db_field.name == 'user':
205 if not request.user.is_admin:
206 # only show users from sites where caller has admin or pi role
207 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
208 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
209 sites = [site_privilege.site for site_privilege in site_privileges]
210 site_privileges = SitePrivilege.objects.filter(site__in=sites)
211 emails = [site_privilege.user.email for site_privilege in site_privileges]
212 users = User.objects.filter(email__in=emails)
213 kwargs['queryset'] = list(users)
214
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400215 return super(SlicePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
Tony Mackc2835a92013-05-28 09:18:49 -0400216
Scott Bakera0015eb2013-08-14 17:28:14 -0700217class SliceNetworkInline(PlStackTabularInline):
Scott Baker74d8e622013-07-29 16:04:22 -0700218 model = Network.slices.through
219 extra = 0
220 verbose_name = "Network Connection"
221 verbose_name_plural = "Network Connections"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400222 suit_classes = 'suit-tab suit-tab-slicenetworks'
Scott Baker74d8e622013-07-29 16:04:22 -0700223
Siobhan Tullyd3515752013-06-21 16:34:53 -0400224class SliceTagInline(PlStackTabularInline):
Scott Baker307e06f2013-05-21 17:25:56 -0700225 model = SliceTag
226 extra = 0
227
Tony Mack5e71a662013-05-03 23:30:41 -0400228class PlainTextWidget(forms.HiddenInput):
229 input_type = 'hidden'
230
231 def render(self, name, value, attrs=None):
232 if value is None:
233 value = ''
Tony Mack1d6b85f2013-05-07 18:49:14 -0400234 return mark_safe(str(value) + super(PlainTextWidget, self).render(name, value, attrs))
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400235
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400236class PlanetStackBaseAdmin(admin.ModelAdmin):
237 save_on_top = False
238
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400239class SliceRoleAdmin(PlanetStackBaseAdmin):
240 model = SliceRole
241 pass
242
243class SiteRoleAdmin(PlanetStackBaseAdmin):
244 model = SiteRole
245 pass
246
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400247class DeploymentAdminForm(forms.ModelForm):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400248 sites = forms.ModelMultipleChoiceField(
249 queryset=Site.objects.all(),
250 required=False,
251 widget=FilteredSelectMultiple(
252 verbose_name=('Sites'), is_stacked=False
253 )
254 )
255 class Meta:
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400256 model = Deployment
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400257
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400258
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400259class DeploymentAdmin(PlanetStackBaseAdmin):
260 form = DeploymentAdminForm
Siobhan Tully2d95e482013-09-06 10:56:06 -0400261 inlines = [DeploymentPrivilegeInline,NodeInline,TagInline]
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400262 fieldsets = [
263 (None, {'fields': ['sites'], 'classes':['suit-tab suit-tab-sites']}),]
Siobhan Tully2d95e482013-09-06 10:56:06 -0400264 suit_form_tabs =(('sites', 'Sites'),('nodes','Nodes'),('deploymentprivileges','Privileges'),('tags','Tags'))
Tony Mack5cd13202013-05-01 21:48:38 -0400265
Siobhan Tullyce652d02013-10-08 21:52:35 -0400266class ServiceAttrAsTabInline(PlStackTabularInline):
267 model = ServiceAttribute
268 fields = ['name','value']
269 extra = 0
270 suit_classes = 'suit-tab suit-tab-serviceattrs'
271
272class ServiceAttributeInline(PlStackTabularInline):
273 model = ServiceAttribute
274 fields = ['name','value']
275 extra = 0
276
277class ServiceAdmin(PlanetStackBaseAdmin):
278 list_display = ("name","enabled")
279 fieldsets = [(None, {'fields': ['name','enabled','description']})]
280 inlines = [ServiceAttributeInline,]
281
Tony Mack0553f282013-06-10 22:54:50 -0400282class SiteAdmin(PlanetStackBaseAdmin):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400283 fieldsets = [
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400284 (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base', 'location'], 'classes':['suit-tab suit-tab-general']}),
285 ('Deployment Networks', {'fields': ['deployments'], 'classes':['suit-tab suit-tab-deployments']}),
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400286 ]
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400287 suit_form_tabs =(('general', 'Site Details'),
288 ('users','Users'),
Siobhan Tully2d95e482013-09-06 10:56:06 -0400289 ('siteprivileges','Privileges'),
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400290 ('deployments','Deployments'),
291 ('slices','Slices'),
292 ('nodes','Nodes'),
293 ('tags','Tags'),
294 )
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400295 list_display = ('name', 'login_base','site_url', 'enabled')
296 filter_horizontal = ('deployments',)
Siobhan Tully2d95e482013-09-06 10:56:06 -0400297 inlines = [SliceInline,UserInline,TagInline, NodeInline, SitePrivilegeInline]
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400298 search_fields = ['name']
299
Tony Mack04062832013-05-10 08:22:44 -0400300 def queryset(self, request):
301 # admins can see all keys. Users can only see sites they belong to.
302 qs = super(SiteAdmin, self).queryset(request)
303 if not request.user.is_admin:
304 valid_sites = [request.user.site.login_base]
305 roles = request.user.get_roles()
306 for tenant_list in roles.values():
307 valid_sites.extend(tenant_list)
308 qs = qs.filter(login_base__in=valid_sites)
309 return qs
310
Tony Mack5cd13202013-05-01 21:48:38 -0400311 def get_formsets(self, request, obj=None):
312 for inline in self.get_inline_instances(request, obj):
313 # hide MyInline in the add view
314 if obj is None:
315 continue
Tony Mack2bd5b412013-06-11 21:05:06 -0400316 if isinstance(inline, SliceInline):
317 inline.model.caller = request.user
318 yield inline.get_formset(request, obj)
319
320 def get_formsets(self, request, obj=None):
321 for inline in self.get_inline_instances(request, obj):
322 # hide MyInline in the add view
323 if obj is None:
324 continue
325 if isinstance(inline, SliverInline):
326 inline.model.caller = request.user
Tony Mack5cd13202013-05-01 21:48:38 -0400327 yield inline.get_formset(request, obj)
328
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400329class SitePrivilegeAdmin(PlanetStackBaseAdmin):
Tony Mack00d361f2013-04-28 10:28:42 -0400330 fieldsets = [
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400331 (None, {'fields': ['user', 'site', 'role'], 'classes':['collapse']})
Tony Mack00d361f2013-04-28 10:28:42 -0400332 ]
333 list_display = ('user', 'site', 'role')
334
Tony Mackc2835a92013-05-28 09:18:49 -0400335 def formfield_for_foreignkey(self, db_field, request, **kwargs):
336 if db_field.name == 'site':
337 if not request.user.is_admin:
338 # only show sites where user is an admin or pi
339 sites = set()
340 for site_privilege in SitePrivilege.objects.filer(user=request.user):
341 if site_privilege.role.role_type in ['admin', 'pi']:
342 sites.add(site_privilege.site)
343 kwargs['queryset'] = Site.objects.filter(site__in=list(sites))
344
345 if db_field.name == 'user':
346 if not request.user.is_admin:
347 # only show users from sites where caller has admin or pi role
348 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
349 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
350 sites = [site_privilege.site for site_privilege in site_privileges]
351 site_privileges = SitePrivilege.objects.filter(site__in=sites)
352 emails = [site_privilege.user.email for site_privilege in site_privileges]
353 users = User.objects.filter(email__in=emails)
354 kwargs['queryset'] = users
355
356 return super(SitePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
357
Tony Mack04062832013-05-10 08:22:44 -0400358 def queryset(self, request):
359 # admins can see all privileges. Users can only see privileges at sites
Tony Mackc2835a92013-05-28 09:18:49 -0400360 # where they have the admin role or pi role.
Tony Mack04062832013-05-10 08:22:44 -0400361 qs = super(SitePrivilegeAdmin, self).queryset(request)
362 if not request.user.is_admin:
Tony Mackc2835a92013-05-28 09:18:49 -0400363 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
364 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
365 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
366 sites = Site.objects.filter(login_base__in=login_bases)
367 qs = qs.filter(site__in=sites)
Tony Mack04062832013-05-10 08:22:44 -0400368 return qs
369
Siobhan Tullyce652d02013-10-08 21:52:35 -0400370class SliceForm(forms.ModelForm):
371 class Meta:
372 model = Slice
373 widgets = {
374 'service': LinkedSelect
375 }
376
Tony Mack2bd5b412013-06-11 21:05:06 -0400377class SliceAdmin(PlanetStackBaseAdmin):
Siobhan Tullyce652d02013-10-08 21:52:35 -0400378 form = SliceForm
379 fieldsets = [('Slice Details', {'fields': ['name', 'site', 'serviceClass', 'enabled','description', 'service', 'slice_url'], 'classes':['suit-tab suit-tab-general']}),]
Siobhan Tully30fd4292013-05-10 08:59:56 -0400380 list_display = ('name', 'site','serviceClass', 'slice_url')
Siobhan Tully2d95e482013-09-06 10:56:06 -0400381 inlines = [SlicePrivilegeInline,SliverInline, TagInline, ReservationInline,SliceNetworkInline]
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400382
383
Siobhan Tully2d95e482013-09-06 10:56:06 -0400384 #inlines = [SliverInline, SliceMembershipInline, TagInline, SliceTagInline, SliceNetworkInline]
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400385 suit_form_tabs =(('general', 'Slice Details'),
Siobhan Tully2d95e482013-09-06 10:56:06 -0400386 ('slicenetworks','Networks'),
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400387 ('sliceprivileges','Privileges'),
388 ('slivers','Slivers'),
389 ('tags','Tags'),
390 ('reservations','Reservations'),
391 )
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400392
Tony Mackc2835a92013-05-28 09:18:49 -0400393 def formfield_for_foreignkey(self, db_field, request, **kwargs):
394 if db_field.name == 'site':
395 if not request.user.is_admin:
396 # only show sites where user is a pi or admin
397 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
398 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
399 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
400 sites = Site.objects.filter(login_base__in=login_bases)
401 kwargs['queryset'] = sites
402
403 return super(SliceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
404
Tony Mack04062832013-05-10 08:22:44 -0400405 def queryset(self, request):
406 # admins can see all keys. Users can only see slices they belong to.
407 qs = super(SliceAdmin, self).queryset(request)
408 if not request.user.is_admin:
409 valid_slices = []
410 roles = request.user.get_roles()
411 for tenant_list in roles.values():
412 valid_slices.extend(tenant_list)
413 qs = qs.filter(name__in=valid_slices)
414 return qs
415
Tony Mack79748612013-05-01 14:52:03 -0400416 def get_formsets(self, request, obj=None):
417 for inline in self.get_inline_instances(request, obj):
418 # hide MyInline in the add view
419 if obj is None:
420 continue
Tony Mack2bd5b412013-06-11 21:05:06 -0400421 if isinstance(inline, SliverInline):
422 inline.model.caller = request.user
Tony Mack79748612013-05-01 14:52:03 -0400423 yield inline.get_formset(request, obj)
424
Tony Mackfdd4d802013-04-27 13:02:33 -0400425 def get_queryset(self, request):
426 qs = super(SliceAdmin, self).get_queryset(request)
427 if request.user.is_superuser:
428 return qs
429 # users can only see slices at their site
Tony Mack2bd5b412013-06-11 21:05:06 -0400430 return qs.filter(site=request.user.site)
431
432 def save_model(self, request, obj, form, change):
433 # update openstack connection to use this site/tenant
434 obj.caller = request.user
435 obj.save()
Tony Mackfdd4d802013-04-27 13:02:33 -0400436
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400437class SlicePrivilegeAdmin(PlanetStackBaseAdmin):
Tony Mack00d361f2013-04-28 10:28:42 -0400438 fieldsets = [
439 (None, {'fields': ['user', 'slice', 'role']})
440 ]
441 list_display = ('user', 'slice', 'role')
Tony Mack00d361f2013-04-28 10:28:42 -0400442
Tony Mackc2835a92013-05-28 09:18:49 -0400443 def formfield_for_foreignkey(self, db_field, request, **kwargs):
444 if db_field.name == 'slice':
445 if not request.user.is_admin:
446 # only show slices at sites where caller has admin or pi role
447 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
448 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
449 sites = [site_privilege.site for site_privilege in site_privileges]
450 slices = Slice.objects.filter(site__in=sites)
451 kwargs['queryset'] = slices
452
453 if db_field.name == 'user':
454 if not request.user.is_admin:
455 # only show users from sites where caller has admin or pi role
456 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
457 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
458 sites = [site_privilege.site for site_privilege in site_privileges]
459 site_privileges = SitePrivilege.objects.filter(site__in=sites)
460 emails = [site_privilege.user.email for site_privilege in site_privileges]
461 users = User.objects.filter(email__in=emails)
462 kwargs['queryset'] = users
463
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400464 return super(SlicePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
Tony Mackc2835a92013-05-28 09:18:49 -0400465
Tony Mack04062832013-05-10 08:22:44 -0400466 def queryset(self, request):
467 # admins can see all memberships. Users can only see memberships of
468 # slices where they have the admin role.
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400469 qs = super(SlicePrivilegeAdmin, self).queryset(request)
Tony Mack04062832013-05-10 08:22:44 -0400470 if not request.user.is_admin:
Tony Mackc2835a92013-05-28 09:18:49 -0400471 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
472 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
473 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
474 sites = Site.objects.filter(login_base__in=login_bases)
475 slices = Slice.objects.filter(site__in=sites)
476 qs = qs.filter(slice__in=slices)
Tony Mack04062832013-05-10 08:22:44 -0400477 return qs
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400478
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400479 def save_model(self, request, obj, form, change):
Tony Mack951dab42013-05-02 19:51:45 -0400480 # update openstack connection to use this site/tenant
481 auth = request.session.get('auth', {})
482 auth['tenant'] = obj.slice.name
483 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400484 obj.save()
485
486 def delete_model(self, request, obj):
Tony Mack951dab42013-05-02 19:51:45 -0400487 # update openstack connection to use this site/tenant
488 auth = request.session.get('auth', {})
489 auth['tenant'] = obj.slice.name
490 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400491 obj.delete()
492
Siobhan Tully567e3e62013-06-21 18:03:16 -0400493
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400494class ImageAdmin(PlanetStackBaseAdmin):
495
496 fieldsets = [('Image Details',
497 {'fields': ['image_id', 'name', 'disk_format', 'container_format'],
498 'classes': ['suit-tab suit-tab-general']})
499 ]
500
501 suit_form_tabs =(('general','Image Details'),('slivers','Slivers'))
502
503 inlines = [SliverInline]
504
505class NodeForm(forms.ModelForm):
506 class Meta:
507 widgets = {
508 'site': LinkedSelect,
509 'deployment': LinkedSelect
510 }
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400511
512class NodeAdmin(admin.ModelAdmin):
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400513 form = NodeForm
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400514 list_display = ('name', 'site', 'deployment')
515 list_filter = ('deployment',)
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400516 inlines = [TagInline,SliverInline]
517 fieldsets = [('Node Details', {'fields': ['name','site','deployment'], 'classes':['suit-tab suit-tab-details']})]
518
519 suit_form_tabs =(('details','Node Details'),('slivers','Slivers'),('tags','Tags'))
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400520
Siobhan Tully567e3e62013-06-21 18:03:16 -0400521
Tony Mackd90cdbf2013-04-16 22:48:40 -0400522class SliverForm(forms.ModelForm):
523 class Meta:
Tony Mack1d6b85f2013-05-07 18:49:14 -0400524 model = Sliver
Tony Mackd90cdbf2013-04-16 22:48:40 -0400525 ip = forms.CharField(widget=PlainTextWidget)
Tony Mack18261812013-05-02 16:39:20 -0400526 instance_name = forms.CharField(widget=PlainTextWidget)
Tony Mackd90cdbf2013-04-16 22:48:40 -0400527 widgets = {
528 'ip': PlainTextWidget(),
Tony Mack18261812013-05-02 16:39:20 -0400529 'instance_name': PlainTextWidget(),
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400530 'slice': LinkedSelect,
531 'deploymentNetwork': LinkedSelect,
532 'node': LinkedSelect,
533 'image': LinkedSelect
Siobhan Tully53437282013-04-26 19:30:27 -0400534 }
Tony Mackd90cdbf2013-04-16 22:48:40 -0400535
Siobhan Tullyd3515752013-06-21 16:34:53 -0400536class TagAdmin(admin.ModelAdmin):
Siobhan Tullyce652d02013-10-08 21:52:35 -0400537 list_display = ['service', 'name', 'value', 'content_type', 'content_object',]
Siobhan Tullyd3515752013-06-21 16:34:53 -0400538
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400539class SliverAdmin(PlanetStackBaseAdmin):
Tony Mackd90cdbf2013-04-16 22:48:40 -0400540 form = SliverForm
Tony Mackcdec0902013-04-15 00:38:49 -0400541 fieldsets = [
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400542 ('Sliver Details', {'fields': ['slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'numberCores', 'image', ], 'classes': ['suit-tab suit-tab-general'], })
Tony Mackcdec0902013-04-15 00:38:49 -0400543 ]
Siobhan Tully5d7dc8d2013-07-02 13:17:33 -0400544 list_display = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400545
546 suit_form_tabs =(('general', 'Sliver Details'),
547 ('tags','Tags'),
548 )
549
Siobhan Tullyde5450d2013-06-21 11:35:33 -0400550 inlines = [TagInline]
Tony Mack53106f32013-04-27 16:43:01 -0400551
Tony Mackc2835a92013-05-28 09:18:49 -0400552 def formfield_for_foreignkey(self, db_field, request, **kwargs):
553 if db_field.name == 'slice':
554 if not request.user.is_admin:
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400555 slices = set([sm.slice.name for sm in SlicePrivilege.objects.filter(user=request.user)])
Tony Mackc2835a92013-05-28 09:18:49 -0400556 kwargs['queryset'] = Slice.objects.filter(name__in=list(slices))
557
558 return super(SliverAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
559
Tony Mack04062832013-05-10 08:22:44 -0400560 def queryset(self, request):
561 # admins can see all slivers. Users can only see slivers of
562 # the slices they belong to.
563 qs = super(SliverAdmin, self).queryset(request)
564 if not request.user.is_admin:
565 tenants = []
566 roles = request.user.get_roles()
567 for tenant_list in roles.values():
568 tenants.extend(tenant_list)
569 valid_slices = Slice.objects.filter(name__in=tenants)
570 qs = qs.filter(slice__in=valid_slices)
571 return qs
572
Tony Mack1d6b85f2013-05-07 18:49:14 -0400573 def get_formsets(self, request, obj=None):
574 # make some fields read only if we are updating an existing record
575 if obj == None:
576 #self.readonly_fields = ('ip', 'instance_name')
577 self.readonly_fields = ()
578 else:
Tony Mack1e889462013-05-10 21:34:54 -0400579 self.readonly_fields = ()
580 #self.readonly_fields = ('ip', 'instance_name', 'slice', 'image', 'key')
Tony Mack1d6b85f2013-05-07 18:49:14 -0400581
582 for inline in self.get_inline_instances(request, obj):
583 # hide MyInline in the add view
584 if obj is None:
585 continue
586 # give inline object access to driver and caller
587 auth = request.session.get('auth', {})
588 auth['tenant'] = obj.name # meed to connect using slice's tenant
589 inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
590 yield inline.get_formset(request, obj)
Tony Mack53106f32013-04-27 16:43:01 -0400591
592 def save_model(self, request, obj, form, change):
Tony Mack951dab42013-05-02 19:51:45 -0400593 # update openstack connection to use this site/tenant
594 auth = request.session.get('auth', {})
595 auth['tenant'] = obj.slice.name
596 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mackb0d97422013-06-10 09:57:45 -0400597 obj.creator = request.user
Tony Mack53106f32013-04-27 16:43:01 -0400598 obj.save()
599
600 def delete_model(self, request, obj):
Tony Mack951dab42013-05-02 19:51:45 -0400601 # update openstack connection to use this site/tenant
602 auth = request.session.get('auth', {})
603 auth['tenant'] = obj.slice.name
604 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack53106f32013-04-27 16:43:01 -0400605 obj.delete()
Tony Mackcdec0902013-04-15 00:38:49 -0400606
Siobhan Tully53437282013-04-26 19:30:27 -0400607class UserCreationForm(forms.ModelForm):
608 """A form for creating new users. Includes all the required
609 fields, plus a repeated password."""
610 password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
611 password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
612
613 class Meta:
Siobhan Tully30fd4292013-05-10 08:59:56 -0400614 model = User
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400615 fields = ('email', 'firstname', 'lastname', 'phone', 'public_key')
Siobhan Tully53437282013-04-26 19:30:27 -0400616
617 def clean_password2(self):
618 # Check that the two password entries match
619 password1 = self.cleaned_data.get("password1")
620 password2 = self.cleaned_data.get("password2")
621 if password1 and password2 and password1 != password2:
622 raise forms.ValidationError("Passwords don't match")
623 return password2
624
625 def save(self, commit=True):
626 # Save the provided password in hashed format
627 user = super(UserCreationForm, self).save(commit=False)
Tony Mackf9f4afb2013-05-01 21:02:12 -0400628 user.password = self.cleaned_data["password1"]
629 #user.set_password(self.cleaned_data["password1"])
Siobhan Tully53437282013-04-26 19:30:27 -0400630 if commit:
631 user.save()
632 return user
633
Siobhan Tully567e3e62013-06-21 18:03:16 -0400634
Siobhan Tully53437282013-04-26 19:30:27 -0400635class UserChangeForm(forms.ModelForm):
636 """A form for updating users. Includes all the fields on
637 the user, but replaces the password field with admin's
638 password hash display field.
639 """
640 password = ReadOnlyPasswordHashField()
641
642 class Meta:
Siobhan Tully30fd4292013-05-10 08:59:56 -0400643 model = User
Siobhan Tully53437282013-04-26 19:30:27 -0400644
645 def clean_password(self):
646 # Regardless of what the user provides, return the initial value.
647 # This is done here, rather than on the field, because the
648 # field does not have access to the initial value
649 return self.initial["password"]
650
Siobhan Tully567e3e62013-06-21 18:03:16 -0400651
Tony Mack2bd5b412013-06-11 21:05:06 -0400652class UserAdmin(UserAdmin):
Siobhan Tully53437282013-04-26 19:30:27 -0400653 class Meta:
654 app_label = "core"
655
656 # The forms to add and change user instances
657 form = UserChangeForm
658 add_form = UserCreationForm
659
660 # The fields to be used in displaying the User model.
661 # These override the definitions on the base UserAdmin
662 # that reference specific fields on auth.User.
Siobhan Tullyfece0d52013-09-06 12:57:05 -0400663 list_display = ('email', 'firstname', 'lastname', 'is_admin', 'last_login')
Siobhan Tullyce652d02013-10-08 21:52:35 -0400664 #list_display = ('email', 'username','firstname', 'lastname', 'is_admin', 'last_login')
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400665 list_filter = ()
666 inlines = [SlicePrivilegeInline,SitePrivilegeInline,DeploymentPrivilegeInline]
Siobhan Tully53437282013-04-26 19:30:27 -0400667 fieldsets = (
Siobhan Tullyfece0d52013-09-06 12:57:05 -0400668 ('Login Details', {'fields': ('email', 'site','password', 'is_admin', 'public_key'), 'classes':['suit-tab suit-tab-general']}),
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400669 ('Contact Information', {'fields': ('firstname','lastname','phone', 'timezone'), 'classes':['suit-tab suit-tab-contact']}),
Siobhan Tully53437282013-04-26 19:30:27 -0400670 #('Important dates', {'fields': ('last_login',)}),
671 )
672 add_fieldsets = (
673 (None, {
674 'classes': ('wide',),
Siobhan Tullyfece0d52013-09-06 12:57:05 -0400675 'fields': ('email', 'firstname', 'lastname', 'phone', 'public_key','password1', 'password2')}
Siobhan Tully53437282013-04-26 19:30:27 -0400676 ),
677 )
678 search_fields = ('email',)
679 ordering = ('email',)
680 filter_horizontal = ()
681
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400682 suit_form_tabs =(('general','Login Details'),('contact','Contact Information'),('sliceprivileges','Slice Privileges'),('siteprivileges','Site Privileges'),('deploymentprivileges','Deployment Privileges'))
683
Tony Mackc2835a92013-05-28 09:18:49 -0400684 def formfield_for_foreignkey(self, db_field, request, **kwargs):
685 if db_field.name == 'site':
686 if not request.user.is_admin:
687 # show sites where caller is an admin or pi
688 sites = []
689 for site_privilege in SitePrivilege.objects.filer(user=request.user):
690 if site_privilege.role.role_type in ['admin', 'pi']:
691 sites.append(site_privilege.site.login_base)
692 kwargs['queryset'] = Site.objects.filter(login_base__in(list(sites)))
693
694 return super(UserAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
695
Scott Baker3de3e372013-05-10 16:50:44 -0700696class ServiceResourceInline(admin.TabularInline):
697 model = ServiceResource
698 extra = 0
699
700class ServiceClassAdmin(admin.ModelAdmin):
701 list_display = ('name', 'commitment', 'membershipFee')
702 inlines = [ServiceResourceInline]
703
Scott Baker133c9212013-05-17 09:09:11 -0700704class ReservedResourceInline(admin.TabularInline):
705 model = ReservedResource
706 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400707 suit_classes = 'suit-tab suit-tab-reservedresources'
Scott Baker133c9212013-05-17 09:09:11 -0700708
709 def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
710 field = super(ReservedResourceInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
711
712 if db_field.name == 'resource':
713 # restrict resources to those that the slice's service class allows
714 if request._slice is not None:
715 field.queryset = field.queryset.filter(serviceClass = request._slice.serviceClass, calendarReservable=True)
716 if len(field.queryset) > 0:
717 field.initial = field.queryset.all()[0]
718 else:
719 field.queryset = field.queryset.none()
720 elif db_field.name == 'sliver':
721 # restrict slivers to those that belong to the slice
722 if request._slice is not None:
723 field.queryset = field.queryset.filter(slice = request._slice)
724 else:
725 field.queryset = field.queryset.none()
726
727 return field
728
729class ReservationChangeForm(forms.ModelForm):
730 class Meta:
731 model = Reservation
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400732 widgets = {
733 'slice' : LinkedSelect
734 }
Scott Baker133c9212013-05-17 09:09:11 -0700735
736class ReservationAddForm(forms.ModelForm):
737 slice = forms.ModelChoiceField(queryset=Slice.objects.all(), widget=forms.Select(attrs={"onChange":"document.getElementById('id_refresh').value=1; submit()"}))
738 refresh = forms.CharField(widget=forms.HiddenInput())
739
740 class Media:
741 css = {'all': ('planetstack.css',)} # .field-refresh { display: none; }
742
743 def clean_slice(self):
744 slice = self.cleaned_data.get("slice")
745 x = ServiceResource.objects.filter(serviceClass = slice.serviceClass, calendarReservable=True)
746 if len(x) == 0:
747 raise forms.ValidationError("The slice you selected does not have a service class that allows reservations")
748 return slice
749
750 class Meta:
751 model = Reservation
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400752 widgets = {
753 'slice' : LinkedSelect
754 }
755
Scott Baker133c9212013-05-17 09:09:11 -0700756
757class ReservationAddRefreshForm(ReservationAddForm):
758 """ This form is displayed when the Reservation Form receives an update
759 from the Slice dropdown onChange handler. It doesn't validate the
760 data and doesn't save the data. This will cause the form to be
761 redrawn.
762 """
763
Scott Baker8737e5f2013-05-17 09:35:32 -0700764 """ don't validate anything other than slice """
765 dont_validate_fields = ("startTime", "duration")
766
Scott Baker133c9212013-05-17 09:09:11 -0700767 def full_clean(self):
768 result = super(ReservationAddForm, self).full_clean()
Scott Baker8737e5f2013-05-17 09:35:32 -0700769
770 for fieldname in self.dont_validate_fields:
771 if fieldname in self._errors:
772 del self._errors[fieldname]
773
Scott Baker133c9212013-05-17 09:09:11 -0700774 return result
775
776 """ don't save anything """
777 def is_valid(self):
778 return False
779
780class ReservationAdmin(admin.ModelAdmin):
Siobhan Tullyce652d02013-10-08 21:52:35 -0400781 fieldsets = [('Reservation Details', {'fields': ['slice', 'startTime', 'duration'], 'classes': ['suit-tab suit-tab-general']})]
Scott Baker133c9212013-05-17 09:09:11 -0700782 list_display = ('startTime', 'duration')
Scott Baker133c9212013-05-17 09:09:11 -0700783 form = ReservationAddForm
784
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400785 suit_form_tabs = (('general','Reservation Details'), ('reservedresources','Reserved Resources'))
786
787 inlines = [ReservedResourceInline]
788
Scott Baker133c9212013-05-17 09:09:11 -0700789 def add_view(self, request, form_url='', extra_context=None):
Scott Bakeracd45142013-05-19 16:19:16 -0700790 timezone.activate(request.user.timezone)
Scott Baker133c9212013-05-17 09:09:11 -0700791 request._refresh = False
792 request._slice = None
793 if request.method == 'POST':
Scott Baker8737e5f2013-05-17 09:35:32 -0700794 # "refresh" will be set to "1" if the form was submitted due to
795 # a change in the Slice dropdown.
Scott Baker133c9212013-05-17 09:09:11 -0700796 if request.POST.get("refresh","1") == "1":
797 request._refresh = True
798 request.POST["refresh"] = "0"
Scott Baker8737e5f2013-05-17 09:35:32 -0700799
800 # Keep track of the slice that was selected, so the
801 # reservedResource inline can filter items for the slice.
Scott Baker133c9212013-05-17 09:09:11 -0700802 request._slice = request.POST.get("slice",None)
803 if (request._slice is not None):
804 request._slice = Slice.objects.get(id=request._slice)
805
806 result = super(ReservationAdmin, self).add_view(request, form_url, extra_context)
807 return result
808
Scott Bakeracd45142013-05-19 16:19:16 -0700809 def changelist_view(self, request, extra_context = None):
810 timezone.activate(request.user.timezone)
811 return super(ReservationAdmin, self).changelist_view(request, extra_context)
812
Scott Baker133c9212013-05-17 09:09:11 -0700813 def get_form(self, request, obj=None, **kwargs):
Siobhan Tullyd3515752013-06-21 16:34:53 -0400814 request._obj_ = obj
815 if obj is not None:
816 # For changes, set request._slice to the slice already set in the
817 # object.
818 request._slice = obj.slice
819 self.form = ReservationChangeForm
820 else:
821 if getattr(request, "_refresh", False):
822 self.form = ReservationAddRefreshForm
823 else:
824 self.form = ReservationAddForm
825 return super(ReservationAdmin, self).get_form(request, obj, **kwargs)
826
Scott Baker133c9212013-05-17 09:09:11 -0700827 def get_readonly_fields(self, request, obj=None):
Siobhan Tullyd3515752013-06-21 16:34:53 -0400828 if (obj is not None):
829 # Prevent slice from being changed after the reservation has been
830 # created.
831 return ['slice']
832 else:
Scott Baker133c9212013-05-17 09:09:11 -0700833 return []
Scott Baker3de3e372013-05-10 16:50:44 -0700834
Scott Baker74d8e622013-07-29 16:04:22 -0700835class NetworkParameterTypeAdmin(admin.ModelAdmin):
Scott Baker74d8e622013-07-29 16:04:22 -0700836 list_display = ("name", )
837
838class RouterAdmin(admin.ModelAdmin):
Scott Baker74d8e622013-07-29 16:04:22 -0700839 list_display = ("name", )
840
841class RouterInline(admin.TabularInline):
Scott Baker74d8e622013-07-29 16:04:22 -0700842 model = Router.networks.through
843 extra = 0
844 verbose_name_plural = "Routers"
845 verbose_name = "Router"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400846 suit_classes = 'suit-tab suit-tab-routers'
Scott Baker74d8e622013-07-29 16:04:22 -0700847
848class NetworkParameterInline(generic.GenericTabularInline):
Scott Baker74d8e622013-07-29 16:04:22 -0700849 model = NetworkParameter
850 extra = 1
851 verbose_name_plural = "Parameters"
852 verbose_name = "Parameter"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400853 suit_classes = 'suit-tab suit-tab-netparams'
Scott Baker74d8e622013-07-29 16:04:22 -0700854
855class NetworkSliversInline(admin.TabularInline):
Scott Baker74d8e622013-07-29 16:04:22 -0700856 readonly_fields = ("ip", )
857 model = NetworkSliver
858 extra = 0
859 verbose_name_plural = "Slivers"
860 verbose_name = "Sliver"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400861 suit_classes = 'suit-tab suit-tab-networkslivers'
Scott Baker74d8e622013-07-29 16:04:22 -0700862
Scott Bakerd7d2a392013-08-06 08:57:30 -0700863class NetworkSlicesInline(admin.TabularInline):
Scott Bakerd7d2a392013-08-06 08:57:30 -0700864 model = NetworkSlice
865 extra = 0
866 verbose_name_plural = "Slices"
867 verbose_name = "Slice"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400868 suit_classes = 'suit-tab suit-tab-networkslices'
Scott Bakerd7d2a392013-08-06 08:57:30 -0700869
Andy Bavierfe81aa42013-11-21 14:11:48 -0500870class NetworkForm(forms.ModelForm):
871 class Meta:
872 widgets = {
873 'deployment': LinkedSelect,
874 'site': LinkedSelect,
875 }
876
Scott Baker74d8e622013-07-29 16:04:22 -0700877class NetworkAdmin(admin.ModelAdmin):
Andy Bavierfe81aa42013-11-21 14:11:48 -0500878 form = NetworkForm
Scott Baker74d8e622013-07-29 16:04:22 -0700879 list_display = ("name", "subnet", "ports", "labels")
Andy Bavierfe81aa42013-11-21 14:11:48 -0500880 list_filter = ('deployment', )
Scott Baker74d8e622013-07-29 16:04:22 -0700881 readonly_fields = ("subnet", )
Siobhan Tully2d95e482013-09-06 10:56:06 -0400882
Scott Bakerd7d2a392013-08-06 08:57:30 -0700883 inlines = [NetworkParameterInline, NetworkSliversInline, NetworkSlicesInline, RouterInline]
Scott Baker74d8e622013-07-29 16:04:22 -0700884
Siobhan Tully2d95e482013-09-06 10:56:06 -0400885 fieldsets = [
Andy Bavierfe81aa42013-11-21 14:11:48 -0500886 (None, {'fields': ['name','template','ports','labels','owner','guaranteedBandwidth', 'permitAllSlices','permittedSlices','site','deployment','network_id','router_id','subnet_id','subnet'], 'classes':['suit-tab suit-tab-general']}),]
Siobhan Tully2d95e482013-09-06 10:56:06 -0400887
888 suit_form_tabs =(
889 ('general','Network Details'),
890 ('netparams', 'Parameters'),
891 ('networkslivers','Slivers'),
892 ('networkslices','Slices'),
893 ('routers','Routers'),
894 )
Scott Baker74d8e622013-07-29 16:04:22 -0700895class NetworkTemplateAdmin(admin.ModelAdmin):
Scott Baker74d8e622013-07-29 16:04:22 -0700896 list_display = ("name", "guaranteedBandwidth", "visibility")
897
Tony Mack31c2b8f2013-04-26 20:01:42 -0400898# register a signal that caches the user's credentials when they log in
899def cache_credentials(sender, user, request, **kwds):
900 auth = {'username': request.POST['username'],
901 'password': request.POST['password']}
902 request.session['auth'] = auth
903user_logged_in.connect(cache_credentials)
904
Siobhan Tullyce652d02013-10-08 21:52:35 -0400905
Siobhan Tully53437282013-04-26 19:30:27 -0400906# Now register the new UserAdmin...
Siobhan Tully30fd4292013-05-10 08:59:56 -0400907admin.site.register(User, UserAdmin)
Siobhan Tully53437282013-04-26 19:30:27 -0400908# ... and, since we're not using Django's builtin permissions,
909# unregister the Group model from admin.
Siobhan Tullyce652d02013-10-08 21:52:35 -0400910#admin.site.unregister(Group)
Siobhan Tully53437282013-04-26 19:30:27 -0400911
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400912#Do not show django evolution in the admin interface
913from django_evolution.models import Version, Evolution
914admin.site.unregister(Version)
915admin.site.unregister(Evolution)
916
917
918# When debugging it is often easier to see all the classes, but for regular use
919# only the top-levels should be displayed
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400920showAll = True
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400921
922admin.site.register(Deployment, DeploymentAdmin)
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400923admin.site.register(Site, SiteAdmin)
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400924admin.site.register(Slice, SliceAdmin)
smbaker43591c32013-06-26 12:43:53 -0700925admin.site.register(ServiceClass, ServiceClassAdmin)
Siobhan Tullyce652d02013-10-08 21:52:35 -0400926admin.site.register(Service, ServiceAdmin)
smbakera3cf70c2013-06-27 02:01:41 -0700927admin.site.register(Reservation, ReservationAdmin)
Scott Baker74d8e622013-07-29 16:04:22 -0700928admin.site.register(Network, NetworkAdmin)
929admin.site.register(Router, RouterAdmin)
930admin.site.register(NetworkParameterType, NetworkParameterTypeAdmin)
931admin.site.register(NetworkTemplate, NetworkTemplateAdmin)
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400932
933if showAll:
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400934 #admin.site.register(PlanetStack)
Siobhan Tullyd3515752013-06-21 16:34:53 -0400935 admin.site.register(Tag, TagAdmin)
Siobhan Tullyce652d02013-10-08 21:52:35 -0400936 admin.site.register(DeploymentRole)
937 admin.site.register(SiteRole)
938 admin.site.register(SliceRole)
939 admin.site.register(PlanetStackRole)
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400940 admin.site.register(Node, NodeAdmin)
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400941 #admin.site.register(SlicePrivilege, SlicePrivilegeAdmin)
942 #admin.site.register(SitePrivilege, SitePrivilegeAdmin)
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400943 admin.site.register(Sliver, SliverAdmin)
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400944 admin.site.register(Image, ImageAdmin)
Tony Mack7130ac32013-03-22 21:58:00 -0400945