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 NodeInline(admin.TabularInline):
45 class PlanetStackBaseAdmin(admin.ModelAdmin):
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)
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)
61 class DeploymentNetworkAdminForm(forms.ModelForm):
62 sites = forms.ModelMultipleChoiceField(
63 queryset=Site.objects.all(),
65 widget=FilteredSelectMultiple(
66 verbose_name=('Sites'), is_stacked=False
70 model = DeploymentNetwork
72 def __init__(self, *args, **kwargs):
73 super(DeploymentNetworkAdminForm, self).__init__(*args, **kwargs)
75 if self.instance and self.instance.pk:
76 self.fields['sites'].initial = self.instance.sites.all()
78 def save(self, commit=True):
79 deploymentNetwork = super(DeploymentNetworkAdminForm, self).save(commit=False)
81 deploymentNetwork.save()
83 if deploymentNetwork.pk:
84 deploymentNetwork.sites = self.cleaned_data['sites']
87 return deploymentNetwork
89 class DeploymentNetworkAdmin(PlanetStackBaseAdmin):
90 form = DeploymentNetworkAdminForm
91 inlines = [NodeInline,]
93 class SiteAdmin(OSModelAdmin):
95 (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base']}),
96 ('Location', {'fields': ['latitude', 'longitude']}),
97 ('Deployment Networks', {'fields': ['deployments']})
99 list_display = ('name', 'login_base','site_url', 'enabled')
100 filter_horizontal = ('deployments',)
101 inlines = [NodeInline,]
102 search_fields = ['name']
104 class KeyAdmin(OSModelAdmin):
106 ('Key', {'fields': ['name', 'key', 'type', 'blacklisted', 'user']})
108 list_display = ['name', 'key', 'type', 'blacklisted', 'user']
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:
115 # users can only see their own keys
116 return qs.filter(user=request.user)
119 class SliceAdmin(OSModelAdmin):
120 fields = ['name', 'site', 'instantiation', 'description', 'slice_url']
121 list_display = ('name', 'site','slice_url', 'instantiation')
122 inlines = [SliverInline]
124 def get_queryset(self, request):
125 qs = super(SliceAdmin, self).get_queryset(request)
126 if request.user.is_superuser:
128 # users can only see slices at their site
129 return qs.filter(site=request.user.site)
131 class SubnetAdmin(OSModelAdmin):
132 fields = ['cidr', 'ip_version', 'start', 'end', 'slice']
133 list_display = ('slice','cidr', 'start', 'end', 'ip_version')
135 class ImageAdmin(admin.ModelAdmin):
136 fields = ['image_id', 'name', 'disk_format', 'container_format']
138 class NodeAdmin(admin.ModelAdmin):
139 list_display = ('name', 'site', 'deploymentNetwork')
140 list_filter = ('deploymentNetwork',)
142 class RoleAdmin(OSModelAdmin):
144 ('Role', {'fields': ['role_type']})
146 list_display = ('role_type',)
148 class PlainTextWidget(forms.Widget):
149 def render(self, _name, value, attrs):
150 return mark_safe(value) if value is not None else ''
152 class SliverForm(forms.ModelForm):
154 ip = forms.CharField(widget=PlainTextWidget)
157 'ip': PlainTextWidget(),
160 class SliverAdmin(OSModelAdmin):
163 ('Sliver', {'fields': ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']})
165 list_display = ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']
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)
172 def delete_model(self, request, obj):
173 client = OpenStackClient(tenant=obj.slice.name, **request.session.get('auth', {}))
174 obj.driver = OpenStackDriver(client=client)
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)
186 fields = ('email', 'firstname', 'lastname', 'phone', 'site')
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")
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"])
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.
210 password = ReadOnlyPasswordHashField()
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"]
222 class PLUserAdmin(UserAdmin, OSModelAdmin):
226 # The forms to add and change user instances
227 form = UserChangeForm
228 add_form = UserCreationForm
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',)
236 (None, {'fields': ('email', 'password')}),
237 ('Personal info', {'fields': ('firstname','lastname','phone','site')}),
238 #('Important dates', {'fields': ('last_login',)}),
242 'classes': ('wide',),
243 'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'password1', 'password2')}
246 search_fields = ('email',)
247 ordering = ('email',)
248 filter_horizontal = ()
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)
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)
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)