You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2015/01/07 12:45:48 UTC

ambari git commit: AMBARI-8487. Oozie service components should indicate security state (rlevas)

Repository: ambari
Updated Branches:
  refs/heads/trunk 53c391541 -> b0e587e42


AMBARI-8487. Oozie service components should indicate security state (rlevas)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b0e587e4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b0e587e4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b0e587e4

Branch: refs/heads/trunk
Commit: b0e587e42ad8e0c9acbbc9b643581e6a98e13652
Parents: 53c3915
Author: Robert Levas <rl...@hortonworks.com>
Authored: Wed Jan 7 06:45:29 2015 -0500
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Wed Jan 7 06:45:29 2015 -0500

----------------------------------------------------------------------
 .../4.0.0.2.0/package/scripts/oozie_server.py   |  70 +++++++++++-
 .../4.0.0.2.0/package/scripts/oozie_service.py  |  10 +-
 .../OOZIE/4.0.0.2.0/package/scripts/params.py   |   2 +-
 .../4.0.0.2.0/package/scripts/status_params.py  |   7 ++
 .../stacks/2.0.6/OOZIE/test_oozie_server.py     | 111 +++++++++++++++++++
 5 files changed, 197 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/b0e587e4/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server.py b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server.py
index f07e36d..61615d2 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_server.py
@@ -20,6 +20,9 @@ limitations under the License.
 
 import sys
 from resource_management import *
+from resource_management.libraries.functions.security_commons import build_expectations, \
+  cached_kinit_executor, get_params_from_filesystem, validate_security_config_properties, \
+  FILE_TYPE_XML
 
 from oozie import oozie
 from oozie_service import oozie_service
@@ -51,6 +54,71 @@ class OozieServer(Script):
     import status_params
     env.set_params(status_params)
     check_process_status(status_params.pid_file)
-    
+
+
+  def security_status(self, env):
+
+    import status_params
+    env.set_params(status_params)
+
+    if status_params.security_enabled:
+      expectations = {
+        "oozie-site":
+          build_expectations('oozie-site',
+                             {
+                               "oozie.authentication.type": "kerberos",
+                               "oozie.service.AuthorizationService.security.enabled": "true",
+                               "oozie.service.HadoopAccessorService.kerberos.enabled": "true"
+                             },
+                             [
+                               "local.realm",
+                               "oozie.authentication.kerberos.principal",
+                               "oozie.authentication.kerberos.keytab",
+                               "oozie.service.HadoopAccessorService.kerberos.principal",
+                               "oozie.service.HadoopAccessorService.keytab.file"
+                             ],
+                             None)
+      }
+
+      security_params = get_params_from_filesystem(status_params.conf_dir,
+                                                   {'oozie-site.xml': FILE_TYPE_XML})
+      result_issues = validate_security_config_properties(security_params, expectations)
+      if not result_issues: # If all validations passed successfully
+        try:
+          # Double check the dict before calling execute
+          if ('oozie-site' not in security_params
+              or 'oozie.authentication.kerberos.principal' not in security_params['oozie-site']
+              or 'oozie.authentication.kerberos.keytab' not in security_params['oozie-site']
+              or 'oozie.service.HadoopAccessorService.kerberos.principal' not in security_params['oozie-site']
+              or 'oozie.service.HadoopAccessorService.keytab.file' not in security_params['oozie-site']):
+            self.put_structured_out({"securityState": "UNSECURED"})
+            self.put_structured_out({"securityIssuesFound": "Keytab file or principal are not set property."})
+            return
+
+          cached_kinit_executor(status_params.kinit_path_local,
+                                status_params.oozie_user,
+                                security_params['oozie-site']['oozie.authentication.kerberos.keytab'],
+                                security_params['oozie-site']['oozie.authentication.kerberos.principal'],
+                                status_params.hostname,
+                                status_params.tmp_dir)
+          cached_kinit_executor(status_params.kinit_path_local,
+                                status_params.oozie_user,
+                                security_params['oozie-site']['oozie.service.HadoopAccessorService.keytab.file'],
+                                security_params['oozie-site']['oozie.service.HadoopAccessorService.kerberos.principal'],
+                                status_params.hostname,
+                                status_params.tmp_dir)
+          self.put_structured_out({"securityState": "SECURED_KERBEROS"})
+        except Exception as e:
+          self.put_structured_out({"securityState": "ERROR"})
+          self.put_structured_out({"securityStateErrorInfo": str(e)})
+      else:
+        issues = []
+        for cf in result_issues:
+          issues.append("Configuration file %s did not pass the validation. Reason: %s" % (cf, result_issues[cf]))
+        self.put_structured_out({"securityIssuesFound": ". ".join(issues)})
+        self.put_structured_out({"securityState": "UNSECURED"})
+    else:
+      self.put_structured_out({"securityState": "UNSECURED"})
+
 if __name__ == "__main__":
   OozieServer().execute()

http://git-wip-us.apache.org/repos/asf/ambari/blob/b0e587e4/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_service.py b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_service.py
index c03f944..59966fd 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_service.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/oozie_service.py
@@ -23,7 +23,15 @@ from resource_management import *
 def oozie_service(action = 'start'): # 'start' or 'stop'
   import params
 
-  kinit_if_needed = format("{kinit_path_local} -kt {oozie_keytab} {oozie_principal};") if params.security_enabled else ""
+  if params.security_enabled:
+    if params.oozie_principal is None:
+      oozie_principal_with_host = 'missing_principal'
+    else:
+      oozie_principal_with_host = params.oozie_principal.replace("_HOST", params.hostname)
+    kinit_if_needed = format("{kinit_path_local} -kt {oozie_keytab} {oozie_principal_with_host};")
+  else:
+    kinit_if_needed = ""
+
   no_op_test = format("ls {pid_file} >/dev/null 2>&1 && ps -p `cat {pid_file}` >/dev/null 2>&1")
   
   if action == 'start':

http://git-wip-us.apache.org/repos/asf/ambari/blob/b0e587e4/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params.py b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params.py
index 3755666..a3d3a2a 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/params.py
@@ -87,7 +87,7 @@ kinit_path_local = functions.get_kinit_path(["/usr/bin", "/usr/kerberos/bin", "/
 oozie_service_keytab = config['configurations']['oozie-site']['oozie.service.HadoopAccessorService.keytab.file']
 oozie_principal = config['configurations']['oozie-site']['oozie.service.HadoopAccessorService.kerberos.principal']
 smokeuser_keytab = config['configurations']['cluster-env']['smokeuser_keytab']
-oozie_keytab = config['configurations']['oozie-env']['oozie_keytab']
+oozie_keytab = default("/configurations/oozie-env/oozie_keytab", oozie_service_keytab)
 oozie_env_sh_template = config['configurations']['oozie-env']['content']
 
 oracle_driver_jar_name = "ojdbc6.jar"

http://git-wip-us.apache.org/repos/asf/ambari/blob/b0e587e4/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/status_params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/status_params.py b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/status_params.py
index a665449..f66448d 100644
--- a/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/status_params.py
+++ b/ambari-server/src/main/resources/common-services/OOZIE/4.0.0.2.0/package/scripts/status_params.py
@@ -24,3 +24,10 @@ config = Script.get_config()
 
 oozie_pid_dir = config['configurations']['oozie-env']['oozie_pid_dir']
 pid_file = format("{oozie_pid_dir}/oozie.pid")
+
+security_enabled = config['configurations']['cluster-env']['security_enabled']
+kinit_path_local = functions.get_kinit_path(["/usr/bin", "/usr/kerberos/bin", "/usr/sbin"])
+conf_dir = "/etc/oozie/conf"
+tmp_dir = Script.get_tmp_dir()
+oozie_user = config['configurations']['oozie-env']['oozie_user']
+hostname = config["hostname"]

http://git-wip-us.apache.org/repos/asf/ambari/blob/b0e587e4/ambari-server/src/test/python/stacks/2.0.6/OOZIE/test_oozie_server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/OOZIE/test_oozie_server.py b/ambari-server/src/test/python/stacks/2.0.6/OOZIE/test_oozie_server.py
index 1fa2677..4324040 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/OOZIE/test_oozie_server.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/OOZIE/test_oozie_server.py
@@ -481,4 +481,115 @@ class TestOozieServer(RMFTestCase):
       self.assertNoMoreResources()
 
 
+  @patch("resource_management.libraries.functions.security_commons.build_expectations")
+  @patch("resource_management.libraries.functions.security_commons.get_params_from_filesystem")
+  @patch("resource_management.libraries.functions.security_commons.validate_security_config_properties")
+  @patch("resource_management.libraries.functions.security_commons.cached_kinit_executor")
+  @patch("resource_management.libraries.script.Script.put_structured_out")
+  def test_security_status(self, put_structured_out_mock, cached_kinit_executor_mock, validate_security_config_mock, get_params_mock, build_exp_mock):
+    # Test that function works when is called with correct parameters
+    security_params = {
+      "oozie-site": {
+        "oozie.authentication.type": "kerberos",
+        "oozie.service.AuthorizationService.security.enabled": "true",
+        "oozie.service.HadoopAccessorService.kerberos.enabled": "true",
+        "local.realm": "EXAMPLE.COM",
+        "oozie.authentication.kerberos.principal": "principal",
+        "oozie.authentication.kerberos.keytab": "/path/to_keytab",
+        "oozie.service.HadoopAccessorService.kerberos.principal": "principal",
+        "oozie.service.HadoopAccessorService.keytab.file": "/path/to_keytab"}
+    }
 
+    result_issues = []
+    props_value_check = {"oozie.authentication.type": "kerberos",
+                         "oozie.service.AuthorizationService.security.enabled": "true",
+                         "oozie.service.HadoopAccessorService.kerberos.enabled": "true"}
+    props_empty_check = [ "local.realm",
+                          "oozie.authentication.kerberos.principal",
+                          "oozie.authentication.kerberos.keytab",
+                          "oozie.service.HadoopAccessorService.kerberos.principal",
+                          "oozie.service.HadoopAccessorService.keytab.file"]
+    props_read_check = None
+
+    get_params_mock.return_value = security_params
+    validate_security_config_mock.return_value = result_issues
+
+    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/oozie_server.py",
+                       classname = "OozieServer",
+                       command = "security_status",
+                       config_file="secured.json",
+                       hdp_stack_version = self.STACK_VERSION,
+                       target = RMFTestCase.TARGET_COMMON_SERVICES
+    )
+
+    import status_params
+
+    get_params_mock.assert_called_with(status_params.conf_dir, {'oozie-site.xml': 'XML'})
+    build_exp_mock.assert_called_with('oozie-site', props_value_check, props_empty_check, props_read_check)
+    put_structured_out_mock.assert_called_with({"securityState": "SECURED_KERBEROS"})
+    self.assertTrue(cached_kinit_executor_mock.call_count, 2)
+    cached_kinit_executor_mock.assert_called_with(status_params.kinit_path_local,
+                                                  status_params.oozie_user,
+                                                  security_params['oozie-site']['oozie.service.HadoopAccessorService.keytab.file'],
+                                                  security_params['oozie-site']['oozie.service.HadoopAccessorService.kerberos.principal'],
+                                                  status_params.hostname,
+                                                  status_params.tmp_dir)
+
+    # Testing that the exception throw by cached_executor is caught
+    cached_kinit_executor_mock.reset_mock()
+    cached_kinit_executor_mock.side_effect = Exception("Invalid command")
+
+    try:
+      self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/oozie_server.py",
+                         classname = "OozieServer",
+                         command = "security_status",
+                         config_file="secured.json",
+                         hdp_stack_version = self.STACK_VERSION,
+                         target = RMFTestCase.TARGET_COMMON_SERVICES
+      )
+    except:
+      self.assertTrue(True)
+
+    # Testing with a security_params which doesn't contains oozie-site
+    empty_security_params = {}
+    cached_kinit_executor_mock.reset_mock()
+    get_params_mock.reset_mock()
+    put_structured_out_mock.reset_mock()
+    get_params_mock.return_value = empty_security_params
+
+    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/oozie_server.py",
+                       classname = "OozieServer",
+                       command = "security_status",
+                       config_file="secured.json",
+                       hdp_stack_version = self.STACK_VERSION,
+                       target = RMFTestCase.TARGET_COMMON_SERVICES
+    )
+    put_structured_out_mock.assert_called_with({"securityIssuesFound": "Keytab file or principal are not set property."})
+
+    # Testing with not empty result_issues
+    result_issues_with_params = {}
+    result_issues_with_params['oozie-site']="Something bad happened"
+
+    validate_security_config_mock.reset_mock()
+    get_params_mock.reset_mock()
+    validate_security_config_mock.return_value = result_issues_with_params
+    get_params_mock.return_value = security_params
+
+    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/oozie_server.py",
+                       classname = "OozieServer",
+                       command = "security_status",
+                       config_file="secured.json",
+                       hdp_stack_version = self.STACK_VERSION,
+                       target = RMFTestCase.TARGET_COMMON_SERVICES
+    )
+    put_structured_out_mock.assert_called_with({"securityState": "UNSECURED"})
+
+    # Testing with security_enable = false
+    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/oozie_server.py",
+                       classname = "OozieServer",
+                       command = "security_status",
+                       config_file="default.json",
+                       hdp_stack_version = self.STACK_VERSION,
+                       target = RMFTestCase.TARGET_COMMON_SERVICES
+    )
+    put_structured_out_mock.assert_called_with({"securityState": "UNSECURED"})