1 from core.models import Site
2 from core.models import *
3 from openstack.manager import OpenStackManager
5 from django.contrib import admin
6 from django.contrib.auth.models import Group
7 from django import forms
8 from django.utils.safestring import mark_safe
9 from django.contrib.auth.admin import UserAdmin
10 from django.contrib.admin.widgets import FilteredSelectMultiple
11 from django.contrib.auth.forms import ReadOnlyPasswordHashField
12 from django.contrib.auth.signals import user_logged_in
15 class ReadonlyTabularInline(admin.TabularInline):
20 def get_readonly_fields(self, request, obj=None):
22 for field in self.model._meta.get_all_field_names():
23 if (not field == 'id'):
24 if (field not in self.editable_fields):
28 def has_add_permission(self, request):
31 class SliverInline(admin.TabularInline):
33 fields = ['ip', 'name', 'slice', 'numberCores', 'image', 'key', 'node', 'deploymentNetwork']
36 class SiteInline(admin.TabularInline):
40 class UserInline(admin.TabularInline):
44 class SliceInline(admin.TabularInline):
48 class UserInline(admin.TabularInline):
52 class RoleInline(admin.TabularInline):
56 class NodeInline(admin.TabularInline):
60 class PlainTextWidget(forms.Widget):
61 def render(self, _name, value, attrs):
62 return mark_safe(value) if value is not None else ''
64 class PlanetStackBaseAdmin(admin.ModelAdmin):
67 class OSModelAdmin(PlanetStackBaseAdmin):
68 """Attach client connection to openstack on delete() and save()"""
70 def save_model(self, request, obj, form, change):
71 auth = request.session.get('auth', {})
72 #auth['tenant'] = request.user.site.login_base
73 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
76 def delete_model(self, request, obj):
77 auth = request.session.get('auth', {})
78 #auth['tenant'] = request.user.site.login_base
79 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
82 class RoleAdmin(OSModelAdmin):
84 ('Role', {'fields': ['role_type']})
86 list_display = ('role_type',)
89 class DeploymentNetworkAdminForm(forms.ModelForm):
90 sites = forms.ModelMultipleChoiceField(
91 queryset=Site.objects.all(),
93 widget=FilteredSelectMultiple(
94 verbose_name=('Sites'), is_stacked=False
98 model = DeploymentNetwork
100 def __init__(self, *args, **kwargs):
101 super(DeploymentNetworkAdminForm, self).__init__(*args, **kwargs)
103 if self.instance and self.instance.pk:
104 self.fields['sites'].initial = self.instance.sites.all()
106 def save(self, commit=True):
107 deploymentNetwork = super(DeploymentNetworkAdminForm, self).save(commit=False)
109 deploymentNetwork.save()
111 if deploymentNetwork.pk:
112 deploymentNetwork.sites = self.cleaned_data['sites']
115 return deploymentNetwork
117 class DeploymentNetworkAdmin(PlanetStackBaseAdmin):
118 form = DeploymentNetworkAdminForm
119 inlines = [NodeInline,]
121 def get_formsets(self, request, obj=None):
122 for inline in self.get_inline_instances(request, obj):
123 # hide MyInline in the add view
126 # give inline object access to driver and caller
127 auth = request.session.get('auth', {})
128 auth['tenant'] = request.user.site.login_base
129 inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
130 yield inline.get_formset(request, obj)
132 class SiteAdmin(OSModelAdmin):
134 (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base']}),
135 ('Location', {'fields': ['latitude', 'longitude']}),
136 ('Deployment Networks', {'fields': ['deployments']})
138 list_display = ('name', 'login_base','site_url', 'enabled')
139 filter_horizontal = ('deployments',)
140 inlines = [NodeInline, UserInline]
141 search_fields = ['name']
143 def get_formsets(self, request, obj=None):
144 for inline in self.get_inline_instances(request, obj):
145 # hide MyInline in the add view
148 # give inline object access to driver and caller
149 auth = request.session.get('auth', {})
150 #auth['tenant'] = request.user.site.login_base
151 inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
152 yield inline.get_formset(request, obj)
154 class SitePrivilegeAdmin(PlanetStackBaseAdmin):
156 (None, {'fields': ['user', 'site', 'role']})
158 list_display = ('user', 'site', 'role')
160 def save_model(self, request, obj, form, change):
161 # update openstack connection to use this site/tenant
162 auth = request.session.get('auth', {})
163 #auth['tenant'] = obj.site.login_base
164 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
167 def delete_model(self, request, obj):
168 # update openstack connection to use this site/tenant
169 auth = request.session.get('auth', {})
170 #auth['tenant'] = obj.site.login_base
171 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
174 class KeyAdmin(OSModelAdmin):
176 ('Key', {'fields': ['name', 'key', 'type', 'blacklisted']})
178 list_display = ['name', 'key', 'type', 'blacklisted']
180 def get_queryset(self, request):
181 # get keys user is allowed to see
182 qs = super(KeyAdmin, self).get_queryset(request)
183 if request.user.is_superuser:
185 # users can only see their own keys
186 return qs.filter(user=request.user)
189 class SliceAdmin(OSModelAdmin):
190 fields = ['name', 'site', 'serviceClass', 'description', 'slice_url']
191 list_display = ('name', 'site','serviceClass', 'slice_url')
192 inlines = [SliverInline]
194 def get_formsets(self, request, obj=None):
195 for inline in self.get_inline_instances(request, obj):
196 # hide MyInline in the add view
199 # give inline object access to driver and caller
200 auth = request.session.get('auth', {})
201 auth['tenant'] = obj.name # meed to connect using slice's tenant
202 inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
203 yield inline.get_formset(request, obj)
205 def get_queryset(self, request):
206 qs = super(SliceAdmin, self).get_queryset(request)
207 if request.user.is_superuser:
209 # users can only see slices at their site
210 return qs.filter(site=request.user.site)
212 class SliceMembershipAdmin(PlanetStackBaseAdmin):
214 (None, {'fields': ['user', 'slice', 'role']})
216 list_display = ('user', 'slice', 'role')
218 def save_model(self, request, obj, form, change):
219 # update openstack connection to use this site/tenant
220 auth = request.session.get('auth', {})
221 auth['tenant'] = obj.slice.name
222 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
225 def delete_model(self, request, obj):
226 # update openstack connection to use this site/tenant
227 auth = request.session.get('auth', {})
228 auth['tenant'] = obj.slice.name
229 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
233 class SubnetAdmin(PlanetStackBaseAdmin):
234 fields = ['cidr', 'ip_version', 'start', 'end', 'slice']
235 list_display = ('slice','cidr', 'start', 'end', 'ip_version')
237 def save_model(self, request, obj, form, change):
238 # update openstack connection to use this site/tenant
239 auth = request.session.get('auth', {})
240 auth['tenant'] = obj.slice.name
241 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
244 def delete_model(self, request, obj):
245 # update openstack connection to use this site/tenant
246 auth = request.session.get('auth', {})
247 auth['tenant'] = obj.slice.name
248 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
251 class ImageAdmin(admin.ModelAdmin):
252 fields = ['image_id', 'name', 'disk_format', 'container_format']
254 class NodeAdmin(admin.ModelAdmin):
255 list_display = ('name', 'site', 'deploymentNetwork')
256 list_filter = ('deploymentNetwork',)
259 class SliverForm(forms.ModelForm):
261 ip = forms.CharField(widget=PlainTextWidget)
262 instance_name = forms.CharField(widget=PlainTextWidget)
265 'ip': PlainTextWidget(),
266 'instance_name': PlainTextWidget(),
269 class SliverAdmin(PlanetStackBaseAdmin):
272 ('Sliver', {'fields': ['ip', 'instance_name', 'name', 'slice', 'numberCores', 'image', 'key', 'node', 'deploymentNetwork']})
274 list_display = ['ip', 'instance_name', 'name', 'slice', 'numberCores', 'image', 'key', 'node', 'deploymentNetwork']
276 def save_model(self, request, obj, form, change):
277 # update openstack connection to use this site/tenant
278 auth = request.session.get('auth', {})
279 auth['tenant'] = obj.slice.name
280 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
283 def delete_model(self, request, obj):
284 # update openstack connection to use this site/tenant
285 auth = request.session.get('auth', {})
286 auth['tenant'] = obj.slice.name
287 obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
290 class UserCreationForm(forms.ModelForm):
291 """A form for creating new users. Includes all the required
292 fields, plus a repeated password."""
293 password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
294 password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
298 fields = ('email', 'firstname', 'lastname', 'phone', 'key', 'site')
300 def clean_password2(self):
301 # Check that the two password entries match
302 password1 = self.cleaned_data.get("password1")
303 password2 = self.cleaned_data.get("password2")
304 if password1 and password2 and password1 != password2:
305 raise forms.ValidationError("Passwords don't match")
308 def save(self, commit=True):
309 # Save the provided password in hashed format
310 user = super(UserCreationForm, self).save(commit=False)
311 user.password = self.cleaned_data["password1"]
312 #user.set_password(self.cleaned_data["password1"])
318 class UserChangeForm(forms.ModelForm):
319 """A form for updating users. Includes all the fields on
320 the user, but replaces the password field with admin's
321 password hash display field.
323 password = ReadOnlyPasswordHashField()
328 def clean_password(self):
329 # Regardless of what the user provides, return the initial value.
330 # This is done here, rather than on the field, because the
331 # field does not have access to the initial value
332 return self.initial["password"]
335 class UserAdmin(UserAdmin, OSModelAdmin):
339 # The forms to add and change user instances
340 form = UserChangeForm
341 add_form = UserCreationForm
343 # The fields to be used in displaying the User model.
344 # These override the definitions on the base UserAdmin
345 # that reference specific fields on auth.User.
346 list_display = ('email', 'site', 'firstname', 'lastname', 'last_login')
347 list_filter = ('site',)
349 (None, {'fields': ('email', 'password')}),
350 ('Personal info', {'fields': ('firstname','lastname','phone','site', 'key')}),
351 #('Important dates', {'fields': ('last_login',)}),
355 'classes': ('wide',),
356 'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'password1', 'password2', 'key')}
359 search_fields = ('email',)
360 ordering = ('email',)
361 filter_horizontal = ()
363 # register a signal that caches the user's credentials when they log in
364 def cache_credentials(sender, user, request, **kwds):
365 auth = {'username': request.POST['username'],
366 'password': request.POST['password']}
367 request.session['auth'] = auth
368 user_logged_in.connect(cache_credentials)
370 # Now register the new UserAdmin...
371 admin.site.register(User, UserAdmin)
372 # ... and, since we're not using Django's builtin permissions,
373 # unregister the Group model from admin.
374 admin.site.unregister(Group)
376 admin.site.register(Site, SiteAdmin)
377 #admin.site.register(SitePrivilege, SitePrivilegeAdmin)
378 admin.site.register(Slice, SliceAdmin)
379 #admin.site.register(SliceMembership, SliceMembershipAdmin)
380 admin.site.register(Subnet, SubnetAdmin)
381 #admin.site.register(Image, ImageAdmin)
382 #admin.site.register(Node, NodeAdmin)
383 admin.site.register(Sliver, SliverAdmin)
384 admin.site.register(Key, KeyAdmin)
385 #admin.site.register(Role, RoleAdmin)
386 admin.site.register(DeploymentNetwork, DeploymentNetworkAdmin)