diff --git a/.gitlab/ci/shellcheck.gitlab-ci.yml b/.gitlab/ci/shellcheck.gitlab-ci.yml index 956ba27b5d83c7693acf4f9c01bea13766d8c491..4b559e061ba7841e356a1ea71b4445c5da30940b 100644 --- a/.gitlab/ci/shellcheck.gitlab-ci.yml +++ b/.gitlab/ci/shellcheck.gitlab-ci.yml @@ -3,7 +3,7 @@ test-shellcheck: image: koalaman/shellcheck-alpine:stable needs: [] script: - - shellcheck src/bin/auto-deploy test/verify-deployment-database + - shellcheck src/bin/auto-deploy test/verify-deployment-database test/verify-application-secret test-shfmt: stage: test @@ -12,4 +12,4 @@ test-shfmt: entrypoint: ["/bin/sh", "-c"] needs: [] script: - - shfmt -i 2 -ci -l -d src/bin/* + - shfmt -i 2 -ci -l -d src/bin/auto-deploy test/verify-deployment-database test/verify-application-secret diff --git a/.gitlab/ci/test.gitlab-ci.yml b/.gitlab/ci/test.gitlab-ci.yml index 542668a7b2597445ccf7e5454a4ed163df77f2e5..ecbe3860e04d01585ea2a803a51bb95a7c292f4d 100644 --- a/.gitlab/ci/test.gitlab-ci.yml +++ b/.gitlab/ci/test.gitlab-ci.yml @@ -395,10 +395,13 @@ test-create-application-secret: KUBE_NAMESPACE: default CI_ENVIRONMENT_SLUG: production K8S_SECRET_CODE: 12345 + K8S_SECRET_CODE_MULTILINE: "12345 + NEW LINE" script: - auto-deploy create_application_secret "stable" - kubectl get secrets -n $KUBE_NAMESPACE - kubectl get secrets production-secret -n $KUBE_NAMESPACE + - ./test/verify-application-secret test-delete: extends: test-deploy diff --git a/Dockerfile b/Dockerfile index 99c46f0cd0303f9517f4cef9714ea818e2346513..65397efe3f30555f327fa120ac639fe4df28b05d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,6 +13,7 @@ RUN apk add --no-cache openssl curl tar gzip bash jq \ && curl -sSL -o /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub \ && curl -sSL -O https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-${GLIBC_VERSION}.apk \ && apk add glibc-${GLIBC_VERSION}.apk \ + && apk add ruby jq \ && rm glibc-${GLIBC_VERSION}.apk RUN ln -s /build/bin/* /usr/local/bin/ diff --git a/src/bin/auto-deploy b/src/bin/auto-deploy index 3d3bf8745f7bd1eff687a336b53550f5314691ef..9d3f37f6da86fea00c38596bae9e222111689262 100755 --- a/src/bin/auto-deploy +++ b/src/bin/auto-deploy @@ -428,22 +428,22 @@ function delete() { # function create_application_secret() { local track="${1-stable}" + local k8s_secrets_file # shellcheck disable=SC2155 # declare and assign separately to avoid masking return values. export APPLICATION_SECRET_NAME=$(application_secret_name "$track") - env | sed -n "s/^K8S_SECRET_\(.*\)$/\1/p" >k8s_prefixed_variables + k8s_secrets_file=$(mktemp) - kubectl create secret \ - -n "$KUBE_NAMESPACE" generic "$APPLICATION_SECRET_NAME" \ - --from-env-file k8s_prefixed_variables -o yaml --dry-run | - kubectl replace -n "$KUBE_NAMESPACE" --force -f - + /build/bin/auto-deploy-application-secrets-yaml "$k8s_secrets_file" + + kubectl replace -f "$k8s_secrets_file" -n "$KUBE_NAMESPACE" --force # shellcheck disable=SC2002 # useless cat, prefer cmd < file # shellcheck disable=SC2155 # declare and assign separately to avoid masking return values. - export APPLICATION_SECRET_CHECKSUM=$(cat k8s_prefixed_variables | sha256sum | cut -d ' ' -f 1) + export APPLICATION_SECRET_CHECKSUM=$(cat "$k8s_secrets_file" | sha256sum | cut -d ' ' -f 1) - rm k8s_prefixed_variables + rm "$k8s_secrets_file" } function application_secret_name() { diff --git a/src/bin/auto-deploy-application-secrets-yaml b/src/bin/auto-deploy-application-secrets-yaml new file mode 100755 index 0000000000000000000000000000000000000000..00694430cf05c77f62d0aec399dbf5d15d23eb7d --- /dev/null +++ b/src/bin/auto-deploy-application-secrets-yaml @@ -0,0 +1,21 @@ +#!/usr/bin/ruby + +require 'yaml' +require 'base64' + +prefix_regex = /^K8S_SECRET_/ + +File.open(ARGV[0], 'w') { |file| + data = ENV + .select { |k, v| k =~ prefix_regex } + .transform_keys { |k| k.sub(prefix_regex, '') } + .transform_values {|v| Base64.strict_encode64 v } + kube_config = { + 'apiVersion' => 'v1', + 'kind' => 'Secret', + 'metadata' => { 'name' => ENV['APPLICATION_SECRET_NAME'] }, + 'type' => 'Opaque', + 'data' => data + } + file.write kube_config.to_yaml +} \ No newline at end of file diff --git a/test/verify-application-secret b/test/verify-application-secret new file mode 100755 index 0000000000000000000000000000000000000000..a4ca6bbff6592f0363d1f8527c010eb49d64b387 --- /dev/null +++ b/test/verify-application-secret @@ -0,0 +1,7 @@ +#!/bin/bash -e + +result=$(kubectl -n "$KUBE_NAMESPACE" get secret production-secret -o json | jq .data.CODE | xargs echo | base64 -d) +if [[ "$result" != "$K8S_SECRET_CODE" ]]; then exit 1; fi + +result=$(kubectl -n "$KUBE_NAMESPACE" get secret production-secret -o json | jq .data.CODE_MULTILINE | xargs echo | base64 -d) +if [[ "$result" != "$K8S_SECRET_CODE_MULTILINE" ]]; then exit 1; fi diff --git a/test/verify-deployment-database b/test/verify-deployment-database index 3549e6e1cb7eedc4acf3a3068ed1bc7f5031c4b8..7b3c292ac2a73c6561ea0f1ed7bdf4760cf404d8 100755 --- a/test/verify-deployment-database +++ b/test/verify-deployment-database @@ -7,8 +7,7 @@ pod_name=$(kubectl get pod -l "app=$appLabel" -n "$KUBE_NAMESPACE" --sort-by '{. # Wait for DB pod to be ready count=0 -while [[ $(kubectl get pods -l "app=$dbLabel" -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}') != "True" ]] -do +while [[ $(kubectl get pods -l "app=$dbLabel" -o 'jsonpath={..status.conditions[?(@.type=="Ready")].status}') != "True" ]]; do [[ $count -lt 30 ]] || exit 1 echo "waiting for pod" && sleep 1