def execute_db_connection_check()

in ambari-server/src/main/resources/custom_actions/scripts/check_host.py [0:0]


  def execute_db_connection_check(self, config, tmp_dir):
    Logger.info("DB connection check started.")

    # initialize needed data

    ambari_server_hostname = config["commandParams"]["ambari_server_host"]
    check_db_connection_jar_name = "DBConnectionVerification.jar"
    jdk_location = config["commandParams"]["jdk_location"]
    ambari_java_home = config["ambariLevelParams"]["ambari_java_home"]
    java_home = ambari_java_home
    db_name = config["commandParams"]["db_name"]
    no_jdbc_error_message = None

    if db_name == DB_MYSQL:
      jdbc_driver_mysql_name = default(
        "/ambariLevelParams/custom_mysql_jdbc_name", None
      )
      if not jdbc_driver_mysql_name:
        no_jdbc_error_message = "The MySQL JDBC driver has not been set. Please ensure that you have executed 'ambari-server setup --jdbc-db=mysql --jdbc-driver=/path/to/jdbc_driver'."
      else:
        jdbc_url = CheckHost.build_url(jdk_location, jdbc_driver_mysql_name)
        jdbc_driver_class = JDBC_DRIVER_CLASS_MYSQL
        jdbc_name = jdbc_driver_mysql_name
    elif db_name == DB_ORACLE:
      jdbc_driver_oracle_name = default(
        "/ambariLevelParams/custom_oracle_jdbc_name", None
      )
      if not jdbc_driver_oracle_name:
        no_jdbc_error_message = "The Oracle JDBC driver has not been set. Please ensure that you have executed 'ambari-server setup --jdbc-db=oracle --jdbc-driver=/path/to/jdbc_driver'."
      else:
        jdbc_url = CheckHost.build_url(jdk_location, jdbc_driver_oracle_name)
        jdbc_driver_class = JDBC_DRIVER_CLASS_ORACLE
        jdbc_name = jdbc_driver_oracle_name
    elif db_name == DB_POSTGRESQL:
      jdbc_driver_postgres_name = default(
        "/ambariLevelParams/custom_postgres_jdbc_name", None
      )
      if not jdbc_driver_postgres_name:
        no_jdbc_error_message = "The Postgres JDBC driver has not been set. Please ensure that you have executed 'ambari-server setup --jdbc-db=postgres --jdbc-driver=/path/to/jdbc_driver'."
      else:
        jdbc_url = CheckHost.build_url(jdk_location, jdbc_driver_postgres_name)
        jdbc_driver_class = JDBC_DRIVER_CLASS_POSTGRESQL
        jdbc_name = jdbc_driver_postgres_name
    elif db_name == DB_MSSQL:
      jdbc_driver_mssql_name = default(
        "/ambariLevelParams/custom_mssql_jdbc_name", None
      )
      if not jdbc_driver_mssql_name:
        no_jdbc_error_message = "The MSSQL JDBC driver has not been set. Please ensure that you have executed 'ambari-server setup --jdbc-db=mssql --jdbc-driver=/path/to/jdbc_driver'."
      else:
        jdbc_url = CheckHost.build_url(jdk_location, jdbc_driver_mssql_name)
        jdbc_driver_class = JDBC_DRIVER_CLASS_MSSQL
        jdbc_name = jdbc_driver_mssql_name
    elif db_name == DB_SQLA:
      jdbc_driver_sqla_name = default(
        "/ambariLevelParams/custom_sqlanywhere_jdbc_name", None
      )
      if not jdbc_driver_sqla_name:
        no_jdbc_error_message = "The SQLAnywhere JDBC driver has not been set. Please ensure that you have executed 'ambari-server setup --jdbc-db=sqlanywhere --jdbc-driver=/path/to/jdbc_driver'."
      else:
        jdbc_url = CheckHost.build_url(jdk_location, jdbc_driver_sqla_name)
        jdbc_driver_class = JDBC_DRIVER_CLASS_SQLA
        jdbc_name = jdbc_driver_sqla_name
    else:
      no_jdbc_error_message = format("'{db_name}' database type not supported.")

    if no_jdbc_error_message:
      Logger.warning(no_jdbc_error_message)
      db_connection_check_structured_output = {
        "exit_code": 1,
        "message": no_jdbc_error_message,
      }
      return db_connection_check_structured_output

    db_connection_url = config["commandParams"]["db_connection_url"]
    user_name = config["commandParams"]["user_name"]
    user_passwd = config["commandParams"]["user_passwd"]
    agent_cache_dir = os.path.abspath(config["agentLevelParams"]["agentCacheDir"])
    check_db_connection_url = CheckHost.build_url(
      jdk_location, check_db_connection_jar_name
    )
    jdbc_path = os.path.join(agent_cache_dir, jdbc_name)
    class_path_delimiter = ":"
    if db_name == DB_SQLA:
      jdbc_jar_path = agent_cache_dir + JDBC_DRIVER_SQLA_JAR_PATH_IN_ARCHIVE
      java_library_path = (
        agent_cache_dir
        + JARS_PATH_IN_ARCHIVE_SQLA
        + class_path_delimiter
        + agent_cache_dir
        + LIBS_PATH_IN_ARCHIVE_SQLA
      )
    else:
      jdbc_jar_path = jdbc_path
      java_library_path = agent_cache_dir

    check_db_connection_path = os.path.join(
      agent_cache_dir, check_db_connection_jar_name
    )

    java_bin = "java"
    if OSCheck.is_windows_family():
      java_bin = "java.exe"
      class_path_delimiter = ";"

    java_exec = os.path.join(java_home, "bin", java_bin)

    if (
      "jdk_name" not in config["commandParams"]
      or config["commandParams"]["jdk_name"] == None
      or config["commandParams"]["jdk_name"] == ""
    ) and not os.path.isfile(java_exec):
      message = (
        "Custom java is not available on host. Please install it. Java home should be the same as on server. "
        "\n"
      )
      Logger.warning(message)
      db_connection_check_structured_output = {"exit_code": 1, "message": message}
      return db_connection_check_structured_output

    environment = {"no_proxy": format("{ambari_server_hostname}")}
    # download and install java if it doesn't exists
    if not os.path.isfile(java_exec):
      jdk_name = config["commandParams"]["jdk_name"]
      jdk_url = CheckHost.build_url(jdk_location, jdk_name)
      jdk_download_target = os.path.join(agent_cache_dir, jdk_name)
      java_dir = os.path.dirname(java_home)
      try:
        download_file(jdk_url, jdk_download_target)
      except Exception as e:
        message = (
          "Error downloading JDK from Ambari Server resources. Check network access to "
          "Ambari Server.\n" + str(e)
        )
        Logger.exception(message)
        db_connection_check_structured_output = {"exit_code": 1, "message": message}
        return db_connection_check_structured_output

      if jdk_name.endswith(".exe"):
        install_cmd = "{0} /s INSTALLDIR={1} STATIC=1 WEB_JAVA=0 /L \\var\\log\\ambari-agent".format(
          os_utils.quote_path(jdk_download_target),
          os_utils.quote_path(java_home),
        )
        install_path = [java_dir]
        try:
          Execute(install_cmd, path=install_path)
        except Exception as e:
          message = "Error installing java.\n" + str(e)
          Logger.exception(message)
          db_connection_check_structured_output = {"exit_code": 1, "message": message}
          return db_connection_check_structured_output
      else:
        tmp_java_dir = tempfile.mkdtemp(prefix="jdk_tmp_", dir=tmp_dir)
        sudo = AMBARI_SUDO_BINARY
        if jdk_name.endswith(".bin"):
          chmod_cmd = ("chmod", "+x", jdk_download_target)
          install_cmd = format(
            "cd {tmp_java_dir} && echo A | {jdk_download_target} -noregister && {sudo} cp -rp {tmp_java_dir}/* {java_dir}"
          )
        elif jdk_name.endswith(".gz"):
          chmod_cmd = ("chmod", "a+x", java_dir)
          install_cmd = format(
            "cd {tmp_java_dir} && tar -xf {jdk_download_target} && {sudo} cp -rp {tmp_java_dir}/* {java_dir}"
          )
        try:
          Directory(java_dir)
          Execute(chmod_cmd, not_if=format("test -e {java_exec}"), sudo=True)
          Execute(install_cmd, not_if=format("test -e {java_exec}"))
          File(format("{java_home}/bin/java"), mode=0o755, cd_access="a")
          Directory(java_home, owner=getpass.getuser(), recursive_ownership=True)
          Execute(("chmod", "-R", "755", java_home), sudo=True)
        except Exception as e:
          message = "Error installing java.\n" + str(e)
          Logger.exception(message)
          db_connection_check_structured_output = {"exit_code": 1, "message": message}
          return db_connection_check_structured_output
        finally:
          Directory(tmp_java_dir, action="delete")

    # download DBConnectionVerification.jar from ambari-server resources
    try:
      download_file(check_db_connection_url, check_db_connection_path)

    except Exception as e:
      message = (
        "Error downloading DBConnectionVerification.jar from Ambari Server resources. Check network access to "
        "Ambari Server.\n" + str(e)
      )
      Logger.exception(message)
      db_connection_check_structured_output = {"exit_code": 1, "message": message}
      return db_connection_check_structured_output

    # download jdbc driver from ambari-server resources
    try:
      download_file(jdbc_url, jdbc_path)
      if db_name == DB_MSSQL and OSCheck.is_windows_family():
        jdbc_auth_path = os.path.join(agent_cache_dir, JDBC_AUTH_SYMLINK_MSSQL)
        jdbc_auth_url = CheckHost.build_url(jdk_location, JDBC_AUTH_SYMLINK_MSSQL)
        download_file(jdbc_auth_url, jdbc_auth_path)
      elif db_name == DB_SQLA:
        # unpack tar.gz jdbc which was donaloaded
        untar_sqla_type2_driver = ("tar", "-xvf", jdbc_path, "-C", agent_cache_dir)
        Execute(untar_sqla_type2_driver, sudo=True)
    except Exception as e:
      message = format(
        "Error: Ambari Server cannot download the database JDBC driver and is unable to test the "
        "database connection. You must run ambari-server setup --jdbc-db={db_name} "
        "--jdbc-driver=/path/to/your/{db_name}/driver.jar on the Ambari Server host to make the JDBC "
        "driver available for download and to enable testing the database connection.\n"
      ) + str(e)
      Logger.exception(message)
      db_connection_check_structured_output = {"exit_code": 1, "message": message}
      return db_connection_check_structured_output

    # For Oracle connection as SYS should be as SYSDBA
    if db_name == DB_ORACLE and user_name.upper() == "SYS":
      user_name = "SYS AS SYSDBA"

    # try to connect to db
    db_connection_check_command = format(
      "{java_exec} -cp {check_db_connection_path}{class_path_delimiter}"
      '{jdbc_jar_path} -Djava.library.path={java_library_path} org.apache.ambari.server.DBConnectionVerification "{db_connection_url}" '
      '"{user_name}" {user_passwd!p} {jdbc_driver_class}'
    )

    if db_name == DB_SQLA:
      db_connection_check_command = (
        "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:{0}{1} {2}".format(
          agent_cache_dir, LIBS_PATH_IN_ARCHIVE_SQLA, db_connection_check_command
        )
      )

    if isinstance(db_connection_check_command, str):
      code, out = shell.call(
        split(db_connection_check_command, comments=True), shell=False
      )
    else:
      code, out = shell.call(db_connection_check_command, shell=False)

    if code == 0:
      db_connection_check_structured_output = {
        "exit_code": 0,
        "message": "DB connection check completed successfully!",
      }
    else:
      db_connection_check_structured_output = {"exit_code": 1, "message": out}

    Logger.info("DB connection check completed.")
    return db_connection_check_structured_output