-
Notifications
You must be signed in to change notification settings - Fork 1
/
menu.sh
executable file
·368 lines (298 loc) · 11.7 KB
/
menu.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
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
#!/bin/bash
#
# Wizard to show available actions
#
BIN_DIR=$(dirname ${BASH_SOURCE[0]})
cd $BIN_DIR
# visual marker for task
declare -A done_status
# BASH does not support multi-dimensional/complex datastructures
# 1st column = action
# 2nd column = description
menu_items=(
"gke-wi-check,Validate workload identity status of GKE cluster"
""
"generic,Deploy generic image"
"simpleksa,Deploy image running as simple KSA"
"annotatedksa,Deploy image running as KSA which is annotated with GSA"
"jsonsecret,Deploy image with GCP json secret mounted"
"workloadid,Deploy image running as KSA with mapping to GSA"
""
"deployments,Validate health of deployments, KSA, GSA role"
""
"generic-test,Rest generic access to kubectl and gcloud"
"simpleksa-test,Test access to kubectl and gcloud"
"annotatedksa-test,Test access to kubectl and gcloud"
"jsonsecret-test,Test access to kubectl and gcloud"
"workloadid-test,Test access to kubectl and gcloud"
""
"ksa-can-i,Test KSA permissions using kubectl can-i"
""
"teardown,remove deployments, KSA, and KSA/GSA binding"
)
# "gcloud-user,Create GCP service account 'gcloud-user'"
function showMenu() {
echo ""
echo ""
echo "==========================================================================="
echo " MAIN MENU for $kubectl_context"
echo "==========================================================================="
echo ""
for menu_item in "${menu_items[@]}"; do
# skip empty lines
[ -n "$menu_item" ] || { printf "\n"; continue; }
menu_id=$(echo $menu_item | cut -d, -f1)
# eval done so that embedded variables get evaluated (e.g. MYKUBECONFIG)
label=$(eval echo $menu_item | cut -d, -f2-)
printf "%-18s %-60s %-10s\n" "$menu_id" "$label" "${done_status[$menu_id]}"
done
echo ""
} # showMenu
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m'
NF='\033[0m'
function echoGreen() {
echo -e "${GREEN}$1${NC}"
}
function echoRed() {
echo -e "${RED}$1${NC}"
}
function echoYellow() {
echo -e "${YELLOW}$1${NC}"
}
function ensure_binary() {
binary="$1"
install_instructions="$2"
binpath=$(which $binary)
if [ -z "$binpath" ]; then
echo "ERROR you must install $binary before running this wizard"
echo "$install_instructions"
exit 1
fi
}
function check_prerequisites() {
if [ ! -f gcloud-user.json ]; then
echo "ERROR you must create the GCP 'gcloud-user' service account before running these actions, run './create-gcloud-user-GSA.sh'"
exit 4
fi
if [ -z "$KUBECONFIG" ]; then
echo "ERROR you must have the environment variable 'KUBECONFIG' defined before running these actions"
exit 5
fi
# make sure binaries are installed
ensure_binary gcloud "install https://cloud.google.com/sdk/docs/install"
ensure_binary kubectl "install https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/"
#ensure_binary yq "download from https://github.com/mikefarah/yq/releases"
#ensure_binary jq "run 'sudo apt install jq'"
# show binary versions
# on apt, can be upgraded with 'sudo apt install --only-upgrade google-cloud-sdk -y'
gcloud --version | grep 'Google Cloud SDK'
kubectl version --short 2>/dev/null
#yq --version
#jq --version
# check for gcloud login context
gcloud projects list > /dev/null 2>&1
[ $? -eq 0 ] || gcloud auth login --no-launch-browser
gcloud auth list
} # check_prerequisites
###### MAIN ###########################################
check_prerequisites "$@"
# export so it can be used as envsubst templating variable
export project_id=$(gcloud config get-value project)
echo "GCP project_id=$project_id"
kubectl_context=$(kubectl config current-context)
echo "Kubetctl current context: $kubectl_context"
# loop where user can select menu items
lastAnswer=""
answer=""
while [ 1 == 1 ]; do
showMenu
test -t 0
if [ ! -z $lastAnswer ]; then echo "Last action was '${lastAnswer}'"; fi
read -p "Which action (q to quit) ? " answer
echo ""
case $answer in
gke-wi-check)
clusters=$(gcloud container clusters list --format="csv[no-heading](name,location)")
IFS=$'\n'
for cluster in $clusters ; do
cname=$(echo $cluster | cut -d, -f1)
echo "----CLUSTER $cname-----------------"
# if location has 2 dashes, then it is zonal GKE cluster. else regional
clocation=$(echo $cluster | cut -d, -f2)
if [[ $clocation =~ .*-.*-.* ]]; then
location_flag=$(echo "--zone=$clocation")
else
location_flag=$(echo "--region=$clocation")
fi
#set -x
wi_identity=$(gcloud container clusters describe $cname $location_flag --format="value(workloadIdentityConfig.workloadPool)")
if [ -z "$wi_identity" ]; then
echo "WARNING!!! workload identity not enabled for cluster $cname, many of these tests will not work as expected !!!!!!!!!!!!!!!!!!"
else
echo "workload identity for $cname: $wi_identity"
nodepool_name=$(gcloud container node-pools list --cluster=$cname $location_flag --format="value(name)")
pool_wi_mode=$(gcloud container node-pools describe $nodepool_name --cluster=$cname $location_flag --format="value(config.workloadMetadataConfig.mode)")
if [ -z "$pool_wi_mode" ]; then
echo "WARNING!!! node pool does not have workload metadata mode set, many of these tests will not work as expected until the nodepool is rebuilt with workload identity enabled!!!!!"
else
echo "workload mode for nodepool $nodepool_name is $pool_wi_mode"
fi
fi
#set +x
done
retVal=0
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
gcloud-user)
set -x
./create-gcloud-user-GSA.sh $project_id
retVal=$?
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
generic)
set -x
kubectl apply -f generic-test/generic-test.yaml 2>/dev/null
retVal=$?
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
simpleksa)
set -x
kubectl apply -f kubectl-with-simple-ksa/my-ksa.yaml 2>/dev/null
kubectl apply -f kubectl-with-simple-ksa/kubectl-ksa-test.yaml 2>/dev/null
retVal=$?
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
annotatedksa)
set -x
envsubst < kubectl-with-annotated-ksa/my-ksa-annotated.yaml | kubectl apply -f - 2>/dev/null
kubectl apply -f kubectl-with-annotated-ksa/kubectl-ksa-annotated-test.yaml 2>/dev/null
retVal=$?
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
jsonsecret)
set -x
gcloud-with-gsa-secret/load_gcloud_secret_into_k8s.sh
kubectl apply -f gcloud-with-gsa-secret/gcloud-gsa-test.yaml 2>/dev/null
retVal=$?
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
workloadid)
set -x
envsubst < workload-identity/my-wi-ksa.yaml | kubectl apply -f - 2>/dev/null
workload-identity/make-ksa-impersonate-gsa.sh
kubectl apply -f workload-identity/workload-identity-test.yaml 2>/dev/null
retVal=$?
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
teardown)
set -x
kubectl delete -f generic-test/generic-test.yaml 2>/dev/null
kubectl delete -f kubectl-with-simple-ksa/my-ksa.yaml 2>/dev/null
kubectl delete -f kubectl-with-simple-ksa/kubectl-ksa-test.yaml 2>/dev/null
envsubst < kubectl-with-annotated-ksa/my-ksa-annotated.yaml | kubectl delete -f - 2>/dev/null
kubectl delete -f kubectl-with-annotated-ksa/kubectl-ksa-annotated-test.yaml 2>/dev/null
kubectl delete -f gcloud-with-gsa-secret/gcloud-gsa-test.yaml 2>/dev/null
kubectl delete secret gke-key -n default 2>/dev/null
workload-identity/remove-ksa-impersonate-gsa.sh
envsubst < workload-identity/my-wi-ksa.yaml | kubectl delete -f - 2>/dev/null
kubectl delete -f workload-identity/workload-identity-test.yaml 2>/dev/null
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
deployments)
set -x
kubectl get deployments 2>/dev/null
kubectl get sa 2>/dev/null
gcloud iam service-accounts get-iam-policy \
--flatten="bindings[].members" \
--format="table(bindings.role, bindings.members)" \
gcloud-user@${project_id}.iam.gserviceaccount.com
gcloud projects get-iam-policy my-gkeproj1-10941 \
--flatten="bindings[].members" \
--format='table(bindings.role)' \
--filter="bindings.members:gcloud-user@${project_id}.iam.gserviceaccount.com"
retVal=$?
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
generic-test)
set -x
./test.sh generic-test
retVal=$?
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
simpleksa-test)
set -x
./test.sh kubectl-ksa-test
retVal=$?
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
annotatedksa-test)
set -x
./test.sh kubectl-ksa-annotated-test
retVal=$?
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
jsonsecret-test)
set -x
./test.sh gcloud-gsa-test
retVal=$?
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
workloadid-test)
set -x
./test.sh workload-identity-test
retVal=$?
set +x
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
ksa-can-i)
echo "--- service account my-ksa ---"
echo "should be able to list pods"
kubectl auth can-i list pods --namespace default --as system:serviceaccount:default:my-ksa 2>/dev/null
echo "should NOT be able to list daemonset"
kubectl auth can-i list daemonsets --namespace default --as system:serviceaccount:default:my-ksa 2>/dev/null
echo "should be able to list replicasets"
kubectl auth can-i list replicasets --namespace default --as system:serviceaccount:default:my-ksa 2>/dev/null
echo ""
echo "--- service account my-ksa-annotated ---"
echo "should be able to list pods"
kubectl auth can-i list pods --namespace default --as system:serviceaccount:default:my-ksa-annotated 2>/dev/null
echo "should be able to list daemonsets"
kubectl auth can-i list daemonsets --namespace default --as system:serviceaccount:default:my-ksa-annotated 2>/dev/null
echo "should NOT be able to list replicasets"
kubectl auth can-i list replicasets --namespace default --as system:serviceaccount:default:my-ksa-annotated 2>/dev/null
echo ""
echo "--- service account my-wi-ksa ---"
echo "should be able to list pods"
kubectl auth can-i list pods --namespace default --as system:serviceaccount:default:my-wi-ksa 2>/dev/null
echo "should be able to list daemonsets"
kubectl auth can-i list daemonsets --namespace default --as system:serviceaccount:default:my-wi-ksa 2>/dev/null
echo "should NOT be able to list deployments"
kubectl auth can-i list deployments --namespace default --as system:serviceaccount:default:my-wi-ksa 2>/dev/null
retVal=0
[ $retVal -eq 0 ] && done_status[$answer]="OK" || done_status[$answer]="ERR"
;;
q|quit|0)
echo "QUITTING"
exit 0;;
*)
echoRed "ERROR that is not one of the options, $answer";;
esac
lastAnswer=$answer
echo "press <ENTER> to continue..."
read -p "" foo
done