forked from JovianX/kubectl-kubeconfig
-
Notifications
You must be signed in to change notification settings - Fork 0
/
kubectl-kubeconfig-generate
executable file
·422 lines (358 loc) · 13.5 KB
/
kubectl-kubeconfig-generate
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
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
#!/bin/bash
set -e
set -o pipefail
SERVICE_ACCOUNT_NAME="jovianx-admin"
NAMESPACE="jovianx-system"
CONTEXT=""
ROLE="cluster-admin"
UPLOAD_URL="https://hub.jovianx.app"
UPLOAD_AUTH_TOKEN=""
TARGET_FOLDER="/tmp/kube"
KUBECFG_FILE_NAME="kubeconfig-${SERVICE_ACCOUNT_NAME}-${NAMESPACE}.yaml"
KUBECFG_FILE_PATH="$TARGET_FOLDER/$KUBECFG_FILE_NAME"
OUTPUT_FILE="./$KUBECFG_FILE_NAME"
DEBUG=false
HELP_TEXT="
Generates administrative Kubeconfig file for your cluster.
This script generates a Kubeconfig file that allows full administrative access
to your cluster
Please note that this creates a Kubernetes service account
'$SERVICE_ACCOUNT_NAME' with *CLUSTER-ADMIN* role in the '$NAMESPACE' namespace.
Available parameters:
--context Name of existing context to use during generation of new
configuration. Defaults to current context of existing
configuration.
--debug if this flag set additional output will provided.
--jovianx-url JovianX host URL. Defaults to: '$UPLOAD_URL'
--jwt-token If was provided configuration will be uploaded to
JovianX Service Hub. Note: in this case configuration
file will not be created on your file system.
--namespace Name of namespace where to service account will be
created. Defaults to '$NAMESPACE'.
--output-file Path to creating Kubernetes configuration file.
Default: '$OUTPUT_FILE'.
--role Name of role during creation of cluster role binding.
Defaults to '$ROLE'.
--service-account Name of service account. Defaults to '$SERVICE_ACCOUNT_NAME'.
--help Print this message.
"
create_target_directory() {
[[ $DEBUG == true ]] && printf "%s" "Creating target directory to hold files in '${TARGET_FOLDER}'... "
mkdir -p "${TARGET_FOLDER}"
[[ $DEBUG == true ]] && printf "%s\n" "Done"
return 0
}
test_current_kubeconfig() {
[[ $DEBUG == true ]] && printf "%s" "Trying to get resoruces using current Kubeconfig... "
if [[ "$DEBUG" == true ]]; then
kubectl get pods --all-namespaces
else
kubectl get pods --all-namespaces > /dev/null
fi
[[ $DEBUG == true ]] && printf "%s\n" "Done"
return 0
}
test_generated_kubeconfig() {
[[ $DEBUG == true ]] && printf "%s" "Trying to get resources using generated Kubeconfig... "
if [[ "$DEBUG" == true ]]; then
KUBECONFIG=${OUTPUT_FILE} kubectl get pods --all-namespaces
else
KUBECONFIG=${OUTPUT_FILE} kubectl get pods --all-namespaces > /dev/null
fi
[[ $DEBUG == true ]] && printf "%s\n" "Done"
return 0
}
create_namespace() {
[[ $DEBUG == true ]] && printf "%s" "Creating namespace ${NAMESPACE}... "
if [[ "$DEBUG" == true ]]; then
kubectl create namespace "${NAMESPACE}"
else
kubectl create namespace "${NAMESPACE}" 2> /dev/null
fi
[[ $DEBUG == true ]] && printf "%s\n" "Done"
return 0
}
create_service_account() {
[[ $DEBUG == true ]] && printf "%s" "Creating a service account '${SERVICE_ACCOUNT_NAME}' in '${NAMESPACE}' namespace... "
if [[ "$DEBUG" == true ]]; then
kubectl create sa "${SERVICE_ACCOUNT_NAME}" --namespace "${NAMESPACE}"
else
kubectl create sa "${SERVICE_ACCOUNT_NAME}" --namespace "${NAMESPACE}" 2> /dev/null
fi
[[ $DEBUG == true ]] && printf "%s\n" "Done"
return 0
}
create_cluster_role_binding() {
[[ $DEBUG == true ]] && printf "%s" "Creating a cluster role binding cluster-admin... "
user="system:serviceaccount:${NAMESPACE}:${SERVICE_ACCOUNT_NAME}"
if [[ "$DEBUG" == true ]]; then
kubectl create clusterrolebinding jovianx-cluster-admin-binding --clusterrole "$ROLE" --user $user
else
kubectl create clusterrolebinding jovianx-cluster-admin-binding --clusterrole "$ROLE" --user $user 2> /dev/null
fi
[[ $DEBUG == true ]] && printf "%s\n" "Done"
return 0
}
get_secret_name_from_service_account() {
[[ $DEBUG == true ]] && printf "%s" "Getting secret of service account ${SERVICE_ACCOUNT_NAME} on ${NAMESPACE}... "
SECRET_NAME=$(kubectl get sa "${SERVICE_ACCOUNT_NAME}" --namespace="${NAMESPACE}" -o json | jq -r .secrets[].name)
[[ $DEBUG == true ]] && printf "%s\n" "Secret name: ${SECRET_NAME}"
return 0
}
extract_ca_crt_from_secret() {
[[ $DEBUG == true ]] && printf "%s" "Extracting ca.crt from secret... "
kubectl get secret --namespace "${NAMESPACE}" "${SECRET_NAME}" -o json | jq \
-r '.data["ca.crt"]' | base64 -d > "${TARGET_FOLDER}/ca.crt"
[[ $DEBUG == true ]] && printf "%s\n" "Done"
return 0
}
get_user_token_from_secret() {
[[ $DEBUG == true ]] && printf "%s" "Getting user token from secret... "
USER_TOKEN=$(kubectl get secret --namespace "${NAMESPACE}" "${SECRET_NAME}" -o json | jq -r '.data["token"]' | base64 -d)
[[ $DEBUG == true ]] && printf "%s\n" "Done"
return 0
}
set_kube_config_values() {
if [[ -z "$CONTEXT" ]]; then
[[ $DEBUG == true ]] && printf "%s" "No context was provided. Getting context... "
CONTEXT=$(kubectl config current-context)
[[ $DEBUG == true ]] && printf "%s\n" "Context: ${CONTEXT}"
fi
[[ $DEBUG == true ]] && printf "%s" "Getting cluster name... "
CLUSTER_NAME=$(kubectl config get-contexts "$CONTEXT" | awk '{print $3}' | tail -n 1)
[[ $DEBUG == true ]] && printf "%s\n" "Cluster name: ${CLUSTER_NAME}"
[[ $DEBUG == true ]] && printf "%s" "Getting endpoint... "
ENDPOINT=$(kubectl config view -o jsonpath="{.clusters[?(@.name == \"${CLUSTER_NAME}\")].cluster.server}")
[[ $DEBUG == true ]] && printf "%s\n" "Endpoint: ${ENDPOINT}"
# Set up the config
[[ $DEBUG == true ]] && printf "%s" "Assembling Kubernetes configuration. Setting a cluster entry... "
if [[ "$DEBUG" == true ]]; then
kubectl config set-cluster "${CLUSTER_NAME}" \
--kubeconfig="${KUBECFG_FILE_PATH}" \
--server="${ENDPOINT}" \
--certificate-authority="${TARGET_FOLDER}/ca.crt" \
--embed-certs=true
else
kubectl config set-cluster "${CLUSTER_NAME}" \
--kubeconfig="${KUBECFG_FILE_PATH}" \
--server="${ENDPOINT}" \
--certificate-authority="${TARGET_FOLDER}/ca.crt" \
--embed-certs=true > /dev/null
fi
[[ $DEBUG == true ]] && printf "%s\n" "Done"
[[ $DEBUG == true ]] && printf "%s" "Assembling Kubernetes configuration. Setting token credentials entry... "
if [[ "$DEBUG" == true ]]; then
kubectl config set-credentials \
"${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
--kubeconfig="${KUBECFG_FILE_PATH}" \
--token="${USER_TOKEN}"
else
kubectl config set-credentials \
"${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
--kubeconfig="${KUBECFG_FILE_PATH}" \
--token="${USER_TOKEN}" > /dev/null
fi
[[ $DEBUG == true ]] && printf "%s\n" "Done"
[[ $DEBUG == true ]] && printf "%s" "Assembling Kubernetes configuration. Setting a context entry... "
if [[ "$DEBUG" == true ]]; then
kubectl config set-context \
"${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
--kubeconfig="${KUBECFG_FILE_PATH}" \
--cluster="${CLUSTER_NAME}" \
--user="${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
--namespace="${NAMESPACE}"
else
kubectl config set-context \
"${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
--kubeconfig="${KUBECFG_FILE_PATH}" \
--cluster="${CLUSTER_NAME}" \
--user="${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
--namespace="${NAMESPACE}" > /dev/null
fi
[[ $DEBUG == true ]] && printf "%s\n" "Done"
[[ $DEBUG == true ]] && printf "%s" "Assembling Kubernetes configuration. Setting the current-context... "
if [[ "$DEBUG" == true ]]; then
kubectl config use-context "${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
--kubeconfig="${KUBECFG_FILE_PATH}"
else
kubectl config use-context "${SERVICE_ACCOUNT_NAME}-${NAMESPACE}-${CLUSTER_NAME}" \
--kubeconfig="${KUBECFG_FILE_PATH}" > /dev/null
fi
[[ $DEBUG == true ]] && printf "%s\n" "Done"
return 0
}
copy_generated_kubeconfig() {
[[ $DEBUG == true ]] && printf "%s" "Copying kubeconfig file to current directory and removing temporary working directory... "
cp "$KUBECFG_FILE_PATH" "$OUTPUT_FILE"
rm -Rf ${TARGET_FOLDER}
[[ $DEBUG == true ]] && printf "%s\n" "Done"
return 0
}
delete_generated_kubeconfig() {
[[ $DEBUG == true ]] && printf "%s" "Deleting kubeconfig file to current directory and removing temporary working directory... "
rm -Rf ${TARGET_FOLDER}
[[ $DEBUG == true ]] && printf "%s\n" "Done"
return 0
}
upload_configuration() {
[[ $DEBUG == true ]] && printf "%s" "Uploading configuration to JovianX Service Hub... "
UPLOAD_ENDPOINT="$UPLOAD_URL/api/v1/organization/kubernetes-configuration"
if [[ -z "$UPLOAD_AUTH_TOKEN" ]]; then
printf "%s\n" "Upload authentication token was not provided."
exit 1
fi
FILE_CONTENT=$(yq --output-format=json eval "${KUBECFG_FILE_PATH}")
if [[ "$DEBUG" == true ]]; then
curl --silent --show-error --write-out 'Server status code: %{http_code}\n' -X 'POST' "$UPLOAD_ENDPOINT" \
-H 'accept: application/json' \
-H "Authorization: Bearer $UPLOAD_AUTH_TOKEN" \
-H 'Content-Type: application/json' \
-d "$FILE_CONTENT"
else
response_code=$(curl --write-out '%{http_code}' --output /dev/null --silent -X 'POST' "$UPLOAD_ENDPOINT" \
-H 'accept: application/json' \
-H "Authorization: Bearer $UPLOAD_AUTH_TOKEN" \
-H 'Content-Type: application/json' \
-d "$FILE_CONTENT")
if [[ "$response_code" != "200" ]]; then
printf "%s\n" "Failed to upload configuration. Server response code is '$response_code'."
exit 1
else
printf "%s\n" "Successfully uploaded configuration."
fi
fi
[[ $DEBUG == true ]] && printf "%s\n" "Done"
return 0
}
while test $# -gt 0; do
case "$1" in
(--debug)
DEBUG=true
shift
;;
(--output-file)
shift
if test $# -gt 0; then
OUTPUT_FILE="$1"
else
printf "%s\n" "$HELP_TEXT"
exit 1
fi
shift
;;
(--output-file*)
OUTPUT_FILE=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
(--context)
shift
if test $# -gt 0; then
CONTEXT="$1"
else
printf "%s\n" "$HELP_TEXT"
exit 1
fi
shift
;;
(--context*)
CONTEXT=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
(--namespace)
shift
if test $# -gt 0; then
NAMESPACE="$1"
else
printf "%s\n" "$HELP_TEXT"
exit 1
fi
shift
;;
(--namespace*)
NAMESPACE=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
(--role)
shift
if test $# -gt 0; then
ROLE="$1"
else
printf "%s\n" "$HELP_TEXT"
exit 1
fi
shift
;;
(--role*)
ROLE=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
(--service-account)
shift
if test $# -gt 0; then
SERVICE_ACCOUNT_NAME="$1"
else
printf "%s\n" "$HELP_TEXT"
exit 1
fi
shift
;;
(--service-account*)
SERVICE_ACCOUNT_NAME=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
(--jovianx-url)
shift
if test $# -gt 0; then
UPLOAD_URL="$1"
else
printf "%s\n" "$HELP_TEXT"
exit 1
fi
shift
;;
(--jovianx-url*)
UPLOAD_URL=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
(--jwt-token)
shift
if test $# -gt 0; then
UPLOAD_AUTH_TOKEN="$1"
else
printf "%s\n" "$HELP_TEXT"
exit 1
fi
shift
;;
(--jwt-token*)
UPLOAD_AUTH_TOKEN=`echo $1 | sed -e 's/^[^=]*=//g'`
shift
;;
(--help)
printf "%s\n" "$HELP_TEXT"
exit 0
;;
*)
printf '%s\n' "Unknown argument $1."
printf "%s\n" "$HELP_TEXT"
exit 1
;;
esac
done
test_current_kubeconfig
create_target_directory
create_namespace || true
create_service_account || true
create_cluster_role_binding || true
get_secret_name_from_service_account
extract_ca_crt_from_secret
get_user_token_from_secret
set_kube_config_values
if [[ -n "$UPLOAD_AUTH_TOKEN" ]]; then
upload_configuration
delete_generated_kubeconfig
else
copy_generated_kubeconfig
test_generated_kubeconfig
printf "%s\n" "Kubernetes configuration saved to: $OUTPUT_FILE"
fi