Skip to content

Commit 97a85e2

Browse files
committed
add data-at-rest-encryption tests
1 parent bb360d9 commit 97a85e2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1003
-6
lines changed

e2e-tests/conf/vault-secret.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
apiVersion: v1
22
kind: Secret
33
metadata:
4-
name: some-name-vault
4+
name: vault-keyring-secret
55
type: Opaque
66
stringData:
77
keyring_vault.conf: |-

e2e-tests/functions

Lines changed: 220 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,12 @@ deploy_client() {
103103
kubectl -n "${NAMESPACE}" apply -f "${TESTS_CONFIG_DIR}/client.yaml"
104104
}
105105

106-
apply_s3_storage_secrets() {
106+
apply_minio_secret() {
107107
kubectl -n "${NAMESPACE}" apply -f "${TESTS_CONFIG_DIR}/minio-secret.yml"
108+
}
109+
110+
apply_s3_storage_secrets() {
111+
apply_minio_secret
108112
kubectl -n "${NAMESPACE}" apply -f "${TESTS_CONFIG_DIR}/cloud-secret.yml"
109113
}
110114

@@ -309,6 +313,217 @@ deploy_minio() {
309313
/usr/bin/aws --endpoint-url http://minio-service:9000 s3 mb s3://operator-testing"
310314
}
311315

316+
prepare_vault_tls() {
317+
local name=$1
318+
local namespace=$2
319+
local csr_name=vault-csr-${RANDOM}
320+
local csr_api_ver="v1"
321+
local csr_signer
322+
323+
if [[ ${platform} == "eks" ]]; then
324+
csr_signer=" signerName: beta.eks.amazonaws.com/app-serving"
325+
else
326+
csr_signer=" signerName: kubernetes.io/kubelet-serving"
327+
fi
328+
329+
openssl genrsa -out ${tmp_dir}/vault.key 2048
330+
cat <<EOF >${tmp_dir}/csr.conf
331+
[req]
332+
req_extensions = v3_req
333+
distinguished_name = req_distinguished_name
334+
[req_distinguished_name]
335+
[ v3_req ]
336+
basicConstraints = CA:FALSE
337+
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
338+
extendedKeyUsage = serverAuth
339+
subjectAltName = @alt_names
340+
[alt_names]
341+
DNS.1 = ${name}
342+
DNS.2 = ${name}.${namespace}
343+
DNS.3 = ${name}.${namespace}.svc
344+
DNS.4 = ${name}.${namespace}.svc.cluster.local
345+
IP.1 = 127.0.0.1
346+
EOF
347+
348+
openssl req -new \
349+
-key ${tmp_dir}/vault.key \
350+
-subj "/CN=system:node:${name}.${namespace}.svc;/O=system:nodes" \
351+
-out ${tmp_dir}/server.csr \
352+
-config ${tmp_dir}/csr.conf
353+
354+
cat <<EOF >${tmp_dir}/csr.yaml
355+
apiVersion: certificates.k8s.io/${csr_api_ver}
356+
kind: CertificateSigningRequest
357+
metadata:
358+
name: ${csr_name}
359+
spec:
360+
groups:
361+
- system:authenticated
362+
request: $(cat ${tmp_dir}/server.csr | base64 | tr -d '\n')
363+
${csr_signer}
364+
usages:
365+
- digital signature
366+
- key encipherment
367+
- server auth
368+
EOF
369+
370+
kubectl create -n ${namespace} -f ${tmp_dir}/csr.yaml
371+
sleep 10
372+
kubectl certificate approve ${csr_name}
373+
kubectl get csr ${csr_name} -o jsonpath='{.status.certificate}' >${tmp_dir}/serverCert
374+
openssl base64 -in ${tmp_dir}/serverCert -d -A -out ${tmp_dir}/vault.crt
375+
kubectl config view --raw --minify --flatten -o jsonpath='{.clusters[].cluster.certificate-authority-data}' | base64 -d >${tmp_dir}/vault.ca
376+
if [[ ${platform} == "openshift" ]]; then
377+
if [[ "x$(kubectl get namespaces | awk '{print $1}' | grep openshift-kube-controller-manager-operator)" != "x" ]]; then
378+
#Detecting openshift 4+
379+
kubectl -n openshift-kube-controller-manager-operator get secret csr-signer -o jsonpath='{.data.tls\.crt}' \
380+
| base64 -d >${tmp_dir}/vault.ca
381+
else
382+
ca_secret_name=$(kubectl -n default get secrets \
383+
| grep default \
384+
| grep service-account-token \
385+
| head -n 1 \
386+
| awk {'print $1'})
387+
kubectl -n default get secret ${ca_secret_name} -o jsonpath='{.data.ca\.crt}' \
388+
| base64 -d >${tmp_dir}/vault.ca
389+
fi
390+
fi
391+
392+
kubectl create secret generic ${name} \
393+
--namespace ${namespace} \
394+
--from-file=vault.key=${tmp_dir}/vault.key \
395+
--from-file=vault.crt=${tmp_dir}/vault.crt \
396+
--from-file=vault.ca=${tmp_dir}/vault.ca
397+
398+
}
399+
400+
_deploy_vault() {
401+
local name=$1
402+
local protocol=$2
403+
local platform=$3
404+
local namespace=$4
405+
local tmp_dir=$5
406+
407+
if kubectl get ns | grep ${namespace}; then
408+
echo "${namespace} is already exist, assuming Vault is running there."
409+
return
410+
fi
411+
412+
rm -rf ${tmp_dir}
413+
mkdir -p ${tmp_dir}
414+
415+
helm repo add hashicorp https://helm.releases.hashicorp.com
416+
helm repo update
417+
418+
kubectl create namespace "${namespace}"
419+
helm uninstall "$name" || :
420+
421+
echo "install Vault $name"
422+
423+
if [[ ${platform} == "openshift" ]]; then
424+
oc patch clusterrole system:auth-delegator --type='json' -p '[{"op":"add","path":"/rules/-", "value":{"apiGroups":["security.openshift.io"], "attributeRestrictions":null, "resourceNames": ["privileged"], "resources":["securitycontextconstraints"],"verbs":["use"]}}]'
425+
fi
426+
427+
if [ $protocol == "https" ]; then
428+
prepare_vault_tls ${name} ${namespace}
429+
helm install $name hashicorp/vault \
430+
--disable-openapi-validation \
431+
--version ${VAULT_VER} \
432+
--namespace "${namespace}" \
433+
--set dataStorage.enabled=false \
434+
--set global.tlsDisable=false \
435+
--set global.logLevel="trace" \
436+
--set global.platform="${platform}" \
437+
--set server.extraVolumes[0].type=secret \
438+
--set server.extraVolumes[0].name=$name \
439+
--set server.extraEnvironmentVars.VAULT_CACERT=/vault/userconfig/$name/vault.ca \
440+
--set server.standalone.config="
441+
listener \"tcp\" {
442+
address = \"[::]:8200\"
443+
cluster_address = \"[::]:8201\"
444+
tls_cert_file = \"/vault/userconfig/$name/vault.crt\"
445+
tls_key_file = \"/vault/userconfig/$name/vault.key\"
446+
tls_client_ca_file = \"/vault/userconfig/$name/vault.ca\"
447+
}
448+
449+
storage \"file\" {
450+
path = \"/vault/data\"
451+
}"
452+
else
453+
helm install $name hashicorp/vault \
454+
--disable-openapi-validation \
455+
--version ${VAULT_VER} \
456+
--namespace "${namespace}" \
457+
--set dataStorage.enabled=false \
458+
--set global.logLevel="trace" \
459+
--set global.platform="${platform}"
460+
fi
461+
462+
if [[ ${platform} == "openshift" ]]; then
463+
oc patch clusterrole $name-agent-injector-clusterrole --type='json' -p '[{"op":"add","path":"/rules/-", "value":{"apiGroups":["security.openshift.io"], "attributeRestrictions":null, "resourceNames": ["privileged"], "resources":["securitycontextconstraints"],"verbs":["use"]}}]'
464+
oc adm policy add-scc-to-user privileged $name-agent-injector
465+
fi
466+
467+
set +o xtrace
468+
retry=0
469+
echo -n "waiting for pod/$name-0 to be ready"
470+
until kubectl get -n ${namespace} pod/$name-0 -o 'jsonpath={.status.containerStatuses[0].state}' 2>/dev/null | grep 'running'; do
471+
echo -n .
472+
sleep 1
473+
let retry+=1
474+
if [[ $retry -ge 480 ]]; then
475+
kubectl -n ${namespace} describe pod/$name-0
476+
kubectl -n ${namespace} logs $name-0
477+
echo max retry count "$retry" reached. something went wrong with vault
478+
exit 1
479+
fi
480+
done
481+
set -o xtrace
482+
483+
kubectl -n ${namespace} exec -it $name-0 -- vault operator init -tls-skip-verify -key-shares=1 -key-threshold=1 -format=json >"$tmp_dir/$name"
484+
local unsealKey=$(jq -r ".unseal_keys_b64[]" <"$tmp_dir/$name")
485+
local token=$(jq -r ".root_token" <"$tmp_dir/$name")
486+
sleep 10
487+
488+
kubectl -n ${namespace} exec -it $name-0 -- vault operator unseal -tls-skip-verify "$unsealKey"
489+
kubectl -n ${namespace} exec -it $name-0 -- \
490+
sh -c "export VAULT_TOKEN=$token && export VAULT_LOG_LEVEL=trace \
491+
&& vault secrets enable --version=1 -tls-skip-verify -path=secret kv \
492+
&& vault audit enable file file_path=/vault/vault-audit.log"
493+
sleep 10
494+
}
495+
496+
deploy_vault() {
497+
local name=${1:-vault-service}
498+
local protocol=${2:-http}
499+
local platform=${3:-kubernetes}
500+
local namespace=${4:-${name}}
501+
502+
local tmp_dir=/tmp/vault
503+
echo "Using tmp dir: ${tmp_dir}"
504+
505+
_deploy_vault ${name} ${protocol} ${platform} ${namespace} ${tmp_dir}
506+
507+
local unsealKey=$(jq -r ".unseal_keys_b64[]" <"$tmp_dir/$name")
508+
local token=$(jq -r ".root_token" <"$tmp_dir/$name")
509+
510+
cat ${ROOT_REPO}/e2e-tests/conf/vault-secret.yaml \
511+
| sed -e "s/#token/$token/" \
512+
| sed -e "s/#vault_url/$protocol:\/\/$name.$name.svc.cluster.local:8200/" \
513+
| sed -e "s/#secret/secret/" >"${tmp_dir}/vault-secret.yaml"
514+
515+
if [ $protocol == "https" ]; then
516+
sed -e 's/^/ /' ${tmp_dir}/vault.ca >${tmp_dir}/vault.new.ca
517+
sed -i "s/#vault_ca/vault_ca/" "${tmp_dir}/vault-secret.yaml"
518+
sed -i "/#certVal/r ${tmp_dir}/vault.new.ca" "${tmp_dir}/vault-secret.yaml"
519+
sed -i "/#certVal/d" "${tmp_dir}/vault-secret.yaml"
520+
else
521+
sed -i "/#vault_ca/d" "${tmp_dir}/vault-secret.yaml"
522+
fi
523+
524+
kubectl apply -n "${NAMESPACE}" -f ${tmp_dir}/vault-secret.yaml
525+
}
526+
312527
retry() {
313528
local max=$1
314529
local delay=$2
@@ -789,10 +1004,10 @@ deploy_chaos_mesh() {
7891004
fi
7901005

7911006
echo "Waiting for chaos-mesh DaemonSet to be ready..."
792-
until [ "$(kubectl get daemonset chaos-daemon -n ${NAMESPACE} -o jsonpath='{.status.numberReady}')" = "$(kubectl get daemonset chaos-daemon -n ${NAMESPACE} -o jsonpath='{.status.desiredNumberScheduled}')" ]; do
793-
echo "Waiting for DaemonSet chaos-daemon..."
794-
sleep 5
795-
done
1007+
until [ "$(kubectl get daemonset chaos-daemon -n ${NAMESPACE} -o jsonpath='{.status.numberReady}')" = "$(kubectl get daemonset chaos-daemon -n ${NAMESPACE} -o jsonpath='{.status.desiredNumberScheduled}')" ]; do
1008+
echo "Waiting for DaemonSet chaos-daemon..."
1009+
sleep 5
1010+
done
7961011
}
7971012

7981013
destroy_chaos_mesh() {

e2e-tests/run-pr.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ auto-config
44
config
55
config-router
66
demand-backup
7+
async-data-at-rest-encryption
8+
gr-data-at-rest-encryption
79
gr-demand-backup
810
gr-demand-backup-haproxy
911
gr-finalizer

e2e-tests/run-release.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ auto-config
44
config
55
config-router
66
demand-backup
7+
async-data-at-rest-encryption
8+
gr-data-at-rest-encryption
79
gr-demand-backup
810
gr-demand-backup-haproxy
911
gr-finalizer
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestAssert
3+
timeout: 120
4+
---
5+
apiVersion: apps/v1
6+
kind: Deployment
7+
metadata:
8+
name: percona-server-mysql-operator
9+
status:
10+
availableReplicas: 1
11+
observedGeneration: 1
12+
readyReplicas: 1
13+
replicas: 1
14+
updatedReplicas: 1
15+
---
16+
apiVersion: apps/v1
17+
kind: Deployment
18+
metadata:
19+
name: minio-service
20+
status:
21+
availableReplicas: 1
22+
observedGeneration: 1
23+
readyReplicas: 1
24+
replicas: 1
25+
updatedReplicas: 1
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestStep
3+
commands:
4+
- timeout: 120
5+
script: |-
6+
set -o errexit
7+
set -o xtrace
8+
9+
source ../../functions
10+
init_temp_dir # do this only in the first TestStep
11+
12+
deploy_client
13+
deploy_operator
14+
15+
deploy_non_tls_cluster_secrets
16+
deploy_tls_cluster_secrets
17+
18+
apply_minio_secret
19+
deploy_minio
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestAssert
3+
timeout: 60
4+
---
5+
apiVersion: v1
6+
kind: Secret
7+
type: Opaque
8+
metadata:
9+
name: vault-keyring-secret
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestStep
3+
commands:
4+
- timeout: 180
5+
script: |-
6+
set -o errexit
7+
set -o xtrace
8+
9+
source ../../functions
10+
11+
deploy_vault
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestAssert
3+
timeout: 420
4+
---
5+
kind: StatefulSet
6+
apiVersion: apps/v1
7+
metadata:
8+
name: async-data-at-rest-encryption-mysql
9+
status:
10+
observedGeneration: 1
11+
replicas: 3
12+
readyReplicas: 3
13+
currentReplicas: 3
14+
updatedReplicas: 3
15+
collisionCount: 0
16+
---
17+
kind: StatefulSet
18+
apiVersion: apps/v1
19+
metadata:
20+
name: async-data-at-rest-encryption-haproxy
21+
status:
22+
observedGeneration: 1
23+
replicas: 3
24+
readyReplicas: 3
25+
currentReplicas: 3
26+
updatedReplicas: 3
27+
collisionCount: 0
28+
---
29+
kind: StatefulSet
30+
apiVersion: apps/v1
31+
metadata:
32+
name: async-data-at-rest-encryption-orc
33+
status:
34+
observedGeneration: 1
35+
replicas: 3
36+
readyReplicas: 3
37+
currentReplicas: 3
38+
updatedReplicas: 3
39+
collisionCount: 0
40+
---
41+
apiVersion: ps.percona.com/v1alpha1
42+
kind: PerconaServerMySQL
43+
metadata:
44+
name: async-data-at-rest-encryption
45+
status:
46+
mysql:
47+
ready: 3
48+
size: 3
49+
state: ready
50+
haproxy:
51+
ready: 3
52+
size: 3
53+
state: ready
54+
state: ready

0 commit comments

Comments
 (0)