Skip to content

Commit ca9571e

Browse files
[test] E2E test for kubeadm-full ETCD (#464)
* - Cleaned up the flatcar chainsaw-test.yaml - Previously the passed keys were kubeadm and flatcar * - added etcd StatefulSet into the assert list * - added test for checking if etcd-disk is added to spec * - added filter to the curl command * - fixed json parse error * - printing disk response to debug the issue * - updated logging mechanism and removed other tests to debug the particular test * - added filter to the linode api call and updated logging * - uncommented tests for other resources * - testing filter for API call * - updated cron job time for backup - added tests to check if objects were being backed up into the bucket * - added retry loops to tests which have scripts - delay of 30 seconds per retry * - fixed makefile error caused by stray test * - updated make file to generate a 32 char ephemeral key - updated chainsaw-test.yaml to use said 32 char ephemeral key - updated bucket retry time to 60 seconds per try * - removed additional logging * - fixed SSE_KEY generation in Makefile * - removed logging using echo - updated retry time to 40 seconds * - made SSE_KEY static - updated API calls to use environment variable LINODE_REGION * - gowrap_version set to v1.3.7 in Makefile * - fixed bucket object deletion using s5cmd - added steps to install s5cmd in Makefile * - updated s3cmd ref to s5cmd * - changed LOCALBIN to CACHE_BIN in Makefile. - this change was made to test and see if s5cmd path was accessible when cache_bin was used instead of localbin * - added s5cmd to make e2e test * - added API call to delete the bucket - added comments to bash scripts
1 parent 662a6b1 commit ca9571e

File tree

4 files changed

+209
-12
lines changed

4 files changed

+209
-12
lines changed

Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ test: generate fmt vet envtest ## Run tests.
152152
rm cover.out.tmp
153153

154154
.PHONY: e2etest
155-
e2etest: generate local-release local-deploy chainsaw
156-
GIT_REF=$(GIT_REF) SSE_KEY=$$(openssl rand -base64 32) $(CHAINSAW) test ./e2e --selector $(E2E_SELECTOR) $(E2E_FLAGS)
155+
e2etest: generate local-release local-deploy chainsaw s5cmd
156+
GIT_REF=$(GIT_REF) SSE_KEY=$$(openssl rand -base64 32) LOCALBIN=$(CACHE_BIN) $(CHAINSAW) test ./e2e --selector $(E2E_SELECTOR) $(E2E_FLAGS)
157157

158158
local-deploy: kind ctlptl tilt kustomize clusterctl
159159
$(CTLPTL) apply -f .tilt/ctlptl-config.yaml
@@ -316,6 +316,7 @@ NILAWAY ?= $(LOCALBIN)/nilaway
316316
GOVULNC ?= $(LOCALBIN)/govulncheck
317317
MOCKGEN ?= $(LOCALBIN)/mockgen
318318
GOWRAP ?= $(CACHE_BIN)/gowrap
319+
S5CMD ?= $(CACHE_BIN)/s5cmd
319320

320321
## Tool Versions
321322
KUSTOMIZE_VERSION ?= v5.4.1
@@ -332,6 +333,7 @@ NILAWAY_VERSION ?= latest
332333
GOVULNC_VERSION ?= v1.1.1
333334
MOCKGEN_VERSION ?= v0.4.0
334335
GOWRAP_VERSION ?= v1.3.7
336+
S5CMD_VERSION ?= v2.2.2
335337

336338
.PHONY: tools
337339
tools: $(KUSTOMIZE) $(CTLPTL) $(CLUSTERCTL) $(KUBECTL) $(CONTROLLER_GEN) $(CONVERSION_GEN) $(TILT) $(KIND) $(CHAINSAW) $(ENVTEST) $(HUSKY) $(NILAWAY) $(GOVULNC) $(MOCKGEN) $(GOWRAP)
@@ -427,3 +429,7 @@ gowrap: $(GOWRAP) ## Download gowrap locally if necessary.
427429
$(GOWRAP): $(CACHE_BIN)
428430
GOBIN=$(CACHE_BIN) go install github.com/hexdigest/gowrap/cmd/gowrap@$(GOWRAP_VERSION)
429431

432+
.PHONY: s5cmd
433+
s5cmd: $(S5CMD)
434+
$(S5CMD): $(CACHE_BIN)
435+
GOBIN=$(CACHE_BIN) go install github.com/peak/s5cmd/v2@$(S5CMD_VERSION)

e2e/capl-cluster-flavors/kubeadm-flatcar-vpcless-capl-cluster/chainsaw-test.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ metadata:
77
# Labels to allow the test to be triggered based on selector flag
88
labels:
99
all:
10-
kubeadm:
11-
flavors:
1210
flatcar:
11+
flavors:
1312
spec:
1413
bindings:
1514
# A short identifier for the E2E test run

e2e/capl-cluster-flavors/kubeadm-full-capl-cluster/assert-child-cluster-statefulsets.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,11 @@ metadata:
55
namespace: kube-system
66
status:
77
replicas: 1
8+
---
9+
apiVersion: apps/v1
10+
kind: StatefulSet
11+
metadata:
12+
name: etcd-backup
13+
namespace: kube-system
14+
status:
15+
replicas: 1

e2e/capl-cluster-flavors/kubeadm-full-capl-cluster/chainsaw-test.yaml

Lines changed: 192 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ spec:
1313
bindings:
1414
# Identifier for the E2E test run
1515
- name: run
16-
value: (join('-', ['e2e', 'kdm-ft', env('GIT_REF')]))
16+
value: (join('-', ['e2e', 'kdmf-tst', env('GIT_REF')]))
1717
- name: cluster
1818
# Format the cluster name
1919
value: (trim((truncate(($run), `32`)), '-'))
@@ -37,15 +37,17 @@ spec:
3737
- name: CLUSTERCTL_CONFIG
3838
value: (env('CLUSTERCTL_CONFIG'))
3939
- name: SSE_KEY
40-
value: (env('SSE_KEY'))
40+
value: "jU$n@AXXf3xseNd&U9ko4J#3B84D6YR6"
4141
- name: KONNECTIVITY_AGENT_REPLICAS
4242
value: '1' # Here, 1 is set for testing purposes. Default is 3.
4343
- name: CLUSTER_AUTOSCALER_VERSION
4444
value: 'v1.29.4'
45+
- name: ETCD_BACKUP_SCHEDULE
46+
value: '* * * * *'
4547
content: |
4648
set -e
4749
if [ -z "$SSE_KEY" ]; then
48-
echo "SSE_KEY not set" >&2
50+
echo "SSE_KEY not set" >&2
4951
exit 1
5052
else
5153
clusterctl generate cluster $CLUSTER -n $NAMESPACE \
@@ -203,17 +205,198 @@ spec:
203205
namespace: kube-system
204206

205207
# Test to check if konnectivity is working
206-
- clusters:
207-
kubeadm-full-cluster:
208-
kubeconfig: ./kubeadm-full-cluster-kubeconfig.yaml
209-
name: Testing to check if logs are retrievable
208+
- name: Testing to check if logs are retrievable
210209
try:
211210
- script:
212211
content: |
213-
KUBECONFIG=./kubeadm-full-cluster-kubeconfig.yaml kubectl logs csi-linode-controller-0 -n kube-system
212+
213+
MAX_RETRIES=5
214+
RETRY_DELAY=30 # 30 seconds delay before retrying
215+
ATTEMPT=0
216+
217+
# retry loop to check if logs are retrievable from a pod
218+
while [ $ATTEMPT -lt $MAX_RETRIES ]; do
219+
KUBECONFIG=./kubeadm-full-cluster-kubeconfig.yaml kubectl logs csi-linode-controller-0 -n kube-system
220+
221+
if [ -z "$error" ]; then
222+
break
223+
else
224+
ATTEMPT=$((ATTEMPT + 1))
225+
sleep $RETRY_DELAY
226+
fi
227+
done
228+
214229
check:
215230
($error == null): true
216231

232+
# Test to check if disks are added to the etcd spec
233+
- name: Testing to check if disks are added to the spec
234+
try:
235+
- script:
236+
env:
237+
- name: TARGET_API
238+
value: api.linode.com
239+
- name: TARGET_API_VERSION
240+
value: v4beta
241+
- name: URI
242+
value: linode/instances
243+
- name: FILTER
244+
value: (to_string({"tags":($cluster)}))
245+
content: |
246+
set -e
247+
248+
MAX_RETRIES=5
249+
RETRY_DELAY=30 # 30 second delay before retrying
250+
ATTEMPT=0
251+
ETCD_LABEL=""
252+
ETCD_STATUS=""
253+
254+
# retry loop to check if etcd disk is attached
255+
while [ $ATTEMPT -lt $MAX_RETRIES ]; do
256+
257+
# API call to get the linode ID
258+
RESPONSE=$(curl -s \
259+
-H "Authorization: Bearer $LINODE_TOKEN" \
260+
-H "X-Filter: $FILTER" \
261+
-H "Content-Type: application/json" \
262+
"https://$TARGET_API/$TARGET_API_VERSION/$URI")
263+
264+
LINODE_ID=$(echo "$RESPONSE" | jq -r '.data[0].id')
265+
266+
if [ -z "$LINODE_ID" ]; then
267+
echo "Error: LINODE_ID is empty. Response was: $RESPONSE"
268+
exit 1
269+
fi
270+
271+
# API call to check the list of disks attached
272+
DISK_RESPONSE=$(curl -s \
273+
-H "Authorization: Bearer $LINODE_TOKEN" \
274+
-H "Content-Type: application/json" \
275+
"https://$TARGET_API/$TARGET_API_VERSION/$URI/$LINODE_ID/disks?page=1&page_size=100")
276+
277+
ETCD_LABEL=$(echo "$DISK_RESPONSE" | jq -r '.data[2].label')
278+
ETCD_STATUS=$(echo "$DISK_RESPONSE" | jq -r '.data[2].status')
279+
280+
if [ "$ETCD_LABEL" == "etcd_disk" ] && [ "$ETCD_STATUS" == "ready" ]; then
281+
break
282+
else
283+
ATTEMPT=$((ATTEMPT + 1))
284+
sleep $RETRY_DELAY
285+
fi
286+
done
287+
288+
echo "{
289+
\"label\": \"$ETCD_LABEL\",
290+
\"status\": \"$ETCD_STATUS\"
291+
}"
292+
293+
check:
294+
($error): ~
295+
(json_parse($stdout)):
296+
label: etcd_disk
297+
status: ready
298+
299+
# Test to query the object storage bucket and check for data
300+
- name: Testing the object storage buckets
301+
try:
302+
- script:
303+
env:
304+
- name: TARGET_API
305+
value: api.linode.com
306+
- name: TARGET_API_VERSION
307+
value: v4beta
308+
- name: BUCKET_NAME
309+
value: (join('-', ['e2e', 'kdmf-tst', env('GIT_REF'), 'etcd-backup']))
310+
- name: URI
311+
value: (join('/', ['object-storage', 'buckets', env('LINODE_REGION')]))
312+
content: |
313+
set -e
314+
315+
MAX_RETRIES=5
316+
RETRY_DELAY=40 # 40 second delay before retrying
317+
ATTEMPT=0
318+
VALID_BUCKET=false
319+
320+
# retry loop to check if bucket is created and objects are present
321+
while [ $ATTEMPT -lt $MAX_RETRIES ]; do
322+
323+
# API call to get the bucket details
324+
RESPONSE=$(curl -s \
325+
-H "Authorization: Bearer $LINODE_TOKEN" \
326+
-H "Content-Type: application/json" \
327+
"https://$TARGET_API/$TARGET_API_VERSION/$URI/$BUCKET_NAME")
328+
329+
BUCKET_SIZE=$(echo "$RESPONSE" | jq -r '.size')
330+
BUCKET_OBJECTS=$(echo "$RESPONSE" | jq -r '.objects')
331+
332+
if [ "$BUCKET_SIZE" -gt 0 ] && [ "$BUCKET_OBJECTS" -gt 0 ]; then
333+
VALID_BUCKET=true
334+
break
335+
else
336+
ATTEMPT=$((ATTEMPT + 1))
337+
sleep $RETRY_DELAY
338+
fi
339+
done
340+
341+
echo "{
342+
\"status\": \"$VALID_BUCKET\"
343+
}"
344+
345+
check:
346+
($error): ~
347+
(json_parse($stdout)):
348+
status: "true"
349+
350+
# Test to check object storage buckets and delete it
351+
- name: Deleting object storage bucket
352+
try:
353+
- script:
354+
env:
355+
- name: CAPL_KUBECONFIG
356+
value: ./kubeadm-full-cluster-kubeconfig.yaml
357+
- name: BUCKET_NAME
358+
value: (join('-', ['e2e', 'kdmf-tst', env('GIT_REF'), 'etcd-backup']))
359+
- name: SECRET_NAME
360+
value: (join('-', ['e2e', 'kdmf-tst', env('GIT_REF'), 'etcd-backup-obj-key']))
361+
- name: BUCKET_ENDPOINT
362+
value: (join('.', [(join('-', [env('LINODE_REGION'), '1'])), 'linodeobjects', 'com' ]))
363+
- name: LOCAL_BIN
364+
value: (env('LOCALBIN'))
365+
- name: BUCKET_REGION
366+
value: env('LINODE_REGION')
367+
- name: TARGET_API
368+
value: api.linode.com
369+
- name: TARGET_API_VERSION
370+
value: v4beta
371+
- name: URI
372+
value: (join('/', ['object-storage', 'buckets', env('LINODE_REGION')]))
373+
content: |
374+
set -e
375+
376+
# Getting the keys from the CAPL cluster
377+
access_key=$(KUBECONFIG=$CAPL_KUBECONFIG kubectl get secret $SECRET_NAME -n kube-system -o=jsonpath='{.data.access_key}' | base64 -d)
378+
secret_key=$(KUBECONFIG=$CAPL_KUBECONFIG kubectl get secret $SECRET_NAME -n kube-system -o=jsonpath='{.data.secret_key}' | base64 -d)
379+
380+
#Storing the keys into a config file
381+
cat <<EOL > .s5cfg
382+
[default]
383+
aws_access_key_id=$access_key
384+
aws_secret_access_key=$secret_key
385+
aws_default_region=$BUCKET_REGION-1
386+
EOL
387+
388+
# delete the objects
389+
$LOCAL_BIN/s5cmd --credentials-file .s5cfg --endpoint-url https://$BUCKET_ENDPOINT rm s3://$BUCKET_NAME/etcd-backup/v2/*
390+
391+
# delete the bucket
392+
curl --request DELETE \
393+
-H "Authorization: Bearer $LINODE_TOKEN" \
394+
-H "Content-Type: application/json" \
395+
"https://$TARGET_API/$TARGET_API_VERSION/$URI/$BUCKET_NAME"
396+
397+
check:
398+
($error): ~
399+
217400
# Test to check if child cluster is deleted
218401
- name: Testing to see if child cluster is deleted
219402
try:
@@ -262,5 +445,6 @@ spec:
262445
content: |
263446
rm -f kubeadm-full-cluster.yaml
264447
rm -f kubeadm-full-cluster-kubeconfig.yaml
448+
rm -f .s5cfg
265449
check:
266450
($error == null): true

0 commit comments

Comments
 (0)