示例#1
0
    hbase_home = format("{stack_root}/current/hbase-client")
    hive_home = format("{stack_root}/current/hive-client")
    sqoop_bin_dir = format("{stack_root}/current/sqoop-client/bin/")
    zoo_conf_dir = format("{stack_root}/current/zookeeper-client/conf")

security_enabled = config['configurations']['cluster-env']['security_enabled']
smokeuser = config['configurations']['cluster-env']['smokeuser']
smokeuser_principal = config['configurations']['cluster-env'][
    'smokeuser_principal_name']
user_group = config['configurations']['cluster-env']['user_group']
sqoop_env_sh_template = config['configurations']['sqoop-env']['content']

sqoop_user = config['configurations']['sqoop-env']['sqoop_user']

smoke_user_keytab = config['configurations']['cluster-env']['smokeuser_keytab']
kinit_path_local = get_kinit_path(
    default('/configurations/kerberos-env/executable_search_paths', None))
#JDBC driver jar name
sqoop_jdbc_drivers_dict = []
sqoop_jdbc_drivers_name_dict = {}
if "jdbc_drivers" in config['configurations']['sqoop-env']:
    sqoop_jdbc_drivers = config['configurations']['sqoop-env'][
        'jdbc_drivers'].split(',')

    for driver_name in sqoop_jdbc_drivers:
        driver_name = driver_name.strip()
        if driver_name and not driver_name == '':
            if driver_name == "com.microsoft.sqlserver.jdbc.SQLServerDriver":
                jdbc_name = default("/hostLevelParams/custom_mssql_jdbc_name",
                                    None)
                jdbc_driver_name = "mssql"
            elif driver_name == "com.mysql.jdbc.Driver":
示例#2
0
def curl_krb_request(tmp_dir,
                     keytab,
                     principal,
                     url,
                     cache_file_prefix,
                     krb_exec_search_paths,
                     return_only_http_code,
                     caller_label,
                     user,
                     connection_timeout=CONNECTION_TIMEOUT_DEFAULT,
                     ca_certs=None,
                     kinit_timer_ms=DEFAULT_KERBEROS_KINIT_TIMER_MS,
                     method='',
                     body='',
                     header=''):
    """
    Makes a curl request using the kerberos credentials stored in a calculated cache file. The
    cache file is created by combining the supplied principal, keytab, user, and request name into
    a unique hash.

    This function will use the klist command to determine if the cache is expired and will perform
    a kinit if necessary. Additionally, it has an internal timer to force a kinit after a
    configurable amount of time. This is to prevent boundary issues where requests hit the edge
    of a ticket's lifetime.

    :param tmp_dir: the directory to use for storing the local kerberos cache for this request.
    :param keytab: the location of the keytab to use when performing a kinit
    :param principal: the principal to use when performing a kinit
    :param url: the URL to request
    :param cache_file_prefix: an identifier used to build the unique cache name for this request.
                              This ensures that multiple requests can use the same cache.
    :param krb_exec_search_paths: the search path to use for invoking kerberos binaries
    :param return_only_http_code: True to return only the HTTP code, False to return GET content
    :param caller_label: an identifier to give context into the caller of this module (used for logging)
    :param user: the user to invoke the curl command as
    :param connection_timeout: if specified, a connection timeout for curl (default 10 seconds)
    :param ca_certs: path to certificates
    :param kinit_timer_ms: if specified, the time (in ms), before forcing a kinit even if the
                           klist cache is still valid.
    :return:
    """

    import uuid
    # backward compatibility with old code and management packs, etc. All new code need pass ca_certs explicitly
    if ca_certs is None:
        try:
            from ambari_agent.AmbariConfig import AmbariConfig
            ca_certs = AmbariConfig.get_resolved_config(
            ).get_ca_cert_file_path()
        except:
            pass
    # start off false
    is_kinit_required = False

    # Create the kerberos credentials cache (ccache) file and set it in the environment to use
    # when executing curl. Use the md5 hash of the combination of the principal and keytab file
    # to generate a (relatively) unique cache filename so that we can use it as needed. Scope
    # this file by user in order to prevent sharing of cache files by multiple users.
    ccache_file_name = _md5("{0}|{1}".format(principal, keytab)).hexdigest()

    curl_krb_cache_path = os.path.join(tmp_dir, "curl_krb_cache")
    if not os.path.exists(curl_krb_cache_path):
        os.makedirs(curl_krb_cache_path)
    os.chmod(curl_krb_cache_path, 0777)

    ccache_file_path = "{0}{1}{2}_{3}_cc_{4}".format(curl_krb_cache_path,
                                                     os.sep, cache_file_prefix,
                                                     user, ccache_file_name)
    kerberos_env = {'KRB5CCNAME': ccache_file_path}

    # concurrent kinit's can cause the following error:
    # Internal credentials cache error while storing credentials while getting initial credentials
    kinit_lock = global_lock.get_lock(global_lock.LOCK_TYPE_KERBEROS)
    kinit_lock.acquire()
    try:
        # If there are no tickets in the cache or they are expired, perform a kinit, else use what
        # is in the cache
        if krb_exec_search_paths:
            klist_path_local = get_klist_path(krb_exec_search_paths)
        else:
            klist_path_local = get_klist_path()

        # take a look at the last time kinit was run for the specified cache and force a new
        # kinit if it's time; this helps to avoid problems approaching ticket boundary when
        # executing a klist and then a curl
        last_kinit_time = _KINIT_CACHE_TIMES.get(ccache_file_name, 0)
        current_time = long(time.time())
        if current_time - kinit_timer_ms > last_kinit_time:
            is_kinit_required = True

        # if the time has not expired, double-check that the cache still has a valid ticket
        if not is_kinit_required:
            klist_command = "{0} -s {1}".format(klist_path_local,
                                                ccache_file_path)
            is_kinit_required = (shell.call(klist_command, user=user)[0] != 0)

        # if kinit is required, the perform the kinit
        if is_kinit_required:
            if krb_exec_search_paths:
                kinit_path_local = get_kinit_path(krb_exec_search_paths)
            else:
                kinit_path_local = get_kinit_path()

            logger.debug(
                "Enabling Kerberos authentication for %s via GSSAPI using ccache at %s",
                caller_label, ccache_file_path)

            # kinit; there's no need to set a ticket timeout as this will use the default invalidation
            # configured in the krb5.conf - regenerating keytabs will not prevent an existing cache
            # from working correctly
            shell.checked_call("{0} -c {1} -kt {2} {3} > /dev/null".format(
                kinit_path_local, ccache_file_path, keytab, principal),
                               user=user)

            # record kinit time
            _KINIT_CACHE_TIMES[ccache_file_name] = current_time
        else:
            # no kinit needed, use the cache
            logger.debug(
                "Kerberos authentication for %s via GSSAPI already enabled using ccache at %s.",
                caller_label, ccache_file_path)
    finally:
        kinit_lock.release()

    # check if cookies dir exists, if not then create it
    cookies_dir = os.path.join(tmp_dir, "cookies")

    if not os.path.exists(cookies_dir):
        os.makedirs(cookies_dir)

    cookie_file_name = str(uuid.uuid4())
    cookie_file = os.path.join(cookies_dir, cookie_file_name)

    start_time = time.time()
    error_msg = None

    # setup timeouts for the request; ensure we use integers since that is what curl needs
    connection_timeout = int(connection_timeout)
    maximum_timeout = connection_timeout + 2

    ssl_options = ['-k']
    if ca_certs:
        ssl_options = ['--cacert', ca_certs]
    try:
        if return_only_http_code:
            _, curl_stdout, curl_stderr = get_user_call_output(
                ['curl', '--location-trusted'] + ssl_options + [
                    '-u', admin_username + ':' + admin_password, '-b',
                    cookie_file, '-c', cookie_file, '-w', '%{http_code}', url,
                    '--connect-timeout',
                    str(connection_timeout), '--max-time',
                    str(maximum_timeout), '-o', '/dev/null'
                ],
                user=user,
                env=kerberos_env)
        else:
            curl_command = ['curl', '--location-trusted'] + ssl_options + [
                '--negotiate', '-u', admin_username + ':' + admin_password,
                '-b', cookie_file, '-c', cookie_file, url, '--connect-timeout',
                str(connection_timeout), '--max-time',
                str(maximum_timeout)
            ]
            # returns response body
            if len(method) > 0 and len(body) == 0 and len(header) == 0:
                curl_command.extend(['-X', method])

            elif len(method) > 0 and len(body) == 0 and len(header) > 0:
                curl_command.extend(['-H', header, '-X', method])

            elif len(method) > 0 and len(body) > 0 and len(header) == 0:
                curl_command.extend(['-X', method, '-d', body])

            elif len(method) > 0 and len(body) > 0 and len(header) > 0:
                curl_command.extend(['-H', header, '-X', method, '-d', body])

            _, curl_stdout, curl_stderr = get_user_call_output(
                curl_command, user=user, env=kerberos_env)

    except Fail:
        if logger.isEnabledFor(logging.DEBUG):
            logger.exception(
                "Unable to make a curl request for {0}.".format(caller_label))
        raise
    finally:
        if os.path.isfile(cookie_file):
            os.remove(cookie_file)

    # empty quotes evaluates to false
    if curl_stderr:
        error_msg = curl_stderr

    time_millis = time.time() - start_time

    # empty quotes evaluates to false
    if curl_stdout:
        if return_only_http_code:
            return (int(curl_stdout), error_msg, time_millis)
        else:
            return (curl_stdout, error_msg, time_millis)

    logger.debug("The curl response for %s is empty; standard error = %s",
                 caller_label, str(error_msg))

    return ("", error_msg, time_millis)
  hadoop_home = '/usr/hdp/current/hbase-client'
  hbase_home = '/usr/hdp/current/hbase-client'
  hive_home = '/usr/hdp/current/hive-client'
  sqoop_bin_dir = '/usr/hdp/current/sqoop-client/bin/'
  zoo_conf_dir = "/usr/hdp/current/zookeeper-client/conf"

security_enabled = config['configurations']['cluster-env']['security_enabled']
smokeuser = config['configurations']['cluster-env']['smokeuser']
smokeuser_principal = config['configurations']['cluster-env']['smokeuser_principal_name']
user_group = config['configurations']['cluster-env']['user_group']
sqoop_env_sh_template = config['configurations']['sqoop-env']['content']

sqoop_user = config['configurations']['sqoop-env']['sqoop_user']

smoke_user_keytab = config['configurations']['cluster-env']['smokeuser_keytab']
kinit_path_local = get_kinit_path(default('/configurations/kerberos-env/executable_search_paths', None))
#JDBC driver jar name
sqoop_jdbc_drivers_dict = {}
sqoop_jdbc_drivers_name_dict = {}
if "jdbc_drivers" in config['configurations']['sqoop-env']:
  sqoop_jdbc_drivers = config['configurations']['sqoop-env']['jdbc_drivers'].split(',')

  for driver_name in sqoop_jdbc_drivers:
    driver_name = driver_name.strip()
    if driver_name and not driver_name == '':
      if driver_name == "com.microsoft.sqlserver.jdbc.SQLServerDriver":
        jdbc_jar_name = "sqljdbc4.jar"
        jdbc_symlink_name = "mssql-jdbc-driver.jar"
        jdbc_driver_name = "mssql"
      elif driver_name == "com.mysql.jdbc.Driver":
        jdbc_jar_name = "mysql-connector-java.jar"
示例#4
0
def _ensure_kerberos_authentication(user, principal, keytab_file, kinit_path):
    kinit_path_local = get_kinit_path(kinit_path)
    shell.checked_call("{0} -kt {1} {2} > /dev/null".format(
        kinit_path_local, keytab_file, principal),
                       user=user)