2 from django.template import RequestContext
3 from django.shortcuts import render_to_response
5 from unfold.loginrequired import LoginRequiredAutoLogoutView
7 from unfold.page import Page
8 from manifold.core.query import Query, AnalyzedQuery
9 from manifold.manifoldapi import execute_query
11 from ui.topmenu import topmenu_items_live, the_user
13 from plugins.raw import Raw
14 from plugins.stack import Stack
15 from plugins.tabs import Tabs
16 from plugins.querytable import QueryTable
17 from plugins.querygrid import QueryGrid
18 from plugins.queryupdater import QueryUpdater
19 from plugins.googlemap import GoogleMap
20 from plugins.senslabmap import SensLabMap
21 #from plugins.scheduler import Scheduler
22 from plugins.scheduler2 import Scheduler2
23 from plugins.querycode import QueryCode
25 # stay away from query editor for now as it seems to make things go very slow
26 # see https://lists.myslice.info/pipermail/devel-myslice/2013-December/000221.html
27 from plugins.query_editor import QueryEditor
28 from plugins.active_filters import ActiveFilters
29 from plugins.quickfilter import QuickFilter
30 from plugins.messages import Messages
31 from plugins.slicestat import SliceStat
33 from myslice.configengine import ConfigEngine
35 tmp_default_slice='ple.upmc.myslicedemo'
37 # temporary : turn off the users part to speed things up
50 class SliceView (LoginRequiredAutoLogoutView):
52 def get (self,request, slicename=tmp_default_slice):
55 page.add_css_files ('css/slice-view.css')
56 page.add_js_files ( [ "js/common.functions.js" ] )
57 page.add_js_chunks ('$(function() { messages.debug("sliceview: jQuery version " + $.fn.jquery); });')
58 page.add_js_chunks ('$(function() { messages.debug("sliceview: users turned %s"); });'%("on" if do_query_users else "off"))
59 page.add_js_chunks ('$(function() { messages.debug("sliceview: leases turned %s"); });'%("on" if do_query_leases else "off"))
60 page.add_js_chunks ('$(function() { messages.debug("manifold URL %s"); });'%(ConfigEngine().manifold_url()))
62 metadata = page.get_metadata()
63 resource_md = metadata.details_by_object('resource')
64 resource_fields = [column['name'] for column in resource_md['column']]
66 user_md = metadata.details_by_object('user')
67 user_fields = ['user_hrn'] # [column['name'] for column in user_md['column']]
69 # TODO The query to run is embedded in the URL
70 main_query = Query.get('slice').filter_by('slice_hrn', '=', slicename)
73 #'resource.hrn', 'resource.urn',
74 'resource.hostname', 'resource.type',
75 'resource.network_hrn',
78 #'application.measurement_point.counter'
80 # for internal use in the querytable plugin;
81 # needs to be a unique column present for each returned record
82 main_query_init_key = 'hostname'
84 query_resource_all = Query.get('resource').select(resource_fields)
86 aq = AnalyzedQuery(main_query, metadata=metadata)
87 page.enqueue_query(main_query, analyzed_query=aq)
88 page.enqueue_query(query_resource_all)
90 # Required: the user must have an authority in its user.config
91 # XXX Temporary solution
92 user_query = Query().get('local:user').select('config','email')
93 user_details = execute_query(self.request, user_query)
95 # not always found in user_details...
97 # for user_detail in user_details:
98 # #email = user_detail['email']
99 # if user_detail['config']:
100 # config = json.loads(user_detail['config'])
101 # user_detail['authority'] = config.get('authority',"Unknown Authority")
103 # if user_detail['authority'] is not None:
104 # sub_authority = user_detail['authority'].split('.')
105 # root_authority = sub_authority[0]
106 # query_user_all = Query.get(root_authority+':user').select(user_fields)
108 # # XXX TODO this filter doesn't work - to be improved in Manifold
109 # #.filter_by('authority.authority_hrn', '=', user_detail['authority'])
111 # page.enqueue_query(query_user_all)
113 # print "authority of the user is not in local:user db"
114 query_user_all = Query.get('user').select(user_fields)
115 # query_user_all = None
117 # ... and for the relations
118 # XXX Let's hardcode resources for now
119 sq_resource = aq.subquery('resource')
120 sq_user = aq.subquery('user')
121 sq_lease = aq.subquery('lease')
122 sq_measurement = aq.subquery('measurement')
125 # Prepare the display according to all metadata
126 # (some parts will be pending, others can be triggered by users).
128 # For example slice measurements will not be requested by default...
130 # Create the base layout (Stack)...
133 title="Slice %s"%slicename,
137 # ... responsible for the slice properties...
144 html="<h2 class='well well-lg'> Slice %s</h2>"%slicename)
147 # --------------------------------------------------------------------------
148 # QueryUpdater (Pending Operations)
150 main_stack.insert(QueryUpdater(
152 title = 'Pending operations',
155 # start turned off, it will open up itself when stuff comes in
158 outline_complete = True,
161 # --------------------------------------------------------------------------
164 # turn off for now -- see above
165 filter_query_editor = QueryEditor(
168 query_all = query_resource_all,
169 title = "Select Columns",
170 domid = 'select-columns',
172 filter_active_filters = ActiveFilters(
175 title = "Active Filters",
177 filters_area = Stack(
179 title = 'Filter Resources',
181 sons = [filter_query_editor,
182 filter_active_filters],
184 toggled = 'persistent',
185 outline_complete = True,
187 main_stack.insert (filters_area)
189 # --------------------------------------------------------------------------
191 # the resources part is made of a Tabs (Geographic, List),
193 resources_as_gmap = GoogleMap(
195 title = 'Geographic view',
196 domid = 'resources-map',
197 # tab's sons preferably turn this off
200 query_all = query_resource_all,
201 # this key is the one issued by google
202 googlemap_api_key = ConfigEngine().googlemap_api_key(),
203 # the key to use at init-time
204 init_key = main_query_init_key,
212 resources_as_3dmap = SensLabMap(
215 domid = 'senslabmap',
217 query_all = query_resource_all,
220 resources_as_list = QueryTable(
222 domid = 'resources-list',
224 # this is the query at the core of the slice list
226 query_all = query_resource_all,
227 init_key = main_query_init_key,
229 datatables_options = {
230 'iDisplayLength': 25,
231 'bLengthChange' : True,
237 resources_as_grid = QueryGrid(
239 domid = 'resources-grid',
241 # this is the query at the core of the slice list
243 query_all = query_resource_all,
244 init_key = main_query_init_key,
251 # resources_as_scheduler = Scheduler(
254 # title = 'Scheduler',
255 # domid = 'scheduler',
256 # query = sq_resource,
257 # query_all_resources = query_resource_all,
258 # query_lease = sq_lease,
262 resources_as_scheduler2 = Scheduler2(
266 # this is the query at the core of the slice list
268 query_all_resources = query_resource_all,
269 query_lease = sq_lease,
272 # with the new 'Filter' stuff on top, no need for anything but the querytable
273 resources_as_list_area = resources_as_list
278 resources_as_scheduler2,
279 resources_as_list_area,
280 ] if do_query_leases else [
283 resources_as_list_area,
284 resources_as_scheduler2,
287 resources_sons.append(resources_as_grid)
289 resources_area = Tabs ( page=page,
293 outline_complete=True,
294 sons= resources_sons,
296 active_domid = 'scheduler',
297 persistent_active=True,
299 main_stack.insert (resources_area)
301 # --------------------------------------------------------------------------
304 if do_query_users and query_user_all is not None:
308 outline_complete = True,
311 active_domid = 'users-list',
313 main_stack.insert(tab_users)
315 tab_users.insert(QueryTable(
317 title = 'Users List',
318 domid = 'users-list',
319 # tab's sons preferably turn this off
321 # this is the query at the core of the slice list
323 query_all = query_user_all,
325 datatables_options = {
326 'iDisplayLength' : 25,
327 'bLengthChange' : True,
333 # --------------------------------------------------------------------------
335 measurements_stats_cpu = SliceStat(
337 domid = 'resources-stats-cpu',
342 slicename = slicename,
346 measurements_stats_mem = SliceStat(
347 title = "Memory Usage",
348 domid = 'resources-stats-mem',
353 slicename = slicename,
357 measurements_stats_asb = SliceStat(
358 title = "Traffic Sent",
359 domid = 'resources-stats-asb',
364 slicename = slicename,
368 measurements_stats_arb = SliceStat(
369 title = "Traffic Received",
370 domid = 'resources-stats-arb',
375 slicename = slicename,
379 tab_measurements = Tabs ( page=page,
380 domid = "measurements",
382 toggled = 'persistent',
383 title = "Measurements",
384 outline_complete=True,
385 sons = [ measurements_stats_cpu, measurements_stats_mem, measurements_stats_asb, measurements_stats_arb ],
386 active_domid = 'resources-stats-cpu',
387 persistent_active = True,
389 main_stack.insert (tab_measurements)
391 # tab_measurements = Tabs (
393 # active_domid = 'measurements-list',
394 # outline_complete = True,
396 # title = 'Measurements',
397 # domid = 'measurements',
399 # main_stack.insert(tab_measurements)
401 # tab_measurements.insert(QueryTable(
403 # title = 'Measurements',
404 # domid = 'measurements-list',
405 # # tab's sons preferably turn this off
407 # # this is the query at the core of the slice list
408 # query = sq_measurement,
409 # # do NOT set checkboxes to False
410 # # this table being otherwise empty, it just does not fly with dataTables
412 # datatables_options = {
413 # 'iDisplayLength' : 25,
414 # 'bLengthChange' : True,
415 # 'bAutoWidth' : True,
419 # # --------------------------------------------------------------------------
420 # # MESSAGES (we use transient=False for now)
422 main_stack.insert(Messages(
424 title = "Runtime messages for slice %s"%slicename,
427 # plain messages are probably less nice for production but more reliable for development for now
429 # these make sense only in non-transient mode..
431 toggled = 'persistent',
432 outline_complete = True,
435 # variables that will get passed to the view-unfold1.html template
438 # define 'unfold_main' to the template engine - the main contents
439 template_env [ 'unfold_main' ] = main_stack.render(request)
441 # more general variables expected in the template
442 template_env [ 'title' ] = '%(slicename)s'%locals()
443 # the menu items on the top
444 template_env [ 'topmenu_items' ] = topmenu_items_live('Slice', page)
445 # so we can sho who is logged
446 template_env [ 'username' ] = the_user (request)
448 # don't forget to run the requests
449 page.expose_js_metadata()
450 # the prelude object in page contains a summary of the requirements() for all plugins
451 # define {js,css}_{files,chunks}
452 template_env.update(page.prelude_env())
454 return render_to_response ('view-unfold1.html',template_env,
455 context_instance=RequestContext(request))