Scheduler: adding/removing resources enforce warnings and recount number of unconfigu...
[myslice.git] / portal / sliceresourceview.py
1 import json
2
3 from django.template                    import RequestContext
4 from django.shortcuts                   import render_to_response
5 from django.views.generic.base          import TemplateView
6 from django.http import HttpResponse
7 from django.shortcuts import render
8
9 from manifold.core.query                import Query, AnalyzedQuery
10 from manifoldapi.manifoldapi            import execute_query
11
12
13 from unfold.loginrequired               import LoginRequiredView
14 from unfold.page                        import Page
15
16 from myslice.configengine               import ConfigEngine
17
18 from plugins.apply                      import ApplyPlugin
19 from plugins.querytable                 import QueryTable
20 from plugins.googlemap                  import GoogleMap
21 # from plugins.queryupdater               import QueryUpdaterPlugin
22 from plugins.filter_status              import FilterStatusPlugin
23 from plugins.testbeds                   import TestbedsPlugin
24 from plugins.scheduler2                 import Scheduler2
25
26 # Bristol plugin
27 from plugins.univbris                   import Univbris
28 from plugins.univbrisfoam               import UnivbrisFoam
29 from plugins.univbrisfv                 import UnivbrisFv
30 from plugins.univbrisfvf                import UnivbrisFvf
31 from plugins.univbrisfvfo               import UnivbrisFvfo
32 from plugins.univbristopo               import UnivbrisTopo
33 from plugins.univbrisvtam               import UnivbrisVtam as UnivbrisVtamPlugin
34 from plugins.univbrisvtamform           import UnivbrisVtamForm
35
36 from plugins.columns_editor             import ColumnsEditor
37 from plugins.sladialog                  import SlaDialog
38 from plugins.lists.simplelist           import SimpleList
39
40 from myslice.theme import ThemeView
41 from myslice.settings import logger
42
43 class SliceResourceView (LoginRequiredView, ThemeView):
44     template_name = "slice-resource-view.html"
45     
46     def get(self, request, slicename):
47
48         if request.GET.get('message') : 
49             msg = "Slice successfully updated"
50         else :
51             msg = None
52
53         page = Page(request)
54         metadata = page.get_metadata()
55         page.expose_js_metadata()
56
57         resource_md = metadata.details_by_object('resource')
58         resource_fields = [column['name'] for column in resource_md['column']]
59
60         user_md = metadata.details_by_object('user')
61         user_fields = ['user_hrn'] # [column['name'] for column in user_md['column']]
62
63         query_resource_all = Query.get('resource').select(resource_fields)
64         #page.enqueue_query(query_resource_all)
65
66         # leases query
67         #lease_md = metadata.details_by_object('lease')
68         #lease_fields = [column['name'] for column in lease_md['column']]
69
70         #query_lease_all = Query.get('lease').select(lease_fields)
71         #page.enqueue_query(query_lease_all)
72
73         slice_md = metadata.details_by_object('slice')
74         slice_fields = [column['name'] for column in slice_md['column']]
75         logger.debug("SLICE RES VIEW fields = {}".format(slice_fields))
76         # TODO The query to run is embedded in the URL
77         # Example: select slice_hrn, resource.urn, lease.resource, lease.start_time, lease.end_time from slice where slice_hrn == "ple.upmc.myslicedemo"
78         main_query = Query.get('slice').filter_by('slice_hrn', '=', slicename)
79         main_query.select(slice_fields)
80
81         # Columns shown by default in Query_table plugin
82         page.expose_js_var("QUERYTABLE_MAP","{'Resource name': 'hostname', 'Type': 'type', 'Facility': 'facility_name','Testbed': 'testbed_name', 'Status':'boot_state'}")
83        
84         # Columns checked by default in Columns_selector plugin
85         query_default_fields = ['hostname', 'type', 'facility_name', 'testbed_name', 'boot_state']
86
87         QUERYTABLE_MAP = { 
88             'hostname'      :   'Resource name',
89             'type'          :   'Type',
90             'facility_name' :   'Facility',
91             'testbed_name'  :   'Testbed',
92             'boot_state'    :   'Status',
93         }
94
95
96         #        # SLICE
97         #        'slice_hrn',
98         #        # - The record key is needed otherwise the storage of records
99         #        #   bugs !
100         #        'slice_urn',
101         #        # RESOURCES
102         #        'resource',
103         #        'lease',
104         #        'resource.urn',
105         #        'resource.hostname', 'resource.type',
106         #        # - The facility_name and testbed_name are required for the
107         #        #   testbeds plugin to properly work.
108         #        'resource.facility_name',
109         #        'resource.testbed_name',
110         #        # LEASES
111         #        'lease.resource',
112         #        'lease.start_time',
113         #        'lease.end_time',
114         #        # - The lease_id is important for NITOS identify already existing
115         #        #   leases
116         #        'lease.lease_id',
117
118         #        # FLOWSPACE
119         #        #'flowspace',
120         #        # VMS
121         #        #'vms',
122
123
124         #        #'user.user_hrn',
125         #        #'application.measurement_point.counter'
126         #)
127         # for internal use in the querytable plugin;
128         # needs to be a unique column present for each returned record
129         main_query_init_key = 'urn'
130         aq = AnalyzedQuery(main_query, metadata=metadata)
131         page.enqueue_query(main_query, analyzed_query=aq)
132         sq_resource    = aq.subquery('resource')
133         sq_lease       = aq.subquery('lease')
134         #sq_flowspace   = aq.subquery('flowspace')
135         #sq_vms         = aq.subquery('vms')
136
137         # --------------------------------------------------------------------------
138         # ALL RESOURCES LIST
139         # resources as a list using datatable plugin
140  
141         list_resources     = QueryTable(
142             page           = page,
143             domid          = 'resources-list',
144             title          = 'List view',
145             query          = sq_resource,
146             query_all      = query_resource_all,
147             mapping        = QUERYTABLE_MAP,
148             default_fields = query_default_fields,
149             init_key       = "urn",
150             checkboxes     = True,
151             datatables_options = {
152                 'iDisplayLength': 25,
153                 'bLengthChange' : True,
154                 'bAutoWidth'    : True,
155                 },
156         )
157
158
159         # --------------------------------------------------------------------------
160         # RESERVED RESOURCES LIST
161         # resources as a list using datatable plugin
162  
163         list_reserved_resources = SimpleList(
164             title = None,
165             page  = page,
166             key   = 'urn',
167             query = sq_resource,
168         )
169
170         list_reserved_leases = SimpleList(
171             title = None,
172             page  = page,
173             key   = 'resource',
174             query = sq_lease,
175         )
176
177 #        list_reserved_resources = QueryTable(
178 #            page       = page,
179 #            domid      = 'resources-reserved-list',
180 #            title      = 'List view',
181 #            query      = sq_resource,
182 #            query_all  = sq_resource,
183 #            init_key   = "urn",
184 #            checkboxes = True,
185 #            datatables_options = {
186 #                'iDisplayLength': 25,
187 #                'bLengthChange' : True,
188 #                'bAutoWidth'    : True,
189 #                },
190 #        )
191
192         # --------------------------------------------------------------------------
193         # COLUMNS EDITOR
194         # list of fields to be applied on the query 
195         # this will add/remove columns in QueryTable plugin
196  
197         filter_column_editor = ColumnsEditor(
198             page  = page,
199             query = sq_resource, 
200             query_all = query_resource_all,
201             default_fields = query_default_fields,
202             title = "Select Columns",
203             domid = 'select-columns',
204         )
205
206         # --------------------------------------------------------------------------
207         # RESOURCES MAP
208         # the resources part is made of a Tabs (Geographic, List), 
209
210         map_resources  = GoogleMap(
211             page       = page,
212             title      = 'Geographic view',
213             domid      = 'resources-map',
214             # tab's sons preferably turn this off
215             togglable  = False,
216             query      = sq_resource,
217             # this key is the one issued by google
218             googlemap_api_key = ConfigEngine().googlemap_api_key(),
219             # the key to use at init-time
220             init_key   = main_query_init_key,
221             checkboxes = True,
222             
223             # To center around Europe : 53,9 / 3
224             latitude   = 53.,
225             longitude  = 9.,
226             zoom       = 3,
227         )
228
229         # --------------------------------------------------------------------------
230         # LEASES Nitos Scheduler
231         # Display the leases reservation timeslots of the resources
232
233         resources_as_scheduler2 = Scheduler2( 
234             page       = page,
235             domid      = 'scheduler',
236             title      = 'Scheduler',
237             # this is the query at the core of the slice list
238             query = sq_resource,
239             query_lease = sq_lease,
240         )
241
242         # --------------------------------------------------------------------------
243         # QueryUpdater (Pending Operations)
244  
245 #         pending_resources = QueryUpdaterPlugin(
246 #             page                = page,
247 #             title               = 'Pending operations',
248 #             query               = main_query,
249 #             togglable           = False,
250 #             # start turned off, it will open up itself when stuff comes in
251 #             toggled             = False,
252 #             domid               = 'pending',
253 #             outline_complete    = True,
254 #             username            = request.user,
255 #         )
256
257         # --------------------------------------------------------------------------
258         # NETWORKS
259         # testbeds as a list of filters 
260
261         network_md = metadata.details_by_object('network')
262         network_fields = [column['name'] for column in network_md['column']]
263
264         #query_networks = Query.get('network').select(network_fields)
265         #page.enqueue_query(query_networks)
266
267         filter_testbeds = TestbedsPlugin(
268             page            = page,
269             domid           = 'testbeds-filter',
270             title           = 'Filter by testbeds',
271             query           = sq_resource,
272             #query_networks  = query_networks,
273             #init_key        = "network_hrn",
274             #checkboxes      = True,
275             #datatables_options = {
276             #    'iDisplayLength': 25,
277             #    'bLengthChange' : True,
278             #    'bAutoWidth'    : True,
279             #    },
280         )
281
282         filter_status = FilterStatusPlugin(
283             page            = page,
284             domid           = "filter-status",
285             query           = sq_resource,
286             query_lease     = sq_lease,
287         )
288         apply = ApplyPlugin(
289             page            = page,
290             domid           = "apply",
291             query           = main_query,
292             username            = request.user,
293         )
294             
295         # --------------------------------------------------------------------------
296         # Ofelia OpenFlow Plugin 
297         # Bristol plugin
298
299         # plugin which display a "gathering resources" message 
300         # waiting for all resources to be returned by manifold
301        # univbriswelcome = Univbris(
302        #     page  = page,
303        #     title = 'univbris_welcome',
304        #     domid = 'univbris_welcome',
305        #     query = query_resource_all,
306        # )
307
308        # univbrisfoamlist = UnivbrisFoam(
309        #     page  = page,
310        #     title = 'univbris_foam_ports_selection',
311        #     domid = 'univbris_foam_ports_selection',
312        #     query = query_resource_all,
313        #     query_all = query_resource_all,
314        #     checkboxes = False,
315        #     datatables_options = {
316        #         'iDisplayLength': 10,
317        #         'bLengthChange' : True,
318        #         'bAutoWidth'    : True,
319        #         },
320        # )
321
322        # #plugin which manages the different flowspaces that the user creates, and also sends flowspaces to manifold
323        # univbrisfvlist = UnivbrisFv(
324        #         page  = page,
325        #         title = 'univbris_flowspace_selection',
326        #         domid = 'univbris_flowspace_selection',
327        #         query = sq_flowspace,
328        #         query_all = query_resource_all,
329        #         datatables_options = {
330        #             'iDisplayLength': 5,
331        #             'bLengthChange' : True,
332        #             'bAutoWidth'    : True,
333        #             },
334        # )
335
336        # #plugin which allows the definition of a single flowspace
337        # univbrisfvform = UnivbrisFvf(
338        #         page  = page,
339        #         title = 'univbris_flowspace_form',
340        #         domid = 'univbris_flowspace_form',
341        #         query = query_resource_all,
342        #         query_all = None,
343        #         datatables_options = {
344        #             'iDisplayLength': 3,
345        #             'bLengthChange' : True,
346        #             'bAutoWidth'    : True,
347        #             },
348        # )
349
350            # #plugin which allows the definition the match criteria on a single OPTICAL flowspace
351        # univbrisofvform = UnivbrisFvfo(
352        #     page  = page,
353        #     title = 'univbris_oflowspace_form',
354        #     domid = 'univbris_oflowspace_form',
355            #     query = None,
356        #     query_all = None,
357        #     datatables_options = { 
358        #         'iDisplayLength': 3,
359        #         'bLengthChange' : True,
360        #         'bAutoWidth'    : True,
361        #         },
362        # )
363
364        # #plugin which display the gathered topology
365        # univbristopology = UnivbrisTopo(
366        #     page  = page,
367        #     title = 'univbris_topology',
368        #     domid = 'univbris_topology',
369        #     query = query_resource_all,
370        # )
371
372        # # --------------------------------------------------------------------------
373        # # Ofelia VTAM Plugin 
374        # # Bristol Plugin
375
376        # #plugin which display a table where an experimenter will add VMs to according to his needs
377        # # responsible to send the data to Manifold
378        # univbrisvtamplugin = UnivbrisVtamPlugin(
379        #     page  = page,
380        #     title = 'univbris_vtam',
381        #     domid = 'univbris_vtam',
382        #     query = sq_vms,
383        #     #query = sq_resource,
384        # )
385
386        # #plugin which display a form where an experimenter will specify 
387        # # in which testbed and which physical server to setup the VM
388        # univbrisvtamform = UnivbrisVtamForm(
389        #     page  = page,
390        #     title = 'univbris_vtam_form',
391        #     domid = 'univbris_vtam_form',
392            #     query =  query_resource_all,
393        #     query_all = None,
394        #     datatables_options = { 
395        #         'iDisplayLength': 3,
396        #         'bLengthChange' : True,
397        #         'bAutoWidth'    : True,
398        #         },
399        # )
400
401        # # --------------------------------------------------------------------------
402        # # SLA View and accept dialog
403        # 
404        # sla_dialog = SlaDialog(
405        #     page                = page,
406        #     title               = 'sla dialog',
407        #     query               = main_query,
408        #     togglable           = False,
409        #     # start turned off, it will open up itself when stuff comes in
410        #     toggled             = True,
411        #     domid               = 'sla_dialog',
412        #     outline_complete    = True,
413        #     username            = request.user,
414        # )
415        # 
416         ## check user is pi or not
417         platform_query  = Query().get('local:platform').select('platform_id','platform','gateway_type','disabled')
418         account_query  = Query().get('local:account').select('user_id','platform_id','auth_type','config')
419         platform_details = execute_query(self.request, platform_query)
420         account_details = execute_query(self.request, account_query)
421
422         # XXX When session has expired, this is None and thus not iterable
423         for platform_detail in platform_details:
424             for account_detail in account_details:
425                 if platform_detail['platform_id'] == account_detail['platform_id']:
426                     if 'config' in account_detail and account_detail['config'] is not '':
427                         account_config = json.loads(account_detail['config'])
428                         if 'myslice' in platform_detail['platform']:
429                             acc_auth_cred = account_config.get('delegated_authority_credentials','N/A')
430         # assigning values
431         if acc_auth_cred == {} or acc_auth_cred == 'N/A':
432             pi = "is_not_pi"
433         else:
434             pi = "is_pi"
435         
436         template_env = {}
437         template_env['list_resources'] = list_resources.render(self.request)
438         template_env['list_reserved_resources'] = list_reserved_resources.render(self.request)
439         template_env['list_reserved_leases'] = list_reserved_leases.render(self.request)
440
441         template_env['columns_editor'] = filter_column_editor.render(self.request)
442
443         template_env['filter_testbeds'] = filter_testbeds.render(self.request)
444         template_env['filter_status'] = filter_status.render(self.request)
445         template_env['apply'] = apply.render(self.request)
446
447         template_env['map_resources'] = map_resources.render(self.request)
448         template_env['scheduler'] = resources_as_scheduler2.render(self.request)
449
450         # Bristol plugin
451        # template_env['welcome'] = univbriswelcome.render(self.request)
452        # template_env['resources'] = univbrisfoamlist.render(self.request)
453        # template_env['flowspaces'] = univbrisfvlist.render(self.request)
454        # template_env['oflowspaces_form'] = univbrisofvform.render(self.request)
455        # template_env['flowspaces_form'] = univbrisfvform.render(self.request)
456        # template_env['topology'] = univbristopology.render(self.request)
457        # template_env['vms_list'] = univbrisvtamplugin.render(self.request)
458        # template_env['vm_form'] = univbrisvtamform.render(self.request)
459
460 #        template_env['pending_resources'] = pending_resources.render(self.request)
461        # template_env['sla_dialog'] = '' # sla_dialog.render(self.request)
462         template_env["theme"] = self.theme
463         template_env["username"] = request.user
464         template_env["pi"] = pi
465         template_env["slice"] = slicename
466         template_env["section"] = "resources"
467         template_env["msg"] = msg
468         template_env.update(page.prelude_env())
469
470         return render_to_response(self.template, template_env, context_instance=RequestContext(request))