remove SubnetAdmin
[plstackapi.git] / plstackapi / core / admin.py
1 from plstackapi.core.models import Site
2 from plstackapi.core.models import *
3 from plstackapi.openstack.manager import OpenStackManager
4
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 
13
14
15 class ReadonlyTabularInline(admin.TabularInline):
16     can_delete = False
17     extra = 0
18     editable_fields = []
19
20     def get_readonly_fields(self, request, obj=None):
21         fields = []
22         for field in self.model._meta.get_all_field_names():
23             if (not field == 'id'):
24                 if (field not in self.editable_fields):
25                     fields.append(field)
26         return fields
27
28     def has_add_permission(self, request):
29         return False
30
31 class SliverInline(admin.TabularInline):
32     model = Sliver
33     fields = ['ip', 'name', 'slice', 'numberCores', 'image', 'key', 'node', 'deploymentNetwork']
34     extra = 0
35
36 class SiteInline(admin.TabularInline):
37     model = Site
38     extra = 0
39
40 class SliceInline(admin.TabularInline):
41     model = Slice
42     extra = 0
43
44 class UserInline(admin.TabularInline):
45     model = PLUser
46     extra = 0
47
48 class RoleInline(admin.TabularInline):
49     model = Role
50     extra = 0 
51
52 class NodeInline(admin.TabularInline):
53     model = Node
54     extra = 0
55
56 class PlainTextWidget(forms.HiddenInput):
57     input_type = 'hidden'
58
59     def render(self, name, value, attrs=None):
60         if value is None:
61             value = ''
62         return mark_safe(value + super(PlainTextWidget, self).render(name, value, attrs))
63
64 class PlanetStackBaseAdmin(admin.ModelAdmin):
65     save_on_top = False
66
67 class OSModelAdmin(PlanetStackBaseAdmin):
68     """Attach client connection to openstack on delete() and save()"""
69
70     def save_model(self, request, obj, form, change):
71         if request.user.site:
72             auth = request.session.get('auth', {})
73             auth['tenant'] = request.user.site.login_base
74             obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
75         obj.save()
76
77     def delete_model(self, request, obj):
78         if request.user.site:
79             auth = request.session.get('auth', {})
80             auth['tenant'] = request.user.site.login_base
81             obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
82         obj.delete() 
83
84 class RoleAdmin(OSModelAdmin):
85     fieldsets = [
86         ('Role', {'fields': ['role_type']})
87     ]
88     list_display = ('role_type',)
89
90
91 class DeploymentNetworkAdminForm(forms.ModelForm):
92     sites = forms.ModelMultipleChoiceField(
93         queryset=Site.objects.all(),
94         required=False,
95         widget=FilteredSelectMultiple(
96             verbose_name=('Sites'), is_stacked=False
97         )
98     )
99     class Meta:
100         model = DeploymentNetwork
101
102     def __init__(self, *args, **kwargs):
103         super(DeploymentNetworkAdminForm, self).__init__(*args, **kwargs)
104
105         if self.instance and self.instance.pk:
106             self.fields['sites'].initial = self.instance.sites.all()
107
108     def save(self, commit=True):
109         deploymentNetwork = super(DeploymentNetworkAdminForm, self).save(commit=False)
110         if commit:
111             deploymentNetwork.save()
112
113         if deploymentNetwork.pk:
114             deploymentNetwork.sites = self.cleaned_data['sites']
115             self.save_m2m()
116
117         return deploymentNetwork
118
119 class DeploymentNetworkAdmin(PlanetStackBaseAdmin):
120     form = DeploymentNetworkAdminForm
121     inlines = [NodeInline,]
122
123     def get_formsets(self, request, obj=None):
124         for inline in self.get_inline_instances(request, obj):
125             # hide MyInline in the add view
126             if obj is None:
127                 continue
128             # give inline object access to driver and caller
129             auth = request.session.get('auth', {})
130             auth['tenant'] = request.user.site.login_base
131             inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
132             yield inline.get_formset(request, obj)
133
134 class SiteAdmin(OSModelAdmin):
135     fieldsets = [
136         (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base']}),
137         ('Location', {'fields': ['latitude', 'longitude']}),
138         ('Deployment Networks', {'fields': ['deployments']})
139     ]
140     list_display = ('name', 'login_base','site_url', 'enabled')
141     filter_horizontal = ('deployments',)
142     inlines = [NodeInline,]
143     search_fields = ['name']
144
145     def get_formsets(self, request, obj=None):
146         for inline in self.get_inline_instances(request, obj):
147             # hide MyInline in the add view
148             if obj is None:
149                 continue
150             # give inline object access to driver and caller
151             auth = request.session.get('auth', {})
152             auth['tenant'] = request.user.site.login_base
153             inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
154             yield inline.get_formset(request, obj)
155
156 class SitePrivilegeAdmin(PlanetStackBaseAdmin):
157     fieldsets = [
158         (None, {'fields': ['user', 'site', 'role']})
159     ]
160     list_display = ('user', 'site', 'role')
161
162     def save_model(self, request, obj, form, change):
163         # update openstack connection to use this site/tenant   
164         auth = request.session.get('auth', {})
165         auth['tenant'] = obj.site.login_base
166         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
167         obj.save()
168
169     def delete_model(self, request, obj):
170         # update openstack connection to use this site/tenant   
171         auth = request.session.get('auth', {})
172         auth['tenant'] = obj.site.login_base
173         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
174         obj.delete()
175
176 class KeyAdmin(OSModelAdmin):
177     fieldsets = [
178         ('Key', {'fields': ['name', 'key', 'type', 'blacklisted', 'user']})
179     ]
180     list_display = ['name', 'key', 'type', 'blacklisted', 'user']
181
182     def get_queryset(self, request):
183         # get keys user is allowed to see
184         qs = super(KeyAdmin, self).get_queryset(request)
185         if request.user.is_superuser:
186             return qs
187         # users can only see their own keys
188         return qs.filter(user=request.user)  
189         
190
191 class SliceAdmin(OSModelAdmin):
192     fields = ['name', 'site', 'serviceClass', 'description', 'slice_url']
193     list_display = ('name', 'site','serviceClass', 'slice_url')
194     inlines = [SliverInline]
195
196     def get_formsets(self, request, obj=None):
197         for inline in self.get_inline_instances(request, obj):
198             # hide MyInline in the add view
199             if obj is None:
200                 continue
201             # give inline object access to driver and caller
202             auth = request.session.get('auth', {})
203             auth['tenant'] = obj.name       # meed to connect using slice's tenant
204             inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
205             yield inline.get_formset(request, obj)
206
207     def get_queryset(self, request):
208         qs = super(SliceAdmin, self).get_queryset(request)
209         if request.user.is_superuser:
210             return qs
211         # users can only see slices at their site
212         return qs.filter(site=request.user.site) 
213
214 class SliceMembershipAdmin(PlanetStackBaseAdmin):
215     fieldsets = [
216         (None, {'fields': ['user', 'slice', 'role']})
217     ]
218     list_display = ('user', 'slice', 'role')
219
220     def save_model(self, request, obj, form, change):
221         # update openstack connection to use this site/tenant
222         auth = request.session.get('auth', {})
223         auth['tenant'] = obj.slice.name
224         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
225         obj.save()
226
227     def delete_model(self, request, obj):
228         # update openstack connection to use this site/tenant
229         auth = request.session.get('auth', {})
230         auth['tenant'] = obj.slice.name
231         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
232         obj.delete()
233
234
235 class ImageAdmin(admin.ModelAdmin):
236     fields = ['image_id', 'name', 'disk_format', 'container_format']
237
238 class NodeAdmin(admin.ModelAdmin):
239     list_display = ('name', 'site', 'deploymentNetwork')
240     list_filter = ('deploymentNetwork',)
241
242
243 class SliverForm(forms.ModelForm):
244     class Meta:
245         ip = forms.CharField(widget=PlainTextWidget)
246         instance_name = forms.CharField(widget=PlainTextWidget)
247         model = Sliver
248         widgets = {
249             'ip': PlainTextWidget(),
250             'instance_name': PlainTextWidget(),
251         }
252
253 class SliverAdmin(PlanetStackBaseAdmin):
254     form = SliverForm
255     fieldsets = [
256         ('Sliver', {'fields': ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'key', 'node', 'deploymentNetwork']})
257     ]
258     list_display = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'key', 'node', 'deploymentNetwork']
259
260     def save_model(self, request, obj, form, change):
261         # update openstack connection to use this site/tenant
262         auth = request.session.get('auth', {})
263         auth['tenant'] = obj.slice.name
264         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
265         obj.save()
266
267     def delete_model(self, request, obj):
268         # update openstack connection to use this site/tenant
269         auth = request.session.get('auth', {})
270         auth['tenant'] = obj.slice.name
271         obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
272         obj.delete()
273
274 class UserCreationForm(forms.ModelForm):
275     """A form for creating new users. Includes all the required
276     fields, plus a repeated password."""
277     password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
278     password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
279
280     class Meta:
281         model = PLUser
282         fields = ('email', 'firstname', 'lastname', 'phone', 'site')
283
284     def clean_password2(self):
285         # Check that the two password entries match
286         password1 = self.cleaned_data.get("password1")
287         password2 = self.cleaned_data.get("password2")
288         if password1 and password2 and password1 != password2:
289             raise forms.ValidationError("Passwords don't match")
290         return password2
291
292     def save(self, commit=True):
293         # Save the provided password in hashed format
294         user = super(UserCreationForm, self).save(commit=False)
295         user.password = self.cleaned_data["password1"]
296         #user.set_password(self.cleaned_data["password1"])
297         if commit:
298             user.save()
299         return user
300
301
302 class UserChangeForm(forms.ModelForm):
303     """A form for updating users. Includes all the fields on
304     the user, but replaces the password field with admin's
305     password hash display field.
306     """
307     password = ReadOnlyPasswordHashField()
308
309     class Meta:
310         model = PLUser
311
312     def clean_password(self):
313         # Regardless of what the user provides, return the initial value.
314         # This is done here, rather than on the field, because the
315         # field does not have access to the initial value
316         return self.initial["password"]
317
318
319 class PLUserAdmin(UserAdmin, OSModelAdmin):
320     class Meta:
321         app_label = "core"
322
323     # The forms to add and change user instances
324     form = UserChangeForm
325     add_form = UserCreationForm
326
327     # The fields to be used in displaying the User model.
328     # These override the definitions on the base UserAdmin
329     # that reference specific fields on auth.User.
330     list_display = ('email', 'site', 'firstname', 'lastname', 'last_login')
331     list_filter = ('site',)
332     fieldsets = (
333         (None, {'fields': ('email', 'password')}),
334         ('Personal info', {'fields': ('firstname','lastname','phone','site')}),
335         #('Important dates', {'fields': ('last_login',)}),
336     )
337     add_fieldsets = (
338         (None, {
339             'classes': ('wide',),
340             'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'password1', 'password2')}
341         ),
342     )
343     search_fields = ('email',)
344     ordering = ('email',)
345     filter_horizontal = ()
346
347 # register a signal that caches the user's credentials when they log in
348 def cache_credentials(sender, user, request, **kwds):
349     auth = {'username': request.POST['username'],
350             'password': request.POST['password']}
351     request.session['auth'] = auth
352 user_logged_in.connect(cache_credentials)
353
354 # Now register the new UserAdmin...
355 admin.site.register(PLUser, PLUserAdmin)
356 # ... and, since we're not using Django's builtin permissions,
357 # unregister the Group model from admin.
358 admin.site.unregister(Group)
359
360 admin.site.register(Site, SiteAdmin)
361 admin.site.register(SitePrivilege, SitePrivilegeAdmin)
362 admin.site.register(Slice, SliceAdmin)
363 admin.site.register(SliceMembership, SliceMembershipAdmin)
364 admin.site.register(Image, ImageAdmin)
365 admin.site.register(Node, NodeAdmin)
366 admin.site.register(Sliver, SliverAdmin)
367 admin.site.register(Key, KeyAdmin)
368 admin.site.register(Role, RoleAdmin)
369 admin.site.register(DeploymentNetwork, DeploymentNetworkAdmin)
370