Эх сурвалжийг харах

HUE-1045 [beeswax] Beeswax host selection sasl

Beeswax should choose the hostname provided as the instance component
of the hive kerberos principal when communicating to the metastore.
Abraham Elmahrek 12 жил өмнө
parent
commit
fa4c985

+ 12 - 12
apps/beeswax/src/beeswax/hive_site.py

@@ -23,6 +23,8 @@ import logging
 import os.path
 import re
 
+from desktop.lib import security_util
+
 import beeswax.conf
 from hadoop import confparse
 
@@ -57,7 +59,6 @@ def get_conf():
     _parse_hive_site()
   return _HIVE_SITE_DICT
 
-
 def get_metastore():
   """
   get_metastore() -> (is_local, host, port, kerberos_principal)
@@ -71,23 +72,22 @@ def get_metastore():
   """
   global _METASTORE_LOC_CACHE
   if not _METASTORE_LOC_CACHE:
-    is_local = get_conf().getbool(_CNF_METASTORE_LOCAL, True)
-    kerberos_principal = get_conf().get(_CNF_METASTORE_KERBEROS_PRINCIPAL, None)
+    kerberos_principal = security_util.get_kerberos_principal(get_conf().get(_CNF_METASTORE_KERBEROS_PRINCIPAL, None))
+    kerberos_principal_components = security_util.get_components(kerberos_principal)
+    thrift_uri = get_conf().get(_CNF_METASTORE_URIS)
+    is_local = thrift_uri is None or thrift_uri == ''
     if is_local:
       host = beeswax.conf.BEESWAX_META_SERVER_HOST.get()
       port = beeswax.conf.BEESWAX_META_SERVER_PORT.get()
     else:
-      thrift_uri = get_conf().get(_CNF_METASTORE_URIS)
       host, port = 'undefined', '0'
-      if thrift_uri is None:
-        LOG.fatal('Remote metastore uri ("%s") not found in hive config %s' %
-                  (_CNF_METASTORE_URIS, _HIVE_SITE_PATH))
+      match = _THRIFT_URI_RE.match(thrift_uri)
+      if not match:
+        LOG.fatal('Cannot understand remote metastore uri "%s"' % (thrift_uri,))
       else:
-        match = _THRIFT_URI_RE.match(thrift_uri)
-        if not match:
-          LOG.fatal('Cannot understand remote metastore uri "%s"' % (thrift_uri,))
-        else:
-          host, port = match.groups()
+        host, port = match.groups()
+      if len(kerberos_principal_components) == 3:
+        host = kerberos_principal_components[1]
     _METASTORE_LOC_CACHE = (is_local, host, int(port), kerberos_principal)
   return _METASTORE_LOC_CACHE
 

+ 1 - 1
apps/beeswax/src/beeswax/server/beeswax_lib.py

@@ -383,9 +383,9 @@ class BeeswaxClient:
         self._encode_partition(new_part)
         return self._client.alter_partition(db_name, tbl_name, new_part)
 
+    # Use service name from kerberos principal set in hive-site.xml
     _, host, port, metastore_kerberos_principal = hive_site.get_metastore()
     use_sasl, kerberos_principal_short_name = BeeswaxClient.get_security()
-    # Use service name from kerberos principal set in hive-site.xml
     kerberos_principal_short_name = metastore_kerberos_principal and metastore_kerberos_principal.split('/', 1)[0] or None
     client = thrift_util.get_client(ThriftHiveMetastore.Client,
                                     host,

+ 48 - 0
desktop/core/src/desktop/lib/security_util.py

@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+# Licensed to Cloudera, Inc. under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  Cloudera, Inc. 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.
+
+import re
+import socket
+
+# Pattern to replace with hostname
+HOSTNAME_PATTERN = '_HOST'
+
+
+def get_kerberos_principal(principal, host=None):
+  components = get_components(principal)
+  if not components or len(components) != 3 or components[1] != HOSTNAME_PATTERN:
+    return principal
+
+
+def get_components(principal):
+  """
+  get_components(principal) -> (short name, instance (FQDN), realm)
+
+  ``principal`` is the kerberos principal to parse.
+  """
+  if not principal:
+    return None
+  return re.split('[\/@]', str(principal))
+
+def replace_hostname_pattern(components, host):
+  fqdn = host
+  if not fqdn or fqdn == '0.0.0.0':
+    fqdn = get_localhost_name()
+  return '%s/%s@%s' % (components[0], fqdn.lowercase(), components[2])
+
+def get_localhost_name():
+  return socket.get_localhost()

+ 0 - 0
desktop/core/src/desktop/lib/security_util_test.py