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
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
16 class ReadonlyTabularInline(admin.TabularInline):
21 def get_readonly_fields(self, request, obj=None):
23 for field in self.model._meta.get_all_field_names():
24 if (not field == 'id'):
25 if (field not in self.editable_fields):
29 def has_add_permission(self, request):
32 class SliverInline(admin.TabularInline):
34 fields = ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']
37 class SiteInline(admin.TabularInline):
41 class SliceInline(admin.TabularInline):
45 class UserInline(admin.TabularInline):
49 class RoleInline(admin.TabularInline):
53 class NodeInline(admin.TabularInline):
57 class PlainTextWidget(forms.Widget):
58 def render(self, _name, value, attrs):
59 return mark_safe(value) if value is not None else ''
61 class PlanetStackBaseAdmin(admin.ModelAdmin):
64 class OSModelAdmin(PlanetStackBaseAdmin):
65 """Attach client connection to openstack on delete() and save()"""
66 def save_model(self, request, obj, form, change):
67 client = OpenStackClient(tenant=request.user.site.login_base, **request.session.get('auth', {}))
68 obj.driver = OpenStackDriver(client=client)
69 obj.caller = request.user
72 def delete_model(self, request, obj):
73 client = OpenStackClient(tenant=request.user.site.login_base, **request.session.get('auth', {}))
74 obj.driver = OpenStackDriver(client=client)
75 obj.caller = request.user
78 class RoleAdmin(OSModelAdmin):
80 ('Role', {'fields': ['role_type']})
82 list_display = ('role_type',)
84 class DeploymentNetworkAdminForm(forms.ModelForm):
85 sites = forms.ModelMultipleChoiceField(
86 queryset=Site.objects.all(),
88 widget=FilteredSelectMultiple(
89 verbose_name=('Sites'), is_stacked=False
93 model = DeploymentNetwork
95 def __init__(self, *args, **kwargs):
96 super(DeploymentNetworkAdminForm, self).__init__(*args, **kwargs)
98 if self.instance and self.instance.pk:
99 self.fields['sites'].initial = self.instance.sites.all()
101 def save(self, commit=True):
102 deploymentNetwork = super(DeploymentNetworkAdminForm, self).save(commit=False)
104 deploymentNetwork.save()
106 if deploymentNetwork.pk:
107 deploymentNetwork.sites = self.cleaned_data['sites']
110 return deploymentNetwork
112 class DeploymentNetworkAdmin(PlanetStackBaseAdmin):
113 form = DeploymentNetworkAdminForm
114 inlines = [NodeInline,]
116 class SiteAdmin(OSModelAdmin):
118 (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base']}),
119 ('Location', {'fields': ['latitude', 'longitude']}),
120 ('Deployment Networks', {'fields': ['deployments']})
122 list_display = ('name', 'login_base','site_url', 'enabled')
123 filter_horizontal = ('deployments',)
124 inlines = [NodeInline,]
125 search_fields = ['name']
127 class SitePrivilegeAdmin(PlanetStackBaseAdmin):
129 (None, {'fields': ['user', 'site', 'role']})
131 list_display = ('user', 'site', 'role')
133 def save_model(self, request, obj, form, change):
134 # update openstack connection to use this site/tenant
135 client = OpenStackClient(tenant=obj.site.login_base, **request.session.get('auth', {}))
136 obj.driver = OpenStackDriver(client=client)
137 obj.caller = request.user
140 def delete_model(self, request, obj):
141 # update openstack connection to use this site/tenant
142 client = OpenStackClient(tenant=obj.site.login_base, **request.session.get('auth', {}))
143 obj.driver = OpenStackDriver(client=client)
144 obj.caller = request.user
147 class KeyAdmin(OSModelAdmin):
149 ('Key', {'fields': ['name', 'key', 'type', 'blacklisted', 'user']})
151 list_display = ['name', 'key', 'type', 'blacklisted', 'user']
153 def get_queryset(self, request):
154 # get keys user is allowed to see
155 qs = super(KeyAdmin, self).get_queryset(request)
156 if request.user.is_superuser:
158 # users can only see their own keys
159 return qs.filter(user=request.user)
162 class SliceAdmin(OSModelAdmin):
163 fields = ['name', 'site', 'instantiation', 'description', 'slice_url']
164 list_display = ('name', 'site','slice_url', 'instantiation')
165 inlines = [SliverInline]
167 def get_queryset(self, request):
168 qs = super(SliceAdmin, self).get_queryset(request)
169 if request.user.is_superuser:
171 # users can only see slices at their site
172 return qs.filter(site=request.user.site)
174 class SliceMembershipAdmin(PlanetStackBaseAdmin):
176 (None, {'fields': ['user', 'slice', 'role']})
178 list_display = ('user', 'slice', 'role')
180 def save_model(self, request, obj, form, change):
181 # update openstack connection to use this slice/tenant
182 client = OpenStackClient(tenant=obj.slice.name, **request.session.get('auth', {}))
183 obj.driver = OpenStackDriver(client=client)
184 obj.caller = request.user
187 def delete_model(self, request, obj):
188 # update openstack connection to use this slice/tenant
189 client = OpenStackClient(tenant=obj.slice.name, **request.session.get('auth', {}))
190 obj.driver = OpenStackDriver(client=client)
191 obj.caller = request.user
194 class SubnetAdmin(PlanetStackBaseAdmin):
195 fields = ['cidr', 'ip_version', 'start', 'end', 'slice']
196 list_display = ('slice','cidr', 'start', 'end', 'ip_version')
198 def save_model(self, request, obj, form, change):
199 # update openstack connection to use this subnet's slice/tenant
200 client = OpenStackClient(tenant=obj.slice.name, **request.session.get('auth', {}))
201 obj.driver = OpenStackDriver(client=client)
202 obj.caller = request.user
205 def delete_model(self, request, obj):
206 # update openstack connection to use this subnet's slice/tenant
207 client = OpenStackClient(tenant=obj.slice.name, **request.session.get('auth', {}))
208 obj.driver = OpenStackDriver(client=client)
209 obj.caller = request.user
212 class ImageAdmin(admin.ModelAdmin):
213 fields = ['image_id', 'name', 'disk_format', 'container_format']
215 class NodeAdmin(admin.ModelAdmin):
216 list_display = ('name', 'site', 'deploymentNetwork')
217 list_filter = ('deploymentNetwork',)
220 class SliverForm(forms.ModelForm):
222 ip = forms.CharField(widget=PlainTextWidget)
225 'ip': PlainTextWidget(),
228 class SliverAdmin(PlanetStackBaseAdmin):
231 ('Sliver', {'fields': ['ip', 'name', 'slice', 'numberCores', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']})
233 list_display = ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']
235 def save_model(self, request, obj, form, change):
236 # update openstack connection to use this sliver's slice/tenant
237 client = OpenStackClient(tenant=obj.slice.name, **request.session.get('auth', {}))
238 obj.driver = OpenStackDriver(client=client)
239 obj.caller = request.user
242 def delete_model(self, request, obj):
243 # update openstack connection to use this sliver's slice/tenant
244 client = OpenStackClient(tenant=obj.slice.name, **request.session.get('auth', {}))
245 obj.driver = OpenStackDriver(client=client)
246 obj.caller = request.user
250 class UserCreationForm(forms.ModelForm):
251 """A form for creating new users. Includes all the required
252 fields, plus a repeated password."""
253 password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
254 password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
258 fields = ('email', 'firstname', 'lastname', 'phone', 'site')
260 def clean_password2(self):
261 # Check that the two password entries match
262 password1 = self.cleaned_data.get("password1")
263 password2 = self.cleaned_data.get("password2")
264 if password1 and password2 and password1 != password2:
265 raise forms.ValidationError("Passwords don't match")
268 def save(self, commit=True):
269 # Save the provided password in hashed format
270 user = super(UserCreationForm, self).save(commit=False)
271 user.set_password(self.cleaned_data["password1"])
277 class UserChangeForm(forms.ModelForm):
278 """A form for updating users. Includes all the fields on
279 the user, but replaces the password field with admin's
280 password hash display field.
282 password = ReadOnlyPasswordHashField()
287 def clean_password(self):
288 # Regardless of what the user provides, return the initial value.
289 # This is done here, rather than on the field, because the
290 # field does not have access to the initial value
291 return self.initial["password"]
294 class PLUserAdmin(UserAdmin, OSModelAdmin):
298 # The forms to add and change user instances
299 form = UserChangeForm
300 add_form = UserCreationForm
302 # The fields to be used in displaying the User model.
303 # These override the definitions on the base UserAdmin
304 # that reference specific fields on auth.User.
305 list_display = ('email', 'site', 'firstname', 'lastname', 'last_login')
306 list_filter = ('site',)
308 (None, {'fields': ('email', 'password')}),
309 ('Personal info', {'fields': ('firstname','lastname','phone','site')}),
310 #('Important dates', {'fields': ('last_login',)}),
314 'classes': ('wide',),
315 'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'password1', 'password2')}
318 search_fields = ('email',)
319 ordering = ('email',)
320 filter_horizontal = ()
322 # register a signal that caches the user's credentials when they log in
323 def cache_credentials(sender, user, request, **kwds):
324 auth = {'username': request.POST['username'],
325 'password': request.POST['password']}
326 request.session['auth'] = auth
327 user_logged_in.connect(cache_credentials)
329 # Now register the new UserAdmin...
330 admin.site.register(PLUser, PLUserAdmin)
331 # ... and, since we're not using Django's builtin permissions,
332 # unregister the Group model from admin.
333 admin.site.unregister(Group)
335 admin.site.register(Site, SiteAdmin)
336 admin.site.register(SitePrivilege, SitePrivilegeAdmin)
337 admin.site.register(Slice, SliceAdmin)
338 admin.site.register(SliceMembership, SliceMembershipAdmin)
339 admin.site.register(Subnet, SubnetAdmin)
340 admin.site.register(Image, ImageAdmin)
341 admin.site.register(Node, NodeAdmin)
342 admin.site.register(Sliver, SliverAdmin)
343 admin.site.register(Flavor)
344 admin.site.register(Key, KeyAdmin)
345 admin.site.register(Role, RoleAdmin)
346 admin.site.register(DeploymentNetwork, DeploymentNetworkAdmin)