You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by at...@apache.org on 2019/01/10 16:23:27 UTC
[ambari] branch trunk updated: AMBARI-25097 Cover views of reassign
wizard with unit tests
This is an automated email from the ASF dual-hosted git repository.
atkach pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push:
new 5f329b9 AMBARI-25097 Cover views of reassign wizard with unit tests
5f329b9 is described below
commit 5f329b9f858c292f7b6aeae4d93b434489278c1b
Author: Andrii Tkach <at...@apache.org>
AuthorDate: Thu Jan 10 17:24:37 2019 +0200
AMBARI-25097 Cover views of reassign wizard with unit tests
---
ambari-web/app/assets/test/tests.js | 5 +
.../app/views/main/service/reassign/step1_view.js | 31 ++--
.../app/views/main/service/reassign/step3_view.js | 16 +-
.../app/views/main/service/reassign/step5_view.js | 6 +-
.../views/main/service/reassign/step1_view_test.js | 128 ++++++++++++++++
.../views/main/service/reassign/step2_view_test.js | 74 +++++++++
.../views/main/service/reassign/step3_view_test.js | 81 ++++++++++
.../views/main/service/reassign/step4_view_test.js | 70 +++++++++
.../views/main/service/reassign/step5_view_test.js | 167 +++++++++++++++++++++
9 files changed, 549 insertions(+), 29 deletions(-)
diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js
index 2f809ec..91fa7b0 100644
--- a/ambari-web/app/assets/test/tests.js
+++ b/ambari-web/app/assets/test/tests.js
@@ -377,6 +377,11 @@ var files = [
'test/views/main/charts/heatmap_test',
'test/views/main/charts/heatmap/heatmap_host_test',
'test/views/main/service/item_test',
+ 'test/views/main/service/reassign/step1_view_test',
+ 'test/views/main/service/reassign/step2_view_test',
+ 'test/views/main/service/reassign/step3_view_test',
+ 'test/views/main/service/reassign/step4_view_test',
+ 'test/views/main/service/reassign/step5_view_test',
'test/views/main/service/manage_config_groups_view_test',
'test/views/main/service/reassign_view_test',
'test/views/main/service/reconfigure_test',
diff --git a/ambari-web/app/views/main/service/reassign/step1_view.js b/ambari-web/app/views/main/service/reassign/step1_view.js
index 5e677e2..7940810 100644
--- a/ambari-web/app/views/main/service/reassign/step1_view.js
+++ b/ambari-web/app/views/main/service/reassign/step1_view.js
@@ -21,40 +21,35 @@ var App = require('app');
var stringUtils = require('utils/string_utils');
App.ReassignMasterWizardStep1View = Em.View.extend({
-
+
+ templateName: require('templates/main/service/reassign/step1'),
+
message: function () {
var componentName = this.get('controller.content.reassign.component_name');
var listOfServices;
var installedServices = App.Service.find().mapProperty('serviceName');
-
- if(this.get('controller.content.componentsToStopAllServices').contains(componentName)) {
+
+ if (this.get('controller.content.componentsToStopAllServices').contains(componentName)) {
listOfServices = installedServices;
} else {
listOfServices = this.get('controller.target.reassignMasterController.relatedServicesMap')[componentName];
- if(!listOfServices || !listOfServices.length) {
- listOfServices = installedServices.filter(function (service) {
- return service != 'HDFS';
- });
+ if (!listOfServices || !listOfServices.length) {
+ listOfServices = installedServices.reject(service => service === 'HDFS');
} else { //not display any service which is not installed
- var installedServicesToStop = listOfServices.filter(function (service) {
- return installedServices.contains(service);
- });
- listOfServices = installedServicesToStop;
+ listOfServices = listOfServices.filter(service => installedServices.contains(service));
}
}
-
+
var messages = [
Em.I18n.t('services.reassign.step1.message1').format(this.get('controller.content.reassign.display_name')),
Em.I18n.t('services.reassign.step1.message3').format(stringUtils.getFormattedStringFromArray(listOfServices),
this.get('controller.content.reassign.display_name'))
];
if (this.get('controller.content.hasManualSteps')) {
- messages.splice(1,0, Em.I18n.t('services.reassign.step1.message2').format(this.get('controller.content.reassign.display_name')));
+ messages.splice(1, 0, Em.I18n.t('services.reassign.step1.message2').format(this.get('controller.content.reassign.display_name')));
}
-
+
return messages;
- }.property('controller.content.reassign.display_name','controller.content.hasManualSteps'),
-
- templateName: require('templates/main/service/reassign/step1')
-
+ }.property('controller.content.reassign.display_name', 'controller.content.hasManualSteps')
+
});
diff --git a/ambari-web/app/views/main/service/reassign/step3_view.js b/ambari-web/app/views/main/service/reassign/step3_view.js
index b6a379e..2bed38c 100644
--- a/ambari-web/app/views/main/service/reassign/step3_view.js
+++ b/ambari-web/app/views/main/service/reassign/step3_view.js
@@ -30,16 +30,16 @@ App.ReassignMasterWizardStep3View = Em.View.extend({
didInsertElement: function () {
this.get('controller').loadStep();
},
-
- jdbcSetupMessage: function() {
- if(['HIVE_SERVER', 'HIVE_METASTORE', 'OOZIE_SERVER'].contains(this.get('controller.content.reassign.component_name'))) {
- if(this.get('controller.content.reassign.component_name') === 'OOZIE_SERVER' && this.get('controller.content.databaseType') === 'derby') {
- return false;
+
+ jdbcSetupMessage: function () {
+ if (['HIVE_SERVER', 'HIVE_METASTORE', 'OOZIE_SERVER'].contains(this.get('controller.content.reassign.component_name'))) {
+ if (this.get('controller.content.reassign.component_name') === 'OOZIE_SERVER' && this.get('controller.content.databaseType') === 'derby') {
+ return '';
}
-
+
return Em.I18n.t('services.service.config.database.msg.jdbcSetup').format(this.get('controller.content.databaseType'), this.get('controller.content.databaseType'));
}
-
- return false;
+
+ return '';
}.property('controller.content.reassign.display_name', 'controller.content.databaseType')
});
diff --git a/ambari-web/app/views/main/service/reassign/step5_view.js b/ambari-web/app/views/main/service/reassign/step5_view.js
index 9c4f39d..c0fa560 100644
--- a/ambari-web/app/views/main/service/reassign/step5_view.js
+++ b/ambari-web/app/views/main/service/reassign/step5_view.js
@@ -18,14 +18,14 @@
var App = require('app');
-var stringUtils = require('utils/string_utils');
App.ReassignMasterWizardStep5View = Em.View.extend({
templateName: require('templates/main/service/reassign/step5'),
manualCommands: function () {
- if (!this.get('controller.content.componentsWithManualCommands').contains(this.get('controller.content.reassign.component_name'))) {
+ const componentName = this.get('controller.content.reassign.component_name');
+ if (!this.get('controller.content.componentsWithManualCommands').contains(componentName)) {
return '';
}
var
@@ -37,7 +37,7 @@ App.ReassignMasterWizardStep5View = Em.View.extend({
ha = '',
user = this.get('controller.content.hdfsUser'), path;
- if (this.get('controller.content.reassign.component_name') === 'NAMENODE' && App.get('isHaEnabled')) {
+ if (componentName === 'NAMENODE' && App.get('isHaEnabled')) {
ha = '_ha';
var nnStartedHost = this.get('controller.content.masterComponentHosts').filterProperty('component', 'NAMENODE').mapProperty('hostName').without(sourceHost).without(targetHost);
}
diff --git a/ambari-web/test/views/main/service/reassign/step1_view_test.js b/ambari-web/test/views/main/service/reassign/step1_view_test.js
new file mode 100644
index 0000000..d071b6a
--- /dev/null
+++ b/ambari-web/test/views/main/service/reassign/step1_view_test.js
@@ -0,0 +1,128 @@
+/**
+ * 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');
+require('views/main/service/reassign/step1_view');
+var stringUtils = require('utils/string_utils');
+
+var view;
+
+function getView() {
+ return App.ReassignMasterWizardStep1View.create();
+}
+
+describe('App.ReassignMasterWizardStep1View', function () {
+
+ beforeEach(function() {
+ view = getView();
+ });
+
+ describe('#message', function() {
+ beforeEach(function() {
+ sinon.stub(App.Service, 'find').returns([{serviceName: 'S1'}, {serviceName: 'HDFS'}]);
+ });
+ afterEach(function() {
+ App.Service.find.restore();
+ });
+
+ it('should return message with all installed services', function() {
+ view.set('controller', Em.Object.create({
+ content: {
+ reassign: {
+ component_name: 'C1',
+ display_name: 'c1'
+ },
+ componentsToStopAllServices: ['C1']
+ }
+ }));
+ view.propertyDidChange('message');
+ expect(view.get('message')).to.be.eql([
+ Em.I18n.t('services.reassign.step1.message1').format('c1'),
+ Em.I18n.t('services.reassign.step1.message3').format(stringUtils.getFormattedStringFromArray(['S1', 'HDFS']), 'c1')
+ ]);
+ });
+
+ it('should return message with all installed services, has manual steps', function() {
+ view.set('controller', Em.Object.create({
+ content: {
+ reassign: {
+ component_name: 'C1',
+ display_name: 'c1'
+ },
+ componentsToStopAllServices: ['C1'],
+ hasManualSteps: true
+ }
+ }));
+ view.propertyDidChange('message');
+ expect(view.get('message')).to.be.eql([
+ Em.I18n.t('services.reassign.step1.message1').format('c1'),
+ Em.I18n.t('services.reassign.step1.message2').format('c1'),
+ Em.I18n.t('services.reassign.step1.message3').format(stringUtils.getFormattedStringFromArray(['S1', 'HDFS']), 'c1')
+ ]);
+ });
+
+ it('should return message with non-HDFS services', function() {
+ view.set('controller', Em.Object.create({
+ content: {
+ reassign: {
+ component_name: 'C1',
+ display_name: 'c1'
+ },
+ componentsToStopAllServices: []
+ },
+ target: {
+ reassignMasterController: {
+ relatedServicesMap: {}
+ }
+ }
+ }));
+ view.propertyDidChange('message');
+ expect(view.get('message')).to.be.eql([
+ Em.I18n.t('services.reassign.step1.message1').format('c1'),
+ Em.I18n.t('services.reassign.step1.message3').format(stringUtils.getFormattedStringFromArray(['S1']), 'c1')
+ ]);
+ });
+
+ it('should return message with related services', function() {
+ view.set('controller', Em.Object.create({
+ content: {
+ reassign: {
+ component_name: 'C1',
+ display_name: 'c1'
+ },
+ componentsToStopAllServices: []
+ },
+ target: {
+ reassignMasterController: {
+ relatedServicesMap: {
+ 'C1': ['S2', 'S1']
+ }
+ }
+ }
+ }));
+ view.propertyDidChange('message');
+ expect(view.get('message')).to.be.eql([
+ Em.I18n.t('services.reassign.step1.message1').format('c1'),
+ Em.I18n.t('services.reassign.step1.message3').format(stringUtils.getFormattedStringFromArray(['S1']), 'c1')
+ ]);
+ });
+
+ });
+
+});
+
diff --git a/ambari-web/test/views/main/service/reassign/step2_view_test.js b/ambari-web/test/views/main/service/reassign/step2_view_test.js
new file mode 100644
index 0000000..2e72bf7
--- /dev/null
+++ b/ambari-web/test/views/main/service/reassign/step2_view_test.js
@@ -0,0 +1,74 @@
+/**
+ * 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');
+require('views/main/service/reassign/step2_view');
+
+var view;
+
+function getView() {
+ return App.ReassignMasterWizardStep2View.create();
+}
+
+describe('App.ReassignMasterWizardStep2View', function () {
+
+ beforeEach(function() {
+ view = getView();
+ });
+
+ describe('#alertMessage', function() {
+ beforeEach(function() {
+ sinon.stub(App, 'get').returns(true);
+ });
+ afterEach(function() {
+ App.get.restore();
+ });
+
+ it('should return NAMENODE alert', function() {
+ view.set('controller', Em.Object.create({
+ content: {
+ reassign: {
+ component_name: 'NAMENODE',
+ display_name: 'Namenode'
+ }
+ }
+ }));
+ view.propertyDidChange('alertMessage');
+ expect(view.get('alertMessage')).to.be.equal(
+ Em.I18n.t('services.reassign.step2.body.namenodeHA').format('Namenode')
+ );
+ });
+
+ it('should return component alert', function() {
+ view.set('controller', Em.Object.create({
+ content: {
+ reassign: {
+ component_name: 'C1',
+ display_name: 'c1'
+ }
+ }
+ }));
+ view.propertyDidChange('alertMessage');
+ expect(view.get('alertMessage')).to.be.equal(
+ Em.I18n.t('services.reassign.step2.body').format('c1')
+ );
+ });
+ });
+
+});
+
diff --git a/ambari-web/test/views/main/service/reassign/step3_view_test.js b/ambari-web/test/views/main/service/reassign/step3_view_test.js
new file mode 100644
index 0000000..78b7ce3
--- /dev/null
+++ b/ambari-web/test/views/main/service/reassign/step3_view_test.js
@@ -0,0 +1,81 @@
+/**
+ * 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');
+require('views/main/service/reassign/step3_view');
+
+var view;
+
+function getView() {
+ return App.ReassignMasterWizardStep3View.create();
+}
+
+describe('App.ReassignMasterWizardStep3View', function () {
+
+ beforeEach(function() {
+ view = getView();
+ });
+
+ describe('#didInsertElement', function() {
+
+ it('loadStep should be called', function() {
+ view.set('controller', {
+ loadStep: sinon.spy()
+ });
+ view.didInsertElement();
+ expect(view.get('controller').loadStep.calledOnce).to.be.true;
+ });
+ });
+
+ describe('#jdbcSetupMessage', function() {
+
+ it('should return empty', function() {
+ view.propertyDidChange('jdbcSetupMessage');
+ expect(view.get('jdbcSetupMessage')).to.be.empty;
+ });
+
+ it('should return empty for OOZIE SERVER', function() {
+ view.set('controller', {
+ content: {
+ reassign: {
+ component_name: 'OOZIE_SERVER'
+ },
+ databaseType: 'derby'
+ }
+ });
+ view.propertyDidChange('jdbcSetupMessage');
+ expect(view.get('jdbcSetupMessage')).to.be.empty;
+ });
+
+ it('should return empty for OOZIE SERVER', function() {
+ view.set('controller', {
+ content: {
+ reassign: {
+ component_name: 'HIVE_SERVER'
+ },
+ databaseType: 'type1'
+ }
+ });
+ view.propertyDidChange('jdbcSetupMessage');
+ expect(view.get('jdbcSetupMessage')).to.be.equal(
+ Em.I18n.t('services.service.config.database.msg.jdbcSetup').format('type1', 'type1')
+ );
+ });
+ });
+
+});
diff --git a/ambari-web/test/views/main/service/reassign/step4_view_test.js b/ambari-web/test/views/main/service/reassign/step4_view_test.js
new file mode 100644
index 0000000..928bef3
--- /dev/null
+++ b/ambari-web/test/views/main/service/reassign/step4_view_test.js
@@ -0,0 +1,70 @@
+/**
+ * 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');
+require('views/main/service/reassign/step4_view');
+
+var view;
+
+function getView() {
+ return App.ReassignMasterWizardStep4View.create();
+}
+
+describe('App.ReassignMasterWizardStep4View', function () {
+
+ beforeEach(function() {
+ view = getView();
+ });
+
+ describe('#noticeCompleted', function() {
+
+ it('should return notice for manual steps', function() {
+ view.set('controller', {
+ content: {
+ hasManualSteps: true,
+ reassign: {
+ component_name: 'C1'
+ }
+ }
+ });
+ view.propertyDidChange('noticeCompleted');
+ expect(view.get('noticeCompleted')).to.be.equal(
+ Em.I18n.t('services.reassign.step4.status.success.withManualSteps').format('c1')
+ );
+ });
+
+ it('should return notice', function() {
+ view.set('controller', {
+ content: {
+ hasManualSteps: false,
+ reassign: {
+ component_name: 'C1'
+ },
+ reassignHosts: {
+ source: 'host1',
+ target: 'host2'
+ }
+ }
+ });
+ view.propertyDidChange('noticeCompleted');
+ expect(view.get('noticeCompleted')).to.be.equal(
+ Em.I18n.t('services.reassign.step4.status.success').format('c1', 'host1', 'host2')
+ );
+ });
+ });
+});
diff --git a/ambari-web/test/views/main/service/reassign/step5_view_test.js b/ambari-web/test/views/main/service/reassign/step5_view_test.js
new file mode 100644
index 0000000..df5d9a7
--- /dev/null
+++ b/ambari-web/test/views/main/service/reassign/step5_view_test.js
@@ -0,0 +1,167 @@
+/**
+ * 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');
+require('views/main/service/reassign/step5_view');
+
+var view;
+
+function getView() {
+ return App.ReassignMasterWizardStep5View.create();
+}
+
+describe('App.ReassignMasterWizardStep5View', function () {
+
+ beforeEach(function() {
+ view = getView();
+ });
+
+ describe('#manualCommands', function() {
+ beforeEach(function() {
+ sinon.stub(App.StackService, 'find').returns({
+ compareCurrentVersion: function() {return 1;}
+ });
+ sinon.stub(App, 'get').returns(true);
+ });
+ afterEach(function() {
+ App.StackService.find.restore();
+ App.get.restore();
+ });
+
+ it('should be empty', function() {
+ view.set('controller', {
+ content: {
+ reassign: {
+ component_name: 'C1'
+ },
+ componentsWithManualCommands: []
+ }
+ });
+ view.propertyDidChange('manualCommands');
+ expect(view.get('manualCommands')).to.be.empty;
+ });
+
+ it('NAMENODE component', function() {
+ view.set('controller', {
+ content: {
+ group: 'group1',
+ masterComponentHosts: [{
+ component: 'NAMENODE',
+ hostName: 'host3'
+ }],
+ hdfsUser: 'hdfs',
+ reassign: {
+ component_name: 'NAMENODE'
+ },
+ reassignHosts: {
+ source: 'host1',
+ target: 'host2'
+ },
+ componentDir: 'dir',
+ componentsWithManualCommands: ['NAMENODE']
+ }
+ });
+ view.propertyDidChange('manualCommands');
+ expect(view.get('manualCommands')).to.be.equal(
+ Em.I18n.t('services.reassign.step5.body.namenode_ha').
+ format('dir', 'host1', 'host2', 'hdfs', 'host3', 'group1', 'dir', undefined, 'timeline-state-store.ldb')
+ );
+ });
+
+ it('APP_TIMELINE_SERVER component', function() {
+ view.set('controller', {
+ content: {
+ configs: {
+ 'yarn-env': {
+ 'yarn_user': 'yarn'
+ },
+ 'yarn-site': {
+ 'yarn.timeline-service.leveldb-timeline-store.path': 'path'
+ }
+ },
+ group: 'group1',
+ hdfsUser: 'hdfs',
+ reassign: {
+ component_name: 'APP_TIMELINE_SERVER'
+ },
+ reassignHosts: {
+ source: 'host1',
+ target: 'host2'
+ },
+ componentDir: 'dir',
+ componentsWithManualCommands: ['APP_TIMELINE_SERVER']
+ }
+ });
+ view.propertyDidChange('manualCommands');
+ expect(view.get('manualCommands')).to.be.equal(
+ Em.I18n.t('services.reassign.step5.body.app_timeline_server').
+ format('dir', 'host1', 'host2', 'yarn', 'host3', 'group1', 'dir', 'path', 'timeline-state-store.ldb')
+ );
+ });
+ });
+
+ describe('#securityNotice', function() {
+
+ beforeEach(function() {
+ sinon.stub(App, 'get').returns(true);
+ });
+ afterEach(function() {
+ App.get.restore();
+ });
+
+ it('no secure configs', function() {
+ view.set('controller', {
+ content: {
+ secureConfigs: [],
+ componentsWithoutSecurityConfigs: [],
+ reassign: {
+ component_name: 'C1'
+ }
+ }
+ });
+ view.propertyDidChange('securityNotice');
+ expect(view.get('securityNotice')).to.be.equal(Em.I18n.t('services.reassign.step5.body.proceedMsg'));
+ });
+
+ it('has secure configs', function() {
+ view.set('controller', {
+ content: {
+ secureConfigs: [{
+ principal: '_HOST',
+ keytab: 'keytab1'
+ }],
+ componentsWithoutSecurityConfigs: [],
+ reassign: {
+ component_name: 'C1'
+ },
+ reassignHosts: {
+ target: 'host2',
+ source: 'host1'
+ }
+ }
+ });
+ view.propertyDidChange('securityNotice');
+ expect(view.get('securityNotice')).to.be.equal(
+ Em.I18n.t('services.reassign.step5.body.securityNotice').format(
+ "<ul><li>" + Em.I18n.t('services.reassign.step5.body.securityConfigsList').format('keytab1','host2', 'host2') + "</li></ul>"
+ ) + Em.I18n.t('services.reassign.step5.body.proceedMsg')
+ );
+ });
+ });
+
+});