You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by ta...@apache.org on 2019/02/19 18:29:02 UTC

[impala] 05/08: IMPALA-7130: impala-shell -b / --kerberos_host_fqdn flag overrides value passed in via -i / --impalad

This is an automated email from the ASF dual-hosted git repository.

tarmstrong pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/impala.git

commit a8d2f2fe2f31dd04bd0e3731ef7f452bd061e5f2
Author: Vincent Tran <vt...@cloudera.com>
AuthorDate: Fri Jun 1 18:49:40 2018 -0400

    IMPALA-7130: impala-shell -b / --kerberos_host_fqdn flag overrides value passed in via -i / --impalad
    
    After additional testing around IMPALA-2782, it was discovered
    that impala-shell starts the session displaying the expected
    hostname (as passed -i flag) on the prompt. This gives the
    impression that the load balancer was bypassed, however the
    actual TSSLSocket is still created with the hostname passed
    in via the -b or --kerberos_host_fqdn flag.
    
    This change ensures that the hostname used to create the
    TSSLSocket will always be the one passed in via the -i flag
    on impala-shell. This change is required by IMPALA-2782.
    
    Testing:
    Using netcat, we verified that the impala daemon host[:port]
    value passed into the -i/--impalad option is indeed the one
    impala-shell tries to connect to in both cases (with and
    without -b)
    
    Change-Id: Ibee05bd0dbe8c6ae108b890f0ae0f6900149773a
    Reviewed-on: http://gerrit.cloudera.org:8080/10580
    Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 shell/impala_client.py                | 23 ++++++++++++++---------
 tests/shell/test_shell_commandline.py | 35 ++++++++++++++++++++++++++++++++++-
 2 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/shell/impala_client.py b/shell/impala_client.py
index 5fa50b0..69c7699 100755
--- a/shell/impala_client.py
+++ b/shell/impala_client.py
@@ -63,7 +63,8 @@ class ImpalaClient(object):
                kerberos_service_name="impala", use_ssl=False, ca_cert=None, user=None,
                ldap_password=None, use_ldap=False):
     self.connected = False
-    self.impalad = impalad
+    self.impalad_host = impalad[0].encode('ascii', 'ignore')
+    self.impalad_port = int(impalad[1])
     self.kerberos_host_fqdn = kerberos_host_fqdn
     self.imp_service = None
     self.transport = None
@@ -278,28 +279,32 @@ class ImpalaClient(object):
     # sasl does not accept unicode strings, explicitly encode the string into ascii.
     # The kerberos_host_fqdn option exposes the SASL client's hostname attribute to
     # the user. impala-shell checks to ensure this host matches the host in the kerberos
-    # principal. So in the presence of a load balancer, the its hostname is expected by
+    # principal. So when a load balancer is configured to be used, its hostname is expected by
     # impala-shell. Setting this option to the load balancer hostname allows impala-shell to
     # connect directly to an impalad.
     if self.kerberos_host_fqdn is not None:
-      host, port = (self.kerberos_host_fqdn.split(':')[0].encode('ascii', 'ignore'),
-            int(self.impalad[1]))
+      sasl_host = self.kerberos_host_fqdn.split(':')[0].encode('ascii', 'ignore')
     else:
-      host, port = self.impalad[0].encode('ascii', 'ignore'), int(self.impalad[1])
+      sasl_host = self.impalad_host
+
+    # Always use the hostname and port passed in to -i / --impalad as the host for the purpose of
+    # creating the actual socket.
+    sock_host = self.impalad_host
+    sock_port = self.impalad_port
     if self.use_ssl:
       if self.ca_cert is None:
         # No CA cert means don't try to verify the certificate
-        sock = TSSLSocketWithWildcardSAN(host, port, validate=False)
+        sock = TSSLSocketWithWildcardSAN(sock_host, sock_port, validate=False)
       else:
-        sock = TSSLSocketWithWildcardSAN(host, port, validate=True, ca_certs=self.ca_cert)
+        sock = TSSLSocketWithWildcardSAN(sock_host, sock_port, validate=True, ca_certs=self.ca_cert)
     else:
-      sock = TSocket(host, port)
+      sock = TSocket(sock_host, sock_port)
     if not (self.use_ldap or self.use_kerberos):
       return TBufferedTransport(sock)
     # Initializes a sasl client
     def sasl_factory():
       sasl_client = sasl.Client()
-      sasl_client.setAttr("host", host)
+      sasl_client.setAttr("host", sasl_host)
       if self.use_ldap:
         sasl_client.setAttr("username", self.user)
         sasl_client.setAttr("password", self.ldap_password)
diff --git a/tests/shell/test_shell_commandline.py b/tests/shell/test_shell_commandline.py
index 5fec7fb..aa936ac 100644
--- a/tests/shell/test_shell_commandline.py
+++ b/tests/shell/test_shell_commandline.py
@@ -21,8 +21,9 @@ import os
 import pytest
 import re
 import signal
+import shlex
 
-from subprocess import call
+from subprocess import call, Popen, PIPE
 from tests.common.impala_service import ImpaladService
 from tests.common.impala_test_suite import ImpalaTestSuite
 from tests.common.skip import SkipIf
@@ -609,3 +610,35 @@ class TestImpalaShell(ImpalaTestSuite):
   def test_missing_query_file(self):
     result = run_impala_shell_cmd('-f nonexistent.sql', expect_success=False)
     assert "Could not open file 'nonexistent.sql'" in result.stderr
+
+  def test_socket_opening(self):
+    ''' Tests that the impala daemon will always open a socket against
+    the host[:port] specified by the -i option with or without the
+    -b option '''
+
+    impala_daemon_port = 42000
+    load_balancer_fqdn = "my-load-balancer.local"
+    ncat_timeout = 1
+    # Building an one-off shell cmd instead of using Util::ImpalaShell since we need
+    # to customize the impala daemon socket
+    shell_cmd =  "%s/bin/impala-shell.sh" % (os.environ['IMPALA_HOME'])
+    args1 = "-i localhost:%d" % (impala_daemon_port,)
+    args2 = "-b %s" % (load_balancer_fqdn,)
+
+    # Verify that impala-shell tries to create a socket again localhost:42000 as
+    # specified by -i option without the -b option
+    impalad_sock = Popen(shlex.split("nc -lp %d -w %d" % (impala_daemon_port, ncat_timeout,)),
+                            stdout = PIPE, stderr = PIPE)
+    impala_shell = Popen(shlex.split("%s %s" % (shell_cmd, args1, )))
+    impalad_sock_stdout, impalad_sock_stderr = impalad_sock.communicate()
+    expected_output = "PingImpalaService"
+    assert expected_output in impalad_sock_stdout
+
+    # Verify that impala-shell tries to create a socket again localhost:42000 as
+    # specified by -i option with the -b option
+
+    impalad_sock = Popen(shlex.split("nc -lp %d -w %d" % (impala_daemon_port, ncat_timeout,)),
+                            stdout = PIPE, stderr = PIPE)
+    impala_shell = Popen(shlex.split("%s %s %s" % (shell_cmd, args1, args2, )))
+    impalad_sock_stdout, impalad_sock_stderr = impalad_sock.communicate()
+    assert expected_output in impalad_sock_stdout