from django.contrib.contenttypes import generic
from suit.widgets import LinkedSelect
from django.core.exceptions import PermissionDenied
-from django.core.urlresolvers import reverse
+from django.core.urlresolvers import reverse, NoReverseMatch
import django_evolution
return actions
def change_view(self,request,object_id, extra_context=None):
-
if self.__user_is_readonly(request):
- self.readonly_fields=self.user_readonly_fields
- self.inlines = self.user_readonly_inlines
+ if not hasattr(self, "readonly_save"):\r
+ # save the original readonly fields\r
+ self.readonly_save = self.readonly_fields\r
+ self.inlines_save = self.inlines\r
+ if hasattr(self, "user_readonly_fields"):\r
+ self.readonly_fields=self.user_readonly_fields\r
+ if hasattr(self, "user_readonly_inlines"):\r
+ self.inlines = self.user_readonly_inlines\r
+ else:\r
+ if hasattr(self, "readonly_save"):\r
+ # restore the original readonly fields\r
+ self.readonly_fields = self.readonly_save\r
+ if hasattr(self, "inlines_save"):\r
+ self.inlines = self.inlines_save
try:
return super(ReadOnlyAwareAdmin, self).change_view(request, object_id, extra_context=extra_context)
request.readonly = True
return super(ReadOnlyAwareAdmin, self).change_view(request, object_id, extra_context=extra_context)
-
def __user_is_readonly(self, request):
return request.user.isReadOnlyUser()
-class SingletonAdmin (admin.ModelAdmin):
+class SingletonAdmin (ReadOnlyAwareAdmin):
def has_add_permission(self, request):
+ if not super(SingletonAdmin, self).has_add_permission(request):
+ return False
+
num_objects = self.model.objects.count()
if num_objects >= 1:
return False
# the selflink field, we override __init__ to modify self.fields and
# self.readonly_fields.
+ self.setup_selflink()
+
+ def get_change_url(self, model, id):
+ """ Get the URL to a change form in the admin for this model """
+ reverse_path = "admin:%s_change" % (model._meta.db_table)
+ try:
+ url = reverse(reverse_path, args=(id,))
+ except NoReverseMatch:
+ return None
+
+ return url
+
+ def setup_selflink(self):
+ if hasattr(self, "selflink_fieldname"):
+ """ self.selflink_model can be defined to punch through a relation
+ to its target object. For example, in SliceNetworkInline, set
+ selflink_model = "network", and the URL will lead to the Network
+ object instead of trying to bring up a change view of the
+ SliceNetwork object.
+ """
+ self.selflink_model = getattr(self.model,self.selflink_fieldname).field.rel.to
+ else:
+ self.selflink_model = self.model
+
+ url = self.get_change_url(self.selflink_model, 0)
+
+ # We don't have an admin for this object, so don't create the
+ # selflink.
+ if (url == None):
+ return
+
+ # Since we need to add "selflink" to the field list, we need to create
+ # self.fields if it is None.
if (self.fields is None):
self.fields = []
for f in self.model._meta.fields:
if f.editable and f.name != "id":
self.fields.append(f.name)
- if (self.fields is not None):
- self.fields = tuple(self.fields) + ("selflink", )
+ self.fields = tuple(self.fields) + ("selflink", )
- if self.readonly_fields is None:
- self.readonly_fields = ()
+ if self.readonly_fields is None:
+ self.readonly_fields = ()
- self.readonly_fields = tuple(self.readonly_fields) + ("selflink", )
+ self.readonly_fields = tuple(self.readonly_fields) + ("selflink", )
def selflink(self, obj):
+ if hasattr(self, "selflink_fieldname"):
+ obj = getattr(obj, self.selflink_fieldname)
+
if obj.id:
- reverse_path = "admin:%s_change" % (self.model._meta.db_table)\r
- url = reverse(reverse_path, args =(obj.id,))\r
- return "<a href='%s'>Details</a>" % str(url)\r
+ url = self.get_change_url(self.selflink_model, obj.id)
+ return "<a href='%s'>Details</a>" % str(url)
else:\r
- return "Not present"
+ return "Not present"\r
selflink.allow_tags = True
selflink.short_description = "Details"
model = Reservation
extra = 0
suit_classes = 'suit-tab suit-tab-reservations'
+
+ def queryset(self, request):
+ return Reservation.select_by_user(request.user)
class TagROInline(generic.GenericTabularInline):
model = Tag
model = Tag
extra = 0
suit_classes = 'suit-tab suit-tab-tags'
+ fields = ['service', 'name', 'value']
+
+ def queryset(self, request):
+ return Tag.select_by_user(request.user)
class NetworkLookerUpper:
""" This is a callable that looks up a network name in a sliver and returns
class SliverROInline(ReadOnlyTabularInline):
model = Sliver
- fields = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
+ fields = ['ip', 'instance_name', 'slice', 'numberCores', 'deploymentNetwork', 'image', 'node']
suit_classes = 'suit-tab suit-tab-slivers'
class SliverInline(PlStackTabularInline):
model = Sliver
- fields = ['ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
+ fields = ['ip', 'instance_name', 'slice', 'numberCores', 'deploymentNetwork', 'image', 'node']
extra = 0
readonly_fields = ['ip', 'instance_name']
suit_classes = 'suit-tab suit-tab-slivers'
+ def queryset(self, request):
+ return Sliver.select_by_user(request.user)
+
+ def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
+ if db_field.name == 'deploymentNetwork':
+ kwargs['queryset'] = Deployment.select_by_acl(request.user)
+ # the inscrutable jquery selector below says:
+ # find the closest parent "tr" to the current element
+ # then find the child with class "field-node"
+ # then find the child with that is a select
+ # then return its id
+ kwargs['widget'] = forms.Select(attrs={'onChange': "update_nodes(this, $($(this).closest('tr')[0]).find('.field-node select')[0].id)"})
+ #kwargs['widget'] = forms.Select(attrs={'onChange': "console.log($($($(this).closest('tr')[0]).children('.field-node')[0]).children('select')[0].id);"})
+
+ field = super(SliverInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
+
+ return field
+
# Note this is breaking in the admin.py when trying to use an inline to add a node/image
# def _declared_fieldsets(self):
# # Return None so django will call get_fieldsets and we can insert our
extra = 0
suit_classes = 'suit-tab suit-tab-sites'
+ def queryset(self, request):
+ return Site.select_by_user(request.user)
+
class UserROInline(ReadOnlyTabularInline):
model = User
fields = ['email', 'firstname', 'lastname']
extra = 0
suit_classes = 'suit-tab suit-tab-users'
+ def queryset(self, request):
+ return User.select_by_user(request.user)
+
class SliceROInline(ReadOnlyTabularInline):
model = Slice
suit_classes = 'suit-tab suit-tab-slices'
extra = 0
suit_classes = 'suit-tab suit-tab-slices'
+ def queryset(self, request):
+ return Slice.select_by_user(request.user)
+
class NodeROInline(ReadOnlyTabularInline):
model = Node
extra = 0
suit_classes = 'suit-tab suit-tab-nodes'
- fields = ['name','deployment']
+ fields = ['name','deployment','site']
class NodeInline(PlStackTabularInline):
model = Node
extra = 0
suit_classes = 'suit-tab suit-tab-nodes'
+ fields = ['name','deployment','site']
class DeploymentPrivilegeROInline(ReadOnlyTabularInline):
model = DeploymentPrivilege
extra = 0
suit_classes = 'suit-tab suit-tab-deploymentprivileges'
- fields = ['user','role']
+ fields = ['user','role','deployment']
class DeploymentPrivilegeInline(PlStackTabularInline):
model = DeploymentPrivilege
extra = 0
suit_classes = 'suit-tab suit-tab-deploymentprivileges'
+ fields = ['user','role','deployment']
+
+ def queryset(self, request):
+ return DeploymentPrivilege.select_by_user(request.user)
#CLEANUP DOUBLE SitePrivilegeInline
class SitePrivilegeROInline(ReadOnlyTabularInline):
model = SitePrivilege
extra = 0
suit_classes = 'suit-tab suit-tab-siteprivileges'
+ fields = ['user','site', 'role']
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'site':
- if not request.user.is_admin:
- # only show sites where user is an admin or pi
- roles = Role.objects.filter(role_type__in=['admin', 'pi'])
- site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
- login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
- sites = Site.objects.filter(login_base__in=login_bases)
- kwargs['queryset'] = sites
+ kwargs['queryset'] = Site.select_by_user(request.user)
if db_field.name == 'user':
- if not request.user.is_admin:
- # only show users from sites where caller has admin or pi role
- roles = Role.objects.filter(role_type__in=['admin', 'pi'])
- site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
- sites = [site_privilege.site for site_privilege in site_privileges]
- site_privileges = SitePrivilege.objects.filter(site__in=sites)
- emails = [site_privilege.user.email for site_privilege in site_privileges]
- users = User.objects.filter(email__in=emails)
- kwargs['queryset'] = users
+ kwargs['queryset'] = User.select_by_user(request.user)
return super(SitePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
-class SitePrivilegeInline(PlStackTabularInline):
- model = SitePrivilege
- suit_classes = 'suit-tab suit-tab-siteprivileges'
+ def queryset(self, request):
+ return SitePrivilege.select_by_user(request.user)
+
+class SiteDeploymentROInline(ReadOnlyTabularInline):
+ model = SiteDeployments
+ #model = Site.deployments.through
+ extra = 0
+ suit_classes = 'suit-tab suit-tab-deployments'
+ fields = ['deployment','site']
+
+class SiteDeploymentInline(PlStackTabularInline):
+ model = SiteDeployments
+ #model = Site.deployments.through
extra = 0
- fields = ('user', 'site','role')
+ suit_classes = 'suit-tab suit-tab-deployments'
+ fields = ['deployment','site']
+
+ def formfield_for_foreignkey(self, db_field, request, **kwargs):
+ if db_field.name == 'site':
+ kwargs['queryset'] = Site.select_by_user(request.user)
+
+ if db_field.name == 'deployment':
+ kwargs['queryset'] = Deployment.select_by_user(request.user)
+ return super(SiteDeploymentInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
+
+ def queryset(self, request):
+ return SiteDeployments.select_by_user(request.user)
+
class SlicePrivilegeROInline(ReadOnlyTabularInline):
model = SlicePrivilege
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'slice':
- if not request.user.is_admin:
- # only show slices at sites where caller has admin or pi role
- roles = Role.objects.filter(role_type__in=['admin', 'pi'])
- site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
- sites = [site_privilege.site for site_privilege in site_privileges]
- slices = Slice.objects.filter(site__in=sites)
- kwargs['queryset'] = slices
+ kwargs['queryset'] = Slice.select_by_user(request.user)
if db_field.name == 'user':
- if not request.user.is_admin:
- # only show users from sites where caller has admin or pi role
- roles = Role.objects.filter(role_type__in=['admin', 'pi'])
- site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
- sites = [site_privilege.site for site_privilege in site_privileges]
- site_privileges = SitePrivilege.objects.filter(site__in=sites)
- emails = [site_privilege.user.email for site_privilege in site_privileges]
- users = User.objects.filter(email__in=emails)
- kwargs['queryset'] = list(users)
+ kwargs['queryset'] = User.select_by_user(request.user)
return super(SlicePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
+ def queryset(self, request):
+ return SlicePrivilege.select_by_user(request.user)
+
class SliceNetworkROInline(ReadOnlyTabularInline):
model = Network.slices.through
extra = 0
class SliceNetworkInline(PlStackTabularInline):
model = Network.slices.through
+ selflink_fieldname = "network"
extra = 0
verbose_name = "Network Connection"
verbose_name_plural = "Network Connections"
suit_classes = 'suit-tab suit-tab-slicenetworks'
+ fields = ['network']
+
+class ImageDeploymentsROInline(ReadOnlyTabularInline):
+ model = ImageDeployments
+ extra = 0
+ verbose_name = "Image Deployments"
+ verbose_name_plural = "Image Deployments"
+ suit_classes = 'suit-tab suit-tab-imagedeployments'
+ fields = ['image', 'deployment', 'glance_image_id']
+
+class ImageDeploymentsInline(PlStackTabularInline):
+ model = ImageDeployments
+ extra = 0
+ verbose_name = "Image Deployments"
+ verbose_name_plural = "Image Deployments"
+ suit_classes = 'suit-tab suit-tab-imagedeployments'
+ fields = ['image', 'deployment', 'glance_image_id']
+ readonly_fields = ['glance_image_id']
class PlainTextWidget(forms.HiddenInput):
input_type = 'hidden'
class PlanetStackBaseAdmin(ReadOnlyAwareAdmin):
save_on_top = False
+
+ def save_model(self, request, obj, form, change):
+ obj.caller = request.user
+ # update openstack connection to use this site/tenant
+ obj.save_by_user(request.user)
+
+ def delete_model(self, request, obj):
+ obj.delete_by_user(request.user)
+
+ def save_formset(self, request, form, formset, change):
+ instances = formset.save(commit=False)
+ for instance in instances:
+ instance.save_by_user(request.user)
+ formset.save_m2m()
class SliceRoleAdmin(PlanetStackBaseAdmin):
model = SliceRole
sites = forms.ModelMultipleChoiceField(
queryset=Site.objects.all(),
required=False,
+ help_text="Select which sites are allowed to host nodes in this deployment",
widget=FilteredSelectMultiple(
verbose_name=('Sites'), is_stacked=False
)
)
+ images = forms.ModelMultipleChoiceField(
+ queryset=Image.objects.all(),
+ required=False,
+ help_text="Select which images should be deployed on this deployment",
+ widget=FilteredSelectMultiple(
+ verbose_name=('Images'), is_stacked=False
+ )
+ )
class Meta:
model = Deployment
+ def __init__(self, *args, **kwargs):
+ request = kwargs.pop('request', None)
+ super(DeploymentAdminForm, self).__init__(*args, **kwargs)
+
+ self.fields['accessControl'].initial = "allow site " + request.user.site.name
+
+ if self.instance and self.instance.pk:
+ self.fields['sites'].initial = [x.site for x in self.instance.sitedeployments_set.all()]
+ self.fields['images'].initial = [x.image for x in self.instance.imagedeployments_set.all()]
+
+ def manipulate_m2m_objs(self, this_obj, selected_objs, all_relations, relation_class, local_attrname, foreign_attrname):
+ """ helper function for handling m2m relations from the MultipleChoiceField
+
+ this_obj: the source object we want to link from
+
+ selected_objs: a list of destination objects we want to link to
+
+ all_relations: the full set of relations involving this_obj, including ones we don't want
+
+ relation_class: the class that implements the relation from source to dest
+
+ local_attrname: field name representing this_obj in relation_class
+
+ foreign_attrname: field name representing selected_objs in relation_class
+
+ This function will remove all newobjclass relations from this_obj
+ that are not contained in selected_objs, and add any relations that
+ are in selected_objs but don't exist in the data model yet.
+ """
+
+ existing_dest_objs = []
+ for relation in list(all_relations):
+ if getattr(relation, foreign_attrname) not in selected_objs:
+ #print "deleting site", sdp.site
+ relation.delete()
+ else:
+ existing_dest_objs.append(getattr(relation, foreign_attrname))
+
+ for dest_obj in selected_objs:
+ if dest_obj not in existing_dest_objs:
+ #print "adding site", site
+ kwargs = {foreign_attrname: dest_obj, local_attrname: this_obj}
+ relation = relation_class(**kwargs)
+ relation.save()
+
+ def save(self, commit=True):
+ deployment = super(DeploymentAdminForm, self).save(commit=False)
+
+ if commit:
+ deployment.save()
+
+ if deployment.pk:
+ # save_m2m() doesn't seem to work with 'through' relations. So we
+ # create/destroy the through models ourselves. There has to be
+ # a better way...
+
+ self.manipulate_m2m_objs(deployment, self.cleaned_data['sites'], deployment.sitedeployments_set.all(), SiteDeployments, "deployment", "site")
+ self.manipulate_m2m_objs(deployment, self.cleaned_data['images'], deployment.imagedeployments_set.all(), ImageDeployments, "deployment", "image")
+
+ self.save_m2m()
+
+ return deployment
+
+class DeploymentAdminROForm(DeploymentAdminForm):
+ def save(self, commit=True):
+ raise PermissionDenied
+
class SiteAssocInline(PlStackTabularInline):
model = Site.deployments.through
extra = 0
suit_classes = 'suit-tab suit-tab-sites'
class DeploymentAdmin(PlanetStackBaseAdmin):
- form = DeploymentAdminForm
model = Deployment
- fieldList = ['name','sites']
+ fieldList = ['name','sites', 'images', 'accessControl']
fieldsets = [(None, {'fields': fieldList, 'classes':['suit-tab suit-tab-sites']})]
- inlines = [DeploymentPrivilegeInline,NodeInline,TagInline]
+ inlines = [DeploymentPrivilegeInline,NodeInline,TagInline] # ,ImageDeploymentsInline]
- user_readonly_inlines = [DeploymentPrivilegeROInline,NodeROInline,TagROInline]
+ user_readonly_inlines = [DeploymentPrivilegeROInline,NodeROInline,TagROInline] # ,ImageDeploymentsROInline]
user_readonly_fields = ['name']
- suit_form_tabs =(('sites','Deployment Details'),('nodes','Nodes'),('deploymentprivileges','Privileges'),('tags','Tags'))
+ suit_form_tabs =(('sites','Deployment Details'),('nodes','Nodes'),('deploymentprivileges','Privileges'),('tags','Tags')) # ,('imagedeployments','Images'))
+
+ def get_form(self, request, obj=None, **kwargs):
+ if request.user.isReadOnlyUser():
+ kwargs["form"] = DeploymentAdminROForm
+ else:
+ kwargs["form"] = DeploymentAdminForm
+ adminForm = super(DeploymentAdmin,self).get_form(request, obj, **kwargs)
+
+ # from stackexchange: pass the request object into the form
+
+ class AdminFormMetaClass(adminForm):
+ def __new__(cls, *args, **kwargs):
+ kwargs['request'] = request
+ return adminForm(*args, **kwargs)
+
+ return AdminFormMetaClass
class ServiceAttrAsTabROInline(ReadOnlyTabularInline):
model = ServiceAttribute
fieldList = ['name', 'site_url', 'enabled', 'is_public', 'login_base', 'accountLink','location']
fieldsets = [
(None, {'fields': fieldList, 'classes':['suit-tab suit-tab-general']}),
- ('Deployment Networks', {'fields': ['deployments'], 'classes':['suit-tab suit-tab-deployments']}),
+ #('Deployment Networks', {'fields': ['deployments'], 'classes':['suit-tab suit-tab-deployments']}),
]
suit_form_tabs =(('general', 'Site Details'),
('users','Users'),
readonly_fields = ['accountLink']
user_readonly_fields = ['name', 'deployments','site_url', 'enabled', 'is_public', 'login_base', 'accountLink']
- user_readonly_inlines = [SliceROInline,UserROInline,TagROInline, NodeROInline, SitePrivilegeROInline]
+ user_readonly_inlines = [SliceROInline,UserROInline,TagROInline, NodeROInline, SitePrivilegeROInline,SiteDeploymentROInline]
list_display = ('name', 'login_base','site_url', 'enabled')
filter_horizontal = ('deployments',)
- inlines = [SliceInline,UserInline,TagInline, NodeInline, SitePrivilegeInline]
+ inlines = [SliceInline,UserInline,TagInline, NodeInline, SitePrivilegeInline, SiteDeploymentInline]
search_fields = ['name']
def queryset(self, request):
- # admins can see all keys. Users can only see sites they belong to.
- qs = super(SiteAdmin, self).queryset(request)
- if not request.user.is_admin:
- valid_sites = [request.user.site.login_base]
- roles = request.user.get_roles()
- for tenant_list in roles.values():
- valid_sites.extend(tenant_list)
- qs = qs.filter(login_base__in=valid_sites)
- return qs
+ return Site.select_by_user(request.user)
def get_formsets(self, request, obj=None):
for inline in self.get_inline_instances(request, obj):
accountLink.allow_tags = True
accountLink.short_description = "Billing"
+ def save_model(self, request, obj, form, change):
+ # update openstack connection to use this site/tenant
+ obj.save_by_user(request.user)
+
+ def delete_model(self, request, obj):
+ obj.delete_by_user(request.user)
+
class SitePrivilegeAdmin(PlanetStackBaseAdmin):
fieldList = ['user', 'site', 'role']
# admins can see all privileges. Users can only see privileges at sites
# where they have the admin role or pi role.
qs = super(SitePrivilegeAdmin, self).queryset(request)
- if not request.user.is_admin:
- roles = Role.objects.filter(role_type__in=['admin', 'pi'])
- site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
- login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
- sites = Site.objects.filter(login_base__in=login_bases)
- qs = qs.filter(site__in=sites)
+ #if not request.user.is_admin:
+ # roles = Role.objects.filter(role_type__in=['admin', 'pi'])
+ # site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
+ # login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
+ # sites = Site.objects.filter(login_base__in=login_bases)
+ # qs = qs.filter(site__in=sites)
return qs
class SliceForm(forms.ModelForm):
class SliceAdmin(PlanetStackBaseAdmin):
form = SliceForm
- fieldList = ['name', 'site', 'serviceClass', 'enabled','description', 'service', 'slice_url']
+ fieldList = ['name', 'site', 'serviceClass', 'enabled','description', 'service', 'slice_url', 'max_slivers']
fieldsets = [('Slice Details', {'fields': fieldList, 'classes':['suit-tab suit-tab-general']}),]
- list_display = ('name', 'site','serviceClass', 'slice_url')
+ list_display = ('name', 'site','serviceClass', 'slice_url', 'max_slivers')
inlines = [SlicePrivilegeInline,SliverInline, TagInline, ReservationInline,SliceNetworkInline]
user_readonly_fields = fieldList
('reservations','Reservations'),
)
+ def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
+ #deployment_nodes = {}
+ #for node in Node.objects.all():
+ # deployment_nodes[node.deployment.id] = get(deployment_nodes, node.deployment.id, []).append( (node.id, node.name) )
+
+ deployment_nodes = []
+ for node in Node.objects.all():
+ deployment_nodes.append( (node.deployment.id, node.id, node.name) )
+
+ context["deployment_nodes"] = deployment_nodes
+
+ return super(SliceAdmin, self).render_change_form(request, context, add, change, form_url, obj)
+
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'site':
- if not request.user.is_admin:
- # only show sites where user is a pi or admin
- roles = Role.objects.filter(role_type__in=['admin', 'pi'])
- site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
- login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
- sites = Site.objects.filter(login_base__in=login_bases)
- kwargs['queryset'] = sites
-
+ kwargs['queryset'] = Site.select_by_user(request.user)
+
return super(SliceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
def queryset(self, request):
# admins can see all keys. Users can only see slices they belong to.
- qs = super(SliceAdmin, self).queryset(request)
- if not request.user.is_admin:
- valid_slices = []
- roles = request.user.get_roles()
- for tenant_list in roles.values():
- valid_slices.extend(tenant_list)
- qs = qs.filter(name__in=valid_slices)
- return qs
+ return Slice.select_by_user(request.user)
def get_formsets(self, request, obj=None):
for inline in self.get_inline_instances(request, obj):
inline.model.caller = request.user
yield inline.get_formset(request, obj)
- def get_queryset(self, request):
- qs = super(SliceAdmin, self).get_queryset(request)
- if request.user.is_superuser:
- return qs
- # users can only see slices at their site
- return qs.filter(site=request.user.site)
class SlicePrivilegeAdmin(PlanetStackBaseAdmin):
fieldsets = [
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'slice':
- if not request.user.is_admin:
- # only show slices at sites where caller has admin or pi role
- roles = Role.objects.filter(role_type__in=['admin', 'pi'])
- site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
- sites = [site_privilege.site for site_privilege in site_privileges]
- slices = Slice.objects.filter(site__in=sites)
- kwargs['queryset'] = slices
+ kwargs['queryset'] = Slice.select_by_user(request.user)
if db_field.name == 'user':
- if not request.user.is_admin:
- # only show users from sites where caller has admin or pi role
- roles = Role.objects.filter(role_type__in=['admin', 'pi'])
- site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
- sites = [site_privilege.site for site_privilege in site_privileges]
- site_privileges = SitePrivilege.objects.filter(site__in=sites)
- emails = [site_privilege.user.email for site_privilege in site_privileges]
- users = User.objects.filter(email__in=emails)
- kwargs['queryset'] = users
+ kwargs['queryset'] = User.select_by_user(request.user)
return super(SlicePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
def queryset(self, request):
# admins can see all memberships. Users can only see memberships of
# slices where they have the admin role.
- qs = super(SlicePrivilegeAdmin, self).queryset(request)
- if not request.user.is_admin:
- roles = Role.objects.filter(role_type__in=['admin', 'pi'])
- site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
- login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
- sites = Site.objects.filter(login_base__in=login_bases)
- slices = Slice.objects.filter(site__in=sites)
- qs = qs.filter(slice__in=slices)
- return qs
+ return SlicePrivilege.select_by_user(request.user)
def save_model(self, request, obj, form, change):
# update openstack connection to use this site/tenant
auth = request.session.get('auth', {})
- auth['tenant'] = obj.slice.name
+ auth['tenant'] = obj.slice.slicename
obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
obj.save()
def delete_model(self, request, obj):
# update openstack connection to use this site/tenant
auth = request.session.get('auth', {})
- auth['tenant'] = obj.slice.name
+ auth['tenant'] = obj.slice.slicename
obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
obj.delete()
class ImageAdmin(PlanetStackBaseAdmin):
fieldsets = [('Image Details',
- {'fields': ['image_id', 'name', 'disk_format', 'container_format'],
+ {'fields': ['name', 'disk_format', 'container_format'],
'classes': ['suit-tab suit-tab-general']})
]
- suit_form_tabs =(('general','Image Details'),('slivers','Slivers'))
+ suit_form_tabs =(('general','Image Details'),('slivers','Slivers'),('imagedeployments','Deployments'))
- inlines = [SliverInline]
-
- user_readonly_fields = ['image_id', 'name', 'disk_format', 'container_format']
- user_readonly_inlines = [SliverROInline]
+ inlines = [SliverInline, ImageDeploymentsInline]
+
+ user_readonly_fields = ['name', 'disk_format', 'container_format']
+ user_readonly_inlines = [SliverROInline, ImageDeploymentsROInline]
class NodeForm(forms.ModelForm):
class Meta:
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'slice':
- if not request.user.is_admin:
- slices = set([sm.slice.name for sm in SlicePrivilege.objects.filter(user=request.user)])
- kwargs['queryset'] = Slice.objects.filter(name__in=list(slices))
+ kwargs['queryset'] = Slice.select_by_user(request.user)
return super(SliverAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
def queryset(self, request):
# admins can see all slivers. Users can only see slivers of
# the slices they belong to.
- qs = super(SliverAdmin, self).queryset(request)
- if not request.user.is_admin:
- tenants = []
- roles = request.user.get_roles()
- for tenant_list in roles.values():
- tenants.extend(tenant_list)
- valid_slices = Slice.objects.filter(name__in=tenants)
- qs = qs.filter(slice__in=valid_slices)
- return qs
+ return Sliver.select_by_user(request.user)
+
def get_formsets(self, request, obj=None):
# make some fields read only if we are updating an existing record
# hide MyInline in the add view
if obj is None:
continue
- # give inline object access to driver and caller
- auth = request.session.get('auth', {})
- auth['tenant'] = obj.name # meed to connect using slice's tenant
- inline.model.os_manager = OpenStackManager(auth=auth, caller=request.user)
+ if isinstance(inline, SliverInline):
+ inline.model.caller = request.user
yield inline.get_formset(request, obj)
#def save_model(self, request, obj, form, change):
# field does not have access to the initial value
return self.initial["password"]
+class UserDashboardViewInline(PlStackTabularInline):
+ model = UserDashboardView
+ extra = 0
+ suit_classes = 'suit-tab suit-tab-dashboards'
+ fields = ['user', 'dashboardView', 'order']
+
+class UserDashboardViewROInline(ReadOnlyTabularInline):
+ model = UserDashboardView
+ extra = 0
+ suit_classes = 'suit-tab suit-tab-dashboards'
+ fields = ['user', 'dashboardView', 'order']
+
class UserAdmin(UserAdmin):
class Meta:
app_label = "core"
list_display = ('email', 'firstname', 'lastname', 'site', 'last_login')
#list_display = ('email', 'username','firstname', 'lastname', 'is_admin', 'last_login')
list_filter = ('site',)
- inlines = [SlicePrivilegeInline,SitePrivilegeInline,DeploymentPrivilegeInline]
+ inlines = [SlicePrivilegeInline,SitePrivilegeInline,DeploymentPrivilegeInline,UserDashboardViewInline]
fieldListLoginDetails = ['email','site','password','is_readonly','is_amin','public_key']
fieldListContactInfo = ['firstname','lastname','phone','timezone']
fieldsets = (
('Login Details', {'fields': ['email', 'site','password', 'is_readonly', 'is_admin', 'public_key'], 'classes':['suit-tab suit-tab-general']}),
('Contact Information', {'fields': ('firstname','lastname','phone', 'timezone'), 'classes':['suit-tab suit-tab-contact']}),
+ #('Dashboard Views', {'fields': ('dashboards',), 'classes':['suit-tab suit-tab-dashboards']}),
#('Important dates', {'fields': ('last_login',)}),
)
add_fieldsets = (
ordering = ('email',)
filter_horizontal = ()
- user_readonly_fields = fieldListLoginDetails
- user_readonly_inlines = [SlicePrivilegeROInline,SitePrivilegeROInline,DeploymentPrivilegeROInline]
+ user_readonly_fields = fieldListLoginDetails + fieldListContactInfo
+ user_readonly_inlines = [SlicePrivilegeROInline,SitePrivilegeROInline,DeploymentPrivilegeROInline,UserDashboardViewROInline]
- suit_form_tabs =(('general','Login Details'),('contact','Contact Information'),('sliceprivileges','Slice Privileges'),('siteprivileges','Site Privileges'),('deploymentprivileges','Deployment Privileges'))
+ suit_form_tabs =(('general','Login Details'),
+ ('contact','Contact Information'),
+ ('sliceprivileges','Slice Privileges'),
+ ('siteprivileges','Site Privileges'),
+ ('deploymentprivileges','Deployment Privileges'),
+ ('dashboards','Dashboard Views'))
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'site':
- if not request.user.is_admin:
- # show sites where caller is an admin or pi
- sites = []
- for site_privilege in SitePrivilege.objects.filer(user=request.user):
- if site_privilege.role.role_type in ['admin', 'pi']:
- sites.append(site_privilege.site.login_base)
- kwargs['queryset'] = Site.objects.filter(login_base__in(list(sites)))
+ kwargs['queryset'] = Site.select_by_user(request.user)
return super(UserAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
def change_view(self,request,object_id, extra_context=None):
if self.__user_is_readonly(request):
+ if not hasattr(self, "readonly_save"):
+ # save the original readonly fields\r
+ self.readonly_save = self.readonly_fields\r
+ self.inlines_save = self.inlines
self.readonly_fields=self.user_readonly_fields
self.inlines = self.user_readonly_inlines
+ else:
+ if hasattr(self, "readonly_save"):\r
+ # restore the original readonly fields\r
+ self.readonly_fields = self.readonly_save\r
+ self.inlines = self.inlines_save
+
try:
return super(UserAdmin, self).change_view(request, object_id, extra_context=extra_context)
except PermissionDenied:
#return "readonly" in groups
return request.user.isReadOnlyUser()
+ def queryset(self, request):
+ return User.select_by_user(request.user)
+
+class DashboardViewAdmin(PlanetStackBaseAdmin):
+ fieldsets = [('Dashboard View Details',
+ {'fields': ['name', 'url'],
+ 'classes': ['suit-tab suit-tab-general']})
+ ]
+ suit_form_tabs =(('general','Dashboard View Details'),)
class ServiceResourceROInline(ReadOnlyTabularInline):
model = ServiceResource
\r
return field
+ def queryset(self, request):
+ return ReservedResource.select_by_user(request.user)
+
class ReservationChangeForm(forms.ModelForm):
class Meta:
model = Reservation
else:
return []
+ def queryset(self, request):
+ return Reservation.select_by_user(request.user)
+
class NetworkParameterTypeAdmin(PlanetStackBaseAdmin):
list_display = ("name", )
user_readonly_fields = ['name']
class NetworkSliversInline(PlStackTabularInline):
readonly_fields = ("ip", )
model = NetworkSliver
+ selflink_fieldname = "sliver"
extra = 0
verbose_name_plural = "Slivers"
verbose_name = "Sliver"
class NetworkSlicesInline(PlStackTabularInline):
model = NetworkSlice
+ selflink_fieldname = "slice"
extra = 0
verbose_name_plural = "Slices"
verbose_name = "Slice"
#admin.site.register(SitePrivilege, SitePrivilegeAdmin)
admin.site.register(Sliver, SliverAdmin)
admin.site.register(Image, ImageAdmin)
+ admin.site.register(DashboardView, DashboardViewAdmin)