You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2017/05/18 14:01:52 UTC

[11/24] ambari git commit: AMBARI-20698. Ability to export blueprint via Ambari installer UI (alexantonenko)

AMBARI-20698. Ability to export blueprint via Ambari installer UI (alexantonenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4427a336
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4427a336
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4427a336

Branch: refs/heads/branch-feature-AMBARI-12556
Commit: 4427a3365732dd971dc294f4feda75e247be4605
Parents: 99d4ca1
Author: Alex Antonenko <hi...@gmail.com>
Authored: Wed May 17 15:32:05 2017 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Wed May 17 15:51:50 2017 +0300

----------------------------------------------------------------------
 .../app/controllers/wizard/step8_controller.js  | 167 ++++++++++++++++++-
 ambari-web/app/messages.js                      |   1 +
 ambari-web/app/templates/wizard/step8.hbs       |   5 +
 .../test/controllers/wizard/step8_test.js       | 132 +++++++++------
 4 files changed, 254 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/4427a336/ambari-web/app/controllers/wizard/step8_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step8_controller.js b/ambari-web/app/controllers/wizard/step8_controller.js
index 4678d03..7e318e0 100644
--- a/ambari-web/app/controllers/wizard/step8_controller.js
+++ b/ambari-web/app/controllers/wizard/step8_controller.js
@@ -18,6 +18,7 @@
 
 var App = require('app');
 var stringUtils = require('utils/string_utils');
+var fileUtils = require('utils/file_utils');
 
 App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wizardDeployProgressControllerMixin, App.ConfigOverridable, App.ConfigsSaverMixin, {
 
@@ -1764,7 +1765,171 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
     });
   },
 
+  getComponentsForHost: function(host) {
+    if(!host.hostComponents) {
+      App.router.get('installerController').get('allHosts');
+    }
+    var componentNameDetail = [];
+    host.hostComponents.mapProperty('componentName').forEach(function (componentName) {
+      if(componentName === 'CLIENT') {
+        this.get('content.clients').mapProperty('component_name').forEach(function (clientComponent) {
+          componentNameDetail.push({ name : clientComponent });
+        }, this);
+        return;
+      }
+      componentNameDetail.push({ name : componentName });
+    }, this);
+    return componentNameDetail;
+  },
+
+  getPropertyAttributesForConfigType : function(configs) {
+    //Currently only looks for final properties, if any
+    var finalProperties = configs.filterProperty('isFinal', 'true');
+    var propertyAttributes = {};
+    finalProperties.forEach(function (finalProperty) {
+      propertyAttributes[finalProperty['name']] = "true";
+    });
+    var finalPropertyMap = {};
+    if (!App.isEmptyObject(finalProperties)) {
+      finalPropertyMap = {
+        "isFinal": propertyAttributes
+      };
+    }
+    return finalPropertyMap;
+  },
+
+  getConfigurationDetailsForConfigType: function(configs) {
+    var configDetails = {};
+    var self = this;
+    configs.forEach(function (propertyObj) {
+      configDetails[propertyObj['name']] = propertyObj['value'];
+    }, this);
+    var configurationsDetails = {
+      "properties_attributes": self.getPropertyAttributesForConfigType(configs),
+      "properties": configDetails
+    };
+    return configurationsDetails;
+  },
+
+  hostInExistingHostGroup: function (newHost, cluster_template_host_groups) {
+    var hostGroupMatched = false;
+      cluster_template_host_groups.some(function (existingHostGroup) {
+        if(!hostGroupMatched) {
+        var fqdnInHostGroup =  existingHostGroup.hosts[0].fqdn;
+        var componentsInExistingHostGroup = this.getRegisteredHosts().filterProperty('hostName', fqdnInHostGroup)[0].hostComponents;
+        if(componentsInExistingHostGroup.length !== newHost.hostComponents.length) {
+          return;
+        } else {
+          var componentMismatch = false;
+          componentsInExistingHostGroup.forEach(function (componentInExistingHostGroup, index) {
+          if(!componentMismatch) {
+            if(!newHost.hostComponents.mapProperty('componentName').includes(componentInExistingHostGroup.componentName)) {
+              componentMismatch = true;
+            }
+          }
+          });
+          if(!componentMismatch) {
+            hostGroupMatched = true;
+            existingHostGroup["cardinality"]["cardinality"] = parseInt(existingHostGroup["cardinality"]["cardinality"]) + 1;
+            existingHostGroup.hosts.push({"fqdn" : newHost.hostName})
+            return true;
+          }
+        }
+        }
+      }, this);
+    return hostGroupMatched;
+  },
+
+  generateBlueprint: function () {
+    console.log("Prepare blueprint for download...");
+    var blueprint = {};
+    var self = this;
+    //service configurations
+    var totalConf = [];
+    //Add cluster-env
+    var clusterEnv = this.get('configs').filterProperty('filename', 'cluster-env.xml');
+    var configurations = {};
+    configurations["cluster-env"] = self.getConfigurationDetailsForConfigType(clusterEnv);
+    totalConf.push(configurations);
+    //Add configurations for selected services
+    this.get('selectedServices').forEach(function (service) {
+      Object.keys(service.get('configTypes')).forEach(function (type) {
+        if (!this.get('serviceConfigTags').someProperty('type', type)) {
+          var configs = this.get('configs').filterProperty('filename', App.config.getOriginalFileName(type));
+          var configurations = {};
+          configurations[type] = self.getConfigurationDetailsForConfigType(configs);
+          totalConf.push(configurations);
+        }
+      }, this);
+    }, this);
+
+    //TODO address configGroups
+    var host_groups = [];
+    var cluster_template_host_groups = [];
+    var counter = 0;
+
+    this.getRegisteredHosts().filterProperty('isInstalled', false).map(function (host) {
+      var clusterTemplateHostGroupDetail = {};
+      if(self.hostInExistingHostGroup(host, cluster_template_host_groups)) {
+        return;
+      }
+
+      var hostGroupId = "host_group_" + counter;
+      var cardinality = {"cardinality": 1};
+      var hostGroupDetail = {
+        "name": hostGroupId,
+        "components": self.getComponentsForHost(host),
+        cardinality
+      };
+      hostGroupDetail.toJSON = function () {
+      var hostGroupDetailResult = {};
+      for (var x in this) {
+        if (x === "cardinality") {
+          hostGroupDetailResult[x] = (this[x]["cardinality"]).toString();
+          } else {
+            hostGroupDetailResult[x] = this[x];
+        }
+      }
+      return hostGroupDetailResult;
+      }
+      host_groups.push(hostGroupDetail);
+      var hostListForGroup = [];
+      var hostDetail = {
+        "fqdn": host.hostName
+      }
+      hostListForGroup.push(hostDetail);
+      clusterTemplateHostGroupDetail = {
+        "name": hostGroupId,
+        "hosts": hostListForGroup,
+        cardinality
+      };
+      clusterTemplateHostGroupDetail.toJSON = function () {
+        return _.omit(this, [ "cardinality" ]);
+      };
+
+      cluster_template_host_groups.push(clusterTemplateHostGroupDetail);
+      counter++;
+    }, this);
+
+    var selectedStack = App.Stack.find().findProperty('isSelected', true);
+    blueprint = { //TODO: bp name
+        'configurations':totalConf,
+        'host_groups':host_groups,
+        'Blueprints':{'stack_name':selectedStack.get('stackName'), 'stack_version':selectedStack.get('stackVersion')}
+    };
+    fileUtils.downloadTextFile(JSON.stringify(blueprint), 'json', 'blueprint.json')
+
+    var cluster_template = {
+      "blueprint": App.clusterStatus.clusterName,
+      "config_recommendation_strategy" : "NEVER_APPLY",
+      "provision_action" : "INSTALL_AND_START",
+      "configurations":[],
+      "host_groups":cluster_template_host_groups
+    };
+    fileUtils.downloadTextFile(JSON.stringify(cluster_template), 'json', 'clustertemplate.json')
+  },
+
   downloadCSV: function() {
     App.router.get('kerberosWizardStep5Controller').getCSVData(false);
   }
-});
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/4427a336/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index b8e7728..f34cbdc 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -125,6 +125,7 @@ Em.I18n.translations = {
   'common.more': 'More...',
   'common.print':'Print',
   'common.deploy':'Deploy',
+  'common.generate.blueprint':'Generate Blueprint',
   'common.message':'Message',
   'common.tasks':'Tasks',
   'common.open':'Open',

http://git-wip-us.apache.org/repos/asf/ambari/blob/4427a336/ambari-web/app/templates/wizard/step8.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/wizard/step8.hbs b/ambari-web/app/templates/wizard/step8.hbs
index ac32710..907b3d4 100644
--- a/ambari-web/app/templates/wizard/step8.hbs
+++ b/ambari-web/app/templates/wizard/step8.hbs
@@ -99,5 +99,10 @@
     </button>
     <button type="button" class="btn btn-info pull-right" {{action printReview target="view"}}>{{t common.print}}</button>
     <button type="button" {{bindAttr class=":btn :btn-primary :pull-right :mrm controller.showDownloadCsv::hide"}} {{action downloadCSV target="controller"}}>{{t admin.kerberos.wizard.step5.downloadCSV}}</button>
+    {{#unless App.router.clusterInstallCompleted}}
+      <button type="button" class="btn btn-success pull-right" {{action generateBlueprint target="controller"}}><i class="glyphicon glyphicon-download-alt"></i>&nbsp;
+        {{t common.generate.blueprint}}
+      </button>
+    {{/unless}}
   </div>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/4427a336/ambari-web/test/controllers/wizard/step8_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard/step8_test.js b/ambari-web/test/controllers/wizard/step8_test.js
index 7cdb69a..1a3214e 100644
--- a/ambari-web/test/controllers/wizard/step8_test.js
+++ b/ambari-web/test/controllers/wizard/step8_test.js
@@ -50,7 +50,73 @@ var configs = Em.A([
   Em.Object.create({filename: 'falcon-startup.properties.xml', name: 'p1', value: 'v1'}),
   Em.Object.create({filename: 'falcon-startup.properties.xml', name: 'p2', value: 'v2'}),
   Em.Object.create({filename: 'falcon-runtime.properties.xml', name: 'p1', value: 'v1'}),
-  Em.Object.create({filename: 'falcon-runtime.properties.xml', name: 'p2', value: 'v2'})
+  Em.Object.create({filename: 'falcon-runtime.properties.xml', name: 'p2', value: 'v2'}),
+  Em.Object.create({filename: 'cluster-env.xml', name: 'p1', value: 'v1'}),
+]);
+
+var services = Em.A([
+        Em.Object.create({
+          serviceName: 's1',
+          isSelected: true,
+          isInstalled: false,
+          displayNameOnSelectServicePage: 's01',
+          isClientOnlyService: false,
+          serviceComponents: Em.A([
+            Em.Object.create({
+              isClient: true
+            })
+          ]),
+          configTypes: Em.A([
+            Em.Object.create({
+              type: 'cluster-env'
+            })
+          ]),
+          isHiddenOnSelectServicePage: false
+        }),
+        Em.Object.create({
+          serviceName: 's2',
+          isSelected: true,
+          isInstalled: false,
+          displayNameOnSelectServicePage: 's02',
+          serviceComponents: Em.A([
+            Em.Object.create({
+              isMaster: true
+            })
+          ]),
+          configTypes: Em.A([
+            Em.Object.create({
+              type: 'hdfs-site'
+            })
+          ]),
+          isHiddenOnSelectServicePage: false
+        }),
+        Em.Object.create({
+          serviceName: 's3',
+          isSelected: true,
+          isInstalled: false,
+          displayNameOnSelectServicePage: 's03',
+          serviceComponents: Em.A([
+            Em.Object.create({
+              isHAComponentOnly: true
+            })
+          ]),
+          configTypes: [],
+          isHiddenOnSelectServicePage: false
+        }),
+        Em.Object.create({
+          serviceName: 's4',
+          isSelected: true,
+          isInstalled: false,
+          displayNameOnSelectServicePage: 's03',
+          isClientOnlyService: true,
+          serviceComponents: Em.A([
+            Em.Object.create({
+              isClient: true
+            })
+          ]),
+          configTypes: [],
+          isHiddenOnSelectServicePage: false
+        })
 ]);
 
 function getController() {
@@ -211,54 +277,6 @@ describe('App.WizardStep8Controller', function () {
   describe('#loadServices', function () {
 
     beforeEach(function () {
-      var services = Em.A([
-        Em.Object.create({
-          serviceName: 's1',
-          isSelected: true,
-          displayNameOnSelectServicePage: 's01',
-          isClientOnlyService: false,
-          serviceComponents: Em.A([
-            Em.Object.create({
-              isClient: true
-            })
-          ]),
-          isHiddenOnSelectServicePage: false
-        }),
-        Em.Object.create({
-          serviceName: 's2',
-          isSelected: true,
-          displayNameOnSelectServicePage: 's02',
-          serviceComponents: Em.A([
-            Em.Object.create({
-              isMaster: true
-            })
-          ]),
-          isHiddenOnSelectServicePage: false
-        }),
-        Em.Object.create({
-          serviceName: 's3',
-          isSelected: true,
-          displayNameOnSelectServicePage: 's03',
-          serviceComponents: Em.A([
-            Em.Object.create({
-              isHAComponentOnly: true
-            })
-          ]),
-          isHiddenOnSelectServicePage: false
-        }),
-        Em.Object.create({
-          serviceName: 's4',
-          isSelected: true,
-          displayNameOnSelectServicePage: 's03',
-          isClientOnlyService: true,
-          serviceComponents: Em.A([
-            Em.Object.create({
-              isClient: true
-            })
-          ]),
-          isHiddenOnSelectServicePage: false
-        })
-      ]);
       var selectedServices = services.filterProperty('isSelected');
       var slaveComponentHosts = Em.A([
         Em.Object.create({
@@ -2323,5 +2341,19 @@ describe('App.WizardStep8Controller', function () {
     });
 
   });
-
+  //TODO
+  describe('#generateBlueprint', function () {
+     console.log("testing.......")
+     beforeEach(function () {
+         installerStep8Controller = getController();
+         installerStep8Controller.set('configs', configs);
+         installerStep8Controller.set('content.services', services.filterProperty('isSelected'))
+         installerStep8Controller.set('selectedServices', []);
+         sinon.spy(installerStep8Controller, 'getConfigurationDetailsForConfigType');
+     });
+     it('should call generateBlueprint', function() {
+       installerStep8Controller.generateBlueprint();
+       expect(installerStep8Controller.getConfigurationDetailsForConfigType.calledThrice).to.be.true;
+     });
+ });
 });