update user admin
[plstackapi.git] / plstackapi / core / admin.py
1 from plstackapi.core.models import Site
2 from plstackapi.core.models import *
3 from plstackapi.openstack.driver import OpenStackDriver
4 from plstackapi.openstack.client import OpenStackClient
5
6 from django.contrib import admin
7 from django.contrib.auth.models import Group
8 from django import forms
9 from django.utils.safestring import mark_safe
10 from django.contrib.auth.admin import UserAdmin
11 from django.contrib.admin.widgets import FilteredSelectMultiple
12 from django.contrib.auth.forms import ReadOnlyPasswordHashField
13 from django.contrib.auth.signals import user_logged_in 
14
15
16 class ReadonlyTabularInline(admin.TabularInline):
17     can_delete = False
18     extra = 0
19     editable_fields = []
20
21     def get_readonly_fields(self, request, obj=None):
22         fields = []
23         for field in self.model._meta.get_all_field_names():
24             if (not field == 'id'):
25                 if (field not in self.editable_fields):
26                     fields.append(field)
27         return fields
28
29     def has_add_permission(self, request):
30         return False
31
32 class SliverInline(admin.TabularInline):
33     model = Sliver
34     fields = ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']
35     extra = 0
36
37 class SiteInline(admin.TabularInline):
38     model = Site
39     extra = 0
40
41 class NodeInline(admin.TabularInline):
42     model = Node
43     extra = 0
44
45 class PlanetStackBaseAdmin(admin.ModelAdmin):
46     save_on_top = False
47
48 class OSModelAdmin(PlanetStackBaseAdmin):
49     """Attach client connection to openstack on delete() and save()""" 
50     def save_model(self, request, obj, form, change):
51         client = OpenStackClient(tenant=request.user.site.login_base, **request.session.get('auth', {}))
52         obj.driver = OpenStackDriver(client=client)
53         obj.save()
54
55     def delete_model(self, request, obj):
56         client = OpenStackClient(tenant=request.user.site.login_base, **request.session.get('auth', {}))
57         obj.driver = OpenStackDriver(client=client)
58         obj.delete()
59     
60
61 class DeploymentNetworkAdminForm(forms.ModelForm):
62     sites = forms.ModelMultipleChoiceField(
63         queryset=Site.objects.all(),
64         required=False,
65         widget=FilteredSelectMultiple(
66             verbose_name=('Sites'), is_stacked=False
67         )
68     )
69     class Meta:
70         model = DeploymentNetwork
71
72     def __init__(self, *args, **kwargs):
73         super(DeploymentNetworkAdminForm, self).__init__(*args, **kwargs)
74
75         if self.instance and self.instance.pk:
76             self.fields['sites'].initial = self.instance.sites.all()
77
78     def save(self, commit=True):
79         deploymentNetwork = super(DeploymentNetworkAdminForm, self).save(commit=False)
80         if commit:
81             deploymentNetwork.save()
82
83         if deploymentNetwork.pk:
84             deploymentNetwork.sites = self.cleaned_data['sites']
85             self.save_m2m()
86
87         return deploymentNetwork
88
89 class DeploymentNetworkAdmin(PlanetStackBaseAdmin):
90     form = DeploymentNetworkAdminForm
91     inlines = [NodeInline,]
92
93 class SiteAdmin(OSModelAdmin):
94     fieldsets = [
95         (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base']}),
96         ('Location', {'fields': ['latitude', 'longitude']}),
97         ('Deployment Networks', {'fields': ['deployments']})
98     ]
99     list_display = ('name', 'login_base','site_url', 'enabled')
100     filter_horizontal = ('deployments',)
101     inlines = [NodeInline,]
102     search_fields = ['name']
103
104 class KeyAdmin(OSModelAdmin):
105     fieldsets = [
106         ('Key', {'fields': ['name', 'key', 'type', 'blacklisted', 'user']})
107     ]
108     list_display = ['name', 'key', 'type', 'blacklisted', 'user']
109
110     def get_queryset(self, request):
111         # get keys user is allowed to see
112         qs = super(KeyAdmin, self).get_queryset(request)
113         if request.user.is_superuser:
114             return qs
115         # users can only see their own keys
116         return qs.filter(user=request.user)  
117         
118
119 class SliceAdmin(OSModelAdmin):
120     fields = ['name', 'site', 'instantiation', 'description', 'slice_url']
121     list_display = ('name', 'site','slice_url', 'instantiation')
122     inlines = [SliverInline]
123
124     def get_queryset(self, request):
125         qs = super(SliceAdmin, self).get_queryset(request)
126         if request.user.is_superuser:
127             return qs
128         # users can only see slices at their site
129         return qs.filter(site=request.user.site) 
130
131 class SubnetAdmin(OSModelAdmin):
132     fields = ['cidr', 'ip_version', 'start', 'end', 'slice']
133     list_display = ('slice','cidr', 'start', 'end', 'ip_version')
134
135 class ImageAdmin(admin.ModelAdmin):
136     fields = ['image_id', 'name', 'disk_format', 'container_format']
137
138 class NodeAdmin(admin.ModelAdmin):
139     list_display = ('name', 'site', 'deploymentNetwork')
140     list_filter = ('deploymentNetwork',)
141
142 class RoleAdmin(OSModelAdmin):
143     fieldsets = [
144         ('Role', {'fields': ['role_type']})
145     ]
146     list_display = ('role_type',)
147
148 class PlainTextWidget(forms.Widget):
149     def render(self, _name, value, attrs):
150         return mark_safe(value) if value is not None else ''
151
152 class SliverForm(forms.ModelForm):
153     class Meta:
154         ip = forms.CharField(widget=PlainTextWidget)
155         model = Sliver
156         widgets = {
157             'ip': PlainTextWidget(),
158         }
159
160 class SliverAdmin(OSModelAdmin):
161     form = SliverForm
162     fieldsets = [
163         ('Sliver', {'fields': ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']})
164     ]
165     list_display = ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']
166
167     def save_model(self, request, obj, form, change):
168         client = OpenStackClient(tenant=obj.slice.name, **request.session.get('auth', {}))
169         obj.driver = OpenStackDriver(client=client)
170         obj.save()
171
172     def delete_model(self, request, obj):
173         client = OpenStackClient(tenant=obj.slice.name, **request.session.get('auth', {}))
174         obj.driver = OpenStackDriver(client=client)
175         obj.delete()
176      
177
178 class UserCreationForm(forms.ModelForm):
179     """A form for creating new users. Includes all the required
180     fields, plus a repeated password."""
181     password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
182     password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
183
184     class Meta:
185         model = PLUser
186         fields = ('email', 'firstname', 'lastname', 'phone', 'site')
187
188     def clean_password2(self):
189         # Check that the two password entries match
190         password1 = self.cleaned_data.get("password1")
191         password2 = self.cleaned_data.get("password2")
192         if password1 and password2 and password1 != password2:
193             raise forms.ValidationError("Passwords don't match")
194         return password2
195
196     def save(self, commit=True):
197         # Save the provided password in hashed format
198         user = super(UserCreationForm, self).save(commit=False)
199         user.set_password(self.cleaned_data["password1"])
200         if commit:
201             user.save()
202         return user
203
204
205 class UserChangeForm(forms.ModelForm):
206     """A form for updating users. Includes all the fields on
207     the user, but replaces the password field with admin's
208     password hash display field.
209     """
210     password = ReadOnlyPasswordHashField()
211
212     class Meta:
213         model = PLUser
214
215     def clean_password(self):
216         # Regardless of what the user provides, return the initial value.
217         # This is done here, rather than on the field, because the
218         # field does not have access to the initial value
219         return self.initial["password"]
220
221
222 class PLUserAdmin(UserAdmin, OSModelAdmin):
223     class Meta:
224         app_label = "core"
225
226     # The forms to add and change user instances
227     form = UserChangeForm
228     add_form = UserCreationForm
229
230     # The fields to be used in displaying the User model.
231     # These override the definitions on the base UserAdmin
232     # that reference specific fields on auth.User.
233     list_display = ('email', 'site', 'firstname', 'lastname', 'last_login')
234     list_filter = ('site',)
235     fieldsets = (
236         (None, {'fields': ('email', 'password')}),
237         ('Personal info', {'fields': ('firstname','lastname','phone','site')}),
238         #('Important dates', {'fields': ('last_login',)}),
239     )
240     add_fieldsets = (
241         (None, {
242             'classes': ('wide',),
243             'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'password1', 'password2')}
244         ),
245     )
246     search_fields = ('email',)
247     ordering = ('email',)
248     filter_horizontal = ()
249
250 # register a signal that caches the user's credentials when they log in
251 def cache_credentials(sender, user, request, **kwds):
252     auth = {'username': request.POST['username'],
253             'password': request.POST['password']}
254     request.session['auth'] = auth
255 user_logged_in.connect(cache_credentials)
256
257 # Now register the new UserAdmin...
258 admin.site.register(PLUser, PLUserAdmin)
259 # ... and, since we're not using Django's builtin permissions,
260 # unregister the Group model from admin.
261 admin.site.unregister(Group)
262
263 admin.site.register(Site, SiteAdmin)
264 admin.site.register(SitePrivilege)
265 admin.site.register(Slice, SliceAdmin)
266 admin.site.register(SliceMembership)
267 admin.site.register(Subnet, SubnetAdmin)
268 admin.site.register(Image, ImageAdmin)
269 admin.site.register(Node, NodeAdmin)
270 admin.site.register(Sliver, SliverAdmin)
271 admin.site.register(Flavor)
272 admin.site.register(Key, KeyAdmin)
273 admin.site.register(Role, RoleAdmin)
274 admin.site.register(DeploymentNetwork, DeploymentNetworkAdmin)
275