blob: 61cd0ca9fa751c9c51d77f625e6e5f2ab46d067b [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.
*/
// Application bootstrapper
require('utils/ember_reopen');
require('utils/ember_computed');
require('utils/bootstrap_reopen');
var stringUtils = require('utils/string_utils');
module.exports = Em.Application.create({
name: 'Ambari Web',
rootElement: '#wrapper',
store: DS.Store.create({
revision: 4,
adapter: DS.FixtureAdapter.create({
simulateRemoteResponse: false
}),
typeMaps: {},
recordCache: []
}),
isAdmin: false,
isOperator: false,
isClusterUser: false,
isPermissionDataLoaded: false,
auth: undefined,
isOnlyViewUser: function() {
return App.auth && (App.auth.length == 0 || (App.isAuthorized('VIEW.USE') && App.auth.length == 1));
}.property('auth'),
/**
* @type {boolean}
* @default false
*/
isKerberosEnabled: false,
/**
* state of stack upgrade process
* states:
* - NOT_REQUIRED
* - PENDING
* - IN_PROGRESS
* - HOLDING
* - COMPLETED
* - ABORTED
* - HOLDING_FAILED
* - HOLDING_TIMEDOUT
* @type {String}
*/
upgradeState: 'NOT_REQUIRED',
/**
* Check if upgrade is in INIT state
* 'INIT' is set on upgrade start and when it's finished
* @type {boolean}
*/
upgradeInit: Em.computed.equal('upgradeState', 'NOT_REQUIRED'),
/**
* flag is true when upgrade process is running
* @returns {boolean}
*/
upgradeInProgress: Em.computed.equal('upgradeState', 'IN_PROGRESS'),
/**
* Checks if update process is completed
* @type {boolean}
*/
upgradeCompleted: Em.computed.equal('upgradeState', 'COMPLETED'),
/**
* flag is true when upgrade process is waiting for user action
* to proceed, retry, perform manual steps etc.
* @returns {boolean}
*/
upgradeHolding: function() {
return this.get('upgradeState').contains("HOLDING") || this.get('upgradeAborted');
}.property('upgradeState', 'upgradeAborted'),
/**
* flag is true when upgrade process is aborted
* SHOULD behave similar to HOLDING_FAILED state
* @returns {boolean}
*/
upgradeAborted: function () {
return this.get('upgradeState') === "ABORTED" && !App.router.get('mainAdminStackAndUpgradeController.isSuspended');
}.property('upgradeState', 'router.mainAdminStackAndUpgradeController.isSuspended'),
/**
* flag is true when upgrade process is suspended
* @returns {boolean}
*/
upgradeSuspended: function () {
return this.get('upgradeState') === "ABORTED" && App.router.get('mainAdminStackAndUpgradeController.isSuspended');
}.property('upgradeState', 'router.mainAdminStackAndUpgradeController.isSuspended'),
/**
* RU is running
* @type {boolean}
*/
upgradeIsRunning: Em.computed.or('upgradeInProgress', 'upgradeHolding'),
/**
* flag is true when upgrade process is running or suspended
* or wizard used by another user
* @returns {boolean}
*/
wizardIsNotFinished: function () {
return this.get('upgradeIsRunning') ||
this.get('upgradeSuspended') ||
App.router.get('wizardWatcherController.isNonWizardUser');
}.property('upgradeIsRunning', 'upgradeAborted', 'router.wizardWatcherController.isNonWizardUser', 'upgradeSuspended'),
/**
* Options:
* - ignoreWizard: ignore when some wizard is running by another user (default `false`)
*
* @param {string} authRoles
* @param {object} options
* @returns {boolean}
*/
isAuthorized: function (authRoles, options) {
options = $.extend({ignoreWizard: false}, options);
var result = false;
authRoles = $.map(authRoles.split(","), $.trim);
// When Upgrade running(not suspended) only operations related to upgrade should be allowed
if ((!this.get('upgradeSuspended') && !authRoles.contains('CLUSTER.UPGRADE_DOWNGRADE_STACK')) &&
!App.get('supports.opsDuringRollingUpgrade') &&
!['NOT_REQUIRED', 'COMPLETED'].contains(this.get('upgradeState')) ||
!App.auth){
return false;
}
if (!options.ignoreWizard && App.router.get('wizardWatcherController.isNonWizardUser')) {
return false;
}
authRoles.forEach(function (auth) {
result = result || App.auth.contains(auth);
});
return result;
},
isStackServicesLoaded: false,
/**
* return url prefix with number value of version of HDP stack
*/
stackVersionURL: function () {
return '/stacks/{0}/versions/{1}'.format(this.get('currentStackName') || 'HDP', this.get('currentStackVersionNumber'));
}.property('currentStackName','currentStackVersionNumber'),
falconServerURL: function () {
var falconService = this.Service.find().findProperty('serviceName', 'FALCON');
if (falconService) {
return falconService.get('hostComponents').findProperty('componentName', 'FALCON_SERVER').get('hostName');
}
return '';
}.property().volatile(),
/* Determine if Application Timeline Service supports Kerberization.
* Because this value is retrieved from the cardinality of the component, it is safe to keep in app.js
* since its value will not change during the lifetime of the application.
*/
doesATSSupportKerberos: function() {
var YARNService = App.StackServiceComponent.find().filterProperty('serviceName', 'YARN');
if (YARNService.length) {
var ATS = App.StackServiceComponent.find().findProperty('componentName', 'APP_TIMELINE_SERVER');
return (!!ATS && !!ATS.get('minToInstall'));
}
return false;
}.property('router.clusterController.isLoaded'),
clusterName: null,
clockDistance: null, // server clock - client clock
currentStackVersion: '',
fullStackVersion: '',
currentStackName: function() {
return Em.get((this.get('currentStackVersion') || this.get('defaultStackVersion')).match(/(.+)-\d.+/), '1');
}.property('currentStackVersion', 'defaultStackVersion'),
/**
* true if cluster has only 1 host
* for now is used to disable move/HA actions
* @type {boolean}
*/
isSingleNode: Em.computed.equal('allHostNames.length', 1),
allHostNames: [],
/**
* This object is populated to keep track of uninstalled components to be included in the layout for recommendation/validation call
* @type {object}
* keys = componentName, hostName
*/
componentToBeAdded: {},
/**
* This object is populated to keep track of installed components to be excluded in the layout for recommendation/validation call
* @type {object}
* keys = componentName, hostName
*/
componentToBeDeleted: {},
uiOnlyConfigDerivedFromTheme: [],
currentStackVersionNumber: function () {
var regExp = new RegExp(this.get('currentStackName') + '-');
return (this.get('currentStackVersion') || this.get('defaultStackVersion')).replace(regExp, '');
}.property('currentStackVersion', 'defaultStackVersion', 'currentStackName'),
isHadoop23Stack: function () {
return (stringUtils.compareVersions(this.get('currentStackVersionNumber'), "2.3") > -1);
}.property('currentStackVersionNumber'),
isHadoopWindowsStack: Em.computed.equal('currentStackName', 'HDPWIN'),
/**
* If NameNode High Availability is enabled
* Based on <code>clusterStatus.isInstalled</code>, stack version, <code>SNameNode</code> availability
*
* @type {bool}
*/
isHaEnabled: function () {
return App.Service.find('HDFS').get('isLoaded') && !App.HostComponent.find().someProperty('componentName', 'SECONDARY_NAMENODE');
}.property('router.clusterController.dataLoadList.services', 'router.clusterController.isServiceContentFullyLoaded'),
/**
* If ResourceManager High Availability is enabled
* Based on number of ResourceManager host components installed
*
* @type {bool}
*/
isRMHaEnabled: function () {
var result = false;
var rmStackComponent = App.StackServiceComponent.find().findProperty('componentName','RESOURCEMANAGER');
if (rmStackComponent && rmStackComponent.get('isMultipleAllowed')) {
result = this.HostComponent.find().filterProperty('componentName', 'RESOURCEMANAGER').length > 1;
}
return result;
}.property('router.clusterController.isLoaded', 'isStackServicesLoaded'),
/**
* If Ranger Admin High Availability is enabled
* Based on number of Ranger Admin host components installed
*
* @type {bool}
*/
isRAHaEnabled: function () {
var result = false;
var raStackComponent = App.StackServiceComponent.find().findProperty('componentName','RANGER_ADMIN');
if (raStackComponent && raStackComponent.get('isMultipleAllowed')) {
result = App.HostComponent.find().filterProperty('componentName', 'RANGER_ADMIN').length > 1;
}
return result;
}.property('router.clusterController.isLoaded', 'isStackServicesLoaded'),
/**
* Object with utility functions for list of service names with similar behavior
*/
services: Em.Object.create({
all: function () {
return App.StackService.find().mapProperty('serviceName');
}.property('App.router.clusterController.isLoaded'),
clientOnly: function () {
return App.StackService.find().filterProperty('isClientOnlyService').mapProperty('serviceName');
}.property('App.router.clusterController.isLoaded'),
hasClient: function () {
return App.StackService.find().filterProperty('hasClient').mapProperty('serviceName');
}.property('App.router.clusterController.isLoaded'),
hasMaster: function () {
return App.StackService.find().filterProperty('hasMaster').mapProperty('serviceName');
}.property('App.router.clusterController.isLoaded'),
hasSlave: function () {
return App.StackService.find().filterProperty('hasSlave').mapProperty('serviceName');
}.property('App.router.clusterController.isLoaded'),
noConfigTypes: function () {
return App.StackService.find().filterProperty('isNoConfigTypes').mapProperty('serviceName');
}.property('App.router.clusterController.isLoaded'),
servicesWithHeatmapTab: function () {
return App.StackService.find().filterProperty('hasHeatmapSection').mapProperty('serviceName');
}.property('App.router.clusterController.isLoaded'),
monitoring: function () {
return App.StackService.find().filterProperty('isMonitoringService').mapProperty('serviceName');
}.property('App.router.clusterController.isLoaded'),
hostMetrics: function () {
return App.StackService.find().filterProperty('isHostMetricsService').mapProperty('serviceName');
}.property('App.router.clusterController.isLoaded'),
serviceMetrics: function () {
return App.StackService.find().filterProperty('isServiceMetricsService').mapProperty('serviceName');
}.property('App.router.clusterController.isLoaded'),
supportsServiceCheck: function() {
return App.StackService.find().filterProperty('serviceCheckSupported').mapProperty('serviceName');
}.property('App.router.clusterController.isLoaded')
}),
/**
* List of components with allowed action for them
* @type {Em.Object}
*/
components: Em.Object.create({
isMasterAddableOnlyOnHA: function () {
return App.StackServiceComponent.find().filterProperty('isMasterAddableOnlyOnHA').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
allComponents: function () {
return App.StackServiceComponent.find().mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
reassignable: function () {
return App.StackServiceComponent.find().filterProperty('isReassignable').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
restartable: function () {
return App.StackServiceComponent.find().filterProperty('isRestartable').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
deletable: function () {
return App.StackServiceComponent.find().filterProperty('isDeletable').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
rollinRestartAllowed: function () {
return App.StackServiceComponent.find().filterProperty('isRollinRestartAllowed').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
decommissionAllowed: function () {
return App.StackServiceComponent.find().filterProperty('isDecommissionAllowed').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
refreshConfigsAllowed: function () {
return App.StackServiceComponent.find().filterProperty('isRefreshConfigsAllowed').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
addableToHost: function () {
return App.StackServiceComponent.find().filterProperty('isAddableToHost').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
addableMasterInstallerWizard: function () {
return App.StackServiceComponent.find().filterProperty('isMasterAddableInstallerWizard').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
multipleMasters: function () {
return App.StackServiceComponent.find().filterProperty('isMasterWithMultipleInstances').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
slaves: function () {
return App.StackServiceComponent.find().filterProperty('isSlave').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
masters: function () {
return App.StackServiceComponent.find().filterProperty('isMaster').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
clients: function () {
return App.StackServiceComponent.find().filterProperty('isClient').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded'),
nonHDP: function () {
return App.StackServiceComponent.find().filterProperty('isNonHDPComponent').mapProperty('componentName')
}.property('App.router.clusterController.isLoaded')
})
});