-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcli
More file actions
executable file
·263 lines (226 loc) · 6.38 KB
/
cli
File metadata and controls
executable file
·263 lines (226 loc) · 6.38 KB
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
#!/bin/bash
set -e
SCRIPT=$(readlink -f "$0")
SCRIPT_PATH=$(dirname "$SCRIPT")
export TF_SKIP_PROVIDER_VERIFY=true
export CLOUD_PROVIDER="azure"
export ARM_SUBSCRIPTION_ID="16c3f0f7-3a06-449e-8ac6-ec2d63078996"
check_dependencies() {
# Define required dependencies
dependencies=("terraform" "ssh" "telnet" "jq")
# Check each dependency
for cmd in "${dependencies[@]}"; do
if ! command -v "$cmd" &> /dev/null; then
echo "$cmd is not installed"
exit 1
fi
done
}
check_ssh_key() {
# azure does not support id_ed25519
# check for ssh key
if [ ! -e "$HOME/.ssh/id_rsa.pub" ]
then
echo "SSH key does not exist"
exit 1
fi
}
check_cloud_credentials() {
# CLOUD_PROVIDER
if [ -z "${CLOUD_PROVIDER}" ]
then
echo "CLOUD_PROVIDER is not set"
exit 1
fi
# cloud provider credentials
if [ "$CLOUD_PROVIDER" == "google_cloud" ]
then
if [ -z "${GOOGLE_APPLICATION_CREDENTIALS}" ]
then
echo "GOOGLE_APPLICATION_CREDENTIALS is not set"
exit 1
fi
elif [ "$CLOUD_PROVIDER" == "vultr" ]
then
if [ -z "${VULTR_API_KEY}" ]
then
echo "VULTR_API_KEY is not set"
exit 1
fi
elif [ "$CLOUD_PROVIDER" == "azure" ]
then
if [ -z "${ARM_SUBSCRIPTION_ID}" ]
then
echo "ARM_SUBSCRIPTION_ID is not set"
exit 1
fi
elif [ "$CLOUD_PROVIDER" == "digitalocean" ]
then
if [ -z "${DIGITALOCEAN_TOKEN}" ]
then
echo "DIGITALOCEAN_TOKEN is not set"
exit 1
fi
elif [ "$CLOUD_PROVIDER" == "hetzner" ]
then
if [ -z "${HCLOUD_TOKEN}" ]
then
echo "HCLOUD_TOKEN is not set"
exit 1
fi
elif [ "$CLOUD_PROVIDER" == "aws" ]
then
if [ -z "${AWS_ACCESS_KEY_ID}" ]
then
echo "AWS_ACCESS_KEY_ID is not set"
exit 1
fi
if [ -z "${AWS_SECRET_ACCESS_KEY}" ]
then
echo "AWS_SECRET_ACCESS_KEY is not set"
exit 1
fi
elif [ "$CLOUD_PROVIDER" == "lima" ]
then
if ! command -v limactl &> /dev/null
then
echo "limactl is not installed"
exit 1
fi
elif [ "$CLOUD_PROVIDER" == "oracle" ]
then
echo "TODO: check for private key file"
else
echo "unknown cloud provider: $CLOUD_PROVIDER"
exit 1
fi
}
accept_ssh_key() {
# Remove any old fingerprint from IPs being re-used, only if it exists
if ssh-keygen -F $instance_ipv4 > /dev/null 2>&1; then
ssh-keygen -R $instance_ipv4
fi
# Accept the SSH fingerprint
if ! ssh-keygen -F $instance_ipv4 > /dev/null
then
ssh-keyscan -H -p ${instance_ssh_port} $instance_ipv4 >> ~/.ssh/known_hosts
fi
}
wait_for_host() {
echo "Waiting for ${instance_ipv4} to become available on port ${instance_ssh_port}..."
while ! (echo > /dev/tcp/${instance_ipv4}/${instance_ssh_port}) 2>/dev/null
do
sleep 1
done
echo "${instance_ipv4} is now available."
}
terraform_destroy() {
module=$1
pushd terraform/$module/
terraform init
terraform destroy -auto-approve
popd
}
terraform_apply() {
module=$1
pushd terraform/$module/
terraform init
terraform apply -auto-approve
popd
}
create_cluster_ssh_tunnel() {
# Function to check if the tunnel is already running
is_tunnel_running() {
ps -ef | grep -E "ssh.*-L 6443:localhost:6443.*${instance_ipv4}" | grep -v grep > /dev/null
}
echo "Checking for existing SSH tunnel..."
if is_tunnel_running; then
echo "SSH tunnel already running"
else
echo "Starting SSH tunnel..."
ssh -fN -L 6443:localhost:6443 -p ${instance_ssh_port} ${instance_username}@${instance_ipv4}
fi
}
cmd_create() {
# 1. Pre-flight checks
check_dependencies
check_ssh_key
check_cloud_credentials
# 2. Infrastructure provisioning
#terraform_apply 00-vm
load_instance_details
# 3. Cluster bootstrap
wait_for_host
accept_ssh_key
terraform_apply 01-k3s
create_cluster_ssh_tunnel
# 4. Platform setup
terraform_apply 02-platform
# 5. Workload deployment
#terraform_apply 03-workloads
}
load_instance_details() {
pushd terraform/00-vm/
# Check if terraform outputs exist and are not empty
if [ "$(terraform output -json 2>/dev/null)" = "{}" ]; then
echo "Error: No terraform outputs found."
exit 1
fi
# Get and verify each output
instance_ipv4=$(terraform output -raw instance_ipv4 2>/dev/null) || { echo "Error: instance_ipv4 output not found"; exit 1; }
instance_username=$(terraform output -raw instance_username 2>/dev/null) || { echo "Error: instance_username output not found"; exit 1; }
instance_ssh_port=$(terraform output -raw instance_ssh_port 2>/dev/null) || { echo "Error: instance_ssh_port output not found"; exit 1; }
popd
}
cmd_connect() {
load_instance_details
# TODO: make sure we have provisioned and these variables are set correctly
ssh -p $instance_ssh_port $instance_username@$instance_ipv4
}
cmd_cleanup() {
# kill tunnels
ps -W | grep "ssh.*-L 6443:localhost:6443" | awk '{print $1}' | xargs -r kill -9
# terraform destroy
terraform_destroy 00-vm
# cleanup temp files
rm -rf /tmp/vm_info.txt
rm -rf $SCRIPT_PATH/terraform/01-k3s/kubeconfig
# cleanup all tfstate files
pushd terraform
find ./00-vm ./01-k3s ./02-platform ./03-workloads \
-type d -name ".terraform" -exec rm -rf {} \; -prune \
-o -type f -name ".terraform.lock.hcl" -delete \
-o -type f -name "*.tfstate" -delete \
-o -type f -name "*.tfstate.backup" -delete
popd
}
# usage
usage() {
echo "Usage: cli <command>"
echo ""
echo "Commands:"
echo " create Create a new instance"
echo " connect SSH into the instance"
echo " cleanup Destroy the instance and clean up local files"
echo " help Show this help message"
}
# route commands
case $1 in
create)
cmd_create
;;
connect)
cmd_connect
;;
cleanup)
cmd_cleanup
;;
help|--help|-h|"")
usage
;;
*)
echo "Unknown command: $1"
usage
exit 1
;;
esac