Browse Source

AMBARI-3783. Hitting Save in the config-group does not update host membership. (srimanth)

Srimanth Gunturi 11 năm trước cách đây
mục cha
commit
e9a1ba1ee6

+ 1 - 1
ambari-web/app/config.js

@@ -44,7 +44,7 @@ App.enableExperimental = false;
 
 App.supports = {
   addServices: false,
-  hostOverrides: false,
+  hostOverrides: true,
   mirroring: false,
   secureCluster: true,
   secureClusterProceedPopup: false,

+ 31 - 1
ambari-web/app/controllers/main/service/item.js

@@ -227,8 +227,38 @@ App.MainServiceItemController = Em.Controller.extend({
       classNames: ['sixty-percent-width-modal', 'manage-configuration-group-popup'],
       primary: Em.I18n.t('common.save'),
       onPrimary: function() {
-        this.hide();
+        // Save modified config-groups
+        var modifiedConfigGroups = this.get('subViewController.hostsModifiedConfigGroups');
+        console.log("manageConfigurationGroups(): Saving modified config-groups: ", modifiedConfigGroups);
+        var self = this;
+        var errors = [];
+        var putCount = modifiedConfigGroups.length;
+        var finishFunction = function(error) {
+          if (error != null) {
+            errors.push(error);
+          }
+          if (--putCount <= 0) {
+            // Done with all the PUTs
+            if (errors.length > 0) {
+              console.log(errors);
+              self.get('subViewController').set('errorMessage',
+                  errors.join(". "));
+            } else {
+              self.hide();
+            }
+          }
+        };
+        modifiedConfigGroups.forEach(function(cg) {
+          App.config.updateConfigurationGroup(cg, finishFunction, finishFunction);
+        });
       },
+      subViewController: function(){
+        return App.router.get('manageConfigGroupsController');
+      }.property('App.router.manageConfigGroupsController'),
+      updateButtons: function(){
+        var modified = this.get('subViewController.isHostsModified');
+        this.set('enablePrimary', modified);
+      }.observes('subViewController.isHostsModified'),
       secondary : Em.I18n.t('common.cancel'),
       didInsertElement: function () {}
     });

+ 60 - 4
ambari-web/app/controllers/main/service/manage_config_groups_controller.js

@@ -62,6 +62,12 @@ App.ManageConfigGroupsController = Em.Controller.extend({
       var configGroups = [];
       data.items.forEach(function (configGroup) {
         configGroup = configGroup.ConfigGroup;
+        var hostNames = configGroup.hosts.mapProperty('host_name');
+        var loadedHostNamesMap = {};
+        hostNames.forEach(function(h){
+          loadedHostNamesMap[h] = true;
+        });
+        loadedHostNamesMap.length = hostNames.length;
         var newConfigGroup = App.ConfigGroup.create({
           id: configGroup.id,
           name: configGroup.group_name,
@@ -69,10 +75,12 @@ App.ManageConfigGroupsController = Em.Controller.extend({
           isDefault: false,
           parentConfigGroup: defaultConfigGroup,
           service: App.Service.find().findProperty('serviceName', configGroup.tag),
-          hosts: configGroup.hosts.mapProperty('host_name'),
+          hosts: hostNames,
           configSiteTags: [],
           properties: [],
-          apiResponse: configGroup
+          apiResponse: configGroup,
+          loadedHostNamesMap: loadedHostNamesMap,
+          hostsModified: false
         });
         usedHosts = usedHosts.concat(newConfigGroup.get('hosts'));
         configGroups.push(newConfigGroup);
@@ -277,6 +285,8 @@ App.ManageConfigGroupsController = Em.Controller.extend({
    * On successful api resonse for creating new config group
    */
   onAddNewConfigGroup: function (data) {
+    var loadedHostNamesMap = {};
+    loadedHostNamesMap.length = 0;
     var newConfigGroupData = App.ConfigGroup.create({
       id: data.resources[0].ConfigGroup.id,
       name: this.get('configGroupName'),
@@ -285,7 +295,9 @@ App.ManageConfigGroupsController = Em.Controller.extend({
       parentConfigGroup: null,
       service: this.get('serviceName'),
       hosts: [],
-      configSiteTags: []
+      configSiteTags: [],
+      loadedHostNamesMap: loadedHostNamesMap,
+      hostsModified: false
     });
     var defaultConfigGroup = this.get('configGroups').popObject();
     this.get('configGroups').pushObjects([newConfigGroupData, defaultConfigGroup]);
@@ -310,5 +322,49 @@ App.ManageConfigGroupsController = Em.Controller.extend({
   successLoadingConfigGroup: function (data) {
     var confGroup = this.get('configGroups').findProperty('id', data.ConfigGroup.id);
     confGroup.set('apiResponse', data.ConfigGroup);
-  }
+  },
+  
+  hostsModifiedConfigGroups: function() {
+    var groups = this.get('configGroups');
+    var hostsRemovedGroup = [];
+    var hostsAddedGroup = [];
+    var hostsChangedGroup = [];
+    groups.forEach(function(g) {
+      if (!g.get('isDefault')) {
+        var loadedMap = g.get('loadedHostNamesMap');
+        var current = g.get('hosts');
+        var currentLength = current ? current.length : 0;
+        if (currentLength == loadedMap.length) {
+          if (currentLength>0) {
+            var changed = false;
+            current.forEach(function(c) {
+              if (!changed && loadedMap[c] == null) {
+                changed = true;
+              }
+            });
+            if (changed) {
+              hostsChangedGroup.push(g);
+            }
+          }
+        } else {
+          if (currentLength < loadedMap.length) {
+            hostsRemovedGroup.push(g);
+          } else {
+            hostsAddedGroup.push(g);
+          }
+        }
+      }
+    });
+    // First PUT removed hosts, then PUT added hosts, then changed hosts
+    var modifiedGroups = [];
+    modifiedGroups = modifiedGroups.concat(hostsRemovedGroup);
+    modifiedGroups = modifiedGroups.concat(hostsAddedGroup);
+    modifiedGroups = modifiedGroups.concat(hostsChangedGroup);
+    return modifiedGroups;
+  }.property('selectedConfigGroup', 'selectedConfigGroup.hosts.@each'),
+  
+  isHostsModified: function () {
+    var groups = this.get('hostsModifiedConfigGroups');
+    return groups && groups.length > 0;
+  }.property('hostsModifiedConfigGroups', 'hostsModifiedConfigGroups.length')
 });

+ 14 - 1
ambari-web/app/styles/application.less

@@ -4889,7 +4889,20 @@ i.icon-asterisks {
 }
 
 .manage-configuration-group-popup {
+  .modal{
+    max-height: 600px;
+  }
+  .modal-body {
+    max-height: 450px;
+  }
   .group-select {
-    width: 100%
+    width: 100%;
+    height: 250px;
+  }
+  .btn-toolbar {
+    margin-top: 0px;
+  }
+  .manage-configuration-group-content {
+    margin-bottom: 30px;
   }
 }

+ 29 - 10
ambari-web/app/templates/main/service/manage_configuration_groups_popup.hbs

@@ -16,11 +16,11 @@
 * limitations under the License.
 }}
 <div class="alert alert-info">{{t services.service.config_groups_popup.notice}}</div>
-<div class="row-fluid">
+<div class="row-fluid  manage-configuration-group-content">
   <div class="span12">
     {{t services.service.config_groups_popup.config_groups}}
     <div class="row-fluid">
-      <div class="span6">
+      <div class="span5">
         {{view Em.Select
           contentBinding="configGroups"
           optionLabelPath="content.displayName"
@@ -28,14 +28,26 @@
           multiple="multiple"
           class="group-select"
         }}
-        <div class="button-group pull-right">
-          <a class="btn" {{action addConfigGroup target="controller"}}>+</a>
-          <a class="btn" {{action deleteConfigGroup target="controller"}}>-</a>
-          <a class="btn" {{action renameConfigGroup target="controller"}}>{{t services.service.config_groups_popup.rename}}</a>
-          <a class="btn" {{action addConfigGroup target="controller"}}>{{t services.service.config_groups_popup.duplicate}}</a>
+        <div class="btn-toolbar pull-right">
+          <button class="btn" {{bindAttr disabled="isHostsModified"}} {{action addConfigGroup target="controller"}}><i class="icon-plus"></i></button>
+          <button class="btn" {{bindAttr disabled="isHostsModified"}} {{action deleteConfigGroup target="controller"}}><i class="icon-minus"></i></button>
+          <div class="btn-group">
+            <button class="btn" {{bindAttr disabled="isHostsModified"}}><i class="icon-cog"></i></button>
+            <button class="btn dropdown-toggle" data-toggle="dropdown" {{bindAttr disabled="isHostsModified"}}>
+              <span class="caret"></span>
+            </button>
+            <ul class="dropdown-menu">
+              <li>
+                <a {{action renameConfigGroup target="controller"}}>{{t services.service.config_groups_popup.rename}}</a>
+              </li>
+              <li>
+                <a {{action addConfigGroup target="controller"}}>{{t services.service.config_groups_popup.duplicate}}</a>
+              </li>
+            </ul>
+          </div>
         </div>
       </div>
-      <div class="span6">
+      <div class="span7">
         <div class="row-fluid">
           <div class="span2">{{t common.hosts}}</div>
           <div class="span10">
@@ -47,8 +59,8 @@
             }}
           </div>
           <div class="button-group pull-right">
-            <button class="btn" {{bindAttr disabled="selectedConfigGroup.isAddHostsDisabled"}} {{action addHosts target="controller"}} >+</button>
-            <button class="btn" {{bindAttr disabled="selectedConfigGroup.isDeleteHostsDisabled"}} {{action deleteHosts target="controller"}} >-</button>
+            <button class="btn" {{bindAttr disabled="selectedConfigGroup.isAddHostsDisabled"}} {{action addHosts target="controller"}} ><i class="icon-plus"></i></button>
+            <button class="btn" {{bindAttr disabled="selectedConfigGroup.isDeleteHostsDisabled"}} {{action deleteHosts target="controller"}} ><i class="icon-minus"></i></button>
           </div>
         </div>
         <div class="row-fluid">
@@ -59,6 +71,13 @@
           </div>
         </div>
       </div>
+      <div class="span12 text-error" id="manage-config-group-error-div">
+        {{#if errorMessage}}
+          {{errorMessage}}
+        {{else}}
+          &nbsp;
+        {{/if}}
+      </div>
     </div>
   </div>
 </div>

+ 11 - 0
ambari-web/app/utils/ajax.js

@@ -1178,6 +1178,17 @@ var urls = {
         }])
       }
     }
+  },
+  'config_groups.update': {
+    'real': '/clusters/{clusterName}/config_groups/{id}',
+    'mock': '',
+    'format': function (data) {
+      return {
+        async: true,
+        type: 'PUT',
+        data: JSON.stringify(data.data)
+      }
+    }
   }
 };
 /**

+ 59 - 0
ambari-web/app/utils/config.js

@@ -1126,6 +1126,65 @@ App.config = Em.Object.create({
     }
     return newConfigGroupData;
   },
+  
+  /**
+   * PUTs the new configuration-group on the server.
+   * Changes possible here are the name, description and
+   * host memberships of the configuration-group.
+   * 
+   * @param configGroup  (App.ConfigGroup) Configuration group to update
+   */
+  updateConfigurationGroup: function (configGroup, successCallback, errorCallback) {
+    var putConfigGroup = {
+      ConfigGroup: {
+        group_name: configGroup.get('name'),
+        description: configGroup.get('description'),
+        tag: configGroup.get('service.serviceName'),
+        hosts: [],
+        desired_configs: []
+      }  
+    };
+    configGroup.get('hosts').forEach(function(h){
+      putConfigGroup.ConfigGroup.hosts.push({
+        host_name: h
+      });
+    });
+    configGroup.get('configSiteTags').forEach(function(cst){
+      putConfigGroup.ConfigGroup.desired_configs.push({
+        type: cst.type,
+        tag: cst.tag
+      });
+    });
+    
+    var sendData = {
+      name: 'config_groups.update',
+      data: {
+        id: configGroup.get('id'),
+        data: putConfigGroup
+      },
+      success: 'successFunction',
+      error: 'errorFunction',
+      successFunction: function () {
+        if(successCallback) {
+          successCallback();
+        }
+      },
+      errorFunction: function (xhr, text, errorThrown) {
+        error = xhr.status + "(" + errorThrown + ") ";
+        try {
+          var json = $.parseJSON(xhr.responseText);
+          error += json.message;
+        } catch (err) {
+        }
+        console.error('Error updating Config Group:', error, configGroup);
+        if(errorCallback) {
+          errorCallback(error);
+        }
+      }
+    };
+    sendData.sender = sendData;
+    App.ajax.send(sendData);
+  },
 
   /**
    * Gets all the configuration-groups for the given service.