Explorar o código

HUE-6176 [frontend] Harmonize app permissions in UI

Romain Rigaux %!s(int64=8) %!d(string=hai) anos
pai
achega
e36ea30

+ 46 - 75
desktop/core/src/desktop/templates/hue.mako

@@ -947,45 +947,45 @@ ${ smart_unicode(login_modal(request).content) | n,unicode }
 
         self.quickCreateActions = [];
 
-        % if 'impala' in apps:
+        % if cluster_config.main_quick_action:
           self.mainQuickCreateAction = {
-            displayName: '${ _('Query') }',
-            icon: 'impala',
+            displayName: '${ cluster_config.main_quick_action['displayName'] }',
+            // Tooltip
+            icon: '${ cluster_config.main_quick_action['type'] }',
             click: function(){
-              page('/editor?type=impala');
-            }
-          };
-        % elif 'beeswax' in apps:
-          self.mainQuickCreateAction = {
-            displayName: '${ _('Query Hive') }',
-            icon: 'hive',
-            click: function(){
-              page('/editor?type=hive');
+              page('${ cluster_config.main_quick_action['page'] }');
             }
           };
         % endif
 
-        % if interpreters:
-          var interpreters = [];
-
-          interpreters.push({
-            displayName: '${ _('Notebook') }',
-            icon: 'notebook',
-            click: function(){
-              page('/notebook');
+        
+        % for name, app in cluster_config.get_apps().iteritems():
+          var interpreters = []; 
+          
+          % if name == 'editor' and SHOW_NOTEBOOKS.get():
+           interpreters.push({
+             displayName: '${ _('Notebook') }',
+             icon: 'notebook',
+             click: function(){
+               page('/notebook');
             }
           });
-        % for interpreter in interpreters:
-          interpreters.push({
-            displayName: '${ interpreter['name'] }',
-            dividerAbove: interpreters.length === 1,
-            icon: '${ interpreter['type'] }',
-            click: function () {
-              page('/editor?type=${ interpreter['type'] }');
-            }
-          });
-        %endfor
-        % if user.is_superuser:
+          % endif
+          
+          % for interpreter in app['interpreters']:
+            interpreters.push({
+              displayName: '${ interpreter['displayName'] }',
+              % if name == 'editor' and SHOW_NOTEBOOKS.get():
+              dividerAbove: interpreters.length === 1,
+              % endif
+              icon: '${ interpreter['type'] }',
+              click: function () {
+                page('/${ interpreter['page'] }');
+              }
+            });
+          % endfor
+          
+          % if name == 'editor' and user.is_superuser:
           interpreters.push({
             displayName: '${ _('Add more...') }',
             dividerAbove: true,
@@ -993,55 +993,26 @@ ${ smart_unicode(login_modal(request).content) | n,unicode }
               window.open('http://gethue.com/sql-editor/', '_blank');
             }
           });
-        % endif
-
-          self.quickCreateActions.push({
-            displayName: '${ _('Editor') }',
-            icon: 'editor',
-            isCategory: true,
-            children: interpreters
-          });
-        %endif
-
-        % if IS_DASHBOARD_ENABLED.get():
-          self.quickCreateActions.push({
-            displayName: '${ _('Dashboard') }',
-            icon: 'dashboard',
-            click: function () {
-              page('/dashboard/new_search');
-            }
-          });
-        % endif
-
+          % endif
 
-        % if 'oozie' in apps:
-          % if not user.has_hue_permission(action="disable_editor_access", app="oozie") or user.is_superuser:
+          % if app['interpreters']:
             self.quickCreateActions.push({
-              displayName: '${ _('Scheduler') }',
-              icon: 'oozie',
+              displayName: '${ app['displayName'] }',
+              icon: '${ app['name'] }',
               isCategory: true,
-              children: [{
-                displayName: '${_('Workflow')}',
-                icon: 'oozie-workflow',
-                click: function() {
-                  page('/oozie/editor/workflow/new/')
-                }
-              }, {
-                displayName: '${_('Schedule')}',
-                icon: 'oozie-coordinator',
-                click: function() {
-                  page('/oozie/editor/coordinator/new/')
-                }
-              }, {
-                displayName: '${_('Bundle')}',
-                icon: 'oozie-bundle',
-                click: function() {
-                  page('/oozie/editor/bundle/new/')
-                }
-              }]
+              children: interpreters
+            });
+          % else:
+            self.quickCreateActions.push({
+              displayName: '${ app['displayName'] }',
+              icon: '${ app['name'] }',
+              click: function () {
+                page('${ app['page'] }');
+              }
             });
           % endif
-        % endif
+        
+        % endfor
 
         self.searchAutocompleteSource = function (request, callback) {
           // TODO: Extract complete contents to common module (shared with nav search autocomplete)

+ 159 - 1
desktop/core/src/desktop/views.py

@@ -27,6 +27,11 @@ import time
 import traceback
 import zipfile
 
+try:
+  from collections import OrderedDict
+except ImportError:
+  from ordereddict import OrderedDict # Python 2.6
+
 from django.conf import settings
 from django.shortcuts import render_to_response
 from django.http import HttpResponse
@@ -39,6 +44,7 @@ from django.views.decorators.http import require_http_methods, require_POST
 import django.views.debug
 
 from aws.conf import is_enabled as is_s3_enabled, has_s3_access
+from dashboard.conf import IS_ENABLED as IS_DASHBOARD_ENABLED
 from notebook.conf import get_ordered_interpreters
 
 import desktop.conf
@@ -67,6 +73,154 @@ def is_alive(request):
   return HttpResponse('')
 
 
+class ClusterConfig():
+  
+  def __init__(self, user, apps=None):
+    self.user = user
+    self.apps = appmanager.get_apps_dict(self.user) if apps is None else apps
+  
+  def setConfig(self):
+    # dataeng Execute  in Hive by default
+    #         JB: hide yarn, show dataeng
+    # Nav, NavOpt?
+    # reload "some ini sections"
+    pass
+  
+  @property
+  def main_quick_action(self):
+    return self._get_editor()['interpreters'][0]
+  
+  
+  def _get_editor(self):
+    interpreters = []
+    
+    for interpreter in get_ordered_interpreters(self.user):
+      interpreters.append({
+        'name': interpreter['name'],
+        'type': interpreter['type'],
+        'displayName': interpreter['type'].title(),
+        'tooltip': _('%s Query') % interpreter['type'].title(),
+        'page': '/editor/?type=%(type)s' % interpreter,
+      })
+
+    return {
+        'name': 'editor',
+        'displayName': _('Editor'),
+        'interpreters': interpreters 
+      }
+
+  def _get_dashboard(self):
+    interpreters = [] # TODO Integrate SQL Dashboards and Solr 6 configs
+#     'interpreters': [
+#           {'solr': {}},
+#           {'impala': {}}
+#         ]    
+    
+    if IS_DASHBOARD_ENABLED.get():    
+      return {
+          'name': 'dashboard',
+          'displayName': _('Dashboard'),
+          'interpreters': interpreters,
+          'page': '/dashboard/new_search'
+        }
+    else:
+      return {}
+  
+  def _get_scheduler(self):
+    interpreters = [{
+        'type': 'oozie-workflow',
+        'displayName': _('Workflow'),
+        'tooltip': _('Workflow'),
+        'page': '/oozie/editor/workflow/new/'
+      }, {
+        'type': 'oozie-coordinator',
+        'displayName': _('Schedule'),
+        'tooltip': _('Schedule'),
+        'page': '/oozie/editor/coordinator/new/'
+      }, {
+        'type': 'oozie-bundle',
+        'displayName': _('Bundle'),
+        'tooltip': _('Bundle'),
+        'page': '/oozie/editor/bundle/new/'
+      }
+    ]
+
+    if 'oozie' in self.apps and not self.user.has_hue_permission(action="disable_editor_access", app="oozie") or self.user.is_superuser:
+      return {
+          'name': 'oozie',
+          'displayName': _('Scheduler'),
+          'interpreters': interpreters,
+        }
+    else:
+      return {}  
+  
+  def get_apps(self):
+    apps = OrderedDict([      
+      ('editor', self._get_editor()
+#        'interpreters': get_ordered_interpreters(self.user)
+#         [
+#           {'hive': {}},
+#           {'impala': {}, 'isDefault': True},
+#           {'pig': {}},
+#           {'notebook': {}}
+#         ]
+      ),
+      ('dashboard', self._get_dashboard()
+      ),
+      ('browser', {
+          'name': 'browser',
+          'displayName': _('Browsers'),
+        'interpreters': [{
+            'type': 'hdfs',
+            'displayName': _('Jobs'),
+            'page': '/jobbrowser/',
+          }, {
+            'type': 'metastore',
+            'displayName': _('Jobs'),
+            'page': '/jobbrowser/',
+          }, {
+            'type': 's3',
+            'displayName': _('Jobs'),
+            'page': '/jobbrowser/',
+          }, {
+            'type': 'jobbrowser',
+            'displayName': _('Jobs'),
+            'page': '/jobbrowser/',
+            'interpreters': [
+              'yarn',
+              'oozie',
+              'dataeng'
+            ]
+          }
+        ]
+      }),
+      ('scheduler', self._get_scheduler())
+    ])
+    
+    # Default action
+    # If not in user setting, first interpreter in apps
+#     default_app = None    
+#     if apps['editor'] and apps['editor']['interpreters']:
+#       if 'impala' in apps['editor']['interpreters']:
+#         default_app = apps['editor']['interpreters']['impala']
+#       elif 'hive' in apps['editor']['interpreters']:
+#         default_app = apps['editor']['interpreters']['hive']
+#       elif 'notebook' in apps['editor']['interpreters']:
+#         default_app = apps['editor']['interpreters']['notebook']
+#     elif apps['dashboard'] and apps['dashboard']['interpreters']:
+#       default_app = apps['dashboard']['interpreters'][0]
+#     elif apps['browser'] and apps['browser']['interpreters']:
+#       default_app = apps['browser']['interpreters'][0]
+#     elif apps['scheduler'] and apps['scheduler']['interpreters']:
+#       default_app = apps['scheduler']['interpreters'][0]
+#     
+#     
+#     
+#     default_app['isDefault'] = True
+    
+    return apps
+
+
 def hue(request):
   apps = appmanager.get_apps_dict(request.user)
 
@@ -81,7 +235,8 @@ def hue(request):
       'attribution': desktop.conf.LEAFLET_TILE_LAYER_ATTRIBUTION.get()
     },
     'is_demo': desktop.conf.DEMO_ENABLED.get(),
-    'banner_message': get_banner_message(request)
+    'banner_message': get_banner_message(request),
+    'cluster_config': ClusterConfig(request.user)
   })
 
 def ko_editor(request):
@@ -122,14 +277,17 @@ def home2(request, is_embeddable=False):
     'is_embeddable': request.GET.get('is_embeddable', False)
   })
 
+
 def home_embeddable(request):
   return home2(request, True)
 
+
 def not_found(request):
   return render('404.mako', request, {
     'is_embeddable': request.GET.get('is_embeddable', False)
   })
 
+
 def server_error(request):
   return render('500.mako', request, {
     'is_embeddable': request.GET.get('is_embeddable', False)

+ 1 - 1
desktop/libs/librdbms/src/librdbms/server/rdbms_base_lib.py

@@ -24,7 +24,7 @@ LOG = logging.getLogger(__name__)
 class BaseRDBMSDataTable(object):
   def __init__(self, cursor, columns, fetch_size=1000):
     self.cursor = cursor
-    if columns and isinstance(columns[0], dict): # Bacward compatible for API without column metadata
+    if columns and isinstance(columns[0], dict): # Backward compatible for API without column metadata
       self.columns_description = columns
       self.columns = [col['name'] for col in columns]
     else:

+ 59 - 46
desktop/libs/notebook/src/notebook/conf.py

@@ -43,20 +43,19 @@ SHOW_NOTEBOOKS = Config(
 def _remove_duplications(a_list):
   return list(OrderedDict.fromkeys(a_list))
 
+
 def get_ordered_interpreters(user=None):
   if not INTERPRETERS.get():
-    _default_interpreters()
+    _default_interpreters(user)
 
   interpreters = INTERPRETERS.get()
   interpreters_shown_on_wheel = _remove_duplications(INTERPRETERS_SHOWN_ON_WHEEL.get())
 
   unknown_interpreters = set(interpreters_shown_on_wheel) - set(interpreters)
   if unknown_interpreters:
-      raise ValueError("Interpreters from interpreters_shown_on_wheel is not in the list of Interpreters %s"
-                       % unknown_interpreters)
+      raise ValueError("Interpreters from interpreters_shown_on_wheel is not in the list of Interpreters %s" % unknown_interpreters)
 
-  reordered_interpreters = interpreters_shown_on_wheel + \
-                           [i for i in interpreters if i not in interpreters_shown_on_wheel]
+  reordered_interpreters = interpreters_shown_on_wheel + [i for i in interpreters if i not in interpreters_shown_on_wheel]
 
   return [{
       "name": interpreters[i].NAME.get(),
@@ -66,6 +65,7 @@ def get_ordered_interpreters(user=None):
       for i in reordered_interpreters
   ]
 
+
 INTERPRETERS = UnspecifiedConfigSection(
   "interpreters",
   help="One entry for each type of snippet.",
@@ -139,14 +139,57 @@ ENABLE_BATCH_EXECUTE = Config(
 )
 
 
-def _default_interpreters():
-  INTERPRETERS.set_for_testing(OrderedDict((
-      ('hive', {
-          'name': 'Hive', 'interface': 'hiveserver2', 'options': {}
-      }),
-      ('impala', {
-          'name': 'Impala', 'interface': 'hiveserver2', 'options': {}
-      }),
+def _default_interpreters(user):
+  interpreters = []
+  apps = appmanager.get_apps_dict(user)
+  
+  if 'impala' in apps:
+    interpreters.append(('hive', {
+      'name': 'Hive', 'interface': 'hiveserver2', 'options': {}
+    }),)
+  
+  if 'impala' in apps:
+    interpreters.append(('impala', {
+      'name': 'Impala', 'interface': 'hiveserver2', 'options': {}
+    }),)
+
+  if 'pig' in apps:
+    interpreters.append(('pig', {
+      'name': 'Pig', 'interface': 'oozie', 'options': {}
+    }))
+  
+  if 'oozie' in apps:  
+    interpreters.extend(
+        ('pig', {
+            'name': 'Pig', 'interface': 'oozie', 'options': {}
+        }),
+        ('java', {
+            'name': 'Java', 'interface': 'oozie', 'options': {}
+        }),
+        ('sqoop1', {
+            'name': 'Sqoop 1', 'interface': 'oozie', 'options': {}
+        }),
+        ('distcp', {
+            'name': 'Distcp', 'interface': 'oozie', 'options': {}
+        }),
+        ('spark2', {
+            'name': 'Spark', 'interface': 'oozie', 'options': {}
+        }),
+        ('mapreduce', {
+            'name': 'MapReduce', 'interface': 'oozie', 'options': {}
+        }),
+        ('shell', {
+            'name': 'Shell', 'interface': 'oozie', 'options': {}
+        }),
+      )
+  
+  if 'serch' in apps: # And Solr 6+
+    interpreters.append(('solr', {
+        'name': 'Solr SQL', 'interface': 'solr', 'options': {}
+    }),)
+  
+  if SHOW_NOTEBOOKS.get():
+    interpreters.extend(
       ('spark', {
           'name': 'Scala', 'interface': 'livy', 'options': {}
       }),
@@ -162,42 +205,12 @@ def _default_interpreters():
       ('py', {
           'name': 'Spark Submit Python', 'interface': 'livy-batch', 'options': {}
       }),
-      ('pig', {
-          'name': 'Pig', 'interface': 'oozie', 'options': {}
-      }),
-      ('solr', {
-          'name': 'Solr SQL', 'interface': 'solr', 'options': {}
-      }),
-      ('java', {
-          'name': 'Java', 'interface': 'oozie', 'options': {}
-      })
-      ,
-      ('sqoop1', {
-          'name': 'Sqoop 1', 'interface': 'oozie', 'options': {}
-      })
-      ,
-      ('distcp', {
-          'name': 'Distcp', 'interface': 'oozie', 'options': {}
-      })
-      ,
-      ('spark2', {
-          'name': 'Spark', 'interface': 'oozie', 'options': {}
-      })
-      ,
-      ('mapreduce', {
-          'name': 'MapReduce', 'interface': 'oozie', 'options': {}
-      })
-      ,
-      ('shell', {
-          'name': 'Shell', 'interface': 'oozie', 'options': {}
-      })
-      ,
       ('text', {
           'name': 'Text', 'interface': 'text', 'options': {}
       }),
       ('markdown', {
           'name': 'Markdown', 'interface': 'text', 'options': {}
       })
-    ))
-  )
-
+    )
+  
+  INTERPRETERS.set_for_testing(OrderedDict(interpreters))