Skip to content

Instantly share code, notes, and snippets.

@purcell
Created August 17, 2023 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save purcell/bb56e044a4306eb6948b34d84f7ba676 to your computer and use it in GitHub Desktop.
Save purcell/bb56e044a4306eb6948b34d84f7ba676 to your computer and use it in GitHub Desktop.
Invoke a postgres command via a bastion host with auth obtained from 1password
#!/bin/bash -e
error_exit() {
echo "$@" >&2
exit 1
}
usage_exit() {
cat <<EOF >&2
Allows you to run a local postgres command, e.g. psql or pg_dump,
against an atlas database accessible from the given host.
USAGE: $(basename "$0") db-name env-name local-pg-command [ARGS]
EOF
exit 2
}
db_name=$1
env_name=$2
[ -n "$db_name" ] || usage_exit
[ -n "$env_name" ] || usage_exit
shift
shift
if [ -z "$1" ]; then
usage_exit
fi
# Assert required tools are available
command -v op>/dev/null || error_exit "You must install the 1password CLI (e.g. via 'brew cask') and sign in. Please refer to the README."
command -v jq>/dev/null || error_exit "You must install jq (e.g. via 'brew')"
echo "Getting credentials from 1password" >&2
ONEPASSWORD_SECRETS=$(op get item "aws db my-system $env_name $db_name")
read_secret() {
jq -r ".details.sections[] | select(.fields).fields[] | select(.t == \"$1\").v" <<<"$ONEPASSWORD_SECRETS"
}
# Grab credentials first to be sure
# We assume default port (5432) on the remote side
export PGDATABASE PGHOST PGUSER PGPASSWORD
PGDATABASE=$(read_secret "database")
[ -n "$PGDATABASE" ] || error_exit "Missing 'database' secret"
PGHOST=$(read_secret "server")
[ -n "$PGHOST" ] || error_exit "Missing 'server' secret"
PGUSER=$(read_secret "username")
[ -n "$PGUSER" ] || error_exit "Missing 'username' secret"
PGPASSWORD=$(read_secret "password")
[ -n "$PGPASSWORD" ] || error_exit "Missing 'password' secret"
ssh_host="atlas-$env_name"
random_port=$(( RANDOM + 3000 ))
echo "Forwarding psql connection via $random_port" >&2
ssh -N -L "$random_port:$PGHOST:5432" "$ssh_host" &
ssh_pid=$!
kill_ssh() { kill "$ssh_pid"; }
trap kill_ssh EXIT HUP INT
# Wait for port to be alive
check_count=0
while ! nc -z -v -w5 localhost $random_port >/dev/null 2>&1; do
check_count=$(( check_count + 1 ))
if [[ $check_count -eq 5 ]]; then
echo "Timed out waiting for forwarded port to be opened." 2>&1
exit 1
fi
sleep 1
done
PGHOST=localhost PGPORT=$random_port "$@"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment