/**
* 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');
App.AddHostController = App.WizardController.extend({
name: 'addHostController',
totalSteps: 7,
/**
* Used for hiding back button in wizard
*/
hideBackButton: true,
/**
* All wizards data will be stored in this variable
*
* cluster - cluster name
* hosts - hosts, ssh key, repo info, etc.
* services - services list
* hostsInfo - list of selected hosts
* slaveComponentHosts, hostSlaveComponents - info about slave hosts
* masterComponentHosts - info about master hosts
* serviceConfigGroups - info about selected config group for service
* configGroups - all config groups
* config??? - to be described later
*/
content: Em.Object.create({
cluster: null,
hosts: null,
installOptions: null,
services: null,
slaveComponentHosts: null,
masterComponentHosts: null,
serviceConfigProperties: null,
advancedServiceConfig: null,
controllerName: 'addHostController',
serviceConfigGroups: null,
configGroups: null
}),
/**
* save info about wizard progress, particularly current step of wizard
* @param currentStep
* @param completed
*/
setCurrentStep: function (currentStep, completed) {
this._super(currentStep, completed);
App.clusterStatus.setClusterStatus({
wizardControllerName: this.get('name'),
localdb: App.db.data
});
},
/**
* return new object extended from clusterStatusTemplate
* @return Object
*/
getCluster: function () {
return jQuery.extend({}, this.get('clusterStatusTemplate'), {name: App.router.getClusterName()});
},
/**
* return new object extended from installOptionsTemplate
* @return Object
*/
getInstallOptions: function () {
return jQuery.extend({}, this.get('installOptionsTemplate'));
},
/**
* Remove host from model. Used at Confirm hosts
step
* @param hosts Array of hosts, which we want to delete
*/
removeHosts: function (hosts) {
var dbHosts = this.getDBProperty('hosts');
hosts.forEach(function (_hostInfo) {
var host = _hostInfo.hostName;
delete dbHosts[host];
});
this.setDBProperty('hosts', dbHosts);
},
/**
* Load services data. Will be used at Select services(step4)
step
*/
loadServices: function () {
var services = this.getDBProperty('services');
if (!services) {
services = {
selectedServices: [],
installedServices: []
};
App.StackService.find().forEach(function(item){
var isInstalled = App.Service.find().someProperty('id', item.get('serviceName'));
item.set('isSelected', isInstalled);
item.set('isInstalled', isInstalled);
if (isInstalled) {
services.selectedServices.push(item.get('serviceName'));
services.installedServices.push(item.get('serviceName'));
}
},this);
this.setDBProperty('services',services);
} else {
App.StackService.find().forEach(function(item) {
var isSelected = services.selectedServices.contains(item.get('serviceName'));
var isInstalled = services.installedServices.contains(item.get('serviceName'));
item.set('isSelected', isSelected);
item.set('isInstalled', isInstalled);
},this);
}
this.set('content.services', App.StackService.find());
},
/**
* Load slave component hosts data for using in required step controllers
* TODO move to mixin
*/
loadSlaveComponentHosts: function () {
var slaveComponentHosts = this.getDBProperty('slaveComponentHosts') || [];
if (slaveComponentHosts.length) {
var hosts = this.getDBProperty('hosts'),
host_names = Em.keys(hosts);
slaveComponentHosts.forEach(function (component) {
component.hosts.forEach(function (host) {
//Em.set(host, 'hostName', hosts[host.host_id].name);
for (var i = 0; i < host_names.length; i++) {
if (hosts[host_names[i]].id === host.host_id) {
host.hostName = host_names[i];
break;
}
}
});
});
}
this.set("content.slaveComponentHosts", slaveComponentHosts);
console.log("AddHostController.loadSlaveComponentHosts: loaded hosts ", slaveComponentHosts);
},
/**
* Generate clients list for selected services and save it to model
*/
saveClients: function () {
var clients = [];
var serviceComponents = App.StackServiceComponent.find();
var clientComponents = [];
var hosts = this.get('content.hosts');
for (var hostName in hosts) {
if(hosts[hostName].isInstalled) {
hosts[hostName].hostComponents.forEach(function (component) {
clientComponents[component.HostRoles.component_name] = true;
}, this);
}
}
this.get('content.services').filterProperty('isSelected').forEach(function (_service) {
var client = serviceComponents.filterProperty('serviceName', _service.get('serviceName')).findProperty('isClient');
if (client) {
clients.push({
component_name: client.get('componentName'),
display_name: client.get('displayName'),
isInstalled: !!clientComponents[client.get('componentName')]
});
}
}, this);
this.setDBProperty('clientInfo', clients);
this.set('content.clients', clients);
console.log("AddHostController.saveClients: saved list ", clients);
},
/**
* Apply config groups from step4 Configurations
*/
applyConfigGroup: function () {
var serviceConfigGroups = this.get('content.configGroups');
serviceConfigGroups.forEach(function (group) {
if (group.configGroups.someProperty('ConfigGroup.group_name', group.selectedConfigGroup)) {
var configGroup = group.configGroups.findProperty('ConfigGroup.group_name', group.selectedConfigGroup);
group.hosts.forEach(function (host) {
configGroup.ConfigGroup.hosts.push({
host_name: host
});
}, this);
delete configGroup.href;
App.ajax.send({
name: 'config_groups.update_config_group',
sender: this,
data: {
id: configGroup.ConfigGroup.id,
configGroup: configGroup
}
});
}
}, this);
},
/**
* Load information about selected config groups
*/
getServiceConfigGroups: function () {
var serviceConfigGroups = this.getDBProperty('serviceConfigGroups');
this.set('content.configGroups', serviceConfigGroups);
},
/**
* Save information about selected config groups
*/
saveServiceConfigGroups: function () {
this.setDBProperty('serviceConfigGroups', this.get('content.configGroups'));
},
/**
* Set content.configGroups for step4
*/
loadServiceConfigGroups: function () {
var selectedServices = [];
this.loadServiceConfigGroupsBySlaves(selectedServices);
this.loadServiceConfigGroupsByClients(selectedServices);
this.sortServiceConfigGroups(selectedServices);
this.set('content.configGroups', selectedServices);
},
/**
* sort config groups by name
* @param selectedServices
*/
sortServiceConfigGroups: function (selectedServices) {
selectedServices.forEach(function (selectedService) {
selectedService.configGroups.sort(function (cfgA, cfgB) {
if (cfgA.ConfigGroup.group_name < cfgB.ConfigGroup.group_name) return -1;
if (cfgA.ConfigGroup.group_name > cfgB.ConfigGroup.group_name) return 1;
return 0;
});
});
},
/**
* load service config groups by slave components,
* push them into selectedServices
* @param selectedServices
*/
loadServiceConfigGroupsBySlaves: function (selectedServices) {
var slaveComponentHosts = this.get('content.slaveComponentHosts');
if (slaveComponentHosts && slaveComponentHosts.length > 0) {
slaveComponentHosts.forEach(function (slave) {
if (slave.hosts.length > 0) {
if (slave.componentName !== "CLIENT") {
var service = App.StackServiceComponent.find(slave.componentName).get('stackService');
var configGroups = this.get('content.configGroups').filterProperty('ConfigGroup.tag', service);
var configGroupsNames = configGroups.mapProperty('ConfigGroup.group_name');
var defaultGroupName = service.get('displayName') + ' Default';
configGroupsNames.unshift(defaultGroupName);
selectedServices.push({
serviceId: service.get('serviceName'),
displayName: service.get('displayName'),
hosts: slave.hosts.mapProperty('hostName'),
configGroupsNames: configGroupsNames,
configGroups: configGroups,
selectedConfigGroup: defaultGroupName
});
}
}
}, this);
return true;
}
return false;
},
/**
* load service config groups by clients,
* push them into selectedServices
* @param selectedServices
*/
loadServiceConfigGroupsByClients: function (selectedServices) {
var slaveComponentHosts = this.get('content.slaveComponentHosts');
var clients = this.get('content.clients');
var client = slaveComponentHosts && slaveComponentHosts.findProperty('componentName', 'CLIENT');
var selectedClientHosts = client && client.hosts.mapProperty('hostName');
if (clients && selectedClientHosts && clients.length > 0 && selectedClientHosts.length > 0) {
this.loadClients();
clients.forEach(function (client) {
var service = App.StackServiceComponent.find(client.component_name).get('stackService');
var serviceName = service.get('serviceName');
var serviceMatch = selectedServices.findProperty('serviceId', serviceName);
if (serviceMatch) {
serviceMatch.hosts = serviceMatch.hosts.concat(selectedClientHosts).uniq();
} else {
var configGroups = this.get('content.configGroups').filterProperty('ConfigGroup.tag', serviceName);
var configGroupsNames = configGroups.mapProperty('ConfigGroup.group_name').sort();
var defaultGroupName = service.get('displayName') + ' Default';
configGroupsNames.unshift(defaultGroupName);
selectedServices.push({
serviceId: serviceName,
displayName: service.get('displayName'),
hosts: selectedClientHosts,
configGroupsNames: configGroupsNames,
configGroups: configGroups,
selectedConfigGroup: defaultGroupName
});
}
}, this);
return true;
}
return false;
},
loadServiceConfigProperties: function () {
var serviceConfigProperties = App.db.get('AddService', 'serviceConfigProperties');
if (!serviceConfigProperties || !serviceConfigProperties.length) {
serviceConfigProperties = App.db.get('Installer', 'serviceConfigProperties');
}
this.set('content.serviceConfigProperties', serviceConfigProperties);
console.log("AddHostController.loadServiceConfigProperties: loaded config ", serviceConfigProperties);
},
/**
* Load data for all steps until current step
*/
loadAllPriorSteps: function () {
var step = this.get('currentStep');
switch (step) {
case '7':
case '6':
case '5':
this.loadServiceConfigProperties();
this.getServiceConfigGroups();
case '4':
case '3':
this.loadClients();
this.loadServices();
this.loadMasterComponentHosts();
this.loadSlaveComponentHosts();
this.load('hosts');
case '2':
this.loadServices();
case '1':
this.load('hosts');
this.load('installOptions');
this.load('cluster');
}
},
/**
* Remove all loaded data.
* Created as copy for App.router.clearAllSteps
*/
clearAllSteps: function () {
this.clearInstallOptions();
// clear temporary information stored during the install
this.set('content.cluster', this.getCluster());
},
clearStorageData: function () {
this._super();
App.db.cleanAddHost();
},
/**
* save the local db data stored on the server as value to the key api/v1/persist/CLUSTER_CURRENT_STATUS
*/
saveClusterState: function () {
App.clusterStatus.setClusterStatus({
clusterName: App.router.getClusterName(),
clusterState: 'DEFAULT'
});
},
clearData: function () {
// Clear Add Host namespace in Browser Local storage and save it to server persist data
this.clearStorageData();
this.saveClusterState();
},
/**
* Clear all temporary data
*/
finish: function () {
this.setCurrentStep('1');
this.clearAllSteps();
this.clearData();
App.router.get('updateController').updateAll();
App.updater.immediateRun('updateHost');
},
/**
* send request to server in order to install services
* @param isRetry
*/
installServices: function (isRetry, callback) {
callback = callback || Em.K;
this.set('content.cluster.oldRequestsId', []);
var clusterName = this.get('content.cluster.name');
var hostNames = [];
for (var hostname in this.getDBProperty('hosts')) {
if(this.getDBProperty('hosts')[hostname].isInstalled == false){
hostNames.push(hostname);
}
}
if(!clusterName || hostNames.length === 0) return false;
App.ajax.send({
name: "common.host_components.update",
sender: this,
data: {
"context": Em.I18n.t('requestInfo.installComponents'),
"query": "HostRoles/host_name.in(" + hostNames.join(',') + ")",
"HostRoles": {"state": "INSTALLED"}
},
success: 'installServicesSuccessCallback',
error: 'installServicesErrorCallback'
}).then(callback, callback);
return true;
}
});