This is an automated email from the ASF dual-hosted git repository.
jaimin pushed a commit to branch branch-feature-AMBARI-14714-ui
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/branch-feature-AMBARI-14714-ui
by this push:
new efae1bc [AMBARI-22826] Mpack related changes to Add Hosts Page. (#200)
efae1bc is described below
commit efae1bc0c47c9b50b0d1a63f2e03c0b571f929a3
Author: Ishan Bhatt <[email protected]>
AuthorDate: Fri Jan 26 17:27:29 2018 -0800
[AMBARI-22826] Mpack related changes to Add Hosts Page. (#200)
---
ambari-web/app/controllers/wizard.js | 8 +-
.../app/controllers/wizard/step2_controller.js | 187 ++++++++++++++-------
ambari-web/app/messages.js | 23 ++-
ambari-web/app/styles/wizard.less | 119 ++++++++++++-
ambari-web/app/templates/wizard/step2.hbs | 147 +++++++++-------
ambari-web/app/utils/ajax/ajax.js | 4 +
ambari-web/app/views/wizard/step2_view.js | 12 +-
ambari-web/test/controllers/wizard/step2_test.js | 117 ++++---------
ambari-web/test/views/wizard/step2_view_test.js | 30 +---
9 files changed, 387 insertions(+), 260 deletions(-)
diff --git a/ambari-web/app/controllers/wizard.js
b/ambari-web/app/controllers/wizard.js
index 7ef227c..f094851 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -704,8 +704,8 @@ App.WizardController =
Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
installOptionsTemplate: {
hostNames: "", //string
- manualInstall: false, //true, false
- useSsh: true, //bool
+ manualInstall: true, //true, false
+ useSsh: false, //bool
javaHome: App.defaultJavaHome, //string
localRepo: false, //true, false
sshKey: "", //string
@@ -717,8 +717,8 @@ App.WizardController =
Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
installWindowsOptionsTemplate: {
hostNames: "", //string
- manualInstall: false, //true, false
- useSsh: true, //bool
+ manualInstall: true, //true, false
+ useSsh: false, //bool
javaHome: App.defaultJavaHome, //string
localRepo: false, //true, false
sshKey: "", //string
diff --git a/ambari-web/app/controllers/wizard/step2_controller.js
b/ambari-web/app/controllers/wizard/step2_controller.js
index c6da054..7caa3c6 100644
--- a/ambari-web/app/controllers/wizard/step2_controller.js
+++ b/ambari-web/app/controllers/wizard/step2_controller.js
@@ -25,6 +25,14 @@ App.WizardStep2Controller = App.WizardStepController.extend({
name: 'wizardStep2Controller',
+ parsedHostsText:
Em.I18n.t('installer.step2.parsedHostsPlaceholder').format(0),
+
+ preRegisteredHostFound:
Em.I18n.t('installer.step2.preRegistered.hostCount').format(0),
+
+ manuallyInstalledHosts: [],
+
+ noPreRegisteredHosts: true,
+
stepName: 'step2',
/**
@@ -55,6 +63,8 @@ App.WizardStep2Controller = App.WizardStepController.extend({
*/
inputtedAgainHostNames: [],
+ filterText: null,
+
/**
* Is Installer Controller used
* @type {bool}
@@ -130,12 +140,24 @@ App.WizardStep2Controller =
App.WizardStepController.extend({
return !App.get('isHadoopWindowsStack');
}.property('App.isHadoopWindowsStack'),
+ useSshRegistration: function () {
+ this.set('content.installOptions.manualInstall', false);
+ this.set('content.installOptions.useSsh', true);
+ },
+
+ useManualInstall: function () {
+ if (!this.get('content.installOptions.manualInstall')) {
+ this.getManuallyInstalledHosts();
+ }
+ this.set('content.installOptions.manualInstall', true);
+ this.set('content.installOptions.useSsh', false);
+ },
/**
* Error-message if <code>sshKey</code> is empty, null otherwise
* @type {string|null}
*/
sshKeyError: function () {
- if (this.get('hasSubmitted') && this.get('manualInstall') === false &&
this.get('useSSH') && Em.isBlank(this.get('sshKey'))) {
+ if (this.get('hasSubmitted') && this.get('manualInstall') === false &&
!this.get('manualInstall') && Em.isBlank(this.get('sshKey'))) {
return Em.I18n.t('installer.step2.sshKey.error.required');
}
return null;
@@ -174,11 +196,13 @@ App.WizardStep2Controller =
App.WizardStepController.extend({
return null;
}.property('agentUser', 'hasSubmitted', 'manualInstall'),
+ preRegisteredHostsError: Em.computed.and('manualInstall'
,'noPreRegisteredHosts'),
+
/**
* is Submit button disabled
* @type {bool}
*/
- isSubmitDisabled: Em.computed.or('hostsError', 'sshKeyError',
'sshUserError', 'sshPortError', 'agentUserError',
'App.router.btnClickInProgress'),
+ isSubmitDisabled: Em.computed.or('hostsError', 'sshKeyError',
'sshUserError', 'sshPortError', 'agentUserError',
'App.router.btnClickInProgress', 'preRegisteredHostsError'),
loadStep: function () {
//save initial hostNames value to check later if changes were made
@@ -198,21 +222,87 @@ App.WizardStep2Controller =
App.WizardStepController.extend({
}.property('content.hosts'),
/**
+ * get hosts that are installed manually
+ return
+ */
+ getManuallyInstalledHosts: function () {
+ App.ajax.send({
+ name: 'hosts.confirmed.install',
+ sender: this,
+ success: 'getManuallyInstalledHostsSuccessCallback'
+ });
+ },
+
+ getManuallyInstalledHostsSuccessCallback(response) {
+ var installedHosts = [],
+ self = this;
+ if (response.items.length > 0) {
+ response.items.forEach(function (item, indx) {
+ installedHosts.push(Em.Object.create({
+ 'controller': self,
+ 'hostName': item.Hosts.host_name,
+ 'cpuCount': item.Hosts.cpu_count,
+ 'memory': (parseFloat(item.Hosts.total_mem) / (1024 *
1024)).toFixed(2) + " GB",
+ 'freeSpace': (parseFloat(item.Hosts.disk_info[0].available) / (1024
* 1024)).toFixed(2) + " GB",
+ 'isVisible': true,
+
+ filterRow: function() {
+ var filter = self.get('filterText');
+ if(filter &&
!(item.Hosts.host_name.toUpperCase().indexOf(filter.toUpperCase()) > -1)) {
+ this.set('isVisible', false);
+ } else {
+ this.set('isVisible', true);
+ }
+ }.observes('controller.filterText')
+ }));
+ });
+ this.set('preRegisteredHostFound',
Em.I18n.t('installer.step2.preRegistered.hostCount').format(installedHosts.length));
+ this.set('manuallyInstalledHosts', installedHosts);
+ this.set('noPreRegisteredHosts', false);
+ } else {
+ this.set('preRegisteredHostFound',
Em.I18n.t('installer.step2.preRegistered.hostCount').format(0));
+ this.set('noPreRegisteredHosts', true);
+ this.set('manuallyInstalledHosts', []);
+ }
+ },
+
+ deleteRegisteredHost: function (event) {
+ var hostName = event.context;
+ App.ajax.send({
+ name: 'common.delete.registered.host',
+ sender: this,
+ data: {
+ hostName: event.context
+ },
+ success: 'deleteRegisteredHostSuccessCallback'
+ });
+ },
+
+ deleteRegisteredHostSuccessCallback: function (response) {
+ this.getManuallyInstalledHosts();
+ },
+
+ /**
* Set not installed hosts to the hostNameArr
* @method updateHostNameArr
*/
updateHostNameArr: function () {
- this.set('hostNameArr', this.get('hostNames').trim().split(new
RegExp("\\s+", "g")));
- this.parseHostNamesAsPatternExpression();
- this.get('inputtedAgainHostNames').clear();
- var tempArr = [],
- hostNameArr = this.get('hostNameArr');
- for (var i = 0; i < hostNameArr.length; i++) {
- if (!this.get('installedHostNames').contains(hostNameArr[i])) {
- tempArr.push(hostNameArr[i]);
- }
- else {
- this.get('inputtedAgainHostNames').push(hostNameArr[i]);
+ var tempArr = [];
+ if (this.get('manualInstall')) {
+ tempArr = this.get('manuallyInstalledHosts').mapProperty('hostName');
+ } else {
+ this.set('hostNameArr', this.get('hostNames').trim().split(new
RegExp("\\s+", "g")));
+ this.parseHostNamesAsPatternExpression();
+ this.get('inputtedAgainHostNames').clear();
+
+ var hostNameArr = this.get('hostNameArr');
+ for (var i = 0; i < hostNameArr.length; i++) {
+ if (!this.get('installedHostNames').contains(hostNameArr[i])) {
+ tempArr.push(hostNameArr[i]);
+ }
+ else {
+ this.get('inputtedAgainHostNames').push(hostNameArr[i]);
+ }
}
}
this.set('hostNameArr', tempArr);
@@ -237,12 +327,22 @@ App.WizardStep2Controller =
App.WizardStepController.extend({
return result;
},
+ parseHosts: function () {
+ var hostNames = this.get('hostNames').trim().split(new RegExp("\\s+",
"g"));
+ if (hostNames[0] == "") {
+ this.set('parsedHostsText',
Em.I18n.t('installer.step2.parsedHostsPlaceholder').format(0));
+ } else {
+ var parsedHostNames = this.parseHostNamesAsPatternExpression(hostNames);
+ this.set('parsedHostsText',
(Em.I18n.t('installer.step2.parsedHostsPlaceholder').format(parsedHostNames.length)
+ '\n' + parsedHostNames.join('\n')));
+ }
+ }.observes('hostNames'),
+
/**
* Set hostsError if host names don't pass validation
* @method checkHostError
*/
checkHostError: function () {
- if (Em.isEmpty(this.get('hostNames').trim())) {
+ if (!this.get('manualInstall') &&
Em.isEmpty(this.get('hostNames').trim())) {
this.set('hostsError',
Em.I18n.t('installer.step2.hostName.error.required'));
}
else {
@@ -314,10 +414,6 @@ App.WizardStep2Controller =
App.WizardStepController.extend({
return false;
}
- if (this.get('isPattern')) {
- this.hostNamePatternPopup(this.get('hostNameArr'));
- return false;
- }
if (this.get('inputtedAgainHostNames.length')) {
this.installedHostsPopup();
}
@@ -332,11 +428,13 @@ App.WizardStep2Controller =
App.WizardStepController.extend({
* push hosts that match pattern in hostNameArr
* @method parseHostNamesAsPatternExpression
*/
- parseHostNamesAsPatternExpression: function () {
+ parseHostNamesAsPatternExpression: function (hostNamesToBeParsed) {
this.set('isPattern', false);
var hostNames = [];
- this.get('hostNameArr').forEach(function (a) {
+ var hostNameArr = hostNamesToBeParsed || this.get('hostNameArr');
+
+ hostNameArr.forEach(function (a) {
var hn,
allPatterns = a.match(/\[\d*\-\d*\]/g),
patternsNumber = allPatterns ? allPatterns.length : 0;
@@ -352,7 +450,11 @@ App.WizardStep2Controller =
App.WizardStepController.extend({
}
}, this);
- this.set('hostNameArr', hostNames.uniq());
+ if(hostNamesToBeParsed) {
+ return hostNames;
+ } else {
+ this.set('hostNameArr', hostNames.uniq());
+ }
},
/**
@@ -406,12 +508,6 @@ App.WizardStep2Controller =
App.WizardStepController.extend({
this.warningPopup();
return false;
}
-
- if (this.get('manualInstall') === true) {
- this.manualInstallPopup();
- return false;
- }
-
this.saveHosts();
App.router.send('next');
return true;
@@ -491,43 +587,6 @@ App.WizardStep2Controller =
App.WizardStepController.extend({
},
/**
- * Show notify that installation is manual
- * save hosts
- * @return {App.ModalPopup}
- * @method manualInstallPopup
- */
- manualInstallPopup: function () {
- var self = this;
- return App.ModalPopup.show({
- header: Em.I18n.t('installer.step2.manualInstall.popup.header'),
- onPrimary: function () {
- this.hide();
- self.saveHosts();
- App.router.send('next');
- },
- bodyClass: Em.View.extend({
- templateName: require('templates/wizard/step2ManualInstallPopup')
- })
- });
- },
-
- /**
- * Warn to manually install ambari-agent on each host
- * @method manualInstallWarningPopup
- */
- manualInstallWarningPopup: function () {
- if (!this.get('content.installOptions.useSsh')) {
- App.ModalPopup.show({
- header: Em.I18n.t('common.warning'),
- body: Em.I18n.t('installer.step2.manualInstall.info'),
- encodeBody: false,
- secondary: null
- });
- }
- this.set('content.installOptions.manualInstall',
!this.get('content.installOptions.useSsh'));
- }.observes('content.installOptions.useSsh'),
-
- /**
* Load java.home value frin server
* @method setAmbariJavaHome
*/
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 55e2f17..70705ce 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -229,6 +229,8 @@ Em.I18n.translations = {
'common.more': 'More...',
'common.move':'Move',
'common.mpack': 'Management Pack',
+ 'common.freeStorage': 'Free Storage',
+ 'common.noHostsFound': 'No Hosts found.',
'common.na': 'n/a',
'common.name':'Name',
'common.next':'Next',
@@ -734,10 +736,11 @@ Em.I18n.translations = {
'installer.step1.checkAtLeastOneAttention': '<b>Attention:</b> Please check
at least one repository.',
'installer.step1.retryRepoUrls': 'Click <b>here</b> to retry.',
- 'installer.step2.header':'Install Options',
- 'installer.step2.body':'Enter the list of hosts to be included in the
cluster and provide your SSH key.',
- 'installer.step2.targetHosts':'Target Hosts',
- 'installer.step2.targetHosts.info':'Enter a list of hosts using the Fully
Qualified Domain Name (FQDN), one per line',
+ 'installer.step2.header':'Add Hosts',
+ 'installer.step2.registration.body1' : 'Ambari Agents can be automatically
installed using SSH, or they can be manually installed and registered with the
Ambari Server.',
+ 'installer.step2.registration.body2' : 'Please choose the installation type
below:',
+ 'installer.step2.enterHosts':'Enter Hosts',
+ 'installer.step2.enterHosts.info':'Enter a list of hosts using the Fully
Qualified Domain Name (FQDN), one per line',
'installer.step2.hostPattern.tooltip.title':'Pattern Expressions',
'installer.step2.hostPattern.tooltip.content':'You can use pattern
expressions to specify a number of target hosts. For example, to specify
host01.domain thru host10.domain, enter host[01-10].domain in the target hosts
textarea.',
'installer.step2.hostName.error.required':'You must specify at least one
host name',
@@ -768,15 +771,18 @@ Em.I18n.translations = {
'installer.step2.javaHome.tooltip.title' : 'JAVA_HOME',
'installer.step2.javaHome.tooltip.content' : 'Path to 64-bit JAVA_HOME.
/usr/jdk/jdk1.6.0_31 is the default used by Ambari. You can override this to a
specific path that contains the JDK. <br/> Note: the path must be valid on
<b>ALL</b> hosts in your cluster.',
'installer.step2.javaHome.tooltip.placeholder' : '/usr/jdk/jdk1.6.0_31',
+ 'installer.step2.automaticInstall' : 'Register Agents automatically',
'installer.step2.automaticInstall.tooltip.title':'automatic registration',
'installer.step2.automaticInstall.tooltip.content':'Ambari will
automatically install and register the Ambari Agent on each host prior to the
cluster installation.',
'installer.step2.useSsh.provide' : 'Provide your',
'installer.step2.useSsh.provide_id_rsa' : ' to automatically register hosts',
'installer.step2.useSsh.tooltip.title':'SSH Private Key',
'installer.step2.useSsh.tooltip.content':'The <b>SSH Private Key File</b> is
used to connect to the target hosts in your cluster to install the Ambari
Agent.',
+ 'installer.step2.useSsh' : 'Register Agents Using SSH',
'installer.step2.install.perform':'Perform',
'installer.step2.install.perform_on_hosts':'on hosts',
'installer.step2.install.without_ssh':' and do not use SSH',
+ 'installer.step2.manualInstall' : 'Register Agents Manually',
'installer.step2.manualInstall.tooltip.title':'manual registration',
'installer.step2.manualInstall.tooltip.content':'Manually registering the
Ambari Agent on each host eliminates the need for SSH and should be performed
prior to continuing cluster installation.',
'installer.step2.manualInstall.tooltip.content_no_ssh':'Manually registering
the Ambari Agent on each host should be performed prior to continuing cluster
installation.',
@@ -803,6 +809,15 @@ Em.I18n.translations = {
'installer.step2.skipHostChecks.label': 'Skip host checks',
'installer.step2.skipHostChecks.popup.header': 'Warning',
'installer.step2.skipHostChecks.popup.body': 'By skipping host checks,
Ambari will not check and warn if any issues with the host are identified and
the host will be added to the cluster as is.',
+ 'installer.step2.parsedHostsPlaceholder' : '{0} HOSTS ADDED',
+ 'installer.step2.preRegistered.hostCount': 'We found <strong>{0}</strong>
registered hosts.',
+ 'installer.step2.noHostsFound.header': 'Please follow the following steps to
register hosts manually. Refresh the table to see the updated list.',
+ 'installer.step2.noHostsFound.step1': '1. Lorem ipsum dolor sit amet,
consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et.',
+ 'installer.step2.noHostsFound.step2': '2. Lorem ipsum dolor sit amet,
consectetur adipiscing elit, sed do eiusmod tempor.',
+ 'installer.step2.noHostsFound.step3': '3. Lorem ipsum dolor sit amet,
consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore.',
+ 'installer.step2.noHostsFound.step4': '4. Lorem ipsum dolor sit amet,
consectetur adipiscing elit.',
+ 'installer.step2.noHostsFound.learn': '<a
href="https://docs.hortonworks.com/HDPDocuments/Ambari-2.6.0.0/bk_ambari-administration/content/ch_amb_ref_installing_ambari_agents_manually.html"
target="_blank"><u>Learn More</u></a>',
+ 'installer.step2.refresh.table': 'REFRESH TABLE',
'installer.step3.header':'Confirm Hosts',
'installer.step3.body':'Registering your hosts.<br>' +
diff --git a/ambari-web/app/styles/wizard.less
b/ambari-web/app/styles/wizard.less
index 8051f6e..129c812 100644
--- a/ambari-web/app/styles/wizard.less
+++ b/ambari-web/app/styles/wizard.less
@@ -64,22 +64,121 @@
}
#installOptions {
- #targetHosts {
- .step-title {
- margin-bottom: 10px;
- }
+ .step-description {
+ color: #999;
+ font-size: 11px;
}
.radio-button-options {
- margin-top: 10px;
- margin-bottom: 10px;
+ padding-bottom: 10px;
+ color: #666;
+ .radio.big-radio {
+ height: 100px;
+ background-color: #dddddd;
+ width: 115px;
+ margin: 15px;
+ padding-left: 0;
+ padding-right: 0;
+ border-radius: 4px;
+ float: left;
+ input[type="radio"] + label, p, .repo-group, {
+ cursor: default;
+ }
+ input[type="radio"] + label:before {
+ border-color: #999;
+ background-color: #fff;
+ }
+ input[type="radio"]:checked + label:before {
+ background: #fff;
+ border-color: #3FAE2A;
+ }
+ input[type="radio"]:checked + label:after {
+ background-color: #3FAE2A;
+ }
+ .repo-checkbox {
+ padding: 0 5px;
+ margin-top: 5px;
+ }
+ .icon {
+ font-size: 37px;
+ text-align: center;
+ position: absolute;
+ top: 15px;
+ padding: 0 20px;
+ width: 100%;
+ color: #fff;
+ }
+ .repo-group {
+ bottom: 0px;
+ position: absolute;
+ background-color: #3FAE2A;
+ color: white;
+ width: 100%;
+ font-size: 12px;
+ text-align: center;
+ border-radius: 2px;
+ }
+ }
}
.wizard-plain-text {
- color: #666;
+ font-weight: normal;
}
.ssh-user, .ssh-port {
padding-top: 8px;
}
+ #host-names, #parsed-host-names {
+ font-size: 12px;
+ }
+
+ #parsed-host-names {
+ background-color: #eee;
+ }
+
+ .hosts-filter-box {
+ padding-right: 5px;
+ .form-control:after {
+ content: '\f080';
+ }
+ }
+
+ .hosts-table-options {
+ overflow: auto;
+ margin-bottom: 20px;
+ .icon-undo {
+ color: #666;
+ }
+ .host-count {
+ color: #666;
+ font-size: 12px;
+ padding-top: 10px;
+ }
+ }
+
+ .no-pre-registered{
+ color: #999;
+ font-size: 10px;
+ p {
+ margin-left: 30px;
+ }
+ .no-host-header {
+ font-size: 30px;
+ margin: 20px 0px 0px 30px;
+ }
+ .no-host-title {
+ font-size: 12px;
+ }
+ }
+
+ .pre-registered{
+ a {
+ color: #666;
+ text-decoration: none;
+ i {
+ color: #999;
+ }
+ }
+ }
+
#sshKey {
color: #555;
font-family: "Courier New","courier";
@@ -104,6 +203,12 @@
color: #666;
}
}
+ .icon-ellipsis-vertical {
+ margin-top: auto;
+ margin-bottom: auto;
+ color: #999;
+ font-size: 18px;
+ }
}
#confirm-hosts {
diff --git a/ambari-web/app/templates/wizard/step2.hbs
b/ambari-web/app/templates/wizard/step2.hbs
index c141ed0..7d523b9 100644
--- a/ambari-web/app/templates/wizard/step2.hbs
+++ b/ambari-web/app/templates/wizard/step2.hbs
@@ -19,15 +19,40 @@
<div id="installOptions" class="wizard-content col-md-9">
<h4 class="step-title">{{t installer.step2.header}}</h4>
{{#if isSaved}}
- <div class="alert alert-warning" role="alert"><strong>{{t
installer.warning.changes.header}}</strong> {{t
installer.warning.changes}}</div>
+ <div class="alert alert-warning" role="alert"><strong>{{t
installer.warning.changes.header}}</strong> {{t
installer.warning.changes}}</div>
{{/if}}
<div class="panel panel-default">
<div class="panel-body">
- <div id="targetHosts" {{QAAttr "target-hosts"}}>
- <div class="step-title" {{QAAttr "target-hosts-title"}}>{{t
installer.step2.targetHosts}}</div>
+ <div class="step-description">
+ <div>{{t installer.step2.registration.body1}}</div>
+ {{t installer.step2.registration.body2}}
+ </div>
+ <div class="row radio-button-options">
+ <div {{bindAttr class=":col-sm-4 :radio :big-radio :manual-radio
:public-radio :wizard-plain-text
controller.content.installOptions.manualInstall:repo-selected:repo-not-selected"}}
{{action useManualInstall target="controller"}}>
+ {{#view view.manualRegistrationRadioButton
classNames="repo-checkbox"
labelIdentifier="manual-registration-radio-button"}}{{/view}}
+ <i class="icon icon-edit"></i>
+ <div class="repo-group">
+ {{t installer.step2.manualInstall}}
+ </div>
+ </div>
+ <div {{bindAttr class=":col-sm-4 :radio :big-radio :ssh-radio
:public-radio :wizard-plain-text
controller.content.installOptions.useSsh:repo-selected:repo-not-selected"}}
{{action useSshRegistration target="controller"}}>
+ {{#view view.providingSSHKeyRadioButton classNames="repo-checkbox"
labelIdentifier="ssh-key-radio-button"}}{{/view}}
+ <i class="icon icon-lock"></i>
+ <div class="repo-group">
+ {{#if useSSH}}
+ {{t installer.step2.useSsh}}
+ {{else}}
+ {{t installer.step2.automaticInstall}}
+ {{/if}}
+ </div>
+ </div>
+ </div>
+
+ <div id="targetHosts" {{QAAttr "target-hosts"}} {{bindAttr
class="controller.content.installOptions.useSsh:display:noDisplay"}}>
+ <div {{QAAttr "target-hosts-title"}}>{{t
installer.step2.enterHosts}}</div>
<div {{bindAttr class="hostsError:has-error :form-group
:target-hosts-input"}}>
- <p class="wizard-plain-text" {{QAAttr
"target-hosts-description"}}>{{t installer.step2.targetHosts.info}}. {{t
installer.step2.orUse}}
+ <p class="step-description" {{QAAttr
"target-hosts-description"}}>{{t installer.step2.enterHosts.info}}. {{t
installer.step2.orUse}}
<a href="javascript:void(null)"
rel="popover"
{{translateAttr
title="installer.step2.hostPattern.tooltip.title"
data-content="installer.step2.hostPattern.tooltip.content"}}
@@ -36,10 +61,14 @@
</a>
</p>
- <div class="row">
- <div class="col-md-8">
+ <div class="row display-flex">
+ <div class="col-md-7">
{{view Ember.TextArea id="host-names" class="form-control"
valueBinding="content.installOptions.hostNames"
- rows="5" placeholder="host names"
data-qa="target-hosts-textarea"}}
+ rows="5" placeholder="Type or paste hosts here..."
data-qa="target-hosts-textarea"}}
+ </div>
+ <i class="icon-ellipsis-vertical"></i>
+ <div class="col-md-7">
+ {{view Ember.TextArea id="parsed-host-names" disabled=true
class="form-control" valueBinding="parsedHostsText" rows="5"}}
</div>
{{#if hostsError}}
<div class="col-md-4">
@@ -50,62 +79,11 @@
</div>
</div>
- <div {{QAAttr "host-registration-info"}}>
- <div class="step-title" {{QAAttr "host-registration-info-title"}}>{{t
installer.step2.sshKey}}</div>
- <div class="row radio-button-options">
- <div class="col-sm-5 row">
- <div class="col-sm-1">
- {{#view view.providingSSHKeyRadioButton
labelIdentifier="ssh-key-radio-button"}}{{/view}}
- </div>
- <div class="col-sm-10 wizard-plain-text">
- {{#if useSSH}}
- {{t installer.step2.useSsh.provide}}
- <a href="javascript:void(null)"
- rel="popover"
- {{translateAttr title="installer.step2.useSsh.tooltip.title"
data-content="installer.step2.useSsh.tooltip.content"}}
- {{QAAttr "ssh-tooltip-link"}}>
- {{t installer.step2.useSsh.tooltip.title}}</a>
- {{t installer.step2.useSsh.provide_id_rsa}}
- {{else}}
- {{t installer.step2.install.perform}}
- <a href="javascript:void(null)"
- rel="popover"
- {{translateAttr
title="installer.step2.automaticInstall.tooltip.title"
data-content="installer.step2.automaticInstall.tooltip.content"}}
- {{QAAttr "ssh-tooltip-link"}}>
- {{t installer.step2.automaticInstall.tooltip.title}}</a>
- {{t installer.step2.install.perform_on_hosts}}
- {{/if}}
- </div>
- </div>
- <div class="col-sm-5 row">
- <div class="col-sm-1">
- {{#view view.manualRegistrationRadioButton
labelIdentifier="manual-registration-radio-button"}}{{/view}}
- </div>
- <div class="col-sm-10 wizard-plain-text">
- {{t installer.step2.install.perform}}
- {{#if useSSH}}
- <a href="javascript:void(null)"
- rel="popover"
- {{translateAttr
title="installer.step2.manualInstall.tooltip.title"
data-content="installer.step2.manualInstall.tooltip.content"}}
- {{QAAttr "ssh-tooltip-link"}}>
- {{t installer.step2.manualInstall.tooltip.title}}</a>
- {{else}}
- <a href="javascript:void(null)"
- rel="popover"
- {{translateAttr
title="installer.step2.manualInstall.tooltip.title"
data-content="installer.step2.manualInstall.tooltip.content_no_ssh"}}
- {{QAAttr "ssh-tooltip-link"}}>
- {{t installer.step2.manualInstall.tooltip.title}}</a>
- {{/if}}
- {{t installer.step2.install.perform_on_hosts}}
- {{#if useSSH}}
- {{t installer.step2.install.without_ssh}}
- {{/if}}
- </div>
- </div>
- </div>
+ <div {{QAAttr "host-registration-info"}} {{bindAttr
class="controller.content.installOptions.useSsh:display:noDisplay"}}>
{{#if useSSH}}
<div class="ssh-key-input">
+ <p>{{t installer.step2.useSsh.tooltip.title}}</p>
{{#if view.isFileApi}}
<div>
{{view App.SshKeyFileUploader
disabledBinding="view.sshKeyState"}}
@@ -114,9 +92,9 @@
{{! ssh key }}
<div {{bindAttr class="sshKeyError:has-error :form-group :row"}}>
- <div class="col-md-8">
+ <div class="col-md-12 display">
{{view Ember.TextArea class="form-control" rows="3" id="sshKey"
- placeholder="ssh private key"
disabledBinding="view.sshKeyState"
+ placeholder="Upload or paste key here"
disabledBinding="view.sshKeyState"
valueBinding="content.installOptions.sshKey"
data-qa="ssh-key-textarea"}}
</div>
{{#if sshKeyError}}
@@ -185,6 +163,51 @@
</div>
{{/if}}
</div>
+ <div {{bindAttr
class="controller.content.installOptions.manualInstall:display:noDisplay"}}>
+ <div class="hosts-table-options">
+ <div {{bindAttr class=":left :host-count
controller.noPreRegisteredHosts:noDisplay:display"}}>{{{controller.preRegisteredHostFound}}}</div>
+ <button {{action getManuallyInstalledHosts target="controller"}}
class="btn btn-default pull-right"><i class="icon-undo"></i> {{t
installer.step2.refresh.table}}</button>
+ <div {{bindAttr class=":hosts-filter-box :pull-right
controller.noPreRegisteredHosts:noDisplay:display"}}>
+ {{view Em.TextField valueBinding="controller.filterText"
class="form-control" placeholder="Filter"}}
+ </div>
+ </div>
+ <table class="table table-hover">
+ <thead>
+ <tr>
+ <th class="col-md-6">{{t common.host}}</th>
+ <th class="col-md-2">{{t common.cores}}</th>
+ <th class="col-md-2">{{t common.freeStorage}}</th>
+ <th class="col-md-2">{{t common.memory}}</th>
+ <th class="col-md-2">{{t common.actions}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{#if noPreRegisteredHosts}}
+ <tr class="no-pre-registered">
+ <td colspan="5">
+ <p class="no-host-header">{{t common.noHostsFound}}</p>
+ <p class="no-host-title">{{t
installer.step2.noHostsFound.header}}</p>
+ <p>{{t installer.step2.noHostsFound.step1}}</p>
+ <p>{{t installer.step2.noHostsFound.step2}}</p>
+ <p>{{t installer.step2.noHostsFound.step3}}</p>
+ <p>{{t installer.step2.noHostsFound.step4}}</p>
+ <p>{{{t installer.step2.noHostsFound.learn}}}</p>
+ </td>
+ </tr>
+ {{else}}
+ {{#each host in manuallyInstalledHosts}}
+ <tr {{bindAttr class=":pre-registered host.isVisible::hidden"}}>
+ <td>{{host.hostName}}</td>
+ <td>{{host.cpuCount}}</td>
+ <td>{{host.freeSpace}}</td>
+ <td>{{host.memory}}</td>
+ <td><a><i class="icon-remove-sign" {{action
deleteRegisteredHost host.hostName target="controller"}}></i></a></td>
+ </tr>
+ {{/each}}
+ {{/if}}
+ </tbody>
+ </table>
+ </div>
{{#if isAddHostWizard}}
<br>
{{view view.skipHostsCheckBox
checkedBinding="content.installOptions.skipHostChecks"}}
diff --git a/ambari-web/app/utils/ajax/ajax.js
b/ambari-web/app/utils/ajax/ajax.js
index b944880..5869f49 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -378,6 +378,10 @@ var urls = {
}
},
+ 'common.delete.registered.host': {
+ 'real': '/hosts/{hostName}',
+ 'type': 'DELETE'
+ },
'common.delete.host': {
'real': '/clusters/{clusterName}/hosts/{hostName}',
'type': 'DELETE'
diff --git a/ambari-web/app/views/wizard/step2_view.js
b/ambari-web/app/views/wizard/step2_view.js
index e498a2d..06f1c21 100644
--- a/ambari-web/app/views/wizard/step2_view.js
+++ b/ambari-web/app/views/wizard/step2_view.js
@@ -60,7 +60,9 @@ App.WizardStep2View = Em.View.extend({
//todo: move them to conroller
this.set('controller.hostsError', null);
this.set('controller.sshKeyError', null);
+ this.set('controller.filterText', null);
this.get('controller').loadStep();
+ this.get('controller').getManuallyInstalledHosts();
},
/**
@@ -87,11 +89,6 @@ App.WizardStep2View = Em.View.extend({
providingSSHKeyRadioButton: App.RadioButtonView.extend({
classNames: ['radio'],
checked: Em.computed.alias('controller.content.installOptions.useSsh'),
-
- click: function () {
- this.set('controller.content.installOptions.useSsh', true);
- this.set('controller.content.installOptions.manualInstall', false);
- }
}),
/**
@@ -101,11 +98,6 @@ App.WizardStep2View = Em.View.extend({
manualRegistrationRadioButton: App.RadioButtonView.extend({
classNames: ['radio'],
checked:
Em.computed.alias('controller.content.installOptions.manualInstall'),
-
- click: function () {
- this.set('controller.content.installOptions.manualInstall', true);
- this.set('controller.content.installOptions.useSsh', false);
- }
}),
/**
diff --git a/ambari-web/test/controllers/wizard/step2_test.js
b/ambari-web/test/controllers/wizard/step2_test.js
index c1614b9..15bb625 100644
--- a/ambari-web/test/controllers/wizard/step2_test.js
+++ b/ambari-web/test/controllers/wizard/step2_test.js
@@ -74,7 +74,7 @@ describe('App.WizardStep2Controller', function () {
App.TestAliases.testAsComputedAlias(getController(), 'agentUser',
'content.installOptions.agentUser', 'string');
- App.TestAliases.testAsComputedOr(getController(), 'isSubmitDisabled',
['hostsError', 'sshKeyError', 'sshUserError', 'sshPortError', 'agentUserError',
'App.router.btnClickInProgress']);
+ App.TestAliases.testAsComputedOr(getController(), 'isSubmitDisabled',
['hostsError', 'sshKeyError', 'sshUserError', 'sshPortError', 'agentUserError',
'App.router.btnClickInProgress', 'preRegisteredHostsError']);
describe('#hostNames', function() {
it('should be equal to content.installOptions.hostNames', function() {
@@ -391,15 +391,6 @@ describe('App.WizardStep2Controller', function () {
});
expect(controller.evaluateStep()).to.equal(false);
});
-
- it('should return false if isPattern is true', function () {
- var controller = App.WizardStep2Controller.create({
- hostNames: 'apache.ambari',
- isPattern: true,
- parseHostNamesAsPatternExpression: Em.K
- });
- expect(controller.evaluateStep()).to.equal(false);
- })
});
describe('#parseHostNamesAsPatternExpression()', function () {
@@ -454,13 +445,11 @@ describe('App.WizardStep2Controller', function () {
beforeEach(function () {
sinon.stub(c, 'warningPopup', Em.K);
- sinon.stub(c, 'manualInstallPopup', Em.K);
sinon.stub(App.router, 'send', Em.K);
});
afterEach(function () {
c.warningPopup.restore();
- c.manualInstallPopup.restore();
App.router.send.restore();
});
@@ -475,16 +464,6 @@ describe('App.WizardStep2Controller', function () {
expect(c.warningPopup.calledOnce).to.equal(true);
});
- it('should call manualInstallPopup if manualInstall is true', function () {
- c.reopen({
- hostNames: '',
- manualInstall: true
- });
- var r = c.proceedNext(true);
- expect(r).to.equal(false);
- expect(c.manualInstallPopup.calledOnce).to.equal(true);
- });
-
it ('should save hosts and proceed next if manualInstall is false',
function() {
c.reopen({
hostNameArr: ['h1'],
@@ -542,66 +521,6 @@ describe('App.WizardStep2Controller', function () {
});
});
- describe('#hostNamePatternPopup', function() {
- beforeEach(function() {
- sinon.spy(App.ModalPopup, 'show');
- sinon.stub(c, 'proceedNext', Em.K);
- });
- afterEach(function() {
- App.ModalPopup.show.restore();
- c.proceedNext.restore();
- });
- it('should call App.ModalPopup.show', function() {
- c.hostNamePatternPopup();
- expect(App.ModalPopup.show.calledOnce).to.equal(true);
- });
- it('should proceed next on primary', function() {
- c.hostNamePatternPopup().onPrimary();
- expect(c.proceedNext.calledOnce).to.equal(true);
- });
- });
-
- describe('#manualInstallPopup', function() {
- beforeEach(function() {
- sinon.spy(App.ModalPopup, 'show');
- sinon.stub(App.router, 'send', Em.K);
- sinon.stub(c, 'saveHosts', Em.K);
- });
- afterEach(function() {
- App.ModalPopup.show.restore();
- App.router.send.restore();
- c.saveHosts.restore();
- });
- it('should call App.ModalPopup.show', function() {
- c.manualInstallPopup();
- expect(App.ModalPopup.show.calledOnce).to.equal(true);
- });
- it('should save hosts and go next on primary', function() {
- c.manualInstallPopup().onPrimary();
- expect(c.saveHosts.calledOnce).to.equal(true);
- expect(App.router.send.calledWith('next')).to.equal(true);
- });
- });
-
- describe('#manualInstallWarningPopup', function() {
- beforeEach(function() {
- sinon.spy(App.ModalPopup, 'show');
- });
- afterEach(function() {
- App.ModalPopup.show.restore();
- });
- it('should call App.ModalPopup.show if content.installOptions.useSsh is
false', function() {
- var controller = App.WizardStep2Controller.create({content:
{installOptions: {useSsh: false}}});
- controller.manualInstallWarningPopup();
- expect(App.ModalPopup.show.calledOnce).to.equal(true);
- });
- it('shouldn\'t call App.ModalPopup.show if content.installOptions.useSsh
is true', function() {
- var controller = App.WizardStep2Controller.create({content:
{installOptions: {useSsh: true}}});
- controller.manualInstallWarningPopup();
- expect(App.ModalPopup.show.called).to.equal(false);
- });
- });
-
describe('#setAmbariJavaHome', function() {
it('should do ajax-request', function() {
@@ -652,4 +571,38 @@ describe('App.WizardStep2Controller', function () {
});
});
+ describe('#useSshRegistration()', function() {
+
+ var controller = App.WizardStep2Controller.create();
+
+ it('should set manualInstall to false', function() {
+ controller.set('content', {'installOptions': {'hostNames': 'h1',
'manualInstall': true, 'useSsh': false }});
+ controller.useSshRegistration();
+ expect(controller.content.installOptions.manualInstall).to.equal(false);
+ });
+
+ it('should set useSsh to true', function() {
+ controller.set('content', {'installOptions': {'hostNames': 'h1',
'manualInstall': true, 'useSsh': false }});
+ controller.useSshRegistration();
+ expect(controller.content.installOptions.useSsh).to.equal(true);
+ });
+ });
+
+ describe('#useManualInstall()', function() {
+
+ var controller = App.WizardStep2Controller.create();
+
+ it('should set manualInstall to true', function() {
+ controller.set('content', {'installOptions': {'hostNames': 'h1',
'manualInstall': false, 'useSsh': true }});
+ controller.useManualInstall();
+ expect(controller.content.installOptions.manualInstall).to.equal(true);
+ });
+
+ it('should set useSsh to false', function() {
+ controller.set('content', {'installOptions': {'hostNames': 'h1',
'manualInstall': false, 'useSsh': true }});
+ controller.useManualInstall();
+ expect(controller.content.installOptions.useSsh).to.equal(false);
+ });
+ });
+
});
diff --git a/ambari-web/test/views/wizard/step2_view_test.js
b/ambari-web/test/views/wizard/step2_view_test.js
index caadb48..ba96a89 100644
--- a/ambari-web/test/views/wizard/step2_view_test.js
+++ b/ambari-web/test/views/wizard/step2_view_test.js
@@ -21,7 +21,8 @@ require('views/wizard/step2_view');
var view, controller = Em.Object.create({
clusterNameError: '',
- loadStep: Em.K
+ loadStep: Em.K,
+ getManuallyInstalledHosts: Em.K
});
function getView() {
@@ -42,6 +43,7 @@ describe('App.WizardStep2View', function () {
sinon.stub(App, 'tooltip', Em.K);
view.set('controller.hostsError', 'some text');
view.set('controller.sshKeyError', 'some text');
+ view.set('controller.manuallyInstalledHosts', []);
});
afterEach(function () {
App.popover.restore();
@@ -90,19 +92,6 @@ describe('App.WizardStep2View', function () {
});
});
- describe('#click', function() {
- it('should update controller.content.installOptions.useSsh', function ()
{
- v.set('controller.content.installOptions.useSsh', false);
- v.click();
-
expect(v.get('controller.content.installOptions.useSsh')).to.equal(true);
- });
- it('should update controller.content.installOptions.manualInstall',
function () {
- v.set('controller.content.installOptions.manualInstall', true);
- v.click();
-
expect(v.get('controller.content.installOptions.manualInstall')).to.equal(false);
- });
- });
-
});
describe('#manualRegistrationRadioButton', function() {
@@ -130,19 +119,6 @@ describe('App.WizardStep2View', function () {
});
});
- describe('#click', function() {
- it('should update controller.content.installOptions.useSsh', function ()
{
- v.set('controller.content.installOptions.useSsh', true);
- v.click();
-
expect(v.get('controller.content.installOptions.useSsh')).to.equal(false);
- });
- it('should update controller.content.installOptions.manualInstall',
function () {
- v.set('controller.content.installOptions.manualInstall', false);
- v.click();
-
expect(v.get('controller.content.installOptions.manualInstall')).to.equal(true);
- });
- });
-
});
describe('#textFieldView', function() {
--
To stop receiving notification emails like this one, please contact
[email protected].