AMBARI-7066 Ambari support for ATS in Kerberized cluster (alejandro)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c8ba5e97 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c8ba5e97 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c8ba5e97 Branch: refs/heads/branch-alerts-dev Commit: c8ba5e97058f1da767f11e01827d5460a3e062b3 Parents: e7131fa Author: Alejandro Fernandez <afernan...@hortonworks.com> Authored: Fri Sep 5 11:31:13 2014 -0700 Committer: Alejandro Fernandez <afernan...@hortonworks.com> Committed: Fri Sep 5 11:31:13 2014 -0700 ---------------------------------------------------------------------- .../scripts/application_timeline_server.py | 4 +- .../YARN/package/scripts/historyserver.py | 4 +- .../services/YARN/package/scripts/params.py | 9 ++ .../services/YARN/package/scripts/service.py | 30 +++--- .../YARN/package/scripts/status_params.py | 2 +- .../stacks/HDP/2.2.1/services/YARN/metainfo.xml | 8 ++ .../stacks/2.0.6/YARN/test_historyserver.py | 104 +++++++++---------- .../stacks/2.0.6/YARN/test_nodemanager.py | 103 +++++++++--------- .../stacks/2.0.6/YARN/test_resourcemanager.py | 102 +++++++++--------- .../python/stacks/2.0.6/configs/secured.json | 4 +- .../stacks/2.1/YARN/test_apptimelineserver.py | 54 +++++----- ambari-web/app/app.js | 13 +++ .../security/add/addSecurity_controller.js | 7 +- .../main/admin/security/add/step1.js | 11 +- .../main/admin/security/add/step3.js | 32 +++++- .../main/admin/security/add/step4.js | 9 +- ambari-web/app/data/HDP2/secure_configs.js | 20 +++- ambari-web/app/data/HDP2/secure_mapping.js | 45 ++++++++ ambari-web/app/data/HDP2/secure_properties.js | 71 +++++++++++++ ambari-web/app/messages.js | 4 +- ambari-web/app/routes/add_security.js | 6 +- .../templates/main/admin/security/add/step1.hbs | 2 +- .../app/views/main/admin/security/add/step1.js | 6 +- .../main/admin/security/add/step1_test.js | 10 +- 24 files changed, 432 insertions(+), 228 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/application_timeline_server.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/application_timeline_server.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/application_timeline_server.py index d66f2f6..85d97c2 100644 --- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/application_timeline_server.py +++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/application_timeline_server.py @@ -39,12 +39,12 @@ class ApplicationTimelineServer(Script): import params env.set_params(params) self.configure(env) # FOR SECURITY - service('historyserver', action='start') + service('timelineserver', action='start') def stop(self, env): import params env.set_params(params) - service('historyserver', action='stop') + service('timelineserver', action='stop') def status(self, env): import status_params http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/historyserver.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/historyserver.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/historyserver.py index d5c6db2..4184dc4 100644 --- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/historyserver.py +++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/historyserver.py @@ -24,7 +24,7 @@ from resource_management import * from yarn import yarn from service import service -class Histroryserver(Script): +class HistoryServer(Script): def install(self, env): self.install_packages(env) @@ -50,4 +50,4 @@ class Histroryserver(Script): check_process_status(status_params.mapred_historyserver_pid_file) if __name__ == "__main__": - Histroryserver().execute() + HistoryServer().execute() http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/params.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/params.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/params.py index 8c5fa9b..313ed94 100644 --- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/params.py +++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/params.py @@ -28,6 +28,8 @@ tmp_dir = Script.get_tmp_dir() config_dir = "/etc/hadoop/conf" +ulimit_cmd = "ulimit -c unlimited;" + mapred_user = status_params.mapred_user yarn_user = status_params.yarn_user hdfs_user = config['configurations']['hadoop-env']['hdfs_user'] @@ -108,8 +110,15 @@ if security_enabled: _rm_principal_name = _rm_principal_name.replace('_HOST',hostname.lower()) rm_kinit_cmd = format("{kinit_path_local} -kt {_rm_keytab} {_rm_principal_name};") + + # YARN timeline security options are only available in HDP Champlain + _yarn_timelineservice_principal_name = config['configurations']['yarn-site']['yarn.timeline-service.principal'] + _yarn_timelineservice_principal_name = _yarn_timelineservice_principal_name.replace('_HOST', hostname.lower()) + _yarn_timelineservice_keytab = config['configurations']['yarn-site']['yarn.timeline-service.keytab'] + yarn_timelineservice_kinit_cmd = format("{kinit_path_local} -kt {_yarn_timelineservice_keytab} {_yarn_timelineservice_principal_name};") else: rm_kinit_cmd = "" + yarn_timelineservice_kinit_cmd = "" yarn_log_aggregation_enabled = config['configurations']['yarn-site']['yarn.log-aggregation-enable'] yarn_nm_app_log_dir = config['configurations']['yarn-site']['yarn.nodemanager.remote-app-log-dir'] http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/service.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/service.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/service.py index d696b67..42a7138 100644 --- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/service.py +++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/service.py @@ -26,7 +26,7 @@ def service(componentName, action='start', serviceName='yarn'): import params - if (serviceName == 'mapreduce' and componentName == 'historyserver'): + if serviceName == 'mapreduce' and componentName == 'historyserver': daemon = format("{mapred_bin}/mr-jobhistory-daemon.sh") pid_file = format("{mapred_pid_dir}/mapred-{mapred_user}-{componentName}.pid") usr = params.mapred_user @@ -38,28 +38,34 @@ def service(componentName, action='start', serviceName='yarn'): cmd = format("export HADOOP_LIBEXEC_DIR={hadoop_libexec_dir} && {daemon} --config {config_dir}") if action == 'start': - daemon_cmd = format("{cmd} start {componentName}") - no_op = format("ls {pid_file} >/dev/null 2>&1 && ps `cat {pid_file}` >/dev/null 2>&1") + daemon_cmd = format("{ulimit_cmd} {cmd} start {componentName}") + check_process = format("ls {pid_file} >/dev/null 2>&1 && ps `cat {pid_file}` >/dev/null 2>&1") + + # Remove the pid file if its corresponding process is not running. + File(pid_file, + action="delete", + not_if=check_process) + + # Attempt to start the process. Internally, this is skipped if the process is already running. Execute(daemon_cmd, user=usr, - not_if=no_op + not_if=check_process ) - Execute(no_op, + # Ensure that the process with the expected PID exists. + Execute(check_process, user=usr, - not_if=no_op, + not_if=check_process, initial_wait=5 ) elif action == 'stop': daemon_cmd = format("{cmd} stop {componentName}") Execute(daemon_cmd, - user=usr, - ) - rm_pid = format("rm -f {pid_file}") - Execute(rm_pid, - user=usr - ) + user=usr) + + File(pid_file, + action="delete") elif action == 'refreshQueues': refresh_cmd = format("export HADOOP_LIBEXEC_DIR={hadoop_libexec_dir} && {yarn_container_bin}/yarn rmadmin -refreshQueues") http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/status_params.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/status_params.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/status_params.py index a3a45be..6bc977c 100644 --- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/status_params.py +++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/YARN/package/scripts/status_params.py @@ -31,5 +31,5 @@ mapred_pid_dir = format("{mapred_pid_dir_prefix}/{mapred_user}") resourcemanager_pid_file = format("{yarn_pid_dir}/yarn-{yarn_user}-resourcemanager.pid") nodemanager_pid_file = format("{yarn_pid_dir}/yarn-{yarn_user}-nodemanager.pid") -yarn_historyserver_pid_file = format("{yarn_pid_dir}/yarn-{yarn_user}-historyserver.pid") +yarn_historyserver_pid_file = format("{yarn_pid_dir}/yarn-{yarn_user}-timelineserver.pid") # *-historyserver.pid is deprecated mapred_historyserver_pid_file = format("{mapred_pid_dir}/mapred-{mapred_user}-historyserver.pid") \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-server/src/main/resources/stacks/HDP/2.2.1/services/YARN/metainfo.xml ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/stacks/HDP/2.2.1/services/YARN/metainfo.xml b/ambari-server/src/main/resources/stacks/HDP/2.2.1/services/YARN/metainfo.xml index 3f17168..fa84a71 100644 --- a/ambari-server/src/main/resources/stacks/HDP/2.2.1/services/YARN/metainfo.xml +++ b/ambari-server/src/main/resources/stacks/HDP/2.2.1/services/YARN/metainfo.xml @@ -22,6 +22,14 @@ <service> <name>YARN</name> <version>2.6.0.2.2</version> + + <components> + <component> + <name>APP_TIMELINE_SERVER</name> + <cardinality>1</cardinality> + </component> + </components> + </service> </services> <service> http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-server/src/test/python/stacks/2.0.6/YARN/test_historyserver.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/python/stacks/2.0.6/YARN/test_historyserver.py b/ambari-server/src/test/python/stacks/2.0.6/YARN/test_historyserver.py index 86e3353..155e07d 100644 --- a/ambari-server/src/test/python/stacks/2.0.6/YARN/test_historyserver.py +++ b/ambari-server/src/test/python/stacks/2.0.6/YARN/test_historyserver.py @@ -29,89 +29,87 @@ class TestHistoryServer(RMFTestCase): def test_configure_default(self): self.executeScript("2.0.6/services/YARN/package/scripts/historyserver.py", - classname = "Histroryserver", - command = "configure", - config_file="default.json" - ) + classname="HistoryServer", + command="configure", + config_file="default.json") self.assert_configure_default() self.assertNoMoreResources() def test_start_default(self): self.executeScript("2.0.6/services/YARN/package/scripts/historyserver.py", - classname = "Histroryserver", - command = "start", - config_file="default.json" - ) - + classname="HistoryServer", + command="start", + config_file="default.json") self.assert_configure_default() - self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-mapreduce/sbin/mr-jobhistory-daemon.sh --config /etc/hadoop/conf start historyserver', - not_if = 'ls /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid` >/dev/null 2>&1', - user = 'mapred' - ) - self.assertResourceCalled('Execute', 'ls /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid` >/dev/null 2>&1', - user = 'mapred', - not_if = 'ls /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid` >/dev/null 2>&1', - initial_wait=5 - ) + + pid_check_cmd = 'ls /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid` >/dev/null 2>&1' + + self.assertResourceCalled('File', '/var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid', + not_if=pid_check_cmd, + action=['delete']) + self.assertResourceCalled('Execute', 'ulimit -c unlimited; export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-mapreduce/sbin/mr-jobhistory-daemon.sh --config /etc/hadoop/conf start historyserver', + not_if=pid_check_cmd, + user='mapred') + self.assertResourceCalled('Execute', pid_check_cmd, + not_if=pid_check_cmd, + initial_wait=5, + user='mapred') self.assertNoMoreResources() def test_stop_default(self): self.executeScript("2.0.6/services/YARN/package/scripts/historyserver.py", - classname = "Histroryserver", - command = "stop", - config_file="default.json" - ) + classname="HistoryServer", + command="stop", + config_file="default.json") self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-mapreduce/sbin/mr-jobhistory-daemon.sh --config /etc/hadoop/conf stop historyserver', - user = 'mapred' - ) - self.assertResourceCalled('Execute', 'rm -f /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid', - user = 'mapred' - ) + user='mapred') + self.assertResourceCalled('File', '/var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid', + action=['delete']) self.assertNoMoreResources() def test_configure_secured(self): self.executeScript("2.0.6/services/YARN/package/scripts/historyserver.py", - classname = "Histroryserver", - command = "configure", - config_file="secured.json" - ) + classname="HistoryServer", + command="configure", + config_file="secured.json") self.assert_configure_secured() self.assertNoMoreResources() def test_start_secured(self): self.executeScript("2.0.6/services/YARN/package/scripts/historyserver.py", - classname = "Histroryserver", - command = "start", - config_file="secured.json" - ) + classname="HistoryServer", + command="start", + config_file="secured.json") self.assert_configure_secured() - self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-mapreduce/sbin/mr-jobhistory-daemon.sh --config /etc/hadoop/conf start historyserver', - not_if = 'ls /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid` >/dev/null 2>&1', - user = 'mapred' - ) - self.assertResourceCalled('Execute', 'ls /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid` >/dev/null 2>&1', - user = 'mapred', - not_if = 'ls /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid` >/dev/null 2>&1', - initial_wait=5 - ) + + pid_check_cmd = 'ls /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid` >/dev/null 2>&1' + + self.assertResourceCalled('File', '/var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid', + not_if=pid_check_cmd, + action=['delete']) + self.assertResourceCalled('Execute', 'ulimit -c unlimited; export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-mapreduce/sbin/mr-jobhistory-daemon.sh --config /etc/hadoop/conf start historyserver', + not_if=pid_check_cmd, + user='mapred') + self.assertResourceCalled('Execute', pid_check_cmd, + user='mapred', + not_if=pid_check_cmd, + initial_wait=5) self.assertNoMoreResources() def test_stop_secured(self): self.executeScript("2.0.6/services/YARN/package/scripts/historyserver.py", - classname = "Histroryserver", - command = "stop", - config_file="secured.json" - ) + classname="HistoryServer", + command="stop", + config_file="secured.json") self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-mapreduce/sbin/mr-jobhistory-daemon.sh --config /etc/hadoop/conf stop historyserver', - user = 'mapred' - ) - self.assertResourceCalled('Execute', 'rm -f /var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid', - user = 'mapred' - ) + user='mapred') + + self.assertResourceCalled('File', '/var/run/hadoop-mapreduce/mapred/mapred-mapred-historyserver.pid', + action=['delete']) self.assertNoMoreResources() def assert_configure_default(self): http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-server/src/test/python/stacks/2.0.6/YARN/test_nodemanager.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/python/stacks/2.0.6/YARN/test_nodemanager.py b/ambari-server/src/test/python/stacks/2.0.6/YARN/test_nodemanager.py index 597324a..4723b0f 100644 --- a/ambari-server/src/test/python/stacks/2.0.6/YARN/test_nodemanager.py +++ b/ambari-server/src/test/python/stacks/2.0.6/YARN/test_nodemanager.py @@ -29,89 +29,84 @@ class TestNodeManager(RMFTestCase): def test_configure_default(self): self.executeScript("2.0.6/services/YARN/package/scripts/nodemanager.py", - classname = "Nodemanager", - command = "configure", - config_file="default.json" - ) + classname="Nodemanager", + command="configure", + config_file="default.json") self.assert_configure_default() self.assertNoMoreResources() def test_start_default(self): self.executeScript("2.0.6/services/YARN/package/scripts/nodemanager.py", - classname = "Nodemanager", - command = "start", - config_file="default.json" - ) - + classname="Nodemanager", + command="start", + config_file="default.json") self.assert_configure_default() - self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf start nodemanager', - not_if = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid` >/dev/null 2>&1', - user = 'yarn' - ) - self.assertResourceCalled('Execute', 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid` >/dev/null 2>&1', - user = 'yarn', - not_if = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid` >/dev/null 2>&1', - initial_wait=5 - ) + + pid_check_cmd = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid` >/dev/null 2>&1' + + self.assertResourceCalled('File', '/var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid', + not_if=pid_check_cmd, + action=['delete']) + self.assertResourceCalled('Execute', 'ulimit -c unlimited; export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf start nodemanager', + not_if=pid_check_cmd, + user='yarn') + self.assertResourceCalled('Execute', pid_check_cmd, + user='yarn', + not_if=pid_check_cmd, + initial_wait=5) self.assertNoMoreResources() def test_stop_default(self): self.executeScript("2.0.6/services/YARN/package/scripts/nodemanager.py", - classname = "Nodemanager", - command = "stop", - config_file="default.json" - ) - + classname="Nodemanager", + command="stop", + config_file="default.json") self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf stop nodemanager', - user = 'yarn' - ) - self.assertResourceCalled('Execute', 'rm -f /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid', - user = 'yarn' - ) + user='yarn') + self.assertResourceCalled('File', '/var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid', + action=['delete']) self.assertNoMoreResources() def test_configure_secured(self): self.executeScript("2.0.6/services/YARN/package/scripts/nodemanager.py", - classname = "Nodemanager", - command = "configure", - config_file="secured.json" - ) + classname="Nodemanager", + command="configure", + config_file="secured.json") self.assert_configure_secured() self.assertNoMoreResources() def test_start_secured(self): self.executeScript("2.0.6/services/YARN/package/scripts/nodemanager.py", - classname = "Nodemanager", - command = "start", - config_file="secured.json" - ) + classname="Nodemanager", + command="start", + config_file="secured.json") self.assert_configure_secured() - self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf start nodemanager', - not_if = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid` >/dev/null 2>&1', - user = 'yarn' - ) + + pid_check_cmd = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid` >/dev/null 2>&1' + + self.assertResourceCalled('File', '/var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid', + not_if=pid_check_cmd, + action=['delete']) + self.assertResourceCalled('Execute', 'ulimit -c unlimited; export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf start nodemanager', + not_if=pid_check_cmd, + user='yarn') self.assertResourceCalled('Execute', 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid` >/dev/null 2>&1', - user = 'yarn', - not_if = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid` >/dev/null 2>&1', - initial_wait=5 - ) + user='yarn', + not_if=pid_check_cmd, + initial_wait=5) self.assertNoMoreResources() def test_stop_secured(self): self.executeScript("2.0.6/services/YARN/package/scripts/nodemanager.py", - classname = "Nodemanager", - command = "stop", - config_file="secured.json" - ) - + classname="Nodemanager", + command="stop", + config_file="secured.json") self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf stop nodemanager', - user = 'yarn' - ) - self.assertResourceCalled('Execute', 'rm -f /var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid', - user = 'yarn' - ) + user='yarn') + self.assertResourceCalled('File', '/var/run/hadoop-yarn/yarn/yarn-yarn-nodemanager.pid', + action=['delete']) self.assertNoMoreResources() def assert_configure_default(self): http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-server/src/test/python/stacks/2.0.6/YARN/test_resourcemanager.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/python/stacks/2.0.6/YARN/test_resourcemanager.py b/ambari-server/src/test/python/stacks/2.0.6/YARN/test_resourcemanager.py index 8410b56..05a1cb6 100644 --- a/ambari-server/src/test/python/stacks/2.0.6/YARN/test_resourcemanager.py +++ b/ambari-server/src/test/python/stacks/2.0.6/YARN/test_resourcemanager.py @@ -29,88 +29,86 @@ class TestResourceManager(RMFTestCase): def test_configure_default(self): self.executeScript("2.0.6/services/YARN/package/scripts/resourcemanager.py", - classname = "Resourcemanager", - command = "configure", - config_file="default.json" - ) + classname="Resourcemanager", + command="configure", + config_file="default.json") self.assert_configure_default() self.assertNoMoreResources() def test_start_default(self): self.executeScript("2.0.6/services/YARN/package/scripts/resourcemanager.py", - classname = "Resourcemanager", - command = "start", - config_file="default.json" - ) + classname="Resourcemanager", + command="start", + config_file="default.json") self.assert_configure_default() - self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf start resourcemanager', - not_if = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid` >/dev/null 2>&1', - user = 'yarn' - ) - self.assertResourceCalled('Execute', 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid` >/dev/null 2>&1', - user = 'yarn', - not_if = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid` >/dev/null 2>&1', - initial_wait=5 - ) + + pid_check_cmd = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid` >/dev/null 2>&1' + + self.assertResourceCalled('File', '/var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid', + not_if=pid_check_cmd, + action=['delete']) + self.assertResourceCalled('Execute', 'ulimit -c unlimited; export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf start resourcemanager', + not_if=pid_check_cmd, + user='yarn') + self.assertResourceCalled('Execute', pid_check_cmd, + user='yarn', + not_if=pid_check_cmd, + initial_wait=5) self.assertNoMoreResources() def test_stop_default(self): self.executeScript("2.0.6/services/YARN/package/scripts/resourcemanager.py", - classname = "Resourcemanager", - command = "stop", - config_file="default.json" - ) + classname="Resourcemanager", + command="stop", + config_file="default.json") self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf stop resourcemanager', - user = 'yarn' - ) - self.assertResourceCalled('Execute', 'rm -f /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid', - user = 'yarn' - ) + user='yarn') + self.assertResourceCalled('File', '/var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid', + action=['delete']) self.assertNoMoreResources() def test_configure_secured(self): self.executeScript("2.0.6/services/YARN/package/scripts/resourcemanager.py", - classname = "Resourcemanager", - command = "configure", - config_file="secured.json" - ) + classname="Resourcemanager", + command="configure", + config_file="secured.json") self.assert_configure_secured() def test_start_secured(self): self.executeScript("2.0.6/services/YARN/package/scripts/resourcemanager.py", - classname = "Resourcemanager", - command = "start", - config_file="secured.json" - ) + classname="Resourcemanager", + command="start", + config_file="secured.json") self.assert_configure_secured() - self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf start resourcemanager', - not_if = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid` >/dev/null 2>&1', - user = 'yarn' - ) - self.assertResourceCalled('Execute', 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid` >/dev/null 2>&1', - user = 'yarn', - not_if = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid` >/dev/null 2>&1', - initial_wait=5 - ) + + pid_check_cmd = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid` >/dev/null 2>&1' + + self.assertResourceCalled('File', '/var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid', + not_if = pid_check_cmd, + action=['delete']) + self.assertResourceCalled('Execute', 'ulimit -c unlimited; export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf start resourcemanager', + not_if=pid_check_cmd, + user='yarn') + self.assertResourceCalled('Execute', pid_check_cmd, + user='yarn', + not_if=pid_check_cmd, + initial_wait=5) self.assertNoMoreResources() def test_stop_secured(self): self.executeScript("2.0.6/services/YARN/package/scripts/resourcemanager.py", - classname = "Resourcemanager", - command = "stop", - config_file="secured.json" - ) + classname="Resourcemanager", + command="stop", + config_file="secured.json") self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf stop resourcemanager', - user = 'yarn' - ) - self.assertResourceCalled('Execute', 'rm -f /var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid', - user = 'yarn' - ) + user='yarn') + self.assertResourceCalled('File', '/var/run/hadoop-yarn/yarn/yarn-yarn-resourcemanager.pid', + action=['delete']) self.assertNoMoreResources() def assert_configure_default(self): http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-server/src/test/python/stacks/2.0.6/configs/secured.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/python/stacks/2.0.6/configs/secured.json b/ambari-server/src/test/python/stacks/2.0.6/configs/secured.json index fc6c063..110003f 100644 --- a/ambari-server/src/test/python/stacks/2.0.6/configs/secured.json +++ b/ambari-server/src/test/python/stacks/2.0.6/configs/secured.json @@ -454,7 +454,9 @@ "yarn.resourcemanager.webapp.spnego-keytab-file": "/etc/security/keytabs/spnego.service.keytab", "yarn.resourcemanager.keytab": "/etc/security/keytabs/rm.service.keytab", "yarn.nodemanager.aux-services.mapreduce_shuffle.class": "org.apache.hadoop.mapred.ShuffleHandler", - "yarn.timeline-service.leveldb-timeline-store.path": "/var/log/hadoop-yarn/timeline" + "yarn.timeline-service.leveldb-timeline-store.path": "/var/log/hadoop-yarn/timeline", + "yarn.timeline-service.principal": "yarn/_h...@example.com", + "yarn.timeline-service.keytab" : "/etc/security/keytabs/yarn.service.keytab" }, "yarn-env": { "yarn_pid_dir_prefix": "/var/run/hadoop-yarn", http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-server/src/test/python/stacks/2.1/YARN/test_apptimelineserver.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/python/stacks/2.1/YARN/test_apptimelineserver.py b/ambari-server/src/test/python/stacks/2.1/YARN/test_apptimelineserver.py index 7dbbd9a..4d28601 100644 --- a/ambari-server/src/test/python/stacks/2.1/YARN/test_apptimelineserver.py +++ b/ambari-server/src/test/python/stacks/2.1/YARN/test_apptimelineserver.py @@ -27,46 +27,50 @@ origin_exists = os.path.exists if args[0][-2:] == "j2" else True)) class TestAppTimelineServer(RMFTestCase): + def test_configure_default(self): self.executeScript("2.0.6/services/YARN/package/scripts/application_timeline_server.py", - classname = "ApplicationTimelineServer", - command = "configure", - config_file="default.json" - ) + classname="ApplicationTimelineServer", + command="configure", + config_file="default.json") + self.assert_configure_default() self.assertNoMoreResources() def test_start_default(self): self.executeScript("2.0.6/services/YARN/package/scripts/application_timeline_server.py", - classname = "ApplicationTimelineServer", - command = "start", - config_file="default.json" - ) + classname="ApplicationTimelineServer", + command="start", + config_file="default.json") + self.assert_configure_default() - self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf start historyserver', - not_if = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-historyserver.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-historyserver.pid` >/dev/null 2>&1', - user = 'yarn') - self.assertResourceCalled('Execute', 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-historyserver.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-historyserver.pid` >/dev/null 2>&1', - initial_wait = 5, - not_if = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-historyserver.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-historyserver.pid` >/dev/null 2>&1', - user = 'yarn') + pid_check_cmd = 'ls /var/run/hadoop-yarn/yarn/yarn-yarn-timelineserver.pid >/dev/null 2>&1 && ps `cat /var/run/hadoop-yarn/yarn/yarn-yarn-timelineserver.pid` >/dev/null 2>&1' + self.assertResourceCalled('File', '/var/run/hadoop-yarn/yarn/yarn-yarn-timelineserver.pid', + not_if=pid_check_cmd, + action=['delete']) + + self.assertResourceCalled('Execute', 'ulimit -c unlimited; export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf start timelineserver', + not_if=pid_check_cmd, + user='yarn') + self.assertResourceCalled('Execute', pid_check_cmd, + initial_wait=5, + not_if=pid_check_cmd, + user='yarn') self.assertNoMoreResources() def test_stop_default(self): self.executeScript("2.0.6/services/YARN/package/scripts/application_timeline_server.py", - classname = "ApplicationTimelineServer", - command = "stop", - config_file="default.json" - ) - self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf stop historyserver', - user = 'yarn') - self.assertResourceCalled('Execute', 'rm -f /var/run/hadoop-yarn/yarn/yarn-yarn-historyserver.pid', - user = 'yarn') - self.assertNoMoreResources() - + classname="ApplicationTimelineServer", + command="stop", + config_file="default.json") + self.assertResourceCalled('Execute', 'export HADOOP_LIBEXEC_DIR=/usr/lib/hadoop/libexec && /usr/lib/hadoop-yarn/sbin/yarn-daemon.sh --config /etc/hadoop/conf stop timelineserver', + user='yarn') + self.assertResourceCalled('File', '/var/run/hadoop-yarn/yarn/yarn-yarn-timelineserver.pid', + action=['delete']) + self.assertNoMoreResources() def assert_configure_default(self): self.assertResourceCalled('Directory', '/var/run/hadoop-yarn/yarn', http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/app/app.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/app.js b/ambari-web/app/app.js index 8ff9b63..2b0e850 100644 --- a/ambari-web/app/app.js +++ b/ambari-web/app/app.js @@ -49,6 +49,19 @@ module.exports = Em.Application.create({ 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('App.router.clusterController.isLoaded'), + clusterName: null, clockDistance: null, // server clock - client clock currentStackVersion: '', http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/app/controllers/main/admin/security/add/addSecurity_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/security/add/addSecurity_controller.js b/ambari-web/app/controllers/main/admin/security/add/addSecurity_controller.js index 697c434..6fd7bc2 100644 --- a/ambari-web/app/controllers/main/admin/security/add/addSecurity_controller.js +++ b/ambari-web/app/controllers/main/admin/security/add/addSecurity_controller.js @@ -28,7 +28,12 @@ App.AddSecurityController = App.WizardController.extend({ services: [], isNnHa: 'false', serviceConfigProperties: null, - controllerName: 'addSecurityController' + controllerName: 'addSecurityController', + isATSInstalled: function() { + // Because the ATS component can be installed/removed at will, the check has to happen every time that security is added. + var yarnService = App.Service.find().findProperty('serviceName','YARN'); + return !!yarnService && yarnService.get('hostComponents').someProperty('componentName', 'APP_TIMELINE_SERVER'); + }.property('App.router.clusterController.isLoaded') }), /** http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/app/controllers/main/admin/security/add/step1.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/security/add/step1.js b/ambari-web/app/controllers/main/admin/security/add/step1.js index e6c74eb..51494c7 100644 --- a/ambari-web/app/controllers/main/admin/security/add/step1.js +++ b/ambari-web/app/controllers/main/admin/security/add/step1.js @@ -21,11 +21,12 @@ App.MainAdminSecurityAddStep1Controller = Em.Controller.extend({ name: 'mainAdminSecurityAddStep1Controller', /** - * identify whether ATS(Application Timeline Server) is installed + * identify whether ATS(Application Timeline Server) is installed and does not support Kerberization. * @return {Boolean} */ - isATSInstalled: function() { - return this.get('content.services').someProperty('serviceName', 'YARN') && - App.Service.find('YARN').get('hostComponents').someProperty('componentName', 'APP_TIMELINE_SERVER'); + shouldRemoveATS: function() { + var isATSInstalled = this.get('content.isATSInstalled'); + var doesATSSupportKerberos = App.get("doesATSSupportKerberos"); + return isATSInstalled && !doesATSSupportKerberos; } -}); \ No newline at end of file +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/app/controllers/main/admin/security/add/step3.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/security/add/step3.js b/ambari-web/app/controllers/main/admin/security/add/step3.js index 8f6fd67..43d5158 100644 --- a/ambari-web/app/controllers/main/admin/security/add/step3.js +++ b/ambari-web/app/controllers/main/admin/security/add/step3.js @@ -46,7 +46,7 @@ App.MainAdminSecurityAddStep3Controller = Em.Controller.extend({ 'STORM_UI_SERVER': 'storm_user', 'FALCON_SERVER': 'falcon_user' }, - + // The componentName, principal, and keytab have to coincide with the values in secure_properties.js componentToConfigMap: [ { componentName: 'NAMENODE', @@ -104,6 +104,20 @@ App.MainAdminSecurityAddStep3Controller = Em.Controller.extend({ keytab: 'nodemanager_http_keytab', displayName: Em.I18n.t('admin.addSecurity.nm.user.httpUser'), isHadoop2Stack: true + }, + { + componentName: 'APP_TIMELINE_SERVER', + principal: 'apptimelineserver_principal_name', + keytab: 'apptimelineserver_keytab', + displayName: Em.I18n.t('admin.addSecurity.user.yarn.atsUser'), + isHadoop2Stack: true + }, + { + componentName: 'APP_TIMELINE_SERVER', + principal: 'apptimelineserver_http_principal_name', + keytab: 'apptimelineserver_http_keytab', + displayName: Em.I18n.t('admin.addSecurity.user.yarn.atsHTTPUser'), + isHadoop2Stack: true } ], @@ -251,11 +265,20 @@ App.MainAdminSecurityAddStep3Controller = Em.Controller.extend({ */ setComponentsConfig: function (result, host, hadoopGroupId) { var hostComponents = host.get('hostComponents'); + + var isATSInstalled = this.get('content.isATSInstalled'); + var doesATSSupportKerberos = App.get("doesATSSupportKerberos"); + this.get('componentToConfigMap').forEach(function (component) { //add specific components that supported only in Hadoop2 stack if (component.isHadoop2Stack && !App.get('isHadoop2Stack')) return; if (hostComponents.someProperty('componentName', component.componentName)) { + + if (component.componentName === "APP_TIMELINE_SERVER" && (!isATSInstalled || !doesATSSupportKerberos)) { + return; + } + var configs = this.get('content.serviceConfigProperties'); var serviceName = App.StackServiceComponent.find(component.componentName).get('serviceName'); var serviceConfigs = configs.filterProperty('serviceName', serviceName); @@ -322,6 +345,9 @@ App.MainAdminSecurityAddStep3Controller = Em.Controller.extend({ var componentToOwnerMap = this.buildComponentToOwnerMap(securityUsers); var hostName = host.get('hostName'); + var isATSInstalled = this.get('content.isATSInstalled'); + var doesATSSupportKerberos = App.get("doesATSSupportKerberos"); + host.get('hostComponents').forEach(function (hostComponent) { if (componentsToDisplay.contains(hostComponent.get('componentName'))) { var serviceConfigs = configs.filterProperty('serviceName', hostComponent.get('service.serviceName')); @@ -329,6 +355,10 @@ App.MainAdminSecurityAddStep3Controller = Em.Controller.extend({ var displayName = this.changeDisplayName(hostComponent.get('displayName')); var key = hostName + "--" + secureProperties.principal; + if (hostComponent.get('componentName') === "APP_TIMELINE_SERVER" && (!isATSInstalled || !doesATSSupportKerberos)) { + return; + } + if (Em.isNone(addedPrincipalsHost[key])) { var owner = componentToOwnerMap[hostComponent.get('componentName')] || ''; http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/app/controllers/main/admin/security/add/step4.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/security/add/step4.js b/ambari-web/app/controllers/main/admin/security/add/step4.js index da599a4..406892d 100644 --- a/ambari-web/app/controllers/main/admin/security/add/step4.js +++ b/ambari-web/app/controllers/main/admin/security/add/step4.js @@ -57,8 +57,11 @@ App.MainAdminSecurityAddStep4Controller = App.MainAdminSecurityProgressControlle loadCommands: function () { this._super(); - // no need to remove ATS component if YARN and ATS are not installed - if (this.get('secureServices').findProperty('serviceName', 'YARN') && App.Service.find('YARN').get('hostComponents').someProperty('componentName', 'APP_TIMELINE_SERVER')) { + + // Determine if ATS Component needs to be removed + var isATSInstalled = this.get('content.isATSInstalled'); + var doesATSSupportKerberos = App.get("doesATSSupportKerberos"); + if (isATSInstalled && !doesATSSupportKerberos) { this.get('commands').splice(2, 0, App.Poll.create({name: 'DELETE_ATS', label: Em.I18n.translations['admin.addSecurity.apply.delete.ats'], isPolling: false})); } }, @@ -170,7 +173,7 @@ App.MainAdminSecurityAddStep4Controller = App.MainAdminSecurityProgressControlle */ onDeleteComplete: function () { var deleteAtsCommand = this.get('commands').findProperty('name', 'DELETE_ATS'); - console.warn('APP_TIMELINE_SERVER doesn\'t support security mode. It has been removed from YARN service '); + console.warn('APP_TIMELINE_SERVER doesn\'t support security mode in this HDP stack. It has been removed from YARN service '); deleteAtsCommand.set('isError', false); deleteAtsCommand.set('isSuccess', true); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/app/data/HDP2/secure_configs.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/data/HDP2/secure_configs.js b/ambari-web/app/data/HDP2/secure_configs.js index 1412eb3..da543e0 100644 --- a/ambari-web/app/data/HDP2/secure_configs.js +++ b/ambari-web/app/data/HDP2/secure_configs.js @@ -17,12 +17,25 @@ */ var App = require('app'); require('models/service_config'); +require('models/service'); + App.SecureConfigProperties = Ember.ArrayProxy.extend({ content: require('data/HDP2/secure_properties').configProperties }); var configProperties = App.SecureConfigProperties.create(); +// Dynamically create YARN properties +var yarnConfigProperties = [ + App.ServiceConfigCategory.create({ name: 'ResourceManager', displayName : 'ResourceManager'}), + App.ServiceConfigCategory.create({ name: 'NodeManager', displayName : 'NodeManager'}) +]; +var isATSInstalled = App.Service.find('YARN').get('hostComponents').someProperty('componentName', 'APP_TIMELINE_SERVER'); +var doesATSSupportKerberos = App.get("doesATSSupportKerberos"); +if (isATSInstalled && doesATSSupportKerberos) { + yarnConfigProperties.push(App.ServiceConfigCategory.create({ name: 'AppTimelineServer', displayName : 'ApplicationTimelineService'})); +} + module.exports = [ { serviceName: 'GENERAL', @@ -62,10 +75,7 @@ module.exports = [ serviceName: 'YARN', displayName: 'YARN', filename: 'yarn-site', - configCategories: [ - App.ServiceConfigCategory.create({ name: 'ResourceManager', displayName : 'ResourceManager'}), - App.ServiceConfigCategory.create({ name: 'NodeManager', displayName : 'NodeManager'}) - ], + configCategories: yarnConfigProperties, // these properties can be dynamic sites: ['yarn-site'], configs: configProperties.filterProperty('serviceName', 'YARN') }, @@ -149,6 +159,6 @@ module.exports = [ sites: ['falcon-startup.properties'], configs: configProperties.filterProperty('serviceName', 'FALCON') } +]; -]; http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/app/data/HDP2/secure_mapping.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/data/HDP2/secure_mapping.js b/ambari-web/app/data/HDP2/secure_mapping.js index a7c5695..cb92e5a 100644 --- a/ambari-web/app/data/HDP2/secure_mapping.js +++ b/ambari-web/app/data/HDP2/secure_mapping.js @@ -16,6 +16,8 @@ * limitations under the License. */ +// All of the "name" properties have to coincide with how they will appear in the *-site.xml file +// The "template" properties can come from the config properties in site_properties.js or secure_properties.js . module.exports = [ { "name": "hadoop.security.authentication", @@ -215,6 +217,49 @@ module.exports = [ "filename": "yarn-site.xml", "serviceName": "YARN" }, + // YARN Timeline Service + // These "http-authentication" properties are supported in HDP Champlain + { + "name": "yarn.timeline-service.principal", + "templateName": ["apptimelineserver_principal_name", "kerberos_domain"], + "foreignKey": null, + "value": "<templateName[0]>@<templateName[1]>", + "filename": "yarn-site.xml", + "serviceName": "YARN" + }, + { + "name": "yarn.timeline-service.keytab", + "templateName": ["apptimelineserver_keytab"], + "foreignKey": null, + "value": "<templateName[0]>", + "filename": "yarn-site.xml", + "serviceName": "YARN" + }, + { + "name": "yarn.timeline-service.http-authentication.type", + "templateName": [], + "foreignKey": null, + "value": "kerberos", + "filename": "yarn-site.xml", + "serviceName": "YARN" + }, + { + "name": "yarn.timeline-service.http-authentication.kerberos.principal", + "templateName": ["apptimelineserver_http_principal_name", "kerberos_domain"], + "foreignKey": null, + "value": "<templateName[0]>@<templateName[1]>", + "filename": "yarn-site.xml", + "serviceName": "YARN" + }, + { + "name": "yarn.timeline-service.http-authentication.kerberos.keytab", + "templateName": ["apptimelineserver_http_keytab"], + "foreignKey": null, + "value": "<templateName[0]>", + "filename": "yarn-site.xml", + "serviceName": "YARN" + }, + // YARN Resource Manager { "name": "yarn.resourcemanager.principal", "templateName": ["resourcemanager_principal_name", "kerberos_domain"], http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/app/data/HDP2/secure_properties.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/data/HDP2/secure_properties.js b/ambari-web/app/data/HDP2/secure_properties.js index ca91978..b67bf29 100644 --- a/ambari-web/app/data/HDP2/secure_properties.js +++ b/ambari-web/app/data/HDP2/secure_properties.js @@ -15,6 +15,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + + +/* + * Description of fields: + * name: has to coincide with how the property will be saved to the file + * displayName: how it will be shown in the Admin Security Wizard + * serviceName: the tab in which it will appear in the Admin Security Wizard + * filename: the file it is saved to, and the section of the command-#.json file + * category: the accordion name in the tab shown in the Admin Security Wizard + * component: Ambari component name + */ + module.exports = { "configProperties": [ @@ -458,6 +470,65 @@ module.exports = "serviceName": "YARN", "category": "ResourceManager" }, + // YARN Application Timeline Server + { + "id": "puppet var", + "name": "apptimelineserver_principal_name", + "displayName": "App Timeline Server Principal name", + "value": "", + "defaultValue": "yarn/_HOST", + "description": "Principal name for App Timeline Server. _HOST will get automatically replaced with actual hostname at an instance of App Timeline Server", + "displayType": "principal", + "isVisible": true, + "isOverridable": true, + "serviceName": "YARN", + "category": "AppTimelineServer", + "component": "APP_TIMELINE_SERVER" + }, + { + "id": "puppet var", + "name": "apptimelineserver_keytab", + "displayName": "Path to App Timeline Server keytab file", + "value": "", + "defaultValue": "/etc/security/keytabs/yarn.service.keytab", + "description": "Path to App Timeline Server keytab file", + "displayType": "directory", + "isVisible": true, + "isOverridable": true, + "serviceName": "YARN", + "category": "AppTimelineServer", + "component": "APP_TIMELINE_SERVER" + }, + { + "id": "puppet var", + "name": "apptimelineserver_http_principal_name", + "displayName": "App Timeline Server HTTP Principal name", + "value": "", + "defaultValue": "HTTP/_HOST", + "description": "Principal name for App Timeline Server HTTP. _HOST will get automatically replaced with actual hostname at an instance of App Timeline Server", + "displayType": "principal", + "isVisible": true, + "isOverridable": true, + "serviceName": "YARN", + "category": "AppTimelineServer", + "component": "APP_TIMELINE_SERVER" + }, + { + "id": "puppet var", + "name": "apptimelineserver_http_keytab", + "displayName": "Path to App Timeline Server HTTP keytab file", + "value": "", + "defaultValue": "/etc/security/keytabs/yarn.service.keytab", + "description": "Path to App Timeline Server HTTP keytab file", + "displayType": "directory", + "isVisible": true, + "isOverridable": true, + "serviceName": "YARN", + "category": "AppTimelineServer", + "component": "APP_TIMELINE_SERVER" + }, + + // YARN Resource Manager { "id": "puppet var", "name": "resourcemanager_principal_name", http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/app/messages.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js index d6829f0..9f9474a 100644 --- a/ambari-web/app/messages.js +++ b/ambari-web/app/messages.js @@ -1057,7 +1057,7 @@ Em.I18n.translations = { 'admin.security.step1.body.instruction2': 'Install and configure the Kerberos client on every host in the cluster', 'admin.security.step1.body.instruction3': 'Create Kerberos principals for Hadoop services and hosts', 'admin.security.step1.body.instruction4': 'Generate keytabs for each principal and place on the appropriate hosts', - 'admin.security.step1.body.instruction5': '<b>Application Timeline Server</b> component of YARN service will be <span class="text-error"><b>deleted</b></span> as part of enabling security', + 'admin.security.step1.body.instruction5': '<b>Application Timeline Server</b> component of YARN service will be <span class="text-error"><b>deleted</b></span> as part of enabling security in this HDP stack version', 'admin.security.step2.body.header': 'Configure Kerberos security properties', 'admin.security.step3.notice': 'You need to create Kerberos principals and keytabs before proceeding.<br />'+ 'Download the CSV file and use it to create a script to generate the principals and keytabs on specified hosts. ' + @@ -1088,6 +1088,8 @@ Em.I18n.translations = { 'admin.addSecurity.webhcat.user.httpUser': 'WebHCat SPNEGO User', 'admin.addSecurity.oozie.user.httpUser': 'Oozie SPNEGO User', 'admin.addSecurity.falcon.user.httpUser': 'Falcon SPNEGO User', + 'admin.addSecurity.user.yarn.atsUser': 'YARN ATS User', + 'admin.addSecurity.user.yarn.atsHTTPUser': 'YARN ATS HTTP User', 'admin.addSecurity.enable.onClose': 'You are in the process of enabling security on your cluster. ' + 'Are you sure you want to quit? If you quit, ' + 'you may have to re-run the security wizard from the beginning to enable security.', http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/app/routes/add_security.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/add_security.js b/ambari-web/app/routes/add_security.js index 099b752..fd43299 100644 --- a/ambari-web/app/routes/add_security.js +++ b/ambari-web/app/routes/add_security.js @@ -85,7 +85,11 @@ module.exports = App.WizardRoute.extend({ clusterName: router.get('content.cluster.name'), clusterState: 'DEFAULT', localdb: App.db.data - },{alwaysCallback: function() {self.hide();router.transitionTo('adminSecurity.index');location.reload();}}); + }, {alwaysCallback: function() { + self.hide(); + router.transitionTo('adminSecurity.index'); + location.reload(); // this is needed because the ATS Component may be deleted in older HDP stacks. + }}); }, didInsertElement: function () { this.fitHeight(); http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/app/templates/main/admin/security/add/step1.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/admin/security/add/step1.hbs b/ambari-web/app/templates/main/admin/security/add/step1.hbs index fafb40b..a8684c8 100644 --- a/ambari-web/app/templates/main/admin/security/add/step1.hbs +++ b/ambari-web/app/templates/main/admin/security/add/step1.hbs @@ -26,7 +26,7 @@ <li>{{t admin.security.step1.body.instruction2}}</li> <li>{{t admin.security.step1.body.instruction3}}</li> <li>{{t admin.security.step1.body.instruction4}}</li> - {{#if view.isATSInstalled}} + {{#if view.shouldRemoveATS}} <li>{{{t admin.security.step1.body.instruction5}}}</li> {{/if}} </ol> http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/app/views/main/admin/security/add/step1.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/admin/security/add/step1.js b/ambari-web/app/views/main/admin/security/add/step1.js index be4ea76..6ef6996 100644 --- a/ambari-web/app/views/main/admin/security/add/step1.js +++ b/ambari-web/app/views/main/admin/security/add/step1.js @@ -21,10 +21,10 @@ var App = require('app'); App.MainAdminSecurityAddStep1View = Em.View.extend({ templateName: require('templates/main/admin/security/add/step1'), - isATSInstalled: false, + shouldRemoveATS: false, didInsertElement: function(){ - var isATSInstalled = this.get('controller').isATSInstalled(); - this.set('isATSInstalled',isATSInstalled); + var shouldRemoveATS = this.get('controller').shouldRemoveATS(); + this.set('shouldRemoveATS', shouldRemoveATS); } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/c8ba5e97/ambari-web/test/controllers/main/admin/security/add/step1_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/security/add/step1_test.js b/ambari-web/test/controllers/main/admin/security/add/step1_test.js index 7672e86..56af0a0 100644 --- a/ambari-web/test/controllers/main/admin/security/add/step1_test.js +++ b/ambari-web/test/controllers/main/admin/security/add/step1_test.js @@ -28,21 +28,21 @@ describe('App.MainAdminSecurityAddStep1Controller', function () { content: {} }); - describe('#isATSInstalled()', function() { + describe('#shouldRemoveATS()', function() { it('content.services is empty', function() { controller.set('content.services', []); - expect(controller.isATSInstalled()).to.be.false; + expect(controller.shouldRemoveATS()).to.be.false; }); it('content.services does not contain YARN', function() { controller.set('content.services', [{serviceName: 'HDFS'}]); - expect(controller.isATSInstalled()).to.be.false; + expect(controller.shouldRemoveATS()).to.be.false; }); it('YARN does not have ATS', function() { sinon.stub(App.Service, 'find', function(){ return Em.Object.create({hostComponents: []}) }); controller.set('content.services', [{serviceName: 'YARN'}]); - expect(controller.isATSInstalled()).to.be.false; + expect(controller.shouldRemoveATS()).to.be.false; App.Service.find.restore(); }); it('YARN has ATS', function() { @@ -52,7 +52,7 @@ describe('App.MainAdminSecurityAddStep1Controller', function () { }]}) }); controller.set('content.services', [{serviceName: 'YARN'}]); - expect(controller.isATSInstalled()).to.be.true; + expect(controller.shouldRemoveATS()).to.be.true; App.Service.find.restore(); }); });