From 61e82da2a38304c7d61b015d81c1f6f48f53d5b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Wed, 6 May 2020 22:34:18 +0200 Subject: [PATCH] Add Vault Support --- .editorconfig | 5 + .github/workflows/ci.yaml | 32 +- .gitignore | 8 +- LICENSE | 2 +- README.md | 399 ++---------------- USAGE.md | 323 ++++++++++++++ completion.yaml | 23 +- examples/sops/.helmignore | 23 + .../projectX => examples/sops}/.sops.yaml | 2 +- examples/sops/Chart.yaml | 23 + examples/sops/secrets.yaml | 32 ++ examples/sops/secrets.yaml.dec | 2 + examples/sops/templates/NOTES.txt | 21 + examples/sops/templates/_helpers.tpl | 63 +++ examples/sops/templates/deployment.yaml | 61 +++ examples/sops/templates/hpa.yaml | 28 ++ examples/sops/templates/ingress.yaml | 41 ++ examples/sops/templates/service.yaml | 15 + examples/sops/templates/serviceaccount.yaml | 12 + .../sops/templates/tests/test-connection.yaml | 15 + examples/sops/values.yaml | 79 ++++ examples/vault/.helmignore | 23 + examples/vault/Chart.yaml | 23 + examples/vault/secrets.yaml | 2 + examples/vault/templates/NOTES.txt | 21 + examples/vault/templates/_helpers.tpl | 63 +++ examples/vault/templates/deployment.yaml | 61 +++ examples/vault/templates/hpa.yaml | 28 ++ examples/vault/templates/ingress.yaml | 41 ++ examples/vault/templates/service.yaml | 15 + examples/vault/templates/serviceaccount.yaml | 12 + .../templates/tests/test-connection.yaml | 15 + examples/vault/values.yaml | 79 ++++ scripts/commands/enc.sh | 5 +- scripts/commands/helm.sh | 17 - scripts/drivers/noop.sh | 2 +- scripts/drivers/sops.sh | 4 +- scripts/drivers/vault.sh | 90 ++++ scripts/run.sh | 171 ++++---- tests/assets/gpg/private.gpg | 58 +++ tests/assets/helm_vars/.sops.yaml | 3 - .../us-east-1/java-app/secrets.yaml | 31 -- .../production/us-east-1/java-app/value.yaml | 1 - .../sandbox/us-east-1/java-app/secrets.yaml | 31 -- .../sandbox/us-east-1/java-app/value.yaml | 1 - tests/assets/helm_vars/projectY/.sops.yaml | 3 - .../us-east-1/java-app/secrets.yaml | 31 -- .../production/us-east-1/java-app/value.yaml | 1 - .../sandbox/us-east-1/java-app/secrets.yaml | 31 -- .../sandbox/us-east-1/java-app/value.yaml | 1 - tests/assets/helm_vars/secrets.yaml | 52 --- tests/assets/helm_vars/values.yaml | 1 - tests/assets/pgp/projectx.asc | 105 ----- tests/assets/pgp/projecty.asc | 105 ----- tests/assets/values/noop/secrets.yaml | 22 + tests/assets/values/sops/.sops.yaml | 3 + tests/assets/values/sops/secrets.dec.yaml | 23 + tests/assets/values/sops/secrets.yaml | 28 ++ tests/assets/values/vault/secrets.yaml | 4 + tests/assets/values/vault/seed.sh | 22 + tests/helper.bash | 64 --- tests/it/00-setup.bats | 16 - tests/it/11-install.bats | 202 --------- tests/it/12-upgrade.bats | 202 --------- tests/it/13-diff.bats | 159 ------- tests/it/99-cleanup.bats | 10 - tests/it/diff.bats | 148 +++++++ tests/it/install.bats | 156 +++++++ tests/it/upgrade.bats | 155 +++++++ tests/lib/create_encrypted_file.bash | 47 +++ tests/lib/helper.bash | 126 ++++++ tests/unit/00-setup.bats | 10 - tests/unit/01-plugin-install.bats | 30 -- tests/unit/02-secret-driver.bats | 69 --- tests/unit/12-dec.bats | 69 --- tests/unit/13-enc.bats | 71 ---- tests/unit/16-lint.bats | 147 ------- tests/unit/17-template.bats | 147 ------- tests/unit/18-kubeval.bats | 152 ------- tests/unit/99-cleanup.bats | 10 - tests/unit/{15-clean.bats => clean.bats} | 6 +- tests/unit/dec.bats | 78 ++++ tests/unit/{14-edit.bats => edit.bats} | 31 +- tests/unit/enc.bats | 123 ++++++ tests/unit/kubeval.bats | 147 +++++++ tests/unit/lint.bats | 124 ++++++ .../plugin-install.bats} | 6 +- tests/unit/secret-driver.bats | 111 +++++ tests/unit/template.bats | 128 ++++++ tests/unit/{11-view.bats => view.bats} | 18 +- 90 files changed, 2931 insertions(+), 2269 deletions(-) create mode 100644 USAGE.md create mode 100644 examples/sops/.helmignore rename {tests/assets/helm_vars/projectX => examples/sops}/.sops.yaml (65%) create mode 100644 examples/sops/Chart.yaml create mode 100644 examples/sops/secrets.yaml create mode 100644 examples/sops/secrets.yaml.dec create mode 100644 examples/sops/templates/NOTES.txt create mode 100644 examples/sops/templates/_helpers.tpl create mode 100644 examples/sops/templates/deployment.yaml create mode 100644 examples/sops/templates/hpa.yaml create mode 100644 examples/sops/templates/ingress.yaml create mode 100644 examples/sops/templates/service.yaml create mode 100644 examples/sops/templates/serviceaccount.yaml create mode 100644 examples/sops/templates/tests/test-connection.yaml create mode 100644 examples/sops/values.yaml create mode 100644 examples/vault/.helmignore create mode 100644 examples/vault/Chart.yaml create mode 100644 examples/vault/secrets.yaml create mode 100644 examples/vault/templates/NOTES.txt create mode 100644 examples/vault/templates/_helpers.tpl create mode 100644 examples/vault/templates/deployment.yaml create mode 100644 examples/vault/templates/hpa.yaml create mode 100644 examples/vault/templates/ingress.yaml create mode 100644 examples/vault/templates/service.yaml create mode 100644 examples/vault/templates/serviceaccount.yaml create mode 100644 examples/vault/templates/tests/test-connection.yaml create mode 100644 examples/vault/values.yaml create mode 100644 scripts/drivers/vault.sh create mode 100644 tests/assets/gpg/private.gpg delete mode 100644 tests/assets/helm_vars/.sops.yaml delete mode 100644 tests/assets/helm_vars/projectX/production/us-east-1/java-app/secrets.yaml delete mode 100644 tests/assets/helm_vars/projectX/production/us-east-1/java-app/value.yaml delete mode 100644 tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml delete mode 100644 tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/value.yaml delete mode 100644 tests/assets/helm_vars/projectY/.sops.yaml delete mode 100644 tests/assets/helm_vars/projectY/production/us-east-1/java-app/secrets.yaml delete mode 100644 tests/assets/helm_vars/projectY/production/us-east-1/java-app/value.yaml delete mode 100644 tests/assets/helm_vars/projectY/sandbox/us-east-1/java-app/secrets.yaml delete mode 100644 tests/assets/helm_vars/projectY/sandbox/us-east-1/java-app/value.yaml delete mode 100644 tests/assets/helm_vars/secrets.yaml delete mode 100644 tests/assets/helm_vars/values.yaml delete mode 100644 tests/assets/pgp/projectx.asc delete mode 100644 tests/assets/pgp/projecty.asc create mode 100644 tests/assets/values/noop/secrets.yaml create mode 100644 tests/assets/values/sops/.sops.yaml create mode 100644 tests/assets/values/sops/secrets.dec.yaml create mode 100644 tests/assets/values/sops/secrets.yaml create mode 100644 tests/assets/values/vault/secrets.yaml create mode 100755 tests/assets/values/vault/seed.sh delete mode 100644 tests/helper.bash delete mode 100755 tests/it/00-setup.bats delete mode 100755 tests/it/11-install.bats delete mode 100755 tests/it/12-upgrade.bats delete mode 100755 tests/it/13-diff.bats delete mode 100755 tests/it/99-cleanup.bats create mode 100755 tests/it/diff.bats create mode 100755 tests/it/install.bats create mode 100755 tests/it/upgrade.bats create mode 100644 tests/lib/create_encrypted_file.bash create mode 100644 tests/lib/helper.bash delete mode 100755 tests/unit/00-setup.bats delete mode 100755 tests/unit/01-plugin-install.bats delete mode 100755 tests/unit/02-secret-driver.bats delete mode 100755 tests/unit/12-dec.bats delete mode 100755 tests/unit/13-enc.bats delete mode 100755 tests/unit/16-lint.bats delete mode 100755 tests/unit/17-template.bats delete mode 100644 tests/unit/18-kubeval.bats delete mode 100755 tests/unit/99-cleanup.bats rename tests/unit/{15-clean.bats => clean.bats} (86%) create mode 100755 tests/unit/dec.bats rename tests/unit/{14-edit.bats => edit.bats} (52%) create mode 100755 tests/unit/enc.bats create mode 100644 tests/unit/kubeval.bats create mode 100755 tests/unit/lint.bats rename tests/{it/01-plugin-install.bats => unit/plugin-install.bats} (83%) create mode 100755 tests/unit/secret-driver.bats create mode 100755 tests/unit/template.bats rename tests/unit/{11-view.bats => view.bats} (57%) diff --git a/.editorconfig b/.editorconfig index 93cd3050..bc7badc6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,4 +9,9 @@ indent_style = space indent_size = 4 max_line_length = 80 trim_trailing_whitespace = true + +[*.sh] shell_variant = posix + +[*.{bash,bats}] +shell_variant = bash diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5ffb7e6e..64985478 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -37,6 +37,7 @@ jobs: - name: Run checkbashisms run: checkbashisms -p scripts/* + unit-tests: runs-on: ${{ matrix.os }} container: ${{ matrix.container }} @@ -47,10 +48,10 @@ jobs: os: [ubuntu-latest, macos-latest] # [dash, zsh] container: [~] include: - - os: ubuntu-latest - container: alpine # ash - - os: ubuntu-latest - container: centos:8 # bash + - os: ubuntu-latest + container: alpine # ash + - os: ubuntu-latest + container: centos:8 # bash steps: - name: Install git & curl run: |- @@ -69,11 +70,15 @@ jobs: with: version: v3.2.0 + - name: Setup vault + uses: volcano-coffee-company/setup-vault@v1 + with: + version: '1.4.1' + - name: Install dependencies run: |- mkdir -p "$GITHUB_WORKSPACE/bin" echo "::add-path::$GITHUB_WORKSPACE/bin/" - #export PATH="$GITHUB_WORKSPACE/bin/:$PATH" curl -sSfL "https://github.com/mozilla/sops/releases/download/v${SOPS_VERSION}/sops-v${SOPS_VERSION}.$(uname | awk '{print tolower($0)}')" -z "$GITHUB_WORKSPACE/bin/sops" -o "$GITHUB_WORKSPACE/bin/sops" chmod +x "$GITHUB_WORKSPACE/bin/sops" @@ -82,7 +87,7 @@ jobs: run: |- tests/bats/core/install.sh "$GITHUB_WORKSPACE" - echo "Shell: $(readlink /bin/sh)" + echo "Shell: $(readlink /bin/sh || readlink /var/select/sh)" bats -v sops --version gpg --version @@ -90,7 +95,20 @@ jobs: - name: helm plugin install run: helm plugin install . - - run: bats --tap -r tests/unit + - name: HELM_SECRETS_DRIVER=sops bats --tap -r tests/unit + run: | + bats --tap -r tests/unit + env: + HELM_SECRETS_DRIVER: sops + + - name: HELM_SECRETS_DRIVER=vault bats --tap -r tests/unit + run: | + vault server -dev -dev-root-token-id=test &>/dev/null & + bats --tap -r tests/unit + env: + HELM_SECRETS_DRIVER: vault + VAULT_ADDR: 'http://127.0.0.1:8200' + integration-tests: needs: [unit-tests] runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index c4e2fc48..aa96ae95 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,4 @@ *.iml /.idea/ - -tests/.home/ -tests/.tmp/ -tests/assets/**/*.yaml.dec -tests/assets/**/*.yaml.test -tests/assets/**/*.tmp.yaml +/tests/.tmp/ +/tests/coverage/ diff --git a/LICENSE b/LICENSE index d6ea3d50..5d0159a0 100644 --- a/LICENSE +++ b/LICENSE @@ -187,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2020 Jan-Otto Kröpke + Copyright 2020 Jan-Otto Kröpke (jkroepke) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 8b368e3e..9d4d0597 100644 --- a/README.md +++ b/README.md @@ -7,22 +7,22 @@ # helm-secrets -## How we use it ? - -We store secrets and values in [`tests/assets/helm_vars/`](tests/assets/helm_vars) dir structure just like in this repository example dir. All this data versioned in GIT. -Working in teams on multiple projects/regions/envs and multiple secrets files at once. - ## Main features -The current version of this plugin using by default [sops](https://github.com/mozilla/sops/) as backend which could be integrated in future into Helm itself, but currently, it is only shell wrapper. +The current version of this plugin using by default [sops](https://github.com/mozilla/sops/) as backend. + +[Vault](http://vaultproject.io/) is support as secret source, too. What kind of problems this plugin solves: -- Simple replaceable layer integrated with helm command for encrypting, decrypting, view secrets files stored in any place. Currently using SOPS as backend. +- Simple replaceable layer integrated with helm command for encrypting, decrypting, view secrets files stored in any place. +- On the fly decryption and cleanup for helm install/upgrade with a helm command wrapper + +If you are using sops you have some additional features: + - [Support for YAML/JSON structures encryption - Helm YAML secrets files](https://github.com/mozilla/sops#important-information-on-types) - [Encryption per value where visual Diff should work even on encrypted files](https://github.com/mozilla/sops/blob/master/example.yaml) - [On the fly decryption for git diff](https://github.com/mozilla/sops#showing-diffs-in-cleartext-in-git) -- On the fly decryption and cleanup for helm install/upgrade with a helm command wrapper - [Multiple key management solutions like PGP, AWS KMS and GCP KMS at same time](https://github.com/mozilla/sops#using-sops-yaml-conf-to-select-kms-pgp-for-new-files) - [Simple adding/removing keys](https://github.com/mozilla/sops#adding-and-removing-keys) - [With AWS KMS permissions management for keys](https://aws.amazon.com/kms/) @@ -30,23 +30,24 @@ What kind of problems this plugin solves: - [Extracting sub-elements from encrypted file structure](https://github.com/mozilla/sops#extract-a-sub-part-of-a-document-tree) - [Encrypt only part of a file if needed](https://github.com/mozilla/sops#encrypting-only-parts-of-a-file). [Example encrypted file](https://github.com/mozilla/sops/blob/master/example.yaml) -## Moving parts of project - -`scripts/install.sh` - Script used as the hook to download and install sops and install git diff configuration for helm-secrets files. +Additional documentation, resources and examples can be found [here](USAGE.md). -`scripts/run.sh` - Main helm-secrets plugin code for all helm-secrets plugin actions available in `helm secrets help` after plugin install +## Moving parts of project -`tests` - Test scripts to check if all parts of the plugin work. Using example dir with vars structure and PGP keys to make real tests on real data with real encryption/decryption. +* `scripts/install.sh` - Script used as the hook to download and install sops and install git diff configuration for helm-secrets files. +* `scripts/run.sh` - Main helm-secrets plugin code for all helm-secrets plugin actions available in `helm secrets help` after plugin install +* `tests` - Test scripts to check if all parts of the plugin work. Using example dir with vars structure and PGP keys to make real tests on real data with real encryption/decryption. +* `examples` - Some example secrets.yaml ## Installation and Dependencies -### SOPS install +### SOPS -Just install the plugin using `helm plugin install https://github.com/jkroepke/helm-secrets` and sops will be installed as part of it. +Just install the plugin using `helm plugin install https://github.com/jkroepke/helm-secrets` and sops will be installed if possible as part of it. You can always install manually in MacOS as below: -``` +```bash brew install sops ``` @@ -56,6 +57,16 @@ For Windows, you cloud install sops separate to mange secrets. This plugin doesn If you want to skip the automatic sops installation, you have to define `SKIP_SOPS_INSTALL=true` on the `helm plugin install` command. +### Vault + +If you use vault with helm-secret, the vault CLI is needed. + +You can always install manually in MacOS as below: + +```bash +brew install vault +``` + ### SOPS git diff Git config part is installed with the plugin, but to be fully functional the following needs to be added to the `.gitattributes` file in the root directory of a charts repo: @@ -67,11 +78,13 @@ secrets.*.yaml diff=sopsdiffer More info on [sops page](https://github.com/mozilla/sops#showing-diffs-in-cleartext-in-git) +By default, helm plugin install does this for you. + ### Using Helm plugin manager As already described above, -``` +```bash helm plugin install https://github.com/jkroepke/helm-secrets ``` @@ -79,7 +92,7 @@ helm plugin install https://github.com/jkroepke/helm-secrets If you need a specific version of helm-secrets, -``` +```bash # MacOS curl -LsSf https://github.com/jkroepke/helm-secrets/archive/v3.0.0.tar.gz | tar -C "$HOME/Library/helm" -xzf- @@ -87,7 +100,7 @@ curl -LsSf https://github.com/jkroepke/helm-secrets/archive/v3.0.0.tar.gz | tar curl -LsSf https://github.com/jkroepke/helm-secrets/archive/v3.0.0.tar.gz | tar -C "$HOME/.local/share/helm" -xzf- ``` -## Change secret driver (experimental) +## Change secret driver It's possible to use an other secret driver then sops, e.g. Hasicorp Vault. @@ -100,7 +113,7 @@ Custom driver can be load via `SECRET_DRIVER` parameter or `-d` option (higher p helm secrets -d sops view ./tests/assets/helm_vars/secrets.yaml # Example for in-tree drivers via environment variable -SECRET_DRIVER=noop helm secrets view ./tests/assets/helm_vars/secrets.yaml +SECRET_DRIVER=vault helm secrets view ./tests/assets/helm_vars/secrets.yaml # Example for out-of-tree drivers helm secrets -d ./path/to/driver.sh view ./tests/assets/helm_vars/secrets.yaml @@ -108,348 +121,12 @@ helm secrets -d ./path/to/driver.sh view ./tests/assets/helm_vars/secrets.yaml Pull Requests are much appreciated. -## Usage and examples +The driver option is a global one. A file level switch isn't supported yet. -``` -$ helm secrets help -GnuPG secrets encryption in Helm Charts - -This plugin provides ability to encrypt/decrypt secrets files -to store in less secure places, before they are installed using -Helm. - -To decrypt/encrypt/edit you need to initialize/first encrypt secrets with -sops - https://github.com/mozilla/sops - -Available Commands: - enc Encrypt secrets file - dec Decrypt secrets file - view Print secrets decrypted - edit Edit secrets file and encrypt afterwards - clean Remove all decrypted files in specified directory (recursively) - wrapper that decrypts secrets[.*].yaml files before running helm -``` - -By convention, files containing secrets are named `secrets.yaml`, or anything beginning with "secrets." and ending with ".yaml". E.g. `secrets.test.yaml` and `secrets.prod.yaml`. - -Decrypted files have the suffix ".yaml.dec" by default. This can be changed using the `HELM_SECRETS_DEC_SUFFIX` environment variable. - -### Basic commands: - -``` - enc Encrypt secrets file - dec Decrypt secrets file - view Print decrypted secrets file - edit Edit secrets file (decrypt before and encrypt after) - clean Delete *.yaml.dec files in directory (recursively) -``` +## Copyright and license -Each of these commands have their own help. - -## Use case and workflow - -### Usage examples - -Note: You need to run `gpg --import tests/assets/pgp/project{x,y}.asc` in order to successfully decrypt secrets included in the examples - -#### Decrypt - -The decrypt operation decrypts a secrets.yaml file and saves the decrypted result in secrets.yaml.dec: - -``` -$ helm secrets dec tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -Decrypting tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -``` - -The secrets.yaml.dec file: - -``` -secret_sandbox_projectx: secret_foo_123 -``` - -Note that if the secrets.yaml.dec file already exists and is newer than secrets.yaml, it will not be overwritten: - -``` -$ helm secrets dec tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -Decrypting tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml.dec is newer than tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -``` - -#### Encrypt - -The encrypt operation encrypts a secrets.yaml.dec file and saves the encrypted result in secrets.yaml: - -If you initially have an unencrypted secrets.yaml file, it will be used as input and will be overwritten: - -``` -$ helm secrets enc tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -Encrypting tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -Encrypted tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -``` - -If you already have an encrypted secrets.yaml file and a decrypted secrets.yaml.dec file, encrypting will encrypt secrets.yaml.dec to secrets.yaml: - -``` -$ helm secrets dec tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -Decrypting tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -$ helm secrets enc tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -Encrypting tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -Encrypted tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml.dec to tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -``` - -#### View - -The view operation decrypts secrets.yaml and prints it to stdout: - -``` -$ helm secrets view tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -secret_sandbox_projectx: secret_foo_123 -``` +© 2020 Jan-Otto Kröpke (jkroepke) -#### Edit +© 2017-2020 [Zendesk](https://github.com/zendesk/helm-secrets) -The edit operation will decrypt the secrets.yaml file and open it in an editor. If the file is modified, it will be encrypted again after you exit the editor. - -``` -$ helm secrets edit tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml -``` - -There is new feature in SOPS master that allows using \$EDITOR to spcify editor used by sops but not released yet. - -#### Clean - -The operation will delete all decrypted files in a directory, recursively: - -``` -$ helm secrets clean tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/ -removed tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml.dec -``` - -If you use git there is commit hook that prevents commiting decrypted files and you can add all \*.yaml.dec files in you repository `.gitignore` file. - -#### Summary - -- Values/Secrets data are not a part of the chart. You need to manage your values, public charts contains mostly defaults without secrets - data vs code -- To use the helm-secrets plugin you should build your `.sops.yaml` rules to make everything automatic -- Use helm secrets for everyday work with you secret yaml files -- Use version control systems like GIT to work in teams and get history of versions -- Everyday search keys is simple even with encrypted files or decrypt on-the-fly with git diff config included -- With example helm_vars you can manage multiple world locations with multiple projects that contain multiple environments -- With the helm wrapper you can easily run "helm secrets install/upgrade/rollback" with secrets files included as `-f` option from you helm_vars values dir tree. - -We use vars for Helm Charts from separate directory tree with the structure like this: - -``` -helm_vars/ -├── .sops.yaml -├── projectX -| ├── .sops.yaml -│ ├── production -│ │ └── us-east-1 -│ │ └── java-app -│ │ └── hello-world -│ │ ├── secrets.yaml -│ │ └── values.yaml -│ ├── sandbox -│ │ └── us-east-1 -│ │ └── java-app -│ │ └── hello-world -│ │ ├── secrets.yaml -│ │ └── values.yaml -| ├── secrets.yaml -│ └── values.yaml -├── projectY -| ├── .sops.yaml -│ ├── production -│ │ └── us-east-1 -│ │ └── java-app -│ │ └── hello-world -│ │ ├── secrets.yaml -│ │ └── values.yaml -│ ├── sandbox -│ │ └── us-east-1 -│ │ └── java-app -│ │ └── hello-world -│ │ ├── secrets.yaml -│ │ └── values.yaml -| ├── secrets.yaml -│ └── values.yaml -├── secrets.yaml -└── values.yaml -``` - -As you can see we can run different PGP or KMS keys per project, globally or per any tree level. Thanks to this we can isolate tree on different CI/CD instances using same GIT repository. -As we use simple -f option when running the helm wrapper we can just use encrypted secrets.yaml and all these secrets will be decrypted and cleaned on the fly before and after helm run. - -`.sops.yaml` file example - -``` ---- -creation_rules: -# Encrypt with AWS KMS -- kms: 'arn:aws:kms:us-east-1:222222222222:key/111b1c11-1c11-1fd1-aa11-a1c1a1sa1dsl1+arn:aws:iam::222222222222:role/helm_secrets' - -# Encrypt using GCP KMS -- gcp_kms: projects/mygcproject/locations/global/keyRings/mykeyring/cryptoKeys/thekey - -# As failover encrypt with PGP -- pgp: '000111122223333444AAAADDDDFFFFGGGG000999' - -# For more help look at https://github.com/mozilla/sops -``` - -Multiple KMS and PGP are allowed. - -Everything is described in SOPS docs - links in this project description. - -### Helm Wrapper - -Running helm to install/upgrade chart with our secrets files is simple with the included helm wrapper which will decrypt on-the-fly and use decrypted secrets files in the actual helm command. - -The wrapper enables you to call these helm commands with on-the-fly decryption of secrets files passed as `-f` or `--values` arguments. Instead of calling e.g. `helm install ...` you can call `helm secrets install ...` to get on-the-fly decryption. - -The diff command is a separate helm plugin, [helm-diff](https://github.com/databus23/helm-diff). Using it you can view the changes that would be deployed before deploying. In the same way as above, instead of calling e.g. `helm diff upgrade ...` you can call `helm secrets diff upgrade ...`, and so on. - -Note that if a decrypted secrets.yaml.dec file exists and is newer then the secrets.yaml file, it will be used in the wrapped command rather than decrypting secrets.yaml. - -Real example of the helm wrapper usage with simple java helloworld application. - -``` -AWS_PROFILE=sandbox helm secrets upgrade \ - helloworld \ - stable/java-app \ - --install \ - --timeout 600 \ - --wait \ - --kube-context=sandbox \ - --namespace=projectx \ - --set global.app_version=bff8fc4 \ - -f helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/secrets.yaml \ - -f helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/values.yaml \ - -f helm_vars/secrets.yaml \ - -f helm_vars/values.yaml - -Release "helloworld" has been upgraded. Happy Helming! -LAST DEPLOYED: Fri May 5 13:27:01 2017 -NAMESPACE: projectx -STATUS: DEPLOYED - -RESOURCES: -==> extensions/v1beta1/Deployment -NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE -helloworld 3 3 3 2 1h - -==> v1/Secret -NAME TYPE DATA AGE -helloworld Opaque 10 1h - -==> v1/ConfigMap -NAME DATA AGE -helloworld 2 1h - -==> v1/Service -NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE -helloworld 100.65.221.245 8080/TCP 1h - -NOTES: -Deploy success helloworld-bff8fc4 in namespace projectx - -removed helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/secrets.yaml.dec -removed helm_vars/secrets.yaml.dec -``` - -You can see that we use a global secrets file and a specific secrets file for this app in this project/environment/region. We use some plain value files next to secrets. We use values from secrets in some secrets template in helloworld application chart template and some values are used in the configmap template in the same chart. Some values are added as env variables in deployment manifest templates in the chart. As you can see we can use secrets and values in helm in many ways. Everything depends on use case. - -Even when helm failed then decrypted files are cleaned - -``` -AWS_PROFILE=sandbox helm-wrapper upgrade \ - helloworld \ - stable/java-app \ - --install \ - --timeout 600 \ - --wait \ - --kube-context=wrongcontext \ - --namespace=projectx \ - --set global.app_version=bff8fc4 \ - -f helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/secrets.yaml \ - -f helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/values.yaml \ - -f helm_vars/secrets.yaml \ - -f helm_vars/values.yaml - -Error: could not get kubernetes config for context 'wrongcontext': context "wrongcontext" does not exist - -removed helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/secrets.yaml.dec -removed helm_vars/secrets.yaml.dec -``` - -#### Using secret values in Helm chart secrets template - -We just need to create Kubernetes secrets template in chart templates dir. -For example in your charts repo you have `stable/helloworld/`. Inside this chart you should have `stable/helloworld/templates/` dir and then create the `stable/helloworld/templates/secrets.yaml` file with content as specified bellow. - -``` -apiVersion: v1 -kind: Secret -metadata: - name: helloworld - labels: - app: helloworld - chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" - release: "{{ .Release.Name }}" - heritage: "{{ .Release.Service }}" -type: Opaque -data: - my_secret_key: {{ .Values.secret_sandbox_helloworld | b64enc | quote }} -``` - -In this example you have a Kubernetes secret named "helloworld" and data inside this secret will be filled in from values defined in `-f helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/secrets.yaml`. We use `.Values.secret_sandbox_helloworld` to refer to the value in the decrypted secret file. In this way, the value from the decrypted `helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/secrets.yaml` will be available as `my_secret_key` in Kubernetes. - -You can now use the "helloworld" secret in your deployment manifest (or any other manifest supporting secretKeyRef) in the env section like this: - -``` -apiVersion: extensions/v1beta1 -kind: Deployment -... -... - containers: - ... - ... - env: - - name: my_new_secret_key - valueFrom: - secretKeyRef: - name: helloworld - key: my_secret_key -``` - -## Important Tips - -### Prevent committing decrypted files to git - -If you like to secure situation when decrypted file is committed by mistake to git you can add your secrets.yaml.dec files to you charts project repository `.gitignore`. - -A second level of security is to add for example a `.sopscommithook` file inside your chart repository local commit hook. - -This will prevent committing decrypted files without sops metadata. - -`.sopscommithook` content example: - -``` -#!/bin/sh - -for FILE in $(git diff-index HEAD --name-only | grep | grep "secrets.y"); do - if [ -f "$FILE" ] && ! grep -C10000 "sops:" $FILE | grep -q "version:"; then - echo "!!!!! $FILE" 'File is not encrypted !!!!!' - echo "Run: helm secrets enc " - exit 1 - fi -done -exit -``` - -Additionally you could create a `.gitignore` to exclude decrypted files from checkin: - -```gitignore -*.yaml.dec -``` +Licensed under the [Apache License, Version 2.0](LICENSE) diff --git a/USAGE.md b/USAGE.md new file mode 100644 index 00000000..18cc4249 --- /dev/null +++ b/USAGE.md @@ -0,0 +1,323 @@ +# Usage and examples + +``` +$ helm secrets help +GnuPG secrets encryption in Helm Charts + +This plugin provides ability to encrypt/decrypt secrets files +to store in less secure places, before they are installed using +Helm. + +To decrypt/encrypt/edit you need to initialize/first encrypt secrets with +sops - https://github.com/mozilla/sops + +Available Commands: + enc Encrypt secrets file + dec Decrypt secrets file + view Print secrets decrypted + edit Edit secrets file and encrypt afterwards + clean Remove all decrypted files in specified directory (recursively) + wrapper that decrypts secrets[.*].yaml files before running helm +``` + +By convention, files containing secrets are named `secrets.yaml`, or anything beginning with "secrets" and ending with ".yaml". E.g. `secrets.test.yaml`, `secrets.prod.yaml` `secretsCOOL.yaml`. + +Decrypted files have the suffix ".yaml.dec" by default. This can be changed using the `HELM_SECRETS_DEC_SUFFIX` environment variable. + +## Basic commands: + +``` + enc Encrypt secrets file + dec Decrypt secrets file + view Print decrypted secrets file + edit Edit secrets file (decrypt before and encrypt after) + clean Delete *.yaml.dec files in directory (recursively) +``` + +Each of these commands have their own help. + +# Use case and workflow + +## Usage examples + +Note: You need to run `gpg --import tests/assets/gpg/private.gpg` in order to successfully decrypt secrets included in the examples + +### Decrypt + +The decrypt operation decrypts a secrets.yaml file and saves the decrypted result in secrets.yaml.dec: + +```bash +helm secrets dec examples/sops/secrets.yaml +``` + +The secrets.yaml.dec file: + +``` +podAnnotations: + secret: value +``` + +Note that if the secrets.yaml.dec file already exists and is newer than secrets.yaml, it will not be overwritten: + +``` +$ helm secrets dec examples/sops/secrets.yaml +Decrypting examples/sops/secrets.yaml +examples/sops/secrets.yaml.dec is newer than examples/sops/secrets.yaml +``` + +### Encrypt + +The encrypt operation encrypts a secrets.yaml.dec file and saves the encrypted result in secrets.yaml: + +If you initially have an unencrypted secrets.yaml file, it will be used as input and will be overwritten: + +``` +$ helm secrets enc examples/sops/secrets.yaml +Encrypting examples/sops/secrets.yaml +Encrypted examples/sops/secrets.yaml +``` + +If you already have an encrypted secrets.yaml file and a decrypted secrets.yaml.dec file, encrypting will encrypt secrets.yaml.dec to secrets.yaml: + +``` +$ helm secrets dec examples/sops/secrets.yaml +Decrypting examples/sops/secrets.yaml +$ helm secrets enc examples/sops/secrets.yaml +Encrypting examples/sops/secrets.yaml +Encrypted examples/sops/secrets.yaml.dec to examples/sops/secrets.yaml +``` + +### View + +The view operation decrypts secrets.yaml and prints it to stdout: + +``` +$ helm secrets view examples/sops/secrets.yaml +podAnnotations: + secret: value +``` + +### Edit + +The edit operation will decrypt the secrets.yaml file and open it in an editor. If the file is modified, it will be encrypted again after you exit the editor. + +``` +$ helm secrets edit examples/sops/secrets.yaml +``` + +There is new feature in SOPS master that allows using \$EDITOR to spcify editor used by sops but not released yet. + +### Clean + +The operation will delete all decrypted files in a directory, recursively: + +``` +$ helm secrets clean examples/sops/ +removed examples/sops/secrets.yaml.dec +``` + +If you use git there is commit hook that prevents commiting decrypted files and you can add all \*.yaml.dec files in you repository `.gitignore` file. + +### Summary + +- Values/Secrets data are not a part of the chart. You need to manage your values, public charts contains mostly defaults without secrets - data vs code +- To use the helm-secrets plugin you should build your `.sops.yaml` rules to make everything automatic +- Use helm secrets for everyday work with you secret yaml files +- Use version control systems like GIT to work in teams and get history of versions +- Everyday search keys is simple even with encrypted files or decrypt on-the-fly with git diff config included +- With example helm_vars you can manage multiple world locations with multiple projects that contain multiple environments +- With the helm wrapper you can easily run "helm secrets install/upgrade/rollback" with secrets files included as `-f` option from you helm_vars values dir tree. + +We use vars for Helm Charts from separate directory tree with the structure like this: + +``` +charts/ +├── .sops.yaml +└── projectX + ├── .sops.yaml + ├── stages + │ ├── dev + │ │ ├── secrets.yaml + │ │ └── env.yaml + │ └── test + │ ├── secrets.yaml + │ └── env.yaml + ├── secrets.yaml + └── values.yaml +``` + +As you can see we can run different PGP or KMS keys per project, globally or per any tree level. Thanks to this we can isolate tree on different CI/CD instances using same GIT repository. +As we use simple -f option when running the helm wrapper we can just use encrypted secrets.yaml and all these secrets will be decrypted and cleaned on the fly before and after helm run. + +`.sops.yaml` file example + +``` +--- +creation_rules: + Encrypt with AWS KMS +- kms: 'arn:aws:kms:us-east-1:222222222222:key/111b1c11-1c11-1fd1-aa11-a1c1a1sa1dsl1+arn:aws:iam::222222222222:role/helm_secrets' + + Encrypt using GCP KMS +- gcp_kms: projects/mygcproject/locations/global/keyRings/mykeyring/cryptoKeys/thekey + + As failover encrypt with PGP (obtan via gpg --list-secret-keys) +- pgp: '000111122223333444AAAADDDDFFFFGGGG000999' + + For more help look at https://github.com/mozilla/sops +``` + +Multiple KMS and PGP are allowed. + +Everything is described in SOPS docs - links in this project description. + +## Helm Wrapper + +Running helm to install/upgrade chart with our secrets files is simple with the included helm wrapper which will decrypt on-the-fly and use decrypted secrets files in the actual helm command. + +The wrapper enables you to call these helm commands with on-the-fly decryption of secrets files passed as `-f` or `--values` arguments. Instead of calling e.g. `helm install ...` you can call `helm secrets install ...` to get on-the-fly decryption. + +The diff command is a separate helm plugin, [helm-diff](https://github.com/databus23/helm-diff). Using it you can view the changes that would be deployed before deploying. In the same way as above, instead of calling e.g. `helm diff upgrade ...` you can call `helm secrets diff upgrade ...`, and so on. + +Note that if a decrypted secrets.yaml.dec file exists and is newer then the secrets.yaml file, it will be used in the wrapped command rather than decrypting secrets.yaml. + +Real example of the helm wrapper usage with simple java helloworld application. + +``` +AWS_PROFILE=sandbox helm secrets upgrade \ + helloworld \ + stable/java-app \ + --install \ + --timeout 600 \ + --wait \ + --kube-context=sandbox \ + --namespace=projectx \ + --set global.app_version=bff8fc4 \ + -f helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/secrets.yaml \ + -f helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/values.yaml \ + -f helm_vars/secrets.yaml \ + -f helm_vars/values.yaml + +Release "helloworld" has been upgraded. Happy Helming! +LAST DEPLOYED: Fri May 5 13:27:01 2017 +NAMESPACE: projectx +STATUS: DEPLOYED + +RESOURCES: +==> extensions/v1beta1/Deployment +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +helloworld 3 3 3 2 1h + +==> v1/Secret +NAME TYPE DATA AGE +helloworld Opaque 10 1h + +==> v1/ConfigMap +NAME DATA AGE +helloworld 2 1h + +==> v1/Service +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +helloworld 100.65.221.245 8080/TCP 1h + +NOTES: +Deploy success helloworld-bff8fc4 in namespace projectx + +removed helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/secrets.yaml.dec +removed helm_vars/secrets.yaml.dec +``` + +You can see that we use a global secrets file and a specific secrets file for this app in this project/environment/region. We use some plain value files next to secrets. We use values from secrets in some secrets template in helloworld application chart template and some values are used in the configmap template in the same chart. Some values are added as env variables in deployment manifest templates in the chart. As you can see we can use secrets and values in helm in many ways. Everything depends on use case. + +Even when helm failed then decrypted files are cleaned + +``` +AWS_PROFILE=sandbox helm-wrapper upgrade \ + helloworld \ + stable/java-app \ + --install \ + --timeout 600 \ + --wait \ + --kube-context=wrongcontext \ + --namespace=projectx \ + --set global.app_version=bff8fc4 \ + -f helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/secrets.yaml \ + -f helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/values.yaml \ + -f helm_vars/secrets.yaml \ + -f helm_vars/values.yaml + +Error: could not get kubernetes config for context 'wrongcontext': context "wrongcontext" does not exist + +removed helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/secrets.yaml.dec +removed helm_vars/secrets.yaml.dec +``` + +### Using secret values in Helm chart secrets template + +We just need to create Kubernetes secrets template in chart templates dir. +For example in your charts repo you have `stable/helloworld/`. Inside this chart you should have `stable/helloworld/templates/` dir and then create the `stable/helloworld/templates/secrets.yaml` file with content as specified bellow. + +``` +apiVersion: v1 +kind: Secret +metadata: + name: helloworld + labels: + app: helloworld + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +type: Opaque +data: + my_secret_key: {{ .Values.secret_sandbox_helloworld | b64enc | quote }} +``` + +In this example you have a Kubernetes secret named "helloworld" and data inside this secret will be filled in from values defined in `-f helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/secrets.yaml`. We use `.Values.secret_sandbox_helloworld` to refer to the value in the decrypted secret file. In this way, the value from the decrypted `helm_vars/projectx/sandbox/us-east-1/java-app/helloworld/secrets.yaml` will be available as `my_secret_key` in Kubernetes. + +You can now use the "helloworld" secret in your deployment manifest (or any other manifest supporting secretKeyRef) in the env section like this: + +``` +apiVersion: extensions/v1beta1 +kind: Deployment +... +... + containers: + ... + ... + env: + - name: my_new_secret_key + valueFrom: + secretKeyRef: + name: helloworld + key: my_secret_key +``` + +# Important Tips + +## Prevent committing decrypted files to git + +If you like to secure situation when decrypted file is committed by mistake to git you can add your secrets.yaml.dec files to you charts project repository `.gitignore`. + +A second level of security is to add for example a `.sopscommithook` file inside your chart repository local commit hook. + +This will prevent committing decrypted files without sops metadata. + +`.sopscommithook` content example: + +``` +!/bin/sh + +for FILE in $(git diff-index HEAD --name-only | grep | grep "secrets.y"); do + if [ -f "$FILE" ] && ! grep -C10000 "sops:" $FILE | grep -q "version:"; then + echo "!!!!! $FILE" 'File is not encrypted !!!!!' + echo "Run: helm secrets enc " + exit 1 + fi +done +exit +``` + +Additionally you could create a `.gitignore` to exclude decrypted files from checkin: + +```gitignore +*.yaml.dec +``` diff --git a/completion.yaml b/completion.yaml index 5ec3eb51..d1872f35 100644 --- a/completion.yaml +++ b/completion.yaml @@ -2,37 +2,16 @@ name: secrets flags: - help - driver + - quiet commands: - name: dec - flags: - - help - name: enc - flags: - - help - name: view - flags: - - help - name: edit - flags: - - help - name: clean - flags: - - help - name: lint - flags: - - quiet - name: template - flags: - - quiet - name: install - flags: - - quiet - name: upgrade - flags: - - quiet - name: diff - flags: - - quiet - name: kubeval - flags: - - quiet diff --git a/examples/sops/.helmignore b/examples/sops/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/examples/sops/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/tests/assets/helm_vars/projectX/.sops.yaml b/examples/sops/.sops.yaml similarity index 65% rename from tests/assets/helm_vars/projectX/.sops.yaml rename to examples/sops/.sops.yaml index f944d20c..ca2b0e7e 100644 --- a/tests/assets/helm_vars/projectX/.sops.yaml +++ b/examples/sops/.sops.yaml @@ -1,3 +1,3 @@ creation_rules: # encrypted using helm-secrets-example-projectx - - pgp: "4434EA5D05F10F59D0DF7399AF1D073646ED4927" + - pgp: "D6174A02027050E59C711075B430C4E58E2BBBA3" diff --git a/examples/sops/Chart.yaml b/examples/sops/Chart.yaml new file mode 100644 index 00000000..311fe619 --- /dev/null +++ b/examples/sops/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +name: simple-chart +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +appVersion: 1.16.0 diff --git a/examples/sops/secrets.yaml b/examples/sops/secrets.yaml new file mode 100644 index 00000000..fb4bc617 --- /dev/null +++ b/examples/sops/secrets.yaml @@ -0,0 +1,32 @@ +podAnnotations: + secret: ENC[AES256_GCM,data:ky/H5qo=,iv:HBO2U9E9+QsC7VvSSM3XmvYXOHW+A5UqjBd6HGF1eVQ=,tag:EGh2niWg5whUZ8XhLFwMXw==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + lastmodified: '2020-05-06T20:49:45Z' + mac: ENC[AES256_GCM,data:YbpCUV+Olo5ybb8QNf+BXZaryyNh+mfe6sxAGs/yQIauJejBZE4DvG6Tdaul2QaazaNEe7jdg3e1qjkRZMH6/CQLCNk1hJ6cAy+Wws379C9uczN0fksBSjV8OCR0ua8FcTSwZ6daUqaUohTEqK3BEpnQmD5o1XcaACDOhMcqJ5Q=,iv:jQFmuea50nmMxhe16ayNIQc8fxeVjO+onyQsASZ77lM=,tag:yG2J4s+3qTTjBTyo3/JTYw==,type:str] + pgp: + - created_at: '2020-05-06T20:49:44Z' + enc: |- + -----BEGIN PGP MESSAGE----- + + wcFMAxYpv4YXKfBAARAAgHaPKFVKMObPsRWix3ZKmTjLG+qgzIEZzHf3IpVppLwr + jhDqv7YNlpsdQZyZFcjJXgI7ov3Vs0S83ZfTtlfYMeEND0EE5BGRtA+j79SmR57H + dxeu/k+R1Za83ZjNOqDEnAy4DDoumaZ4J3cDoa5+e0fmAjRasUu6A+Ksnj4Wa4js + CNTKgha78LzXEoL0lTUaoTnL06unUzk9SPXN8evf5/Zn9SMZiHq4fV+JlCiGPcm7 + EUe4Wu3MctmbwdGNJ8heQ/wbIs47JeeCTtBLs/8eA31JMXkmPgBvn3n25aoaRRuJ + Gx3WJK6e8tOq7XvWpgRitbj/RlhaRfroGjc0n6EI5b9BVdc8PhSjnqQOWRyqERi3 + i+eeCsUW9F7UMUUnT0KmnO8q8J6occWmhdUfWPoWBxBljlRQ28M3juBH2xAwtOIy + nb9rzhefwAzB6ALN1daEjOaWL0Rb+I8BCl/keW7qOw0CNyK5CUkbLwSjY0P9ssTg + pfqD0z5+/9sWEBHR5n0aiSXx1KkoyN92xu5tLkPoTVRWH5fBvHTieA/uXqCvGqDg + 9utfJZzYQP6PDW+FHwbQOepkmfEqVu2tWetk8ZYMxGjlW52HAnwQvnQmPDGF0/ZK + 5CFUsxR0IEAadBAqymLTOoMjzma18lfv4/7YsfQVuR7kkhtyC20sB9EFY1aOJIXS + 4AHku4irpzIM9eHTmSSj4kMl8+F/B+C/4GHh6PPgSuJPwZNq4EflBlI4oaGTSxFF + R1owBOlCFf5YXz9VOMTPTdZZtOozkW/gLOSWfc9SgaICPaDQxbPtY/Dd4nseXlrh + v6UA + =8Xmb + -----END PGP MESSAGE----- + fp: 4434EA5D05F10F59D0DF7399AF1D073646ED4927 + unencrypted_suffix: _unencrypted + version: 3.5.0 diff --git a/examples/sops/secrets.yaml.dec b/examples/sops/secrets.yaml.dec new file mode 100644 index 00000000..6513c279 --- /dev/null +++ b/examples/sops/secrets.yaml.dec @@ -0,0 +1,2 @@ +podAnnotations: + secret: value diff --git a/examples/sops/templates/NOTES.txt b/examples/sops/templates/NOTES.txt new file mode 100644 index 00000000..0a893a5e --- /dev/null +++ b/examples/sops/templates/NOTES.txt @@ -0,0 +1,21 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "simple-chart.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "simple-chart.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "simple-chart.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "simple-chart.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 +{{- end }} diff --git a/examples/sops/templates/_helpers.tpl b/examples/sops/templates/_helpers.tpl new file mode 100644 index 00000000..f01138a6 --- /dev/null +++ b/examples/sops/templates/_helpers.tpl @@ -0,0 +1,63 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "simple-chart.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "simple-chart.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "simple-chart.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "simple-chart.labels" -}} +helm.sh/chart: {{ include "simple-chart.chart" . }} +{{ include "simple-chart.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "simple-chart.selectorLabels" -}} +app.kubernetes.io/name: {{ include "simple-chart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "simple-chart.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "simple-chart.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/examples/sops/templates/deployment.yaml b/examples/sops/templates/deployment.yaml new file mode 100644 index 00000000..82ed17a0 --- /dev/null +++ b/examples/sops/templates/deployment.yaml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "simple-chart.fullname" . }} + labels: + {{- include "simple-chart.labels" . | nindent 4 }} +spec: +{{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} +{{- end }} + selector: + matchLabels: + {{- include "simple-chart.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "simple-chart.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "simple-chart.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 80 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/examples/sops/templates/hpa.yaml b/examples/sops/templates/hpa.yaml new file mode 100644 index 00000000..a9f63dd9 --- /dev/null +++ b/examples/sops/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "simple-chart.fullname" . }} + labels: + {{- include "simple-chart.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "simple-chart.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/examples/sops/templates/ingress.yaml b/examples/sops/templates/ingress.yaml new file mode 100644 index 00000000..eebfcaa4 --- /dev/null +++ b/examples/sops/templates/ingress.yaml @@ -0,0 +1,41 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "simple-chart.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "simple-chart.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ . }} + backend: + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} diff --git a/examples/sops/templates/service.yaml b/examples/sops/templates/service.yaml new file mode 100644 index 00000000..f4bb7eba --- /dev/null +++ b/examples/sops/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "simple-chart.fullname" . }} + labels: + {{- include "simple-chart.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "simple-chart.selectorLabels" . | nindent 4 }} diff --git a/examples/sops/templates/serviceaccount.yaml b/examples/sops/templates/serviceaccount.yaml new file mode 100644 index 00000000..a17d70a0 --- /dev/null +++ b/examples/sops/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "simple-chart.serviceAccountName" . }} + labels: + {{- include "simple-chart.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/examples/sops/templates/tests/test-connection.yaml b/examples/sops/templates/tests/test-connection.yaml new file mode 100644 index 00000000..05870a2d --- /dev/null +++ b/examples/sops/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "simple-chart.fullname" . }}-test-connection" + labels: + {{- include "simple-chart.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "simple-chart.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/examples/sops/values.yaml b/examples/sops/values.yaml new file mode 100644 index 00000000..08baa117 --- /dev/null +++ b/examples/sops/values.yaml @@ -0,0 +1,79 @@ +# Default values for simple-chart. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: nginx + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart version. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: [] + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/examples/vault/.helmignore b/examples/vault/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/examples/vault/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/examples/vault/Chart.yaml b/examples/vault/Chart.yaml new file mode 100644 index 00000000..311fe619 --- /dev/null +++ b/examples/vault/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +name: simple-chart +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +appVersion: 1.16.0 diff --git a/examples/vault/secrets.yaml b/examples/vault/secrets.yaml new file mode 100644 index 00000000..58eccbe4 --- /dev/null +++ b/examples/vault/secrets.yaml @@ -0,0 +1,2 @@ +podAnnotations: + secret: !vault secret/production#pod_annotation diff --git a/examples/vault/templates/NOTES.txt b/examples/vault/templates/NOTES.txt new file mode 100644 index 00000000..0a893a5e --- /dev/null +++ b/examples/vault/templates/NOTES.txt @@ -0,0 +1,21 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "simple-chart.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "simple-chart.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "simple-chart.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "simple-chart.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 +{{- end }} diff --git a/examples/vault/templates/_helpers.tpl b/examples/vault/templates/_helpers.tpl new file mode 100644 index 00000000..f01138a6 --- /dev/null +++ b/examples/vault/templates/_helpers.tpl @@ -0,0 +1,63 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "simple-chart.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "simple-chart.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "simple-chart.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "simple-chart.labels" -}} +helm.sh/chart: {{ include "simple-chart.chart" . }} +{{ include "simple-chart.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "simple-chart.selectorLabels" -}} +app.kubernetes.io/name: {{ include "simple-chart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "simple-chart.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "simple-chart.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/examples/vault/templates/deployment.yaml b/examples/vault/templates/deployment.yaml new file mode 100644 index 00000000..82ed17a0 --- /dev/null +++ b/examples/vault/templates/deployment.yaml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "simple-chart.fullname" . }} + labels: + {{- include "simple-chart.labels" . | nindent 4 }} +spec: +{{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} +{{- end }} + selector: + matchLabels: + {{- include "simple-chart.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "simple-chart.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "simple-chart.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 80 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/examples/vault/templates/hpa.yaml b/examples/vault/templates/hpa.yaml new file mode 100644 index 00000000..a9f63dd9 --- /dev/null +++ b/examples/vault/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "simple-chart.fullname" . }} + labels: + {{- include "simple-chart.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "simple-chart.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/examples/vault/templates/ingress.yaml b/examples/vault/templates/ingress.yaml new file mode 100644 index 00000000..eebfcaa4 --- /dev/null +++ b/examples/vault/templates/ingress.yaml @@ -0,0 +1,41 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "simple-chart.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "simple-chart.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ . }} + backend: + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} diff --git a/examples/vault/templates/service.yaml b/examples/vault/templates/service.yaml new file mode 100644 index 00000000..f4bb7eba --- /dev/null +++ b/examples/vault/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "simple-chart.fullname" . }} + labels: + {{- include "simple-chart.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "simple-chart.selectorLabels" . | nindent 4 }} diff --git a/examples/vault/templates/serviceaccount.yaml b/examples/vault/templates/serviceaccount.yaml new file mode 100644 index 00000000..a17d70a0 --- /dev/null +++ b/examples/vault/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "simple-chart.serviceAccountName" . }} + labels: + {{- include "simple-chart.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/examples/vault/templates/tests/test-connection.yaml b/examples/vault/templates/tests/test-connection.yaml new file mode 100644 index 00000000..05870a2d --- /dev/null +++ b/examples/vault/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "simple-chart.fullname" . }}-test-connection" + labels: + {{- include "simple-chart.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "simple-chart.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/examples/vault/values.yaml b/examples/vault/values.yaml new file mode 100644 index 00000000..08baa117 --- /dev/null +++ b/examples/vault/values.yaml @@ -0,0 +1,79 @@ +# Default values for simple-chart. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: nginx + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart version. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: [] + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/scripts/commands/enc.sh b/scripts/commands/enc.sh index 2d21430b..afbaf72f 100644 --- a/scripts/commands/enc.sh +++ b/scripts/commands/enc.sh @@ -33,14 +33,13 @@ encrypt_helper() { printf 'File does not exist: %s\n' "${dir}/${file}" exit 1 fi - file_dec="$(file_dec_name "${file}")" if [ ! -f "${file_dec}" ]; then file_dec="${file}" fi - if is_file_encrypted "${file_dec}"; then + if driver_is_file_encrypted "${file_dec}"; then printf "Already encrypted: %s\n" "${file_dec}" exit 1 fi @@ -48,7 +47,7 @@ encrypt_helper() { driver_encrypt_file "yaml" "${file_dec}" "${file}" if [ "${file}" = "${file_dec}" ]; then - printf 'Encrypted %s\n' "${file}" + printf 'Encrypted %s\n' "${file_dec}" else printf 'Encrypted %s to %s\n' "${file_dec}" "${file}" fi diff --git a/scripts/commands/helm.sh b/scripts/commands/helm.sh index b30e543d..04c4fe06 100644 --- a/scripts/commands/helm.sh +++ b/scripts/commands/helm.sh @@ -40,8 +40,6 @@ helm_wrapper_cleanup() { helm_wrapper() { decrypted_files=$(mktemp) - QUIET=false - HELM_CMD_SET=false argc=$# j=0 @@ -84,22 +82,7 @@ helm_wrapper() { shift j=$((j + 1)) ;; - -*) - if [ "${HELM_CMD_SET}" = "false" ]; then - case "$1" in - -q | --quiet) - QUIET=true - ;; - *) - set -- "$@" "$1" - ;; - esac - else - set -- "$@" "$1" - fi - ;; *) - HELM_CMD_SET=true set -- "$@" "$1" ;; esac diff --git a/scripts/drivers/noop.sh b/scripts/drivers/noop.sh index 576e0061..31a4f349 100644 --- a/scripts/drivers/noop.sh +++ b/scripts/drivers/noop.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh driver_is_file_encrypted() { - true + false } driver_encrypt_file() { diff --git a/scripts/drivers/sops.sh b/scripts/drivers/sops.sh index b0fdec8c..6522d2d1 100644 --- a/scripts/drivers/sops.sh +++ b/scripts/drivers/sops.sh @@ -1,9 +1,9 @@ #!/usr/bin/env sh driver_is_file_encrypted() { - file="${1}" + input="${1}" - grep -q 'sops:' "${file}" && grep -q 'version:' "${file}" + grep -q 'sops:' "${input}" && grep -q 'version:' "${input}" } driver_encrypt_file() { diff --git a/scripts/drivers/vault.sh b/scripts/drivers/vault.sh new file mode 100644 index 00000000..55b05865 --- /dev/null +++ b/scripts/drivers/vault.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env sh + +_VAULT_REGEX='!vault [A-z0-9][A-z0-9/\-]*\#[A-z0-9][A-z0-9-]*' + +_sed_i() { + # MacOS syntax is different for in-place + if [ "$(uname)" = "Darwin" ]; then + sed -i "" "$@" + else + sed -i "$@" + fi +} + +_regex_escape() { + # This is a function because dealing with quotes is a pain. + # http://stackoverflow.com/a/2705678/120999 + sed -e 's/[]\/()$*.^|[]/\\&/g' +} + +driver_is_file_encrypted() { + input="${1}" + + grep -q -e "${_VAULT_REGEX}" "${input}" +} + +driver_encrypt_file() { + echo "Encrypting files via vault driver is not supported!" + exit 1 +} + +driver_decrypt_file() { + type="${1}" + input="${2}" + # if omit then output to stdout + output="${3:-}" + + if [ "${type}" != "yaml" ]; then + echo "Only decryption of yaml files are allowed!" + exit 1 + fi + + input_tmp="$(mktemp)" + output_tmp="$(mktemp)" + cp "${input}" "${input_tmp}" + + # Grab all patterns, dedublicate and pass it to loop + # https://github.com/koalaman/shellcheck/wiki/SC2013 + grep -o -e "${_VAULT_REGEX}" "${input}" | sort | uniq | while IFS= read -r EXPRESSION; do + # remove prefix + VAULT_SECRET="$(echo "${EXPRESSION}" | sed 's/!vault //')" + VAULT_SECRET_PATH="$(echo "${VAULT_SECRET}" | cut -d '#' -f1)" + VAULT_SECRET_FIELD="$(echo "${VAULT_SECRET}" | cut -d '#' -f2)" + + if ! SECRET="$(vault kv get -format=yaml -field="${VAULT_SECRET_FIELD}" "${VAULT_SECRET_PATH}")"; then + echo "Error while get secret from vault!" >&2 + echo vault kv get -format=yaml -field="${VAULT_SECRET_FIELD}" "${VAULT_SECRET_PATH}" >&2 + exit 1 + fi + + # generate yaml anchor name + YAML_ANCHOR=$(printf 'vault-%s-%s' "${VAULT_SECRET_PATH}" "${VAULT_SECRET_FIELD}" | tr '/' _) + + # Replace vault expression with yaml anchor + EXPRESSION="$(echo "${EXPRESSION}" | _regex_escape)" + _sed_i "s/${EXPRESSION}/*${YAML_ANCHOR}/g" "${input_tmp}" + + if [ "${VAULT_SECRET_FIELD}" = "data" ]; then + { + printf '.%s: &%s\n' "${YAML_ANCHOR}" "${YAML_ANCHOR}" + printf '%s\n\n' "${SECRET}" | sed -e 's/^/ /g' + } >>"${output_tmp}" + else + { + printf '.%s: &%s ' "${YAML_ANCHOR}" "${YAML_ANCHOR}" + printf '%s\n\n' "${SECRET}" + } >>"${output_tmp}" + fi + done + + if [ "${output}" = "" ]; then + cat "${output_tmp}" "${input_tmp}" + else + cat "${output_tmp}" "${input_tmp}" >"${output}" + fi +} + +driver_edit_file() { + echo "Editing files via vault driver is not supported!" + exit 1 +} diff --git a/scripts/run.sh b/scripts/run.sh index 207d29cb..f17a1915 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -5,8 +5,11 @@ set -eu # Path to current directory SCRIPT_DIR="$(dirname "$0")" +# Output debug infos +QUIET="${HELM_SECRETS_QUIET:-false}" + # Define the secret driver engine -SECRET_DRIVER="${SECRET_DRIVER:-sops}" +SECRET_DRIVER="${HELM_SECRETS_DRIVER:-sops}" # The suffix to use for decrypted files. The default can be overridden using # the HELM_SECRETS_DEC_SUFFIX environment variable. @@ -75,83 +78,95 @@ load_secret_driver() { fi } -# TODO more generic arg parser if we have more commands -if [ "${1:-}" = "-d" ] || [ "${1:-}" = "--driver" ]; then - load_secret_driver "$2" - shift - shift -else - load_secret_driver "$SECRET_DRIVER" -fi - -case "${1:-}" in -enc) - # shellcheck disable=SC1090 - . "${SCRIPT_DIR}/commands/enc.sh" - - if [ $# -lt 2 ]; then - enc_usage - echo "Error: secrets file required." - exit 1 - fi - enc "$2" - ;; -dec) - # shellcheck disable=SC1090 - . "${SCRIPT_DIR}/commands/dec.sh" - - if [ $# -lt 2 ]; then - dec_usage - echo "Error: secrets file required." - exit 1 - fi - dec "$2" - ;; -view) - # shellcheck disable=SC1090 - . "${SCRIPT_DIR}/commands/view.sh" - - if [ $# -lt 2 ]; then - view_usage - echo "Error: secrets file required." - exit 1 - fi - view "$2" - ;; -edit) - # shellcheck disable=SC1090 - . "${SCRIPT_DIR}/commands/edit.sh" - - if [ $# -lt 2 ]; then - edit_usage - echo "Error: secrets file required." - exit 1 - fi - edit "$2" - ;; -clean) - # shellcheck disable=SC1090 - . "${SCRIPT_DIR}/commands/clean.sh" - - if [ $# -lt 2 ]; then - clean_usage - echo "Error: Chart package required." +load_secret_driver "$SECRET_DRIVER" + +while true; do + case "${1:-}" in + enc) + # shellcheck disable=SC1090 + . "${SCRIPT_DIR}/commands/enc.sh" + + if [ $# -lt 2 ]; then + enc_usage + echo "Error: secrets file required." + exit 1 + fi + enc "$2" + break + ;; + dec) + # shellcheck disable=SC1090 + . "${SCRIPT_DIR}/commands/dec.sh" + + if [ $# -lt 2 ]; then + dec_usage + echo "Error: secrets file required." + exit 1 + fi + dec "$2" + break + ;; + view) + # shellcheck disable=SC1090 + . "${SCRIPT_DIR}/commands/view.sh" + + if [ $# -lt 2 ]; then + view_usage + echo "Error: secrets file required." + exit 1 + fi + view "$2" + break + ;; + edit) + # shellcheck disable=SC1090 + . "${SCRIPT_DIR}/commands/edit.sh" + + if [ $# -lt 2 ]; then + edit_usage + echo "Error: secrets file required." + exit 1 + fi + edit "$2" + break + ;; + clean) + # shellcheck disable=SC1090 + . "${SCRIPT_DIR}/commands/clean.sh" + + if [ $# -lt 2 ]; then + clean_usage + echo "Error: Chart package required." + exit 1 + fi + clean "$2" + break + ;; + --help | -h | help) + usage + break + ;; + --driver | -d) + load_secret_driver "$2" + shift + ;; + --quiet | -q) + # shellcheck disable=SC2034 + QUIET=true + ;; + "") + usage exit 1 - fi - clean "$2" - ;; ---help | -h | help) - usage - ;; -"") - usage - exit 1 - ;; -*) - # shellcheck disable=SC1090 - . "${SCRIPT_DIR}/commands/helm.sh" - helm_command "$@" - ;; -esac + ;; + *) + # shellcheck disable=SC1090 + . "${SCRIPT_DIR}/commands/helm.sh" + helm_command "$@" + break + ;; + esac + + shift +done exit 0 diff --git a/tests/assets/gpg/private.gpg b/tests/assets/gpg/private.gpg new file mode 100644 index 00000000..88188d68 --- /dev/null +++ b/tests/assets/gpg/private.gpg @@ -0,0 +1,58 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lQOYBF6zI0oBCACmpAJ9Ldmf/u8E4Gta5lLx88ss8OYI2KbezPnp4IU79ccLGAsZ +U+LFGyvHTP6p1KkZDYfMh29YEnJTg2CVGwVMQr1fDZCSGvHLvsv3Np0gvJzepjfP +P1THHY9z6HbkRSM2EpjqXxdkCyJaYHNcJeyC+hw0YjAF0ZGXGXQn9VjVuX9Tqjnj +fz39h7Qcou1CFaas2Wus3IdKY9MqCg6b2IJTQVZl1eBzhAWbvXYI7AsMjk3RbX6l +UfAwUWW528bOfctU1kqyvnFXfEiYdLrtElukR0EvJd5h1ajTcmddTs7XkxUQNC3S +Tw6IySgtVLvDoRps0FwQsJo3pJIB8gW2+dLDABEBAAEAB/41UvtW6lKe/7mlsli4 +LEbzlMN53JaH0yhG2InKXOXVo5bvhmCa2LySvVibfJhraRk5YpqHiPlI0hJShhJk +dFKULjEiFxmhn0yrmaD0OT47qQ97se3e/FGZK+zpNsTA1Bzp4zaanRZDlcqG6CFS +JfKSkQ1wd9ENM5wmoWcJmFm2fhKf9i2XHXI4S63ZQbNAvkPQqbnLSkcppviXhzAo +Ic1SmFKajR6K6z9TWaRXeIQ4/evavy9h3soMbFhVX2D/drajEwvq1gCxLtABa0cN +Mjsu3/BEYSPldgQ3ygYmFohnrP6I6mgem60CAuCjlMFjdyZ+EyXbxrDTGEyLQzEk +8S2dBADFvbSU+2SPBIaRJcnIwuV4A+42WUmyyio9hUyvGoBNtC6s3WQEXcrqwaWQ +8WO2HEYjNwzayBSTd7WAU9DVrXZMRInrrMsHKmUSlOMnW1jcEtriU+1KWFQNsRXo +HyS5gTIzwLkicvNjZ5qlVfq9028xiCvf+39pDaBKW25h+hbiPQQA17ycBPj2MtrH +8d/Ze/eS5/BweR46V4BpmqRuX3iIFQZTC7183PtKkS+RRGWkG0dN3OWlSOo7ZEly +Y5YUujlB94Ndo12lr6HHGZfWil2N6h8+RmbYpubhzrk7Nx278gUXzNJx0lKcPghy +DQNjxSkdrVUMotEQZYdjCp1OpmQn2P8D/ibXb/pruQlCoi5tSTjkbCZ2E57QwSr6 +2gqofL46PJvFPrd8ic9g3V0GD0RSzJU58IgoFzANNWNJdwUkLaFNr57OJhPvqfXd +3uMu3OOJG2AbIRl9vm1Dxk3zXbzQdPFuaWkIlBqbSr7X4h2uSdo8Y9NHZxcSOwcp +Xt8hYyNA8Qj4OeS0UWprcm9lcGtlL2hlbG0tc2VjcmV0cyBERU1PIChET05UIFVT +RSBUSElTIEtFWSBJTiBQUk9EVUNUSU9OKSA8Z2l0aHViQGprcm9lcGtlLmRlPokB +TgQTAQgAOBYhBNYXSgICcFDlnHEQdbQwxOWOK7ujBQJesyNKAhsDBQsJCAcCBhUK +CQgLAgQWAgMBAh4BAheAAAoJELQwxOWOK7ujtIQH/098e12HE5FB255AA2RHahYl +JvekXh5yf8r+Hlm+rWGO5dUtvl1AwQiDi5GyP7LRjGiLCdzRPjTURQ/6TFaBSAlt +/zQAoTMiYAXIVvBzWVRLe/DW3DGhbXftCeKtb6xTfclyYNXuzAIaQDXqUw3fhldD +7ihevcYa976fDaEiwfE22ohQHR01j1LpcGRMcFcQ6iVXS65hBTjdfkfl60pi0SdH +HurlwGYksLNT7lHx6ADe2n9SqhLawZR/Cv4qXfFb46GSiSB+qTOJZsw2igXhHwmT +s/ANZmxu8T23S8ax2fcShc/OUZCuT/RN1yH1Vp9LdSJnWFHwbkGhM3iAhoZ92FCd +A5gEXrMjSgEIANcU512CjCgKzrumW7sL3OkGZ7cep0q9PCNHnISA/fV1B2hRPdal +IXD7Pj9DgquQTdFO4ObTVHLgfCQ1Uf72UGCcaekDSFX07UbqsKwq48SoMiKKZ8hq +T4H49wmnNK+m4s179wGr5XvPqmkAGhJzHq7qSK6sPwQslsju64wkv0V5Van0LYLn +HXJpH7kTFhOVlLpPzNIoB6wKvpfRpmv5pLk2keiSrk6G2YwTZSTrbfuOfy3rY8eJ +rtc2S5Mlb9B4I3Vy28ACwAIsME02/hbrUNEHB1YrkH2heK8WJa+nvWZRj7HmLCN8 +rMM/2TPf7yrSRD8GBLWFQBdnqEOP1CjaRyUAEQEAAQAH/Ax0ph7Li/kDAeHqym5/ +S2B7VyT1s359OFmwBf0ZHfFJwQ9mKmH0gjFG0N4Ht4OJVy2t7GcHCgxKZSYQ/cSk +LcIf4h+fvwqrT9UcNksM2M/vZafhGA2KipGJAirJnMrSAVnLugxGENjQt++zannI +YkMtnN6babLWL41HY4C5iBIqehXX6t618xUN+/5a6cPniKWAIkBGdq+5dV585iQo +cjbKioo3sjatVxioXfXKxPQrCQUYm4ru3CmgmIdvxnPDD35n075o+mgUOascr7pu +7aoobh6mPpgd2dypgVHzLT02PL0xjTDsVa/IMYNlYLN6JiXOrlsDQhvr23McCYgA +AOkEANiyB1W3IDGUHAeFBoS7BE8EYwiGQm3dfcMpjvP/WfT5eUU0Md1tmXN4u00g +zuKqlymnIjrh+hhjQNWo9rSpHMF9xkX1NlwmAdP87YYBR6XgXcuVl/IsbkRQMtJ6 +H011q8exK2H3wQaoLnlYljDQVf+8ZftJHCby839IAQ6QtLjPBAD+F/EcmVAtF+wp +8U0Wh4+SQ/g0jYBQaD1n5VyCxwOIxMUUQ6D0mkS9rCKKcpeo7nzxPXgKTgnHy16V +hlWLp4CTd74RQcdX9lbCtFDVAHXW2FPGw5CclYVFjwA9hsz6O95ai51a46MZtZWU +2yNVs429hU/wTqsI62RrPpgJcqFVywQArYI4IF5NcK+oHEux5313AsW/qjVkmdvl +dE9pIoUHg63qwz0Sq1vyW0IRES5tfbxSfMT5hMvnDsp9TUcJ8tIgWFkRQN0Qg3t5 +pP2KAr32isGWdD06RU+c/f9RZJzCdWbfoT40JLad/f0tFjZugyhRt0J6sEIobDdA +3TS3MNF7GKw5bYkBNgQYAQgAIBYhBNYXSgICcFDlnHEQdbQwxOWOK7ujBQJesyNK +AhsMAAoJELQwxOWOK7ujWjQH/il8GmRUff+0KHZ73INNRSNeKUbuylwKb2zCXuui +UhHTURPYnO+UdLrn87Pbe2mAck531ShJdPPNRXSGow4foXfKzVbe3p4GBd1Sw+Jp +eAEdxNSEDQC2Jtkjf9JV8CpqM52xnkNR67hzVJbRvdE8VU+DjeQaB46JWLyuvE94 +qW5VH87Rils2O+BT377B4w0VSBmwYi7C3E1cCzWAidTyojEGqHtyAB1f2QrxiVwV +QpCRoisL/3cKuNlyik1DFm6eeKVz8P8YQBTSs+4GwCtQkRF2+xnurxfv35ASsFU/ +KHqJewI7r4OR8AE5kwoEMKNeI+uSDnRXfM/frH9X61EgXXc= +=YUJL +-----END PGP PRIVATE KEY BLOCK----- diff --git a/tests/assets/helm_vars/.sops.yaml b/tests/assets/helm_vars/.sops.yaml deleted file mode 100644 index 3487ec5d..00000000 --- a/tests/assets/helm_vars/.sops.yaml +++ /dev/null @@ -1,3 +0,0 @@ -creation_rules: - # encrypted using helm-secrets-example-projectx and helm-secrets-example-projecty - - pgp: "4434EA5D05F10F59D0DF7399AF1D073646ED4927,40B6FAEC80FD467E3FE9421019F6A67BB1B8DDBE" diff --git a/tests/assets/helm_vars/projectX/production/us-east-1/java-app/secrets.yaml b/tests/assets/helm_vars/projectX/production/us-east-1/java-app/secrets.yaml deleted file mode 100644 index e741ce30..00000000 --- a/tests/assets/helm_vars/projectX/production/us-east-1/java-app/secrets.yaml +++ /dev/null @@ -1,31 +0,0 @@ -secret_production_projectx: ENC[AES256_GCM,data:NUSh2U7MeE9Ilg6zuUk=,iv:CVAqiUQV460zJ2J2RCcbvwxWbkF0tomXz/GI24RuDXE=,tag:lpCPR5jXR9t6tNh5HzxQrA==,type:str] -sops: - kms: [] - gcp_kms: [] - azure_kv: [] - lastmodified: '2019-03-29T11:02:08Z' - mac: ENC[AES256_GCM,data:IygJhBcNtb+3hb0J/DlY01XWYZFfwGQxfXGCuYiqFiMreZ91RL8PATfuQsOuUqLQdubuFJnnCGxW1rNwpqIXaUPjTN1IjUs031ALs3VSu+GGmAm9VL37d4dBbP3m4YYzhgV5m/Mn5Z19H59KcxjaLuujIBaPDztgOn211Ijkui8=,iv:kQDdkQODDg58vYXG90XjuM1ATzYHBCC7Lem5/pllX5E=,tag:MbJuvLqLW57RO/2C5g4wVA==,type:str] - pgp: - - created_at: '2019-03-29T11:02:08Z' - enc: |- - -----BEGIN PGP MESSAGE----- - - wcFMAxYpv4YXKfBAARAAAA8gRfuMZviZ+4kpzEOafKYT7kQ6QSqd/TGdgiZHtJFl - p5X0L8NJgXcgr6TNuBQF8f2AUy2IA0lfPfgESMofRD510Js0c7+W8YCrdIIV2kt7 - wgqrzGFJAMmdbfOyFPCCYQJ/4HEolRvyxuDDfVPcNFxbiPqVeTnPCEZ0fMmsm26o - 0XWDdKJ7qz5fDA/pi/9zDOsH5nBgksXpdlLGCUjGb1256FadIeYyX1L7ZFDW7jm9 - IvwU9TQUlJFQ/VPsJPoahPujIVcgRyFSi14vUd9tYglr8cLnJJlFpD1rnb/plKea - O1mu7HYQFAdHmCHNtaooHD1tIsrZbCT8SG1qDOif3q8hCDFdLh9QknljTAu/pi3r - OMR3opOxw+0ZOFKwaum4iBEG2bDLvDAF574r0HwLWrRvYFvPQLM/ZE9tB6KPBaD4 - iCm94HgUAPJsVSuuGXRpkkzixGVf3Ozt3CE4Sv3FFwtTBoCFGJxzAQVoYvjaXDjA - jZwFTfJoCMmXoq3tHoTEdTJdtvaoGXk2N8n7BZhwhj8jnOftFjhGUaJZggvC2qGT - 00IqROarjKpoErVvcVxkgPpFa4HLyhNRBdaU3ECet4dNslM+P4j/i1ojNn1BYfG+ - U5tXFyzp/vQd4MVVhLC+vyGLgQovwm1LXzghsXFHJYICaPewU0ad+qNZGozZjHrS - 4AHknsSb6QLyJKL6Pn5g/nvrfeEBZeDU4KHh3tHgYuKCnFxp4KTlOoLn0zq7FF7V - icU1zn8CpnjF7Y7ofwDhVdgUjnzdQRvgKuSsDnaoZig1t/y9Si1YaEsx4jXbVnjh - fREA - =rpBY - -----END PGP MESSAGE----- - fp: 4434EA5D05F10F59D0DF7399AF1D073646ED4927 - unencrypted_suffix: _unencrypted - version: 3.2.0 diff --git a/tests/assets/helm_vars/projectX/production/us-east-1/java-app/value.yaml b/tests/assets/helm_vars/projectX/production/us-east-1/java-app/value.yaml deleted file mode 100644 index 4bd473e7..00000000 --- a/tests/assets/helm_vars/projectX/production/us-east-1/java-app/value.yaml +++ /dev/null @@ -1 +0,0 @@ -projectx_production_value: "bar" diff --git a/tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml b/tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml deleted file mode 100644 index c005719d..00000000 --- a/tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/secrets.yaml +++ /dev/null @@ -1,31 +0,0 @@ -secret_sandbox_projectx: ENC[AES256_GCM,data:KSZG/XTW6Wy6RPJ5zIQMTA==,iv:1CbKkKCtk9ze6wmwK6rvfiZcjM6KuCFGUnc6JjtbXR4=,tag:heTaPsUsr2BtkasZ1Zj+/g==,type:str] -sops: - kms: [] - gcp_kms: [] - azure_kv: [] - lastmodified: '2019-03-29T11:02:07Z' - mac: ENC[AES256_GCM,data:lGMVD/vMAQ1tC9nwhnskvDE+D9EDe6v/XfAu4MXZWLDaA4gpNgYCJTEvAihVoJIO4jxsbIlzvq35GDRu+mMQMRcxrBK584ZPLv8CXxFRCrfNHOpkKwY3GEQXsLBMq9zUtayYihijR72xyDKoOVpj+zEADwwRIK34/EWN7ht5d8Q=,iv:r2ObjVV9etc1qlv08C35b52kx42ZoVbJluVMA2h/iFk=,tag:WRN2uoL/J9frpaMNSVqUxg==,type:str] - pgp: - - created_at: '2019-03-29T11:02:07Z' - enc: |- - -----BEGIN PGP MESSAGE----- - - wcFMAxYpv4YXKfBAARAAUCaamEEJbGWhWCiIiOeWGaKJYzd/FkC5Qvvv3yFl4YKt - 6apRMA1/7u9nTEGzVnsH6CwgoU276Fj4oKjOiDuKdaTwEHC1gWZNT5EOll0Jh6ED - oQ2rAWexkk/A6hyGdn7tAh/7IAMQK5QIHI0Z+H88DPV8ZfbEC6NRlyepP/LUt92S - eVoH1aeUVyTEJVOwmvkKSkAEeQlP+iLJFOECyVO0T5NfnPj8E7OFvJ8Nv5kD1vec - wdYVfbRUIZwIySE6alduz2cjxuUBhpbLjMqIT25pL5uXoSzIrxKmvkVg1DInYYJ/ - 1radpOYIGJRJ1aMMfBYtNsL5rSRRjexiykgCm+ZG54SvUbnA8/KfsZLZiZqSxduD - k6YX8BAL6WzknJ0qjY3SxZ3tpu6FPBJH9U69z2sM0hFxXCBLOWfsQ3JXpQ+HKRUX - c4mlA3lBeOCLVefrJuhy1TjO9094yTEc/i+r9yG7xvLwzWlFSeFpf6ph0vvK+bYG - ITglOP9Ipy0T5cTzlKq3pCCLlBAUSRiVncHhspfnoFSSlTgN2kawbikpF1a7I/Qh - Mpe29nPBywq4LFzyOJrpOAD6n1HU+KQKp3qZCjhdxx8EawFlZqUF6j7qLkKTN1AQ - w43l9pfqS2FXVXuouLlqPcg/KjG+5lx+KFjb1l6cvpvtL0Jvr8YiJ64t75GLoPPS - 4AHkTeYCfXmj7nRhZWZCuGVaxOFlCeDv4CjhyKfgr+IOF56v4NzlwZRMyKuOnr6R - 0G8vX7H5t8XJPbUsgB99we6hRY911ZzgAORsusuyK6Aiv2+b58CnLXMp4huU1rTh - 9L4A - =eUDm - -----END PGP MESSAGE----- - fp: 4434EA5D05F10F59D0DF7399AF1D073646ED4927 - unencrypted_suffix: _unencrypted - version: 3.2.0 diff --git a/tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/value.yaml b/tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/value.yaml deleted file mode 100644 index cca7916c..00000000 --- a/tests/assets/helm_vars/projectX/sandbox/us-east-1/java-app/value.yaml +++ /dev/null @@ -1 +0,0 @@ -projectx_sandbox_value: "bar" diff --git a/tests/assets/helm_vars/projectY/.sops.yaml b/tests/assets/helm_vars/projectY/.sops.yaml deleted file mode 100644 index 31fe1ea5..00000000 --- a/tests/assets/helm_vars/projectY/.sops.yaml +++ /dev/null @@ -1,3 +0,0 @@ -creation_rules: - # encrypted using helm-secrets-example-projecty - - pgp: "40B6FAEC80FD467E3FE9421019F6A67BB1B8DDBE" diff --git a/tests/assets/helm_vars/projectY/production/us-east-1/java-app/secrets.yaml b/tests/assets/helm_vars/projectY/production/us-east-1/java-app/secrets.yaml deleted file mode 100644 index 7f0ce987..00000000 --- a/tests/assets/helm_vars/projectY/production/us-east-1/java-app/secrets.yaml +++ /dev/null @@ -1,31 +0,0 @@ -secret_production_projecty: ENC[AES256_GCM,data:0jcFuH/OjCjnXmaH6lM=,iv:i3KOj0uQPazU87Jb2T8RD7f3eUrKXOW9OsICuB4Rmco=,tag:VsrWeUmMiEgP/ZZvk7BrzQ==,type:str] -sops: - kms: [] - gcp_kms: [] - azure_kv: [] - lastmodified: '2019-03-29T11:02:10Z' - mac: ENC[AES256_GCM,data:l8MS+OjSUrbaoIdlp7HxzPE3ApNyjxlK7ojuHdyjvBXXYUDuZ5gpLMtaeXxgjKNQaGtIeVOevpiENzOANkL7Hn+MtUJmmeTu7bx1hPQyxebGyLH/Y4DVAM8rY4mGZngTg4LYZcHuL3j9HBIUkf3WLSTqjYFMcbuDKqCCOPuyQf0=,iv:lSAmW9OPRoJeaNAtXFB7u/SPPIPfNJrIgUCD6yoBuR8=,tag:s2KAjECP055ZgDYBoagz5w==,type:str] - pgp: - - created_at: '2019-03-29T11:02:10Z' - enc: |- - -----BEGIN PGP MESSAGE----- - - wcFMAxzSiC7ZHNQZARAATDA+rolBbJrsHLGqgjGDjFANuSiqQOcSYKRF5kFCi1Yj - dhHbH5psqVJmdsLQzQDrO5Lrx1Sq8vSzlj5rOA1wMnWbE8M+BzZt4vkvwMw3FOgO - IMco/FZUlSUUKe3V2pvMhax9BieJMgFVDYxEB4KI0EeZhqbC/wwGrK+7X0zni7bE - jdRhIZ1Xtci6gf24/i5ttA0jc8pRKcFouVJdAz5g79AbcK3Nxph+LlrKNliwRjYc - zFs6vnwOR+fOCpCdK9aJY1zG02I1OitRjXKfQUzbsjIG/o4P5gwxuyTm87mWl9Ov - rt1vxXWX8EVSBgYfTPC6Oq+gESl47wECGJflun+hlxD06k/16/Pvk6CtQBYF65ss - mZb+YAXtck6cxMPuBVaD3L6zs3tvWMl+fdaJb5CAXQLPsXAoOuN9yXCbd9+T1rLo - Y6Kn9ZoxTEJk+zN8VAhBuE0aZ/ktmaVXwU98NimuOXTbVt+9noXfgbzRMi+kPui6 - SXg0IgSwOCSR/oRMk5gqgr3v2LKwMDw/2gdxxTTjCv4x/Mjaz4zmVIqTHM+oR0F/ - eER4EgVFFN2N5QxcMU3NgGaPgq067F+xOlb1VlXnvxANMEoE9Vcp+nD2aVtsEX+t - 5egy4xdJzhSIovWjxq4Y9QF0qRp52NYuOkDeadY/XavEjyTBLmp2AF0tpjwcPqbS - 4AHkyZ1LXa8ja6zN9lCl8gAPWOHDS+Bl4PnhCOrgOuJQ8tNI4FblAT5gFlx5vTIb - +AGwfNODVhnB6QJywpHozYV5hxAWYCfgDuQLEaOpis7ypp483Gv9UqwO4tELnnnh - ZQMA - =Pb7g - -----END PGP MESSAGE----- - fp: 40B6FAEC80FD467E3FE9421019F6A67BB1B8DDBE - unencrypted_suffix: _unencrypted - version: 3.2.0 diff --git a/tests/assets/helm_vars/projectY/production/us-east-1/java-app/value.yaml b/tests/assets/helm_vars/projectY/production/us-east-1/java-app/value.yaml deleted file mode 100644 index d9148c78..00000000 --- a/tests/assets/helm_vars/projectY/production/us-east-1/java-app/value.yaml +++ /dev/null @@ -1 +0,0 @@ -projecty_production_value: "bar" diff --git a/tests/assets/helm_vars/projectY/sandbox/us-east-1/java-app/secrets.yaml b/tests/assets/helm_vars/projectY/sandbox/us-east-1/java-app/secrets.yaml deleted file mode 100644 index 9910f60f..00000000 --- a/tests/assets/helm_vars/projectY/sandbox/us-east-1/java-app/secrets.yaml +++ /dev/null @@ -1,31 +0,0 @@ -secret_sandbox_projecty: ENC[AES256_GCM,data:AC3dznJbIJBZ7/r6kw2U,iv:uVeNY1dzRAvjyKqahhy2OrqI8sxWeLTqhOMdtVN3X30=,tag:qAImwVgVBnr4lwnS1Yu3iQ==,type:str] -sops: - kms: [] - gcp_kms: [] - azure_kv: [] - lastmodified: '2019-03-29T11:02:09Z' - mac: ENC[AES256_GCM,data:aZIT/mClu2sx36vpRxzRRtlS3WM+2Qkb1mlhjhHjdrU1NqITFTPyBSemvilpxiF1bUdT5M8Y32dtRFoylsAnZ+w60DvaRynAOm2jL0PSzFq0iLo5W8oUWSPFmJv+/Ixc7SLtKpfjJO9qEt8ad0SipEHEFHc6gKpxMgMIDrbIeWc=,iv:0k7k++pPOFqDXNvOUYbt39MgkW0s2j5a7SnYcaK6WnA=,tag:hx7MixPps3ps7dThnJgcIw==,type:str] - pgp: - - created_at: '2019-03-29T11:02:09Z' - enc: |- - -----BEGIN PGP MESSAGE----- - - wcFMAxzSiC7ZHNQZARAACg4g710ru5aOFnrsOTnoUqvrdbGVTcfOqn7Pk25RmGyH - r6hS/zwdB9rbxGhWSiUFHXIpKFecJ6ste9/MuwdYtyvWC1On7ZtaOb0iGo4Oa8zu - EZBtB+yeQYvxfNMef6ibnf4H2IALVccyTJq406QDUSRIoAsrKLI5vKqzyEsrAKbS - q8TweMV7L0JySCZa9B+zyof1Y8kMjizu3ldQZiwDc63LhpUuxMkoki+2YIcB0Svx - Mm+/emXeLBfyBYjyOMUTStVh+J82Nm6nlCD1TgUgfJUwWKGKNzmRPQaUZCY2HSNf - PoW4cpw0xtfNCzQL84xL7Cgz9b+jqeMQcSeTvGS/viZaFgln84ISVQ8nz/64IxS7 - iRu6uYM92PpIqCZcuLgT3O2yL1e91+amr1UMViGLG4dOFspu8dBpUQYGgqr6wrtq - acBfiv8iihXZNLfAooCd1XGFE0b5XZ7C4e10PoAYjNg+cLtbRyh1rHhWPBX55BY8 - bFLKAJIV49hIZf7KUuaQcXi4+oBM/Gyc0ZzT147iZZdWnJ7NGz7Yn/WB7ITqWrUy - OLhRTqEn4hvKnpIlNBzlv0Z3TWhiJhw6tRZYGts3/FLEnFq646oAjbxNxcKlf3xK - ASkuJ1uNuFFZLbuTzLSrCOq/H28rBkUFP2xDQQ1eSYdAnkE0MXF+Twda8dSPdQ7S - 4AHkT7zdy5tUboxpmy9Kbs7E1+GzC+DG4MDhzmPgmOLdijXG4JzlxpCjUfI0icOx - BAL7hSieSssfq9NAW9waO0h4RZhznmHgjuQ4n27UVdWR6+iqD/TCQHq14nRsowLh - tOYA - =0z0k - -----END PGP MESSAGE----- - fp: 40B6FAEC80FD467E3FE9421019F6A67BB1B8DDBE - unencrypted_suffix: _unencrypted - version: 3.2.0 diff --git a/tests/assets/helm_vars/projectY/sandbox/us-east-1/java-app/value.yaml b/tests/assets/helm_vars/projectY/sandbox/us-east-1/java-app/value.yaml deleted file mode 100644 index 2407f383..00000000 --- a/tests/assets/helm_vars/projectY/sandbox/us-east-1/java-app/value.yaml +++ /dev/null @@ -1 +0,0 @@ -projecty_sandbox_value: "bar" diff --git a/tests/assets/helm_vars/secrets.yaml b/tests/assets/helm_vars/secrets.yaml deleted file mode 100644 index bd7edb48..00000000 --- a/tests/assets/helm_vars/secrets.yaml +++ /dev/null @@ -1,52 +0,0 @@ -global_secret: ENC[AES256_GCM,data:hTCjP27OpbbHGQ==,iv:JkpWKJeOXM5dtvbxip4t9XkgeusQ0MhDeCs0bLF/SlM=,tag:Rgkndqlk3+LGmHZp/uwzKQ==,type:str] -sops: - kms: [] - gcp_kms: [] - azure_kv: [] - lastmodified: '2020-04-26T14:42:58Z' - mac: ENC[AES256_GCM,data:as/vgaW5iuLeEC343Be+biGG+5TvEkzs1uhNAtQQQBl4EfuUAKQHz9gdDOYwef/ZZQMnyR5ovkMMgpSfuszBktwewkj1/lwkAR2zGz4J/hAqqE1yfcwvftxn2aqwAmxVlrcpaPCp9Kf0CvvqatJHo/r6gokFUeR35RRQ54/X+/Q=,iv:EPbAr40g7lZE3nTU+naZlJqiX1q+4/Rppbz5t2GTwlw=,tag:QA4X0DDxzrLd2DdnzhNJnA==,type:str] - pgp: - - created_at: '2020-04-26T14:42:57Z' - enc: |- - -----BEGIN PGP MESSAGE----- - - wcFMAxYpv4YXKfBAARAAagUx/8sKUMrmAKq+6pTQ03rB8j+hnyA58xQ2V9SMQTJr - ZQGPed2ZQJAeCERPpDehGO1EyXzCuOK2yg0MJjFDNX0UJqo3nfruURnimAd0ll4H - j/OMnFTYad9BvD9amiXzfpH9GpDOHPw2VspkWPW8/TpvhkEwY3GGsTgAL1Zw0Osh - Im4gcniEojePOjWp04awQVMohA20KjM4CzvVDCvYFTXg+8/u111slFjhLmSM0jHw - N1huOHbZFqy6RlkvXNT1pJaXShSObL27Ej0nW8FQnKYOrYKTrjwZD4zv/uBbUICZ - usbywArwaNIFQMI3IcPKLy79QyeZpwzqly9IF4jdxysIGHMsPZ155+XSu/SNZ0q8 - wAu+tAxX9HYXfBJquxh2sLJLDqUrGH4v63R9NiihBjR9IY64IDKTrAlxKJrcO3R2 - nbJIMxUWygkyR6Hw6jQejWmMtvYyo02i6zp7p/tRrLtngfDjbJTeqTLHSwvRjrU6 - VVlPtMw7rEBnPrPNBwD0wV1BtWz6OFpU9DF/SsEjKi8/keI8jMng4Qh04Z0/ku0a - 5XQ8R7T3ifdlk9BtPm6/5C7lvWFn/u/wY502wb0mNmfKbjKE0G3zfoQ3udAlM6/e - v2ScQfPfo//PtFIXW5mFSbrs1XxhBvgwg2rz0PgMEt2cDj/sYX8OlypltS9gKhrS - 4AHk8UeQUtRF0KziHREime0y6+EDzOAl4GjhwUPgieKwoq9o4KvlxE2dGDPs6lSi - g6qFdfJ1exeGIhWnz1K19t7ddxIG63PgpOSQ6SUPY77Y4vYuY5lfHEoi4mSaxC/h - c5sA - =KRgJ - -----END PGP MESSAGE----- - fp: 4434EA5D05F10F59D0DF7399AF1D073646ED4927 - - created_at: '2020-04-26T14:42:57Z' - enc: |- - -----BEGIN PGP MESSAGE----- - - wcFMAxzSiC7ZHNQZARAACgu2YBtg0kJ2zjwj791CcdqfpjGeK/l5xWPMy7pj9qX+ - ULfAgO2fTA+iA1wgV4Hguzaw+cH1dmLV7vbynT7CD9N9HSaFsSTMrz94vBhWmOfv - QIXkaQrwkHyqmYP5V//rk+Uhgpy2CY4CRuqxxFTv8U8P/SlTXJ9golh2a13aArq9 - old/CNSbbDkhDyuiE7Gs5bCUO+5YFa5/gAWUjhT/3Q3z7nA42zuF2J9R5aJ2QqpZ - Ca8YWZG29THUFow0nIEWdr0xs5Xadz0yAMIikAS1hZPKI2Iw93CZscv5Ka/VM+tY - ZrMF8kBdhI+799xFtmmIga8EfuxPSAWzVrkKMtoLE7aduj8vt6d1+ZMR317bfmqB - rcoPaaSVVMZe/liu8rFfKHr4nL2fx4If3S/RULSEgqeckSXuM5LotHI8ze5ic/JL - sxX51nSxaT/F8Zqai921J8hORdx43l2/1KGeoHp2+7l4UwCzWU2rq72s875Z46EA - FONOoIJenTi1i4BIlqqeAXqX542JQuByK7uP5MaO75Vl/fKuJJ4Yn0IG1aCf7jPd - UhUbHBTY4ReTyEQCTjrmHIcu7bqJH3IY8fzVh2O1+7p6+bUUFHbiyyl6oT4wbpUz - EqI/9wctK8RwiWJXMk57QnQQkJzdJ5Pupvke9a2qcZ+xix4ztRABMQVv7qECjCnS - 4AHkSR8FiCP16hKjQJ25BfSM1eFuzOBm4DnhE2rgLeJRw+4F4PjlxN1A+EEm0xdW - 8fWhs7yLwz6nGZeazII5M6QfGCx/Z0HgmOSc2iUywMxBR8ksZuhz2AaU4r3GykTh - 5NsA - =sYJf - -----END PGP MESSAGE----- - fp: 40B6FAEC80FD467E3FE9421019F6A67BB1B8DDBE - unencrypted_suffix: _unencrypted - version: 3.5.0 diff --git a/tests/assets/helm_vars/values.yaml b/tests/assets/helm_vars/values.yaml deleted file mode 100644 index 4ffdd4f1..00000000 --- a/tests/assets/helm_vars/values.yaml +++ /dev/null @@ -1 +0,0 @@ -global_value: "global_foo" diff --git a/tests/assets/pgp/projectx.asc b/tests/assets/pgp/projectx.asc deleted file mode 100644 index c6b71353..00000000 --- a/tests/assets/pgp/projectx.asc +++ /dev/null @@ -1,105 +0,0 @@ ------BEGIN PGP PRIVATE KEY BLOCK----- - -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 -oCMZ5lJbirIQtJXJj2HMxfR+MgIe -=Xduf ------END PGP PRIVATE KEY BLOCK----- diff --git a/tests/assets/pgp/projecty.asc b/tests/assets/pgp/projecty.asc deleted file mode 100644 index 54793f0a..00000000 --- a/tests/assets/pgp/projecty.asc +++ /dev/null @@ -1,105 +0,0 @@ ------BEGIN PGP PRIVATE KEY BLOCK----- - -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 -IuLUZrOLWiOU+zKolW66ZeRj6j/B -=2Mcm ------END PGP PRIVATE KEY BLOCK----- diff --git a/tests/assets/values/noop/secrets.yaml b/tests/assets/values/noop/secrets.yaml new file mode 100644 index 00000000..8cfa01f2 --- /dev/null +++ b/tests/assets/values/noop/secrets.yaml @@ -0,0 +1,22 @@ +global_secret: global_bar +key: |- + -----BEGIN PGP MESSAGE----- + + wcFMAxYpv4YXKfBAARAAVzE7/FMD7+UWwMls23zKKLoTs+5w9GMvugn0wi5KOJ8P + PSrRY4r27VhwQH38gWDrzo3RCmO9414xZ0JW0HaN2Pgd3ml6mYCY/5RE7apgGZQI + 3Im0fv8bhIwaP2UWPp74EXLzA3mh1dUtwxmuWOeoSq+Vm5NtbjkfUt/4MIcF5IAY + c+U4ZOdQlzgExwu+VtOpeBrkwfglh5fFuKqM8Fg1IICi/Pp6YAlpAdGqlt1zS4Pj + yjAS6eAvnpM0eA5hShuoO9JsAu4kVjaaBlipVpc1I2zdcT3H/1d7ASziwbKOm6jE + PJxzaMDxn0UfMjkhTaTZ8v27lz6W7qdlHdCWGGI348QkSoDotm7OzMC7ZLfps3+9 + GrXo9Kwxkj6oy/thn92W2cRSeSD28g6kcUkHeG8L3mMv+gpTjIhM+Z8x3jJcVp2i + yoA2dO/kO2/HTcUfnEjppKigqUlRuKfDn8ercjYiq+foqtimH192iXXyRmltYlH0 + GUSJ1FcNLAC9g0WLFPQnMFh5KxSweavpbdd6PILqEsyKvZpC5a+hzLKwGjWOveW1 + K34QZf6Ay3CPCegAyGVjxmsg1vPKD+9WAZinveCl37l3cCQW1VZzbGkHgtLQ30Qr + DCRFZEstraLAQUf6VLAk9bPYX/fvkXmra970i/CfJjIg0SpOXbADBR4x+zRRZqrS + 4AHkWTmhH/xXWyAgmh+sGs18OOFGfeC04AjhMmvg4uKzly6+4IDlNhPif2VpJYOi + EmU8gQoUsAHKYro0hPfzBZyJlL+TqCPgHeRPANVgm4Ww6RlVrNFpTy9H4m4s5y/h + EzAA + =jf7D + -----END PGP MESSAGE----- +service: + port: 81 diff --git a/tests/assets/values/sops/.sops.yaml b/tests/assets/values/sops/.sops.yaml new file mode 100644 index 00000000..ca2b0e7e --- /dev/null +++ b/tests/assets/values/sops/.sops.yaml @@ -0,0 +1,3 @@ +creation_rules: + # encrypted using helm-secrets-example-projectx + - pgp: "D6174A02027050E59C711075B430C4E58E2BBBA3" diff --git a/tests/assets/values/sops/secrets.dec.yaml b/tests/assets/values/sops/secrets.dec.yaml new file mode 100644 index 00000000..7f00aef6 --- /dev/null +++ b/tests/assets/values/sops/secrets.dec.yaml @@ -0,0 +1,23 @@ +global_secret: global_bar +key: |- + -----BEGIN PGP MESSAGE----- + + wcFMAxYpv4YXKfBAARAAVzE7/FMD7+UWwMls23zKKLoTs+5w9GMvugn0wi5KOJ8P + PSrRY4r27VhwQH38gWDrzo3RCmO9414xZ0JW0HaN2Pgd3ml6mYCY/5RE7apgGZQI + 3Im0fv8bhIwaP2UWPp74EXLzA3mh1dUtwxmuWOeoSq+Vm5NtbjkfUt/4MIcF5IAY + c+U4ZOdQlzgExwu+VtOpeBrkwfglh5fFuKqM8Fg1IICi/Pp6YAlpAdGqlt1zS4Pj + yjAS6eAvnpM0eA5hShuoO9JsAu4kVjaaBlipVpc1I2zdcT3H/1d7ASziwbKOm6jE + PJxzaMDxn0UfMjkhTaTZ8v27lz6W7qdlHdCWGGI348QkSoDotm7OzMC7ZLfps3+9 + GrXo9Kwxkj6oy/thn92W2cRSeSD28g6kcUkHeG8L3mMv+gpTjIhM+Z8x3jJcVp2i + yoA2dO/kO2/HTcUfnEjppKigqUlRuKfDn8ercjYiq+foqtimH192iXXyRmltYlH0 + GUSJ1FcNLAC9g0WLFPQnMFh5KxSweavpbdd6PILqEsyKvZpC5a+hzLKwGjWOveW1 + K34QZf6Ay3CPCegAyGVjxmsg1vPKD+9WAZinveCl37l3cCQW1VZzbGkHgtLQ30Qr + DCRFZEstraLAQUf6VLAk9bPYX/fvkXmra970i/CfJjIg0SpOXbADBR4x+zRRZqrS + 4AHkWTmhH/xXWyAgmh+sGs18OOFGfeC04AjhMmvg4uKzly6+4IDlNhPif2VpJYOi + EmU8gQoUsAHKYro0hPfzBZyJlL+TqCPgHeRPANVgm4Ww6RlVrNFpTy9H4m4s5y/h + EzAA + =jf7D + -----END PGP MESSAGE----- +service: + port: 81 + diff --git a/tests/assets/values/sops/secrets.yaml b/tests/assets/values/sops/secrets.yaml new file mode 100644 index 00000000..c6923e24 --- /dev/null +++ b/tests/assets/values/sops/secrets.yaml @@ -0,0 +1,28 @@ +global_secret: ENC[AES256_GCM,data:QSuqKj9jUft+Ug==,iv:CXfhR2O5l6IF8KI5SSDxMiWQ7kghfHHb1wASAJ7JMPw=,tag:g/n7/KeltD1ODvolNCLD1w==,type:str] +key: ENC[AES256_GCM,data:9nAQWTLrA71vJ82ebiEWOP/bt3B3AjCllGRiAU1szxcN95papkFeNRl3mBJT0fqhbsMD/B3hmO+kRbxxzoDAezXI0gDIrlo9fyxoSwzsRxYBzHqg4USFs6iI+THFQLkxDaCu45Ku2cxksdBTBFpswkyk0ZBFhASLfT59GhWji4+n19MXPwb0tyGiCyIpgteXBA7FdMCiLc4ZRTZechZVpvfu1EJf5UgDT39dBAn9+Rwn0oQpDKTHij908VLsH18XcCgISYnixyoShqQxtmFbLipi1Blzs5zqgYFE7BbZ6ZgdCm69/WSXBiLabG+KYMPeEYXI6IRMbf+5qteWqEriRLmjKKbRFRjIdPI3+6ysySje0xYSUHOD3YjpzzeiQPT0OqzPJ/H7LZAO+/MUhel7h83HxzWYR33ieJLE/MghpQYN4zPgqzK4XQpb5ERHtpGrXSbzcSIcICTDrlNf9T7r3SzmHXulUMAIx/AH0s3Kyuv0BzUKWYNNgwj9j99FxofQsdJHx16qph0vu7y1iKu9/Jy89rPWn/LOh8llCGztQj+TXygnUyUfMHXMBAe0X+abCu7WcWuij9ow+adA9HxCA8ezue1pPPDoPTk0OnM7FUxVdgLgEBZu0gEl3jkhVEhouLIka08fE6eJL/iNmepqFb+x815pPVVsJkDDeKxjxt+YwAYgm3BX+ZZdLZVtg93AIEPUeBgZRGw4bYQWvsKwmC8zZhLvMsyX4NwKTj+gViXsCrSv92i1epZZwrzj+xszExz3k3633VdwMOqNtK0/c9GhzSNSktkw9yKMSGTEp4O8TYepovjM/Vei0M9FQ0+rQfLEaRyPMeCIhysh2ggXxIWr5kQdEH3KCIm1aJDRA9QVOvUeXcenfN7x9pG9mqMNkumVu4ops4rDCOy/NlSvJW+n7vk+wHqSIKtwWZxNX+HRQgSmHZmvQS8IEyK5vQOxD8rQD2Er+w6Io6PvLm2F1Op1mV7ea+Lvg2pStFkQVCgRP/TbejN7gNBEsNTkel1D1uEgT2wvN+j2iFvNyEhUFUylaeUBYmDHJ9ZjQqJ2/3QZzR2yN2i+HN9sVZGdHm6bBH08GtDmjliqh8CKRjh0OMJfCZ1ZcoSBz1/m0E5zAZl3ZMuTDZaW70QsO4FoxA0oUqD14c4nxhqL3B9SxA6ErrYWY1+j3vo/ws6sBzWWzLXC59SwlwMg3PytxNWLpw==,iv:w0KBImdBsS63co+HyQVOYOxOFI/tLeRYnr+L+lCcNo8=,tag:ReQ99Km7LDQwEnlN/ppmxg==,type:str] +service: + port: ENC[AES256_GCM,data:o3U=,iv:9NmG3nt9dutvAlXUk4cPFIiq69F+5Npf5vFDMLKipuE=,tag:Y/wUBGdB05WfC4FTokGvzw==,type:int] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + lastmodified: '2020-05-06T20:54:31Z' + mac: ENC[AES256_GCM,data:pgCBRi189SbfeNz1DnI7kAaEC/GwfjjfW+bWTU2OHrBRGmkioC4aaRMdGJJ1i98DFyxAhfSha5wzNsipN8tg4ZYstp8OrIjXbi3KWAzRzWqwECK8W3SgRhReZ48hHd+vVvxK7xFoV2cCtPIvJnXESZ+3PetMULxgjzAnJhIiNGE=,iv:meLE4+eocQV3GhZwLhdTsJbOWmIlZD/VLHGkXUMfUIo=,tag:1qfijLq9RVu7qPi0WdPjfQ==,type:str] + pgp: + - created_at: '2020-05-06T20:54:30Z' + enc: | + -----BEGIN PGP MESSAGE----- + + hQEMA9ce5qCwOO4MAQgAhLFu+zlo/fPrfAVGeQVEIEttihpMzo7CSRJDGYqSqgOO + g/NbA/hDVWkE9jzGnxDY01W9RR4FOss+yd1SHlNzsPDDfkXi8e2PA8tNR6XKyoSq + aCMYE4TP8JnH2hplxWucib5va2EUkgwAF+86I/ISlMLIXqeVE6xKJAuGcPQ8UwDG + YUO5KzcLF8oTyoRGxvakIiCAfCWrzz7wBkT8KG5t8pQvucTtvzOpiexRL/9OU+SA + Spgp8WPds+A9WArkLVQ7lcZhI0XiMxITmZdBgXGIG+1pMoGjajXUk2SA5FXeHkgH + kgfAhsDlEI3mfSwYMwuFP5/659Wl3gWkMIlTpfBY2NJeAUeCmOKYRwTHR8UFa2Gg + wF7wB+aj71S6v4kO932ZFHNNL0JS8OGqg/IigOhgjIC/7ozHehhKNIxCUre2g1Ws + dj7U81vziuDuH/sOrgwYdqfQHa6ytoomZbiYLQl4wg== + =5Jl6 + -----END PGP MESSAGE----- + fp: D6174A02027050E59C711075B430C4E58E2BBBA3 + unencrypted_suffix: _unencrypted + version: 3.5.0 diff --git a/tests/assets/values/vault/secrets.yaml b/tests/assets/values/vault/secrets.yaml new file mode 100644 index 00000000..8ccf04b1 --- /dev/null +++ b/tests/assets/values/vault/secrets.yaml @@ -0,0 +1,4 @@ +global_secret: !vault secret/production#global_secret +key: !vault secret/gpg#key +service: + port: !vault secret/production#port diff --git a/tests/assets/values/vault/seed.sh b/tests/assets/values/vault/seed.sh new file mode 100755 index 00000000..b7d260c5 --- /dev/null +++ b/tests/assets/values/vault/seed.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env sh + +vault kv put secret/production global_secret=global_bar port=81 + +vault kv put secret/gpg key="-----BEGIN PGP MESSAGE----- + +wcFMAxYpv4YXKfBAARAAVzE7/FMD7+UWwMls23zKKLoTs+5w9GMvugn0wi5KOJ8P +PSrRY4r27VhwQH38gWDrzo3RCmO9414xZ0JW0HaN2Pgd3ml6mYCY/5RE7apgGZQI +3Im0fv8bhIwaP2UWPp74EXLzA3mh1dUtwxmuWOeoSq+Vm5NtbjkfUt/4MIcF5IAY +c+U4ZOdQlzgExwu+VtOpeBrkwfglh5fFuKqM8Fg1IICi/Pp6YAlpAdGqlt1zS4Pj +yjAS6eAvnpM0eA5hShuoO9JsAu4kVjaaBlipVpc1I2zdcT3H/1d7ASziwbKOm6jE +PJxzaMDxn0UfMjkhTaTZ8v27lz6W7qdlHdCWGGI348QkSoDotm7OzMC7ZLfps3+9 +GrXo9Kwxkj6oy/thn92W2cRSeSD28g6kcUkHeG8L3mMv+gpTjIhM+Z8x3jJcVp2i +yoA2dO/kO2/HTcUfnEjppKigqUlRuKfDn8ercjYiq+foqtimH192iXXyRmltYlH0 +GUSJ1FcNLAC9g0WLFPQnMFh5KxSweavpbdd6PILqEsyKvZpC5a+hzLKwGjWOveW1 +K34QZf6Ay3CPCegAyGVjxmsg1vPKD+9WAZinveCl37l3cCQW1VZzbGkHgtLQ30Qr +DCRFZEstraLAQUf6VLAk9bPYX/fvkXmra970i/CfJjIg0SpOXbADBR4x+zRRZqrS +4AHkWTmhH/xXWyAgmh+sGs18OOFGfeC04AjhMmvg4uKzly6+4IDlNhPif2VpJYOi +EmU8gQoUsAHKYro0hPfzBZyJlL+TqCPgHeRPANVgm4Ww6RlVrNFpTy9H4m4s5y/h +EzAA +=jf7D +-----END PGP MESSAGE-----" diff --git a/tests/helper.bash b/tests/helper.bash deleted file mode 100644 index 2059e34c..00000000 --- a/tests/helper.bash +++ /dev/null @@ -1,64 +0,0 @@ -GIT_ROOT="$(git rev-parse --show-toplevel)" -export GIT_ROOT - -TEST_DIR="${GIT_ROOT}/tests" -export TEST_DIR - -TEST_HOME="${TEST_DIR}/.home" -export TEST_HOME - -setup() { - TEST_TEMP_DIR="$(temp_make --prefix 'helm-secrets-')" -} - -teardown() { - temp_del "$TEST_TEMP_DIR" -} - -helm() { - env HOME="${TEST_HOME}" helm "$@" -} - -gpg() { - env HOME="${TEST_HOME}" gpg "$@" -} - -create_chart() { - run helm create "${TEST_DIR}/.tmp/$1" - assert_success - assert_output --partial "Creating ${TEST_DIR}/.tmp/$1" - - if [ -f "${TEST_DIR}/.tmp/$1/secrets.yaml" ]; then - cp "${TEST_DIR}/assets/helm_vars/.sops.yaml" "${TEST_DIR}/.tmp/$1/" >&2 - - run helm secrets enc "${TEST_DIR}/.tmp/$1/secrets.yaml" - assert_success - fi -} - -tests_setup() { - # Reset test environment - run git checkout HEAD -- "${TEST_DIR}/assets/helm_vars/" - assert_success - - run rm -rf "${TEST_HOME}" "${TEST_DIR}/.tmp/" - assert_success - - run mkdir -p "${TEST_HOME}" "${TEST_DIR}/.tmp/" - assert_success - - run find "${TEST_DIR}/assets" \( -name '*.yaml.*' -o -name 'secrets.tmp.yaml' \) -delete - assert_success - - run gpg --batch --import "${TEST_DIR}/assets/pgp/projectx.asc" - assert_success - - run gpg --batch --import "${TEST_DIR}/assets/pgp/projecty.asc" - assert_success -} - -tests_cleanup() { - # Reset test environment - run git checkout HEAD -- tests/assets/helm_vars/ - assert_success -} diff --git a/tests/it/00-setup.bats b/tests/it/00-setup.bats deleted file mode 100755 index 51b5d480..00000000 --- a/tests/it/00-setup.bats +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "Prepare test environment" { - tests_setup - - run mkdir -p "${TEST_HOME}/.kube" - assert_success - - run cp "${HOME}/.kube/config" "${TEST_HOME}/.kube/config" - assert_success -} diff --git a/tests/it/11-install.bats b/tests/it/11-install.bats deleted file mode 100755 index a24013b5..00000000 --- a/tests/it/11-install.bats +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "install: helm install" { - run helm secrets install - assert_success - assert_output --partial 'helm secrets install' -} - -@test "install: helm install --help" { - run helm secrets install --help - assert_success - assert_output --partial 'helm secrets install' -} - -@test "install: helm install w/ chart" { - CHART="install" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - create_chart "${CHART}" - - run helm secrets install "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial 'STATUS: deployed' - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=install,app.kubernetes.io/instance=${RELEASE}" - assert_success - - run helm del "${RELEASE}" - assert_success -} - -@test "install: helm install w/ chart + secret file" { - CHART="install" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets install "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "STATUS: deployed" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=install,app.kubernetes.io/instance=${RELEASE}" - assert_success - assert_output --partial "secret: value" - - run helm del "${RELEASE}" - assert_success -} - -@test "install: helm install w/ chart + secret file + helm flag" { - CHART="install" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets install "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" --set image.pullPolicy=Always 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "STATUS: deployed" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=install,app.kubernetes.io/instance=${RELEASE}" - assert_success - assert_output --partial "secret: value" - - run helm del "${RELEASE}" - assert_success -} - -@test "install: helm install w/ chart + pre decrypted secret file" { - CHART="install" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - printf 'podAnnotations:\n secret: othervalue' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - - create_chart "${CHART}" - - run helm secrets install "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt skipped: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "STATUS: deployed" - assert [ -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run rm "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_success - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=install,app.kubernetes.io/instance=${RELEASE}" - assert_success - assert_output --partial "secret: othervalue" - - run helm del "${RELEASE}" - assert_success -} - -@test "install: helm install w/ chart + secret file + q flag" { - CHART="install" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets -q install "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "STATUS: deployed" - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=install,app.kubernetes.io/instance=${RELEASE}" - assert_success - assert_output --partial "secret: value" - - run helm del "${RELEASE}" - assert_success -} - -@test "install: helm install w/ chart + secret file + quiet flag" { - CHART="install" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets --quiet install "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "STATUS: deployed" - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=install,app.kubernetes.io/instance=${RELEASE}" - assert_success - assert_output --partial "secret: value" - - run helm del "${RELEASE}" - assert_success -} - -@test "install: helm install w/ chart + secret file + special path" { - # shellcheck disable=SC2016 - CHART=$(printf '%s' 'a@b§c!d\$e\f(g)h=i^j😀')/install - RELEASE="${CHART#*/}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets install "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "STATUS: deployed" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=install,app.kubernetes.io/instance=${RELEASE}" - assert_success - assert_output --partial "secret: value" - - run helm del "${RELEASE}" - assert_success -} - -@test "install: helm install w/ chart + invalid yaml" { - CHART="install" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'replicaCount: |\n a:' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets install "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_failure - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "Error: YAML parse error on" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] -} diff --git a/tests/it/12-upgrade.bats b/tests/it/12-upgrade.bats deleted file mode 100755 index 4438e92d..00000000 --- a/tests/it/12-upgrade.bats +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "upgrade: helm upgrade" { - run helm secrets upgrade - assert_success - assert_output --partial 'helm secrets upgrade' -} - -@test "upgrade: helm upgrade --help" { - run helm secrets upgrade --help - assert_success - assert_output --partial 'helm secrets upgrade' -} - -@test "upgrade: helm upgrade w/ chart" { - CHART="upgrade" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - create_chart "${CHART}" - - run helm secrets upgrade -i "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial 'STATUS: deployed' - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=upgrade,app.kubernetes.io/instance=${RELEASE}" - assert_success - - run helm del "${RELEASE}" - assert_success -} - -@test "upgrade: helm upgrade w/ chart + secret file" { - CHART="upgrade" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets upgrade -i "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "STATUS: deployed" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=upgrade,app.kubernetes.io/instance=${RELEASE}" - assert_success - assert_output --partial "secret: value" - - run helm del "${RELEASE}" - assert_success -} - -@test "upgrade: helm upgrade w/ chart + secret file + helm flag" { - CHART="upgrade" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets upgrade -i "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" --set image.pullPolicy=Always 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "STATUS: deployed" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=upgrade,app.kubernetes.io/instance=${RELEASE}" - assert_success - assert_output --partial "secret: value" - - run helm del "${RELEASE}" - assert_success -} - -@test "upgrade: helm upgrade w/ chart + pre decrypted secret file" { - CHART="upgrade" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - printf 'podAnnotations:\n secret: othervalue' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - - create_chart "${CHART}" - - run helm secrets upgrade -i "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt skipped: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "STATUS: deployed" - assert [ -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run rm "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_success - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=upgrade,app.kubernetes.io/instance=${RELEASE}" - assert_success - assert_output --partial "secret: othervalue" - - run helm del "${RELEASE}" - assert_success -} - -@test "upgrade: helm upgrade w/ chart + secret file + q flag" { - CHART="upgrade" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets -q upgrade -i "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "STATUS: deployed" - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=upgrade,app.kubernetes.io/instance=${RELEASE}" - assert_success - assert_output --partial "secret: value" - - run helm del "${RELEASE}" - assert_success -} - -@test "upgrade: helm upgrade w/ chart + secret file + quiet flag" { - CHART="upgrade" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets --quiet upgrade -i "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "STATUS: deployed" - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=upgrade,app.kubernetes.io/instance=${RELEASE}" - assert_success - assert_output --partial "secret: value" - - run helm del "${RELEASE}" - assert_success -} - -@test "upgrade: helm upgrade w/ chart + secret file + special path" { - # shellcheck disable=SC2016 - CHART=$(printf '%s' 'a@b§c!d\$e\f(g)h=i^j😀')/upgrade - RELEASE="${CHART#*/}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets upgrade -i "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "STATUS: deployed" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run kubectl get deploy -o yaml -l "app.kubernetes.io/name=upgrade,app.kubernetes.io/instance=${RELEASE}" - assert_success - assert_output --partial "secret: value" - - run helm del "${RELEASE}" - assert_success -} - -@test "upgrade: helm upgrade w/ chart + invalid yaml" { - CHART="upgrade" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'replicaCount: |\n a:' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets upgrade -i "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" --no-hooks -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_failure - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "Error: YAML parse error on" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] -} diff --git a/tests/it/13-diff.bats b/tests/it/13-diff.bats deleted file mode 100755 index 4046d2ed..00000000 --- a/tests/it/13-diff.bats +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "kubeval: helm plugin install helm-diff" { - run helm plugin install https://github.com/databus23/helm-diff - assert_success -} - -@test "diff: helm install" { - run helm secrets diff - assert_success - assert_output --partial 'helm secrets diff' -} - -@test "diff: helm diff upgrade --help" { - run helm secrets diff --help - assert_success - assert_output --partial 'helm secrets diff' -} - -@test "diff: helm diff upgrade w/ chart" { - CHART="diff" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - create_chart "${CHART}" - - run helm secrets diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "Release was not present in Helm." - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] -} - -@test "diff: helm diff upgrade w/ chart + secret file" { - CHART="diff" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "secret: value" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] -} - -@test "diff: helm diff upgrade w/ chart + secret file + helm flag" { - CHART="diff" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" --set image.pullPolicy=Always 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "imagePullPolicy: Always" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] -} - -@test "diff: helm diff upgrade w/ chart + pre decrypted secret file" { - CHART="diff" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - printf 'podAnnotations:\n secret: othervalue' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - - create_chart "${CHART}" - - run helm secrets diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt skipped: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "secret: othervalue" - assert [ -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] - - run rm "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_success -} - -@test "diff: helm diff upgrade w/ chart + secret file + q flag" { - CHART="diff" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets -q diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "secret: value" - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] -} - -@test "diff: helm diff upgrade w/ chart + secret file + quiet flag" { - CHART="diff" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets --quiet diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "secret: value" - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] -} - -@test "diff: helm diff upgrade w/ chart + secret file + special path" { - # shellcheck disable=SC2016 - CHART=$(printf '%s' 'a@b§c!d\$e\f(g)h=i^j😀')/diff - RELEASE="${CHART#*/}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "secret: value" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] -} - -@test "diff: helm diff upgrade w/ chart + invalid yaml" { - CHART="diff" - RELEASE="${CHART}-$(date +%s)-${RANDOM}" - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'replicaCount: |\n a:' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_failure - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "Error: YAML parse error on" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert [ ! -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" ] -} diff --git a/tests/it/99-cleanup.bats b/tests/it/99-cleanup.bats deleted file mode 100755 index 8f28e49f..00000000 --- a/tests/it/99-cleanup.bats +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "Cleanup test environment" { - tests_cleanup -} diff --git a/tests/it/diff.bats b/tests/it/diff.bats new file mode 100755 index 00000000..c1c6aef5 --- /dev/null +++ b/tests/it/diff.bats @@ -0,0 +1,148 @@ +#!/usr/bin/env bats + +load '../lib/helper' +load '../lib/create_encrypted_file' +load '../bats/extensions/bats-support/load' +load '../bats/extensions/bats-assert/load' +load '../bats/extensions/bats-file/load' + +@test "diff: helm install" { + helm_plugin_install "diff" + + run helm secrets diff + assert_success + assert_output --partial 'helm secrets diff' +} + +@test "diff: helm diff upgrade --help" { + helm_plugin_install "diff" + + run helm secrets diff --help + assert_success + assert_output --partial 'helm secrets diff' +} + +@test "diff: helm diff upgrade w/ chart" { + helm_plugin_install "diff" + RELEASE="diff-$(date +%s)-${SEED}" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_TEMP_DIR}/chart" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "Release was not present in Helm." + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] +} + +@test "diff: helm diff upgrade w/ chart + secret file" { + helm_plugin_install "diff" + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="diff-$(date +%s)-${SEED}" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "port: 81" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] +} + +@test "diff: helm diff upgrade w/ chart + secret file + helm flag" { + helm_plugin_install "diff" + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="diff-$(date +%s)-${SEED}" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_TEMP_DIR}/chart" -f "${FILE}" --set service.type=NodePort 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "port: 81" + assert_output --partial "type: NodePort" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] +} + +@test "diff: helm diff upgrade w/ chart + pre decrypted secret file" { + helm_plugin_install "diff" + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="diff-$(date +%s)-${SEED}" + + printf 'service:\n port: 82' > "${FILE}.dec" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt skipped: ${FILE}" + assert_output --partial "port: 82" + assert [ -f "${FILE}.dec" ] + + run rm "${FILE}.dec" + assert_success +} + +@test "diff: helm diff upgrade w/ chart + secret file + q flag" { + helm_plugin_install "diff" + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="diff-$(date +%s)-${SEED}" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets -q diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "port: 81" + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] +} + +@test "diff: helm diff upgrade w/ chart + secret file + quiet flag" { + helm_plugin_install "diff" + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="diff-$(date +%s)-${SEED}" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets --quiet diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "port: 81" + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] +} + +@test "diff: helm diff upgrade w/ chart + secret file + special path" { + helm_plugin_install "diff" + FILE="${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="diff-$(date +%s)-${SEED}" + + create_chart "${SPECIAL_CHAR_DIR}" + + run helm secrets diff upgrade --no-color --allow-unreleased "${RELEASE}" "${SPECIAL_CHAR_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "port: 81" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] +} + +@test "diff: helm diff upgrade w/ chart + invalid yaml" { + helm_plugin_install "diff" + FILE="${TEST_TEMP_DIR}/secrets.yaml" + RELEASE="diff-$(date +%s)-${SEED}" + + create_encrypted_file 'replicaCount: |\n a:' + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets diff upgrade --no-color --allow-unreleased "${RELEASE}" "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_failure + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "Error: YAML parse error on" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] +} diff --git a/tests/it/install.bats b/tests/it/install.bats new file mode 100755 index 00000000..061c8676 --- /dev/null +++ b/tests/it/install.bats @@ -0,0 +1,156 @@ +#!/usr/bin/env bats + +load '../lib/helper' +load '../lib/create_encrypted_file' +load '../bats/extensions/bats-support/load' +load '../bats/extensions/bats-assert/load' +load '../bats/extensions/bats-file/load' + +@test "install: helm install" { + run helm secrets install + assert_success + assert_output --partial 'helm secrets install' +} + +@test "install: helm install --help" { + run helm secrets install --help + assert_success + assert_output --partial 'helm secrets install' +} + +@test "install: helm install w/ chart" { + RELEASE="install-$(date +%s)-${SEED}" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets install "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial 'STATUS: deployed' + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success +} + +@test "install: helm install w/ chart + secret file" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="install-$(date +%s)-${SEED}" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets install "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "STATUS: deployed" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success + assert_output --partial "port: 81" +} + +@test "install: helm install w/ chart + secret file + helm flag" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="install-$(date +%s)-${SEED}" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets install "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks -f "${FILE}" --set service.type=NodePort 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "STATUS: deployed" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success + assert_output --partial "port: 81" + assert_output --partial "type: NodePort" +} + +@test "install: helm install w/ chart + pre decrypted secret file" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="install-$(date +%s)-${SEED}" + printf 'service:\n port: 82' > "${FILE}.dec" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets install "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt skipped: ${FILE}" + assert_output --partial "STATUS: deployed" + assert [ -f "${FILE}.dec" ] + + run rm "${FILE}.dec" + assert_success + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success + assert_output --partial "port: 82" +} + +@test "install: helm install w/ chart + secret file + q flag" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="install-$(date +%s)-${SEED}" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets -q install "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks -f "${FILE}" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "STATUS: deployed" + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success + assert_output --partial "port: 81" +} + +@test "install: helm install w/ chart + secret file + quiet flag" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="install-$(date +%s)-${SEED}" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets --quiet install "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks -f "${FILE}" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "STATUS: deployed" + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success + assert_output --partial "port: 81" +} + +@test "install: helm install w/ chart + secret file + special path" { + FILE="${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="install-$(date +%s)-${SEED}" + create_chart "${SPECIAL_CHAR_DIR}" + + run helm secrets install "${RELEASE}" "${SPECIAL_CHAR_DIR}/chart" --no-hooks -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "STATUS: deployed" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success + assert_output --partial "port: 81" +} + +@test "install: helm install w/ chart + invalid yaml" { + FILE="${TEST_TEMP_DIR}/secrets.yaml" + RELEASE="install-$(date +%s)-${SEED}" + + create_encrypted_file 'replicaCount: |\n a:' + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets install "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks -f "${FILE}" 2>&1 + assert_failure + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "Error: YAML parse error on" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] +} diff --git a/tests/it/upgrade.bats b/tests/it/upgrade.bats new file mode 100755 index 00000000..5bb68a6e --- /dev/null +++ b/tests/it/upgrade.bats @@ -0,0 +1,155 @@ +#!/usr/bin/env bats + +load '../lib/helper' +load '../lib/create_encrypted_file' +load '../bats/extensions/bats-support/load' +load '../bats/extensions/bats-assert/load' +load '../bats/extensions/bats-file/load' + +@test "upgrade: helm upgrade" { + run helm secrets upgrade + assert_success + assert_output --partial 'helm secrets upgrade' +} + +@test "upgrade: helm upgrade --help" { + run helm secrets upgrade --help + assert_success + assert_output --partial 'helm secrets upgrade' +} + +@test "upgrade: helm upgrade w/ chart" { + RELEASE="upgrade-$(date +%s)-${SEED}" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets upgrade -i "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial 'STATUS: deployed' + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success +} + +@test "upgrade: helm upgrade w/ chart + secret file" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="upgrade-$(date +%s)-${SEED}" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets upgrade -i "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "STATUS: deployed" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success + assert_output --partial "port: 81" +} + +@test "upgrade: helm upgrade w/ chart + secret file + helm flag" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="upgrade-$(date +%s)-${SEED}" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets upgrade -i "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks -f "${FILE}" --set service.type=NodePort 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "STATUS: deployed" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success + assert_output --partial "port: 81" + assert_output --partial "type: NodePort" +} + +@test "upgrade: helm upgrade w/ chart + pre decrypted secret file" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="upgrade-$(date +%s)-${SEED}" + printf 'service:\n port: 82' > "${FILE}.dec" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets upgrade -i "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt skipped: ${FILE}" + assert_output --partial "STATUS: deployed" + assert [ -f "${FILE}.dec" ] + + run rm "${FILE}.dec" + assert_success + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success + assert_output --partial "port: 82" +} + +@test "upgrade: helm upgrade w/ chart + secret file + q flag" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="upgrade-$(date +%s)-${SEED}" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets -q upgrade -i "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks -f "${FILE}" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "STATUS: deployed" + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success + assert_output --partial "port: 81" +} + +@test "upgrade: helm upgrade w/ chart + secret file + quiet flag" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="upgrade-$(date +%s)-${SEED}" + create_chart "${TEST_TEMP_DIR}" + + run helm secrets --quiet upgrade -i "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks -f "${FILE}" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "STATUS: deployed" + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success + assert_output --partial "port: 81" +} + +@test "upgrade: helm upgrade w/ chart + secret file + special path" { + FILE="${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + RELEASE="upgrade-$(date +%s)-${SEED}" + create_chart "${SPECIAL_CHAR_DIR}" + + run helm secrets upgrade -i "${RELEASE}" "${SPECIAL_CHAR_DIR}/chart" --no-hooks -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "STATUS: deployed" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] + + run kubectl get svc -o yaml -l "app.kubernetes.io/name=chart,app.kubernetes.io/instance=${RELEASE}" + assert_success + assert_output --partial "port: 81" +} + +@test "upgrade: helm upgrade w/ chart + invalid yaml" { + FILE="${TEST_TEMP_DIR}/secrets.yaml" + RELEASE="upgrade-$(date +%s)-${SEED}" + + create_encrypted_file 'replicaCount: |\n a:' + create_chart "${TEST_TEMP_DIR}" + + run helm secrets upgrade -i "${RELEASE}" "${TEST_TEMP_DIR}/chart" --no-hooks -f "${FILE}" 2>&1 + assert_failure + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "Error: YAML parse error on" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert [ ! -f "${FILE}.dec" ] +} diff --git a/tests/lib/create_encrypted_file.bash b/tests/lib/create_encrypted_file.bash new file mode 100644 index 00000000..d1ce1eb3 --- /dev/null +++ b/tests/lib/create_encrypted_file.bash @@ -0,0 +1,47 @@ +create_encrypted_file() { + { + file="${2:-secrets.yaml}" + case "${3:-${HELM_SECRETS_DRIVER}}" in + noop) + ( + # shellcheck disable=SC2164 + cd "${TEST_TEMP_DIR}" + echo "$1" >"${file}" + ) + ;; + sops) + ( + # shellcheck disable=SC2164 + cd "${TEST_TEMP_DIR}" + # shellcheck disable=SC2059 + printf "$1" >"${file}" + sops -e -i "${file}" + ) + ;; + vault) + ( + # shellcheck disable=SC2164 + cd "${TEST_TEMP_DIR}" + + # Check for multiline + if echo "$1" | grep -q ': |'; then + # shellcheck disable=SC2059 + secret_content="$(printf "$1" | tail -n +2 | sed -e 's/^ //g')" + secret_key="$(printf '%s' "$secret_content" | _shasum | cut -d' ' -f1)" + else + # shellcheck disable=SC2059 + secret_content="$(printf "$1" | cut -d: -f2 | tr -d ' ')" + secret_key="$(printf '%s' "$secret_content" | _shasum | cut -d' ' -f1)" + fi + + printf '%s: !vault secret/%s#key' "$(echo "$1" | cut -d: -f1)" "${secret_key}" >"${file}" + printf '%s' "${secret_content}" | vault kv put "secret/${secret_key}" key=- + ) + ;; + *) + echo "Unknown driver ${HELM_SECRETS_DRIVER}" + ;; + + esac + } >&2 +} diff --git a/tests/lib/helper.bash b/tests/lib/helper.bash new file mode 100644 index 00000000..dbfa984c --- /dev/null +++ b/tests/lib/helper.bash @@ -0,0 +1,126 @@ +GIT_ROOT="$(git rev-parse --show-toplevel)" +TEST_DIR="${GIT_ROOT}/tests" +HELM_SECRETS_DRIVER="${HELM_SECRETS_DRIVER:-"sops"}" +HELM_CACHE="${TEST_DIR}/.tmp/cache/helm" +REAL_HOME="${HOME}" + +_shasum() { + # MacOS have shasum, others have sha1sum + if command -v shasum >/dev/null; then + shasum "$@" + else + sha1sum "$@" + fi +} + +_sed_i() { + # MacOS syntax is different for in-place + if [ "$(uname)" = "Darwin" ]; then + sed -i "" "$@" + else + sed -i "$@" + fi +} + +initiate() { + { + mkdir -p "${HELM_CACHE}/home" + if [ ! -d "${HELM_CACHE}/chart" ]; then + helm create "${HELM_CACHE}/chart" + fi + } >&2 +} + +setup() { + # https://github.com/bats-core/bats-core/issues/39 + if [[ ${BATS_TEST_NAME:?} == "${BATS_TEST_NAMES[0]:?}" ]]; then + initiate + fi + + SEED="${RANDOM}" + + TEST_TEMP_DIR="$(mktemp -d)" + HOME="${TEST_TEMP_DIR}/home" + # shellcheck disable=SC2016 + SPECIAL_CHAR_DIR="${TEST_TEMP_DIR}/$(printf '%s' 'a@b§c!d\$e\f(g)h=i^j😀')" + + mkdir "${HOME}" "${TEST_TEMP_DIR}/chart" "${SPECIAL_CHAR_DIR}" + + # install helm plugin + helm plugin install "${GIT_ROOT}" + + # copy .kube from real home + if [ -d "${REAL_HOME}/.kube" ]; then + cp -r "${REAL_HOME}/.kube" "${HOME}" + fi + + # copy assets + cp -r "${TEST_DIR}/assets/values" "${TEST_TEMP_DIR}" + cp -r "${TEST_DIR}/assets/values" "$(printf '%s' "${SPECIAL_CHAR_DIR}")" + cp -r "${TEST_DIR}/assets/values/sops/.sops.yaml" "${TEST_TEMP_DIR}" + + # import default gpg key + gpg --batch --import "${TEST_DIR}/assets/gpg/private.gpg" + + case "${HELM_SECRETS_DRIVER}" in + sops) ;; + + vault) + if [ -f .dockerenv ]; then + # If we run inside docker, we expect vault on this location + export VAULT_ADDR=${VAULT_ADDR:-'http://vault:8200'} + else + export VAULT_ADDR=${VAULT_ADDR:-'http://127.0.0.1:8200'} + fi + + vault login token=test + + _sed_i "s!put secret/!put secret/${SEED}/!g" "$(printf '%s/values/vault/seed.sh' "${TEST_TEMP_DIR}")" + + _sed_i "s!vault secret/!vault secret/${SEED}/!g" "$(printf '%s/values/vault/secrets.yaml' "${TEST_TEMP_DIR}")" + _sed_i "s!vault secret/!vault secret/${SEED}/!g" "$(printf '%s/values/vault/secrets.yaml' "${SPECIAL_CHAR_DIR}")" + + sh "${TEST_TEMP_DIR}/values/vault/seed.sh" + ;; + esac +} + +teardown() { + # https://stackoverflow.com/a/13864829/8087167 + if [ -n "${RELEASE+x}" ]; then + helm del "${RELEASE}" + fi + + # https://github.com/bats-core/bats-file/pull/29 + chmod -R 777 "${TEST_TEMP_DIR}" + + # rm: cannot remove '/tmp/tmp.11dcSX0g8Q/home/.gnupg/S.gpg-agent.browser': No such file or directory + rm -rf "${TEST_TEMP_DIR}/home/.gnupg/" + + temp_del "${TEST_TEMP_DIR}" +} + +create_chart() { + { + cp -r "${HELM_CACHE}/chart" "${1}" + cp -r "${TEST_TEMP_DIR}/values" "${1}/chart" + cp "${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" "${1}/chart" + } >&2 +} + +helm_plugin_install() { + { + if ! env HOME="${HELM_CACHE}/home/" helm plugin list | grep -q "${1}"; then + case "${1}" in + kubeval) + env HOME="${HELM_CACHE}/home/" helm plugin install https://github.com/instrumenta/helm-kubeval + ;; + diff) + env HOME="${HELM_CACHE}/home/" helm plugin install https://github.com/databus23/helm-diff + ;; + esac + fi + + cp -r "${HELM_CACHE}/home/." "${HOME}" + } >&2 +} diff --git a/tests/unit/00-setup.bats b/tests/unit/00-setup.bats deleted file mode 100755 index ba4acaa5..00000000 --- a/tests/unit/00-setup.bats +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "Prepare test environment" { - tests_setup -} diff --git a/tests/unit/01-plugin-install.bats b/tests/unit/01-plugin-install.bats deleted file mode 100755 index c58903fd..00000000 --- a/tests/unit/01-plugin-install.bats +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "plugin-install: helm plugin install" { - run helm plugin install "${GIT_ROOT}" - assert_success - assert_file_exist "${TEST_HOME}/.gitconfig" -} - -@test "plugin-install: helm plugin list" { - run helm plugin list - assert_success - assert_output --partial 'secrets' -} - -@test "plugin-install: helm secrets" { - run helm secrets - assert_failure - assert_output --partial 'Available Commands:' -} - -@test "plugin-install: helm secrets --help" { - run helm secrets --help - assert_success - assert_output --partial 'Available Commands:' -} diff --git a/tests/unit/02-secret-driver.bats b/tests/unit/02-secret-driver.bats deleted file mode 100755 index c29b597e..00000000 --- a/tests/unit/02-secret-driver.bats +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "secret-driver: helm secrets -d" { - run helm secrets -d nonexists view "tests/assets/helm_vars/secrets.yaml" - assert_failure - assert_output --partial "Can't find secret driver: nonexists" -} - -@test "secret-driver: helm secrets --driver" { - run helm secrets --driver nonexists view "tests/assets/helm_vars/secrets.yaml" - assert_failure - assert_output --partial "Can't find secret driver: nonexists" -} - -@test "secret-driver: helm secrets w/ env SECRET_DRIVER" { - SECRET_DRIVER=nonexists - export SECRET_DRIVER - - run helm secrets view "${TEST_DIR}/assets/helm_vars/secrets.yaml" - assert_failure - assert_output --partial "Can't find secret driver: nonexists" -} - -@test "secret-driver: helm secrets -d sops" { - run helm secrets -d sops view "${TEST_DIR}/assets/helm_vars/secrets.yaml" - assert_success - assert_output --partial 'global_secret: global_bar' -} - -@test "secret-driver: helm secrets --driver sops" { - run helm secrets --driver sops view "${TEST_DIR}/assets/helm_vars/secrets.yaml" - assert_success - assert_output --partial 'global_secret: global_bar' -} - -@test "secret-driver: helm secrets w/ env SECRET_DRIVER=sops" { - SECRET_DRIVER=sops - export SECRET_DRIVER - - run helm secrets view "${TEST_DIR}/assets/helm_vars/secrets.yaml" - assert_success - assert_output --partial 'global_secret: global_bar' -} - -@test "secret-driver: helm secrets -d noop" { - run helm secrets -d noop view "${TEST_DIR}/assets/helm_vars/secrets.yaml" - assert_success - assert_output --partial 'sops:' -} - -@test "secret-driver: helm secrets --driver noop" { - run helm secrets --driver noop view "${TEST_DIR}/assets/helm_vars/secrets.yaml" - assert_success - assert_output --partial 'sops:' -} - -@test "secret-driver: helm secrets w/ env SECRET_DRIVER=noop" { - SECRET_DRIVER=noop - export SECRET_DRIVER=noop - - run helm secrets view "${TEST_DIR}/assets/helm_vars/secrets.yaml" - assert_success - assert_output --partial 'sops:' -} diff --git a/tests/unit/12-dec.bats b/tests/unit/12-dec.bats deleted file mode 100755 index 99cd657c..00000000 --- a/tests/unit/12-dec.bats +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "dec: helm dec" { - run helm secrets dec - assert_failure - assert_output --partial 'Error: secrets file required.' -} - -@test "dec: helm dec --help" { - run helm secrets dec --help - assert_success - assert_output --partial 'Decrypt secrets' -} - -@test "dec: File not exits" { - run helm secrets dec nonexists - assert_failure - assert_output --partial 'File does not exist: nonexists' -} - -@test "dec: Decrypt assets/helm_vars/secrets.yaml" { - FILE=tests/assets/helm_vars/secrets.yaml - - run helm secrets dec "${FILE}" - assert_success - assert_output "Decrypting ${FILE}" - assert_file_exist "${FILE}.dec" - - run cat "${FILE}.dec" - assert_success - assert_output 'global_secret: global_bar' -} - -@test "dec: Decrypt assets/helm_vars/secrets.yaml with HELM_SECRETS_DEC_SUFFIX" { - HELM_SECRETS_DEC_SUFFIX=.yaml.test - export HELM_SECRETS_DEC_SUFFIX - - FILE=tests/assets/helm_vars/secrets.yaml - - run helm secrets dec "${FILE}" - assert_success - assert_output "Decrypting ${FILE}" - assert [ -e "${FILE}.test" ] - - run cat "${FILE}.test" - assert_success - assert_output 'global_secret: global_bar' -} - -@test "dec: Decrypt assets/helm_vars/secrets.yaml with HELM_SECRETS_DEC_DIR" { - HELM_SECRETS_DEC_DIR="$(mktemp -d)" - export HELM_SECRETS_DEC_DIR - - FILE=tests/assets/helm_vars/secrets.yaml - - run helm secrets dec "${FILE}" - assert_success - assert_output "Decrypting ${FILE}" - assert_file_exist "${HELM_SECRETS_DEC_DIR}/secrets.yaml.dec" - - run cat "${HELM_SECRETS_DEC_DIR}/secrets.yaml.dec" - assert_success - assert_output 'global_secret: global_bar' -} diff --git a/tests/unit/13-enc.bats b/tests/unit/13-enc.bats deleted file mode 100755 index 8a9054a6..00000000 --- a/tests/unit/13-enc.bats +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "enc: helm enc" { - run helm secrets enc - assert_failure - assert_output --partial 'Error: secrets file required.' -} - -@test "enc: helm enc --help" { - run helm secrets enc --help - assert_success - assert_output --partial 'Encrypt secrets' -} - -@test "enc: File not exits" { - run helm secrets enc nonexists - assert_failure - assert_output --partial 'File does not exist: nonexists' -} - -@test "enc: Encrypt assets/helm_vars/secrets.yaml" { - FILE=tests/assets/helm_vars/secrets.yaml - - run helm secrets enc "${FILE}" - assert_success - assert_output --partial "Encrypting ${FILE}" - assert_output --partial "Encrypted ./secrets.yaml.dec to secrets.yaml" - - run helm secrets view "${FILE}" - assert_success - assert_output 'global_secret: global_bar' -} - -@test "enc: Encrypt assets/helm_vars/secrets.yaml with HELM_SECRETS_DEC_SUFFIX" { - HELM_SECRETS_DEC_SUFFIX=.yaml.test - export HELM_SECRETS_DEC_SUFFIX - - FILE=tests/assets/helm_vars/secrets.yaml - - run helm secrets enc "${FILE}" - assert_success - assert_output --partial "Encrypting ${FILE}" - assert_output --partial "Encrypted ./secrets.yaml.test to secrets.yaml" - - run helm secrets view "${FILE}" - assert_success - assert_output 'global_secret: global_bar' -} - -@test "enc: Encrypt assets/helm_vars/secrets.tmp.yaml" { - FILE=tests/assets/helm_vars/secrets.tmp.yaml - - YAML="hello: world" - echo "${YAML}" > "${FILE}" - - run helm secrets enc "${FILE}" - assert_success - assert_output --partial "Encrypting ${FILE}" - - run helm secrets dec "${FILE}" - assert_success - - run cat "${FILE}.dec" - assert_success - assert_output 'hello: world' -} diff --git a/tests/unit/16-lint.bats b/tests/unit/16-lint.bats deleted file mode 100755 index 5a9f0ad6..00000000 --- a/tests/unit/16-lint.bats +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "lint: helm lint" { - run helm secrets lint - assert_success - assert_output --partial 'helm secrets lint' -} - -@test "lint: helm lint --help" { - run helm secrets lint --help - assert_success - assert_output --partial 'helm secrets lint' -} - -@test "lint: helm lint w/ chart" { - CHART=lint - create_chart "${CHART}" - - run helm secrets lint "${TEST_DIR}/.tmp/${CHART}" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial '1 chart(s) linted, 0 chart(s) failed' - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "lint: helm lint w/ chart + secret file" { - CHART=lint - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets lint "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "1 chart(s) linted, 0 chart(s) failed" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "lint: helm lint w/ chart + secret file + helm flag" { - CHART=lint - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets lint "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" --set image.pullPolicy=Always 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "1 chart(s) linted, 0 chart(s) failed" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "lint: helm lint w/ chart + pre decrypted secret file" { - CHART=lint - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - printf 'podAnnotations:\n secret: othervalue' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - - create_chart "${CHART}" - - run helm secrets lint "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt skipped: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "1 chart(s) linted, 0 chart(s) failed" - assert_file_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - - run rm "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_success -} - -@test "lint: helm lint w/ chart + secret file + q flag" { - CHART=lint - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets -q lint "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "1 chart(s) linted, 0 chart(s) failed" - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "lint: helm lint w/ chart + secret file + quiet flag" { - CHART=lint - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets --quiet lint "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "1 chart(s) linted, 0 chart(s) failed" - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "lint: helm lint w/ chart + secret file + special path" { - # CHART="l§\\i'!&@\$n%t" - # shellcheck disable=SC2016 - CHART=$(printf '%s' 'a@b§c!d\$e\f(g)h=i^j😀')/lint - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets lint "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "1 chart(s) linted, 0 chart(s) failed" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "lint: helm lint w/ chart + invalid yaml" { - CHART=lint - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'replicaCount: |\n a:' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets lint "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_failure - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "Error: 1 chart(s) linted, 1 chart(s) failed" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} diff --git a/tests/unit/17-template.bats b/tests/unit/17-template.bats deleted file mode 100755 index 1b96b7be..00000000 --- a/tests/unit/17-template.bats +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "template: helm template" { - run helm secrets template - assert_success - assert_output --partial 'helm secrets template' -} - -@test "template: helm template --help" { - run helm secrets template --help - assert_success - assert_output --partial 'helm secrets template' -} - -@test "template: helm template w/ chart" { - CHART=template - create_chart "${CHART}" - - run helm secrets template "${TEST_DIR}/.tmp/${CHART}" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial '# Source: template/templates/serviceaccount.yaml' - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "template: helm template w/ chart + secret file" { - CHART=template - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets template "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "secret: value" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "template: helm template w/ chart + secret file + helm flag" { - CHART=template - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets template "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" --set image.pullPolicy=Always 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "imagePullPolicy: Always" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "template: helm template w/ chart + pre decrypted secret file" { - CHART=template - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - printf 'podAnnotations:\n secret: othervalue' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - - create_chart "${CHART}" - - run helm secrets template "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt skipped: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "secret: othervalue" - assert_file_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - - run rm "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_success -} - -@test "template: helm template w/ chart + secret file + q flag" { - CHART=template - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets -q template "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "secret: value" - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "template: helm template w/ chart + secret file + quiet flag" { - CHART=template - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets --quiet template "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "secret: value" - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "template: helm template w/ chart + secret file + special path" { - # CHART="l§\\i'!&@\$n%t" - # shellcheck disable=SC2016 - CHART=$(printf '%s' 'a@b§c!d\$e\f(g)h=i^j😀')/template - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets template "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "secret: value" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "template: helm template w/ chart + invalid yaml" { - CHART=template - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'replicaCount: |\n a:' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets template "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" 2>&1 - assert_failure - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "Error: YAML parse error" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} diff --git a/tests/unit/18-kubeval.bats b/tests/unit/18-kubeval.bats deleted file mode 100644 index 02f50a8a..00000000 --- a/tests/unit/18-kubeval.bats +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "kubeval: helm plugin install helm-kubeval" { - run helm plugin install https://github.com/instrumenta/helm-kubeval - assert_success -} - -@test "kubeval: helm kubeval" { - run helm secrets kubeval - assert_success - assert_output --partial 'helm secrets kubeval' -} - -@test "kubeval: helm kubeval --help" { - run helm secrets kubeval --help - assert_success - assert_output --partial 'helm secrets kubeval' -} - -@test "kubeval: helm kubeval w/ chart" { - CHART=kubeval - create_chart "${CHART}" - - run helm secrets kubeval "${TEST_DIR}/.tmp/${CHART}" --strict 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial 'The file kubeval/templates/serviceaccount.yaml contains a valid ServiceAccount' - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "kubeval: helm kubeval w/ chart + secret file" { - CHART=kubeval - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets kubeval "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" --strict 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "The file kubeval/templates/serviceaccount.yaml contains a valid ServiceAccount" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "kubeval: helm kubeval w/ chart + secret file + helm flag" { - CHART=kubeval - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets kubeval "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" --set image.pullPolicy=Always --strict 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "The file kubeval/templates/serviceaccount.yaml contains a valid ServiceAccount" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "kubeval: helm kubeval w/ chart + pre decrypted secret file" { - CHART=kubeval - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - printf 'podAnnotations:\n secret: othervalue' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - - create_chart "${CHART}" - - run helm secrets kubeval "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" --strict 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt skipped: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "The file kubeval/templates/serviceaccount.yaml contains a valid ServiceAccount" - assert_file_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - - run rm "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_success -} - -@test "kubeval: helm kubeval w/ chart + secret file + q flag" { - CHART=kubeval - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets -q kubeval "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" --strict 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "The file kubeval/templates/serviceaccount.yaml contains a valid ServiceAccount" - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "kubeval: helm kubeval w/ chart + secret file + quiet flag" { - CHART=kubeval - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets --quiet kubeval "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" --strict 2>&1 - assert_success - refute_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "The file kubeval/templates/serviceaccount.yaml contains a valid ServiceAccount" - refute_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "kubeval: helm kubeval w/ chart + secret file + special path" { - # CHART="l§\\i'!&@\$n%t" - # shellcheck disable=SC2016 - CHART=$(printf '%s' 'a@b§c!d\$e\f(g)h=i^j😀')/kubeval - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'podAnnotations:\n secret: value' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets kubeval "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" --strict 2>&1 - assert_success - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "The file kubeval/templates/serviceaccount.yaml contains a valid ServiceAccount" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} - -@test "kubeval: helm kubeval w/ chart + invalid yaml" { - CHART=kubeval - - mkdir -p "${TEST_DIR}/.tmp/${CHART}" >&2 - printf 'replicaCount: |\n a:' > "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - - create_chart "${CHART}" - - run helm secrets kubeval "${TEST_DIR}/.tmp/${CHART}" -f "${TEST_DIR}/.tmp/${CHART}/secrets.yaml" --strict 2>&1 - assert_failure - assert_output --partial "[helm-secrets] Decrypt: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml" - assert_output --partial "Error: YAML parse error" - assert_output --partial "[helm-secrets] Removed: ${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" - assert_file_not_exist "${TEST_DIR}/.tmp/${CHART}/secrets.yaml.dec" -} diff --git a/tests/unit/99-cleanup.bats b/tests/unit/99-cleanup.bats deleted file mode 100755 index 8f28e49f..00000000 --- a/tests/unit/99-cleanup.bats +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bats - -load '../helper' -load '../bats/extensions/bats-support/load' -load '../bats/extensions/bats-assert/load' -load '../bats/extensions/bats-file/load' - -@test "Cleanup test environment" { - tests_cleanup -} diff --git a/tests/unit/15-clean.bats b/tests/unit/clean.bats similarity index 86% rename from tests/unit/15-clean.bats rename to tests/unit/clean.bats index 9e2f9845..cd83b566 100755 --- a/tests/unit/15-clean.bats +++ b/tests/unit/clean.bats @@ -1,6 +1,6 @@ #!/usr/bin/env bats -load '../helper' +load '../lib/helper' load '../bats/extensions/bats-support/load' load '../bats/extensions/bats-assert/load' load '../bats/extensions/bats-file/load' @@ -24,7 +24,7 @@ load '../bats/extensions/bats-file/load' } @test "clean: Cleanup" { - FILE=tests/assets/helm_vars/projectX/production/us-east-1/java-app/secrets.yaml + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" run helm secrets dec "${FILE}" assert_success @@ -40,7 +40,7 @@ load '../bats/extensions/bats-file/load' HELM_SECRETS_DEC_SUFFIX=.yaml.test export HELM_SECRETS_DEC_SUFFIX - FILE=tests/assets/helm_vars/projectX/production/us-east-1/java-app/secrets.yaml + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" run helm secrets dec "${FILE}" assert_success diff --git a/tests/unit/dec.bats b/tests/unit/dec.bats new file mode 100755 index 00000000..90977297 --- /dev/null +++ b/tests/unit/dec.bats @@ -0,0 +1,78 @@ +#!/usr/bin/env bats + +load '../lib/helper' +load '../bats/extensions/bats-support/load' +load '../bats/extensions/bats-assert/load' +load '../bats/extensions/bats-file/load' + +@test "dec: helm dec" { + run helm secrets dec + assert_failure + assert_output --partial 'Error: secrets file required.' +} + +@test "dec: helm dec --help" { + run helm secrets dec --help + assert_success + assert_output --partial 'Decrypt secrets' +} + +@test "dec: File not exits" { + run helm secrets dec nonexists + assert_failure + assert_output --partial 'File does not exist: nonexists' +} + +@test "dec: Decrypt secrets.yaml" { + run helm secrets dec "${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + assert_success + assert_output "Decrypting ${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + assert_file_exist "${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml.dec" + + run cat "${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml.dec" + assert_success + assert_output --partial 'global_secret: ' + assert_output --partial 'global_bar' +} + +@test "dec: Decrypt secrets.yaml + special char directory name" { + run helm secrets dec "${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + assert_success + assert_output "Decrypting ${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + assert_file_exist "${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml.dec" + + run cat "${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml.dec" + assert_success + assert_output --partial 'global_secret: ' + assert_output --partial 'global_bar' +} + +@test "dec: Decrypt secrets.yaml + HELM_SECRETS_DEC_SUFFIX" { + HELM_SECRETS_DEC_SUFFIX=.yaml.test + export HELM_SECRETS_DEC_SUFFIX + + run helm secrets dec "${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + assert_success + assert_output "Decrypting ${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + assert [ -e "${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml.test" ] + + run cat "${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml.test" + assert_success + assert_output --partial 'global_secret: ' + assert_output --partial 'global_bar' +} + +@test "dec: Decrypt secrets.yaml + HELM_SECRETS_DEC_DIR" { + HELM_SECRETS_DEC_DIR="$(mktemp -d)" + export HELM_SECRETS_DEC_DIR + + run helm secrets dec "${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + assert_success + assert_output "Decrypting ${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + assert_file_exist "${HELM_SECRETS_DEC_DIR}/secrets.yaml.dec" + + run cat "${HELM_SECRETS_DEC_DIR}/secrets.yaml.dec" + assert_success + assert_output --partial 'global_secret: ' + assert_output --partial 'global_bar' +} diff --git a/tests/unit/14-edit.bats b/tests/unit/edit.bats similarity index 52% rename from tests/unit/14-edit.bats rename to tests/unit/edit.bats index 4d9597fe..79728c52 100755 --- a/tests/unit/14-edit.bats +++ b/tests/unit/edit.bats @@ -1,6 +1,6 @@ #!/usr/bin/env bats -load '../helper' +load '../lib/helper' load '../bats/extensions/bats-support/load' load '../bats/extensions/bats-assert/load' load '../bats/extensions/bats-file/load' @@ -23,11 +23,34 @@ load '../bats/extensions/bats-file/load' assert_output --partial 'File does not exist: nonexists' } -@test "edit: Edit tests/assets/helm_vars/projectY/production/us-east-1/java-app/" { - EDITOR=tests/assets/mock-editor/editor.sh +@test "edit: secrets.yaml" { + if [ "${HELM_SECRETS_DRIVER}" != "sops" ]; then + skip + fi + + EDITOR="${TEST_DIR}/assets/mock-editor/editor.sh" + export EDITOR + + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + run helm secrets edit "${FILE}" + assert_success + + run helm secrets view "${FILE}" + assert_success + assert_output "hello: world" +} + + +@test "edit: secrets.yaml + special path" { + if [ "${HELM_SECRETS_DRIVER}" != "sops" ]; then + skip + fi + + EDITOR="${TEST_DIR}/assets/mock-editor/editor.sh" export EDITOR - FILE=tests/assets/helm_vars/projectY/production/us-east-1/java-app/secrets.yaml + FILE="${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" run helm secrets edit "${FILE}" assert_success diff --git a/tests/unit/enc.bats b/tests/unit/enc.bats new file mode 100755 index 00000000..d6f61046 --- /dev/null +++ b/tests/unit/enc.bats @@ -0,0 +1,123 @@ +#!/usr/bin/env bats + +load '../lib/helper' +load '../bats/extensions/bats-support/load' +load '../bats/extensions/bats-assert/load' +load '../bats/extensions/bats-file/load' + +@test "enc: helm enc" { + run helm secrets enc + assert_failure + assert_output --partial 'Error: secrets file required.' +} + +@test "enc: helm enc --help" { + run helm secrets enc --help + assert_success + assert_output --partial 'Encrypt secrets' +} + +@test "enc: File not exits" { + run helm secrets enc nonexists + assert_failure + assert_output --partial 'File does not exist: nonexists' +} + +@test "enc: Encrypt secrets.yaml" { + if [ "${HELM_SECRETS_DRIVER}" != "sops" ]; then + skip + fi + + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.dec.yaml" + + run helm secrets enc "${FILE}" + + assert_output --partial "Encrypting ${FILE}" + assert_output --partial "Encrypted secrets.dec.yaml" + + run helm secrets view "${FILE}" + assert_success + assert_output --partial 'global_secret: ' + assert_output --partial 'global_bar' +} + +@test "enc: Encrypt secrets.yaml.dec" { + if [ "${HELM_SECRETS_DRIVER}" != "sops" ]; then + skip + fi + + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.dec.yaml" + + cp "${FILE}" "${FILE}.dec" + + run helm secrets enc "${FILE}" + + assert_output --partial "Encrypting ${FILE}" + assert_output --partial "Encrypted ./secrets.dec.yaml.dec to secrets.dec.yaml" + + run helm secrets view "${FILE}" + assert_success + assert_output --partial 'global_secret: ' + assert_output --partial 'global_bar' +} + +@test "enc: Encrypt secrets.yaml + special char directory name" { + if [ "${HELM_SECRETS_DRIVER}" != "sops" ]; then + skip + fi + + FILE="${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.dec.yaml" + + run helm secrets enc "${FILE}" + + assert_output --partial "Encrypting ${FILE}" + assert_output --partial "Encrypted secrets.dec.yaml" + + run helm secrets view "${FILE}" + assert_success + assert_output --partial 'global_secret: ' + assert_output --partial 'global_bar' +} + +@test "enc: Encrypt secrets.yaml with HELM_SECRETS_DEC_SUFFIX" { + if [ "${HELM_SECRETS_DRIVER}" != "sops" ]; then + skip + fi + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.dec.yaml" + cp "${FILE}" "${FILE}.test" + + HELM_SECRETS_DEC_SUFFIX=.yaml.test + export HELM_SECRETS_DEC_SUFFIX + + run helm secrets enc "${FILE}" + assert_success + assert_output --partial "Encrypting ${FILE}" + assert_output --partial "Encrypted ./secrets.dec.yaml.test to secrets.dec.yaml" + + run helm secrets view "${FILE}" + assert_success + assert_output --partial 'global_secret: ' + assert_output --partial 'global_bar' +} + +@test "enc: Encrypt secrets.tmp.yaml" { + if [ "${HELM_SECRETS_DRIVER}" != "sops" ]; then + skip + fi + + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.tmp.yaml" + + YAML="hello: world" + echo "${YAML}" > "${FILE}" + + run helm secrets enc "${FILE}" + assert_success + assert_output --partial "Encrypting ${FILE}" + + run helm secrets dec "${FILE}" + assert_success + + run cat "${FILE}.dec" + assert_success + assert_output 'hello: world' +} diff --git a/tests/unit/kubeval.bats b/tests/unit/kubeval.bats new file mode 100644 index 00000000..19062986 --- /dev/null +++ b/tests/unit/kubeval.bats @@ -0,0 +1,147 @@ +#!/usr/bin/env bats + +load '../lib/helper' +load '../lib/create_encrypted_file' +load '../bats/extensions/bats-support/load' +load '../bats/extensions/bats-assert/load' +load '../bats/extensions/bats-file/load' + +@test "kubeval: helm kubeval" { + helm_plugin_install "kubeval" + + run helm secrets kubeval + assert_success + assert_output --partial 'helm secrets kubeval' +} + +@test "kubeval: helm kubeval --help" { + helm_plugin_install "kubeval" + + run helm secrets kubeval --help + assert_success + assert_output --partial 'helm secrets kubeval' +} + +@test "kubeval: helm kubeval w/ chart" { + helm_plugin_install "kubeval" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets kubeval "${TEST_TEMP_DIR}/chart" --strict 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial 'The file chart/templates/serviceaccount.yaml contains a valid ServiceAccount' + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "kubeval: helm kubeval w/ chart + secret file" { + helm_plugin_install "kubeval" + + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets kubeval "${TEST_TEMP_DIR}/chart" -f "${FILE}" --strict 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "The file chart/templates/serviceaccount.yaml contains a valid ServiceAccount" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "kubeval: helm kubeval w/ chart + secret file + helm flag" { + helm_plugin_install "kubeval" + + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets kubeval "${TEST_TEMP_DIR}/chart" -f "${FILE}" --set image.pullPolicy=Always --strict 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "The file chart/templates/serviceaccount.yaml contains a valid ServiceAccount" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "kubeval: helm kubeval w/ chart + pre decrypted secret file" { + helm_plugin_install "kubeval" + + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + printf 'service:\n port: 82' > "${FILE}.dec" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets kubeval "${TEST_TEMP_DIR}/chart" -f "${FILE}" --strict 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt skipped: ${FILE}" + assert_output --partial "The file chart/templates/serviceaccount.yaml contains a valid ServiceAccount" + assert_file_exist "${FILE}.dec" + + run rm "${FILE}.dec" + assert_success +} + +@test "kubeval: helm kubeval w/ chart + secret file + q flag" { + helm_plugin_install "kubeval" + + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets -q kubeval "${TEST_TEMP_DIR}/chart" -f "${FILE}" --strict 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "The file chart/templates/serviceaccount.yaml contains a valid ServiceAccount" + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "kubeval: helm kubeval w/ chart + secret file + quiet flag" { + helm_plugin_install "kubeval" + + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets --quiet kubeval "${TEST_TEMP_DIR}/chart" -f "${FILE}" --strict 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "The file chart/templates/serviceaccount.yaml contains a valid ServiceAccount" + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "kubeval: helm kubeval w/ chart + secret file + special path" { + helm_plugin_install "kubeval" + + FILE="${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${SPECIAL_CHAR_DIR}" + + run helm secrets kubeval "${SPECIAL_CHAR_DIR}/chart" -f "${FILE}" --strict 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "The file chart/templates/serviceaccount.yaml contains a valid ServiceAccount" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "kubeval: helm kubeval w/ chart + invalid yaml" { + helm_plugin_install "kubeval" + + FILE="${TEST_TEMP_DIR}/secrets.yaml" + + create_encrypted_file 'replicaCount: |\n a:' + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets kubeval "${TEST_TEMP_DIR}/chart" -f "${FILE}" --strict 2>&1 + assert_failure + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "Error: YAML parse error" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} diff --git a/tests/unit/lint.bats b/tests/unit/lint.bats new file mode 100755 index 00000000..54dae59e --- /dev/null +++ b/tests/unit/lint.bats @@ -0,0 +1,124 @@ +#!/usr/bin/env bats + +load '../lib/helper' +load '../lib/create_encrypted_file' +load '../bats/extensions/bats-support/load' +load '../bats/extensions/bats-assert/load' +load '../bats/extensions/bats-file/load' + +@test "lint: helm lint" { + run helm secrets lint + assert_success + assert_output --partial 'helm secrets lint' +} + +@test "lint: helm lint --help" { + run helm secrets lint --help + assert_success + assert_output --partial 'helm secrets lint' +} + +@test "lint: helm lint w/ chart" { + create_chart "${TEST_TEMP_DIR}" + + run helm secrets lint "${TEST_TEMP_DIR}/chart" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${TEST_TEMP_DIR}/chart/secrets.yaml" + assert_output --partial '1 chart(s) linted, 0 chart(s) failed' + refute_output --partial "[helm-secrets] Removed: ${TEST_TEMP_DIR}/chart/secrets.yaml.dec" + assert_file_not_exist "${TEST_TEMP_DIR}/chart/secrets.yaml.dec" +} + +@test "lint: helm lint w/ chart + secret file" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets lint "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "1 chart(s) linted, 0 chart(s) failed" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${TEST_TEMP_DIR}/chart/secrets.yaml.dec" +} + +@test "lint: helm lint w/ chart + secret file + helm flag" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets lint "${TEST_TEMP_DIR}/chart" -f "${FILE}" --set image.pullPolicy=Always 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "1 chart(s) linted, 0 chart(s) failed" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${TEST_TEMP_DIR}/chart/secrets.yaml.dec" +} + +@test "lint: helm lint w/ chart + pre decrypted secret file" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + printf 'service:\n port: 82' > "${FILE}.dec" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets lint "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt skipped: ${FILE}" + assert_output --partial "1 chart(s) linted, 0 chart(s) failed" + assert_file_exist "${FILE}.dec" +} + +@test "lint: helm lint w/ chart + secret file + q flag" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets -q lint "${TEST_TEMP_DIR}/chart" -f "${TEST_TEMP_DIR}/chart/values/${HELM_SECRETS_DRIVER}/secrets.yaml" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${TEST_TEMP_DIR}/chart/secrets.yaml" + assert_output --partial "1 chart(s) linted, 0 chart(s) failed" + refute_output --partial "[helm-secrets] Removed: ${TEST_TEMP_DIR}/chart/secrets.yaml.dec" + assert_file_not_exist "${TEST_TEMP_DIR}/chart/secrets.yaml.dec" +} + +@test "lint: helm lint w/ chart + secret file + quiet flag" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets --quiet lint "${TEST_TEMP_DIR}/chart" -f "${TEST_TEMP_DIR}/chart/values/${HELM_SECRETS_DRIVER}/secrets.yaml" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${TEST_TEMP_DIR}/chart/secrets.yaml" + assert_output --partial "1 chart(s) linted, 0 chart(s) failed" + refute_output --partial "[helm-secrets] Removed: ${TEST_TEMP_DIR}/chart/secrets.yaml.dec" + assert_file_not_exist "${TEST_TEMP_DIR}/chart/secrets.yaml.dec" +} + +@test "lint: helm lint w/ chart + secret file + special path" { + FILE="${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${SPECIAL_CHAR_DIR}" + + run helm secrets lint "${SPECIAL_CHAR_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "1 chart(s) linted, 0 chart(s) failed" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "lint: helm lint w/ chart + invalid yaml" { + FILE="${TEST_TEMP_DIR}/secrets.yaml" + + create_encrypted_file 'replicaCount: |\n a:' + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets lint "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_failure + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "Error: 1 chart(s) linted, 1 chart(s) failed" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} diff --git a/tests/it/01-plugin-install.bats b/tests/unit/plugin-install.bats similarity index 83% rename from tests/it/01-plugin-install.bats rename to tests/unit/plugin-install.bats index ecafa341..9cabcc05 100755 --- a/tests/it/01-plugin-install.bats +++ b/tests/unit/plugin-install.bats @@ -1,14 +1,12 @@ #!/usr/bin/env bats -load '../helper' +load '../lib/helper' load '../bats/extensions/bats-support/load' load '../bats/extensions/bats-assert/load' load '../bats/extensions/bats-file/load' @test "plugin-install: helm plugin install" { - run helm plugin install "${GIT_ROOT}" - assert_success - assert [ -e "${TEST_HOME}/.gitconfig" ] + assert_file_exist "${HOME}/.gitconfig" } @test "plugin-install: helm plugin list" { diff --git a/tests/unit/secret-driver.bats b/tests/unit/secret-driver.bats new file mode 100755 index 00000000..9fe2c4e4 --- /dev/null +++ b/tests/unit/secret-driver.bats @@ -0,0 +1,111 @@ +#!/usr/bin/env bats + +load '../lib/helper' +load '../bats/extensions/bats-support/load' +load '../bats/extensions/bats-assert/load' +load '../bats/extensions/bats-file/load' + +@test "secret-driver: helm secrets -d" { + FILE="${TEST_TEMP_DIR}/values/noop/secrets.yaml" + + run helm secrets -d nonexists view "${FILE}" + assert_failure + assert_output --partial "Can't find secret driver: nonexists" +} + +@test "secret-driver: helm secrets --driver" { + FILE="${TEST_TEMP_DIR}/values/noop/secrets.yaml" + + run helm secrets --driver nonexists view "${FILE}" + assert_failure + assert_output --partial "Can't find secret driver: nonexists" +} + +@test "secret-driver: helm secrets + env HELM_SECRETS_DRIVER" { + # shellcheck disable=SC2030 + HELM_SECRETS_DRIVER=nonexists + export HELM_SECRETS_DRIVER + + FILE="${TEST_TEMP_DIR}/values/noop/secrets.yaml" + + run helm secrets view "${FILE}" + assert_failure + assert_output --partial "Can't find secret driver: nonexists" +} + +@test "secret-driver: helm secrets -d sops" { + # shellcheck disable=SC2031 + FILE="${TEST_TEMP_DIR}/values/sops/secrets.yaml" + + run helm secrets -d sops view "${FILE}" + assert_success + assert_output --partial 'global_secret: global_bar' +} + +@test "secret-driver: helm secrets --driver sops" { + # shellcheck disable=SC2031 + FILE="${TEST_TEMP_DIR}/values/sops/secrets.yaml" + + run helm secrets --driver sops view "${FILE}" + assert_success + assert_output --partial 'global_secret: global_bar' +} + +@test "secret-driver: helm secrets -d sops + q flag" { + # shellcheck disable=SC2031 + FILE="${TEST_TEMP_DIR}/values/sops/secrets.yaml" + + run helm secrets -q -d sops view "${FILE}" + assert_success + assert_output --partial 'global_secret: global_bar' +} + +@test "secret-driver: helm secrets + env HELM_SECRETS_DRIVER=sops" { + HELM_SECRETS_DRIVER=sops + export HELM_SECRETS_DRIVER + + FILE="${TEST_TEMP_DIR}/values/sops/secrets.yaml" + + run helm secrets view "${FILE}" + assert_success + assert_output --partial 'global_secret: global_bar' +} + +@test "secret-driver: helm secrets -d noop" { + FILE="${TEST_TEMP_DIR}/values/sops/secrets.yaml" + + run helm secrets -d noop view "${FILE}" + assert_success + assert_output --partial 'sops:' +} + +@test "secret-driver: helm secrets --driver noop" { + FILE="${TEST_TEMP_DIR}/values/sops/secrets.yaml" + + run helm secrets --driver noop view "${FILE}" + assert_success + assert_output --partial 'sops:' +} + +@test "secret-driver: helm secrets + env HELM_SECRETS_DRIVER=noop" { + HELM_SECRETS_DRIVER=noop + export HELM_SECRETS_DRIVER=noop + + FILE="${TEST_TEMP_DIR}/values/sops/secrets.yaml" + + run helm secrets view "${FILE}" + assert_success + assert_output --partial 'sops:' +} + + +@test "secret-driver: helm secrets + prefer cli arg over env" { + HELM_SECRETS_DRIVER=sops + export HELM_SECRETS_DRIVER=sops + + FILE="${TEST_TEMP_DIR}/values/sops/secrets.yaml" + + run helm secrets -d noop view "${FILE}" + assert_success + assert_output --partial 'sops:' +} diff --git a/tests/unit/template.bats b/tests/unit/template.bats new file mode 100755 index 00000000..6a92a9fc --- /dev/null +++ b/tests/unit/template.bats @@ -0,0 +1,128 @@ +#!/usr/bin/env bats + +load '../lib/helper' +load '../lib/create_encrypted_file' +load '../bats/extensions/bats-support/load' +load '../bats/extensions/bats-assert/load' +load '../bats/extensions/bats-file/load' + +@test "template: helm template" { + run helm secrets template + assert_success + assert_output --partial 'helm secrets template' +} + +@test "template: helm template --help" { + run helm secrets template --help + assert_success + assert_output --partial 'helm secrets template' +} + +@test "template: helm template w/ chart" { + create_chart "${TEST_TEMP_DIR}" + + run helm secrets template "${TEST_TEMP_DIR}/chart" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial 'RELEASE-NAME-' + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "template: helm template w/ chart + secret file" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets template "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "port: 81" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "template: helm template w/ chart + secret file + helm flag" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets template "${TEST_TEMP_DIR}/chart" -f "${FILE}" --set image.pullPolicy=Always 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "port: 81" + assert_output --partial "imagePullPolicy: Always" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "template: helm template w/ chart + pre decrypted secret file" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + printf 'service:\n port: 82' > "${FILE}.dec" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets template "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt skipped: ${FILE}" + assert_output --partial "port: 82" + assert_file_exist "${FILE}.dec" + + run rm "${FILE}.dec" + assert_success +} + +@test "template: helm template w/ chart + secret file + q flag" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets -q template "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "port: 81" + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "template: helm template w/ chart + secret file + quiet flag" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets --quiet template "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + refute_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "port: 81" + refute_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "template: helm template w/ chart + secret file + special path" { + FILE="${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + create_chart "${SPECIAL_CHAR_DIR}" + + run helm secrets template "${SPECIAL_CHAR_DIR}/chart" -f "${FILE}" 2>&1 + assert_success + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "port: 81" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} + +@test "template: helm template w/ chart + invalid yaml" { + FILE="${TEST_TEMP_DIR}/secrets.yaml" + + create_encrypted_file 'replicaCount: |\n a:' + + create_chart "${TEST_TEMP_DIR}" + + run helm secrets template "${TEST_TEMP_DIR}/chart" -f "${FILE}" 2>&1 + assert_failure + assert_output --partial "[helm-secrets] Decrypt: ${FILE}" + assert_output --partial "Error: YAML parse error" + assert_output --partial "[helm-secrets] Removed: ${FILE}.dec" + assert_file_not_exist "${FILE}.dec" +} diff --git a/tests/unit/11-view.bats b/tests/unit/view.bats similarity index 57% rename from tests/unit/11-view.bats rename to tests/unit/view.bats index 82b20a46..b55058b0 100755 --- a/tests/unit/11-view.bats +++ b/tests/unit/view.bats @@ -1,6 +1,6 @@ #!/usr/bin/env bats -load '../helper' +load '../lib/helper' load '../bats/extensions/bats-support/load' load '../bats/extensions/bats-assert/load' load '../bats/extensions/bats-file/load' @@ -23,10 +23,20 @@ load '../bats/extensions/bats-file/load' assert_output --partial 'File does not exist: nonexists' } -@test "view: View assets/helm_vars/secrets.yaml" { - FILE=tests/assets/helm_vars/secrets.yaml +@test "view: secrets.yaml" { + FILE="${TEST_TEMP_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" run helm secrets view "${FILE}" assert_success - assert_output 'global_secret: global_bar' + assert_output --partial 'global_secret: ' + assert_output --partial 'global_bar' +} + +@test "view: secrets.yaml + special char directory name" { + FILE="${SPECIAL_CHAR_DIR}/values/${HELM_SECRETS_DRIVER}/secrets.yaml" + + run helm secrets view "${FILE}" + assert_success + assert_output --partial 'global_secret: ' + assert_output --partial 'global_bar' }