This repository has been archived by the owner on May 24, 2023. It is now read-only.
forked from mesosphere/marathon-lb
-
Notifications
You must be signed in to change notification settings - Fork 18
/
run
executable file
·289 lines (248 loc) · 8.37 KB
/
run
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
#!/bin/bash
set -euo pipefail
source /usr/sbin/b-log.sh
B_LOG --stdout true
DOCKER_LOG_LEVEL=${DOCKER_LOG_LEVEL:-INFO}
eval LOG_LEVEL_${DOCKER_LOG_LEVEL}
# # # # # # # # # #
# Vault config:
# STRING_VAULT_HOST
# VAULT_PORT
#
# Token Auth:
# VAULT_TOKEN
#
# Dynamic Auth:
# VAULT_ROLE_ID
# VAULT_SECRET_ID
# # # # # # # # #
VAULT_ENABLED=0
MARATHON_LB_CERT_NAME="000_marathon-lb.pem"
# KMS_UTILS & Dynamic authentication
if [ -n "${STRING_VAULT_HOST-}" ] && [ -n "${VAULT_PORT-}" ]; then
OLD_IFS=${IFS}
IFS=',' read -r -a VAULT_HOSTS <<< "$STRING_VAULT_HOST"
IFS=${OLD_IFS}
if [ -n "${VAULT_ROLE_ID-}" ] && [ -n "${VAULT_SECRET_ID-}" ]; then
source /usr/sbin/kms_utils.sh
VAULT_ENABLED=1
INFO "VAULT - Dynamic authentication provided"
INFO "Dynamic login with vault..."
login
INFO "Login success"
elif [ -n "${VAULT_TOKEN-}" ]; then
source /usr/sbin/kms_utils.sh
VAULT_ENABLED=1
INFO "VAULT - Token authentication provided"
else
INFO "VAULT - ERROR: Vault host configuration provided, but no token nor dynamic authentication configuration provided"
exit 1
fi
fi
#
LOG_PREFIX="$(pwd) $0"
log() {
logline=$(echo "[$LOG_PREFIX] $1" | sed "s/%/%%/g")
INFO "$logline" >&1
}
log_error() {
logline="[$LOG_PREFIX] $1"
ERROR "$logline"
}
if [ -n "${HAPROXY_SYSLOGD-}" ]; then
SYSLOGD_SERVICE="/marathon-lb/service/syslogd"
mkdir -p $SYSLOGD_SERVICE
cp /marathon-lb/syslogd/run "$SYSLOGD_SERVICE/"
fi
if [ "${HAPROXY_RSYSLOG:-true}" = true ]; then
RSYSLOG_SERVICE="/marathon-lb/service/rsyslog"
mkdir -p $RSYSLOG_SERVICE
cp /marathon-lb/rsyslog/run "$RSYSLOG_SERVICE/"
fi
# Custom syslog socket for marathon-lb.py logging
SYSLOG_SOCKET=${SYSLOG_SOCKET:-/dev/null}
LB_SERVICE="/marathon-lb/service/lb"
mkdir -p $LB_SERVICE
HAPROXY_SERVICE="/marathon-lb/service/haproxy"
mkdir -p $HAPROXY_SERVICE/env
if [ -n "${PORTS-}" ]; then
log "$PORTS > $HAPROXY_SERVICE/env/PORTS"
else
log_error "Define $PORTS with a comma-separated list of ports to which HAProxy binds"
exit 1
fi
# Find the --ssl-certs arg if one was provided,
# get the certs and remove them and the arg from the list
# of positional parameters so we don't duplicate them
# further down when we pass $@ to marathon_lb.py
declare -i ssl_certs_pos=0
for ((i=1; i<=$#; i++)); do
if [ "${!i}" = '--ssl-certs' ]; then
ssl_certs_pos=$(($i+1))
break
fi
done
if [ $ssl_certs_pos -gt 0 ]; then
SSL_CERTS=${!ssl_certs_pos}
set -- "${@:1:$(($ssl_certs_pos-2))}" "${@:$(($ssl_certs_pos+1))}"
[ -n "${HAPROXY_SSL_CERT-}" ] && SSL_CERTS+=",/etc/ssl/cert.pem"
else
SSL_CERTS="/etc/ssl/cert.pem"
fi
if [ ${VAULT_ENABLED} -eq 1 ]; then
INFO "Downloading certificates from vault..."
SSL_CERTS="/marathon-lb/vault_certs"
mkdir -p "$SSL_CERTS"
# Try to download cert from MARATHON_APP_ID
# MARATHON_APP_ID can be of the form "/<folder1>/<folder2> ... /name", e.g. /test/nginx or /nginx
# The multitenant convention replaces "/" for "." and reverses the order,
# For example, if MARATHON_APP_ID is /test/nginx, CONV_MARATHON_APP_ID should be nginx.test
# if MARATHON_APP_ID is /test1/test2/nginx, CONV_MARATHON_APP_ID should be nginx.test2.test1
OLD_IFS=${IFS}
IFS='/' read -r -a MARATHON_APP_ID_ARRAY <<< "$MARATHON_APP_ID"
IFS=${OLD_IFS}
unset "MARATHON_APP_ID_ARRAY[0]"
CONV_MARATHON_APP_ID=$(printf '%s\n' "${MARATHON_APP_ID_ARRAY[@]}" | tac | tr '\n' '.')
CONV_MARATHON_APP_ID=${CONV_MARATHON_APP_ID%?}
INFO "Trying to download certificate from /userland/certificates/${CONV_MARATHON_APP_ID}"
set +e
getCert userland "${CONV_MARATHON_APP_ID}" "${CONV_MARATHON_APP_ID}" PEM "${SSL_CERTS}" 2>&1
if [ $? -ne 0 ]
then
set -e
INFO "Certificate in /userland/certificates/${CONV_MARATHON_APP_ID} does not exist, falling back to default route /userland/certificates/marathon-lb"
getCert userland marathon-lb marathon-lb PEM "$SSL_CERTS"
CONV_MARATHON_APP_ID="marathon-lb"
fi
set -e
# if provided Vault credentials, use it.
chmod 644 "$SSL_CERTS/$CONV_MARATHON_APP_ID.pem"
cat "$SSL_CERTS/$CONV_MARATHON_APP_ID.key" >> "$SSL_CERTS/$CONV_MARATHON_APP_ID.pem"
rm -f "$SSL_CERTS/$CONV_MARATHON_APP_ID.key"
# Change the name to be the first alphabetical order certificate (SNI)
mv "$SSL_CERTS/$CONV_MARATHON_APP_ID.pem" "$SSL_CERTS/$MARATHON_LB_CERT_NAME"
src_file_path=/marathon-lb/vault_certs/$MARATHON_LB_CERT_NAME.orig
dest_file_path=/marathon-lb/vault_certs/$MARATHON_LB_CERT_NAME
mv $dest_file_path $src_file_path
fold -w 64 $src_file_path > $dest_file_path
rm -f $src_file_path
# Copy the certificate to make it available in the old default path
cp "$SSL_CERTS/$MARATHON_LB_CERT_NAME" /etc/ssl/cert.pem
SSL_CERTS="$SSL_CERTS/"
INFO "Downloaded"
INFO "Downloading ca-bundle from vault..."
getCAbundle /etc/ssl PEM
INFO "Downloaded"
src_file_path=/etc/ssl/ca-bundle.pem.orig
dest_file_path=/etc/ssl/ca-bundle.pem
mv $dest_file_path $src_file_path
fold -w 64 $src_file_path > $dest_file_path
elif [ -n "${HAPROXY_SSL_CERT-}" ]; then
# if provided via environment variable, use it.
echo -e "$HAPROXY_SSL_CERT" > /etc/ssl/cert.pem
# if additional certs were provided as $HAPROXY_SSL_CERT0 .. 100
for i in {0..100}; do
certenv="HAPROXY_SSL_CERT$i"
if [ -n "${!certenv-}" ]; then
certfile="/etc/ssl/cert$i.pem"
echo -e "${!certenv}" > $certfile
SSL_CERTS+=",$certfile"
fi
done
elif [ $ssl_certs_pos -eq 0 ]; then # if --ssl-certs wasn't passed as arg to this script
# if no environment variable or command line argument is provided,
# create self-signed ssl certificate
openssl genrsa -out /tmp/server-key.pem 2048
openssl req -new -key /tmp/server-key.pem -out /tmp/server-csr.pem -subj /CN=*/
openssl x509 -req -in /tmp/server-csr.pem -out /tmp/server-cert.pem -signkey /tmp/server-key.pem -days 3650
cat /tmp/server-cert.pem /tmp/server-key.pem > /etc/ssl/cert.pem
rm /tmp/server-*.pem
fi
if [ -n "${MESOS_SANDBOX-}" ] && [ -d "$MESOS_SANDBOX/templates" ]; then
mkdir -p templates
cp -v "$MESOS_SANDBOX/templates/"* templates/
fi
if [ -n "${HAPROXY_SYSCTL_PARAMS-}" ]; then
log "setting sysctl params to: ${HAPROXY_SYSCTL_PARAMS}"
if [ -n "${HAPROXY_SYSCTL_NONSTRICT-}" ]; then
# ignore errors
sysctl -w $HAPROXY_SYSCTL_PARAMS || true
else
sysctl -w $HAPROXY_SYSCTL_PARAMS
fi
fi
MODE=$1; shift
case "$MODE" in
poll)
POLL_INTERVAL="${POLL_INTERVAL:-60}"
ARGS=""
;;
sse)
ARGS="--sse"
;;
*)
log_error "Unknown mode $MODE. Synopsis: $0 poll|sse [marathon_lb.py args]"
exit 1
;;
esac
if [ ${VAULT_ENABLED} -eq 1 ]; then
INFO "Downloading marathon credentials from Vault..."
getPass dcs marathon rest
CREDENTIALS="$MARATHON_REST_USER:$MARATHON_REST_PASS"
ARGS="$ARGS --auth-credentials $CREDENTIALS"
INFO "Downloaded"
fi
export WRAPPER_SYSLOG_SOCKET=$SYSLOG_SOCKET
WRAPPER_LOG_FORMAT_NEXT="false"
WRAPPER_LOG_LEVEL_NEXT="false"
for arg in "$@"; do
escaped=$(printf %q "$arg")
ARGS="$ARGS $escaped"
if [ $WRAPPER_LOG_FORMAT_NEXT = "true" ]; then
WRAPPER_LOG_FORMAT=$arg
fi
if [ $WRAPPER_LOG_LEVEL_NEXT = "true" ]; then
WRAPPER_LOG_LEVEL=$arg
fi
if [ "$arg" = "--log-format" ]; then
WRAPPER_LOG_FORMAT_NEXT="true"
else
WRAPPER_LOG_FORMAT_NEXT="false"
fi
if [ "$arg" = "--log-level" ]; then
WRAPPER_LOG_LEVEL_NEXT="true"
else
WRAPPER_LOG_LEVEL_NEXT="false"
fi
done
WRAPPER_LOG_FORMAT=${WRAPPER_LOG_FORMAT:-%(asctime)-15s %(name)s: %(message)s}
export WRAPPER_LOG_FORMAT
WRAPPER_LOG_LEVEL=${WRAPPER_LOG_LEVEL:-DEBUG}
export WRAPPER_LOG_LEVEL
grep -q -F -w "sv reload ${HAPROXY_SERVICE}" /marathon-lb/reload_haproxy.sh || echo "sv reload ${HAPROXY_SERVICE}" >> /marathon-lb/reload_haproxy.sh
cat > $LB_SERVICE/run << EOF
#!/bin/sh
exec 2>&1
cd /marathon-lb
exec /marathon-lb/marathon_lb.py \
--marathon-lb-cert-name "$MARATHON_LB_CERT_NAME" \
--syslog-socket $SYSLOG_SOCKET \
--haproxy-config /marathon-lb/haproxy.cfg \
--ssl-certs "${SSL_CERTS}" \
--command "/marathon-lb/reload_haproxy.sh" \
$ARGS
EOF
chmod 755 $LB_SERVICE/run
log "Created $LB_SERVICE/run with contents:"
LB_RUN=$(cat $LB_SERVICE/run)
log "$LB_RUN"
if [ "${MODE}" == "poll" ]; then
cat > $LB_SERVICE/finish << EOF
#!/bin/sh
sleep ${POLL_INTERVAL}
EOF
chmod 755 $LB_SERVICE/finish
fi
runsvdir -P /marathon-lb/service &
trap "kill -s 1 $!" TERM INT
wait