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']
168 class UserCreationForm(forms.ModelForm):
169 """A form for creating new users. Includes all the required
170 fields, plus a repeated password."""
171 password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
172 password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
176 fields = ('email', 'firstname', 'lastname', 'phone', 'site')
178 def clean_password2(self):
179 # Check that the two password entries match
180 password1 = self.cleaned_data.get("password1")
181 password2 = self.cleaned_data.get("password2")
182 if password1 and password2 and password1 != password2:
183 raise forms.ValidationError("Passwords don't match")
186 def save(self, commit=True):
187 # Save the provided password in hashed format
188 user = super(UserCreationForm, self).save(commit=False)
189 user.set_password(self.cleaned_data["password1"])
195 class UserChangeForm(forms.ModelForm):
196 """A form for updating users. Includes all the fields on
197 the user, but replaces the password field with admin's
198 password hash display field.
200 password = ReadOnlyPasswordHashField()
205 def clean_password(self):
206 # Regardless of what the user provides, return the initial value.
207 # This is done here, rather than on the field, because the
208 # field does not have access to the initial value
209 return self.initial["password"]
212 class PLUserAdmin(UserAdmin):
216 # The forms to add and change user instances
217 form = UserChangeForm
218 add_form = UserCreationForm
220 # The fields to be used in displaying the User model.
221 # These override the definitions on the base UserAdmin
222 # that reference specific fields on auth.User.
223 list_display = ('email', 'site', 'firstname', 'lastname', 'last_login')
224 list_filter = ('site',)
226 (None, {'fields': ('email', 'password')}),
227 ('Personal info', {'fields': ('firstname','lastname','phone','site')}),
228 #('Important dates', {'fields': ('last_login',)}),
232 'classes': ('wide',),
233 'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'password1', 'password2')}
236 search_fields = ('email',)
237 ordering = ('email',)
238 filter_horizontal = ()
240 # register a signal that caches the user's credentials when they log in
241 def cache_credentials(sender, user, request, **kwds):
242 auth = {'username': request.POST['username'],
243 'password': request.POST['password']}
244 request.session['auth'] = auth
245 user_logged_in.connect(cache_credentials)
247 # Now register the new UserAdmin...
248 admin.site.register(PLUser, PLUserAdmin)
249 # ... and, since we're not using Django's builtin permissions,
250 # unregister the Group model from admin.
251 admin.site.unregister(Group)
253 admin.site.register(Site, SiteAdmin)
254 admin.site.register(SitePrivilege)
255 admin.site.register(Slice, SliceAdmin)
256 admin.site.register(SliceMembership)
257 admin.site.register(Subnet, SubnetAdmin)
258 admin.site.register(Image, ImageAdmin)
259 admin.site.register(Node, NodeAdmin)
260 admin.site.register(Sliver, SliverAdmin)
261 admin.site.register(Flavor)
262 admin.site.register(Key, KeyAdmin)
263 admin.site.register(Role, RoleAdmin)
264 admin.site.register(DeploymentNetwork, DeploymentNetworkAdmin)