forked from aws/aws-nitro-enclaves-with-k8s
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenclavectl
executable file
·361 lines (294 loc) · 9.77 KB
/
enclavectl
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
#!/bin/bash
# Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
MY_VERSION="0.1.0"
MY_NAME="enclavectl"
MY_DESC="AWS Nitro Enclaves with K8s deployment tool"
source "$(dirname $(realpath $0))/scripts/common.sh"
# Configuration items
CONFIG_NAMES=(region instance_type eks_cluster_name eks_worker_node_name eks_worker_node_capacity k8s_version node_enclave_cpu_limit node_enclave_memory_limit_mib)
# Utility functions and definitions
source "$SCRIPTS_DIR/utils.sh"
# Scripts
readonly CREATE_LAUNCH_TEMPLATE="00_create_launch_template.sh"
readonly CREATE_EKS_CLUSTER="01_create_eks_cluster.sh"
readonly ENABLE_DEVICE_PLUGIN="02_enable_device_plugin.sh"
readonly BUILD_ENCLAVE_APPS="03_build_enclave_apps.sh"
readonly BUILD_IMAGE="04_build_image.sh"
readonly PUSH_IMAGE="05_push_image.sh"
readonly RUN_APP="06_run_app.sh"
readonly STOP_APP="07_stop_app.sh"
readonly CLEANUP_RESOURCES="99_cleanup_resources.sh"
USAGE="\
$MY_NAME v$MY_VERSION - $MY_DESC
Usage: $(basename "$0") <command> [arguments]
Commands:
configure Prepare the setup configuration
--file The file containing the settings for configuration (i.e. settings.json)
setup Setup a Nitro Enable enabled EKS cluster based on input configuration
- Generates a basic EC2 Launch Template for Nitro Enclaves and UserData
- Creates an EKS cluster with a managed node-group of configured capacity
- Deploys the Nitro Enclaves K8s Device plugin
build Build a Nitro Enclave based application for deployment
--image The application image name.
push Push the Nitro Enclaves application container to a remote auto-generated
private ECR repository.
--image The application image name
run Generate the deployment specification for the Nitro Enclaves application
and deploy it
--image The application image name
[--prepare-only] Only generate the application deployment specification file without
deploying it
stop Terminate the Nitro Enclaves with K8s application deployed via the 'run' command
--image The application image name
cleanup Clean up all the resources previously created via the 'setup' command
[--force] Ignores errors and force cleans all resources and configuration
"
# Validate number of arguments given to a function.
#
validate_arg_count() {
local arg_count=$1; shift
for arg in "$@"
do
[[ "$arg_count" == "$arg" ]] && { return; }
done
die "Invalid arguments. Please use \`$MY_NAME help\` for help."
}
# Print usage
#
cmd_help() {
say "$USAGE"
}
# Ensure basic dependencies of the project are installed.
ensure_basic_deps() {
which docker > /dev/null 2>&1
ok_or_die "docker not found. Aborting." \
"Please make sure you have docker installed. For more information, see" \
"https://docs.docker.com/desktop/install/linux-install"
which jq > /dev/null 2>&1
ok_or_die "jq not found. Aborting." \
"Please make sure you have jq package installed."
}
# Ensure eksctl and kubectl are available on this deployment machine
ensure_eks_deps() {
which eksctl > /dev/null 2>&1
ok_or_die "eksctl not found. Aborting." \
"Please make sure you have eksctl installed. For more information, see" \
"https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html."
which kubectl > /dev/null 2>&1
ok_or_die "kubectl not found. Aborting." \
"Please make sure you have kubectl installed. For more information, see" \
"https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html."
}
exec_subscript() {
source "$1"
shift
main "$@"
}
apply_configuration() {
local settings=$1
local json_name=$2
local ret
truncate -s 0 "$WORKING_DIR/$FILE_CONFIGURATION"; ret=$?
[[ $ret -eq 0 ]] && {
for item in "${CONFIG_NAMES[@]}"
do
local value
value=$(echo "$settings" | jq -r ".$item"); ret=$?
[[ "$value" = "null" ]] && {
say_err "$item value is not set in the $json_name file!";
ret=$FAILURE;
rm -f "$WORKING_DIR/$FILE_CONFIGURATION"
break
}
echo "CONFIG_$(to_upper_case ${item})=\"$value\"" >> "$WORKING_DIR/$FILE_CONFIGURATION"
done
}
return $ret
}
try_create_setup_uuid() {
local uuid_pattern='^\{?[A-Z0-9a-z]{8}-[A-Z0-9a-z]{4}-[A-Z0-9a-z]{4}-[A-Z0-9a-z]{4}-[A-Z0-9a-z]{12}\}?$'
CONFIG_SETUP_UUID=""
# Try loading the UUID from file.
[[ -f $WORKING_DIR/$FILE_SETUP_ID ]] && { CONFIG_SETUP_UUID=$(<"$WORKING_DIR/$FILE_SETUP_ID"); }
[[ "${CONFIG_SETUP_UUID}" != "" ]] || {
say "Setup UUID doesn't exist. Creating one..."
CONFIG_SETUP_UUID=$(uuidgen)
}
# Check if the UUID is valid.
[[ $CONFIG_SETUP_UUID =~ $uuid_pattern ]] || {
die "Your existing configuration seems corrupted!" \
"Run './$MY_NAME cleanup' to clean invalid setup configuration" \
"and try restarting demo setup. If you already created some resources, you" \
"need remove them manually."
}
echo "$CONFIG_SETUP_UUID" > "$WORKING_DIR/$FILE_SETUP_ID"
ok_or_die "Cannot create session UUID file!" \
"Please ensure that you have write access to the project folder."
say "Using setup UUID: $CONFIG_SETUP_UUID"
}
try_load_configuration() {
[[ -f "$WORKING_DIR/$FILE_CONFIGURATION" ]] && {
source "$WORKING_DIR/$FILE_CONFIGURATION"
for item in "${CONFIG_NAMES[@]}"
do
local var_name="CONFIG_$(to_upper_case ${item})"
local value=${!var_name}
[[ $value = "" || $value = "null" ]] && {
say_warn "The configuration seems corrupted! Ignoring existing configuration..."
rm -f "$WORKING_DIR/$FILE_CONFIGURATION"
return
}
done
}
[[ -f "$WORKING_DIR/$FILE_CONFIGURATION" ]] && \
CONFIG_SETUP_UUID=$(<"$WORKING_DIR/$FILE_SETUP_ID");
}
cmd_configure() {
validate_arg_count $# 2
case $1 in
--file)
[ -f "$WORKING_DIR/$FILE_CONFIGURATION" ] && {
say_warn "Project settings have already been configured." \
"To apply new settings, please clean up the resources first" \
"and try again."
exit 0
}
settings_file="$2";
;;
*)
die "Invalid argument: $1. Please use \`$0 help\` for help.";;
esac
# Create a setup uuid. Load if it already exists.
try_create_setup_uuid
local settings
settings=$(cat "$settings_file" 2> /dev/null)
ok_or_die "Cannot open the settings file: $settings_file"
echo "$settings" | jq '.' 2>&1 > /dev/null
ok_or_die "Cannot parse the settings file."
apply_configuration "$settings" "$settings_file"
ok_or_die "Cannot create configuration from $settings_file!"
say "Using configuration"
echo "$settings" | jq '.'
say "Configuration finished successfully."
}
cmd_setup() {
validate_arg_count $# 0
say "Running setup..."
# Nitro Enclave Launch Template
exec_subscript "$SCRIPTS_DIR/$CREATE_LAUNCH_TEMPLATE"
ok_or_die "Cannot create EC2 Launch Template."
# EKS Cluster
exec_subscript "$SCRIPTS_DIR/$CREATE_EKS_CLUSTER"
ok_or_die "Cannot create EKS Cluster."
# Enable Device Plugin
exec_subscript "$SCRIPTS_DIR/$ENABLE_DEVICE_PLUGIN"
ok_or_die "Error while enabling the device plugin."
say "Done."
}
cmd_build() {
validate_arg_count $# 2
case $1 in
--image)
exec_subscript "$SCRIPTS_DIR/$BUILD_ENCLAVE_APPS" "$2"
ok_or_die "Cannot build enclave applications for $2!"
exec_subscript "$SCRIPTS_DIR/$BUILD_IMAGE" "$2"
ok_or_die "Cannot build docker image for $2!"
;;
*)
die "Invalid arguments. Please use \`$0 help\` for help."
esac
}
cmd_push() {
validate_arg_count $# 2
case $1 in
--image)
exec_subscript "$SCRIPTS_DIR/$PUSH_IMAGE" "$2"
ok_or_die "Cannot push docker image for $2!"
;;
*)
die "Invalid arguments. Please use \`$0 help\` for help."
esac
}
cmd_run() {
validate_arg_count $# 2 3
local image=""
local prepare_only=false
while [[ $# -ge 1 ]]
do
case $1 in
"--image")
image=$2;
shift;
;;
"--prepare-only")
prepare_only=true
;;
*)
die "Invalid arguments. Please use \`$0 help\` for help."
esac
shift;
done
exec_subscript "$SCRIPTS_DIR/$RUN_APP" "$image" "$prepare_only"
ok_or_die "Error while running application!"
}
cmd_stop() {
validate_arg_count $# 2
case $1 in
--image)
exec_subscript "$SCRIPTS_DIR/$STOP_APP" "$2"
ok_or_die "Error while stopping the application!"
;;
*)
die "Invalid arguments. Please use \`$0 help\` for help."
esac
}
cmd_cleanup() {
validate_arg_count $# 0 1
local ignore_errors=false
case $1 in
--force)
ignore_errors=true
;;
"")
;;
*)
die "Invalid arguments. Please use \`$0 help\` for help."
esac
exec_subscript "$SCRIPTS_DIR/$CLEANUP_RESOURCES" "$ignore_errors"
ok_or_die "Cannot clean resources due to previous errors."
}
main() {
if [ "$#" -eq 0 ]; then
cmd_help
exit 1
fi
# Ensure basic dependencies
ensure_basic_deps
# Try loading applied settings.
try_load_configuration
local cmd="$1"
case "$1" in
-h|help)
cmd_help
exit 1
;;
-c|configure)
shift
cmd_configure "$@"
;;
*)
declare -f "cmd_$cmd" > /dev/null
ok_or_die "Unknown command: $1. Please use \`$MY_NAME help\` for help."
case "$1" in
setup|run|stop)
ensure_eks_deps
;;
esac
[[ ! -f $WORKING_DIR/$FILE_CONFIGURATION ]] && \
die "The demo hasn't been configured yet. Please use \`$MY_NAME help\` to know how to configure."
cmd_"$@"
;;
esac
}
main "${@}"