Browse Source

AMBARI-8467 Ambari Web: Lock navigation down while upgrade is happening. (atkach)

Andrii Tkach 10 năm trước cách đây
mục cha
commit
b68b716a59
37 tập tin đã thay đổi với 206 bổ sung85 xóa
  1. 39 3
      ambari-web/app/app.js
  2. 1 1
      ambari-web/app/controllers/application.js
  3. 1 1
      ambari-web/app/controllers/main/service/info/configs.js
  4. 1 1
      ambari-web/app/controllers/wizard/step7_controller.js
  5. 2 2
      ambari-web/app/mixins/common/userPref.js
  6. 2 2
      ambari-web/app/models/cluster_states.js
  7. 4 4
      ambari-web/app/router.js
  8. 1 1
      ambari-web/app/routes/add_alert_definition_routes.js
  9. 1 1
      ambari-web/app/routes/add_service_routes.js
  10. 1 1
      ambari-web/app/routes/installer.js
  11. 2 2
      ambari-web/app/routes/main.js
  12. 4 4
      ambari-web/app/templates/application.hbs
  13. 6 6
      ambari-web/app/templates/common/configs/config_history_flow.hbs
  14. 2 2
      ambari-web/app/templates/common/configs/overriddenProperty.hbs
  15. 2 2
      ambari-web/app/templates/common/configs/service_config.hbs
  16. 6 6
      ambari-web/app/templates/common/configs/service_config_category.hbs
  17. 2 2
      ambari-web/app/templates/common/configs/service_config_wizard.hbs
  18. 2 2
      ambari-web/app/templates/common/configs/service_version_box.hbs
  19. 8 6
      ambari-web/app/templates/main/admin/security.hbs
  20. 2 2
      ambari-web/app/templates/main/host.hbs
  21. 2 2
      ambari-web/app/templates/main/host/bulk_operation_menu.hbs
  22. 2 2
      ambari-web/app/templates/main/host/details.hbs
  23. 4 4
      ambari-web/app/templates/main/host/details/host_component.hbs
  24. 5 1
      ambari-web/app/templates/main/host/stack_versions.hbs
  25. 6 6
      ambari-web/app/templates/main/host/summary.hbs
  26. 2 2
      ambari-web/app/templates/main/mirroring/datasets.hbs
  27. 2 2
      ambari-web/app/templates/main/mirroring/jobs.hbs
  28. 2 2
      ambari-web/app/templates/main/service/all_services_actions.hbs
  29. 4 4
      ambari-web/app/templates/main/service/info/configs.hbs
  30. 2 2
      ambari-web/app/templates/main/service/info/summary.hbs
  31. 2 2
      ambari-web/app/templates/main/service/item.hbs
  32. 7 0
      ambari-web/app/utils/helper.js
  33. 1 1
      ambari-web/app/utils/host_progress_popup.js
  34. 2 2
      ambari-web/app/views/common/table_view.js
  35. 1 1
      ambari-web/app/views/main/menu.js
  36. 1 1
      ambari-web/app/views/main/mirroring/jobs_view.js
  37. 72 0
      ambari-web/test/app_test.js

+ 39 - 3
ambari-web/app/app.js

@@ -34,9 +34,45 @@ module.exports = Em.Application.create({
   }),
   isAdmin: false,
   isOperator: false,
-  isManager: function() {
-    return this.get('isAdmin') || this.get('isOperator');
-  }.property('isAdmin','isOperator'),
+  /**
+   * indicate whether stack upgrade is running or not
+   * @type {boolean}
+   */
+  isUpgrading: false,
+  /**
+   * compute user access rights by permission type
+   * types:
+   *  - ADMIN
+   *  - MANAGER
+   *  - OPERATOR
+   *  - ONLY_ADMIN
+   * prefix "upgrade_" mean that element will not be unconditionally blocked while stack upgrade running
+   * @param type {string}
+   * @return {boolean}
+   */
+  isAccessible: function (type) {
+    if (this.get('isUpgrading') && !type.contains('upgrade_')) {
+      return false;
+    }
+
+    if (type.contains('upgrade_')) {
+      //slice off "upgrade_" prefix to have actual permission type
+      type = type.slice(8);
+    }
+
+    switch (type) {
+      case 'ADMIN':
+        return this.get('isAdmin');
+      case 'MANAGER':
+        return this.get('isAdmin') || this.get('isOperator');
+      case 'OPERATOR':
+        return this.get('isOperator');
+      case 'ONLY_ADMIN':
+        return this.get('isAdmin') && !this.get('isOperator');
+      default:
+        return false;
+    }
+  },
 
   isStackServicesLoaded: false,
   /**

+ 1 - 1
ambari-web/app/controllers/application.js

@@ -111,7 +111,7 @@ App.ApplicationController = Em.Controller.extend(App.UserPref, {
 
   showSettingsPopup: function() {
     // Settings only for admins
-    if (!App.get('isAdmin')) return;
+    if (!App.isAccessible('upgrade_ADMIN')) return;
 
     var self = this;
     var curValue = null;

+ 1 - 1
ambari-web/app/controllers/main/service/info/configs.js

@@ -1077,7 +1077,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.ServerValidatorM
   setEditability: function (serviceConfigProperty, defaultGroupSelected) {
     serviceConfigProperty.set('isEditable', false);
     if (serviceConfigProperty.get('isComparison')) return;
-    if (App.get('isAdmin') && defaultGroupSelected && !this.get('isHostsConfigsPage') && !serviceConfigProperty.get('group')) {
+    if (App.isAccessible('ADMIN') && defaultGroupSelected && !this.get('isHostsConfigsPage') && !serviceConfigProperty.get('group')) {
       serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
     } else if (serviceConfigProperty.get('group') && this.get('selectedConfigGroup.name') === serviceConfigProperty.get('group.name')) {
       serviceConfigProperty.set('isEditable', true);

+ 1 - 1
ambari-web/app/controllers/wizard/step7_controller.js

@@ -435,7 +435,7 @@ App.WizardStep7Controller = Em.Controller.extend(App.ServerValidatorMixin, {
    * @method _updateIsEditableFlagForConfig
    */
   _updateIsEditableFlagForConfig: function (serviceConfigProperty, defaultGroupSelected) {
-    if (App.get('isAdmin')) {
+    if (App.isAccessible('ADMIN')) {
       if (defaultGroupSelected && !this.get('isHostsConfigsPage') && !Em.get(serviceConfigProperty, 'group')) {
         serviceConfigProperty.set('isEditable', serviceConfigProperty.get('isReconfigurable'));
       } else if (Em.get(serviceConfigProperty, 'group') && Em.get(serviceConfigProperty, 'group.name') == this.get('selectedConfigGroup.name')) {

+ 2 - 2
ambari-web/app/mixins/common/userPref.js

@@ -80,9 +80,9 @@ App.UserPref = Em.Mixin.create({
    * @param {Object} value
    */
   postUserPref: function (key, value) {
-    if (!App.get('isAdmin')) {
+    if (!App.isAccessible('upgrade_ADMIN')) {
       return $.Deferred().reject().promise();
-    };
+    }
     var keyValuePair = {};
     keyValuePair[key] = JSON.stringify(value);
     return App.ajax.send({

+ 2 - 2
ambari-web/app/models/cluster_states.js

@@ -137,7 +137,7 @@ App.clusterStatus = Em.Object.create(App.UserPref, {
       if (response.localdb) {
         this.set('localdb', response.localdb);
         // restore HAWizard data if process was started
-        var isHAWizardStarted = App.get('isAdmin') && !App.isEmptyObject(response.localdb.HighAvailabilityWizard);
+        var isHAWizardStarted = App.isAccessible('ADMIN') && !App.isEmptyObject(response.localdb.HighAvailabilityWizard);
         if (params.data.overrideLocaldb || isHAWizardStarted) {
           var localdbTables = (App.db.data.app && App.db.data.app.tables) ? App.db.data.app.tables : {};
           App.db.data = response.localdb;
@@ -190,7 +190,7 @@ App.clusterStatus = Em.Object.create(App.UserPref, {
    */
   setClusterStatus: function (newValue, opt) {
     if (App.get('testMode')) return false;
-    if (!App.get('isAdmin')) {
+    if (!App.isAccessible('ADMIN')) {
       Em.assert('Non-Admin user should not execute setClusterStatus function', true);
     }
     var user = App.db.getUser();

+ 4 - 4
ambari-web/app/router.js

@@ -485,7 +485,7 @@ App.Router = Em.Router.extend({
     adminView: Em.Route.extend({
       route: '/adminView',
       enter: function (router) {
-        if (!router.get('loggedIn') || !App.get('isAdmin') || App.get('isOperator')) {
+        if (!router.get('loggedIn') || !App.isAccessible('upgrade_ADMIN') || App.isAccessible('upgrade_OPERATOR')) {
           Em.run.next(function () {
             router.transitionTo('login');
           });
@@ -498,7 +498,7 @@ App.Router = Em.Router.extend({
     experimental: Em.Route.extend({
       route: '/experimental',
       enter: function (router, context) {
-        if (App.get('isOperator')) {
+        if (App.isAccessible('upgrade_OPERATOR')) {
           Em.run.next(function () {
             if (router.get('clusterInstallCompleted')) {
               router.transitionTo("main.dashboard.widgets");
@@ -506,14 +506,14 @@ App.Router = Em.Router.extend({
               router.route("installer");
             }
           });
-        } else if (!App.get('isAdmin')) {
+        } else if (!App.isAccessible('upgrade_ADMIN')) {
           Em.run.next(function () {
             router.transitionTo("main.views.index");
           });
         }
       },
       connectOutlets: function (router, context) {
-        if (App.get('isAdmin') && !App.get('isOperator')) {
+        if (App.isAccessible('upgrade_ONLY_ADMIN')) {
           $('title').text(Em.I18n.t('app.name.subtitle.experimental'));
           console.log('/experimental:connectOutlet');
           router.get('applicationController').connectOutlet('experimental');

+ 1 - 1
ambari-web/app/routes/add_alert_definition_routes.js

@@ -23,7 +23,7 @@ module.exports = App.WizardRoute.extend({
   route: '/alerts/add',
 
   enter: function (router) {
-    if (App.get('isAdmin')) {
+    if (App.isAccessible('ADMIN')) {
       Em.run.next(function () {
         var addAlertDefinitionController = router.get('addAlertDefinitionController');
         App.router.get('updateController').set('isWorking', false);

+ 1 - 1
ambari-web/app/routes/add_service_routes.js

@@ -23,7 +23,7 @@ module.exports = App.WizardRoute.extend({
 
   enter: function (router) {
     console.log('in /service/add:enter');
-    if (App.get('isAdmin')) {
+    if (App.isAccessible('ADMIN')) {
       Em.run.next(function () {
         var addServiceController = router.get('addServiceController');
         App.router.get('updateController').set('isWorking', false);

+ 1 - 1
ambari-web/app/routes/installer.js

@@ -38,7 +38,7 @@ module.exports = Em.Route.extend({
           $('title').text('Ambari - ' + name);
 
           App.router.get('mainViewsController').loadAmbariViews();
-          if (App.get('isAdmin')) {
+          if (App.isAccessible('ADMIN')) {
             router.get('mainController').stopPolling();
             console.log('In installer with successful authenticated');
             console.log('current step=' + router.get('installerController.currentStep'));

+ 2 - 2
ambari-web/app/routes/main.js

@@ -353,7 +353,7 @@ module.exports = Em.Route.extend({
   admin: Em.Route.extend({
     route: '/admin',
     enter: function (router, transition) {
-      if (router.get('loggedIn') && !App.get('isAdmin')) {
+      if (router.get('loggedIn') && !App.isAccessible('upgrade_ADMIN')) {
         Em.run.next(function () {
           router.transitionTo('main.dashboard.index');
         });
@@ -361,7 +361,7 @@ module.exports = Em.Route.extend({
     },
 
     routePath: function (router, event) {
-      if (!App.isAdmin) {
+      if (!App.isAccessible('upgrade_ADMIN')) {
         Em.run.next(function () {
           App.router.transitionTo('main.dashboard.index');
         });

+ 4 - 4
ambari-web/app/templates/application.hbs

@@ -57,13 +57,13 @@
               </button>
               <ul class="dropdown-menu">
                   <li><a href="" {{action showAboutPopup target="controller"}}>{{t app.aboutAmbari}}</a></li>
-                  {{#if App.isAdmin}}{{#unless App.isOperator}}
+                  {{#isAccessible upgrade_ONLY_ADMIN}}
                     <li><a href="" {{action goToAdminView target="controller"}}>{{t app.manageAmbari}}</a></li>
-                  {{/unless}}{{/if}}
+                  {{/isAccessible}}
                 {{#if isClusterDataLoaded}}
-                  {{#if App.isAdmin}}
+                  {{#isAccessible upgrade_ADMIN}}
                       <li><a href="" {{action showSettingsPopup target="controller"}}>{{t app.settings}}</a></li>
-                  {{/if}}
+                  {{/isAccessible}}
                 {{/if}}
                   <li class="break"></li>
                   <li><a href="" {{action logoff}}>{{t app.signout}}</a></li>

+ 6 - 6
ambari-web/app/templates/common/configs/config_history_flow.hbs

@@ -29,7 +29,7 @@
 
   </div>
   <div class="version-info-bar-wrapper">
-    {{#if App.isManager}}
+    {{#isAccessible MANAGER}}
       <div {{bindAttr class="view.showCompareVersionBar::hidden :version-info-bar"}}>
           <div class="row-fluid">
               <div class="span1 remove-compare-bar" {{action removeCompareVersionBar target="view"}} data-toggle="arrow-tooltip" {{translateAttr data-original-title="services.service.config.configHistory.dismissIcon.tooltip"}}>
@@ -52,7 +52,7 @@
               </div>
           </div>
       </div>
-    {{/if}}
+    {{/isAccessible}}
       <div class="version-info-bar">
         <div class="row-fluid">
             <div class="btn-group pull-left">
@@ -78,10 +78,10 @@
                       </div>
                       <div class="version-operations-buttons">
                         <button {{bindAttr disabled="serviceVersion.disabledActionAttr.view" class=":btn serviceVersion.isDisplayed:not-allowed-cursor" title="serviceVersion.disabledActionMessages.view"}} {{action doAction serviceVersion view.actionTypes.SWITCH target="view"}}><i class="icon-search"></i>&nbsp;{{t common.view}}</button>
-                        {{#if App.isManager}}
+                        {{#isAccessible MANAGER}}
                         <button {{bindAttr disabled="serviceVersion.disabledActionAttr.compare" class=":btn serviceVersion.isDisplayed:not-allowed-cursor" title="serviceVersion.disabledActionMessages.compare"}} {{action doAction serviceVersion view.actionTypes.COMPARE target="view"}}><i class="icon-copy"></i>&nbsp;{{t common.compare}}</button>
                         <button {{bindAttr disabled="serviceVersion.disabledActionAttr.revert" class=":btn serviceVersion.isCurrent:not-allowed-cursor" title="serviceVersion.disabledActionMessages.revert"}} {{action doAction serviceVersion view.actionTypes.REVERT target="view"}}>{{t dashboard.configHistory.info-bar.revert.button}}</button>
-                        {{/if}}
+                        {{/isAccessible}}
                       </div>
                     </ul>
                   </li>
@@ -107,7 +107,7 @@
                 <strong>{{view.displayedServiceVersion.author}}</strong>&nbsp;{{t dashboard.configHistory.info-bar.authoredOn}}&nbsp;<strong>{{view.displayedServiceVersion.createdDate}}</strong>
               {{/if}}
             </div>
-          {{#if App.isManager}}
+          {{#isAccessible MANAGER}}
             <div class="pull-right operations-button">
                 <div {{bindAttr class="view.displayedServiceVersion.isCurrent::hidden"}}>
                     <button class="btn" {{action doCancel target="controller"}} {{bindAttr disabled="view.isDiscardDisabled"}}>{{t common.discard}}</button>
@@ -115,7 +115,7 @@
                 </div>
                 <button class="btn btn-success"  {{action doAction view.serviceVersionsReferences.displayed view.actionTypes.REVERT target="view"}} {{bindAttr disabled="view.versionActionsDisabled" class="view.displayedServiceVersion.isCurrent:hidden"}}>{{view.displayedServiceVersion.makeCurrentButtonText}}</button>
             </div>
-          {{/if}}
+          {{/isAccessible}}
         </div>
       </div>
   </div>

+ 2 - 2
ambari-web/app/templates/common/configs/overriddenProperty.hbs

@@ -42,13 +42,13 @@
             <i class="icon-undo"></i>
           </a>
         {{/if}}
-        {{#if App.isAdmin}}
+        {{#isAccessible ADMIN}}
           <a class="btn btn-small" href="#" data-toggle="tooltip"
             {{action "removeOverride" overriddenSCP target="view"}}
             {{translateAttr data-original-title="common.remove"}}>
             <i class="icon-minus-sign"></i>
           </a>
-        {{/if}}
+        {{/isAccessible}}
           <span class="help-inline">{{overriddenSCP.errorMessage}}</span>
       {{else}}
         <a class="action">{{overriddenSCP.group.switchGroupTextShort}}</a> <i class="icon-spinner"></i>

+ 2 - 2
ambari-web/app/templates/common/configs/service_config.hbs

@@ -64,13 +64,13 @@
         {{/each}}
 		  </ul>
 		</span>
-    {{#if App.isAdmin}}
+    {{#isAccessible ADMIN}}
       {{#if controller.isHostsConfigsPage}}
           &nbsp;<a href="#" {{action "switchHostGroup" target="controller"}}>{{t common.change}}</a>
       {{else}}
           <a href="#"  class="link-left-pad" {{action "manageConfigurationGroup" target="controller"}}>{{t services.service.actions.manage_configuration_groups.short}}</a>
       {{/if}}
-    {{/if}}
+    {{/isAccessible}}
      <div class="pull-right">
        {{view App.FilterComboCleanableView filterBinding="view.filter" columnsBinding="view.columns" popoverDescriptionBinding="view.propertyFilterPopover"}}
      </div>

+ 6 - 6
ambari-web/app/templates/common/configs/service_config_category.hbs

@@ -69,7 +69,7 @@
               {{#if view.canEdit}}
                 {{#if isPropertyOverridable}}
                   {{#if view.supportsHostOverrides}}
-                    {{#if App.isAdmin}}
+                    {{#isAccessible ADMIN}}
                       {{#unless this.isComparison}}
                           <a class="btn btn-small" href="#" data-toggle="tooltip"
                             {{action "createOverrideProperty" this target="view"}}
@@ -77,7 +77,7 @@
                               <i class="icon-plus-sign"></i>
                           </a>
                       {{/unless}}
-                    {{/if}}
+                    {{/isAccessible}}
                   {{/if}}
                 {{/if}}
                 {{#unless cantBeUndone}}
@@ -90,7 +90,7 @@
                   {{/if}}
                 {{/unless}}
                 {{#if isRemovable}}
-                  {{#if App.isAdmin}}
+                  {{#isAccessible ADMIN}}
                     {{#unless this.isComparison}}
                         <a class="btn btn-small" href="#" data-toggle="tooltip"
                           {{action "removeProperty" this target="view"}}
@@ -98,7 +98,7 @@
                             <i class="icon-minus-sign"></i>
                         </a>
                     {{/unless}}
-                  {{/if}}
+                  {{/isAccessible}}
                 {{/if}}
                 {{#unless isEditable}}
                   {{#if group}}
@@ -125,7 +125,7 @@
       {{/each}}
 
       {{! For Advanced, Advanced Core Site, Advanced HDFS Site sections, show the 'Add Property' link.}}
-      {{#if App.isAdmin}}
+      {{#isAccessible ADMIN}}
         {{#if view.canEdit}}
           {{#if view.category.customCanAddProperty }}
             <div>
@@ -133,7 +133,7 @@
             </div>
           {{/if}}
         {{/if}}
-      {{/if}}
+      {{/isAccessible}}
     </form>
   </div>
 </div>

+ 2 - 2
ambari-web/app/templates/common/configs/service_config_wizard.hbs

@@ -35,13 +35,13 @@
         {{/each}}
       </ul>
 		</span>
-    {{#if App.isAdmin}}
+    {{#isAccessible ADMIN}}
       {{#if controller.isHostsConfigsPage}}
         &nbsp;<a href="#" {{action "switchHostGroup" target="controller"}}>{{t common.change}}</a>
       {{else}}
         <a href="#"  class="link-left-pad" {{action "manageConfigurationGroup" target="controller"}}>{{t services.service.actions.manage_configuration_groups.short}}</a>
       {{/if}}
-    {{/if}}
+    {{/isAccessible}}
     <div class="pull-right">
       {{view App.FilterComboCleanableView filterBinding="view.filter" columnsBinding="view.columns" popoverDescriptionBinding="view.propertyFilterPopover"}}
     </div>

+ 2 - 2
ambari-web/app/templates/common/configs/service_version_box.hbs

@@ -43,10 +43,10 @@
       </div>
       <div class="version-operations-buttons">
         <button {{bindAttr disabled="serviceVersion.disabledActionAttr.view" class=":btn serviceVersion.isDisplayed:not-allowed-cursor" title="serviceVersion.disabledActionMessages.view"}} {{action doAction serviceVersion view.actionTypes.SWITCH target="view.parentView"}}><i class="icon-search"></i>&nbsp;{{t common.view}}</button>
-        {{#if App.isManager}}
+        {{#isAccessible MANAGER}}
           <button {{bindAttr disabled="serviceVersion.disabledActionAttr.compare" class=":btn serviceVersion.isDisplayed:not-allowed-cursor" title="serviceVersion.disabledActionMessages.compare"}} {{action doAction serviceVersion view.actionTypes.COMPARE target="view.parentView"}}><i class="icon-copy"></i>&nbsp;{{t common.compare}}</button>
           <button {{bindAttr disabled="serviceVersion.disabledActionAttr.revert" class=":btn serviceVersion.isCurrent:not-allowed-cursor" title="serviceVersion.disabledActionMessages.revert"}} {{action doAction serviceVersion view.actionTypes.REVERT target="view.parentView"}}>{{t dashboard.configHistory.info-bar.revert.button}}</button>
-        {{/if}}
+        {{/isAccessible}}
       </div>
     </div>
   </div>

+ 8 - 6
ambari-web/app/templates/main/admin/security.hbs

@@ -19,9 +19,10 @@
   {{#if securityEnabled}}
     <div>
       <p class="text-success">{{t admin.security.enabled}}
-        <a
-                class="btn btn-padding btn-warning" {{bindAttr disabled="isSubmitDisabled"}} {{action notifySecurityOffPopup target="controller"}}>{{t admin.security.button.disable}}
-        </a> <br/>
+        {{#isAccessible ADMIN}}
+          <a class="btn btn-padding btn-warning" {{bindAttr disabled="isSubmitDisabled"}} {{action notifySecurityOffPopup target="controller"}}>{{t admin.security.button.disable}}
+          </a> <br/>
+        {{/isAccessible}}
       </p>
     </div>
     <div id="serviceConfig">
@@ -30,9 +31,10 @@
   {{else}}
     <div>
       <p class="muted">{{t admin.security.disabled}}
-        <a
-                class="btn btn-padding btn-success" {{action addSecurity}}>{{t admin.security.button.enable}}
-        </a> <br/>
+        {{#isAccessible ADMIN}}
+          <a class="btn btn-padding btn-success" {{action addSecurity}}>{{t admin.security.button.enable}}
+          </a> <br/>
+        {{/isAccessible}}
       </p>
     </div>
   {{/if}}

+ 2 - 2
ambari-web/app/templates/main/host.hbs

@@ -20,9 +20,9 @@
 
   <div class="box-header row">
     <div class="hosts-actions pull-left">
-      {{#if App.isAdmin}}
+      {{#isAccessible ADMIN}}
         {{view App.HostTableMenuView}}
-      {{/if}}
+      {{/isAccessible}}
     </div>
     <div class="health-status-bar pull-left">
       {{#view view.statusFilter categoriesBinding="view.categories"}}

+ 2 - 2
ambari-web/app/templates/main/host/bulk_operation_menu.hbs

@@ -19,10 +19,10 @@
 <div class="dropdown bulk-menu">
   <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">{{t common.actions}} <span class="caret"></span></a>
   <ul class="dropdown-menu">
-    {{#if App.isAdmin}}
+    {{#isAccessible ADMIN}}
       <li><a href="#" {{action addHost}}><i class="icon-plus icon-white"></i> {{t hosts.host.add}}</a></li>
       <li class="divider"></li>
-    {{/if}}
+    {{/isAccessible}}
     <li class="dropdown-submenu">
       <a {{bindAttr class="view.parentView.showSelectedFilter::disabled"}} tabindex="-1" href="javascript:void(null);">{{view.menuItems.s.label}}
         ({{view.parentView.selectedHosts.length}})</a>

+ 2 - 2
ambari-web/app/templates/main/host/details.hbs

@@ -34,7 +34,7 @@
             class="icon-arrow-left"></i>&nbsp;{{t common.back}}</a></div>
     <div class="content">
       {{view App.MainHostMenuView}}
-      {{#if App.isAdmin}}
+      {{#isAccessible ADMIN}}
         <div class="service-button">
           <div class="btn-group display-inline-block">
             <a href="javascript:void(null)" {{bindAttr class=":btn :dropdown-toggle"}} data-toggle="dropdown">
@@ -67,7 +67,7 @@
             </ul>
           </div>
         </div>
-      {{/if}}
+      {{/isAccessible}}
       {{outlet}}
     </div>
   </div>

+ 4 - 4
ambari-web/app/templates/main/host/details/host_component.hbs

@@ -18,11 +18,11 @@
 
 <div class="span7">
   {{#if view.isUpgradeFailed}}
-    {{#if App.isAdmin}}
+    {{#isAccessible ADMIN}}
       <a href="#" {{action "upgradeComponent" view.content target="controller"}} >
         <i title="Component upgrade failed" class="components-health icon-arrow-up"></i>
       </a>
-    {{/if}}
+    {{/isAccessible}}
   {{else}}
     <span rel='componentHealthTooltip' {{bindAttr class="view.statusClass view.statusIconClass :components-health" data-original-title="view.componentTextStatus"}}></span>&nbsp;
   {{/if}}
@@ -42,7 +42,7 @@
   {{/unless}}
 </div>
 <div class="span5 pull-right">
-  {{#if App.isAdmin}}
+  {{#isAccessible ADMIN}}
     <div class="btn-group pull-right">
       <a {{ bindAttr class="view.disabled :btn :dropdown-toggle"}} data-toggle="dropdown">
         {{view.componentTextStatus}}
@@ -140,5 +140,5 @@
       {{/each}}
       </ul>
     </div>
-  {{/if}}
+  {{/isAccessible}}
 </div>

+ 5 - 1
ambari-web/app/templates/main/host/stack_versions.hbs

@@ -42,7 +42,11 @@
             <span class="label label-success">{{t common.current}}</span>
           {{/if}}
         </td>
-        <td class="install-repo-version"><button class="btn" {{bindAttr disabled="this.installDisabled"}}><i class="icon-off"></i>&nbsp;{{t common.install}}</button></td>
+        <td class="install-repo-version">
+          {{#isAccessible ADMIN}}
+            <button class="btn" {{bindAttr disabled="this.installDisabled"}}><i class="icon-off"></i>&nbsp;{{t common.install}}</button>
+          {{/isAccessible}}
+        </td>
       </tr>
     {{/each}}
   {{else}}

+ 6 - 6
ambari-web/app/templates/main/host/summary.hbs

@@ -26,7 +26,7 @@
             <h4>{{t common.components}}</h4>
           </div>
           <div class="pull-right span5 row-fluid" style="padding:0 10px;">
-            {{#if App.isAdmin}}
+            {{#isAccessible ADMIN}}
               <div class="btn-group pull-right">
                 <button id="add_component" data-toggle="dropdown" {{bindAttr class="view.addComponentDisabled:disabled :btn :dropdown-toggle"}}>
                   <span class="icon-plus"></span>&nbsp;{{t add}}
@@ -41,13 +41,13 @@
                   {{/each}}
                 </ul>
               </div>
-            {{/if}}
+            {{/isAccessible}}
           </div>
         </div>
         <div class="host-components">
         {{#if view.sortedComponents.length}}
 
-          {{#if App.isAdmin}}
+          {{#isAccessible ADMIN}}
             {{#if view.content.componentsWithStaleConfigsCount}}
               <div class="alert alert-warning clearfix">
                 <i class="icon-refresh"></i> {{view.needToRestartMessage}}
@@ -56,7 +56,7 @@
                   </button>
               </div>
             {{/if}}
-          {{/if}}
+          {{/isAccessible}}
 
           {{#each component in view.sortedComponents}}
             <div class="row-fluid">
@@ -77,7 +77,7 @@
               {{/if}}
             </div>
             <div class="span5 row">
-              {{#if App.isAdmin}}
+              {{#isAccessible ADMIN}}
                 {{#if view.clients.length}}
                   <div class="btn-group pull-right">
                     <button id="add_component" data-toggle="dropdown" {{bindAttr class=":btn :dropdown-toggle controller.content.isNotHeartBeating:disabled"}}>
@@ -115,7 +115,7 @@
                     </ul>
                   </div>
                 {{/if}}
-              {{/if}}
+              {{/isAccessible}}
             </div>
           </div>
         </div>

+ 2 - 2
ambari-web/app/templates/main/mirroring/datasets.hbs

@@ -25,7 +25,7 @@
         <div class="pull-left">
           <h4>{{t mirroring.dataset.dataSets}}</h4>
         </div>
-        {{#if App.isAdmin}}
+        {{#isAccessible ADMIN}}
           <div class="mirroring-top-nav pull-right btn-group">
             <button {{bindAttr disabled="controller.actionsDisabled"}} class="btn">{{t common.actions}}</button>
             <button {{bindAttr disabled="controller.actionsDisabled"}} class="btn dropdown-toggle" data-toggle="dropdown">
@@ -44,7 +44,7 @@
               </li>
             </ul>
           </div>
-        {{/if}}
+        {{/isAccessible}}
       </div>
       <table class="table advanced-header-table table-bordered dataset-thead">
         <thead>

+ 2 - 2
ambari-web/app/templates/main/mirroring/jobs.hbs

@@ -34,7 +34,7 @@
       </tr>
     </table>
   </div>
-  {{#if App.isAdmin}}
+  {{#isAccessible ADMIN}}
     <div class="top-right">
       <div class="btn-group pull-right">
         <button class="btn">{{t common.actions}}</button>
@@ -78,7 +78,7 @@
       <span {{bindAttr class=":label view.dataset.isRunning:label-info  view.dataset.isSuspended:label-warning  view.dataset.isSubmitted:label-success :pull-right :dataset-status"}}>
         {{view.dataset.statusFormatted}}</span>
     </div>
-  {{/if}}
+  {{/isAccessible}}
   <div class="bottom-right">{{t common.download}}: <a href="javascript:void(null);" {{action downloadEntity target="controller"}}>{{t mirroring.dataset.entity}}.xml</a></div>
 </div>
 {{/if}}

+ 2 - 2
ambari-web/app/templates/main/service/all_services_actions.hbs

@@ -16,7 +16,7 @@
 * limitations under the License.
 }}
 
-{{#if App.isAdmin}}
+{{#isAccessible ADMIN}}
   <div class="service-button" style="margin-top: 10px;">
     <div class="btn-group display-inline-block span11 offset1">
       <a class="btn dropdown-toggle span10" data-toggle="dropdown" href="#">{{t common.actions}}
@@ -49,4 +49,4 @@
       </ul>
     </div>
   </div>
-{{/if}}
+{{/isAccessible}}

+ 4 - 4
ambari-web/app/templates/main/service/info/configs.hbs

@@ -19,7 +19,7 @@
 <div id="serviceConfig">
   {{#if dataIsLoaded}}
     {{#if controller.content.isRestartRequired}}
-      {{#if App.isAdmin}}
+      {{#isAccessible ADMIN}}
         <div>
           <div class="alert alert-warning clearfix">
             <i class="icon-refresh"></i> {{t services.service.config.restartService.needToRestart}}  <a
@@ -45,11 +45,11 @@
             </div>
           </div>
         </div>
-      {{/if}}
+      {{/isAccessible}}
     {{/if}}
     <div class="clearfix"></div>
     {{view App.ServiceConfigView filterBinding="controller.filter" columnsBinding="controller.filterColumns" canEditBinding="controller.isCurrentSelected" showConfigHistoryFeatureBinding="controller.showConfigHistoryFeature"}}
-    {{#if App.isAdmin}}
+    {{#isAccessible ADMIN}}
       {{#unless showConfigHistoryFeature}}
           <p class="pull-right">
               <!--<input class="btn btn-primary" type="button" value="Save" {{!bindAttr disabled="isSubmitDisabled"}} />-->
@@ -58,7 +58,7 @@
                 {{action restartServicePopup target="controller"}}>{{t common.save}}</a>
           </p>
       {{/unless}}
-    {{/if}}
+    {{/isAccessible}}
   {{else}}
     <div class="spinner"></div>
   {{/if}}

+ 2 - 2
ambari-web/app/templates/main/service/info/summary.hbs

@@ -17,7 +17,7 @@
 }}
 
 {{#if view.service.isRestartRequired}}
-  {{#if App.isAdmin}}
+  {{#isAccessible ADMIN}}
     <div id="summary-restart-bar">
       <div class="alert alert-warning clearfix">
         <i class="icon-refresh"></i> {{{view.needToRestartMessage}}} {{t services.service.config.restartService.needToRestart}}
@@ -41,7 +41,7 @@
         </div>
       </div>
     </div>
-  {{/if}}
+  {{/isAccessible}}
 {{/if}}
 
 <div class="row-fluid service-block">

+ 2 - 2
ambari-web/app/templates/main/service/item.hbs

@@ -52,7 +52,7 @@
     {{/if}}
   </div>
 
-{{#if App.isAdmin}}
+{{#isAccessible ADMIN}}
 <div class="service-button">
   {{#if view.isMaintenanceActive}}
     <div class="btn-group display-inline-block">
@@ -105,5 +105,5 @@
     </div>
   {{/if}}
 </div>
-{{/if}}
+{{/isAccessible}}
 {{outlet}}

+ 7 - 0
ambari-web/app/utils/helper.js

@@ -254,6 +254,13 @@ Em.Handlebars.registerHelper('highlight', function (property, words, fn) {
 
   return new Em.Handlebars.SafeString(property);
 });
+
+Em.Handlebars.registerHelper('isAccessible', function (context, options) {
+  if (App.isAccessible(context)) {
+    return options.fn(this);
+  }
+});
+
 /**
  * @namespace App
  */

+ 1 - 1
ambari-web/app/utils/host_progress_popup.js

@@ -357,7 +357,7 @@ App.HostPopup = Em.Object.create({
           updatedService = this.createService(service);
           servicesInfo.insertAt(index, updatedService);
         }
-        updatedService.set('isAbortable',  App.get('isManager') &&  this.isAbortableByStatus(service.status));
+        updatedService.set('isAbortable',  App.isAccessible('MANAGER') &&  this.isAbortableByStatus(service.status));
       }, this);
       this.removeOldServices(servicesInfo, currentServices);
       this.setBackgroundOperationHeader(isServiceListHidden);

+ 2 - 2
ambari-web/app/views/common/table_view.js

@@ -164,7 +164,7 @@ App.TableView = Em.View.extend(App.UserPref, {
     console.log('Persist did NOT find the key');
     var displayLengthDefault = this.get('defaultDisplayLength');
     this.set('displayLength', displayLengthDefault);
-    if (App.get('isAdmin')) {
+    if (App.isAccessible('upgrade_ADMIN')) {
       this.saveDisplayLength();
     }
     this.filter();
@@ -372,7 +372,7 @@ App.TableView = Em.View.extend(App.UserPref, {
     Em.run.next(function() {
       App.db.setDisplayLength(self.get('controller.name'), self.get('displayLength'));
       if (!App.get('testMode')) {
-        if (App.get('isAdmin')) {
+        if (App.isAccessible('upgrade_ADMIN')) {
           self.postUserPref(self.displayLengthKey(), self.get('displayLength'));
         }
       }

+ 1 - 1
ambari-web/app/views/main/menu.js

@@ -50,7 +50,7 @@ App.MainMenuView = Em.CollectionView.extend({
           result.push({ label: Em.I18n.t('menu.item.jobs'), routing: 'apps'});
         }
 
-        if (App.get('isAdmin')) {
+        if (App.isAccessible('upgrade_ADMIN')) {
           result.push({ label: Em.I18n.t('menu.item.admin'), routing: 'admin'});
         }
       }

+ 1 - 1
ambari-web/app/views/main/mirroring/jobs_view.js

@@ -202,7 +202,7 @@ App.MainDatasetJobsView = App.TableView.extend({
     tagName: 'tr',
 
     showActions: function () {
-      return ['RUNNING', 'SUSPENDED'].contains(this.get('content.status')) && App.get('isAdmin');
+      return ['RUNNING', 'SUSPENDED'].contains(this.get('content.status')) && App.isAccessible('ADMIN');
     }.property('content.status')
   }),
 

+ 72 - 0
ambari-web/test/app_test.js

@@ -461,4 +461,76 @@ describe('App', function () {
       })
     })
   });
+
+  describe("#isAccessible()", function() {
+    it("Upgrade running, element should be blocked", function() {
+      App.set('isUpgrading', true);
+      App.set('isAdmin', true);
+      expect(App.isAccessible('ADMIN')).to.be.false;
+    });
+    it("Upgrade running, upgrade element should not be blocked", function() {
+      App.set('isUpgrading', true);
+      App.set('isAdmin', true);
+      expect(App.isAccessible('upgrade_ADMIN')).to.be.true;
+    });
+    it("ADMIN type, isAdmin true", function() {
+      App.set('isUpgrading', false);
+      App.set('isAdmin', true);
+      expect(App.isAccessible('ADMIN')).to.be.true;
+    });
+    it("ADMIN type, isAdmin false", function() {
+      App.set('isUpgrading', false);
+      App.set('isAdmin', false);
+      expect(App.isAccessible('ADMIN')).to.be.false;
+    });
+    it("MANAGER type, isOperator false", function() {
+      App.set('isUpgrading', false);
+      App.set('isAdmin', true);
+      App.set('isOperator', false);
+      expect(App.isAccessible('MANAGER')).to.be.true;
+    });
+    it("MANAGER type, isAdmin false", function() {
+      App.set('isUpgrading', false);
+      App.set('isAdmin', false);
+      App.set('isOperator', true);
+      expect(App.isAccessible('MANAGER')).to.be.true;
+    });
+    it("MANAGER type, isAdmin and isOperator false", function() {
+      App.set('isUpgrading', false);
+      App.set('isAdmin', false);
+      App.set('isOperator', false);
+      expect(App.isAccessible('MANAGER')).to.be.false;
+    });
+    it("OPERATOR type, isOperator false", function() {
+      App.set('isUpgrading', false);
+      App.set('isOperator', false);
+      expect(App.isAccessible('OPERATOR')).to.be.false;
+    });
+    it("OPERATOR type, isOperator false", function() {
+      App.set('isUpgrading', false);
+      App.set('isOperator', true);
+      expect(App.isAccessible('OPERATOR')).to.be.true;
+    });
+    it("ONLY_ADMIN type, isAdmin false", function() {
+      App.set('isUpgrading', false);
+      App.set('isAdmin', false);
+      expect(App.isAccessible('ONLY_ADMIN')).to.be.false;
+    });
+    it("ONLY_ADMIN type, isAdmin true, isOperator false", function() {
+      App.set('isUpgrading', false);
+      App.set('isAdmin', true);
+      App.set('isOperator', false);
+      expect(App.isAccessible('ONLY_ADMIN')).to.be.true;
+    });
+    it("ONLY_ADMIN type, isAdmin true, isOperator true", function() {
+      App.set('isUpgrading', false);
+      App.set('isAdmin', true);
+      App.set('isOperator', true);
+      expect(App.isAccessible('ONLY_ADMIN')).to.be.false;
+    });
+    it("unknown type", function() {
+      App.set('isUpgrading', false);
+      expect(App.isAccessible('')).to.be.false;
+    });
+  });
 });