blob: 90a9700e72d2d98f44a6b17473be2a8558602643 [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 Tullyd3515752013-06-21 16:34:53 -040019class PlStackTabularInline(admin.TabularInline):
20 exclude = ['enacted']
21
Siobhan Tullybfd11dc2013-09-03 12:59:24 -040022class ReservationInline(PlStackTabularInline):
23 model = Reservation
24 extra = 0
25 suit_classes = 'suit-tab suit-tab-reservations'
26
27
Siobhan Tullyd3515752013-06-21 16:34:53 -040028class ReadonlyTabularInline(PlStackTabularInline):
Siobhan Tully4bc09f22013-04-10 21:15:21 -040029 can_delete = False
30 extra = 0
31 editable_fields = []
32
33 def get_readonly_fields(self, request, obj=None):
34 fields = []
35 for field in self.model._meta.get_all_field_names():
36 if (not field == 'id'):
37 if (field not in self.editable_fields):
38 fields.append(field)
39 return fields
40
41 def has_add_permission(self, request):
42 return False
43
Siobhan Tullyde5450d2013-06-21 11:35:33 -040044class TagInline(generic.GenericTabularInline):
45 model = Tag
46 exclude = ['enacted']
Siobhan Tullybfd11dc2013-09-03 12:59:24 -040047 extra = 0
48 suit_classes = 'suit-tab suit-tab-tags'
Siobhan Tullyde5450d2013-06-21 11:35:33 -040049
Scott Baker74d8e622013-07-29 16:04:22 -070050class NetworkLookerUpper:
51 """ This is a callable that looks up a network name in a sliver and returns
52 the ip address for that network.
53 """
54
55 def __init__(self, name):
56 self.short_description = name
57 self.__name__ = name
58 self.network_name = name
59
60 def __call__(self, obj):
61 if obj is not None:
62 for nbs in obj.networksliver_set.all():
63 if (nbs.network.name == self.network_name):
64 return nbs.ip
65 return ""
66
67 def __str__(self):
68 return self.network_name
69
Siobhan Tullyd3515752013-06-21 16:34:53 -040070class SliverInline(PlStackTabularInline):
Siobhan Tully4bc09f22013-04-10 21:15:21 -040071 model = Sliver
Tony Mackb0d97422013-06-10 09:57:45 -040072 fields = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
Siobhan Tully4bc09f22013-04-10 21:15:21 -040073 extra = 0
Tony Mack3777b012013-05-07 21:38:06 -040074 readonly_fields = ['ip', 'instance_name']
Siobhan Tullybfd11dc2013-09-03 12:59:24 -040075 suit_classes = 'suit-tab suit-tab-slivers'
Scott Baker74d8e622013-07-29 16:04:22 -070076
Siobhan Tully2d95e482013-09-06 10:56:06 -040077# 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
80# # dynamic fields
81# return None
82#
83# def get_readonly_fields(self, request, obj=None):
84# readonly_fields = super(SliverInline, self).get_readonly_fields(request, obj)
85#
86# # Lookup the networks that are bound to the slivers, and add those
87# # network names to the list of readonly fields.
88#
89# for sliver in obj.slivers.all():
90# for nbs in sliver.networksliver_set.all():
91# if nbs.ip:
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))
95#
96# return readonly_fields
97#
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)
105#
106# return [(None, {'fields': fields})]
Scott Baker74d8e622013-07-29 16:04:22 -0700107
Tony Mackc2835a92013-05-28 09:18:49 -0400108
Siobhan Tully567e3e62013-06-21 18:03:16 -0400109
Siobhan Tullyd3515752013-06-21 16:34:53 -0400110class SiteInline(PlStackTabularInline):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400111 model = Site
112 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400113 suit_classes = 'suit-tab suit-tab-sites'
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400114
Siobhan Tullyd3515752013-06-21 16:34:53 -0400115class UserInline(PlStackTabularInline):
Siobhan Tully30fd4292013-05-10 08:59:56 -0400116 model = User
Siobhan Tully47ae1b52013-05-10 15:53:14 -0400117 fields = ['email', 'firstname', 'lastname']
Siobhan Tully30fd4292013-05-10 08:59:56 -0400118 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400119 suit_classes = 'suit-tab suit-tab-users'
Siobhan Tully30fd4292013-05-10 08:59:56 -0400120
Siobhan Tullyd3515752013-06-21 16:34:53 -0400121class SliceInline(PlStackTabularInline):
Tony Mack00d361f2013-04-28 10:28:42 -0400122 model = Slice
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400123 fields = ['name','enabled','description','slice_url']
Tony Mack00d361f2013-04-28 10:28:42 -0400124 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400125 suit_classes = 'suit-tab suit-tab-slices'
126
Tony Mack00d361f2013-04-28 10:28:42 -0400127
Siobhan Tullyd3515752013-06-21 16:34:53 -0400128class RoleInline(PlStackTabularInline):
Tony Mack00d361f2013-04-28 10:28:42 -0400129 model = Role
130 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400131 suit_classes = 'suit-tab suit-tab-roles'
Tony Mack00d361f2013-04-28 10:28:42 -0400132
Siobhan Tullyd3515752013-06-21 16:34:53 -0400133class NodeInline(PlStackTabularInline):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400134 model = Node
135 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400136 suit_classes = 'suit-tab suit-tab-nodes'
137
138class SlicePrivilegeInline(PlStackTabularInline):
139 model = SlicePrivilege
140 extra = 0
141 suit_classes = 'suit-tab suit-tab-sliceprivileges'
142
143class DeploymentPrivilegeInline(PlStackTabularInline):
144 model = DeploymentPrivilege
145 extra = 0
146 suit_classes = 'suit-tab suit-tab-deploymentprivileges'
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400147
Siobhan Tullyd3515752013-06-21 16:34:53 -0400148class SitePrivilegeInline(PlStackTabularInline):
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400149 model = SitePrivilege
150 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400151 suit_classes = 'suit-tab suit-tab-siteprivileges'
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400152
Tony Mackc2835a92013-05-28 09:18:49 -0400153 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
162
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)
174
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400175class SitePrivilegeInline(PlStackTabularInline):
176 model = SitePrivilege
177 suit_classes = 'suit-tab suit-tab-siteprivileges'
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400178 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400179 fields = ('user', 'site','role')
180
181class SlicePrivilegeInline(PlStackTabularInline):
182 model = SlicePrivilege
183 suit_classes = 'suit-tab suit-tab-sliceprivileges'
184 extra = 0
185 fields = ('user', 'slice','role')
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400186
Tony Mackc2835a92013-05-28 09:18:49 -0400187 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)
206
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400207 return super(SlicePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
Tony Mackc2835a92013-05-28 09:18:49 -0400208
Scott Bakera0015eb2013-08-14 17:28:14 -0700209class SliceNetworkInline(PlStackTabularInline):
Scott Baker74d8e622013-07-29 16:04:22 -0700210 model = Network.slices.through
211 extra = 0
212 verbose_name = "Network Connection"
213 verbose_name_plural = "Network Connections"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400214 suit_classes = 'suit-tab suit-tab-slicenetworks'
Scott Baker74d8e622013-07-29 16:04:22 -0700215
Siobhan Tullyd3515752013-06-21 16:34:53 -0400216class SliceTagInline(PlStackTabularInline):
Scott Baker307e06f2013-05-21 17:25:56 -0700217 model = SliceTag
218 extra = 0
219
Tony Mack5e71a662013-05-03 23:30:41 -0400220class PlainTextWidget(forms.HiddenInput):
221 input_type = 'hidden'
222
223 def render(self, name, value, attrs=None):
224 if value is None:
225 value = ''
Tony Mack1d6b85f2013-05-07 18:49:14 -0400226 return mark_safe(str(value) + super(PlainTextWidget, self).render(name, value, attrs))
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400227
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400228class PlanetStackBaseAdmin(admin.ModelAdmin):
229 save_on_top = False
Siobhan Tullyd3515752013-06-21 16:34:53 -0400230 exclude = ['enacted']
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400231
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400232class SliceRoleAdmin(PlanetStackBaseAdmin):
233 model = SliceRole
234 pass
235
236class SiteRoleAdmin(PlanetStackBaseAdmin):
237 model = SiteRole
238 pass
239
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400240class DeploymentAdminForm(forms.ModelForm):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400241 sites = forms.ModelMultipleChoiceField(
242 queryset=Site.objects.all(),
243 required=False,
244 widget=FilteredSelectMultiple(
245 verbose_name=('Sites'), is_stacked=False
246 )
247 )
248 class Meta:
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400249 model = Deployment
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400250
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400251
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400252class DeploymentAdmin(PlanetStackBaseAdmin):
253 form = DeploymentAdminForm
Siobhan Tully2d95e482013-09-06 10:56:06 -0400254 inlines = [DeploymentPrivilegeInline,NodeInline,TagInline]
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400255 fieldsets = [
256 (None, {'fields': ['sites'], 'classes':['suit-tab suit-tab-sites']}),]
Siobhan Tully2d95e482013-09-06 10:56:06 -0400257 suit_form_tabs =(('sites', 'Sites'),('nodes','Nodes'),('deploymentprivileges','Privileges'),('tags','Tags'))
Tony Mack5cd13202013-05-01 21:48:38 -0400258
Tony Mack0553f282013-06-10 22:54:50 -0400259class SiteAdmin(PlanetStackBaseAdmin):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400260 fieldsets = [
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400261 (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']}),
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400263 ]
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400264 suit_form_tabs =(('general', 'Site Details'),
265 ('users','Users'),
Siobhan Tully2d95e482013-09-06 10:56:06 -0400266 ('siteprivileges','Privileges'),
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400267 ('deployments','Deployments'),
268 ('slices','Slices'),
269 ('nodes','Nodes'),
270 ('tags','Tags'),
271 )
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400272 list_display = ('name', 'login_base','site_url', 'enabled')
273 filter_horizontal = ('deployments',)
Siobhan Tully2d95e482013-09-06 10:56:06 -0400274 inlines = [SliceInline,UserInline,TagInline, NodeInline, SitePrivilegeInline]
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400275 search_fields = ['name']
276
Tony Mack04062832013-05-10 08:22:44 -0400277 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)
286 return qs
287
Tony Mack5cd13202013-05-01 21:48:38 -0400288 def get_formsets(self, request, obj=None):
289 for inline in self.get_inline_instances(request, obj):
290 # hide MyInline in the add view
291 if obj is None:
292 continue
Tony Mack2bd5b412013-06-11 21:05:06 -0400293 if isinstance(inline, SliceInline):
294 inline.model.caller = request.user
295 yield inline.get_formset(request, obj)
296
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
300 if obj is None:
301 continue
302 if isinstance(inline, SliverInline):
303 inline.model.caller = request.user
Tony Mack5cd13202013-05-01 21:48:38 -0400304 yield inline.get_formset(request, obj)
305
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400306class SitePrivilegeAdmin(PlanetStackBaseAdmin):
Tony Mack00d361f2013-04-28 10:28:42 -0400307 fieldsets = [
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400308 (None, {'fields': ['user', 'site', 'role'], 'classes':['collapse']})
Tony Mack00d361f2013-04-28 10:28:42 -0400309 ]
310 list_display = ('user', 'site', 'role')
311
Tony Mackc2835a92013-05-28 09:18:49 -0400312 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
316 sites = set()
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))
321
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
332
333 return super(SitePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
334
Tony Mack04062832013-05-10 08:22:44 -0400335 def queryset(self, request):
336 # admins can see all privileges. Users can only see privileges at sites
Tony Mackc2835a92013-05-28 09:18:49 -0400337 # where they have the admin role or pi role.
Tony Mack04062832013-05-10 08:22:44 -0400338 qs = super(SitePrivilegeAdmin, self).queryset(request)
339 if not request.user.is_admin:
Tony Mackc2835a92013-05-28 09:18:49 -0400340 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)
Tony Mack04062832013-05-10 08:22:44 -0400345 return qs
346
Tony Mack2bd5b412013-06-11 21:05:06 -0400347class SliceAdmin(PlanetStackBaseAdmin):
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400348 fieldsets = [('Slice Details', {'fields': ['name', 'site', 'serviceClass', 'description', 'slice_url'], 'classes':['suit-tab suit-tab-general']}),]
Siobhan Tully30fd4292013-05-10 08:59:56 -0400349 list_display = ('name', 'site','serviceClass', 'slice_url')
Siobhan Tully2d95e482013-09-06 10:56:06 -0400350 inlines = [SlicePrivilegeInline,SliverInline, TagInline, ReservationInline,SliceNetworkInline]
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400351
352
Siobhan Tully2d95e482013-09-06 10:56:06 -0400353 #inlines = [SliverInline, SliceMembershipInline, TagInline, SliceTagInline, SliceNetworkInline]
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400354 suit_form_tabs =(('general', 'Slice Details'),
Siobhan Tully2d95e482013-09-06 10:56:06 -0400355 ('slicenetworks','Networks'),
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400356 ('sliceprivileges','Privileges'),
357 ('slivers','Slivers'),
358 ('tags','Tags'),
359 ('reservations','Reservations'),
360 )
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400361
Tony Mackc2835a92013-05-28 09:18:49 -0400362 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
371
372 return super(SliceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
373
Tony Mack04062832013-05-10 08:22:44 -0400374 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:
378 valid_slices = []
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)
383 return qs
384
Tony Mack79748612013-05-01 14:52:03 -0400385 def get_formsets(self, request, obj=None):
386 for inline in self.get_inline_instances(request, obj):
387 # hide MyInline in the add view
388 if obj is None:
389 continue
Tony Mack2bd5b412013-06-11 21:05:06 -0400390 if isinstance(inline, SliverInline):
391 inline.model.caller = request.user
Tony Mack79748612013-05-01 14:52:03 -0400392 yield inline.get_formset(request, obj)
393
Tony Mackfdd4d802013-04-27 13:02:33 -0400394 def get_queryset(self, request):
395 qs = super(SliceAdmin, self).get_queryset(request)
396 if request.user.is_superuser:
397 return qs
398 # users can only see slices at their site
Tony Mack2bd5b412013-06-11 21:05:06 -0400399 return qs.filter(site=request.user.site)
400
401 def save_model(self, request, obj, form, change):
402 # update openstack connection to use this site/tenant
403 obj.caller = request.user
404 obj.save()
Tony Mackfdd4d802013-04-27 13:02:33 -0400405
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400406class SlicePrivilegeAdmin(PlanetStackBaseAdmin):
Tony Mack00d361f2013-04-28 10:28:42 -0400407 fieldsets = [
408 (None, {'fields': ['user', 'slice', 'role']})
409 ]
410 list_display = ('user', 'slice', 'role')
Tony Mack00d361f2013-04-28 10:28:42 -0400411
Tony Mackc2835a92013-05-28 09:18:49 -0400412 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
421
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
432
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400433 return super(SlicePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
Tony Mackc2835a92013-05-28 09:18:49 -0400434
Tony Mack04062832013-05-10 08:22:44 -0400435 def queryset(self, request):
436 # admins can see all memberships. Users can only see memberships of
437 # slices where they have the admin role.
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400438 qs = super(SlicePrivilegeAdmin, self).queryset(request)
Tony Mack04062832013-05-10 08:22:44 -0400439 if not request.user.is_admin:
Tony Mackc2835a92013-05-28 09:18:49 -0400440 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)
Tony Mack04062832013-05-10 08:22:44 -0400446 return qs
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400447
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400448 def save_model(self, request, obj, form, change):
Tony Mack951dab42013-05-02 19:51:45 -0400449 # 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)
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400453 obj.save()
454
455 def delete_model(self, request, obj):
Tony Mack951dab42013-05-02 19:51:45 -0400456 # 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)
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400460 obj.delete()
461
Siobhan Tully567e3e62013-06-21 18:03:16 -0400462
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400463class ImageAdmin(PlanetStackBaseAdmin):
464
465 fieldsets = [('Image Details',
466 {'fields': ['image_id', 'name', 'disk_format', 'container_format'],
467 'classes': ['suit-tab suit-tab-general']})
468 ]
469
470 suit_form_tabs =(('general','Image Details'),('slivers','Slivers'))
471
472 inlines = [SliverInline]
473
474class NodeForm(forms.ModelForm):
475 class Meta:
476 widgets = {
477 'site': LinkedSelect,
478 'deployment': LinkedSelect
479 }
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400480
481class NodeAdmin(admin.ModelAdmin):
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400482 form = NodeForm
483 exclude = ['enacted']
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400484 list_display = ('name', 'site', 'deployment')
485 list_filter = ('deployment',)
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400486 inlines = [TagInline,SliverInline]
487 fieldsets = [('Node Details', {'fields': ['name','site','deployment'], 'classes':['suit-tab suit-tab-details']})]
488
489 suit_form_tabs =(('details','Node Details'),('slivers','Slivers'),('tags','Tags'))
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400490
Siobhan Tully567e3e62013-06-21 18:03:16 -0400491
Tony Mackd90cdbf2013-04-16 22:48:40 -0400492class SliverForm(forms.ModelForm):
493 class Meta:
Tony Mack1d6b85f2013-05-07 18:49:14 -0400494 model = Sliver
Tony Mackd90cdbf2013-04-16 22:48:40 -0400495 ip = forms.CharField(widget=PlainTextWidget)
Tony Mack18261812013-05-02 16:39:20 -0400496 instance_name = forms.CharField(widget=PlainTextWidget)
Tony Mackd90cdbf2013-04-16 22:48:40 -0400497 widgets = {
498 'ip': PlainTextWidget(),
Tony Mack18261812013-05-02 16:39:20 -0400499 'instance_name': PlainTextWidget(),
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400500 'slice': LinkedSelect,
501 'deploymentNetwork': LinkedSelect,
502 'node': LinkedSelect,
503 'image': LinkedSelect
Siobhan Tully53437282013-04-26 19:30:27 -0400504 }
Tony Mackd90cdbf2013-04-16 22:48:40 -0400505
Siobhan Tullyd3515752013-06-21 16:34:53 -0400506class ProjectAdmin(admin.ModelAdmin):
507 exclude = ['enacted']
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400508 inlines = [TagInline]
509
510class MemberAdmin(admin.ModelAdmin):
511 exclude = ['enacted']
512 list_display = ['role', 'rightContent_type', 'content_type', 'content_object',]
Siobhan Tullyd3515752013-06-21 16:34:53 -0400513
514class TagAdmin(admin.ModelAdmin):
515 exclude = ['enacted']
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400516 list_display = ['project', 'name', 'value', 'content_type', 'content_object',]
Siobhan Tullyd3515752013-06-21 16:34:53 -0400517
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400518class SliverAdmin(PlanetStackBaseAdmin):
Tony Mackd90cdbf2013-04-16 22:48:40 -0400519 form = SliverForm
Tony Mackcdec0902013-04-15 00:38:49 -0400520 fieldsets = [
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400521 ('Sliver Details', {'fields': ['slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'numberCores', 'image', ], 'classes': ['suit-tab suit-tab-general'], })
Tony Mackcdec0902013-04-15 00:38:49 -0400522 ]
Siobhan Tully5d7dc8d2013-07-02 13:17:33 -0400523 list_display = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400524
525 suit_form_tabs =(('general', 'Sliver Details'),
526 ('tags','Tags'),
527 )
528
Siobhan Tullyde5450d2013-06-21 11:35:33 -0400529 inlines = [TagInline]
Tony Mack53106f32013-04-27 16:43:01 -0400530
Tony Mackc2835a92013-05-28 09:18:49 -0400531 def formfield_for_foreignkey(self, db_field, request, **kwargs):
532 if db_field.name == 'slice':
533 if not request.user.is_admin:
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400534 slices = set([sm.slice.name for sm in SlicePrivilege.objects.filter(user=request.user)])
Tony Mackc2835a92013-05-28 09:18:49 -0400535 kwargs['queryset'] = Slice.objects.filter(name__in=list(slices))
536
537 return super(SliverAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
538
Tony Mack04062832013-05-10 08:22:44 -0400539 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:
544 tenants = []
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)
550 return qs
551
Tony Mack1d6b85f2013-05-07 18:49:14 -0400552 def get_formsets(self, request, obj=None):
553 # make some fields read only if we are updating an existing record
554 if obj == None:
555 #self.readonly_fields = ('ip', 'instance_name')
556 self.readonly_fields = ()
557 else:
Tony Mack1e889462013-05-10 21:34:54 -0400558 self.readonly_fields = ()
559 #self.readonly_fields = ('ip', 'instance_name', 'slice', 'image', 'key')
Tony Mack1d6b85f2013-05-07 18:49:14 -0400560
561 for inline in self.get_inline_instances(request, obj):
562 # hide MyInline in the add view
563 if obj is None:
564 continue
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)
Tony Mack53106f32013-04-27 16:43:01 -0400570
571 def save_model(self, request, obj, form, change):
Tony Mack951dab42013-05-02 19:51:45 -0400572 # 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)
Tony Mackb0d97422013-06-10 09:57:45 -0400576 obj.creator = request.user
Tony Mack53106f32013-04-27 16:43:01 -0400577 obj.save()
578
579 def delete_model(self, request, obj):
Tony Mack951dab42013-05-02 19:51:45 -0400580 # 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)
Tony Mack53106f32013-04-27 16:43:01 -0400584 obj.delete()
Tony Mackcdec0902013-04-15 00:38:49 -0400585
Siobhan Tully53437282013-04-26 19:30:27 -0400586class 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)
591
592 class Meta:
Siobhan Tully30fd4292013-05-10 08:59:56 -0400593 model = User
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400594 fields = ('email', 'firstname', 'lastname', 'phone', 'public_key')
Siobhan Tully53437282013-04-26 19:30:27 -0400595
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")
602 return password2
603
604 def save(self, commit=True):
605 # Save the provided password in hashed format
606 user = super(UserCreationForm, self).save(commit=False)
Tony Mackf9f4afb2013-05-01 21:02:12 -0400607 user.password = self.cleaned_data["password1"]
608 #user.set_password(self.cleaned_data["password1"])
Siobhan Tully53437282013-04-26 19:30:27 -0400609 if commit:
610 user.save()
611 return user
612
Siobhan Tully567e3e62013-06-21 18:03:16 -0400613
Siobhan Tully53437282013-04-26 19:30:27 -0400614class 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.
618 """
619 password = ReadOnlyPasswordHashField()
620
621 class Meta:
Siobhan Tully30fd4292013-05-10 08:59:56 -0400622 model = User
Siobhan Tully53437282013-04-26 19:30:27 -0400623
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"]
629
Siobhan Tully567e3e62013-06-21 18:03:16 -0400630
Tony Mack2bd5b412013-06-11 21:05:06 -0400631class UserAdmin(UserAdmin):
Siobhan Tully53437282013-04-26 19:30:27 -0400632 class Meta:
633 app_label = "core"
634
635 # The forms to add and change user instances
636 form = UserChangeForm
637 add_form = UserCreationForm
638
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.
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400642 list_display = ('email', 'username','firstname', 'lastname', 'is_admin', 'last_login')
643 list_filter = ()
644 inlines = [SlicePrivilegeInline,SitePrivilegeInline,DeploymentPrivilegeInline]
Siobhan Tully53437282013-04-26 19:30:27 -0400645 fieldsets = (
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400646 ('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']}),
Siobhan Tully53437282013-04-26 19:30:27 -0400648 #('Important dates', {'fields': ('last_login',)}),
649 )
650 add_fieldsets = (
651 (None, {
652 'classes': ('wide',),
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400653 'fields': ('email', 'username','firstname', 'lastname', 'phone', 'public_key','password1', 'password2')}
Siobhan Tully53437282013-04-26 19:30:27 -0400654 ),
655 )
656 search_fields = ('email',)
657 ordering = ('email',)
658 filter_horizontal = ()
659
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400660 suit_form_tabs =(('general','Login Details'),('contact','Contact Information'),('sliceprivileges','Slice Privileges'),('siteprivileges','Site Privileges'),('deploymentprivileges','Deployment Privileges'))
661
Tony Mackc2835a92013-05-28 09:18:49 -0400662 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
666 sites = []
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)))
671
672 return super(UserAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
673
Scott Baker3de3e372013-05-10 16:50:44 -0700674class ServiceResourceInline(admin.TabularInline):
smbaker4ff4f562013-06-30 23:48:25 -0700675 exclude = ['enacted']
Scott Baker3de3e372013-05-10 16:50:44 -0700676 model = ServiceResource
677 extra = 0
678
679class ServiceClassAdmin(admin.ModelAdmin):
smbaker4ff4f562013-06-30 23:48:25 -0700680 exclude = ['enacted']
Scott Baker3de3e372013-05-10 16:50:44 -0700681 list_display = ('name', 'commitment', 'membershipFee')
682 inlines = [ServiceResourceInline]
683
Scott Baker133c9212013-05-17 09:09:11 -0700684class ReservedResourceInline(admin.TabularInline):
smbakera3cf70c2013-06-27 02:01:41 -0700685 exclude = ['enacted']
Scott Baker133c9212013-05-17 09:09:11 -0700686 model = ReservedResource
687 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400688 suit_classes = 'suit-tab suit-tab-reservedresources'
Scott Baker133c9212013-05-17 09:09:11 -0700689
690 def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
691 field = super(ReservedResourceInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
692
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]
699 else:
700 field.queryset = field.queryset.none()
701 elif db_field.name == 'sliver':
702 # restrict slivers to those that belong to the slice
703 if request._slice is not None:
704 field.queryset = field.queryset.filter(slice = request._slice)
705 else:
706 field.queryset = field.queryset.none()
707
708 return field
709
710class ReservationChangeForm(forms.ModelForm):
711 class Meta:
712 model = Reservation
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400713 widgets = {
714 'slice' : LinkedSelect
715 }
Scott Baker133c9212013-05-17 09:09:11 -0700716
717class 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())
720
721 class Media:
722 css = {'all': ('planetstack.css',)} # .field-refresh { display: none; }
723
724 def clean_slice(self):
725 slice = self.cleaned_data.get("slice")
726 x = ServiceResource.objects.filter(serviceClass = slice.serviceClass, calendarReservable=True)
727 if len(x) == 0:
728 raise forms.ValidationError("The slice you selected does not have a service class that allows reservations")
729 return slice
730
731 class Meta:
732 model = Reservation
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400733 widgets = {
734 'slice' : LinkedSelect
735 }
736
Scott Baker133c9212013-05-17 09:09:11 -0700737
738class 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
742 redrawn.
743 """
744
Scott Baker8737e5f2013-05-17 09:35:32 -0700745 """ don't validate anything other than slice """
746 dont_validate_fields = ("startTime", "duration")
747
Scott Baker133c9212013-05-17 09:09:11 -0700748 def full_clean(self):
749 result = super(ReservationAddForm, self).full_clean()
Scott Baker8737e5f2013-05-17 09:35:32 -0700750
751 for fieldname in self.dont_validate_fields:
752 if fieldname in self._errors:
753 del self._errors[fieldname]
754
Scott Baker133c9212013-05-17 09:09:11 -0700755 return result
756
757 """ don't save anything """
758 def is_valid(self):
759 return False
760
761class ReservationAdmin(admin.ModelAdmin):
smbakera3cf70c2013-06-27 02:01:41 -0700762 exclude = ['enacted']
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400763 fieldsets = [('Reservation Details', {'fields': ['startTime', 'duration','slice'], 'classes': ['suit-tab suit-tab-general']})]
Scott Baker133c9212013-05-17 09:09:11 -0700764 list_display = ('startTime', 'duration')
Scott Baker133c9212013-05-17 09:09:11 -0700765 form = ReservationAddForm
766
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400767 suit_form_tabs = (('general','Reservation Details'), ('reservedresources','Reserved Resources'))
768
769 inlines = [ReservedResourceInline]
770
Scott Baker133c9212013-05-17 09:09:11 -0700771 def add_view(self, request, form_url='', extra_context=None):
Scott Bakeracd45142013-05-19 16:19:16 -0700772 timezone.activate(request.user.timezone)
Scott Baker133c9212013-05-17 09:09:11 -0700773 request._refresh = False
774 request._slice = None
775 if request.method == 'POST':
Scott Baker8737e5f2013-05-17 09:35:32 -0700776 # "refresh" will be set to "1" if the form was submitted due to
777 # a change in the Slice dropdown.
Scott Baker133c9212013-05-17 09:09:11 -0700778 if request.POST.get("refresh","1") == "1":
779 request._refresh = True
780 request.POST["refresh"] = "0"
Scott Baker8737e5f2013-05-17 09:35:32 -0700781
782 # Keep track of the slice that was selected, so the
783 # reservedResource inline can filter items for the slice.
Scott Baker133c9212013-05-17 09:09:11 -0700784 request._slice = request.POST.get("slice",None)
785 if (request._slice is not None):
786 request._slice = Slice.objects.get(id=request._slice)
787
788 result = super(ReservationAdmin, self).add_view(request, form_url, extra_context)
789 return result
790
Scott Bakeracd45142013-05-19 16:19:16 -0700791 def changelist_view(self, request, extra_context = None):
792 timezone.activate(request.user.timezone)
793 return super(ReservationAdmin, self).changelist_view(request, extra_context)
794
Scott Baker133c9212013-05-17 09:09:11 -0700795 def get_form(self, request, obj=None, **kwargs):
Siobhan Tullyd3515752013-06-21 16:34:53 -0400796 request._obj_ = obj
797 if obj is not None:
798 # For changes, set request._slice to the slice already set in the
799 # object.
800 request._slice = obj.slice
801 self.form = ReservationChangeForm
802 else:
803 if getattr(request, "_refresh", False):
804 self.form = ReservationAddRefreshForm
805 else:
806 self.form = ReservationAddForm
807 return super(ReservationAdmin, self).get_form(request, obj, **kwargs)
808
Scott Baker133c9212013-05-17 09:09:11 -0700809 def get_readonly_fields(self, request, obj=None):
Siobhan Tullyd3515752013-06-21 16:34:53 -0400810 if (obj is not None):
811 # Prevent slice from being changed after the reservation has been
812 # created.
813 return ['slice']
814 else:
Scott Baker133c9212013-05-17 09:09:11 -0700815 return []
Scott Baker3de3e372013-05-10 16:50:44 -0700816
Scott Baker74d8e622013-07-29 16:04:22 -0700817class NetworkParameterTypeAdmin(admin.ModelAdmin):
818 exclude = ['enacted']
819 list_display = ("name", )
820
821class RouterAdmin(admin.ModelAdmin):
822 exclude = ['enacted']
823 list_display = ("name", )
824
825class RouterInline(admin.TabularInline):
826 # exclude = ['enacted']
827 model = Router.networks.through
828 extra = 0
829 verbose_name_plural = "Routers"
830 verbose_name = "Router"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400831 suit_classes = 'suit-tab suit-tab-routers'
Scott Baker74d8e622013-07-29 16:04:22 -0700832
833class NetworkParameterInline(generic.GenericTabularInline):
834 exclude = ['enacted']
835 model = NetworkParameter
836 extra = 1
837 verbose_name_plural = "Parameters"
838 verbose_name = "Parameter"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400839 suit_classes = 'suit-tab suit-tab-netparams'
Scott Baker74d8e622013-07-29 16:04:22 -0700840
841class NetworkSliversInline(admin.TabularInline):
842 exclude = ['enacted']
843 readonly_fields = ("ip", )
844 model = NetworkSliver
845 extra = 0
846 verbose_name_plural = "Slivers"
847 verbose_name = "Sliver"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400848 suit_classes = 'suit-tab suit-tab-networkslivers'
Scott Baker74d8e622013-07-29 16:04:22 -0700849
Scott Bakerd7d2a392013-08-06 08:57:30 -0700850class NetworkSlicesInline(admin.TabularInline):
851 exclude = ['enacted']
852 model = NetworkSlice
853 extra = 0
854 verbose_name_plural = "Slices"
855 verbose_name = "Slice"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400856 suit_classes = 'suit-tab suit-tab-networkslices'
Scott Bakerd7d2a392013-08-06 08:57:30 -0700857
Scott Baker74d8e622013-07-29 16:04:22 -0700858class NetworkAdmin(admin.ModelAdmin):
859 exclude = ['enacted']
860 list_display = ("name", "subnet", "ports", "labels")
861 readonly_fields = ("subnet", )
Siobhan Tully2d95e482013-09-06 10:56:06 -0400862
Scott Bakerd7d2a392013-08-06 08:57:30 -0700863 inlines = [NetworkParameterInline, NetworkSliversInline, NetworkSlicesInline, RouterInline]
Scott Baker74d8e622013-07-29 16:04:22 -0700864
Siobhan Tully2d95e482013-09-06 10:56:06 -0400865 fieldsets = [
866 (None, {'fields': ['name','template','ports','labels','owner','guaranteedBandwidth', 'permitAllSlices','permittedSlices','network_id','router_id','subnet_id','subnet'], 'classes':['suit-tab suit-tab-general']}),]
867
868 suit_form_tabs =(
869 ('general','Network Details'),
870 ('netparams', 'Parameters'),
871 ('networkslivers','Slivers'),
872 ('networkslices','Slices'),
873 ('routers','Routers'),
874 )
Scott Baker74d8e622013-07-29 16:04:22 -0700875class NetworkTemplateAdmin(admin.ModelAdmin):
876 exclude = ['enacted']
877 list_display = ("name", "guaranteedBandwidth", "visibility")
878
Tony Mack31c2b8f2013-04-26 20:01:42 -0400879# register a signal that caches the user's credentials when they log in
880def cache_credentials(sender, user, request, **kwds):
881 auth = {'username': request.POST['username'],
882 'password': request.POST['password']}
883 request.session['auth'] = auth
884user_logged_in.connect(cache_credentials)
885
Siobhan Tully53437282013-04-26 19:30:27 -0400886# Now register the new UserAdmin...
Siobhan Tully30fd4292013-05-10 08:59:56 -0400887admin.site.register(User, UserAdmin)
Siobhan Tully53437282013-04-26 19:30:27 -0400888# ... and, since we're not using Django's builtin permissions,
889# unregister the Group model from admin.
890admin.site.unregister(Group)
891
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400892#Do not show django evolution in the admin interface
893from django_evolution.models import Version, Evolution
894admin.site.unregister(Version)
895admin.site.unregister(Evolution)
896
897
898# When debugging it is often easier to see all the classes, but for regular use
899# only the top-levels should be displayed
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400900showAll = True
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400901
902admin.site.register(Deployment, DeploymentAdmin)
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400903admin.site.register(Site, SiteAdmin)
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400904admin.site.register(Slice, SliceAdmin)
Siobhan Tullyd3515752013-06-21 16:34:53 -0400905admin.site.register(Project, ProjectAdmin)
smbaker43591c32013-06-26 12:43:53 -0700906admin.site.register(ServiceClass, ServiceClassAdmin)
smbakera3cf70c2013-06-27 02:01:41 -0700907admin.site.register(Reservation, ReservationAdmin)
Scott Baker74d8e622013-07-29 16:04:22 -0700908admin.site.register(Network, NetworkAdmin)
909admin.site.register(Router, RouterAdmin)
910admin.site.register(NetworkParameterType, NetworkParameterTypeAdmin)
911admin.site.register(NetworkTemplate, NetworkTemplateAdmin)
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400912
913if showAll:
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400914 #admin.site.register(PlanetStack)
Siobhan Tullyd3515752013-06-21 16:34:53 -0400915 admin.site.register(Tag, TagAdmin)
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400916 admin.site.register(Node, NodeAdmin)
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400917 #admin.site.register(SlicePrivilege, SlicePrivilegeAdmin)
918 #admin.site.register(SitePrivilege, SitePrivilegeAdmin)
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400919 admin.site.register(Member, MemberAdmin)
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400920 admin.site.register(Sliver, SliverAdmin)
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400921 admin.site.register(Image, ImageAdmin)
Tony Mack7130ac32013-03-22 21:58:00 -0400922