X-Git-Url: http://git.onelab.eu/?p=myslice.git;a=blobdiff_plain;f=portal%2Fsliceview.py;h=eaec3faa038258630b98517b106a520291adbb87;hp=78c2fabd498aa900db4365c5e81cf78fec03eed4;hb=20e712f9703d8b2eaf226fdf8807315edcea6a9a;hpb=7d39f58ac87cac2ae29cf3b8e3e4ebb47fe2e2e9 diff --git a/portal/sliceview.py b/portal/sliceview.py index 78c2fabd..eaec3faa 100644 --- a/portal/sliceview.py +++ b/portal/sliceview.py @@ -1,3 +1,4 @@ +import json from django.template import RequestContext from django.shortcuts import render_to_response @@ -5,24 +6,30 @@ from unfold.loginrequired import LoginRequiredAutoLogoutView from unfold.page import Page from manifold.core.query import Query, AnalyzedQuery +from manifold.manifoldapi import execute_query -from ui.topmenu import topmenu_items, the_user +from ui.topmenu import topmenu_items_live, the_user from plugins.raw import Raw from plugins.stack import Stack from plugins.tabs import Tabs -from plugins.hazelnut import Hazelnut -from plugins.resources_selected import ResourcesSelected +from plugins.querytable import QueryTable +from plugins.querygrid import QueryGrid +from plugins.queryupdater import QueryUpdater from plugins.googlemap import GoogleMap from plugins.senslabmap import SensLabMap +from plugins.scheduler import Scheduler from plugins.querycode import QueryCode +# Thierry +# stay away from query editor for now as it seems to make things go very slow +# see https://lists.myslice.info/pipermail/devel-myslice/2013-December/000221.html from plugins.query_editor import QueryEditor from plugins.active_filters import ActiveFilters from plugins.quickfilter import QuickFilter from plugins.messages import Messages from plugins.slicestat import SliceStat -from myslice.config import Config +from myslice.configengine import ConfigEngine tmp_default_slice='ple.upmc.myslicedemo' @@ -30,6 +37,15 @@ tmp_default_slice='ple.upmc.myslicedemo' #do_query_users=True do_query_users=False +#do_query_leases=True +do_query_leases=False + +insert_grid=False +#insert_grid=True + +insert_messages=False +#insert_messages=True + class SliceView (LoginRequiredAutoLogoutView): def get (self,request, slicename=tmp_default_slice): @@ -39,10 +55,9 @@ class SliceView (LoginRequiredAutoLogoutView): page.add_js_files ( [ "js/common.functions.js" ] ) page.add_js_chunks ('$(function() { messages.debug("sliceview: jQuery version " + $.fn.jquery); });') page.add_js_chunks ('$(function() { messages.debug("sliceview: users turned %s"); });'%("on" if do_query_users else "off")) - config=Config() - page.add_js_chunks ('$(function() { messages.debug("manifold URL %s"); });'%(config.manifold_url())) - page.expose_js_metadata() - + page.add_js_chunks ('$(function() { messages.debug("sliceview: leases turned %s"); });'%("on" if do_query_leases else "off")) + page.add_js_chunks ('$(function() { messages.debug("manifold URL %s"); });'%(ConfigEngine().manifold_url())) + metadata = page.get_metadata() resource_md = metadata.details_by_object('resource') resource_fields = [column['name'] for column in resource_md['column']] @@ -54,22 +69,49 @@ class SliceView (LoginRequiredAutoLogoutView): main_query = Query.get('slice').filter_by('slice_hrn', '=', slicename) main_query.select( 'slice_hrn', - 'resource.hrn', 'resource.hostname', 'resource.type', + #'resource.hrn', 'resource.urn', + 'resource.hostname', 'resource.type', 'resource.network_hrn', - #'lease.urn', + 'lease.urn', 'user.user_hrn', #'application.measurement_point.counter' ) + # for internal use in the querytable plugin; + # needs to be a unique column present for each returned record + main_query_init_key = 'hostname' query_resource_all = Query.get('resource').select(resource_fields) - if do_query_users: - query_user_all = Query.get('user').select(user_fields) - + aq = AnalyzedQuery(main_query, metadata=metadata) page.enqueue_query(main_query, analyzed_query=aq) page.enqueue_query(query_resource_all) if do_query_users: - page.enqueue_query(query_user_all) + # Required: the user must have an authority in its user.config + # XXX Temporary solution + user_query = Query().get('local:user').select('config','email') + user_details = execute_query(self.request, user_query) + + # not always found in user_details... + config={} +# for user_detail in user_details: +# #email = user_detail['email'] +# if user_detail['config']: +# config = json.loads(user_detail['config']) +# user_detail['authority'] = config.get('authority',"Unknown Authority") +# +# if user_detail['authority'] is not None: +# sub_authority = user_detail['authority'].split('.') +# root_authority = sub_authority[0] +# query_user_all = Query.get(root_authority+':user').select(user_fields) +# +# # XXX TODO this filter doesn't work - to be improved in Manifold +# #.filter_by('authority.authority_hrn', '=', user_detail['authority']) +# +# page.enqueue_query(query_user_all) +# else: +# print "authority of the user is not in local:user db" + query_user_all = Query.get('user').select(user_fields) + # query_user_all = None # ... and for the relations # XXX Let's hardcode resources for now @@ -102,9 +144,9 @@ class SliceView (LoginRequiredAutoLogoutView): ) # -------------------------------------------------------------------------- - # ResourcesSelected (Pending Operations) + # QueryUpdater (Pending Operations) - main_stack.insert(ResourcesSelected( + main_stack.insert(QueryUpdater( page = page, title = 'Pending operations', query = main_query, @@ -118,6 +160,7 @@ class SliceView (LoginRequiredAutoLogoutView): # -------------------------------------------------------------------------- # Filter Resources +# turn off for now -- see above filter_query_editor = QueryEditor( page = page, query = sq_resource, @@ -134,7 +177,8 @@ class SliceView (LoginRequiredAutoLogoutView): page = page, title = 'Filter Resources', domid = 'filters', - sons = [filter_query_editor, filter_active_filters], + sons = [filter_query_editor, + filter_active_filters], togglable = True, toggled = 'persistent', outline_complete = True, @@ -145,7 +189,7 @@ class SliceView (LoginRequiredAutoLogoutView): # RESOURCES # the resources part is made of a Tabs (Geographic, List), - resources_as_map = GoogleMap( + resources_as_gmap = GoogleMap( page = page, title = 'Geographic view', domid = 'resources-map', @@ -153,6 +197,10 @@ class SliceView (LoginRequiredAutoLogoutView): togglable = False, query = sq_resource, query_all = query_resource_all, + # this key is the one issued by google + googlemap_api_key = ConfigEngine().googlemap_api_key(), + # the key to use at init-time + init_key = main_query_init_key, checkboxes = True, # center on Paris latitude = 49., @@ -160,13 +208,22 @@ class SliceView (LoginRequiredAutoLogoutView): zoom = 4, ) - resources_as_list = Hazelnut( + resources_as_3dmap = SensLabMap( + page = page, + title = '3D Map', + domid = 'senslabmap', + query = sq_resource, + query_all = query_resource_all, + ) + + resources_as_list = QueryTable( page = page, domid = 'resources-list', title = 'List view', # this is the query at the core of the slice list query = sq_resource, query_all = query_resource_all, + init_key = main_query_init_key, checkboxes = True, datatables_options = { 'iDisplayLength': 25, @@ -175,67 +232,59 @@ class SliceView (LoginRequiredAutoLogoutView): }, ) - resources_stats_cpu = SliceStat( - title = "CPU Usage", - domid = 'resources-stats-cpu', - page = page, - stats = 'slice', - key = 'hrn', - query = 'none', - slicename = slicename, - o = 'cpu' - ) - - resources_stats_mem = SliceStat( - title = "Memory Usage", - domid = 'resources-stats-mem', - page = page, - stats = 'slice', - key = 'hrn', - query = 'none', - slicename = slicename, - o = 'mem' - ) - - resources_stats_asb = SliceStat( - title = "Traffic Sent", - domid = 'resources-stats-asb', - page = page, - stats = 'slice', - key = 'hrn', - query = 'none', - slicename = slicename, - o = 'asb' - ) - - resources_stats_arb = SliceStat( - title = "Traffic Received", - domid = 'resources-stats-arb', - page = page, - stats = 'slice', - key = 'hrn', - query = 'none', - slicename = slicename, - o = 'arb' - ) - - # with the new 'Filter' stuff on top, no need for anything but the hazelnut + if insert_grid: + resources_as_grid = QueryGrid( + page = page, + domid = 'resources-grid', + title = 'Grid view', + # this is the query at the core of the slice list + query = sq_resource, + query_all = query_resource_all, + init_key = main_query_init_key, + checkboxes = True, + ) + + if do_query_leases: + resources_as_scheduler = Scheduler( + page = page, + title = 'Scheduler', + domid = 'scheduler', + query = sq_resource, + query_all_resources = query_resource_all, + query_lease = sq_lease, + ) + + # with the new 'Filter' stuff on top, no need for anything but the querytable resources_as_list_area = resources_as_list + resources_sons = [ + resources_as_gmap, + resources_as_3dmap, + resources_as_scheduler, + resources_as_list_area, + ] if do_query_leases else [ + resources_as_gmap, + resources_as_3dmap, + resources_as_list_area, + ] + if insert_grid: + resources_sons.append(resources_as_grid) + resources_area = Tabs ( page=page, domid="resources", togglable=True, title="Resources", outline_complete=True, - sons=[ resources_as_map, resources_as_list_area, resources_stats_cpu, resources_stats_mem, resources_stats_asb, resources_stats_arb ], + sons= resources_sons, active_domid = 'resources-map', + persistent_active=True, ) main_stack.insert (resources_area) # -------------------------------------------------------------------------- # USERS - if do_query_users: + if do_query_users and query_user_all is not None: tab_users = Tabs( page = page, domid = 'users', @@ -246,7 +295,7 @@ class SliceView (LoginRequiredAutoLogoutView): ) main_stack.insert(tab_users) - tab_users.insert(Hazelnut( + tab_users.insert(QueryTable( page = page, title = 'Users List', domid = 'users-list', @@ -266,6 +315,62 @@ class SliceView (LoginRequiredAutoLogoutView): # DEMO # -------------------------------------------------------------------------- # MEASUREMENTS + measurements_stats_cpu = SliceStat( + title = "CPU Usage", + domid = 'resources-stats-cpu', + page = page, + stats = 'slice', + key = 'hrn', + query = 'none', + slicename = slicename, + o = 'cpu' + ) + + measurements_stats_mem = SliceStat( + title = "Memory Usage", + domid = 'resources-stats-mem', + page = page, + stats = 'slice', + key = 'hrn', + query = 'none', + slicename = slicename, + o = 'mem' + ) + + measurements_stats_asb = SliceStat( + title = "Traffic Sent", + domid = 'resources-stats-asb', + page = page, + stats = 'slice', + key = 'hrn', + query = 'none', + slicename = slicename, + o = 'asb' + ) + + measurements_stats_arb = SliceStat( + title = "Traffic Received", + domid = 'resources-stats-arb', + page = page, + stats = 'slice', + key = 'hrn', + query = 'none', + slicename = slicename, + o = 'arb' + ) + + tab_measurements = Tabs ( page=page, + domid = "measurements", + togglable = True, + toggled = 'persistent', + title = "Measurements", + outline_complete=True, + sons = [ measurements_stats_cpu, measurements_stats_mem, measurements_stats_asb, measurements_stats_arb ], + active_domid = 'resources-stats-cpu', + persistent_active = True, + ) + main_stack.insert (tab_measurements) + # tab_measurements = Tabs ( # page = page, # active_domid = 'measurements-list', @@ -276,7 +381,7 @@ class SliceView (LoginRequiredAutoLogoutView): # ) # main_stack.insert(tab_measurements) # -# tab_measurements.insert(Hazelnut( +# tab_measurements.insert(QueryTable( # page = page, # title = 'Measurements', # domid = 'measurements-list', @@ -296,43 +401,38 @@ class SliceView (LoginRequiredAutoLogoutView): # # # -------------------------------------------------------------------------- # # MESSAGES (we use transient=False for now) -# main_stack.insert(Messages( -# page = page, -# title = "Runtime messages for slice %s"%slicename, -# domid = "msgs-pre", -# levels = "ALL", -# # plain messages are probably less nice for production but more reliable for development for now -# transient = False, -# # these make sense only in non-transient mode.. -# togglable = True, -# toggled = 'persistent', -# outline_complete = True, -# )) -# + if insert_messages: + main_stack.insert(Messages( + page = page, + title = "Runtime messages for slice %s"%slicename, + domid = "msgs-pre", + levels = "ALL", + # plain messages are probably less nice for production but more reliable for development for now + transient = False, + # these make sense only in non-transient mode.. + togglable = True, + toggled = 'persistent', + outline_complete = True, + )) # variables that will get passed to the view-unfold1.html template template_env = {} - # define 'unfold1_main' to the template engine - the main contents - template_env [ 'unfold1_main' ] = main_stack.render(request) + # define 'unfold_main' to the template engine - the main contents + template_env [ 'unfold_main' ] = main_stack.render(request) # more general variables expected in the template template_env [ 'title' ] = '%(slicename)s'%locals() # the menu items on the top - template_env [ 'topmenu_items' ] = topmenu_items('Slice', request) + template_env [ 'topmenu_items' ] = topmenu_items_live('Slice', page) # so we can sho who is logged template_env [ 'username' ] = the_user (request) # don't forget to run the requests - page.expose_queries () - - # xxx create another plugin with the same query and a different layout (with_datatables) - # show that it worls as expected, one single api call to backend and 2 refreshed views - + page.expose_js_metadata() # the prelude object in page contains a summary of the requirements() for all plugins # define {js,css}_{files,chunks} - prelude_env = page.prelude_env() - template_env.update(prelude_env) - result=render_to_response ('view-unfold1.html',template_env, + template_env.update(page.prelude_env()) + + return render_to_response ('view-unfold1.html',template_env, context_instance=RequestContext(request)) - return result