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 PlanetStackBaseAdmin(admin.ModelAdmin):
60 class OSModelAdmin(PlanetStackBaseAdmin):
61 """Attach client connection to openstack on delete() and save()"""
62 def save_model(self, request, obj, form, change):
63 client = OpenStackClient(tenant=request.user.site.login_base, **request.session.get('auth', {}))
64 obj.driver = OpenStackDriver(client=client)
67 def delete_model(self, request, obj):
68 client = OpenStackClient(tenant=request.user.site.login_base, **request.session.get('auth', {}))
69 obj.driver = OpenStackDriver(client=client)
73 class DeploymentNetworkAdminForm(forms.ModelForm):
74 sites = forms.ModelMultipleChoiceField(
75 queryset=Site.objects.all(),
77 widget=FilteredSelectMultiple(
78 verbose_name=('Sites'), is_stacked=False
82 model = DeploymentNetwork
84 def __init__(self, *args, **kwargs):
85 super(DeploymentNetworkAdminForm, self).__init__(*args, **kwargs)
87 if self.instance and self.instance.pk:
88 self.fields['sites'].initial = self.instance.sites.all()
90 def save(self, commit=True):
91 deploymentNetwork = super(DeploymentNetworkAdminForm, self).save(commit=False)
93 deploymentNetwork.save()
95 if deploymentNetwork.pk:
96 deploymentNetwork.sites = self.cleaned_data['sites']
99 return deploymentNetwork
101 class DeploymentNetworkAdmin(PlanetStackBaseAdmin):
102 form = DeploymentNetworkAdminForm
103 inlines = [NodeInline,]
105 class SiteAdmin(OSModelAdmin):
107 (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base']}),
108 ('Location', {'fields': ['latitude', 'longitude']}),
109 ('Deployment Networks', {'fields': ['deployments']})
111 list_display = ('name', 'login_base','site_url', 'enabled')
112 filter_horizontal = ('deployments',)
113 inlines = [NodeInline,]
114 search_fields = ['name']
116 class SitePrivilegeAdmin(OSModelAdmin):
118 (None, {'fields': ['user', 'site', 'role']})
120 list_display = ('user', 'site', 'role')
122 class KeyAdmin(OSModelAdmin):
124 ('Key', {'fields': ['name', 'key', 'type', 'blacklisted', 'user']})
126 list_display = ['name', 'key', 'type', 'blacklisted', 'user']
128 def get_queryset(self, request):
129 # get keys user is allowed to see
130 qs = super(KeyAdmin, self).get_queryset(request)
131 if request.user.is_superuser:
133 # users can only see their own keys
134 return qs.filter(user=request.user)
137 class SliceAdmin(OSModelAdmin):
138 fields = ['name', 'site', 'instantiation', 'description', 'slice_url']
139 list_display = ('name', 'site','slice_url', 'instantiation')
140 inlines = [SliverInline]
142 def get_queryset(self, request):
143 qs = super(SliceAdmin, self).get_queryset(request)
144 if request.user.is_superuser:
146 # users can only see slices at their site
147 return qs.filter(site=request.user.site)
149 class SliceMembershipAdmin(OSModelAdmin):
151 (None, {'fields': ['user', 'slice', 'role']})
153 list_display = ('user', 'slice', 'role')
154 inlines = [UserInline, SliceInline, RoleInline]
156 class SubnetAdmin(OSModelAdmin):
157 fields = ['cidr', 'ip_version', 'start', 'end', 'slice']
158 list_display = ('slice','cidr', 'start', 'end', 'ip_version')
160 class ImageAdmin(admin.ModelAdmin):
161 fields = ['image_id', 'name', 'disk_format', 'container_format']
163 class NodeAdmin(admin.ModelAdmin):
164 list_display = ('name', 'site', 'deploymentNetwork')
165 list_filter = ('deploymentNetwork',)
167 class RoleAdmin(OSModelAdmin):
169 ('Role', {'fields': ['role_type']})
171 list_display = ('role_type',)
173 class PlainTextWidget(forms.Widget):
174 def render(self, _name, value, attrs):
175 return mark_safe(value) if value is not None else ''
177 class SliverForm(forms.ModelForm):
179 ip = forms.CharField(widget=PlainTextWidget)
182 'ip': PlainTextWidget(),
185 class SliverAdmin(OSModelAdmin):
188 ('Sliver', {'fields': ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']})
190 list_display = ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']
192 def save_model(self, request, obj, form, change):
193 client = OpenStackClient(tenant=obj.slice.name, **request.session.get('auth', {}))
194 obj.driver = OpenStackDriver(client=client)
197 def delete_model(self, request, obj):
198 client = OpenStackClient(tenant=obj.slice.name, **request.session.get('auth', {}))
199 obj.driver = OpenStackDriver(client=client)
203 class UserCreationForm(forms.ModelForm):
204 """A form for creating new users. Includes all the required
205 fields, plus a repeated password."""
206 password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
207 password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
211 fields = ('email', 'firstname', 'lastname', 'phone', 'site')
213 def clean_password2(self):
214 # Check that the two password entries match
215 password1 = self.cleaned_data.get("password1")
216 password2 = self.cleaned_data.get("password2")
217 if password1 and password2 and password1 != password2:
218 raise forms.ValidationError("Passwords don't match")
221 def save(self, commit=True):
222 # Save the provided password in hashed format
223 user = super(UserCreationForm, self).save(commit=False)
224 user.set_password(self.cleaned_data["password1"])
230 class UserChangeForm(forms.ModelForm):
231 """A form for updating users. Includes all the fields on
232 the user, but replaces the password field with admin's
233 password hash display field.
235 password = ReadOnlyPasswordHashField()
240 def clean_password(self):
241 # Regardless of what the user provides, return the initial value.
242 # This is done here, rather than on the field, because the
243 # field does not have access to the initial value
244 return self.initial["password"]
247 class PLUserAdmin(UserAdmin, OSModelAdmin):
251 # The forms to add and change user instances
252 form = UserChangeForm
253 add_form = UserCreationForm
255 # The fields to be used in displaying the User model.
256 # These override the definitions on the base UserAdmin
257 # that reference specific fields on auth.User.
258 list_display = ('email', 'site', 'firstname', 'lastname', 'last_login')
259 list_filter = ('site',)
261 (None, {'fields': ('email', 'password')}),
262 ('Personal info', {'fields': ('firstname','lastname','phone','site')}),
263 #('Important dates', {'fields': ('last_login',)}),
267 'classes': ('wide',),
268 'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'password1', 'password2')}
271 search_fields = ('email',)
272 ordering = ('email',)
273 filter_horizontal = ()
275 # register a signal that caches the user's credentials when they log in
276 def cache_credentials(sender, user, request, **kwds):
277 auth = {'username': request.POST['username'],
278 'password': request.POST['password']}
279 request.session['auth'] = auth
280 user_logged_in.connect(cache_credentials)
282 # Now register the new UserAdmin...
283 admin.site.register(PLUser, PLUserAdmin)
284 # ... and, since we're not using Django's builtin permissions,
285 # unregister the Group model from admin.
286 admin.site.unregister(Group)
288 admin.site.register(Site, SiteAdmin)
289 admin.site.register(SitePrivilege, SitePrivilegeAdmin)
290 admin.site.register(Slice, SliceAdmin)
291 admin.site.register(SliceMembership, SliceMembershipAdmin)
292 admin.site.register(Subnet, SubnetAdmin)
293 admin.site.register(Image, ImageAdmin)
294 admin.site.register(Node, NodeAdmin)
295 admin.site.register(Sliver, SliverAdmin)
296 admin.site.register(Flavor)
297 admin.site.register(Key, KeyAdmin)
298 admin.site.register(Role, RoleAdmin)
299 admin.site.register(DeploymentNetwork, DeploymentNetworkAdmin)