From b6c8ef34b06d6b225eb632a4992a969e85e1d1fe Mon Sep 17 00:00:00 2001 From: Tom Chauveau Date: Sat, 5 Jun 2021 23:10:21 +0200 Subject: [PATCH] Add docker-compose tests Signed-off-by: Tom Chauveau --- stdlib/docker/compose/compose.cue | 1 + .../directory/.dagger/env/default/.gitignore | 2 + .../.dagger/env/default/plan/cleanup.cue | 77 +++++++++++ .../.dagger/env/default/plan/compose.cue | 28 ++++ .../.dagger/env/default/plan/verify.cue | 121 ++++++++++++++++++ .../directory/.dagger/env/default/values.yaml | 27 ++++ .../compose/directory/testdata/Dockerfile | 15 +++ .../directory/testdata/docker-compose.yaml | 7 + .../compose/directory/testdata/index.ts | 13 ++ .../compose/directory/testdata/package.json | 22 ++++ .../compose/directory/testdata/tsconfig.json | 12 ++ .../.dagger/env/default/.gitignore | 2 + .../.dagger/env/default/plan/cleanup.cue | 77 +++++++++++ .../.dagger/env/default/plan/compose.cue | 39 ++++++ .../.dagger/env/default/plan/verify.cue | 121 ++++++++++++++++++ .../.dagger/env/default/values.yaml | 27 ++++ .../compose/mix-context/testdata/Dockerfile | 15 +++ .../mix-context/testdata/docker-compose.yaml | 7 + .../compose/mix-context/testdata/index.ts | 13 ++ .../compose/mix-context/testdata/package.json | 22 ++++ .../mix-context/testdata/tsconfig.json | 12 ++ .../simple/.dagger/env/default/.gitignore | 2 + .../.dagger/env/default/plan/cleanup.cue | 77 +++++++++++ .../.dagger/env/default/plan/compose.cue | 33 +++++ .../.dagger/env/default/plan/verify.cue | 120 +++++++++++++++++ .../simple/.dagger/env/default/values.yaml | 24 ++++ .../voteapp/.dagger/env/default/.gitignore | 2 + .../.dagger/env/default/plan/cleanup.cue | 77 +++++++++++ .../.dagger/env/default/plan/compose.cue | 35 +++++ .../.dagger/env/default/plan/verify.cue | 120 +++++++++++++++++ .../voteapp/.dagger/env/default/values.yaml | 24 ++++ 31 files changed, 1174 insertions(+) create mode 100644 tests/stdlib/docker/compose/directory/.dagger/env/default/.gitignore create mode 100644 tests/stdlib/docker/compose/directory/.dagger/env/default/plan/cleanup.cue create mode 100644 tests/stdlib/docker/compose/directory/.dagger/env/default/plan/compose.cue create mode 100644 tests/stdlib/docker/compose/directory/.dagger/env/default/plan/verify.cue create mode 100644 tests/stdlib/docker/compose/directory/.dagger/env/default/values.yaml create mode 100644 tests/stdlib/docker/compose/directory/testdata/Dockerfile create mode 100644 tests/stdlib/docker/compose/directory/testdata/docker-compose.yaml create mode 100644 tests/stdlib/docker/compose/directory/testdata/index.ts create mode 100644 tests/stdlib/docker/compose/directory/testdata/package.json create mode 100644 tests/stdlib/docker/compose/directory/testdata/tsconfig.json create mode 100644 tests/stdlib/docker/compose/mix-context/.dagger/env/default/.gitignore create mode 100644 tests/stdlib/docker/compose/mix-context/.dagger/env/default/plan/cleanup.cue create mode 100644 tests/stdlib/docker/compose/mix-context/.dagger/env/default/plan/compose.cue create mode 100644 tests/stdlib/docker/compose/mix-context/.dagger/env/default/plan/verify.cue create mode 100644 tests/stdlib/docker/compose/mix-context/.dagger/env/default/values.yaml create mode 100644 tests/stdlib/docker/compose/mix-context/testdata/Dockerfile create mode 100644 tests/stdlib/docker/compose/mix-context/testdata/docker-compose.yaml create mode 100644 tests/stdlib/docker/compose/mix-context/testdata/index.ts create mode 100644 tests/stdlib/docker/compose/mix-context/testdata/package.json create mode 100644 tests/stdlib/docker/compose/mix-context/testdata/tsconfig.json create mode 100644 tests/stdlib/docker/compose/simple/.dagger/env/default/.gitignore create mode 100644 tests/stdlib/docker/compose/simple/.dagger/env/default/plan/cleanup.cue create mode 100644 tests/stdlib/docker/compose/simple/.dagger/env/default/plan/compose.cue create mode 100644 tests/stdlib/docker/compose/simple/.dagger/env/default/plan/verify.cue create mode 100644 tests/stdlib/docker/compose/simple/.dagger/env/default/values.yaml create mode 100644 tests/stdlib/docker/compose/voteapp/.dagger/env/default/.gitignore create mode 100644 tests/stdlib/docker/compose/voteapp/.dagger/env/default/plan/cleanup.cue create mode 100644 tests/stdlib/docker/compose/voteapp/.dagger/env/default/plan/compose.cue create mode 100644 tests/stdlib/docker/compose/voteapp/.dagger/env/default/plan/verify.cue create mode 100644 tests/stdlib/docker/compose/voteapp/.dagger/env/default/values.yaml diff --git a/stdlib/docker/compose/compose.cue b/stdlib/docker/compose/compose.cue index d67eb7e8..5be7881c 100644 --- a/stdlib/docker/compose/compose.cue +++ b/stdlib/docker/compose/compose.cue @@ -72,6 +72,7 @@ import ( #up: [ op.#Load & {from: #Client}, + // Login to registries for registry in registries { op.#DockerLogin & {registry} }, diff --git a/tests/stdlib/docker/compose/directory/.dagger/env/default/.gitignore b/tests/stdlib/docker/compose/directory/.dagger/env/default/.gitignore new file mode 100644 index 00000000..01ec19b0 --- /dev/null +++ b/tests/stdlib/docker/compose/directory/.dagger/env/default/.gitignore @@ -0,0 +1,2 @@ +# dagger state +state/** diff --git a/tests/stdlib/docker/compose/directory/.dagger/env/default/plan/cleanup.cue b/tests/stdlib/docker/compose/directory/.dagger/env/default/plan/cleanup.cue new file mode 100644 index 00000000..d44afb09 --- /dev/null +++ b/tests/stdlib/docker/compose/directory/.dagger/env/default/plan/cleanup.cue @@ -0,0 +1,77 @@ +package compose + +import ( + "strconv" + + "dagger.io/dagger" + "dagger.io/dagger/op" +) + +#CleanupCompose: { + // docker-compose up context + context: dagger.#Artifact + + ssh: { + // ssh host + host: string @dagger(input) + + // ssh user + user: string @dagger(input) + + // ssh port + port: *22 | int @dagger(input) + + // private key + key: dagger.#Secret @dagger(input) + + // fingerprint + fingerprint?: string @dagger(input) + + // ssh key passphrase + keyPassphrase?: dagger.#Secret @dagger(input) + } + + #code: #""" + # Export host + export DOCKER_HOST="ssh://$DOCKER_USERNAME@$DOCKER_HOSTNAME:$DOCKER_PORT" + + # Start ssh agent + eval $(ssh-agent) > /dev/null + ssh-add /key > /dev/null + + # Down + cd /context + docker-compose down -v + """# + + #up: [ + op.#Load & {from: context}, + + op.#WriteFile & { + content: #code + dest: "/entrypoint.sh" + }, + + op.#Exec & { + always: true + args: [ + "/bin/sh", + "--noprofile", + "--norc", + "-eo", + "pipefail", + "/entrypoint.sh", + ] + env: { + DOCKER_HOSTNAME: ssh.host + DOCKER_USERNAME: ssh.user + DOCKER_PORT: strconv.FormatInt(ssh.port, 10) + } + mount: { + if ssh.key != _|_ { + "/key": secret: ssh.key + } + } + }, + ] +} diff --git a/tests/stdlib/docker/compose/directory/.dagger/env/default/plan/compose.cue b/tests/stdlib/docker/compose/directory/.dagger/env/default/plan/compose.cue new file mode 100644 index 00000000..1e3d251c --- /dev/null +++ b/tests/stdlib/docker/compose/directory/.dagger/env/default/plan/compose.cue @@ -0,0 +1,28 @@ +package compose + +import ( + "dagger.io/dagger" + "dagger.io/docker/compose" +) + +repo: dagger.#Artifact + +TestCompose: { + up: compose.#Up & { + ssh: { + host: "143.198.64.230" + user: "root" + } + context: repo + } + + verify: #VerifyCompose & { + ssh: up.ssh + port: 8080 + } + + cleanup: #CleanupCompose & { + context: up + ssh: verify.ssh + } +} diff --git a/tests/stdlib/docker/compose/directory/.dagger/env/default/plan/verify.cue b/tests/stdlib/docker/compose/directory/.dagger/env/default/plan/verify.cue new file mode 100644 index 00000000..8921d6c5 --- /dev/null +++ b/tests/stdlib/docker/compose/directory/.dagger/env/default/plan/verify.cue @@ -0,0 +1,121 @@ +package compose + +import ( + "strconv" + + "dagger.io/alpine" + "dagger.io/dagger/op" + "dagger.io/dagger" +) + +#VerifyCompose: { + ssh: { + // ssh host + host: string @dagger(input) + + // ssh user + user: string @dagger(input) + + // ssh port + port: *22 | int @dagger(input) + + // private key + key: dagger.#Secret @dagger(input) + + // fingerprint + fingerprint?: string @dagger(input) + + // ssh key passphrase + keyPassphrase?: dagger.#Secret @dagger(input) + } + + port: int | *8080 + + #code: #""" + # Start ssh-agent + eval $(ssh-agent) > /dev/null + + # Add key + if [ -f "/key" ]; then + message="$(ssh-keygen -y -f /key < /dev/null 2>&1)" || { + >&2 echo "$message" + exit 1 + } + ssh-add /key > /dev/null + if [ "$?" != 0 ]; then + exit 1 + fi + fi + + if [[ ! -z $FINGERPRINT ]]; then + mkdir -p "$HOME"/.ssh + # Add user's fingerprint to known hosts + echo "$FINGERPRINT" >> "$HOME"/.ssh/known_hosts + else + # Add host to known hosts + ssh -i /key -o "UserKnownHostsFile "$HOME"/.ssh/known_hosts" -o "StrictHostKeyChecking accept-new" -p "$REMOTE_PORT" "$REMOTE_USERNAME"@"$REMOTE_HOSTNAME" /bin/true > /dev/null 2>&1 + fi + + ssh -i /key -p "$REMOTE_PORT" "$REMOTE_USERNAME"@"$REMOTE_HOSTNAME" curl localhost:"$CONTAINER_PORT"/ping > result.txt + grep -q "pong" result.txt + """# + + #up: [ + op.#Load & { + from: alpine.#Image & { + package: { + bash: true + curl: true + "openssh-client": true + } + } + }, + + if ssh.keyPassphrase != _|_ { + op.#WriteFile & { + content: #""" + #!/bin/bash + cat /passphrase + """# + dest: "/get_passphrase" + mode: 0o500 + } + }, + + op.#WriteFile & { + content: #code + dest: "/entrypoint.sh" + }, + + op.#Exec & { + always: true + args: [ + "/bin/sh", + "--noprofile", + "--norc", + "-eo", + "pipefail", + "/entrypoint.sh", + ] + env: { + CONTAINER_PORT: strconv.FormatInt(port, 10) + REMOTE_HOSTNAME: ssh.host + REMOTE_USERNAME: ssh.user + REMOTE_PORT: strconv.FormatInt(ssh.port, 10) + if ssh.keyPassphrase != _|_ { + SSH_ASKPASS: "/get_passphrase" + DISPLAY: "1" + } + if ssh.fingerprint != _|_ { + FINGERPRINT: ssh.fingerprint + } + } + mount: { + "/key": secret: ssh.key + if ssh.keyPassphrase != _|_ { + "/passphrase": secret: ssh.keyPassphrase + } + } + }, + ] +} diff --git a/tests/stdlib/docker/compose/directory/.dagger/env/default/values.yaml b/tests/stdlib/docker/compose/directory/.dagger/env/default/values.yaml new file mode 100644 index 00000000..ce5dd5b8 --- /dev/null +++ b/tests/stdlib/docker/compose/directory/.dagger/env/default/values.yaml @@ -0,0 +1,27 @@ +name: default +inputs: + TestCompose.up.ssh.key: + secret: ENC[AES256_GCM,data:/IwBkVdtKdXNYmJVyMhN9VUV9Hxku7E1coy1hJFNEA3cilmMsSw1rAf8NVol1QA92/Phw78he+uCosaQSWhgNIPcUWm/cX5dXOS35DLjt07Wjprw0ZMO3x+qMXp9yPZ6pBQvBZkvaJ+A8T7Ik9/H+AqtrH9uLD8GSUmy/KUTUqKO/M4lUr/PaMOJKtR9K+z9sOF+LbD061U4YwyM1RhZhkf/7/USLsHy6cCwW1FbCUjUy2Q/T6gq3SdcJKoL6bhKWxwTWQnLe9tYN1+c4gBDW4RBtsj4XKuetn/T+2ticlV/0Doc4ZihlC1IKHOc6KrrKVRTcCeVEOgNTEs73yeCIhnfm5Ndwli+nLdIkVYZJcG3HiOGvly84ZZpUEcxJfu2pnX1Qrcp7zJKoOk+JaxqQGxbqGaiAQgrB3qBX9oNIUI3p05Sd0LCHgM/HNxhLc71d2oT2gbHwCapNUPm+5Ga0M4NsPbJnRJWKbjp3p/C2FdhXSOLpJ17qWNNaLZS4Yoq8wGn5Gt01TteETIek9ZaLo/hgEaEC/ZoEjEq,iv:39HyMlg/2ctq5sqAUkpX6P7D2UFXPD2N8AIfqWxtHC8=,tag:NrLXRcVAKx82sXSIJihfPQ==,type:str] + repo: + dir: + path: ./testdata +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrQXpjM0VuVFhxNm5BUFRq + YWNwV0NCYTRpVTNFUnlaNHNkZzdidE8ydVhBCmtnQmJXZWFEaS9Ja0ViR0xBRisy + RlN3SGwyTXJuZExNOXV0Q0pPSk40THMKLS0tIHk5OXU3bTdUNzVMRVliWEZUaElP + UDQ3VG5mZzhGd21iYzl3L3N2UnF5bWMKllktgXwodYZEJypAC3C/VOATVlVsB8m+ + t3/WUeAe913Mhbxg11v2PekSFiUhv3Hh8Uz5FT4XJYeyXWl8UoS4jg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2021-06-05T19:29:59Z" + mac: ENC[AES256_GCM,data:aRwx2MCtVXUdKXiogYZ9c61FYH4MTMXCwuPmW6neHAhwKc962u01Bje6Zqypc74iddmCz3QCADs5OhkL6sT7utTmM1oJKBUfYwxh8udabWP5WRE/bmW1xXMLQsYW2j++uC0OJuZNQliOSo+Rw+6hwbVVezI/dNBG6ki87eyT6K0=,iv:D5/nJ9enZ1CO4wBcRiKSILezYWywD1bTiDSZJps7hA0=,tag:stneW8K4u/vsxW9k++g+lA==,type:str] + pgp: [] + encrypted_suffix: secret + version: 3.7.1 diff --git a/tests/stdlib/docker/compose/directory/testdata/Dockerfile b/tests/stdlib/docker/compose/directory/testdata/Dockerfile new file mode 100644 index 00000000..25d4c068 --- /dev/null +++ b/tests/stdlib/docker/compose/directory/testdata/Dockerfile @@ -0,0 +1,15 @@ +FROM node:12-alpine + +WORKDIR /app + +COPY package.json package.json + +RUN npm install + +COPY . . + +ENV PORT=8080 + +EXPOSE 8080 + +CMD ["npm", "start"] \ No newline at end of file diff --git a/tests/stdlib/docker/compose/directory/testdata/docker-compose.yaml b/tests/stdlib/docker/compose/directory/testdata/docker-compose.yaml new file mode 100644 index 00000000..b091d2e1 --- /dev/null +++ b/tests/stdlib/docker/compose/directory/testdata/docker-compose.yaml @@ -0,0 +1,7 @@ +version: "3" + +services: + api: + build: . + ports: + - "8080:8080" \ No newline at end of file diff --git a/tests/stdlib/docker/compose/directory/testdata/index.ts b/tests/stdlib/docker/compose/directory/testdata/index.ts new file mode 100644 index 00000000..d37fe572 --- /dev/null +++ b/tests/stdlib/docker/compose/directory/testdata/index.ts @@ -0,0 +1,13 @@ +import express from "express"; +import { get } from "env-var"; + + +const app = express(); + +const port: number = get('PORT').required().asPortNumber(); + +app.get('/ping', (req, res) => { + res.status(200).send('pong') +}); + +app.listen(port, '0.0.0.0', () => console.log("Server listen on http://localhost:" + port)); \ No newline at end of file diff --git a/tests/stdlib/docker/compose/directory/testdata/package.json b/tests/stdlib/docker/compose/directory/testdata/package.json new file mode 100644 index 00000000..c2be41f2 --- /dev/null +++ b/tests/stdlib/docker/compose/directory/testdata/package.json @@ -0,0 +1,22 @@ +{ + "name": "test", + "version": "1.0.0", + "description": "A simple api", + "main": "index.ts", + "scripts": { + "build": "tsc", + "start": "ts-node index.ts", + "test": "test" + }, + "author": "Tom Chauveau", + "license": "ISC", + "devDependencies": { + "ts-node": "^8.9.1", + "typescript": "^3.8.3" + }, + "dependencies": { + "@types/express": "^4.17.6", + "env-var": "^6.1.1", + "express": "^4.17.1" + } +} diff --git a/tests/stdlib/docker/compose/directory/testdata/tsconfig.json b/tests/stdlib/docker/compose/directory/testdata/tsconfig.json new file mode 100644 index 00000000..98907427 --- /dev/null +++ b/tests/stdlib/docker/compose/directory/testdata/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "sourceMap": true, + "outDir": "dist", + "strict": true, + "lib": [ + "esnext", + "dom" + ], + "esModuleInterop": true + } +} diff --git a/tests/stdlib/docker/compose/mix-context/.dagger/env/default/.gitignore b/tests/stdlib/docker/compose/mix-context/.dagger/env/default/.gitignore new file mode 100644 index 00000000..01ec19b0 --- /dev/null +++ b/tests/stdlib/docker/compose/mix-context/.dagger/env/default/.gitignore @@ -0,0 +1,2 @@ +# dagger state +state/** diff --git a/tests/stdlib/docker/compose/mix-context/.dagger/env/default/plan/cleanup.cue b/tests/stdlib/docker/compose/mix-context/.dagger/env/default/plan/cleanup.cue new file mode 100644 index 00000000..d44afb09 --- /dev/null +++ b/tests/stdlib/docker/compose/mix-context/.dagger/env/default/plan/cleanup.cue @@ -0,0 +1,77 @@ +package compose + +import ( + "strconv" + + "dagger.io/dagger" + "dagger.io/dagger/op" +) + +#CleanupCompose: { + // docker-compose up context + context: dagger.#Artifact + + ssh: { + // ssh host + host: string @dagger(input) + + // ssh user + user: string @dagger(input) + + // ssh port + port: *22 | int @dagger(input) + + // private key + key: dagger.#Secret @dagger(input) + + // fingerprint + fingerprint?: string @dagger(input) + + // ssh key passphrase + keyPassphrase?: dagger.#Secret @dagger(input) + } + + #code: #""" + # Export host + export DOCKER_HOST="ssh://$DOCKER_USERNAME@$DOCKER_HOSTNAME:$DOCKER_PORT" + + # Start ssh agent + eval $(ssh-agent) > /dev/null + ssh-add /key > /dev/null + + # Down + cd /context + docker-compose down -v + """# + + #up: [ + op.#Load & {from: context}, + + op.#WriteFile & { + content: #code + dest: "/entrypoint.sh" + }, + + op.#Exec & { + always: true + args: [ + "/bin/sh", + "--noprofile", + "--norc", + "-eo", + "pipefail", + "/entrypoint.sh", + ] + env: { + DOCKER_HOSTNAME: ssh.host + DOCKER_USERNAME: ssh.user + DOCKER_PORT: strconv.FormatInt(ssh.port, 10) + } + mount: { + if ssh.key != _|_ { + "/key": secret: ssh.key + } + } + }, + ] +} diff --git a/tests/stdlib/docker/compose/mix-context/.dagger/env/default/plan/compose.cue b/tests/stdlib/docker/compose/mix-context/.dagger/env/default/plan/compose.cue new file mode 100644 index 00000000..2620c472 --- /dev/null +++ b/tests/stdlib/docker/compose/mix-context/.dagger/env/default/plan/compose.cue @@ -0,0 +1,39 @@ +package compose + +import ( + "dagger.io/dagger" + "dagger.io/docker/compose" +) + +repo: dagger.#Artifact + +TestCompose: { + up: compose.#Up & { + ssh: { + host: "143.198.64.230" + user: "root" + } + context: repo + composeFile: #""" + version: "3" + + services: + api: + build: . + environment: + PORT: 7000 + ports: + - 7000:7000 + """# + } + + verify: #VerifyCompose & { + ssh: up.ssh + port: 7000 + } + + cleanup: #CleanupCompose & { + context: up + ssh: verify.ssh + } +} diff --git a/tests/stdlib/docker/compose/mix-context/.dagger/env/default/plan/verify.cue b/tests/stdlib/docker/compose/mix-context/.dagger/env/default/plan/verify.cue new file mode 100644 index 00000000..8921d6c5 --- /dev/null +++ b/tests/stdlib/docker/compose/mix-context/.dagger/env/default/plan/verify.cue @@ -0,0 +1,121 @@ +package compose + +import ( + "strconv" + + "dagger.io/alpine" + "dagger.io/dagger/op" + "dagger.io/dagger" +) + +#VerifyCompose: { + ssh: { + // ssh host + host: string @dagger(input) + + // ssh user + user: string @dagger(input) + + // ssh port + port: *22 | int @dagger(input) + + // private key + key: dagger.#Secret @dagger(input) + + // fingerprint + fingerprint?: string @dagger(input) + + // ssh key passphrase + keyPassphrase?: dagger.#Secret @dagger(input) + } + + port: int | *8080 + + #code: #""" + # Start ssh-agent + eval $(ssh-agent) > /dev/null + + # Add key + if [ -f "/key" ]; then + message="$(ssh-keygen -y -f /key < /dev/null 2>&1)" || { + >&2 echo "$message" + exit 1 + } + ssh-add /key > /dev/null + if [ "$?" != 0 ]; then + exit 1 + fi + fi + + if [[ ! -z $FINGERPRINT ]]; then + mkdir -p "$HOME"/.ssh + # Add user's fingerprint to known hosts + echo "$FINGERPRINT" >> "$HOME"/.ssh/known_hosts + else + # Add host to known hosts + ssh -i /key -o "UserKnownHostsFile "$HOME"/.ssh/known_hosts" -o "StrictHostKeyChecking accept-new" -p "$REMOTE_PORT" "$REMOTE_USERNAME"@"$REMOTE_HOSTNAME" /bin/true > /dev/null 2>&1 + fi + + ssh -i /key -p "$REMOTE_PORT" "$REMOTE_USERNAME"@"$REMOTE_HOSTNAME" curl localhost:"$CONTAINER_PORT"/ping > result.txt + grep -q "pong" result.txt + """# + + #up: [ + op.#Load & { + from: alpine.#Image & { + package: { + bash: true + curl: true + "openssh-client": true + } + } + }, + + if ssh.keyPassphrase != _|_ { + op.#WriteFile & { + content: #""" + #!/bin/bash + cat /passphrase + """# + dest: "/get_passphrase" + mode: 0o500 + } + }, + + op.#WriteFile & { + content: #code + dest: "/entrypoint.sh" + }, + + op.#Exec & { + always: true + args: [ + "/bin/sh", + "--noprofile", + "--norc", + "-eo", + "pipefail", + "/entrypoint.sh", + ] + env: { + CONTAINER_PORT: strconv.FormatInt(port, 10) + REMOTE_HOSTNAME: ssh.host + REMOTE_USERNAME: ssh.user + REMOTE_PORT: strconv.FormatInt(ssh.port, 10) + if ssh.keyPassphrase != _|_ { + SSH_ASKPASS: "/get_passphrase" + DISPLAY: "1" + } + if ssh.fingerprint != _|_ { + FINGERPRINT: ssh.fingerprint + } + } + mount: { + "/key": secret: ssh.key + if ssh.keyPassphrase != _|_ { + "/passphrase": secret: ssh.keyPassphrase + } + } + }, + ] +} diff --git a/tests/stdlib/docker/compose/mix-context/.dagger/env/default/values.yaml b/tests/stdlib/docker/compose/mix-context/.dagger/env/default/values.yaml new file mode 100644 index 00000000..485db6d9 --- /dev/null +++ b/tests/stdlib/docker/compose/mix-context/.dagger/env/default/values.yaml @@ -0,0 +1,27 @@ +name: default +inputs: + TestCompose.up.ssh.key: + secret: ENC[AES256_GCM,data:VER9BalLBamLFIvFPCHS5xW6lTjyToNDCmnQu6pSsnsOo6B9WYoZf5KiMfnmRYL99eKiGJAgK67S6jWyiUYCdFBi+wXav+YpvqgWENFP1gSVk3AvoQx2RR403/1D9hFtJd+cQaL2wjUBkGRdjZ2WX//ElBeDAPlcdoLnNvOvITIYsb54elqvkfQdm5yCgwi+EsSkaGresWYUdBxFqhkILUPhJ6hKd/7RyPRyOVCTEK9HxpfY/a6Q7gcLJk1W+mJQLPd1T+Z+GkJuv2Xe1uozazrXDLb+Yt/Cz3TfXwXt2zbE10zoM3dhQ++DC6ZQx+wWOaGhIn8fd4WUb9DM4NqbcSQWxmmbo9mhhRBpP7/ea8EFs8wz0otF/FZy5sK/bThq1ziotUc3i7CWrU4xrwDwK+pYGA7kssXUFzi2mUn9mqH2WoYUAsC24BP5XJjgjz8nqhhx+WnMzYY1RhW7+cAZFvgzAJPmJ3aEv9tyGbdczg2O3n0fboumIP3Rl/99Ld+5JMVzcneHmdS7adH9+CWi19a66o9I0Jxufys1,iv:4D7/IZk3niD8rFbOcZEI0w9Wz6kwS2DCDp9BgW+eoho=,tag:AJdUzma7XAPiqbo7z90OEQ==,type:str] + repo: + dir: + path: ./testdata +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjSVBlUG54ZlJyRXVVZUVx + dGZOT3FueFkwditJSEY0YytaMkZoSWM0aEZrCmVOM3J1Wnc0VjgwZUJYSndXS255 + dUFUdzhHQy95Nkg1aHZtR3ExL3Y1WncKLS0tIExVZC94aWFCbkZGWkFSdmFNbTRJ + S0p6aEVtOFdKYk03NjUzU21Zdk5GYm8KuPlFhlBq31vMea+RQhBliHlm/iXIGq2u + QsSR6owRh7doEq0PheYz8ypZuqWduj9tuTLqXxCz0djjgsVbvo52LQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2021-06-05T19:55:53Z" + mac: ENC[AES256_GCM,data:FB0sUdVVYjWeovBYR5K78CGBxUfd8ddsHulWNzNUp/Jf/M6Rd/LBCN0DmneUO2oWI9pgOJYlvgK3EO7xIA42uO9gIyRU1O7ikjhN0pzFcCE7VKVUjBky2p5UQ5m9kvm4RIXYRC0aKkp7NJ8V3XXDrpag21+R5Y/p7iF9/BkdlsU=,iv:bbq/sIa2uSTc3Yu0j/AJ3dmDyn4tSV2JmutFwdi3B/c=,tag:3Rc2FjmX1u/qF6oWiFmKkA==,type:str] + pgp: [] + encrypted_suffix: secret + version: 3.7.1 diff --git a/tests/stdlib/docker/compose/mix-context/testdata/Dockerfile b/tests/stdlib/docker/compose/mix-context/testdata/Dockerfile new file mode 100644 index 00000000..25d4c068 --- /dev/null +++ b/tests/stdlib/docker/compose/mix-context/testdata/Dockerfile @@ -0,0 +1,15 @@ +FROM node:12-alpine + +WORKDIR /app + +COPY package.json package.json + +RUN npm install + +COPY . . + +ENV PORT=8080 + +EXPOSE 8080 + +CMD ["npm", "start"] \ No newline at end of file diff --git a/tests/stdlib/docker/compose/mix-context/testdata/docker-compose.yaml b/tests/stdlib/docker/compose/mix-context/testdata/docker-compose.yaml new file mode 100644 index 00000000..b091d2e1 --- /dev/null +++ b/tests/stdlib/docker/compose/mix-context/testdata/docker-compose.yaml @@ -0,0 +1,7 @@ +version: "3" + +services: + api: + build: . + ports: + - "8080:8080" \ No newline at end of file diff --git a/tests/stdlib/docker/compose/mix-context/testdata/index.ts b/tests/stdlib/docker/compose/mix-context/testdata/index.ts new file mode 100644 index 00000000..d37fe572 --- /dev/null +++ b/tests/stdlib/docker/compose/mix-context/testdata/index.ts @@ -0,0 +1,13 @@ +import express from "express"; +import { get } from "env-var"; + + +const app = express(); + +const port: number = get('PORT').required().asPortNumber(); + +app.get('/ping', (req, res) => { + res.status(200).send('pong') +}); + +app.listen(port, '0.0.0.0', () => console.log("Server listen on http://localhost:" + port)); \ No newline at end of file diff --git a/tests/stdlib/docker/compose/mix-context/testdata/package.json b/tests/stdlib/docker/compose/mix-context/testdata/package.json new file mode 100644 index 00000000..c2be41f2 --- /dev/null +++ b/tests/stdlib/docker/compose/mix-context/testdata/package.json @@ -0,0 +1,22 @@ +{ + "name": "test", + "version": "1.0.0", + "description": "A simple api", + "main": "index.ts", + "scripts": { + "build": "tsc", + "start": "ts-node index.ts", + "test": "test" + }, + "author": "Tom Chauveau", + "license": "ISC", + "devDependencies": { + "ts-node": "^8.9.1", + "typescript": "^3.8.3" + }, + "dependencies": { + "@types/express": "^4.17.6", + "env-var": "^6.1.1", + "express": "^4.17.1" + } +} diff --git a/tests/stdlib/docker/compose/mix-context/testdata/tsconfig.json b/tests/stdlib/docker/compose/mix-context/testdata/tsconfig.json new file mode 100644 index 00000000..98907427 --- /dev/null +++ b/tests/stdlib/docker/compose/mix-context/testdata/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "sourceMap": true, + "outDir": "dist", + "strict": true, + "lib": [ + "esnext", + "dom" + ], + "esModuleInterop": true + } +} diff --git a/tests/stdlib/docker/compose/simple/.dagger/env/default/.gitignore b/tests/stdlib/docker/compose/simple/.dagger/env/default/.gitignore new file mode 100644 index 00000000..01ec19b0 --- /dev/null +++ b/tests/stdlib/docker/compose/simple/.dagger/env/default/.gitignore @@ -0,0 +1,2 @@ +# dagger state +state/** diff --git a/tests/stdlib/docker/compose/simple/.dagger/env/default/plan/cleanup.cue b/tests/stdlib/docker/compose/simple/.dagger/env/default/plan/cleanup.cue new file mode 100644 index 00000000..d44afb09 --- /dev/null +++ b/tests/stdlib/docker/compose/simple/.dagger/env/default/plan/cleanup.cue @@ -0,0 +1,77 @@ +package compose + +import ( + "strconv" + + "dagger.io/dagger" + "dagger.io/dagger/op" +) + +#CleanupCompose: { + // docker-compose up context + context: dagger.#Artifact + + ssh: { + // ssh host + host: string @dagger(input) + + // ssh user + user: string @dagger(input) + + // ssh port + port: *22 | int @dagger(input) + + // private key + key: dagger.#Secret @dagger(input) + + // fingerprint + fingerprint?: string @dagger(input) + + // ssh key passphrase + keyPassphrase?: dagger.#Secret @dagger(input) + } + + #code: #""" + # Export host + export DOCKER_HOST="ssh://$DOCKER_USERNAME@$DOCKER_HOSTNAME:$DOCKER_PORT" + + # Start ssh agent + eval $(ssh-agent) > /dev/null + ssh-add /key > /dev/null + + # Down + cd /context + docker-compose down -v + """# + + #up: [ + op.#Load & {from: context}, + + op.#WriteFile & { + content: #code + dest: "/entrypoint.sh" + }, + + op.#Exec & { + always: true + args: [ + "/bin/sh", + "--noprofile", + "--norc", + "-eo", + "pipefail", + "/entrypoint.sh", + ] + env: { + DOCKER_HOSTNAME: ssh.host + DOCKER_USERNAME: ssh.user + DOCKER_PORT: strconv.FormatInt(ssh.port, 10) + } + mount: { + if ssh.key != _|_ { + "/key": secret: ssh.key + } + } + }, + ] +} diff --git a/tests/stdlib/docker/compose/simple/.dagger/env/default/plan/compose.cue b/tests/stdlib/docker/compose/simple/.dagger/env/default/plan/compose.cue new file mode 100644 index 00000000..20cafe92 --- /dev/null +++ b/tests/stdlib/docker/compose/simple/.dagger/env/default/plan/compose.cue @@ -0,0 +1,33 @@ +package compose + +import ( + "dagger.io/docker/compose" +) + +TestCompose: { + up: compose.#Up & { + ssh: { + host: "143.198.64.230" + user: "root" + } + composeFile: #""" + version: "3" + + services: + nginx: + image: nginx:alpine + ports: + - 8080:80 + """# + } + + verify: #VerifyCompose & { + ssh: up.ssh + port: 8080 + } + + cleanup: #CleanupCompose & { + context: up + ssh: verify.ssh + } +} diff --git a/tests/stdlib/docker/compose/simple/.dagger/env/default/plan/verify.cue b/tests/stdlib/docker/compose/simple/.dagger/env/default/plan/verify.cue new file mode 100644 index 00000000..5d0c2e5e --- /dev/null +++ b/tests/stdlib/docker/compose/simple/.dagger/env/default/plan/verify.cue @@ -0,0 +1,120 @@ +package compose + +import ( + "strconv" + + "dagger.io/alpine" + "dagger.io/dagger/op" + "dagger.io/dagger" +) + +#VerifyCompose: { + ssh: { + // ssh host + host: string @dagger(input) + + // ssh user + user: string @dagger(input) + + // ssh port + port: *22 | int @dagger(input) + + // private key + key: dagger.#Secret @dagger(input) + + // fingerprint + fingerprint?: string @dagger(input) + + // ssh key passphrase + keyPassphrase?: dagger.#Secret @dagger(input) + } + + port: int | *8080 + + #code: #""" + # Start ssh-agent + eval $(ssh-agent) > /dev/null + + # Add key + if [ -f "/key" ]; then + message="$(ssh-keygen -y -f /key < /dev/null 2>&1)" || { + >&2 echo "$message" + exit 1 + } + ssh-add /key > /dev/null + if [ "$?" != 0 ]; then + exit 1 + fi + fi + + if [[ ! -z $FINGERPRINT ]]; then + mkdir -p "$HOME"/.ssh + # Add user's fingerprint to known hosts + echo "$FINGERPRINT" >> "$HOME"/.ssh/known_hosts + else + # Add host to known hosts + ssh -i /key -o "UserKnownHostsFile "$HOME"/.ssh/known_hosts" -o "StrictHostKeyChecking accept-new" -p "$REMOTE_PORT" "$REMOTE_USERNAME"@"$REMOTE_HOSTNAME" /bin/true > /dev/null 2>&1 + fi + + ssh -i /key -p "$REMOTE_PORT" "$REMOTE_USERNAME"@"$REMOTE_HOSTNAME" curl localhost:"$CONTAINER_PORT" + """# + + #up: [ + op.#Load & { + from: alpine.#Image & { + package: { + bash: true + curl: true + "openssh-client": true + } + } + }, + + if ssh.keyPassphrase != _|_ { + op.#WriteFile & { + content: #""" + #!/bin/bash + cat /passphrase + """# + dest: "/get_passphrase" + mode: 0o500 + } + }, + + op.#WriteFile & { + content: #code + dest: "/entrypoint.sh" + }, + + op.#Exec & { + always: true + args: [ + "/bin/sh", + "--noprofile", + "--norc", + "-eo", + "pipefail", + "/entrypoint.sh", + ] + env: { + CONTAINER_PORT: strconv.FormatInt(port, 10) + REMOTE_HOSTNAME: ssh.host + REMOTE_USERNAME: ssh.user + REMOTE_PORT: strconv.FormatInt(ssh.port, 10) + if ssh.keyPassphrase != _|_ { + SSH_ASKPASS: "/get_passphrase" + DISPLAY: "1" + } + if ssh.fingerprint != _|_ { + FINGERPRINT: ssh.fingerprint + } + } + mount: { + "/key": secret: ssh.key + if ssh.keyPassphrase != _|_ { + "/passphrase": secret: ssh.keyPassphrase + } + } + }, + ] +} diff --git a/tests/stdlib/docker/compose/simple/.dagger/env/default/values.yaml b/tests/stdlib/docker/compose/simple/.dagger/env/default/values.yaml new file mode 100644 index 00000000..01dedc9c --- /dev/null +++ b/tests/stdlib/docker/compose/simple/.dagger/env/default/values.yaml @@ -0,0 +1,24 @@ +name: default +inputs: + TestCompose.up.ssh.key: + secret: ENC[AES256_GCM,data:ixiwG8s0jeEQ2hy6kQmOOYjwTAAaLB9hz0ih8az0mvqPV0HZSWQwOg3OPVgBW9Slk3MZjv6RYc8n2YoanHWZm2WxsA/neSFI7XG/IH/xhLDtxX+wmqrjP4To1KGZ4R4QgVdpA/bhCxXDt9a9lqJSMGGh2mOklRs+vMDhV6kkXbc/dX1ki7JSH754QME3HRdQn6Q7VYDg2ro3Ry/IrOA9uzqNUdAK7GW4ADe3Lez3HPg3jS2vvccHURRfSGnBBbtLa7kgpQdtrAhZuZP6h+6XOJZDZ+/aZSar+nY/CFey+2JnBSAMzZ2MvNy9uoW/NwalT5uN+U/skqdhfVMWVkExb5Pnhpfr44pLBt8uvBwOzZ97XUgI/rgWkmi3efY33A9/vL2ac3HVZSok7XMz8TbwOZM9JU3u3nHx6VS//Mp6c0qXYSrHNlJJeBpF61HGX/rqpYoZC86Sj2AwzuYVsbUwVGwGI9FytJVyp/zCrQaRte0coM1Huy5UKX7KotMIFyQdjtDmsOo5dfjkmxWC+4AB5nwgu+wYz6qUKV7C,iv:T7hpMnKdGirSirC9V/xitgFwhHsuYc9XuHXc7NqX8Eg=,tag:w1jORINS1hyDpOJskHOQ7Q==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvcFgyV0NXUCthU1B4NE5I + RWRXREZuS3FtbEd3a0p2SHZmNW9QOGpxWG5JClgzamp0SUlkY0E1SytKK2pXb2ts + YzZpZWxWR0lua1g0V3U5Nlk1Y1hIWWsKLS0tIC9MVTZCdDNFUmtnR2RjekZnbnUv + M1czbGlnRmdmaVQxK1h2eGhqSXpJcTQKWl4r3FLuqFkX13ivmsIAsRxoXGGyeu9f + CfkCQ9jc7N6YH4MtEFO33VNJNc+xQDXKzRDVjo0vCxxk12iebi5o3w== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2021-06-05T16:01:39Z" + mac: ENC[AES256_GCM,data:CuzfQP5Wg4AJHI83onmg2SYC9U8a/KezVORQH0DLr9BaYRMX/qpxv0+DEqLlWADmaCNcA2NF43FmwcaKybn5SBc4i2GoVfouwIxzfPSvfu3cCH/uyjFVZ4Me0IP6vnd3EGLbZDQgJFV6bBTYSJS6OqVypmFPr6pyaAd1RO5KqfA=,iv:MY3Vdx9BqPC+HIY8Qc4ldu0sjM2rlxy4GEEzIKXyUCk=,tag:jCgDpsf3WZQC3Rlngd1uVg==,type:str] + pgp: [] + encrypted_suffix: secret + version: 3.7.1 diff --git a/tests/stdlib/docker/compose/voteapp/.dagger/env/default/.gitignore b/tests/stdlib/docker/compose/voteapp/.dagger/env/default/.gitignore new file mode 100644 index 00000000..01ec19b0 --- /dev/null +++ b/tests/stdlib/docker/compose/voteapp/.dagger/env/default/.gitignore @@ -0,0 +1,2 @@ +# dagger state +state/** diff --git a/tests/stdlib/docker/compose/voteapp/.dagger/env/default/plan/cleanup.cue b/tests/stdlib/docker/compose/voteapp/.dagger/env/default/plan/cleanup.cue new file mode 100644 index 00000000..d44afb09 --- /dev/null +++ b/tests/stdlib/docker/compose/voteapp/.dagger/env/default/plan/cleanup.cue @@ -0,0 +1,77 @@ +package compose + +import ( + "strconv" + + "dagger.io/dagger" + "dagger.io/dagger/op" +) + +#CleanupCompose: { + // docker-compose up context + context: dagger.#Artifact + + ssh: { + // ssh host + host: string @dagger(input) + + // ssh user + user: string @dagger(input) + + // ssh port + port: *22 | int @dagger(input) + + // private key + key: dagger.#Secret @dagger(input) + + // fingerprint + fingerprint?: string @dagger(input) + + // ssh key passphrase + keyPassphrase?: dagger.#Secret @dagger(input) + } + + #code: #""" + # Export host + export DOCKER_HOST="ssh://$DOCKER_USERNAME@$DOCKER_HOSTNAME:$DOCKER_PORT" + + # Start ssh agent + eval $(ssh-agent) > /dev/null + ssh-add /key > /dev/null + + # Down + cd /context + docker-compose down -v + """# + + #up: [ + op.#Load & {from: context}, + + op.#WriteFile & { + content: #code + dest: "/entrypoint.sh" + }, + + op.#Exec & { + always: true + args: [ + "/bin/sh", + "--noprofile", + "--norc", + "-eo", + "pipefail", + "/entrypoint.sh", + ] + env: { + DOCKER_HOSTNAME: ssh.host + DOCKER_USERNAME: ssh.user + DOCKER_PORT: strconv.FormatInt(ssh.port, 10) + } + mount: { + if ssh.key != _|_ { + "/key": secret: ssh.key + } + } + }, + ] +} diff --git a/tests/stdlib/docker/compose/voteapp/.dagger/env/default/plan/compose.cue b/tests/stdlib/docker/compose/voteapp/.dagger/env/default/plan/compose.cue new file mode 100644 index 00000000..150f286d --- /dev/null +++ b/tests/stdlib/docker/compose/voteapp/.dagger/env/default/plan/compose.cue @@ -0,0 +1,35 @@ +package compose + +import ( + "dagger.io/git" + "dagger.io/docker/compose" +) + +TestCompose: { + up: compose.#Up & { + ssh: { + host: "143.198.64.230" + user: "root" + } + context: git.#Repository & { + remote: "https://github.com/dagger/examples" + ref: "main" + subdir: "voteapp" + } + } + + verifyApp: #VerifyCompose & { + ssh: up.ssh + port: 5000 + } + + verifyResult: #VerifyCompose & { + ssh: up.ssh + port: 5001 + } + + cleanup: #CleanupCompose & { + context: up + ssh: verifyResult.ssh + } +} diff --git a/tests/stdlib/docker/compose/voteapp/.dagger/env/default/plan/verify.cue b/tests/stdlib/docker/compose/voteapp/.dagger/env/default/plan/verify.cue new file mode 100644 index 00000000..5d0c2e5e --- /dev/null +++ b/tests/stdlib/docker/compose/voteapp/.dagger/env/default/plan/verify.cue @@ -0,0 +1,120 @@ +package compose + +import ( + "strconv" + + "dagger.io/alpine" + "dagger.io/dagger/op" + "dagger.io/dagger" +) + +#VerifyCompose: { + ssh: { + // ssh host + host: string @dagger(input) + + // ssh user + user: string @dagger(input) + + // ssh port + port: *22 | int @dagger(input) + + // private key + key: dagger.#Secret @dagger(input) + + // fingerprint + fingerprint?: string @dagger(input) + + // ssh key passphrase + keyPassphrase?: dagger.#Secret @dagger(input) + } + + port: int | *8080 + + #code: #""" + # Start ssh-agent + eval $(ssh-agent) > /dev/null + + # Add key + if [ -f "/key" ]; then + message="$(ssh-keygen -y -f /key < /dev/null 2>&1)" || { + >&2 echo "$message" + exit 1 + } + ssh-add /key > /dev/null + if [ "$?" != 0 ]; then + exit 1 + fi + fi + + if [[ ! -z $FINGERPRINT ]]; then + mkdir -p "$HOME"/.ssh + # Add user's fingerprint to known hosts + echo "$FINGERPRINT" >> "$HOME"/.ssh/known_hosts + else + # Add host to known hosts + ssh -i /key -o "UserKnownHostsFile "$HOME"/.ssh/known_hosts" -o "StrictHostKeyChecking accept-new" -p "$REMOTE_PORT" "$REMOTE_USERNAME"@"$REMOTE_HOSTNAME" /bin/true > /dev/null 2>&1 + fi + + ssh -i /key -p "$REMOTE_PORT" "$REMOTE_USERNAME"@"$REMOTE_HOSTNAME" curl localhost:"$CONTAINER_PORT" + """# + + #up: [ + op.#Load & { + from: alpine.#Image & { + package: { + bash: true + curl: true + "openssh-client": true + } + } + }, + + if ssh.keyPassphrase != _|_ { + op.#WriteFile & { + content: #""" + #!/bin/bash + cat /passphrase + """# + dest: "/get_passphrase" + mode: 0o500 + } + }, + + op.#WriteFile & { + content: #code + dest: "/entrypoint.sh" + }, + + op.#Exec & { + always: true + args: [ + "/bin/sh", + "--noprofile", + "--norc", + "-eo", + "pipefail", + "/entrypoint.sh", + ] + env: { + CONTAINER_PORT: strconv.FormatInt(port, 10) + REMOTE_HOSTNAME: ssh.host + REMOTE_USERNAME: ssh.user + REMOTE_PORT: strconv.FormatInt(ssh.port, 10) + if ssh.keyPassphrase != _|_ { + SSH_ASKPASS: "/get_passphrase" + DISPLAY: "1" + } + if ssh.fingerprint != _|_ { + FINGERPRINT: ssh.fingerprint + } + } + mount: { + "/key": secret: ssh.key + if ssh.keyPassphrase != _|_ { + "/passphrase": secret: ssh.keyPassphrase + } + } + }, + ] +} diff --git a/tests/stdlib/docker/compose/voteapp/.dagger/env/default/values.yaml b/tests/stdlib/docker/compose/voteapp/.dagger/env/default/values.yaml new file mode 100644 index 00000000..3d64b33d --- /dev/null +++ b/tests/stdlib/docker/compose/voteapp/.dagger/env/default/values.yaml @@ -0,0 +1,24 @@ +name: default +inputs: + TestCompose.up.ssh.key: + secret: ENC[AES256_GCM,data:eLBDG05PNBU5O3ICj7GAgUO4niTgxEGhqo0XvhKlkLnSvys0/MXHMnuRpJdEXypt6V3aoD+iAgOvO4M3JKvxWNagYk45yfjrtCpjW8e/j+pu7zc1IrxJtD++GMfIQ3WZBDHu7bZ4XJWGbVHhEngPjhgJKozgb1GLZQKw0ArgrufIIZ9S4mgYnCytiCjV1M5WFWmI0AVAEgGgQdlvKDUK/k6hcUNb/8bQhXPnlLM7nGjz1yLYaUfScWeDaHSx/NXMwIaadHzR/6naFnEn5xJJZjQ8Y+SkJcLu1fwE2Z5zYuhvqhYdu+36x7gDHTrtf6+eCCitRUU2Mj4RN1g9FzGDCyFuhn/I1E54lhm8N6WcPHLTX1kRIQk/7wLF0zT918YNLoWicXLg4hqOe/D5ew8i+ZLnQJAjzlYKZQawZsaSkhOozSuYFg8pjrTbroX+yg0cipfodt7J1aX0ddgWSuzYQADUDx2iIJwuFxFtQiSJw4IIJiAeKipWsEKKyBHChpDFz3+RIWkzOe0rs/VYf4SKhGAO4oMaOmXtBY6Z,iv:KjCJFkm3rOz55yeIc8pTx6LQqNZselhjsyHIyHps0MY=,tag:/upNvd/QGzU+A86tv7h0AA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1gxwmtwahzwdmrskhf90ppwlnze30lgpm056kuesrxzeuyclrwvpsupwtpk + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIUkd0TUY5Zlc5TUJTaEgw + RlEwWU10RWcvOGR2WkRpajh4WWtjUmZYV0U0CjRyQlB2N0paMXdTRXJSRmV5T1lX + WmwzbDZleG9IZXdDMHlLbmhVSTlVYncKLS0tIEJIaitaSUw3LzhkOHVjQVpzd3NV + bWFNREMxU1NVQ01xUmU5cnlER0Fad0UKMkFvd3S/56/k0dw2GYDsGyjBWqy29Mht + ed/N7FxrAkHBnGzfs+A1mMtrrTsrs70sWOsZvxr406Pp+Iue899Q2A== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2021-06-05T21:00:42Z" + mac: ENC[AES256_GCM,data:ajVoJ9nInK6kvxxkCpAjMNQ97oZdXgIvscA3R7OlItRA1Xlvu3C6ndU6VoSy6hotR8OJkad2EHfCXDlgrcodXVJcwaqVdCTNDSJLyu8XAIDQKqIpGQwtl6dPrvomE4gmEg3qDC5xPfDV9MNpo1j5M6VyIhrmSJjnWiCg4juIHD4=,iv:FjfWpIHdfQ7gwbM5PBUBVR0LOofRmLvgCpSeMkgGmI4=,tag:FCSHpYrCZR0eLVgy//gI/g==,type:str] + pgp: [] + encrypted_suffix: secret + version: 3.7.1