-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathdb-connect.sh
executable file
·139 lines (119 loc) · 3.64 KB
/
db-connect.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/bin/sh
#
# Connect to a Terra Data Repo database in an environment.
#
# It uses the gcloud CLI to get the credentials for the cluster, kubectl to port
# forward to the SQL proxy pod, and psql to connect to the database.
#
# You MUST have gcloud, kubectl, jq, and psql installed to run this script. In
# addition, you MUST be connected to the VPN to access the database.
#
# See usage section below for more details. All arguments are optional.
#
set -eu
usage() {
cat <<EOF
Usage: $0 [OPTION]...
Connect to a Terra Data Repo database in an environment.
You MUST have gcloud, kubectl, jq, and psql installed to run this script. In
addition, you MUST be connected to the VPN to access the database.
--env ENV Environment to connect to, either dev or staging
(default: dev)
--port PORT Local port to forward to the SQL proxy (default: 5432)
--database DATABASE Database to connect to, either datarepo or stairway
(default: datarepo)
--help Display this help and exit
EOF
exit 0
}
error() {
echo "ERROR: $1" >&2
exit 1
}
# default values that may be overridden by command line arguments or environment variables
ENV="${ENV:-dev}"
PORT="${PORT:-5432}"
DATABASE="${DATABASE:-datarepo}"
parse_cli_args() {
while [ $# -gt 0 ]; do
case "$1" in
--env)
ENV="$2"
shift 2
;;
--port)
PORT="$2"
shift 2
;;
--database)
if [ "$2" != "datarepo" ] && [ "$2" != "stairway" ]; then
error "Database must be one of 'datarepo' or 'stairway'"
fi
DATABASE="$2"
shift 2
;;
--help)
usage
;;
*)
error "Unknown option: $1. Try --help to see a list of all options."
;;
esac
done
}
cleanup() {
kill "$PID"
}
set_vars_from_env() {
case "$ENV" in
dev)
PROJECT="broad-jade-dev"
NAMESPACE="dev"
SECRET="helm-datarepodb"
;;
staging)
PROJECT="terra-datarepo-staging"
NAMESPACE="terra-staging"
SECRET="sql-db"
;;
*)
error "Unknown environment: $ENV"
;;
esac
}
set_project_config() {
gcloud config set project "$PROJECT"
}
set_cluster_credentials() {
CLUSTER_JSON=$(gcloud container clusters list --format="json")
REGION=$(echo "$CLUSTER_JSON" | jq -r .[0].zone)
NAME=$(echo "$CLUSTER_JSON" | jq -r .[0].name)
gcloud container clusters get-credentials "$NAME" --region="$REGION" --project="$PROJECT"
}
port_forward_sqlproxy() {
POD_JSON=$(kubectl get pods --namespace="$NAMESPACE" --output="json")
# validate that the namespace is in the list of namespaces
if ! echo "$POD_JSON" | jq -r '.items[].metadata.namespace' | grep -q "$NAMESPACE"; then
error "Namespace '$NAMESPACE' not found in list of namespaces"
fi
# select the first pod that has a name that contains "sqlproxy"
SQLPROXY_POD=$(kubectl get pods --namespace="$NAMESPACE" --output="json" | jq -r '.items | map(.metadata.name | select(contains("sqlproxy"))) | first')
kubectl port-forward "$SQLPROXY_POD" --namespace "$NAMESPACE" "$PORT:5432" &
PID=$!
trap cleanup EXIT
}
connect_cloud_sql_db() {
USERNAME="drmanager"
PASSWORD=$(gcloud secrets versions access latest --project="$PROJECT" --secret="$SECRET" | jq -r '.datarepopassword')
# validate that the password is not empty
if [ -z "$PASSWORD" ]; then
error "Could not retrieve password for project '$PROJECT' with secret path '$SECRET'"
fi
psql "postgresql://$USERNAME:$PASSWORD@localhost:$PORT/$DATABASE"
}
parse_cli_args "$@"
set_vars_from_env
set_project_config
set_cluster_credentials
port_forward_sqlproxy
connect_cloud_sql_db