bug fixes
[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 DeploymentNetworkAdminForm(forms.ModelForm):
49     sites = forms.ModelMultipleChoiceField(
50         queryset=Site.objects.all(),
51         required=False,
52         widget=FilteredSelectMultiple(
53             verbose_name=('Sites'), is_stacked=False
54         )
55     )
56     class Meta:
57         model = DeploymentNetwork
58
59     def __init__(self, *args, **kwargs):
60         super(DeploymentNetworkAdminForm, self).__init__(*args, **kwargs)
61
62         if self.instance and self.instance.pk:
63             self.fields['sites'].initial = self.instance.sites.all()
64
65     def save(self, commit=True):
66         deploymentNetwork = super(DeploymentNetworkAdminForm, self).save(commit=False)
67         if commit:
68             deploymentNetwork.save()
69
70         if deploymentNetwork.pk:
71             deploymentNetwork.sites = self.cleaned_data['sites']
72             self.save_m2m()
73
74         return deploymentNetwork
75
76 class DeploymentNetworkAdmin(PlanetStackBaseAdmin):
77     form = DeploymentNetworkAdminForm
78     inlines = [NodeInline,]
79
80 class SiteAdmin(admin.ModelAdmin):
81     fieldsets = [
82         (None, {'fields': ['name', 'site_url', 'enabled', 'is_public', 'login_base']}),
83         ('Location', {'fields': ['latitude', 'longitude']}),
84         ('Deployment Networks', {'fields': ['deployments']})
85     ]
86     list_display = ('name', 'login_base','site_url', 'enabled')
87     filter_horizontal = ('deployments',)
88     inlines = [NodeInline,]
89     search_fields = ['name']
90
91 class KeyAdmin(admin.ModelAdmin):
92     fieldsets = [
93         ('Key', {'fields': ['name', 'key', 'type', 'blacklisted', 'user']})
94     ]
95     list_display = ['name', 'key', 'type', 'blacklisted', 'user']
96
97     def save_model(self, request, obj, form, change):
98         # attach the caller's openstack clien connection to the object 
99         client = OpenStackClient(tenant=request.user.site.login_base, **request.session.get('auth', {}))
100         obj.driver = OpenStackDriver(client=client)
101         obj.save()
102
103     def delete_model(self, request, obj):
104         client = OpenStackClient(tenant=request.user.site.login_base, **request.session.get('auth', {}))
105         obj.driver = OpenStackDriver(client=client)
106         obj.delete()
107
108 class SliceAdmin(PlanetStackBaseAdmin):
109     fields = ['name', 'site', 'instantiation', 'description', 'slice_url']
110     list_display = ('name', 'site','slice_url', 'instantiation')
111     inlines = [SliverInline]
112
113 class SubnetAdmin(admin.ModelAdmin):
114     fields = ['cidr', 'ip_version', 'start', 'end', 'slice']
115     list_display = ('slice','cidr', 'start', 'end', 'ip_version' )
116
117 class ImageAdmin(admin.ModelAdmin):
118     fields = ['image_id', 'name', 'disk_format', 'container_format']
119
120 class NodeAdmin(admin.ModelAdmin):
121     list_display = ('name', 'site', 'deploymentNetwork')
122     list_filter = ('deploymentNetwork',)
123
124 class RoleAdmin(admin.ModelAdmin):
125     fieldsets = [
126         ('Role', {'fields': ['role_type']})
127     ]
128     list_display = ('role_type',)
129
130 class PlainTextWidget(forms.Widget):
131     def render(self, _name, value, attrs):
132         return mark_safe(value) if value is not None else ''
133
134 class SliverForm(forms.ModelForm):
135     class Meta:
136         ip = forms.CharField(widget=PlainTextWidget)
137         model = Sliver
138         widgets = {
139             'ip': PlainTextWidget(),
140         }
141
142 class SliverAdmin(admin.ModelAdmin):
143     form = SliverForm
144     fieldsets = [
145         ('Sliver', {'fields': ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']})
146     ]
147     list_display = ['ip', 'name', 'slice', 'flavor', 'image', 'key', 'node', 'deploymentNetwork']
148
149 class UserCreationForm(forms.ModelForm):
150     """A form for creating new users. Includes all the required
151     fields, plus a repeated password."""
152     password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
153     password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
154
155     class Meta:
156         model = PLUser
157         fields = ('email', 'firstname', 'lastname', 'phone', 'site')
158
159     def clean_password2(self):
160         # Check that the two password entries match
161         password1 = self.cleaned_data.get("password1")
162         password2 = self.cleaned_data.get("password2")
163         if password1 and password2 and password1 != password2:
164             raise forms.ValidationError("Passwords don't match")
165         return password2
166
167     def save(self, commit=True):
168         # Save the provided password in hashed format
169         user = super(UserCreationForm, self).save(commit=False)
170         user.set_password(self.cleaned_data["password1"])
171         if commit:
172             user.save()
173         return user
174
175
176 class UserChangeForm(forms.ModelForm):
177     """A form for updating users. Includes all the fields on
178     the user, but replaces the password field with admin's
179     password hash display field.
180     """
181     password = ReadOnlyPasswordHashField()
182
183     class Meta:
184         model = PLUser
185
186     def clean_password(self):
187         # Regardless of what the user provides, return the initial value.
188         # This is done here, rather than on the field, because the
189         # field does not have access to the initial value
190         return self.initial["password"]
191
192
193 class PLUserAdmin(UserAdmin):
194     class Meta:
195         app_label = "core"
196
197     # The forms to add and change user instances
198     form = UserChangeForm
199     add_form = UserCreationForm
200
201     # The fields to be used in displaying the User model.
202     # These override the definitions on the base UserAdmin
203     # that reference specific fields on auth.User.
204     list_display = ('email', 'site', 'firstname', 'lastname', 'last_login')
205     list_filter = ('site',)
206     fieldsets = (
207         (None, {'fields': ('email', 'password')}),
208         ('Personal info', {'fields': ('firstname','lastname','phone','site')}),
209         #('Important dates', {'fields': ('last_login',)}),
210     )
211     add_fieldsets = (
212         (None, {
213             'classes': ('wide',),
214             'fields': ('email', 'firstname', 'lastname', 'phone', 'site', 'password1', 'password2')}
215         ),
216     )
217     search_fields = ('email',)
218     ordering = ('email',)
219     filter_horizontal = ()
220
221 # register a signal that caches the user's credentials when they log in
222 def cache_credentials(sender, user, request, **kwds):
223     auth = {'username': request.POST['username'],
224             'password': request.POST['password']}
225     request.session['auth'] = auth
226 user_logged_in.connect(cache_credentials)
227
228 # Now register the new UserAdmin...
229 admin.site.register(PLUser, PLUserAdmin)
230 # ... and, since we're not using Django's builtin permissions,
231 # unregister the Group model from admin.
232 admin.site.unregister(Group)
233
234 admin.site.register(Site, SiteAdmin)
235 admin.site.register(SitePrivilege)
236 admin.site.register(Slice, SliceAdmin)
237 admin.site.register(SliceMembership)
238 admin.site.register(Subnet, SubnetAdmin)
239 admin.site.register(Image, ImageAdmin)
240 admin.site.register(Node, NodeAdmin)
241 admin.site.register(Sliver, SliverAdmin)
242 admin.site.register(Flavor)
243 admin.site.register(Key, KeyAdmin)
244 admin.site.register(Role, RoleAdmin)
245 admin.site.register(DeploymentNetwork, DeploymentNetworkAdmin)
246