blob: bae7be152b8b7e154d5ee730b2c537911787d4c2 [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):
Siobhan Tully2c780ad2013-09-06 11:22:40 -040020 pass
Siobhan Tullyd3515752013-06-21 16:34:53 -040021
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
Siobhan Tullybfd11dc2013-09-03 12:59:24 -040046 extra = 0
47 suit_classes = 'suit-tab suit-tab-tags'
Siobhan Tullyde5450d2013-06-21 11:35:33 -040048
Scott Baker74d8e622013-07-29 16:04:22 -070049class NetworkLookerUpper:
Siobhan Tully2c780ad2013-09-06 11:22:40 -040050 """ This is a callable that looks up a network name in a sliver and returns
51 the ip address for that network.
52 """
53
54 def __init__(self, name):
55 self.short_description = name
56 self.__name__ = name
57 self.network_name = name
58
59 def __call__(self, obj):
60 if obj is not None:
61 for nbs in obj.networksliver_set.all():
62 if (nbs.network.name == self.network_name):
63 return nbs.ip
Scott Baker74d8e622013-07-29 16:04:22 -070064 return ""
65
66 def __str__(self):
67 return self.network_name
68
Siobhan Tullyd3515752013-06-21 16:34:53 -040069class SliverInline(PlStackTabularInline):
Siobhan Tully4bc09f22013-04-10 21:15:21 -040070 model = Sliver
Tony Mackb0d97422013-06-10 09:57:45 -040071 fields = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
Siobhan Tully4bc09f22013-04-10 21:15:21 -040072 extra = 0
Tony Mack3777b012013-05-07 21:38:06 -040073 readonly_fields = ['ip', 'instance_name']
Siobhan Tullybfd11dc2013-09-03 12:59:24 -040074 suit_classes = 'suit-tab suit-tab-slivers'
Scott Baker74d8e622013-07-29 16:04:22 -070075
Siobhan Tully2d95e482013-09-06 10:56:06 -040076# Note this is breaking in the admin.py when trying to use an inline to add a node/image
77# def _declared_fieldsets(self):
78# # Return None so django will call get_fieldsets and we can insert our
79# # dynamic fields
80# return None
81#
82# def get_readonly_fields(self, request, obj=None):
83# readonly_fields = super(SliverInline, self).get_readonly_fields(request, obj)
84#
85# # Lookup the networks that are bound to the slivers, and add those
86# # network names to the list of readonly fields.
87#
88# for sliver in obj.slivers.all():
89# for nbs in sliver.networksliver_set.all():
90# if nbs.ip:
91# network_name = nbs.network.name
92# if network_name not in [str(x) for x in readonly_fields]:
93# readonly_fields.append(NetworkLookerUpper(network_name))
94#
95# return readonly_fields
96#
97# def get_fieldsets(self, request, obj=None):
98# form = self.get_formset(request, obj).form
99# # fields = the read/write files + the read-only fields
100# fields = self.fields
101# for fieldName in self.get_readonly_fields(request,obj):
102# if not fieldName in fields:
103# fields.append(fieldName)
104#
105# return [(None, {'fields': fields})]
Scott Baker74d8e622013-07-29 16:04:22 -0700106
Tony Mackc2835a92013-05-28 09:18:49 -0400107
Siobhan Tully567e3e62013-06-21 18:03:16 -0400108
Siobhan Tullyd3515752013-06-21 16:34:53 -0400109class SiteInline(PlStackTabularInline):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400110 model = Site
111 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400112 suit_classes = 'suit-tab suit-tab-sites'
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400113
Siobhan Tullyd3515752013-06-21 16:34:53 -0400114class UserInline(PlStackTabularInline):
Siobhan Tully30fd4292013-05-10 08:59:56 -0400115 model = User
Siobhan Tully47ae1b52013-05-10 15:53:14 -0400116 fields = ['email', 'firstname', 'lastname']
Siobhan Tully30fd4292013-05-10 08:59:56 -0400117 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400118 suit_classes = 'suit-tab suit-tab-users'
Siobhan Tully30fd4292013-05-10 08:59:56 -0400119
Siobhan Tullyd3515752013-06-21 16:34:53 -0400120class SliceInline(PlStackTabularInline):
Tony Mack00d361f2013-04-28 10:28:42 -0400121 model = Slice
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400122 fields = ['name','enabled','description','slice_url']
Tony Mack00d361f2013-04-28 10:28:42 -0400123 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400124 suit_classes = 'suit-tab suit-tab-slices'
125
Tony Mack00d361f2013-04-28 10:28:42 -0400126
Siobhan Tullyd3515752013-06-21 16:34:53 -0400127class RoleInline(PlStackTabularInline):
Tony Mack00d361f2013-04-28 10:28:42 -0400128 model = Role
129 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400130 suit_classes = 'suit-tab suit-tab-roles'
Tony Mack00d361f2013-04-28 10:28:42 -0400131
Siobhan Tullyd3515752013-06-21 16:34:53 -0400132class NodeInline(PlStackTabularInline):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400133 model = Node
134 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400135 suit_classes = 'suit-tab suit-tab-nodes'
136
137class SlicePrivilegeInline(PlStackTabularInline):
138 model = SlicePrivilege
139 extra = 0
140 suit_classes = 'suit-tab suit-tab-sliceprivileges'
141
142class DeploymentPrivilegeInline(PlStackTabularInline):
143 model = DeploymentPrivilege
144 extra = 0
145 suit_classes = 'suit-tab suit-tab-deploymentprivileges'
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400146
Siobhan Tullyd3515752013-06-21 16:34:53 -0400147class SitePrivilegeInline(PlStackTabularInline):
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400148 model = SitePrivilege
149 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400150 suit_classes = 'suit-tab suit-tab-siteprivileges'
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400151
Tony Mackc2835a92013-05-28 09:18:49 -0400152 def formfield_for_foreignkey(self, db_field, request, **kwargs):
153 if db_field.name == 'site':
154 if not request.user.is_admin:
155 # only show sites where user is an admin or pi
156 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
157 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
158 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
159 sites = Site.objects.filter(login_base__in=login_bases)
160 kwargs['queryset'] = sites
161
162 if db_field.name == 'user':
163 if not request.user.is_admin:
164 # only show users from sites where caller has admin or pi role
165 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
166 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
167 sites = [site_privilege.site for site_privilege in site_privileges]
168 site_privileges = SitePrivilege.objects.filter(site__in=sites)
169 emails = [site_privilege.user.email for site_privilege in site_privileges]
170 users = User.objects.filter(email__in=emails)
171 kwargs['queryset'] = users
172 return super(SitePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
173
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400174class SitePrivilegeInline(PlStackTabularInline):
175 model = SitePrivilege
176 suit_classes = 'suit-tab suit-tab-siteprivileges'
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400177 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400178 fields = ('user', 'site','role')
179
180class SlicePrivilegeInline(PlStackTabularInline):
181 model = SlicePrivilege
182 suit_classes = 'suit-tab suit-tab-sliceprivileges'
183 extra = 0
184 fields = ('user', 'slice','role')
Siobhan Tullyaa1bcd52013-05-10 12:43:09 -0400185
Tony Mackc2835a92013-05-28 09:18:49 -0400186 def formfield_for_foreignkey(self, db_field, request, **kwargs):
187 if db_field.name == 'slice':
188 if not request.user.is_admin:
189 # only show slices at sites where caller has admin or pi role
190 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
191 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
192 sites = [site_privilege.site for site_privilege in site_privileges]
193 slices = Slice.objects.filter(site__in=sites)
194 kwargs['queryset'] = slices
195 if db_field.name == 'user':
196 if not request.user.is_admin:
197 # only show users from sites where caller has admin or pi role
198 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
199 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
200 sites = [site_privilege.site for site_privilege in site_privileges]
201 site_privileges = SitePrivilege.objects.filter(site__in=sites)
202 emails = [site_privilege.user.email for site_privilege in site_privileges]
203 users = User.objects.filter(email__in=emails)
204 kwargs['queryset'] = list(users)
205
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400206 return super(SlicePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
Tony Mackc2835a92013-05-28 09:18:49 -0400207
Scott Bakera0015eb2013-08-14 17:28:14 -0700208class SliceNetworkInline(PlStackTabularInline):
Scott Baker74d8e622013-07-29 16:04:22 -0700209 model = Network.slices.through
210 extra = 0
211 verbose_name = "Network Connection"
212 verbose_name_plural = "Network Connections"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400213 suit_classes = 'suit-tab suit-tab-slicenetworks'
Scott Baker74d8e622013-07-29 16:04:22 -0700214
Siobhan Tullyd3515752013-06-21 16:34:53 -0400215class SliceTagInline(PlStackTabularInline):
Scott Baker307e06f2013-05-21 17:25:56 -0700216 model = SliceTag
217 extra = 0
218
Tony Mack5e71a662013-05-03 23:30:41 -0400219class PlainTextWidget(forms.HiddenInput):
220 input_type = 'hidden'
221
222 def render(self, name, value, attrs=None):
223 if value is None:
224 value = ''
Tony Mack1d6b85f2013-05-07 18:49:14 -0400225 return mark_safe(str(value) + super(PlainTextWidget, self).render(name, value, attrs))
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400226
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400227class PlanetStackBaseAdmin(admin.ModelAdmin):
228 save_on_top = False
229
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400230class SliceRoleAdmin(PlanetStackBaseAdmin):
231 model = SliceRole
232 pass
233
234class SiteRoleAdmin(PlanetStackBaseAdmin):
235 model = SiteRole
236 pass
237
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400238class DeploymentAdminForm(forms.ModelForm):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400239 sites = forms.ModelMultipleChoiceField(
240 queryset=Site.objects.all(),
241 required=False,
242 widget=FilteredSelectMultiple(
243 verbose_name=('Sites'), is_stacked=False
244 )
245 )
246 class Meta:
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400247 model = Deployment
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400248
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400249
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400250class DeploymentAdmin(PlanetStackBaseAdmin):
251 form = DeploymentAdminForm
Siobhan Tully2d95e482013-09-06 10:56:06 -0400252 inlines = [DeploymentPrivilegeInline,NodeInline,TagInline]
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400253 fieldsets = [
254 (None, {'fields': ['sites'], 'classes':['suit-tab suit-tab-sites']}),]
Siobhan Tully2d95e482013-09-06 10:56:06 -0400255 suit_form_tabs =(('sites', 'Sites'),('nodes','Nodes'),('deploymentprivileges','Privileges'),('tags','Tags'))
Tony Mack5cd13202013-05-01 21:48:38 -0400256
Tony Mack0553f282013-06-10 22:54:50 -0400257class SiteAdmin(PlanetStackBaseAdmin):
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400258 fieldsets = [
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400259 (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base', 'location'], 'classes':['suit-tab suit-tab-general']}),
260 ('Deployment Networks', {'fields': ['deployments'], 'classes':['suit-tab suit-tab-deployments']}),
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400261 ]
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400262 suit_form_tabs =(('general', 'Site Details'),
263 ('users','Users'),
Siobhan Tully2d95e482013-09-06 10:56:06 -0400264 ('siteprivileges','Privileges'),
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400265 ('deployments','Deployments'),
266 ('slices','Slices'),
267 ('nodes','Nodes'),
268 ('tags','Tags'),
269 )
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400270 list_display = ('name', 'login_base','site_url', 'enabled')
271 filter_horizontal = ('deployments',)
Siobhan Tully2d95e482013-09-06 10:56:06 -0400272 inlines = [SliceInline,UserInline,TagInline, NodeInline, SitePrivilegeInline]
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400273 search_fields = ['name']
274
Tony Mack04062832013-05-10 08:22:44 -0400275 def queryset(self, request):
276 # admins can see all keys. Users can only see sites they belong to.
277 qs = super(SiteAdmin, self).queryset(request)
278 if not request.user.is_admin:
279 valid_sites = [request.user.site.login_base]
280 roles = request.user.get_roles()
281 for tenant_list in roles.values():
282 valid_sites.extend(tenant_list)
283 qs = qs.filter(login_base__in=valid_sites)
284 return qs
285
Tony Mack5cd13202013-05-01 21:48:38 -0400286 def get_formsets(self, request, obj=None):
287 for inline in self.get_inline_instances(request, obj):
288 # hide MyInline in the add view
289 if obj is None:
290 continue
Tony Mack2bd5b412013-06-11 21:05:06 -0400291 if isinstance(inline, SliceInline):
292 inline.model.caller = request.user
293 yield inline.get_formset(request, obj)
294
295 def get_formsets(self, request, obj=None):
296 for inline in self.get_inline_instances(request, obj):
297 # hide MyInline in the add view
298 if obj is None:
299 continue
300 if isinstance(inline, SliverInline):
301 inline.model.caller = request.user
Tony Mack5cd13202013-05-01 21:48:38 -0400302 yield inline.get_formset(request, obj)
303
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400304class SitePrivilegeAdmin(PlanetStackBaseAdmin):
Tony Mack00d361f2013-04-28 10:28:42 -0400305 fieldsets = [
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400306 (None, {'fields': ['user', 'site', 'role'], 'classes':['collapse']})
Tony Mack00d361f2013-04-28 10:28:42 -0400307 ]
308 list_display = ('user', 'site', 'role')
309
Tony Mackc2835a92013-05-28 09:18:49 -0400310 def formfield_for_foreignkey(self, db_field, request, **kwargs):
311 if db_field.name == 'site':
312 if not request.user.is_admin:
313 # only show sites where user is an admin or pi
314 sites = set()
315 for site_privilege in SitePrivilege.objects.filer(user=request.user):
316 if site_privilege.role.role_type in ['admin', 'pi']:
317 sites.add(site_privilege.site)
318 kwargs['queryset'] = Site.objects.filter(site__in=list(sites))
319
320 if db_field.name == 'user':
321 if not request.user.is_admin:
322 # only show users from sites where caller has admin or pi role
323 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
324 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
325 sites = [site_privilege.site for site_privilege in site_privileges]
326 site_privileges = SitePrivilege.objects.filter(site__in=sites)
327 emails = [site_privilege.user.email for site_privilege in site_privileges]
328 users = User.objects.filter(email__in=emails)
329 kwargs['queryset'] = users
330
331 return super(SitePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
332
Tony Mack04062832013-05-10 08:22:44 -0400333 def queryset(self, request):
334 # admins can see all privileges. Users can only see privileges at sites
Tony Mackc2835a92013-05-28 09:18:49 -0400335 # where they have the admin role or pi role.
Tony Mack04062832013-05-10 08:22:44 -0400336 qs = super(SitePrivilegeAdmin, self).queryset(request)
337 if not request.user.is_admin:
Tony Mackc2835a92013-05-28 09:18:49 -0400338 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
339 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
340 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
341 sites = Site.objects.filter(login_base__in=login_bases)
342 qs = qs.filter(site__in=sites)
Tony Mack04062832013-05-10 08:22:44 -0400343 return qs
344
Tony Mack2bd5b412013-06-11 21:05:06 -0400345class SliceAdmin(PlanetStackBaseAdmin):
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400346 fieldsets = [('Slice Details', {'fields': ['name', 'site', 'serviceClass', 'description', 'slice_url'], 'classes':['suit-tab suit-tab-general']}),]
Siobhan Tully30fd4292013-05-10 08:59:56 -0400347 list_display = ('name', 'site','serviceClass', 'slice_url')
Siobhan Tully2d95e482013-09-06 10:56:06 -0400348 inlines = [SlicePrivilegeInline,SliverInline, TagInline, ReservationInline,SliceNetworkInline]
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400349
350
Siobhan Tully2d95e482013-09-06 10:56:06 -0400351 #inlines = [SliverInline, SliceMembershipInline, TagInline, SliceTagInline, SliceNetworkInline]
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400352 suit_form_tabs =(('general', 'Slice Details'),
Siobhan Tully2d95e482013-09-06 10:56:06 -0400353 ('slicenetworks','Networks'),
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400354 ('sliceprivileges','Privileges'),
355 ('slivers','Slivers'),
356 ('tags','Tags'),
357 ('reservations','Reservations'),
358 )
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400359
Tony Mackc2835a92013-05-28 09:18:49 -0400360 def formfield_for_foreignkey(self, db_field, request, **kwargs):
361 if db_field.name == 'site':
362 if not request.user.is_admin:
363 # only show sites where user is a pi or admin
364 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
365 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
366 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
367 sites = Site.objects.filter(login_base__in=login_bases)
368 kwargs['queryset'] = sites
369
370 return super(SliceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
371
Tony Mack04062832013-05-10 08:22:44 -0400372 def queryset(self, request):
373 # admins can see all keys. Users can only see slices they belong to.
374 qs = super(SliceAdmin, self).queryset(request)
375 if not request.user.is_admin:
376 valid_slices = []
377 roles = request.user.get_roles()
378 for tenant_list in roles.values():
379 valid_slices.extend(tenant_list)
380 qs = qs.filter(name__in=valid_slices)
381 return qs
382
Tony Mack79748612013-05-01 14:52:03 -0400383 def get_formsets(self, request, obj=None):
384 for inline in self.get_inline_instances(request, obj):
385 # hide MyInline in the add view
386 if obj is None:
387 continue
Tony Mack2bd5b412013-06-11 21:05:06 -0400388 if isinstance(inline, SliverInline):
389 inline.model.caller = request.user
Tony Mack79748612013-05-01 14:52:03 -0400390 yield inline.get_formset(request, obj)
391
Tony Mackfdd4d802013-04-27 13:02:33 -0400392 def get_queryset(self, request):
393 qs = super(SliceAdmin, self).get_queryset(request)
394 if request.user.is_superuser:
395 return qs
396 # users can only see slices at their site
Tony Mack2bd5b412013-06-11 21:05:06 -0400397 return qs.filter(site=request.user.site)
398
399 def save_model(self, request, obj, form, change):
400 # update openstack connection to use this site/tenant
401 obj.caller = request.user
402 obj.save()
Tony Mackfdd4d802013-04-27 13:02:33 -0400403
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400404class SlicePrivilegeAdmin(PlanetStackBaseAdmin):
Tony Mack00d361f2013-04-28 10:28:42 -0400405 fieldsets = [
406 (None, {'fields': ['user', 'slice', 'role']})
407 ]
408 list_display = ('user', 'slice', 'role')
Tony Mack00d361f2013-04-28 10:28:42 -0400409
Tony Mackc2835a92013-05-28 09:18:49 -0400410 def formfield_for_foreignkey(self, db_field, request, **kwargs):
411 if db_field.name == 'slice':
412 if not request.user.is_admin:
413 # only show slices at sites where caller has admin or pi role
414 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
415 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
416 sites = [site_privilege.site for site_privilege in site_privileges]
417 slices = Slice.objects.filter(site__in=sites)
418 kwargs['queryset'] = slices
419
420 if db_field.name == 'user':
421 if not request.user.is_admin:
422 # only show users from sites where caller has admin or pi role
423 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
424 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
425 sites = [site_privilege.site for site_privilege in site_privileges]
426 site_privileges = SitePrivilege.objects.filter(site__in=sites)
427 emails = [site_privilege.user.email for site_privilege in site_privileges]
428 users = User.objects.filter(email__in=emails)
429 kwargs['queryset'] = users
430
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400431 return super(SlicePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
Tony Mackc2835a92013-05-28 09:18:49 -0400432
Tony Mack04062832013-05-10 08:22:44 -0400433 def queryset(self, request):
434 # admins can see all memberships. Users can only see memberships of
435 # slices where they have the admin role.
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400436 qs = super(SlicePrivilegeAdmin, self).queryset(request)
Tony Mack04062832013-05-10 08:22:44 -0400437 if not request.user.is_admin:
Tony Mackc2835a92013-05-28 09:18:49 -0400438 roles = Role.objects.filter(role_type__in=['admin', 'pi'])
439 site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
440 login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
441 sites = Site.objects.filter(login_base__in=login_bases)
442 slices = Slice.objects.filter(site__in=sites)
443 qs = qs.filter(slice__in=slices)
Tony Mack04062832013-05-10 08:22:44 -0400444 return qs
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400445
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400446 def save_model(self, request, obj, form, change):
Tony Mack951dab42013-05-02 19:51:45 -0400447 # update openstack connection to use this site/tenant
448 auth = request.session.get('auth', {})
449 auth['tenant'] = obj.slice.name
450 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400451 obj.save()
452
453 def delete_model(self, request, obj):
Tony Mack951dab42013-05-02 19:51:45 -0400454 # update openstack connection to use this site/tenant
455 auth = request.session.get('auth', {})
456 auth['tenant'] = obj.slice.name
457 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400458 obj.delete()
459
Siobhan Tully567e3e62013-06-21 18:03:16 -0400460
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400461class ImageAdmin(PlanetStackBaseAdmin):
462
463 fieldsets = [('Image Details',
464 {'fields': ['image_id', 'name', 'disk_format', 'container_format'],
465 'classes': ['suit-tab suit-tab-general']})
466 ]
467
468 suit_form_tabs =(('general','Image Details'),('slivers','Slivers'))
469
470 inlines = [SliverInline]
471
472class NodeForm(forms.ModelForm):
473 class Meta:
474 widgets = {
475 'site': LinkedSelect,
476 'deployment': LinkedSelect
477 }
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400478
479class NodeAdmin(admin.ModelAdmin):
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400480 form = NodeForm
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400481 list_display = ('name', 'site', 'deployment')
482 list_filter = ('deployment',)
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400483 inlines = [TagInline,SliverInline]
484 fieldsets = [('Node Details', {'fields': ['name','site','deployment'], 'classes':['suit-tab suit-tab-details']})]
485
486 suit_form_tabs =(('details','Node Details'),('slivers','Slivers'),('tags','Tags'))
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400487
Siobhan Tully567e3e62013-06-21 18:03:16 -0400488
Tony Mackd90cdbf2013-04-16 22:48:40 -0400489class SliverForm(forms.ModelForm):
490 class Meta:
Tony Mack1d6b85f2013-05-07 18:49:14 -0400491 model = Sliver
Tony Mackd90cdbf2013-04-16 22:48:40 -0400492 ip = forms.CharField(widget=PlainTextWidget)
Tony Mack18261812013-05-02 16:39:20 -0400493 instance_name = forms.CharField(widget=PlainTextWidget)
Tony Mackd90cdbf2013-04-16 22:48:40 -0400494 widgets = {
495 'ip': PlainTextWidget(),
Tony Mack18261812013-05-02 16:39:20 -0400496 'instance_name': PlainTextWidget(),
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400497 'slice': LinkedSelect,
498 'deploymentNetwork': LinkedSelect,
499 'node': LinkedSelect,
500 'image': LinkedSelect
Siobhan Tully53437282013-04-26 19:30:27 -0400501 }
Tony Mackd90cdbf2013-04-16 22:48:40 -0400502
Siobhan Tullyd3515752013-06-21 16:34:53 -0400503class ProjectAdmin(admin.ModelAdmin):
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400504 inlines = [TagInline]
505
Siobhan Tullyd3515752013-06-21 16:34:53 -0400506class TagAdmin(admin.ModelAdmin):
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400507 list_display = ['project', 'name', 'value', 'content_type', 'content_object',]
Siobhan Tullyd3515752013-06-21 16:34:53 -0400508
Tony Mack9bcbe4f2013-04-29 08:13:27 -0400509class SliverAdmin(PlanetStackBaseAdmin):
Tony Mackd90cdbf2013-04-16 22:48:40 -0400510 form = SliverForm
Tony Mackcdec0902013-04-15 00:38:49 -0400511 fieldsets = [
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400512 ('Sliver Details', {'fields': ['slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'numberCores', 'image', ], 'classes': ['suit-tab suit-tab-general'], })
Tony Mackcdec0902013-04-15 00:38:49 -0400513 ]
Siobhan Tully5d7dc8d2013-07-02 13:17:33 -0400514 list_display = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400515
516 suit_form_tabs =(('general', 'Sliver Details'),
517 ('tags','Tags'),
518 )
519
Siobhan Tullyde5450d2013-06-21 11:35:33 -0400520 inlines = [TagInline]
Tony Mack53106f32013-04-27 16:43:01 -0400521
Tony Mackc2835a92013-05-28 09:18:49 -0400522 def formfield_for_foreignkey(self, db_field, request, **kwargs):
523 if db_field.name == 'slice':
524 if not request.user.is_admin:
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400525 slices = set([sm.slice.name for sm in SlicePrivilege.objects.filter(user=request.user)])
Tony Mackc2835a92013-05-28 09:18:49 -0400526 kwargs['queryset'] = Slice.objects.filter(name__in=list(slices))
527
528 return super(SliverAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
529
Tony Mack04062832013-05-10 08:22:44 -0400530 def queryset(self, request):
531 # admins can see all slivers. Users can only see slivers of
532 # the slices they belong to.
533 qs = super(SliverAdmin, self).queryset(request)
534 if not request.user.is_admin:
535 tenants = []
536 roles = request.user.get_roles()
537 for tenant_list in roles.values():
538 tenants.extend(tenant_list)
539 valid_slices = Slice.objects.filter(name__in=tenants)
540 qs = qs.filter(slice__in=valid_slices)
541 return qs
542
Tony Mack1d6b85f2013-05-07 18:49:14 -0400543 def get_formsets(self, request, obj=None):
544 # make some fields read only if we are updating an existing record
545 if obj == None:
546 #self.readonly_fields = ('ip', 'instance_name')
547 self.readonly_fields = ()
548 else:
Tony Mack1e889462013-05-10 21:34:54 -0400549 self.readonly_fields = ()
550 #self.readonly_fields = ('ip', 'instance_name', 'slice', 'image', 'key')
Tony Mack1d6b85f2013-05-07 18:49:14 -0400551
552 for inline in self.get_inline_instances(request, obj):
553 # hide MyInline in the add view
554 if obj is None:
555 continue
556 # give inline object access to driver and caller
557 auth = request.session.get('auth', {})
558 auth['tenant'] = obj.name # meed to connect using slice's tenant
559 inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
560 yield inline.get_formset(request, obj)
Tony Mack53106f32013-04-27 16:43:01 -0400561
562 def save_model(self, request, obj, form, change):
Tony Mack951dab42013-05-02 19:51:45 -0400563 # update openstack connection to use this site/tenant
564 auth = request.session.get('auth', {})
565 auth['tenant'] = obj.slice.name
566 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mackb0d97422013-06-10 09:57:45 -0400567 obj.creator = request.user
Tony Mack53106f32013-04-27 16:43:01 -0400568 obj.save()
569
570 def delete_model(self, request, obj):
Tony Mack951dab42013-05-02 19:51:45 -0400571 # update openstack connection to use this site/tenant
572 auth = request.session.get('auth', {})
573 auth['tenant'] = obj.slice.name
574 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
Tony Mack53106f32013-04-27 16:43:01 -0400575 obj.delete()
Tony Mackcdec0902013-04-15 00:38:49 -0400576
Siobhan Tully53437282013-04-26 19:30:27 -0400577class UserCreationForm(forms.ModelForm):
578 """A form for creating new users. Includes all the required
579 fields, plus a repeated password."""
580 password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
581 password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
582
583 class Meta:
Siobhan Tully30fd4292013-05-10 08:59:56 -0400584 model = User
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400585 fields = ('email', 'firstname', 'lastname', 'phone', 'public_key')
Siobhan Tully53437282013-04-26 19:30:27 -0400586
587 def clean_password2(self):
588 # Check that the two password entries match
589 password1 = self.cleaned_data.get("password1")
590 password2 = self.cleaned_data.get("password2")
591 if password1 and password2 and password1 != password2:
592 raise forms.ValidationError("Passwords don't match")
593 return password2
594
595 def save(self, commit=True):
596 # Save the provided password in hashed format
597 user = super(UserCreationForm, self).save(commit=False)
Tony Mackf9f4afb2013-05-01 21:02:12 -0400598 user.password = self.cleaned_data["password1"]
599 #user.set_password(self.cleaned_data["password1"])
Siobhan Tully53437282013-04-26 19:30:27 -0400600 if commit:
601 user.save()
602 return user
603
Siobhan Tully567e3e62013-06-21 18:03:16 -0400604
Siobhan Tully53437282013-04-26 19:30:27 -0400605class UserChangeForm(forms.ModelForm):
606 """A form for updating users. Includes all the fields on
607 the user, but replaces the password field with admin's
608 password hash display field.
609 """
610 password = ReadOnlyPasswordHashField()
611
612 class Meta:
Siobhan Tully30fd4292013-05-10 08:59:56 -0400613 model = User
Siobhan Tully53437282013-04-26 19:30:27 -0400614
615 def clean_password(self):
616 # Regardless of what the user provides, return the initial value.
617 # This is done here, rather than on the field, because the
618 # field does not have access to the initial value
619 return self.initial["password"]
620
Siobhan Tully567e3e62013-06-21 18:03:16 -0400621
Tony Mack2bd5b412013-06-11 21:05:06 -0400622class UserAdmin(UserAdmin):
Siobhan Tully53437282013-04-26 19:30:27 -0400623 class Meta:
624 app_label = "core"
625
626 # The forms to add and change user instances
627 form = UserChangeForm
628 add_form = UserCreationForm
629
630 # The fields to be used in displaying the User model.
631 # These override the definitions on the base UserAdmin
632 # that reference specific fields on auth.User.
Siobhan Tullyfece0d52013-09-06 12:57:05 -0400633 list_display = ('email', 'firstname', 'lastname', 'is_admin', 'last_login')
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400634 list_filter = ()
635 inlines = [SlicePrivilegeInline,SitePrivilegeInline,DeploymentPrivilegeInline]
Siobhan Tully53437282013-04-26 19:30:27 -0400636 fieldsets = (
Siobhan Tullyfece0d52013-09-06 12:57:05 -0400637 ('Login Details', {'fields': ('email', 'site','password', 'is_admin', 'public_key'), 'classes':['suit-tab suit-tab-general']}),
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400638 ('Contact Information', {'fields': ('firstname','lastname','phone', 'timezone'), 'classes':['suit-tab suit-tab-contact']}),
Siobhan Tully53437282013-04-26 19:30:27 -0400639 #('Important dates', {'fields': ('last_login',)}),
640 )
641 add_fieldsets = (
642 (None, {
643 'classes': ('wide',),
Siobhan Tullyfece0d52013-09-06 12:57:05 -0400644 'fields': ('email', 'firstname', 'lastname', 'phone', 'public_key','password1', 'password2')}
Siobhan Tully53437282013-04-26 19:30:27 -0400645 ),
646 )
647 search_fields = ('email',)
648 ordering = ('email',)
649 filter_horizontal = ()
650
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400651 suit_form_tabs =(('general','Login Details'),('contact','Contact Information'),('sliceprivileges','Slice Privileges'),('siteprivileges','Site Privileges'),('deploymentprivileges','Deployment Privileges'))
652
Tony Mackc2835a92013-05-28 09:18:49 -0400653 def formfield_for_foreignkey(self, db_field, request, **kwargs):
654 if db_field.name == 'site':
655 if not request.user.is_admin:
656 # show sites where caller is an admin or pi
657 sites = []
658 for site_privilege in SitePrivilege.objects.filer(user=request.user):
659 if site_privilege.role.role_type in ['admin', 'pi']:
660 sites.append(site_privilege.site.login_base)
661 kwargs['queryset'] = Site.objects.filter(login_base__in(list(sites)))
662
663 return super(UserAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
664
Scott Baker3de3e372013-05-10 16:50:44 -0700665class ServiceResourceInline(admin.TabularInline):
666 model = ServiceResource
667 extra = 0
668
669class ServiceClassAdmin(admin.ModelAdmin):
670 list_display = ('name', 'commitment', 'membershipFee')
671 inlines = [ServiceResourceInline]
672
Scott Baker133c9212013-05-17 09:09:11 -0700673class ReservedResourceInline(admin.TabularInline):
674 model = ReservedResource
675 extra = 0
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400676 suit_classes = 'suit-tab suit-tab-reservedresources'
Scott Baker133c9212013-05-17 09:09:11 -0700677
678 def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
679 field = super(ReservedResourceInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
680
681 if db_field.name == 'resource':
682 # restrict resources to those that the slice's service class allows
683 if request._slice is not None:
684 field.queryset = field.queryset.filter(serviceClass = request._slice.serviceClass, calendarReservable=True)
685 if len(field.queryset) > 0:
686 field.initial = field.queryset.all()[0]
687 else:
688 field.queryset = field.queryset.none()
689 elif db_field.name == 'sliver':
690 # restrict slivers to those that belong to the slice
691 if request._slice is not None:
692 field.queryset = field.queryset.filter(slice = request._slice)
693 else:
694 field.queryset = field.queryset.none()
695
696 return field
697
698class ReservationChangeForm(forms.ModelForm):
699 class Meta:
700 model = Reservation
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400701 widgets = {
702 'slice' : LinkedSelect
703 }
Scott Baker133c9212013-05-17 09:09:11 -0700704
705class ReservationAddForm(forms.ModelForm):
706 slice = forms.ModelChoiceField(queryset=Slice.objects.all(), widget=forms.Select(attrs={"onChange":"document.getElementById('id_refresh').value=1; submit()"}))
707 refresh = forms.CharField(widget=forms.HiddenInput())
708
709 class Media:
710 css = {'all': ('planetstack.css',)} # .field-refresh { display: none; }
711
712 def clean_slice(self):
713 slice = self.cleaned_data.get("slice")
714 x = ServiceResource.objects.filter(serviceClass = slice.serviceClass, calendarReservable=True)
715 if len(x) == 0:
716 raise forms.ValidationError("The slice you selected does not have a service class that allows reservations")
717 return slice
718
719 class Meta:
720 model = Reservation
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400721 widgets = {
722 'slice' : LinkedSelect
723 }
724
Scott Baker133c9212013-05-17 09:09:11 -0700725
726class ReservationAddRefreshForm(ReservationAddForm):
727 """ This form is displayed when the Reservation Form receives an update
728 from the Slice dropdown onChange handler. It doesn't validate the
729 data and doesn't save the data. This will cause the form to be
730 redrawn.
731 """
732
Scott Baker8737e5f2013-05-17 09:35:32 -0700733 """ don't validate anything other than slice """
734 dont_validate_fields = ("startTime", "duration")
735
Scott Baker133c9212013-05-17 09:09:11 -0700736 def full_clean(self):
737 result = super(ReservationAddForm, self).full_clean()
Scott Baker8737e5f2013-05-17 09:35:32 -0700738
739 for fieldname in self.dont_validate_fields:
740 if fieldname in self._errors:
741 del self._errors[fieldname]
742
Scott Baker133c9212013-05-17 09:09:11 -0700743 return result
744
745 """ don't save anything """
746 def is_valid(self):
747 return False
748
749class ReservationAdmin(admin.ModelAdmin):
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400750 fieldsets = [('Reservation Details', {'fields': ['startTime', 'duration','slice'], 'classes': ['suit-tab suit-tab-general']})]
Scott Baker133c9212013-05-17 09:09:11 -0700751 list_display = ('startTime', 'duration')
Scott Baker133c9212013-05-17 09:09:11 -0700752 form = ReservationAddForm
753
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400754 suit_form_tabs = (('general','Reservation Details'), ('reservedresources','Reserved Resources'))
755
756 inlines = [ReservedResourceInline]
757
Scott Baker133c9212013-05-17 09:09:11 -0700758 def add_view(self, request, form_url='', extra_context=None):
Scott Bakeracd45142013-05-19 16:19:16 -0700759 timezone.activate(request.user.timezone)
Scott Baker133c9212013-05-17 09:09:11 -0700760 request._refresh = False
761 request._slice = None
762 if request.method == 'POST':
Scott Baker8737e5f2013-05-17 09:35:32 -0700763 # "refresh" will be set to "1" if the form was submitted due to
764 # a change in the Slice dropdown.
Scott Baker133c9212013-05-17 09:09:11 -0700765 if request.POST.get("refresh","1") == "1":
766 request._refresh = True
767 request.POST["refresh"] = "0"
Scott Baker8737e5f2013-05-17 09:35:32 -0700768
769 # Keep track of the slice that was selected, so the
770 # reservedResource inline can filter items for the slice.
Scott Baker133c9212013-05-17 09:09:11 -0700771 request._slice = request.POST.get("slice",None)
772 if (request._slice is not None):
773 request._slice = Slice.objects.get(id=request._slice)
774
775 result = super(ReservationAdmin, self).add_view(request, form_url, extra_context)
776 return result
777
Scott Bakeracd45142013-05-19 16:19:16 -0700778 def changelist_view(self, request, extra_context = None):
779 timezone.activate(request.user.timezone)
780 return super(ReservationAdmin, self).changelist_view(request, extra_context)
781
Scott Baker133c9212013-05-17 09:09:11 -0700782 def get_form(self, request, obj=None, **kwargs):
Siobhan Tullyd3515752013-06-21 16:34:53 -0400783 request._obj_ = obj
784 if obj is not None:
785 # For changes, set request._slice to the slice already set in the
786 # object.
787 request._slice = obj.slice
788 self.form = ReservationChangeForm
789 else:
790 if getattr(request, "_refresh", False):
791 self.form = ReservationAddRefreshForm
792 else:
793 self.form = ReservationAddForm
794 return super(ReservationAdmin, self).get_form(request, obj, **kwargs)
795
Scott Baker133c9212013-05-17 09:09:11 -0700796 def get_readonly_fields(self, request, obj=None):
Siobhan Tullyd3515752013-06-21 16:34:53 -0400797 if (obj is not None):
798 # Prevent slice from being changed after the reservation has been
799 # created.
800 return ['slice']
801 else:
Scott Baker133c9212013-05-17 09:09:11 -0700802 return []
Scott Baker3de3e372013-05-10 16:50:44 -0700803
Scott Baker74d8e622013-07-29 16:04:22 -0700804class NetworkParameterTypeAdmin(admin.ModelAdmin):
Scott Baker74d8e622013-07-29 16:04:22 -0700805 list_display = ("name", )
806
807class RouterAdmin(admin.ModelAdmin):
Scott Baker74d8e622013-07-29 16:04:22 -0700808 list_display = ("name", )
809
810class RouterInline(admin.TabularInline):
Scott Baker74d8e622013-07-29 16:04:22 -0700811 model = Router.networks.through
812 extra = 0
813 verbose_name_plural = "Routers"
814 verbose_name = "Router"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400815 suit_classes = 'suit-tab suit-tab-routers'
Scott Baker74d8e622013-07-29 16:04:22 -0700816
817class NetworkParameterInline(generic.GenericTabularInline):
Scott Baker74d8e622013-07-29 16:04:22 -0700818 model = NetworkParameter
819 extra = 1
820 verbose_name_plural = "Parameters"
821 verbose_name = "Parameter"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400822 suit_classes = 'suit-tab suit-tab-netparams'
Scott Baker74d8e622013-07-29 16:04:22 -0700823
824class NetworkSliversInline(admin.TabularInline):
Scott Baker74d8e622013-07-29 16:04:22 -0700825 readonly_fields = ("ip", )
826 model = NetworkSliver
827 extra = 0
828 verbose_name_plural = "Slivers"
829 verbose_name = "Sliver"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400830 suit_classes = 'suit-tab suit-tab-networkslivers'
Scott Baker74d8e622013-07-29 16:04:22 -0700831
Scott Bakerd7d2a392013-08-06 08:57:30 -0700832class NetworkSlicesInline(admin.TabularInline):
Scott Bakerd7d2a392013-08-06 08:57:30 -0700833 model = NetworkSlice
834 extra = 0
835 verbose_name_plural = "Slices"
836 verbose_name = "Slice"
Siobhan Tully2d95e482013-09-06 10:56:06 -0400837 suit_classes = 'suit-tab suit-tab-networkslices'
Scott Bakerd7d2a392013-08-06 08:57:30 -0700838
Scott Baker74d8e622013-07-29 16:04:22 -0700839class NetworkAdmin(admin.ModelAdmin):
Scott Baker74d8e622013-07-29 16:04:22 -0700840 list_display = ("name", "subnet", "ports", "labels")
841 readonly_fields = ("subnet", )
Siobhan Tully2d95e482013-09-06 10:56:06 -0400842
Scott Bakerd7d2a392013-08-06 08:57:30 -0700843 inlines = [NetworkParameterInline, NetworkSliversInline, NetworkSlicesInline, RouterInline]
Scott Baker74d8e622013-07-29 16:04:22 -0700844
Siobhan Tully2d95e482013-09-06 10:56:06 -0400845 fieldsets = [
846 (None, {'fields': ['name','template','ports','labels','owner','guaranteedBandwidth', 'permitAllSlices','permittedSlices','network_id','router_id','subnet_id','subnet'], 'classes':['suit-tab suit-tab-general']}),]
847
848 suit_form_tabs =(
849 ('general','Network Details'),
850 ('netparams', 'Parameters'),
851 ('networkslivers','Slivers'),
852 ('networkslices','Slices'),
853 ('routers','Routers'),
854 )
Scott Baker74d8e622013-07-29 16:04:22 -0700855class NetworkTemplateAdmin(admin.ModelAdmin):
Scott Baker74d8e622013-07-29 16:04:22 -0700856 list_display = ("name", "guaranteedBandwidth", "visibility")
857
Tony Mack31c2b8f2013-04-26 20:01:42 -0400858# register a signal that caches the user's credentials when they log in
859def cache_credentials(sender, user, request, **kwds):
860 auth = {'username': request.POST['username'],
861 'password': request.POST['password']}
862 request.session['auth'] = auth
863user_logged_in.connect(cache_credentials)
864
Siobhan Tully53437282013-04-26 19:30:27 -0400865# Now register the new UserAdmin...
Siobhan Tully30fd4292013-05-10 08:59:56 -0400866admin.site.register(User, UserAdmin)
Siobhan Tully53437282013-04-26 19:30:27 -0400867# ... and, since we're not using Django's builtin permissions,
868# unregister the Group model from admin.
869admin.site.unregister(Group)
870
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400871#Do not show django evolution in the admin interface
872from django_evolution.models import Version, Evolution
873admin.site.unregister(Version)
874admin.site.unregister(Evolution)
875
876
877# When debugging it is often easier to see all the classes, but for regular use
878# only the top-levels should be displayed
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400879showAll = True
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400880
881admin.site.register(Deployment, DeploymentAdmin)
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400882admin.site.register(Site, SiteAdmin)
Siobhan Tully4bc09f22013-04-10 21:15:21 -0400883admin.site.register(Slice, SliceAdmin)
Siobhan Tullyd3515752013-06-21 16:34:53 -0400884admin.site.register(Project, ProjectAdmin)
smbaker43591c32013-06-26 12:43:53 -0700885admin.site.register(ServiceClass, ServiceClassAdmin)
smbakera3cf70c2013-06-27 02:01:41 -0700886admin.site.register(Reservation, ReservationAdmin)
Scott Baker74d8e622013-07-29 16:04:22 -0700887admin.site.register(Network, NetworkAdmin)
888admin.site.register(Router, RouterAdmin)
889admin.site.register(NetworkParameterType, NetworkParameterTypeAdmin)
890admin.site.register(NetworkTemplate, NetworkTemplateAdmin)
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400891
892if showAll:
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400893 #admin.site.register(PlanetStack)
Siobhan Tullyd3515752013-06-21 16:34:53 -0400894 admin.site.register(Tag, TagAdmin)
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400895 admin.site.register(Node, NodeAdmin)
Siobhan Tullybfd11dc2013-09-03 12:59:24 -0400896 #admin.site.register(SlicePrivilege, SlicePrivilegeAdmin)
897 #admin.site.register(SitePrivilege, SitePrivilegeAdmin)
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400898 admin.site.register(Sliver, SliverAdmin)
Siobhan Tullybf1153a2013-05-27 20:53:48 -0400899 admin.site.register(Image, ImageAdmin)
Tony Mack7130ac32013-03-22 21:58:00 -0400900