blob: d171beb4e292dbf29436770e048337972528b76a [file] [log] [blame]
from django.contrib import admin
from hpc.models import *
from django import forms
from django.utils.safestring import mark_safe
from django.contrib.auth.admin import UserAdmin
from django.contrib.admin.widgets import FilteredSelectMultiple
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.signals import user_logged_in
from django.utils import timezone
from django.contrib.contenttypes import generic
from suit.widgets import LinkedSelect
from core.admin import ServiceAppAdmin,SliceInline,ServiceAttrAsTabInline, ReadOnlyAwareAdmin, XOSTabularInline, SliderWidget, ServicePrivilegeInline
from core.middleware import get_request
from functools import update_wrapper
from django.contrib.admin.views.main import ChangeList
from django.core.urlresolvers import reverse
from django.contrib.admin.utils import quote
import threading
_thread_locals = threading.local()
class FilteredChangeList(ChangeList):
""" A special ChangeList with a doctored url_for_result function that
points to the filteredchange view instead of the default change
view.
"""
def __init__(self, request, *args, **kwargs):
self.hpcService = getattr(request, "hpcService", None)
self.embedded = getattr(request, "embedded", False)
super(FilteredChangeList, self).__init__(request, *args, **kwargs)
def url_for_result(self, result):
if (self.hpcService is None):
return super(FilteredChangeList, self).url_for_result(result)
pk = getattr(result, self.pk_attname)
if self.embedded:
return reverse('admin:%s_%s_embeddedfilteredchange' % (self.opts.app_label,
self.opts.model_name),
args=(quote(self.hpcService.id), quote(pk),),
current_app=self.model_admin.admin_site.name)
else:
return reverse('admin:%s_%s_filteredchange' % (self.opts.app_label,
self.opts.model_name),
args=(quote(self.hpcService.id), quote(pk),),
current_app=self.model_admin.admin_site.name)
class FilteredAdmin(ReadOnlyAwareAdmin):
"""
One approach to filtering the HPC Admin views by HPCService. Encode
the HPCService into the URL for the changelist view. Then we could do our
custom filtering in self.filtered_changelist_view.
To make this work, a few changes needed to be made to the change and
change_list templates.
1) "custom_changelist_breadcrumb_url" is used to replace the breadcrumb
in change and add views with one that will point back to the filtered
list.
2) "custom_add_url" is used to replace the Add button's URL with one
that points to the filtered add view.
TODO: Save & Add Another,
the add link when the changelist is empty
"""
@property
def change_list_template(self):
return _thread_locals.change_list_template
@property
def change_form_template(self):
return _thread_locals.change_form_template
def get_urls(self):
from django.conf.urls import patterns, url
def wrap(view):
def wrapper(*args, **kwargs):
return self.admin_site.admin_view(view)(*args, **kwargs)
return update_wrapper(wrapper, view)
urls = super(FilteredAdmin, self).get_urls()
info = self.model._meta.app_label, self.model._meta.model_name
my_urls = [
url(r'^(.+)/filteredlist/$', wrap(self.filtered_changelist_view), name="%s_%s_filteredchangelist" % info),
url(r'^(.+)/embeddedfilteredlist/$', wrap(self.embedded_filtered_changelist_view), name="%s_%s_embeddedfilteredchangelist" % info),
url(r'^(.+)/(.+)/filteredchange$', wrap(self.filtered_change_view), name='%s_%s_filteredchange' % info),
url(r'^(.+)/(.+)/embeddedfilteredchange$', wrap(self.embedded_filtered_change_view), name='%s_%s_embeddedfilteredchange' % info),
url(r'^(.+)/filteredadd/$', wrap(self.filtered_add_view), name='%s_%s_filteredadd' % info),
url(r'^(.+)/embeddedfilteredadd/$', wrap(self.embedded_filtered_add_view), name='%s_%s_embeddedfilteredadd' % info),
]
return my_urls + urls
def add_extra_context(self, request, extra_context):
super(FilteredAdmin, self).add_extra_context(request, extra_context)
if getattr(request,"hpcService",None) is not None:
extra_context["custom_changelist_breadcrumb_url"] = "/admin/hpc/%s/%s/filteredlist/" % (self.model._meta.model_name, str(request.hpcService.id))
if getattr(request,"embedded",False):
extra_context["custom_add_url"] = "/admin/hpc/%s/%s/embeddedfilteredadd/" % (self.model._meta.model_name, str(request.hpcService.id))
else:
extra_context["custom_add_url"] = "/admin/hpc/%s/%s/filteredadd/" % (self.model._meta.model_name, str(request.hpcService.id))
def changelist_view(self, *args, **kwargs):
if "template" in kwargs:
_thread_locals.change_list_template = kwargs["template"]
del kwargs["template"]
else:
_thread_locals.change_list_template = "admin/change_list_bc.html"
return super(FilteredAdmin, self).changelist_view(*args, **kwargs)
def filtered_changelist_view(self, request, hpcServiceId, extra_context=None):
request.hpcService = HpcService.objects.get(id=hpcServiceId)
return self.changelist_view(request, extra_context=extra_context)
def embedded_filtered_changelist_view(self, request, hpcServiceId, extra_context=None):
request.hpcService = HpcService.objects.get(id=hpcServiceId)
request.embedded = True
return self.changelist_view(request, template="admin/change_list_embedded.html", extra_context=extra_context)
def change_view(self, *args, **kwargs):
if "template" in kwargs:
_thread_locals.change_form_template = kwargs["template"]
del kwargs["template"]
else:
_thread_locals.change_form_template = "admin/change_form_bc.html"
return super(FilteredAdmin, self).change_view(*args, **kwargs)
def filtered_change_view(self, request, hpcServiceId, object_id, extra_context=None):
request.hpcService = HpcService.objects.get(id=hpcServiceId)
return self.change_view(request, object_id, extra_context=extra_context)
def embedded_filtered_change_view(self, request, hpcServiceId, object_id, extra_context=None):
request.hpcService = HpcService.objects.get(id=hpcServiceId)
request.embedded = True
return self.change_view(request, object_id, template="admin/change_form_embedded.html", extra_context=extra_context)
def add_view(self, *args, **kwargs):
if "template" in kwargs:
_thread_locals.change_form_template = kwargs["template"]
del kwargs["template"]
else:
_thread_locals.change_form_template = "admin/change_form_bc.html"
return super(FilteredAdmin, self).add_view(*args, **kwargs)
def filtered_add_view(self, request, hpcServiceId, extra_context=None):
request.hpcService = HpcService.objects.get(id=hpcServiceId)
return self.add_view(request, extra_context=extra_context)
def embedded_filtered_add_view(self, request, hpcServiceId, extra_context=None):
request.hpcService = HpcService.objects.get(id=hpcServiceId)
request.embedded = True
return self.add_view(request, template="admin/change_form_embedded.html", extra_context=extra_context)
def get_queryset(self, request):
# request.hpcService will be set in filtered_changelist_view so we can
# use it to filter what will be displayed in the list.
qs = self.model.objects.all()
if (getattr(request,"hpcService",None) is not None) and (hasattr(self.model, "filter_by_hpcService")):
qs = self.model.filter_by_hpcService(qs, request.hpcService)
return qs
def get_changelist(self, request, **kwargs):
# We implement a custom ChangeList, so the URLs point to the
# filtered_change_view rather than the default change_view.
return FilteredChangeList
class HpcServiceForm(forms.ModelForm):
scale = forms.IntegerField(widget = SliderWidget, required=False)
def __init__(self, *args, **kwargs):
super(HpcServiceForm, self).__init__(*args, **kwargs)
self.fields['scale'].initial = kwargs["instance"].scale
def save(self, *args, **kwargs):
if self.cleaned_data['scale']:
self.instance.scale = self.cleaned_data['scale']
return super(HpcServiceForm, self).save(*args, **kwargs)
class HpcServiceAdmin(ReadOnlyAwareAdmin):
model = HpcService
verbose_name = "HPC Service"
verbose_name_plural = "HPC Service"
list_display = ("backend_status_icon", "name","enabled")
list_display_links = ('backend_status_icon', 'name', )
fieldsets = [(None, {'fields': ['backend_status_text', 'name','scale','enabled','versionNumber', 'description', "cmi_hostname"], 'classes':['suit-tab suit-tab-general']})]
readonly_fields = ('backend_status_text', )
inlines = [SliceInline,ServiceAttrAsTabInline,ServicePrivilegeInline]
form = HpcServiceForm
extracontext_registered_admins = True
user_readonly_fields = ["name", "enabled", "versionNumber", "description"]
suit_form_tabs =(('general', 'HPC Service Details'),
('administration', 'Administration'),
('tools', 'Tools'),
('slices','Slices'),
('serviceattrs','Additional Attributes'),
('serviceprivileges','Privileges'),
)
suit_form_includes = (('hpcadmin.html', 'top', 'administration'),
('hpctools.html', 'top', 'tools') )
def url_for_model_changelist(self, request, model):
if not request.resolver_match.args:
return reverse('admin:%s_%s_changelist' % (model._meta.app_label, model._meta.model_name), current_app=model._meta.app_label)
else:
obj_id = request.resolver_match.args[0]
changelist_url = reverse('admin:%s_%s_filteredchangelist' % (model._meta.app_label, model._meta.model_name), args=(obj_id,), current_app=model._meta.app_label)
return changelist_url
class HPCAdmin(FilteredAdmin):
# Change the application breadcrumb to point to an HPC Service if one is
# defined
"""
@property
def change_form_template(self):
request=get_request()
if request.GET.get("embedded",False):
return "admin/change_form_embedded.html"
else:
return "admin/change_form_bc.html"
"""
#change_form_template = "admin/change_form_bc.html"
#change_list_template = "admin/change_list_bc.html"
custom_app_breadcrumb_name = "Hpc"
@property
def custom_app_breadcrumb_url(self):
services = HpcService.objects.all()
if len(services)==1:
return "/admin/hpc/hpcservice/%s/" % services[0].id
else:
return "/admin/hpc/hpcservice/"
class CDNPrefixInline(XOSTabularInline):
model = CDNPrefix
extra = 0
suit_classes = 'suit-tab suit-tab-prefixes'
fields = ('backend_status_icon', 'cdn_prefix_id', 'prefix', 'defaultOriginServer', 'enabled')
readonly_fields = ('backend_status_icon', 'cdn_prefix_id',)
class ContentProviderInline(XOSTabularInline):
model = ContentProvider
extra = 0
suit_classes = 'suit-tab suit-tab-cps'
fields = ('backend_status_icon', 'content_provider_id', 'name', 'enabled')
readonly_fields = ('backend_status_icon', 'content_provider_id',)
class OriginServerAdmin(HPCAdmin):
list_display = ('backend_status_icon', 'url','protocol','redirects','contentProvider','authenticated','enabled' )
list_display_links = ('backend_status_icon', 'url', )
fields = ('backend_status_text', 'url','protocol','redirects','contentProvider','authenticated','enabled','origin_server_id','description' )
readonly_fields = ('backend_status_text', 'origin_server_id',)
user_readonly_fields = ('url','protocol','redirects','contentProvider','authenticated','enabled','origin_server_id','description')
class ContentProviderForm(forms.ModelForm):
class Meta:
widgets = {
'serviceProvider' : LinkedSelect
}
class ContentProviderAdmin(HPCAdmin):
form = ContentProviderForm
list_display = ('backend_status_icon', 'name','description','enabled' )
list_display_links = ('backend_status_icon', 'name', )
fieldsets = [ (None, {'fields': ['backend_status_text', 'name','enabled','description','serviceProvider','users'], 'classes':['suit-tab suit-tab-general']})]
readonly_fields = ('backend_status_text', )
inlines = [CDNPrefixInline]
user_readonly_fields = ('name','description','enabled','serviceProvider','users')
suit_form_tabs = (('general','Details'),('prefixes','CDN Prefixes'))
class ServiceProviderAdmin(HPCAdmin):
list_display = ('backend_status_icon', 'name', 'description', 'enabled')
list_display_links = ('backend_status_icon', 'name', )
fieldsets = [
(None, {'fields': ['backend_status_text', 'name','description','enabled', 'hpcService'], 'classes':['suit-tab suit-tab-general']})]
#, ('Content Providers', {'fields':['contentProviders'],'classes':['suit-tab suit-tab-cps']})]
readonly_fields = ('backend_status_text', )
user_readonly_fields = ('name', 'description', 'enabled')
suit_form_tabs = (('general','Details'),('cps','Content Providers'))
inlines = [ContentProviderInline]
class CDNPrefixForm(forms.ModelForm):
class Meta:
widgets = {
'contentProvider' : LinkedSelect
}
class CDNPrefixAdmin(HPCAdmin):
form = CDNPrefixForm
list_display = ['backend_status_icon', 'prefix','contentProvider']
list_display_links = ('backend_status_icon', 'prefix', )
fields = ['backend_status_text', 'prefix', 'contentProvider', 'cdn_prefix_id', 'description', 'defaultOriginServer', 'enabled']
readonly_fields = ('backend_status_text', )
user_readonly_fields = ['prefix','contentProvider', "cdn_prefix_id", "description", "defaultOriginServer", "enabled"]
class SiteMapAdmin(HPCAdmin):
model = SiteMap
verbose_name = "Site Map"
verbose_name_plural = "Site Map"
list_display = ("backend_status_icon", "name", "contentProvider", "serviceProvider")
list_display_links = ('backend_status_icon', 'name', )
fields = ['backend_status_text', 'name', 'hpcService', 'cdnPrefix', 'contentProvider', 'serviceProvider', 'map', 'map_id']
user_readonly_fields = ('backend_status_text', "name", "hpcService", "cdnPrefix", "contentProvider", "serviceProvider", "description", "map")
readonly_fields = ('backend_status_text', )
class AccessMapAdmin(HPCAdmin):
model = AccessMap
verbose_name = "Access Map"
verbose_name_plural = "Access Map"
list_display = ("backend_status_icon", "name", "contentProvider")
list_display_links = ('backend_status_icon', 'name', )
user_readonly_fields = ('backend_status_text', "name", "contentProvider", "description", "map")
readonly_fields = ('backend_status_text', )
class HpcHealthCheckAdmin(HPCAdmin):
model = HpcHealthCheck
verbose_name = "Health Check"
verbose_name = "Health Checks"
list_display = ["backend_status_icon", "resource_name", "kind"]
list_display_links = ["backend_status_icon", "resource_name"]
fields = ["backend_status_text", "hpcService", "resource_name", "kind", "result_contains", "result_min_size", "result_max_size"]
readonly_fields = ["backend_status_text",]
admin.site.register(ServiceProvider, ServiceProviderAdmin)
admin.site.register(ContentProvider, ContentProviderAdmin)
admin.site.register(CDNPrefix, CDNPrefixAdmin)
admin.site.register(OriginServer,OriginServerAdmin)
admin.site.register(HpcService, HpcServiceAdmin)
admin.site.register(SiteMap, SiteMapAdmin)
admin.site.register(AccessMap, AccessMapAdmin)
admin.site.register(HpcHealthCheck, HpcHealthCheckAdmin)