-
Notifications
You must be signed in to change notification settings - Fork 8
/
cp-certs.sh
executable file
·244 lines (210 loc) · 7.48 KB
/
cp-certs.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
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
#!/bin/bash
function check_and_wait_all_cert_files_in_var_lib_kubelet_kubeconfig(){
local CERTS_DIR="/var/lib/kubelet/kubeconfig"
local FILE_LIST="ca.crt kubecfg.crt kubecfg.key"
# Wait a moment until all files exist
local CERTS_EXISTED="false"
until [[ "${CERTS_EXISTED}" == "true" ]]; do
CERTS_EXISTED="true"
for FILE in ${FILE_LIST}; do
test -f "${CERTS_DIR}/${FILE}" || { CERTS_EXISTED="false" && break; }
done
if [[ "${CERTS_EXISTED}" == "false" ]]; then
sleep 1
fi
done
echo "All certs in ${CERTS_DIR}" 1>&2
}
function check_and_wait_all_cert_files_in_srv_kubernetes(){
local CERTS_DIR="/srv/kubernetes"
local FILE_LIST="ca.crt kubecfg.crt kubecfg.key server.cert server.key basic_auth.csv known_tokens.csv abac-policy-file.jsonl"
# Wait a moment until all files exist
local CERTS_EXISTED="false"
until [[ "${CERTS_EXISTED}" == "true" ]]; do
CERTS_EXISTED="true"
for FILE in ${FILE_LIST}; do
test -f "${CERTS_DIR}/${FILE}" || { CERTS_EXISTED="false" && break; }
done
if [[ "${CERTS_EXISTED}" == "false" ]]; then
sleep 1
fi
done
echo "All certs in ${CERTS_DIR}" 1>&2
}
function check_and_wait_all_certs_exist_on_etcd(){
local ETCD_PATH="$1"
local CERT_LIST="ca.crt kubecfg.crt kubecfg.key server.cert server.key basic_auth.csv known_tokens.csv"
local CERTS_EXISTED
# Wait a moment until all certs exist
until [[ "${CERTS_EXISTED}" == "true" ]]; do
CERTS_EXISTED="true"
for CERT in ${CERT_LIST}; do
curl -sf "http://127.0.0.1:2379/v2/keys/${ETCD_PATH}/${CERT}" &>/dev/null \
|| { CERTS_EXISTED="false" && break; }
done
if [[ "${CERTS_EXISTED}" == "false" ]]; then
sleep 1
fi
done
echo "All certs on etcd" 1>&2
}
function check_certs_exist_on_etcd(){
local ETCD_PATH="$1"
local ERROR_CODE=""
local CERTS_ON_ETCD=""
until curl -s "http://127.0.0.1:2379/v2/keys" &>/dev/null; do
echo "Waiting for etcd ready..." 1>&2
sleep 1
done
# Atomic operation for ensuring there are no certs on etcd that uploaded by other node before.
curl -sf "http://127.0.0.1:2379/v2/keys/${ETCD_PATH}?prevExist=false" -XPUT -d dir=true 1>&2
ERROR_CODE="$?"
# Error code 22 means the certs have alreay been uploaded by other node before
if [[ "${ERROR_CODE}" == "22" ]]; then
CERTS_ON_ETCD="true"
elif [[ "${ERROR_CODE}" == "0" ]]; then
CERTS_ON_ETCD="false"
else
echo "Connect to etcd error, exiting..." 1>&2
exit "${ERROR_CODE}"
fi
echo "${CERTS_ON_ETCD}"
}
# clone client-certificate and client-key for kube-proxy & kubelet
function cp_kube_certs(){
local CERTS_DIR="/srv/kubernetes"
local FILE_LIST="ca.crt kubecfg.crt kubecfg.key"
local DEST_DIR="/var/lib/kubelet/kubeconfig"
local CERTS_EXISTED
mkdir -p "${DEST_DIR}"
for FILE in ${FILE_LIST}; do
rm -f "${DEST_DIR}/${FILE}" || true
done
# Wait a moment until all files exist
echo "Copying certs to ${DEST_DIR}..." 1>&2
until [[ "${CERTS_EXISTED}" == "true" ]]; do
CERTS_EXISTED="true"
for FILE in ${FILE_LIST}; do
test -f "${CERTS_DIR}/${FILE}" || { CERTS_EXISTED="false" && break; }
done
if [[ "${CERTS_EXISTED}" == "false" ]]; then
sleep 1
fi
done
for FILE in ${FILE_LIST}; do
cp -f "${CERTS_DIR}/${FILE}" "${DEST_DIR}" \
&& echo "${FILE}" copied 1>&2
done
}
function upload_kube_certs(){
local ETCD_PATH="$1"
local CERTS_DIR="/srv/kubernetes"
local FILE_LIST="ca.crt kubecfg.crt kubecfg.key server.cert server.key basic_auth.csv known_tokens.csv abac-policy-file.jsonl"
local ENCODED_DATA=""
# Wait a moment until all files exist
local CERTS_EXISTED="false"
until [[ "${CERTS_EXISTED}" == "true" ]]; do
CERTS_EXISTED="true"
for FILE in ${FILE_LIST}; do
test -f "${CERTS_DIR}/${FILE}" || { CERTS_EXISTED="false" && break; }
done
if [[ "${CERTS_EXISTED}" == "false" ]]; then
sleep 1
fi
done
# Check again if CA exists, don't upload anything
curl -sf "http://127.0.0.1:2379/v2/keys/${ETCD_PATH}/ca.crt" 1>&2
ERROR_CODE="$?"
if [[ "${ERROR_CODE}" == "22" ]]; then
echo There are no certs on etcd, uploading certs... 1>&2
for FILE in ${FILE_LIST}; do
ENCODED_DATA="$(cat "${CERTS_DIR}/${FILE}" | base64)"
curl -s "http://127.0.0.1:2379/v2/keys/${ETCD_PATH}/${FILE}" -XPUT -d value="${ENCODED_DATA}" 1>/dev/null \
&& echo "${FILE}" uploaded 1>&2
done
else
download_kube_certs "${ETCD_PATH}"
fi
}
function download_kube_certs(){
local ETCD_PATH="$1"
local CERTS_DIR="/srv/kubernetes"
local FILE_LIST="ca.crt kubecfg.crt kubecfg.key server.cert server.key basic_auth.csv known_tokens.csv abac-policy-file.jsonl"
local RAWDATA=""
local CERT=""
mkdir -p "${CERTS_DIR}"
echo "Downloading certs to ${CERTS_DIR}..." 1>&2
for FILE in ${FILE_LIST}; do
until RAWDATA="$(curl -sf "http://127.0.0.1:2379/v2/keys/${ETCD_PATH}/${FILE}")"; do
echo "Waiting to get etcd keys..." 1>&2
sleep 1
done
CERT="$(echo "${RAWDATA}" \
| sed -n "s/.*value\":\"\(.*\)\",.*/\1/p" \
| sed "s/\\\n/\n/g" \
| base64 -d -i)"
echo "${CERT}" | tee "${CERTS_DIR}/${FILE}" 1>/dev/null \
&& echo "${FILE} downloaded" 1>&2 \
|| { echo "Error: download or writing '${FILE}' failed!"; return 1; }
done
for FILE in ${FILE_LIST}; do
if [[ "${FILE}" == "kubecfg.crt" ]] || [[ "${FILE}" == "kubecfg.key" ]]; then
chmod 600 "${CERTS_DIR}/${FILE}"
elif [[ "${FILE}" == "basic_auth.csv" ]] || [[ "${FILE}" == "known_tokens.csv" ]]; then
chmod 644 "${CERTS_DIR}/${FILE}"
else
chown root:root "${CERTS_DIR}/${FILE}"
chmod 660 "${CERTS_DIR}/${FILE}"
fi
done
}
function export_keystone_ssl(){
local KEYSTONE_CERTS_PATH="/srv/keystone"
local CERTS_DIR="/srv/kubernetes"
mkdir -p "${KEYSTONE_CERTS_PATH}"
openssl x509 -outform PEM -in "${CERTS_DIR}/ca.crt" -out "${KEYSTONE_CERTS_PATH}/ca.pem"
openssl x509 -outform PEM -in "${CERTS_DIR}/server.cert" -out "${KEYSTONE_CERTS_PATH}/keystone.pem"
openssl rsa -outform PEM -in "${CERTS_DIR}/server.key" -out "${KEYSTONE_CERTS_PATH}/keystonekey.pem" 1>/dev/null
# Waiting for apiserver ready
until /hyperkube kubectl get secret &>/dev/null; do
sleep 1
done
# Try to delete old certs and upload new certs
/hyperkube kubectl delete secret keystone-tls-certs &>/dev/null
/hyperkube kubectl create secret generic keystone-tls-certs --from-file="${KEYSTONE_CERTS_PATH}" --namespace=default 1>/dev/null \
&& echo "keystone certs uploaded as secret."
}
function main(){
if ! which curl &>/dev/null; then
apt-get update 1>/dev/null
apt-get install -y curl 1>/dev/null
fi
local DOMAIN_NAME="$1"
local DONT_HOLD="$2"
local ETCD_PATH="k8sup/cluster/k8s_certs"
local CERTS_DIR="/srv/kubernetes"
local CERTS_ON_ETCD=""
CERTS_ON_ETCD="$(check_certs_exist_on_etcd "${ETCD_PATH}")" || exit
if [[ "${CERTS_ON_ETCD}" == "true" ]]; then
download_kube_certs "${ETCD_PATH}" || exit 1
else
upload_kube_certs "${ETCD_PATH}" &
fi
mkdir -p "${CERTS_DIR}"
if [[ -f "/abac-policy-file.jsonl" ]]; then
cp -f "/abac-policy-file.jsonl" "${CERTS_DIR}"
fi
/setup-files.sh "${DOMAIN_NAME}" &
cp_kube_certs
if [[ "${DONT_HOLD}" != "DONT_HOLD" ]]; then
check_and_wait_all_cert_files_in_srv_kubernetes
export_keystone_ssl
sleep infinity
else
check_and_wait_all_certs_exist_on_etcd "${ETCD_PATH}"
check_and_wait_all_cert_files_in_srv_kubernetes
check_and_wait_all_cert_files_in_var_lib_kubelet_kubeconfig
exit 0
fi
}
main "$@"