blob: 418ba2b2b65b39b708506f8398bff075638d7342 [file] [log] [blame]
Siobhan Tullycf04fb62014-01-11 11:25:57 -05001from django.contrib import admin
2
jcnelson575a1352014-07-10 19:33:34 -04003from syndicate_storage.models import *
Siobhan Tullycf04fb62014-01-11 11:25:57 -05004from django import forms
5from django.utils.safestring import mark_safe
6from django.contrib.auth.admin import UserAdmin
7from django.contrib.admin.widgets import FilteredSelectMultiple
8from django.contrib.auth.forms import ReadOnlyPasswordHashField
9from django.contrib.auth.signals import user_logged_in
10from django.utils import timezone
11from django.contrib.contenttypes import generic
12from suit.widgets import LinkedSelect
13from core.admin import ReadOnlyTabularInline,ReadOnlyAwareAdmin,SingletonAdmin,SliceInline,ServiceAttrAsTabInline,PlanetStackBaseAdmin, PlStackTabularInline,SliceROInline,ServiceAttrAsTabROInline
14from suit.widgets import LinkedSelect
Scott Baker65a670a2014-05-08 22:14:13 -070015from django.core.exceptions import ValidationError, ObjectDoesNotExist
Siobhan Tullycf04fb62014-01-11 11:25:57 -050016
17class SyndicateServiceAdmin(SingletonAdmin,ReadOnlyAwareAdmin):
18 model = SyndicateService
jcnelson575a1352014-07-10 19:33:34 -040019 verbose_name = "Syndicate Storage"
20 verbose_name_plural = "Syndicate Storage"
Siobhan Tullycf04fb62014-01-11 11:25:57 -050021 list_display = ("name","enabled")
22 fieldsets = [(None, {'fields': ['name','enabled','versionNumber', 'description',], 'classes':['suit-tab suit-tab-general']})]
23 inlines = [SliceInline,ServiceAttrAsTabInline]
24
25 user_readonly_fields = ['name','enabled','versionNumber','description']
26 user_readonly_inlines = [SliceROInline, ServiceAttrAsTabROInline]
27
jcnelson575a1352014-07-10 19:33:34 -040028 suit_form_tabs =(('general', 'Syndicate Storage Details'),
Siobhan Tullycf04fb62014-01-11 11:25:57 -050029 ('slices','Slices'),
30 ('serviceattrs','Additional Attributes'),
31 )
32
Scott Baker65a670a2014-05-08 22:14:13 -070033
Siobhan Tullycf04fb62014-01-11 11:25:57 -050034class VolumeAccessRightForUserROInline(ReadOnlyTabularInline):
35 model = VolumeAccessRight
36 extra = 0
37 suit_classes = 'suit-tab suit-tab-volumeAccessRights'
jcnelson575a1352014-07-10 19:33:34 -040038 fields = ['volume','cap_read_data', 'cap_write_data', 'cap_host_data']
Siobhan Tullycf04fb62014-01-11 11:25:57 -050039
40class VolumeAccessRightROInline(ReadOnlyTabularInline):
41 model = VolumeAccessRight
42 extra = 0
43 suit_classes = 'suit-tab suit-tab-volumeAccessRights'
jcnelson575a1352014-07-10 19:33:34 -040044 fields = ['owner_id','cap_read_data', 'cap_write_data', 'cap_host_data']
Siobhan Tullycf04fb62014-01-11 11:25:57 -050045
46class VolumeAccessRightInline(PlStackTabularInline):
47 model = VolumeAccessRight
48 extra = 0
49 suit_classes = 'suit-tab suit-tab-volumeAccessRights'
Siobhan Tullycf04fb62014-01-11 11:25:57 -050050
Scott Baker65a670a2014-05-08 22:14:13 -070051
52class VolumeSliceFormSet( forms.models.BaseInlineFormSet ):
53 # verify that our VolumeSlice is valid
54
55 @classmethod
56 def verify_unchanged( cls, volume_pk, slice_pk, field_name, new_value ):
57 vs = None
58 try:
59 vs = VolumeSlice.objects.get( volume_id=volume_pk, slice_id=slice_pk )
60 except ObjectDoesNotExist, dne:
61 return True, None
62
63 old_value = getattr( vs, field_name )
64 if old_value != new_value:
65 return False, old_value
66 else:
67 return True, None
68
69
70 def clean( self ):
71 for form in self.forms:
72 # check each inline's cleaned data, if it's valid
73 cleaned_data = None
74 try:
75 if form.cleaned_data:
76 cleaned_data = form.cleaned_data
77 except AttributeError:
78 continue
jcnelson575a1352014-07-10 19:33:34 -040079
Scott Baker65a670a2014-05-08 22:14:13 -070080 # verify that the ports haven't changed
81 volume_pk = cleaned_data['volume_id'].pk
82 slice_pk = cleaned_data['slice_id'].pk
83
jcnelson575a1352014-07-10 19:33:34 -040084 if not cleaned_data.has_key('UG_portnum'):
85 raise ValidationError("Missing UG port number")
Scott Baker65a670a2014-05-08 22:14:13 -070086
jcnelson575a1352014-07-10 19:33:34 -040087 if not cleaned_data.has_key('RG_portnum'):
88 raise ValidationError("Missing RG port number")
Scott Baker65a670a2014-05-08 22:14:13 -070089
jcnelson575a1352014-07-10 19:33:34 -040090 rc1, old_peer_port = VolumeSliceFormSet.verify_unchanged( volume_pk, slice_pk, 'UG_portnum', cleaned_data['UG_portnum'] )
91 rc2, old_replicate_port = VolumeSliceFormSet.verify_unchanged( volume_pk, slice_pk, 'RG_portnum', cleaned_data['RG_portnum'] )
Scott Baker65a670a2014-05-08 22:14:13 -070092
93 err1str = ""
94 err2str = ""
95 if not rc1:
jcnelson575a1352014-07-10 19:33:34 -040096 err1str = "change %s back to %s" % (cleaned_data['UG_portnum'], old_peer_port)
Scott Baker65a670a2014-05-08 22:14:13 -070097 if not rc2:
jcnelson575a1352014-07-10 19:33:34 -040098 err2str = " and change %s back to %s" % (cleaned_data['RG_portnum'], old_replicate_port )
Scott Baker65a670a2014-05-08 22:14:13 -070099
100 if not rc1 or not rc2:
jcnelson575a1352014-07-10 19:33:34 -0400101 raise ValidationError("At this time, port numbers cannot be changed once they are set. Please %s %s" % (err1str, err2str))
Scott Baker65a670a2014-05-08 22:14:13 -0700102
103
104
105class VolumeSliceInline(PlStackTabularInline):
106 model = VolumeSlice
107 extra = 0
108 suit_classes = 'suit-tab suit-tab-volumeSlices'
jcnelson575a1352014-07-10 19:33:34 -0400109 fields = ['volume_id', 'slice_id', 'cap_read_data', 'cap_write_data', 'cap_host_data', 'UG_portnum', 'RG_portnum']
Scott Baker65a670a2014-05-08 22:14:13 -0700110
111 formset = VolumeSliceFormSet
112
113 readonly_fields = ['credentials_blob']
114
115
116class VolumeSliceROInline(ReadOnlyTabularInline):
117 model = VolumeSlice
118 extra = 0
119 suit_classes = 'suit-tab suit-tab-volumeSlices'
jcnelson575a1352014-07-10 19:33:34 -0400120 fields = ['volume_id', 'slice_id', 'cap_read_data', 'cap_write_data', 'cap_host_data', 'UG_portnum', 'RG_portnum']
Scott Baker65a670a2014-05-08 22:14:13 -0700121
122 formset = VolumeSliceFormSet
123
124 readonly_fields = ['credentials_blob']
jcnelson575a1352014-07-10 19:33:34 -0400125
Scott Baker65a670a2014-05-08 22:14:13 -0700126
Siobhan Tullycf04fb62014-01-11 11:25:57 -0500127class VolumeAdmin(ReadOnlyAwareAdmin):
128 model = Volume
Scott Baker65a670a2014-05-08 22:14:13 -0700129
130 def get_readonly_fields(self, request, obj=None ):
jcnelson575a1352014-07-10 19:33:34 -0400131 always_readonly = []
Scott Baker65a670a2014-05-08 22:14:13 -0700132 if obj == None:
133 # all fields are editable on add
134 return always_readonly
135
136 else:
137 # can't change owner, slice id, or block size on update
138 return ['blocksize', 'owner_id'] + always_readonly
139
140
Siobhan Tullycf04fb62014-01-11 11:25:57 -0500141 list_display = ['name', 'owner_id']
142
jcnelson575a1352014-07-10 19:33:34 -0400143 detailsFieldList = ['name', 'owner_id', 'description','blocksize', 'private','archive', 'cap_read_data', 'cap_write_data', 'cap_host_data' ]
Siobhan Tullycf04fb62014-01-11 11:25:57 -0500144
Siobhan Tullycf04fb62014-01-11 11:25:57 -0500145 fieldsets = [
146 (None, {'fields': detailsFieldList, 'classes':['suit-tab suit-tab-general']}),
Siobhan Tullycf04fb62014-01-11 11:25:57 -0500147 ]
148
Scott Baker65a670a2014-05-08 22:14:13 -0700149 inlines = [VolumeAccessRightInline, VolumeSliceInline]
Siobhan Tullycf04fb62014-01-11 11:25:57 -0500150
jcnelson575a1352014-07-10 19:33:34 -0400151 user_readonly_fields = ['name','owner_id','description','blocksize','private', 'archive', 'cap_read_data', 'cap_write_data', 'cap_host_data']
Scott Baker65a670a2014-05-08 22:14:13 -0700152
153 user_readonly_inlines = [VolumeAccessRightROInline, VolumeSliceROInline]
Siobhan Tullycf04fb62014-01-11 11:25:57 -0500154
155 suit_form_tabs =(('general', 'Volume Details'),
Scott Baker65a670a2014-05-08 22:14:13 -0700156 ('volumeSlices', 'Slices'),
jcnelson575a1352014-07-10 19:33:34 -0400157 ('volumeAccessRights', 'Volume Access Rights'))
Siobhan Tullycf04fb62014-01-11 11:25:57 -0500158
jcnelson575a1352014-07-10 19:33:34 -0400159 def queryset(self, request):
160 # only show volumes that are public, or owned by the caller
161 return Volume.select_by_user(request.user)
162
163
Scott Baker65a670a2014-05-08 22:14:13 -0700164# left panel:
Siobhan Tullycf04fb62014-01-11 11:25:57 -0500165admin.site.register(SyndicateService, SyndicateServiceAdmin)
Siobhan Tullycf04fb62014-01-11 11:25:57 -0500166admin.site.register(Volume, VolumeAdmin)