blob: 0db9314264ba3fa0be217283aa59a96c50ebfff8 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var App = require('app');
var blueprintUtils = require('utils/blueprint');
var validationUtils = require('utils/validator');
/**
* By Step 6, we have the following information stored in App.db and set on this
* controller by the router:
*
* hosts: App.db.hosts (list of all hosts the user selected in Step 3)
* selectedServiceNames: App.db.selectedServiceNames (the services that the user selected in Step 4)
* masterComponentHosts: App.db.masterComponentHosts (master-components-to-hosts mapping the user selected in Step 5)
*
* Step 6 will set the following information in App.db:
* slaveComponentHosts: App.db.slaveComponentHosts (slave-components-to-hosts mapping the user selected in Step 6)
*
*/
App.WizardStep6Controller = Em.Controller.extend(App.BlueprintMixin, {
name: 'wizardStep6Controller',
/**
* List of hosts
* @type {object[]}
*/
hosts: [],
/**
* List of components info about selecting/deselecting status for components.
*
* @type {Array}
* @item {Em.Object}
* @property name {String} - component name
* @property label {String} - component display name
* @property allChecked {bool} - all checkboxes are checked
* @property noChecked {bool} - no checkboxes checked
*/
headers: [],
/**
* @type {bool}
*/
isLoaded: false,
/**
* Indication if user has chosen hosts to install clients
* @type {bool}
*/
isClientsSet: false,
/**
* Define state for submit button
* @type {bool}
*/
submitDisabled: Em.computed.or('validationInProgress', 'App.router.btnClickInProgress'),
/**
* timer for validation request
*/
timer: null,
/**
* true if request for validation is in progress
*
* @type {bool}
*/
validationInProgress: false,
/**
* Check if <code>addHostWizard</code> used
* @type {bool}
*/
isAddHostWizard: Em.computed.equal('content.controllerName', 'addHostController'),
/**
* Check if <code>installerWizard</code> used
* @type {bool}
*/
isInstallerWizard: Em.computed.equal('content.controllerName', 'installerController'),
isAllCheckboxesEmpty: function() {
var hosts = this.get('hosts');
for (var i = 0; i < hosts.length; i++) {
var checkboxes = hosts[i].checkboxes;
for (var j = 0; j < checkboxes.length; j++) {
if (checkboxes[j].checked) {
return false;
}
}
}
return true;
},
/**
* Check if <code>addServiceWizard</code> used
* @type {bool}
*/
isAddServiceWizard: Em.computed.equal('content.controllerName', 'addServiceController'),
installedServiceNames: function () {
return this.get('content.services').filterProperty('isInstalled').mapProperty('serviceName');
}.property('content.services').cacheable(),
/**
* Validation error messages which don't related with any master
*/
generalErrorMessages: [],
/**
* Validation warning messages which don't related with any master
*/
generalWarningMessages: [],
/**
* true if validation has any general (which is not related with concrete host) error message
*/
anyGeneralErrors: Em.computed.or('errorMessage','generalErrorMessages.length'),
/**
* true if validation has any general (which is not related with concrete host) warning message
*/
anyGeneralWarnings: Em.computed.gt('generalWarningMessages.length', 0),
/**
* true if validation has any general (which is not related with concrete host) error or warning message
*/
anyGeneralIssues: Em.computed.or('anyGeneralErrors', 'anyGeneralWarnings'),
anyHostErrors: function () {
return this.get('hosts').some(function(h) { return h.errorMessages ? h.errorMessages.length > 0 : false;});
}.property('hosts.@each.errorMessages'),
/**
* true if validation has any error message (general or host specific)
*/
anyErrors: Em.computed.or('anyGeneralErrors', 'anyHostErrors'),
anyHostWarnings: function () {
return this.get('hosts').some(function(h) { return h.warnMessages ? h.warnMessages.length > 0 : false;});
}.property('hosts.@each.warnMessages'),
/**
* true if validation has any warning message (general or host specific)
*/
anyWarnings: Em.computed.or('anyGeneralWarnings', 'anyHostWarnings'),
openSlavesAndClientsIssues: function () {
App.ModalPopup.show({
header: Em.I18n.t('installer.step6.validationSlavesAndClients.popup.header'),
bodyClass: Em.View.extend({
controller: this,
templateName: require('templates/wizard/step6/step6_issues_popup')
}),
secondary: null
});
},
/**
* Verify condition that at least one checkbox of each component was checked
* @method clearError
*/
clearError: function () {
var self = this;
var isError = false;
var err = false;
var hosts = this.get('hosts');
var headers = this.get('headers');
var headersMap = headers.toWickMapByProperty('name');
hosts.forEach(function (host) {
host.checkboxes.forEach(function (checkbox) {
if (headersMap[checkbox.component]) {
headersMap[checkbox.component] = !checkbox.checked;
}
});
});
for (var i in headersMap) {
err |= headersMap[i];
}
if (!err) {
this.set('errorMessage', '');
}
if (this.get('isAddHostWizard')) {
hosts.forEach(function (host) {
isError = false;
headers.forEach(function (header) {
isError |= host.checkboxes.findProperty('title', header.get('label')).checked;
});
isError = !isError;
if (!isError) {
self.set('errorMessage', '');
}
});
}
},
/**
* Clear Step6 data like <code>hosts</code>, <code>headers</code> etc
* @method clearStep
*/
clearStep: function () {
this.set('hosts', []);
this.set('headers', []);
this.clearError();
this.set('isLoaded', false);
this.set('validationInProgress', false);
},
/**
* Enable some service for all hosts
* @param {object} event
* @method selectAllNodes
*/
selectAllNodes: function (event) {
var name = Em.get(event, 'context.name');
if (name) {
this.setAllNodes(name, true);
this.callValidation();
}
},
/**
* Disable some services for all hosts
* @param {object} event
* @method deselectAllNodes
*/
deselectAllNodes: function (event) {
var name = Em.get(event, 'context.name');
if (name) {
this.setAllNodes(name, false);
this.callValidation();
}
},
/**
* Enable/disable some service for all hosts
* @param {String} component - component name
* @param {bool} checked - true - enable, false - disable
* @method setAllNodes
*/
setAllNodes: function (component, checked) {
this.get('hosts').forEach(function (host) {
host.checkboxes.filterProperty('isInstalled', false).forEach(function (checkbox) {
if (checkbox.component === component) {
Em.set(checkbox, 'checked', checked);
}
});
});
this.checkCallback(component);
},
/**
* Checkbox check callback
* Verify if all/none checkboxes for current component are checked
* @param {String} component
* @method checkCallback
*/
checkCallback: function (component) {
var header = this.get('headers').findProperty('name', component);
if (header) {
var hosts = this.get('hosts');
var allTrue = true;
var allFalse = true;
hosts.forEach(function (host) {
host.checkboxes.forEach(function (checkbox) {
if (checkbox.component === component && !checkbox.isInstalled) {
allTrue = allTrue && checkbox.checked;
allFalse = allFalse && !checkbox.checked;
}
});
});
header.set('allChecked', allTrue);
header.set('noChecked', allFalse);
}
this.clearError();
},
/**
* Init step6 data
* @method loadStep
*/
loadStep: function () {
this.clearStep();
var parentController = App.router.get(this.get('content.controllerName'));
if (parentController && parentController.get('content.componentsFromConfigs')) {
parentController.clearConfigActionComponents();
}
var selectedServices = App.StackService.find().filterProperty('isSelected');
var installedServices = App.StackService.find().filterProperty('isInstalled');
var services;
if (this.get('isInstallerWizard')) services = selectedServices;
else if (this.get('isAddHostWizard')) services = installedServices;
else if (this.get('isAddServiceWizard')) services = installedServices.concat(selectedServices);
var headers = Em.A([]);
services.forEach(function (stackService) {
stackService.get('serviceComponents').forEach(function (serviceComponent) {
if (serviceComponent.get('isShownOnInstallerSlaveClientPage')) {
headers.pushObject(Em.Object.create({
name: serviceComponent.get('componentName'),
label: App.format.role(serviceComponent.get('componentName'), false),
allChecked: false,
isRequired: serviceComponent.get('isRequired'),
noChecked: true,
isDisabled: installedServices.someProperty('serviceName', stackService.get('serviceName')) && this.get('isAddServiceWizard'),
allId: 'all-' + serviceComponent.get('componentName'),
noneId: 'none-' + serviceComponent.get('componentName')
}));
}
}, this);
}, this);
if (this.get('content.clients') && !!this.get('content.clients').length) {
headers.pushObject(Em.Object.create({
name: 'CLIENT',
label: App.format.role('CLIENT', false),
allChecked: false,
noChecked: true,
isDisabled: false,
allId: 'all-CLIENT',
noneId: 'none-CLIENT'
}));
}
this.get('headers').pushObjects(headers);
this.render();
if (this.get('content.skipSlavesStep')) {
App.router.send('next');
} else {
this.callValidation();
}
},
/**
* Get active host names
* @return {string[]}
* @method getHostNames
*/
getHostNames: function () {
var hostInfo = this.get('content.hosts');
var hostNames = [];
//flag identify whether get all hosts or only uninstalled(newly added) hosts
var getUninstalledHosts = this.get('content.controllerName') !== 'addServiceController';
for (var index in hostInfo) {
if (hostInfo.hasOwnProperty(index)) {
if (hostInfo[index].bootStatus === 'REGISTERED') {
if (!getUninstalledHosts || !hostInfo[index].isInstalled) {
hostNames.push(hostInfo[index].name);
}
}
}
}
return hostNames;
},
/**
* Load all data needed for this module. Then it automatically renders in template
* @method render
*/
render: function () {
var hostsObj = [],
masterHosts = [],
headers = this.get('headers'),
masterHostNames = this.get('content.masterComponentHosts').mapProperty('hostName').uniq(),
masterHostNamesMap = masterHostNames.toWickMap();
this.getHostNames().forEach(function (_hostName) {
var hasMaster = masterHostNamesMap[_hostName];
var obj = {
hostName: _hostName,
hasMaster: hasMaster,
checkboxes: headers.map(function (header) {
return{
component: header.name,
title: header.label,
checked: false,
isInstalled: false,
isDisabled: header.get('isDisabled')
};
})
};
if (hasMaster) {
masterHosts.pushObject(obj)
} else {
hostsObj.pushObject(obj);
}
});
//hosts with master components should be in the beginning of list
hostsObj.unshift.apply(hostsObj, masterHosts);
hostsObj = this.renderSlaves(hostsObj);
this.set('hosts', hostsObj);
headers.forEach(function (header) {
this.checkCallback(header.get('name'));
}, this);
this.set('isLoaded', true);
},
/**
* Set checked values for slaves checkboxes
* @param {Array} hostsObj
* @return {Array}
* @method renderSlaves
*/
renderSlaves: function (hostsObj) {
var slaveComponents = this.get('content.slaveComponentHosts');
if (Em.isNone(slaveComponents)) { // we are at this page for the first time
this.selectRecommendedComponents(hostsObj);
this.setInstalledComponents(hostsObj);
} else {
this.restoreComponentsSelection(hostsObj, slaveComponents);
}
if (this.get('isAddServiceWizard')) {
this.enableCheckboxesForDependentComponents(hostsObj);
}
this.selectClientHost(hostsObj);
return hostsObj;
},
/**
* set installed flag of host-components
* @param {Array} hostsObj
* @returns {boolean}
*/
setInstalledComponents: function(hostsObj) {
if (Em.isNone(this.get('content.installedHosts'))) return false;
var hosts = this.get('content.installedHosts');
hostsObj.forEach(function(host) {
var installedHost = hosts[host.hostName];
var installedComponents = installedHost ? installedHost.hostComponents.mapProperty('HostRoles.component_name') : [];
host.checkboxes.forEach(function(checkbox) {
checkbox.isInstalled = installedComponents.contains(checkbox.component);
if (checkbox.isInstalled) {
checkbox.checked = true;
}
});
});
},
/**
* Enable checkboxes for dependent components of already installed services, that can be added
* @param hostsObj
*/
enableCheckboxesForDependentComponents: function (hostsObj) {
var dependentSlaves = {};
App.StackService.find().filterProperty('isSelected').forEach(function (service) {
service.get('serviceComponents').forEach(function (component) {
component.get('dependencies').forEach(function (dependency) {
var dependentService = App.StackService.find().findProperty('serviceName', dependency.serviceName);
var dependentComponent = dependentService.get('serviceComponents').findProperty('componentName', dependency.componentName);
if (dependentComponent.get('isSlave') && dependentService.get('isInstalled')) {
dependentSlaves[dependentComponent.get('componentName')] = [];
}
});
});
});
if (!Em.keys(dependentSlaves)) return false;
hostsObj.forEach(function (hostObj) {
hostObj.checkboxes.forEach(function (checkbox) {
if (dependentSlaves[checkbox.component] && !checkbox.isInstalled) {
dependentSlaves[checkbox.component].push(checkbox);
}
});
});
for (var component in dependentSlaves) {
if (dependentSlaves.hasOwnProperty(component)) {
var maxToInstall = App.StackServiceComponent.find().findProperty('componentName', component).get('maxToInstall');
maxToInstall = maxToInstall === Infinity ? hostsObj.length : maxToInstall;
if (maxToInstall > hostsObj.length - dependentSlaves[component].length) {
dependentSlaves[component].setEach('isDisabled', false);
}
}
}
return true;
},
/**
* restore previous component selection
* @param {Array} hostsObj
* @param {Array} slaveComponents
*/
restoreComponentsSelection: function(hostsObj, slaveComponents) {
var slaveComponentsMap = slaveComponents.toMapByProperty('componentName');
var hostsObjMap = hostsObj.toMapByProperty('hostName');
this.get('headers').forEach(function (header) {
var slaveComponent = slaveComponentsMap[header.get('name')];
if (slaveComponent) {
slaveComponent.hosts.forEach(function (_node) {
var node = hostsObjMap[_node.hostName];
if (node) {
Em.set(node.checkboxes.findProperty('title', header.get('label')), 'checked', true);
Em.set(node.checkboxes.findProperty('title', header.get('label')), 'isInstalled', _node.isInstalled);
}
});
}
});
},
/**
* select component which should be checked according to recommendations
* @param hostsObj
*/
selectRecommendedComponents: function(hostsObj) {
var recommendations = this.get('content.recommendations'),
recommendedMap = {},
clientComponentsMap = App.get('components.clients').toWickMap();
recommendations.blueprint.host_groups.forEach(function(hostGroup) {
var group = recommendations.blueprint_cluster_binding.host_groups.findProperty('name', hostGroup.name);
var hosts = group.hosts || [];
hosts.forEach(function (host) {
recommendedMap[host.fqdn] = hostGroup.components.mapProperty('name');
});
});
hostsObj.forEach(function (host) {
var checkboxes = host.checkboxes;
var hostComponents = recommendedMap[host.hostName] || [];
checkboxes.forEach(function (checkbox) {
var checked;
if (!checkbox.isDisabled) {
checked = hostComponents.contains(checkbox.component);
if (checkbox.component === 'CLIENT' && !checked) {
checked = hostComponents.some(function (componentName) {
return clientComponentsMap[componentName];
});
}
checkbox.checked = checked;
}
});
});
},
/**
* For clients - select first non-master host, if all has masters then last host
* @param hostsObj
*/
selectClientHost: function (hostsObj) {
if (!this.get('isClientsSet')) {
var nonMasterHost = hostsObj.findProperty('hasMaster', false);
var clientHost = !!nonMasterHost ? nonMasterHost : hostsObj[hostsObj.length - 1]; // last host
var clientCheckBox = clientHost.checkboxes.findProperty('component', 'CLIENT');
if (clientCheckBox) {
Em.set(clientCheckBox, 'checked', true);
}
this.set('isClientsSet', true);
}
},
/**
* Select checkboxes which correspond to master components
*
* @param {Array} hostsObj
* @return {Array}
* @method selectMasterComponents
*/
selectMasterComponents: function (hostsObj) {
var masterComponentHosts = this.get('content.masterComponentHosts');
if (masterComponentHosts) {
masterComponentHosts.forEach(function (item) {
var host = hostsObj.findProperty('hostName', item.hostName);
if (host) {
var checkbox = host.get('checkboxes').findProperty('component', item.component);
if (checkbox) {
checkbox.set('checked', true);
}
}
});
}
return hostsObj;
},
/**
* Return list of master components for specified <code>hostname</code>
* @param {string} hostName
* @return {string[]}
* @method getMasterComponentsForHost
*/
getMasterComponentsForHost: function (hostName) {
return this.get('content.masterComponentHosts').filterProperty('hostName', hostName).mapProperty('component');
},
callValidation: function (successCallback) {
var self = this;
clearTimeout(this.get('timer'));
if (this.get('validationInProgress')) {
this.set('timer', setTimeout(function () {
self.callValidation(successCallback);
}, 700));
} else {
this.callServerSideValidation(successCallback);
}
},
/**
* Update submit button status
* @method callServerSideValidation
*/
callServerSideValidation: function (successCallback) {
var self = this;
this.set('validationInProgress', true);
var selectedServices = App.StackService.find().filterProperty('isSelected').mapProperty('serviceName');
var installedServices = App.StackService.find().filterProperty('isInstalled').mapProperty('serviceName');
var services = installedServices.concat(selectedServices).uniq();
var hostNames = self.get('hosts').mapProperty('hostName');
var slaveBlueprint = self.getCurrentBlueprint();
var masterBlueprint = null;
//Existing Installed but invisible masters on `Assign Masters page` should be included in host component layout for recommnedation/validation call
var invisibleInstalledMasters = [];
if (this.get('isAddServiceWizard')) {
var invisibleMasters = App.StackServiceComponent.find().filterProperty("isMaster").filterProperty("isShownOnAddServiceAssignMasterPage", false);
invisibleInstalledMasters = invisibleMasters.filter(function(item){
var masterComponent = App.MasterComponent.find().findProperty('componentName', item.get('componentName'));
return masterComponent && !!masterComponent.get('totalCount');
}).mapProperty("componentName");
}
var invisibleSlavesAndClients = App.StackServiceComponent.find().filter(function (component) {
return component.get("isSlave") && component.get("isShownOnInstallerSlaveClientPage") === false ||
component.get("isClient") && component.get("isRequiredOnAllHosts");
}).mapProperty("componentName");
if (this.get('isInstallerWizard') || this.get('isAddServiceWizard')) {
masterBlueprint = self.getCurrentMastersBlueprint();
var selectedClientComponents = self.get('content.clients').mapProperty('component_name');
var alreadyInstalledClients = App.get('components.clients').reject(function (c) {
return selectedClientComponents.contains(c);
});
var invisibleComponents = invisibleInstalledMasters.concat(invisibleSlavesAndClients).concat(alreadyInstalledClients);
var invisibleBlueprint = blueprintUtils.filterByComponents(this.get('content.recommendations'), invisibleComponents);
masterBlueprint = blueprintUtils.mergeBlueprints(masterBlueprint, invisibleBlueprint);
} else if (this.get('isAddHostWizard')) {
masterBlueprint = self.getCurrentMasterSlaveBlueprint();
hostNames = hostNames.concat(App.Host.find().mapProperty("hostName")).uniq();
slaveBlueprint = blueprintUtils.addComponentsToBlueprint(slaveBlueprint, invisibleSlavesAndClients);
}
var bluePrintsForValidation = blueprintUtils.mergeBlueprints(masterBlueprint, slaveBlueprint);
this.set('content.recommendationsHostGroups', bluePrintsForValidation);
return App.ajax.send({
name: 'config.validations',
sender: self,
data: {
stackVersionUrl: App.get('stackVersionURL'),
hosts: hostNames,
services: services,
validate: 'host_groups',
recommendations: bluePrintsForValidation
},
success: 'updateValidationsSuccessCallback',
error: 'updateValidationsErrorCallback'
}).
then(function () {
self.set('validationInProgress', false);
if (App.get('router.btnClickInProgress') && successCallback) {
successCallback();
}
}
);
},
/**
* Success-callback for validations request
* @param {object} data
* @method updateValidationsSuccessCallback
*/
updateValidationsSuccessCallback: function (data) {
var self = this;
var clientComponents = App.get('components.clients');
this.set('generalErrorMessages', []);
this.set('generalWarningMessages', []);
this.get('hosts').setEach('warnMessages', []);
this.get('hosts').setEach('errorMessages', []);
this.get('hosts').setEach('anyMessage', false);
this.get('hosts').forEach(function (host) {
host.checkboxes.setEach('hasWarnMessage', false);
host.checkboxes.setEach('hasErrorMessage', false);
});
var anyGeneralClientErrors = false; // any error/warning for any client component (under "CLIENT" alias)
var validationData = validationUtils.filterNotInstalledComponents(data);
validationData.filterProperty('type', 'host-component').filter(function (i) {
return !(i['component-name'] && App.StackServiceComponent.find().findProperty('componentName', i['component-name']).get('isMaster'));
}).forEach(function (item) {
var checkboxWithIssue = null;
var isGeneralClientValidationItem = clientComponents.contains(item['component-name']); // it is an error/warning for any client component (under "CLIENT" alias)
var host = self.get('hosts').find(function (h) {
return h.hostName === item.host && h.checkboxes.some(function (checkbox) {
var isClientComponent = checkbox.component === "CLIENT" && isGeneralClientValidationItem;
if (checkbox.component === item['component-name'] || isClientComponent) {
checkboxWithIssue = checkbox;
return true;
}
return false;
});
});
if (host) {
Em.set(host, 'anyMessage', true);
if (item.level === 'ERROR') {
host.errorMessages.pushObject(item.message);
Em.set(checkboxWithIssue, 'hasErrorMessage', true);
}
else
if (item.level === 'WARN') {
host.warnMessages.pushObject(item.message);
Em.set(checkboxWithIssue, 'hasWarnMessage', true);
}
}
else {
var component;
if (isGeneralClientValidationItem) {
if (!anyGeneralClientErrors) {
anyGeneralClientErrors = true;
component = "Client";
}
}
else {
component = item['component-name'];
}
if (component || !item['component-name']) {
var details = "";
if (item.host) {
details += " (" + item.host + ")";
}
if (item.level === 'ERROR') {
self.get('generalErrorMessages').push(item.message + details);
}
else
if (item.level === 'WARN') {
self.get('generalWarningMessages').push(item.message + details);
}
}
}
});
},
/**
* Error-callback for validations request
* @param {object} jqXHR
* @param {object} ajaxOptions
* @param {string} error
* @param {object} opt
* @method updateValidationsErrorCallback
*/
updateValidationsErrorCallback: function (jqXHR, ajaxOptions, error, opt) {
},
/**
* Composes selected values of comboboxes into blueprint format
*/
getCurrentBlueprint: function () {
var self = this;
var res = {
blueprint: { host_groups: [] },
blueprint_cluster_binding: { host_groups: [] }
};
var clientComponents = self.get('content.clients').mapProperty('component_name');
var mapping = self.get('hosts');
mapping.forEach(function (item, i) {
var groupName = 'host-group-' + (i+1);
var hostGroup = {
name: groupName,
components: item.checkboxes.filterProperty('checked', true).map(function (checkbox) {
if (checkbox.component === "CLIENT") {
return clientComponents.map(function (client) {
return { name: client };
});
} else {
return { name: checkbox.component };
}
})
};
hostGroup.components = [].concat.apply([], hostGroup.components);
var binding = {
name: groupName,
hosts: [
{ fqdn: item.hostName }
]
};
res.blueprint.host_groups.push(hostGroup);
res.blueprint_cluster_binding.host_groups.push(binding);
});
return res;
},
/**
* Create blueprint from assigned master components to appropriate hosts
* @returns {Object}
* @method getCurrentMastersBlueprint
*/
getCurrentMastersBlueprint: function () {
var res = {
blueprint: { host_groups: [] },
blueprint_cluster_binding: { host_groups: [] }
};
var masters = this.get('content.masterComponentHosts');
var hosts = this.get('content.hosts');
Em.keys(hosts).forEach(function (host, i) {
var groupName = 'host-group-' + (i + 1);
var components = [];
masters.forEach(function (master) {
if (master.hostName === host) {
components.push({
name: master.component
});
}
});
res.blueprint.host_groups.push({
name: groupName,
components: components
});
res.blueprint_cluster_binding.host_groups.push({
name: groupName,
hosts: [
{
fqdn: host
}
]
});
}, this);
return blueprintUtils.mergeBlueprints(res, this.getCurrentSlaveBlueprint());
},
/**
* In case of any validation issues shows accept dialog box for user which allow cancel and fix issues or continue anyway
* @metohd submit
*/
showValidationIssuesAcceptBox: function(callback) {
var self = this;
if (self.get('anyWarnings') || self.get('anyErrors')) {
App.ModalPopup.show({
primary: Em.I18n.t('common.continueAnyway'),
header: Em.I18n.t('installer.step6.validationIssuesAttention.header'),
body: Em.I18n.t('installer.step6.validationIssuesAttention'),
primaryClass: 'btn-danger',
onPrimary: function () {
this.hide();
callback();
},
onSecondary: function () {
App.set('router.nextBtnClickInProgress', false);
this._super();
}
});
} else {
callback();
}
}
});