2022-11-11 22:29:26 +01:00
|
|
|
#!/usr/bin/env bash
|
2022-12-22 17:12:23 +01:00
|
|
|
set -e
|
|
|
|
SQL_PROXY_HOST="${SQL_PROXY_HOST:-localhost}"
|
2023-01-06 09:32:29 +01:00
|
|
|
SSH_SQL_PROXY_HOST="sqlproxy.${SQL_PROXY_HOST}"
|
2022-12-22 17:12:23 +01:00
|
|
|
CONNECTION_CACHE="$HOME/.cache/sqlproxy_${SQL_PROXY_HOST}"
|
2022-11-11 22:29:26 +01:00
|
|
|
|
2022-11-18 11:56:29 +01:00
|
|
|
HELP="Usage: myssh [ls|connect]\n
|
|
|
|
SUBCOMMANDS:\n
|
|
|
|
ls: list available database hosts\n
|
|
|
|
connect: connect to a database host\n
|
|
|
|
disconnect: Quit existing ssh master session\n
|
|
|
|
\n
|
2022-11-11 22:29:26 +01:00
|
|
|
SYNTAX connect host [-u user] [-p password] [-c client]
|
|
|
|
"
|
|
|
|
|
2022-12-22 17:12:23 +01:00
|
|
|
get_template_string() {
|
|
|
|
if [ -z "$SQL_CLI_TEMPLATE" ]
|
|
|
|
then
|
2023-01-05 09:48:19 +01:00
|
|
|
if [ "$(uname -s)" = "Linux" ]
|
2022-12-22 17:12:23 +01:00
|
|
|
then
|
|
|
|
SQL_CLI_TEMPLATE='mysql --protocol=TCP -u $MYSQL_USERNAME -p$MYSQL_PASSWORD -h localhost -P 6033'
|
|
|
|
else
|
|
|
|
SQL_CLI_TEMPLATE='open \"mysql://$MYSQL_USERNAME:$MYSQL_PASSWORD@localhost:6033\" -a \"Sequel Ace\"'
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
echo -e "Warning, custom client string:\n$SQL_CLI_TEMPLATE"
|
|
|
|
read -r -p "Continue [Y/n] " CONTINUE
|
|
|
|
if [[ ! $CONTINUE =~ "^[Yy]" ]]
|
|
|
|
then
|
|
|
|
exit
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
printf '%s' "${SQL_CLI_TEMPLATE}"
|
|
|
|
}
|
|
|
|
|
2022-11-17 13:01:07 +01:00
|
|
|
ssh_status() {
|
2023-01-06 14:54:36 +01:00
|
|
|
ssh -n -O check -S "${HOME}/.ssh/controlmasters/%r@%h:%p" "${SSH_SQL_PROXY_HOST}" > /dev/null 2>&1
|
2022-11-11 22:29:26 +01:00
|
|
|
}
|
|
|
|
|
2022-11-17 13:01:07 +01:00
|
|
|
connect() {
|
2023-01-05 09:48:19 +01:00
|
|
|
mkdir -p "${HOME}/.ssh/controlmasters"
|
2022-11-17 13:01:07 +01:00
|
|
|
|
2023-01-05 09:48:19 +01:00
|
|
|
if ! ssh_status
|
2022-11-17 13:01:07 +01:00
|
|
|
then
|
2023-01-05 09:48:19 +01:00
|
|
|
echo "" > "${CONNECTION_CACHE}"
|
2023-01-06 14:54:36 +01:00
|
|
|
ssh -n -o "ControlPersist=10m" -M -S "${HOME}/.ssh/controlmasters/%r@%h:%p" "${SSH_SQL_PROXY_HOST}" q
|
2022-11-17 13:01:07 +01:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
disconnect() {
|
2023-01-05 09:48:19 +01:00
|
|
|
if ssh_status
|
2022-11-17 13:01:07 +01:00
|
|
|
then
|
2023-01-06 14:54:36 +01:00
|
|
|
ssh -n -O stop -S "${HOME}/.ssh/controlmasters/%r@%h:%p" "${SSH_SQL_PROXY_HOST}" q
|
2022-11-17 13:01:07 +01:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2022-12-22 17:12:23 +01:00
|
|
|
# Establishes a port forward to the target host
|
|
|
|
# args:
|
|
|
|
# $1 - target ip
|
|
|
|
# $2 - target port
|
2022-11-17 13:01:07 +01:00
|
|
|
port_forward() {
|
2023-01-05 09:48:19 +01:00
|
|
|
ACTIVE_HOST=$(cat "${CONNECTION_CACHE}")
|
2022-12-24 19:48:31 +01:00
|
|
|
if [ -z "${ACTIVE_HOST}" ] || [ "${ACTIVE_HOST}" != "$1:$2" ]
|
2022-11-11 22:29:26 +01:00
|
|
|
then
|
2022-12-24 19:48:31 +01:00
|
|
|
if [ -n "${ACTIVE_HOST}" ]
|
2022-11-11 22:29:26 +01:00
|
|
|
then
|
2023-01-06 14:54:36 +01:00
|
|
|
ssh -n -O cancel -L "6033:${ACTIVE_HOST}" -S "${HOME}/.ssh/controlmasters/%r@%h:%p" "${SSH_SQL_PROXY_HOST}" q
|
2022-11-11 22:29:26 +01:00
|
|
|
fi
|
2023-01-06 14:54:36 +01:00
|
|
|
ssh -n -O forward -L "6033:$1:$2" -S "${HOME}/.ssh/controlmasters/%r@%h:%p" "${SSH_SQL_PROXY_HOST}"
|
2022-11-11 22:29:26 +01:00
|
|
|
fi
|
2022-12-22 17:12:23 +01:00
|
|
|
echo "$1:$2" > "${CONNECTION_CACHE}"
|
2022-11-11 22:29:26 +01:00
|
|
|
}
|
|
|
|
|
2022-11-17 13:01:07 +01:00
|
|
|
ls_hosts() {
|
2023-01-06 14:54:36 +01:00
|
|
|
ssh -n -S "${HOME}/.ssh/controlmasters/%r@%h:%p" "${SSH_SQL_PROXY_HOST}" ls
|
2022-12-21 19:30:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
get_host() {
|
2023-01-05 09:48:19 +01:00
|
|
|
if [ "$1" = '' ]
|
2022-12-21 19:30:38 +01:00
|
|
|
then
|
|
|
|
printf 'Please specify the host to connect to.\nRun "myssh ls" to list all available hosts.\n'
|
2022-12-22 17:12:23 +01:00
|
|
|
exit 1
|
2022-12-21 19:30:38 +01:00
|
|
|
else
|
2023-01-06 14:54:36 +01:00
|
|
|
TARGET_HOST_DATA=$(ssh -n -S "${HOME}/.ssh/controlmasters/%r@%h:%p" "${SSH_SQL_PROXY_HOST}" "get $1")
|
2022-12-22 17:12:23 +01:00
|
|
|
if [ "${TARGET_HOST_DATA}" = '' ]
|
|
|
|
then
|
2023-01-05 09:48:19 +01:00
|
|
|
printf 'No such host: "%s"\n' "$1"
|
2022-12-22 17:12:23 +01:00
|
|
|
exit 1
|
|
|
|
fi
|
2022-12-21 19:30:38 +01:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2022-12-22 17:12:23 +01:00
|
|
|
# Checks and sets sql login variables
|
|
|
|
# args:
|
|
|
|
# $1 - sql type (mysql or psql)
|
|
|
|
# $2 - target ip
|
|
|
|
# $3 - target port
|
|
|
|
# $4 - username (optional)
|
|
|
|
# $5 - password (optional)
|
2022-12-21 19:30:38 +01:00
|
|
|
set_host_env() {
|
2023-01-05 09:48:19 +01:00
|
|
|
if [ "$1" = 'mysql' ] || [ "$1" = 'postgres' ]
|
2022-12-21 19:30:38 +01:00
|
|
|
then
|
2022-12-23 11:14:55 +01:00
|
|
|
TARGET_HOST_TYPE="$1"
|
2022-12-22 17:12:23 +01:00
|
|
|
else
|
2022-12-23 11:14:55 +01:00
|
|
|
printf 'Invalid Database type: "%s"\n' "$1"
|
2022-12-22 17:12:23 +01:00
|
|
|
exit 1
|
2022-12-21 19:30:38 +01:00
|
|
|
fi
|
2022-12-23 11:14:55 +01:00
|
|
|
if [[ "$2" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
|
2022-12-21 19:30:38 +01:00
|
|
|
then
|
2022-12-23 11:14:55 +01:00
|
|
|
TARGET_HOST_IP="$2"
|
2022-12-22 17:12:23 +01:00
|
|
|
else
|
2022-12-23 11:14:55 +01:00
|
|
|
printf 'Invalid Host IP "%s" given.\n' "$2"
|
2022-12-22 17:12:23 +01:00
|
|
|
exit 1
|
|
|
|
fi
|
2022-12-23 11:14:55 +01:00
|
|
|
if [[ "$3" =~ ^[0-9]+$ ]]
|
2022-12-22 17:12:23 +01:00
|
|
|
then
|
2022-12-23 11:14:55 +01:00
|
|
|
TARGET_HOST_PORT="$3"
|
2022-12-22 17:12:23 +01:00
|
|
|
else
|
|
|
|
printf 'Invalid Host Port "%s" given.\n' "$3"
|
2022-12-23 11:14:55 +01:00
|
|
|
exit 1
|
2022-12-22 17:12:23 +01:00
|
|
|
fi
|
2022-12-23 11:14:55 +01:00
|
|
|
if [ -z "${TARGET_HOST_USERNAME}" ] && [ -n "$4" ]
|
2022-12-22 17:12:23 +01:00
|
|
|
then
|
2022-12-23 11:14:55 +01:00
|
|
|
TARGET_HOST_USERNAME="$4"
|
2022-12-22 17:12:23 +01:00
|
|
|
fi
|
2022-12-23 11:14:55 +01:00
|
|
|
if [ -z "${TARGET_HOST_PASSWORD}" ] && [ -n "$5" ]
|
2022-12-22 17:12:23 +01:00
|
|
|
then
|
2022-12-23 11:14:55 +01:00
|
|
|
TARGET_HOST_PASSWORD="$5"
|
2022-12-21 19:30:38 +01:00
|
|
|
fi
|
2022-12-22 17:12:23 +01:00
|
|
|
|
2022-11-11 22:29:26 +01:00
|
|
|
}
|
|
|
|
|
2022-12-22 17:12:23 +01:00
|
|
|
# Runs the sql client for an active connection
|
|
|
|
# args:
|
|
|
|
# $1 - sql type (mysql or psql)
|
|
|
|
# $2 - username
|
|
|
|
# $3 - password
|
2022-11-11 22:29:26 +01:00
|
|
|
run_client() {
|
2022-12-22 17:12:23 +01:00
|
|
|
if [ "$1" = 'mysql' ]
|
|
|
|
then
|
|
|
|
if which ace >/dev/null 2>&1
|
|
|
|
then
|
|
|
|
ace
|
|
|
|
elif which mysql >/dev/null 2>&1
|
|
|
|
then
|
|
|
|
mysql --protocol=TCP -u "$2" -p"$3" -h "${SQL_PROXY_HOST}" -P 6033
|
|
|
|
else
|
|
|
|
SHOW_CLI_HELP=true
|
|
|
|
fi
|
2023-01-05 09:48:19 +01:00
|
|
|
elif [ "$1" = 'postgres' ]
|
2022-12-22 17:12:23 +01:00
|
|
|
then
|
2023-01-05 09:48:19 +01:00
|
|
|
if which psql >/dev/null 2>&1
|
|
|
|
then
|
|
|
|
psql "postgresql://$2:$3@${SQL_PROXY_HOST}:6033/postgres"
|
|
|
|
else
|
|
|
|
SHOW_CLI_HELP=true
|
|
|
|
fi
|
2022-12-22 17:12:23 +01:00
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "${SHOW_CLI_HELP}" = true ]
|
|
|
|
then
|
2023-01-05 09:48:19 +01:00
|
|
|
printf 'No %s client binary found.\nYou can maually establish a connection using the following data.\n' "$1"
|
|
|
|
printf 'host:\t%s\nport:\t%s\nuser:\t%s\npassword:\t%s\n' "${SQL_PROXY_HOST}" '6033' "$2" "$3"
|
2022-12-22 17:12:23 +01:00
|
|
|
fi
|
2022-11-11 22:29:26 +01:00
|
|
|
}
|
|
|
|
|
2022-12-23 11:14:55 +01:00
|
|
|
MAIN_OPTION="$1"
|
|
|
|
if [ -n "$1" ]
|
|
|
|
then
|
|
|
|
shift
|
|
|
|
fi
|
2022-11-11 22:29:26 +01:00
|
|
|
|
2022-11-17 15:26:23 +01:00
|
|
|
# ensure connection
|
|
|
|
connect
|
2022-12-23 11:14:55 +01:00
|
|
|
case "${MAIN_OPTION}" in
|
2022-11-11 22:29:26 +01:00
|
|
|
ls)
|
2022-11-17 13:01:07 +01:00
|
|
|
ls_hosts;;
|
2022-11-11 22:29:26 +01:00
|
|
|
connect)
|
|
|
|
# check if host is valid
|
2022-12-23 11:14:55 +01:00
|
|
|
TARGET_HOST="$1"
|
|
|
|
if [ -n "$1" ]
|
|
|
|
then
|
|
|
|
shift
|
|
|
|
else
|
|
|
|
printf 'No host specified.\n'
|
|
|
|
exit 1
|
|
|
|
fi
|
2022-12-21 19:30:38 +01:00
|
|
|
|
|
|
|
while getopts "u:p:" o
|
|
|
|
do
|
|
|
|
case "$o" in
|
2022-12-22 17:12:23 +01:00
|
|
|
u) TARGET_HOST_USERNAME="$OPTARG" ;;
|
|
|
|
p) TARGET_HOST_PASSWORD="$OPTARG" ;;
|
2022-12-21 19:30:38 +01:00
|
|
|
esac
|
|
|
|
done
|
2022-12-23 11:14:55 +01:00
|
|
|
get_host "${TARGET_HOST}"
|
2023-01-05 09:48:19 +01:00
|
|
|
# Do not quote this.
|
2022-12-23 11:14:55 +01:00
|
|
|
set_host_env ${TARGET_HOST_DATA}
|
2022-12-22 17:12:23 +01:00
|
|
|
port_forward "${TARGET_HOST_IP}" "$TARGET_HOST_PORT"
|
|
|
|
if [ -n "${TARGET_HOST_USERNAME}" ] && [ -n "${TARGET_HOST_PASSWORD}" ]
|
|
|
|
then
|
|
|
|
run_client "${TARGET_HOST_TYPE}" "${TARGET_HOST_USERNAME}" "${TARGET_HOST_PASSWORD}"
|
|
|
|
fi
|
2022-11-11 22:29:26 +01:00
|
|
|
;;
|
2022-11-17 13:01:07 +01:00
|
|
|
disconnect)
|
|
|
|
disconnect;;
|
2022-11-11 22:29:26 +01:00
|
|
|
*)
|
2022-12-23 11:14:55 +01:00
|
|
|
echo -e "${HELP}";;
|
2022-11-11 22:29:26 +01:00
|
|
|
esac
|