From d3e65b2358418567d6e6b999470b8c10b180629d Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Mon, 14 Feb 2022 11:00:17 -0500 Subject: [PATCH 01/25] Initial attempt at reworking e2e tests This is an potential implementation as to how we can write our e2e tests so that they can be run as part of a build pipeline as well as run locally. In both cases, the e2e uses a KinD cluster to test against. --- .github/workflows/slash-command-dispatch.yml | 15 - .github/workflows/test-command.yml | 664 +------------------ Makefile | 12 + go.mod | 1 + go.sum | 8 + test/e2e/README.md | 28 + test/e2e/common.go | 253 +++---- test/e2e/e2e_data_injection_test.go | 43 -- test/e2e/e2e_example_game_test.go | 53 -- test/e2e/e2e_general_cli_test.go | 164 ++--- test/e2e/e2e_gitea_and_grafana_test.go | 45 -- test/e2e/e2e_gitops_example_test.go | 63 -- 12 files changed, 257 insertions(+), 1092 deletions(-) delete mode 100644 .github/workflows/slash-command-dispatch.yml create mode 100644 test/e2e/README.md delete mode 100644 test/e2e/e2e_data_injection_test.go delete mode 100644 test/e2e/e2e_example_game_test.go delete mode 100644 test/e2e/e2e_gitea_and_grafana_test.go delete mode 100644 test/e2e/e2e_gitops_example_test.go diff --git a/.github/workflows/slash-command-dispatch.yml b/.github/workflows/slash-command-dispatch.yml deleted file mode 100644 index 9de4ef5d63..0000000000 --- a/.github/workflows/slash-command-dispatch.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: Slash Command Dispatch -on: - issue_comment: - types: [created] -jobs: - slashCommandDispatch: - runs-on: ubuntu-latest - steps: - - name: Slash Command Dispatch - uses: peter-evans/slash-command-dispatch@v2 - with: - token: ${{ secrets.PAT }} - commands: test - permission: write - issue-type: pull-request diff --git a/.github/workflows/test-command.yml b/.github/workflows/test-command.yml index 1d19f6786f..58ca2a4ab2 100644 --- a/.github/workflows/test-command.yml +++ b/.github/workflows/test-command.yml @@ -1,651 +1,33 @@ # Attribution for a bunch of this goes to CloudPosse # https://github.com/cloudposse/actions/blob/master/.github/workflows/test-command.yml -name: test +name: e2e on: - repository_dispatch: - types: [test-command] - -defaults: - run: - # We need -e -o pipefail for consistency with GitHub Actions' default behavior - shell: bash -e -o pipefail {0} + - pull_request jobs: - # Parse the command so we can decide which tests to run. Examples: "/test all", "/test validate", "/test e2e" - # We can do as many of these as we want to get as granular as we want. - parse: - runs-on: ubuntu-latest - outputs: - run-ping: ${{ steps.parse.outputs.ping }} - run-build: ${{ steps.parse.outputs.build }} - run-e2e: ${{ steps.parse.outputs.e2e }} - steps: - - name: Parse Args - id: parse - env: - DEBUG: ${{ toJSON(github.event.client_payload.slash_command) }} - ARGS_V1: ${{ github.event.client_payload.slash_command.arg1 }} - ARGS_V2: ${{ github.event.client_payload.slash_command.args.unnamed.all }} - shell: bash - run: | - ARGS="${ARGS_V1}${ARGS_V2}" - printf "Args are %s\n" "$ARGS" - printf "\n\nslash_command is %s\n\n" "$DEBUG" - COMMANDS=(PING BUILD E2E) - if printf "%s" "${ARGS^^}" | grep -qE '\bALL\b'; then - # "all" explicitly does not include "ping" - for cmd in "${COMMANDS[@]}"; do - [[ $cmd == "PING" ]] && ! { printf "%s" "${ARGS^^}" | grep -qE '\bPING\b'; } && continue - printf -v "$cmd" "true" - done - else - for cmd in "${COMMANDS[@]}"; do - if printf "%s" "${ARGS^^}" | grep -qE "\b${cmd}\b"; then - printf -v "$cmd" "true" - fi - done - fi - for out in "${COMMANDS[@]}"; do - printf "::set-output name=%s::%s\n" "${out,,}" "${!out:-false}" - printf "%s=%s\n" "${out,,}" "${!out:-false}" - done - - # Do a simple ping/pong status update to validate things are working - ping: - runs-on: ubuntu-latest - needs: parse - if: needs.parse.outputs.run-ping == 'true' - steps: - # Update GitHub status for dispatch events - - name: "Update GitHub Status for this ref" - uses: "docker://cloudposse/github-status-updater" - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: success - GITHUB_CONTEXT: "/test ping" - GITHUB_DESCRIPTION: "pong" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Build and upload the artifacts so they can be used later in the pipeline - build: - runs-on: ubuntu-latest - needs: parse - # Run if they explicitly want it, or run if they want a different stage that depends on this - if: needs.parse.outputs.run-build == 'true' || needs.parse.outputs.run-e2e == 'true' - container: cloudposse/test-harness:latest - steps: - # Update GitHub status for pending pipeline run - - name: "Update GitHub Status for pending" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: pending - GITHUB_CONTEXT: "/test build" - GITHUB_DESCRIPTION: "started by @${{ github.event.client_payload.github.actor }}" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Checkout the code from GitHub Pull Request - - name: "Checkout the code" - uses: actions/checkout@v2 - with: - token: ${{ secrets.PAT }} - repository: ${{ github.event.client_payload.pull_request.head.repo.full_name }} - ref: ${{ github.event.client_payload.pull_request.head.ref }} - - - name: "Build the artifacts" - shell: bash -x -e -o pipefail {0} - run: | - # cloudposse/test-harness has golang 1.15, we need 1.16. This is the easiest way I know to do it. This should definitely be revisited and cleaned up. - git clone --branch v0.8.0 --depth 1 https://github.com/asdf-vm/asdf.git $HOME/.asdf - source ~/.asdf/asdf.sh - export PATH="$HOME/.asdf/bin:$PATH" - asdf plugin-add golang https://github.com/kennyp/asdf-golang.git - asdf install golang 1.16.7 - asdf global golang 1.16.7 - export GOPATH="$HOME/go" - export PATH="$PATH:$GOPATH/bin" - make build-cli-linux - ./build/zarf tools registry login registry1.dso.mil --username "${{ secrets.REGISTRY1_USERNAME_ZARF_ROBOT }}" --password "${{ secrets.REGISTRY1_PASSWORD_ZARF_ROBOT }}" - make init-package - - - name: "Upload the artifacts" - uses: actions/upload-artifact@v2 - with: - name: build - path: build - if-no-files-found: error - - # Update GitHub status for failing pipeline run - - name: "Update GitHub Status for failure" - if: ${{ failure() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: failure - GITHUB_CONTEXT: "/test build" - GITHUB_DESCRIPTION: "run failed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for successful pipeline run - - name: "Update GitHub Status for success" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: success - GITHUB_CONTEXT: "/test build" - GITHUB_DESCRIPTION: "run passed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for cancelled pipeline run - - name: "Update GitHub Status for cancelled" - if: ${{ cancelled() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: error - GITHUB_CONTEXT: "/test build" - GITHUB_DESCRIPTION: "run cancelled" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Run the Game E2E test - e2e-game: - runs-on: ubuntu-latest - needs: [parse, build] - if: needs.parse.outputs.run-e2e == 'true' - container: cloudposse/test-harness:latest - steps: - # Update GitHub status for pending pipeline run - - name: "Update GitHub Status for pending" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: pending - GITHUB_CONTEXT: "/test e2e - Game Example" - GITHUB_DESCRIPTION: "started by @${{ github.event.client_payload.github.actor }}" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Checkout the code from GitHub Pull Request - - name: "Checkout the code" - uses: actions/checkout@v2 - with: - token: ${{ secrets.PAT }} - repository: ${{ github.event.client_payload.pull_request.head.repo.full_name }} - ref: ${{ github.event.client_payload.pull_request.head.ref }} - - # Download the built artifacts - - name: "Download the built artifacts" - uses: actions/download-artifact@v2 - - - name: "Run E2E tests" - shell: bash -x -e -o pipefail {0} - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} - AWS_DEFAULT_REGION: us-east-1 - run: | - # cloudposse/test-harness has golang 1.15, we need 1.16. This is the easiest way I know to do it. This should definitely be revisited and cleaned up. - git clone --branch v0.8.0 --depth 1 https://github.com/asdf-vm/asdf.git $HOME/.asdf - source ~/.asdf/asdf.sh - export PATH="$HOME/.asdf/bin:$PATH" - asdf plugin-add golang https://github.com/kennyp/asdf-golang.git - asdf install golang 1.16.7 - asdf global golang 1.16.7 - export GOPATH="$HOME/go" - export PATH="$PATH:$GOPATH/bin" - chmod +x build/zarf - make package-example-game test-cloud-e2e-example-game - - # Update GitHub status for failing pipeline run - - name: "Update GitHub Status for failure" - if: ${{ failure() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: failure - GITHUB_CONTEXT: "/test e2e - Game Example" - GITHUB_DESCRIPTION: "run failed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for successful pipeline run - - name: "Update GitHub Status for success" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: success - GITHUB_CONTEXT: "/test e2e - Game Example" - GITHUB_DESCRIPTION: "run passed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for cancelled pipeline run - - name: "Update GitHub Status for cancelled" - if: ${{ cancelled() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: error - GITHUB_CONTEXT: "/test e2e - Game Example" - GITHUB_DESCRIPTION: "run cancelled" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Run the E2E test of Gitea and Grafana - e2e-gitea-grafana: - runs-on: ubuntu-latest - needs: [parse, build] - if: needs.parse.outputs.run-e2e == 'true' - container: cloudposse/test-harness:latest - steps: - # Update GitHub status for pending pipeline run - - name: "Update GitHub Status for pending" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: pending - GITHUB_CONTEXT: "/test e2e - Gitea & Grafana" - GITHUB_DESCRIPTION: "started by @${{ github.event.client_payload.github.actor }}" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Checkout the code from GitHub Pull Request - - name: "Checkout the code" - uses: actions/checkout@v2 - with: - token: ${{ secrets.PAT }} - repository: ${{ github.event.client_payload.pull_request.head.repo.full_name }} - ref: ${{ github.event.client_payload.pull_request.head.ref }} - - # Download the built artifacts - - name: "Download the built artifacts" - uses: actions/download-artifact@v2 - - - name: "Run E2E tests" - shell: bash -x -e -o pipefail {0} - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} - AWS_DEFAULT_REGION: us-east-1 - run: | - # cloudposse/test-harness has golang 1.15, we need 1.16. This is the easiest way I know to do it. This should definitely be revisited and cleaned up. - git clone --branch v0.8.0 --depth 1 https://github.com/asdf-vm/asdf.git $HOME/.asdf - source ~/.asdf/asdf.sh - export PATH="$HOME/.asdf/bin:$PATH" - asdf plugin-add golang https://github.com/kennyp/asdf-golang.git - asdf install golang 1.16.7 - asdf global golang 1.16.7 - export GOPATH="$HOME/go" - export PATH="$PATH:$GOPATH/bin" - chmod +x build/zarf - make test-cloud-e2e-gitea-and-grafana - - # Update GitHub status for failing pipeline run - - name: "Update GitHub Status for failure" - if: ${{ failure() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: failure - GITHUB_CONTEXT: "/test e2e - Gitea & Grafana" - GITHUB_DESCRIPTION: "run failed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for successful pipeline run - - name: "Update GitHub Status for success" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: success - GITHUB_CONTEXT: "/test e2e - Gitea & Grafana" - GITHUB_DESCRIPTION: "run passed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for cancelled pipeline run - - name: "Update GitHub Status for cancelled" - if: ${{ cancelled() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: error - GITHUB_CONTEXT: "/test e2e - Gitea & Grafana" - GITHUB_DESCRIPTION: "run cancelled" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Run the E2E test of the Data Injection example - e2e-data-injection: - runs-on: ubuntu-latest - needs: [parse, build] - if: needs.parse.outputs.run-e2e == 'true' - container: cloudposse/test-harness:latest - steps: - # Update GitHub status for pending pipeline run - - name: "Update GitHub Status for pending" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: pending - GITHUB_CONTEXT: "/test e2e - Data Injection" - GITHUB_DESCRIPTION: "started by @${{ github.event.client_payload.github.actor }}" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Checkout the code from GitHub Pull Request - - name: "Checkout the code" - uses: actions/checkout@v2 - with: - token: ${{ secrets.PAT }} - repository: ${{ github.event.client_payload.pull_request.head.repo.full_name }} - ref: ${{ github.event.client_payload.pull_request.head.ref }} - - # Download the built artifacts - - name: "Download the built artifacts" - uses: actions/download-artifact@v2 - - - name: "Run E2E tests" - shell: bash -x -e -o pipefail {0} - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} - AWS_DEFAULT_REGION: us-east-1 - run: | - # cloudposse/test-harness has golang 1.15, we need 1.16. This is the easiest way I know to do it. This should definitely be revisited and cleaned up. - git clone --branch v0.8.0 --depth 1 https://github.com/asdf-vm/asdf.git $HOME/.asdf - source ~/.asdf/asdf.sh - export PATH="$HOME/.asdf/bin:$PATH" - asdf plugin-add golang https://github.com/kennyp/asdf-golang.git - asdf install golang 1.16.7 - asdf global golang 1.16.7 - export GOPATH="$HOME/go" - export PATH="$PATH:$GOPATH/bin" - chmod +x build/zarf - ./build/zarf tools registry login registry1.dso.mil --username "${{ secrets.REGISTRY1_USERNAME_ZARF_ROBOT }}" --password "${{ secrets.REGISTRY1_PASSWORD_ZARF_ROBOT }}" - make test-cloud-e2e-data-injection - - # Update GitHub status for failing pipeline run - - name: "Update GitHub Status for failure" - if: ${{ failure() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: failure - GITHUB_CONTEXT: "/test e2e - Data Injection" - GITHUB_DESCRIPTION: "run failed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for successful pipeline run - - name: "Update GitHub Status for success" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: success - GITHUB_CONTEXT: "/test e2e - Data Injection" - GITHUB_DESCRIPTION: "run passed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for cancelled pipeline run - - name: "Update GitHub Status for cancelled" - if: ${{ cancelled() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: error - GITHUB_CONTEXT: "/test e2e - Data Injection" - GITHUB_DESCRIPTION: "run cancelled" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Run E2E test for general CLI stuff - e2e-general-cli: + build-and-test: runs-on: ubuntu-latest - needs: [ parse, build ] - if: needs.parse.outputs.run-e2e == 'true' - container: cloudposse/test-harness:latest steps: - # Update GitHub status for pending pipeline run - - name: "Update GitHub Status for pending" - uses: docker://cloudposse/github-status-updater + - name: Install GoLang + uses: actions/setup-go@v2 with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: pending - GITHUB_CONTEXT: "/test e2e - General CLI" - GITHUB_DESCRIPTION: "started by @${{ github.event.client_payload.github.actor }}" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Checkout the code from GitHub Pull Request - - name: "Checkout the code" + go-version: 1.16.x + - name: Checkout Repo uses: actions/checkout@v2 - with: - token: ${{ secrets.PAT }} - repository: ${{ github.event.client_payload.pull_request.head.repo.full_name }} - ref: ${{ github.event.client_payload.pull_request.head.ref }} - - # Download the built artifacts - - name: "Download the built artifacts" - uses: actions/download-artifact@v2 - - - name: "Run E2E tests" - shell: bash -x -e -o pipefail {0} - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} - AWS_DEFAULT_REGION: us-east-1 - run: | - # cloudposse/test-harness has golang 1.15, we need 1.16. This is the easiest way I know to do it. This should definitely be revisited and cleaned up. - git clone --branch v0.8.0 --depth 1 https://github.com/asdf-vm/asdf.git $HOME/.asdf - source ~/.asdf/asdf.sh - export PATH="$HOME/.asdf/bin:$PATH" - asdf plugin-add golang https://github.com/kennyp/asdf-golang.git - asdf install golang 1.16.7 - asdf global golang 1.16.7 - export GOPATH="$HOME/go" - export PATH="$PATH:$GOPATH/bin" - chmod +x build/zarf - ./build/zarf tools registry login registry1.dso.mil --username "${{ secrets.REGISTRY1_USERNAME_ZARF_ROBOT }}" --password "${{ secrets.REGISTRY1_PASSWORD_ZARF_ROBOT }}" - make test-cloud-e2e-general-cli - - # Update GitHub status for failing pipeline run - - name: "Update GitHub Status for failure" - if: ${{ failure() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: failure - GITHUB_CONTEXT: "/test e2e - General CLI" - GITHUB_DESCRIPTION: "run failed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for successful pipeline run - - name: "Update GitHub Status for success" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: success - GITHUB_CONTEXT: "/test e2e - General CLI" - GITHUB_DESCRIPTION: "run passed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for cancelled pipeline run - - name: "Update GitHub Status for cancelled" - if: ${{ cancelled() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: error - GITHUB_CONTEXT: "/test e2e - General CLI" - GITHUB_DESCRIPTION: "run cancelled" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Run the E2E gitops example test - e2e-gitops: - runs-on: ubuntu-latest - needs: [parse, build] - if: needs.parse.outputs.run-e2e == 'true' - container: cloudposse/test-harness:latest - steps: - # Update GitHub status for pending pipeline run - - name: "Update GitHub Status for pending" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: pending - GITHUB_CONTEXT: "/test e2e - Gitops Example" - GITHUB_DESCRIPTION: "started by @${{ github.event.client_payload.github.actor }}" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Checkout the code from GitHub Pull Request - - name: "Checkout the code" - uses: actions/checkout@v2 - with: - token: ${{ secrets.PAT }} - repository: ${{ github.event.client_payload.pull_request.head.repo.full_name }} - ref: ${{ github.event.client_payload.pull_request.head.ref }} - - # Download the built artifacts - - name: "Download the built artifacts" - uses: actions/download-artifact@v2 - - - name: "Run E2E tests" - shell: bash -x -e -o pipefail {0} - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} - AWS_DEFAULT_REGION: us-east-1 - run: | - # cloudposse/test-harness has golang 1.15, we need 1.16. This is the easiest way I know to do it. This should definitely be revisited and cleaned up. - git clone --branch v0.8.0 --depth 1 https://github.com/asdf-vm/asdf.git $HOME/.asdf - source ~/.asdf/asdf.sh - export PATH="$HOME/.asdf/bin:$PATH" - asdf plugin-add golang https://github.com/kennyp/asdf-golang.git - asdf install golang 1.16.7 - asdf global golang 1.16.7 - export GOPATH="$HOME/go" - export PATH="$PATH:$GOPATH/bin" - chmod +x build/zarf - make test-cloud-e2e-gitops - - # Update GitHub status for failing pipeline run - - name: "Update GitHub Status for failure" - if: ${{ failure() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: failure - GITHUB_CONTEXT: "/test e2e - Gitops Example" - GITHUB_DESCRIPTION: "run failed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for successful pipeline run - - name: "Update GitHub Status for success" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: success - GITHUB_CONTEXT: "/test e2e - Gitops Example" - GITHUB_DESCRIPTION: "run passed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for cancelled pipeline run - - name: "Update GitHub Status for cancelled" - if: ${{ cancelled() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: error - GITHUB_CONTEXT: "/test e2e - Gitops Example" - GITHUB_DESCRIPTION: "run cancelled" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} + - name: Build CLI + run: make build-cli-linux + - name: Sign into Repo1 + run: ./build/zarf tools registry login registry1.dso.mil -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} + - name: Make Packages + run: make init-package + + - uses: engineerd/setup-kind@v0.5.0 + with: + wait: 300s + version: v0.11.1 + image: kindest/node:v1.21.1 + name: test-cluster + + - name: Run Tests + run: make test-new-e2e diff --git a/Makefile b/Makefile index 1183846555..c3c31ac00c 100644 --- a/Makefile +++ b/Makefile @@ -100,3 +100,15 @@ test-cloud-e2e-general-cli: package-example-tiny-kafka ## Runs tests of the CLI .PHONY: test-e2e test-e2e: package-example-game test-cloud-e2e-example-game ## DEPRECATED - to be replaced by individual e2e test targets + + +.PHONY: build-and-test-e2e +build-and-test-e2e: build-cli init-package test-new-e2e ## Builds the cli and init package and runs the local e2e tests + +# TODO: Rename this once we are certain this is the e2e approach we are going to be taking +# TODO: I'm pretty sure there's some way Makefiles could be setup to not run dependant steps if their results are already cached or something +# That way we wouldn't need this target and can just call build-and-test-e2e and not have to wait for the build if it was already built. +# TODO: This can be cleaned up a little more when `zarf init` is able to provide the path to the `zarf-init.tar.zst` +.PHONY: test-new-e2e +test-new-e2e: ## Run e2e tests on a KiND cluster. All dependencies are assumed to be built and in the ./build directory + cd test/e2e && cp ../../build/zarf-init.tar.zst . && go test ./... -v -timeout 1200s && rm zarf-init.tar.zst diff --git a/go.mod b/go.mod index fd360b00f8..bed758af68 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( k8s.io/apimachinery v0.22.5 k8s.io/client-go v0.22.5 k8s.io/klog/v2 v2.40.1 + sigs.k8s.io/kind v0.11.1 sigs.k8s.io/kustomize/api v0.8.11 sigs.k8s.io/kustomize/kyaml v0.11.0 sigs.k8s.io/yaml v1.3.0 diff --git a/go.sum b/go.sum index 2c856a138c..f5167e6750 100644 --- a/go.sum +++ b/go.sum @@ -157,6 +157,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= +github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= @@ -467,6 +469,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.2.0 h1:8ozOH5xxoMYDt5/u+yMTsVXydVCbTORFnOOoq2lumco= +github.com/evanphx/json-patch/v5 v5.2.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= @@ -790,6 +794,7 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o= github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= @@ -1083,6 +1088,7 @@ github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtP github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= @@ -2039,6 +2045,8 @@ rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/kind v0.11.1 h1:pVzOkhUwMBrCB0Q/WllQDO3v14Y+o2V0tFgjTqIUjwA= +sigs.k8s.io/kind v0.11.1/go.mod h1:fRpgVhtqAWrtLB9ED7zQahUimpUXuG/iHT88xYqEGIA= sigs.k8s.io/kustomize/api v0.8.11 h1:LzQzlq6Z023b+mBtc6v72N2mSHYmN8x7ssgbf/hv0H8= sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g= sigs.k8s.io/kustomize/cmd/config v0.9.13/go.mod h1:7547FLF8W/lTaDf0BDqFTbZxM9zqwEJqCKN9sSR0xSs= diff --git a/test/e2e/README.md b/test/e2e/README.md new file mode 100644 index 0000000000..796aaec355 --- /dev/null +++ b/test/e2e/README.md @@ -0,0 +1,28 @@ +# Zarf End-To-End Tests + +This directory holds all of our e2e tests that we use to verify Zarf functionality in an environment that replicates a live setting. The tests in this directory are automatically run whenever a PR is opened against the repo and the passing of all of the tests is a pre-condition to having a PR merged into the baseline. The e2e tests stand up a KinD cluster for Zarf to use during the testing. + + +## Running Tests Locally + +### Dependencies +Running the tests locally have the same prerequisites as running and building Zarf: + 1. GoLang >= `1.16.x` + 2. Make + +### Local K8s Cluster +If you have a cluster already running on your local machine, great! As long as your kubeconfig is accessible at `~/.kube/.config` or is exposed in your `$KUBECONFIG` environment variable, the e2e tests will be able to use your cluster to run your tests. If you do not have a local cluster running, still great! The e2e tests use the `sigs.k8s.io/kind` library to stand up a local KinD cluster to test against. +> NOTE: Your existing local cluster needs to have the cluster name `test-cluster` for the e2e tests to use it + +If your cluster existed before the e2e test ran, your cluster will still be up after the tests are completed. Just note that since the tests are actively using your cluster it might be in a very different state. +If you did not have a local cluster running before the e2e test but you want to keep it up afterwards to do some debugging, you can set the `SKIP_TEARDOWN` environment variable and the e2e tests will leave the create cluster up after all testing is completed. + +### Actually Running The Test +Recommend running the tests by going to the directory of the Zarf repo and running `make test-new-e2e` this will guarantee all the necessary packages are built and in the right place for the test to find. If you already built everything you can run the tests by staying in this directory and using the command `go test ./... -v` + +## Adding More Tests +> NOTE: Since all of the tests use the same K8s cluster, do not write new tests to be executed in parallel and remember to cleanup the cluster after each test by executing `zarf destroy --confirm --remove-components`. An example can be found [TODO PLACE LINK] + +In the future, our goals is to be able to run all of the tests while using an exhaustive combination of different k8s distros and base operating systems. + + diff --git a/test/e2e/common.go b/test/e2e/common.go index 2949ce959c..dda89c7093 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -1,187 +1,136 @@ package test import ( - "bufio" - "encoding/base64" + "context" + "errors" "fmt" - "github.com/gruntwork-io/terratest/modules/random" - "github.com/gruntwork-io/terratest/modules/retry" - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" - "io/ioutil" "os" - "testing" + "path" + "runtime" "time" - "github.com/gruntwork-io/terratest/modules/aws" - "github.com/gruntwork-io/terratest/modules/ssh" - "github.com/gruntwork-io/terratest/modules/terraform" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "sigs.k8s.io/kind/pkg/cluster" + kindcmd "sigs.k8s.io/kind/pkg/cmd" ) type ZarfE2ETest struct { - testing *testing.T - tempFolder string - username string - terraformOptions *terraform.Options - keyPair *aws.Ec2Keypair - publicIP string - publicHost ssh.Host + zarfBinPath string + + clusterName string `default: "test-cluster"` + kubeconfigPath string + kubeconfig *os.File + provider *cluster.Provider + restConfig *restclient.Config + clientset *kubernetes.Clientset + clusterAlreadyExists bool } -func NewE2ETest(testing *testing.T) *ZarfE2ETest { +func getKubeconfigPath() (string, error) { - testing.Parallel() - - // Copy the terraform folder to a temp directory so we can run multiple tests in parallel - tempFolder := teststructure.CopyTerraformFolderToTemp(testing, "..", "tf/public-ec2-instance") - - e2e := ZarfE2ETest{ - testing: testing, - tempFolder: tempFolder, - // Our SSH username, will change based on which AMI we use - username: "ubuntu", + // Check if the $KUBECONFIG env is set + // TODO: It would probably be good to verify a useable kubeconfig lives here + kubeconfigEnv := os.Getenv("KUBECONFIG") + if kubeconfigEnv != "" { + return kubeconfigEnv, nil } - // Deploy the terraform infra - teststructure.RunTestStage(testing, "SETUP", e2e.setup) - - return &e2e -} - -func (e2e *ZarfE2ETest) runSSHCommand(format string, a ...interface{}) (string, error) { - command := fmt.Sprintf(format, a...) - return ssh.CheckSshCommandE(e2e.testing, e2e.publicHost, command) -} + userHomeDir, err := os.UserHomeDir() + if err != nil { + return "", err + } -func (e2e *ZarfE2ETest) teardown() { - keyPair := teststructure.LoadEc2KeyPair(e2e.testing, e2e.tempFolder) - aws.DeleteEC2KeyPair(e2e.testing, keyPair) + configBaseDir := path.Join(userHomeDir, ".kube") + if err := os.MkdirAll(configBaseDir, 0700); err != nil { + return "", err + } - terraformOptions := teststructure.LoadTerraformOptions(e2e.testing, e2e.tempFolder) - terraform.Destroy(e2e.testing, terraformOptions) + kubeconfigPath := path.Join(configBaseDir, "config") + _, err = os.OpenFile(kubeconfigPath, os.O_RDWR|os.O_CREATE, 0755) + return kubeconfigPath, err } -func (e2e *ZarfE2ETest) setup() { - terraformOptions, keyPair, err := e2e.configureTerraformOptions() - require.NoError(e2e.testing, err) - - // Save the options and key pair so later test stages can use them - teststructure.SaveTerraformOptions(e2e.testing, e2e.tempFolder, terraformOptions) - teststructure.SaveEc2KeyPair(e2e.testing, e2e.tempFolder, keyPair) +func (e2e *ZarfE2ETest) setUp() error { - // This will run `terraform init` and `terraform apply` and fail the test if there are any errors - terraform.InitAndApply(e2e.testing, terraformOptions) + // Determine what the name of the zarfBinary should be + e2e.zarfBinPath = path.Join("../../build", getCLIName()) - // Run `terraform output` to get the value of an output variable - e2e.publicIP = terraform.Output(e2e.testing, terraformOptions, "public_instance_ip") - e2e.terraformOptions = terraformOptions - e2e.keyPair = keyPair - - // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", - // as we know the Instance is running an Ubuntu AMI that has such a user - e2e.publicHost = ssh.Host{ - Hostname: e2e.publicIP, - SshKeyPair: e2e.keyPair.KeyPair, - SshUserName: e2e.username, + var err error + // Create or get the kubeconfig + e2e.kubeconfigPath, err = getKubeconfigPath() + if err != nil { + return err } -} -func (e2e *ZarfE2ETest) configureTerraformOptions() (*terraform.Options, *aws.Ec2Keypair, error) { - // A unique ID we can use to namespace resources so we don't clash with anything already in the AWS account or - // tests running in parallel - uniqueID := random.UniqueId() - namespace := "zarf" - stage := "terratest" - name := fmt.Sprintf("e2e-%s", uniqueID) + // Set up a KinD cluster if necessary + e2e.provider = cluster.NewProvider(cluster.ProviderWithLogger(kindcmd.NewLogger())) + nodes, err := e2e.provider.ListNodes(e2e.clusterName) + if len(nodes) > 0 { + // There already is a cluster up!! yay!! + e2e.clusterAlreadyExists = true + } else { + err = e2e.provider.Create( + e2e.clusterName, + cluster.CreateWithNodeImage(""), + cluster.CreateWithRetain(false), + cluster.CreateWithWaitForReady(time.Duration(0)), + cluster.CreateWithKubeconfigPath(e2e.kubeconfigPath), + cluster.CreateWithDisplayUsage(false), + ) + } - // Get the region to use from the system's environment - awsRegion, err := getAwsRegion() + // Get config and client for the k8s cluster + e2e.restConfig, err = clientcmd.BuildConfigFromFlags("", e2e.kubeconfigPath) + if err != nil { + return err + } + e2e.clientset, err = kubernetes.NewForConfig(e2e.restConfig) if err != nil { - return nil, nil, err + return err } - instanceType := "t3a.large" - - // Create an EC2 KeyPair that we can use for SSH access - keyPairName := fmt.Sprintf("%s-%s-%s", namespace, stage, name) - keyPair := aws.CreateAndImportEC2KeyPair(e2e.testing, awsRegion, keyPairName) - - // Construct the terraform options with default retryable errors to handle the most common retryable errors in - // terraform testing. - terraformOptions := terraform.WithDefaultRetryableErrors(e2e.testing, &terraform.Options{ - // The path to where our Terraform code is located - TerraformDir: e2e.tempFolder, - - // Variables to pass to our Terraform code using -var options - Vars: map[string]interface{}{ - "aws_region": awsRegion, - "namespace": namespace, - "stage": stage, - "name": name, - "instance_type": instanceType, - "key_pair_name": keyPairName, - }, - }) - - return terraformOptions, keyPair, nil -} + // Wait for the cluster to have pods before we let the test suite run + // TODO: Pretty sure there's a cleaner way to do this + attempt := 0 + for attempt < 10 { + pods, err := e2e.clientset.CoreV1().Pods("kube-system").List(context.TODO(), metav1.ListOptions{}) + if err == nil && len(pods.Items) >= 0 { + fmt.Printf("💥 Cluster %s ready. You can access it by setting:\nexport KUBECONFIG='%s'\n", e2e.clusterName, e2e.kubeconfigPath) + break + } -// syncFileToRemoteServer uses SCP to sync a file from source to destination. `destPath` can be absolute or relative to -// the SSH user's home directory. It has to be in a directory that the SSH user is allowed to write to. -func (e2e *ZarfE2ETest) syncFileToRemoteServer(srcPath string, destPath string, chmod string) { - // Run `terraform output` to get the value of an output variable - publicInstanceIP := terraform.Output(e2e.testing, e2e.terraformOptions, "public_instance_ip") - - // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", - // as we know the Instance is running an Ubuntu AMI that has such a user - host := ssh.Host{ - Hostname: publicInstanceIP, - SshKeyPair: e2e.keyPair.KeyPair, - SshUserName: e2e.username, + time.Sleep(1 * time.Second) + attempt++ + if attempt > 15 { + return errors.New("unable to connect to KinD cluster for e2e tests") + } } - // It can take a minute or so for the Instance to boot up, so retry a few times - maxRetries := 15 - timeBetweenRetries, err := time.ParseDuration("5s") - require.NoError(e2e.testing, err) + return err +} - // Wait for the instance to be ready - _, err = retry.DoWithRetryE(e2e.testing, "Wait for the instance to be ready", maxRetries, timeBetweenRetries, func() (string, error) { - _, err := ssh.CheckSshCommandE(e2e.testing, host, "whoami") - if err != nil { - return "", err - } - return "", nil - }) - require.NoError(e2e.testing, err) - - // Create the folder structure - output, err := ssh.CheckSshCommandE(e2e.testing, host, fmt.Sprintf("bash -c 'install -m 644 -D /dev/null \"%s\"'", destPath)) - require.NoError(e2e.testing, err, output) - - // The ssh lib only supports sending strings so we'll base64encode it first - f, err := os.Open(srcPath) - require.NoError(e2e.testing, err) - reader := bufio.NewReader(f) - content, err := ioutil.ReadAll(reader) - require.NoError(e2e.testing, err) - encodedContent := base64.StdEncoding.EncodeToString(content) - err = ssh.ScpFileToE(e2e.testing, host, 0600, fmt.Sprintf("%s.b64", destPath), encodedContent) - require.NoError(e2e.testing, err) - output, err = ssh.CheckSshCommandE(e2e.testing, host, fmt.Sprintf("base64 -d \"%s.b64\" > \"%s\" && chmod \"%s\" \"%s\"", destPath, destPath, chmod, destPath)) - require.NoError(e2e.testing, err, output) +func (e2e *ZarfE2ETest) tearDown() error { + // Delete the cluster and kubeconfig file + provider := cluster.NewProvider(cluster.ProviderWithLogger(kindcmd.NewLogger())) + err := provider.Delete(e2e.clusterName, e2e.kubeconfigPath) + os.Remove(e2e.kubeconfigPath) + + return err } -// getAwsRegion returns the desired AWS region to use by first checking the env var AWS_REGION, then checking -// AWS_DEFAULT_REGION if AWS_REGION isn't set. If neither is set it returns an error -func getAwsRegion() (string, error) { - val, present := os.LookupEnv("AWS_REGION") - if !present { - val, present = os.LookupEnv("AWS_DEFAULT_REGION") - } - if !present { - return "", fmt.Errorf("expected either AWS_REGION or AWS_DEFAULT_REGION env var to be set, but they were not") - } else { - return val, nil +func getCLIName() string { + var binaryName string + if runtime.GOOS == "linux" { + binaryName = "zarf" + } else if runtime.GOOS == "darwin" { + if runtime.GOARCH == "arm64" { + binaryName = "zarf-mac-apple" + } else { + binaryName = "zarf-mac-intel" + } } + return binaryName } diff --git a/test/e2e/e2e_data_injection_test.go b/test/e2e/e2e_data_injection_test.go deleted file mode 100644 index f7b6af82ae..0000000000 --- a/test/e2e/e2e_data_injection_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package test - -import ( - "fmt" - "testing" - - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" -) - -func TestDataInjection(t *testing.T) { - - e2e := NewE2ETest(t) - - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) - - // Upload the Zarf artifacts - teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { - e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") - e2e.syncFileToRemoteServer("../../build/zarf-package-data-injection-demo.tar", fmt.Sprintf("/home/%s/build/zarf-package-data-injection-demo.tar", e2e.username), "0600") - }) - - teststructure.RunTestStage(e2e.testing, "TEST", func() { - // run `zarf init` - output, err := e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Deploy the data injection example - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-data-injection-demo.tar --confirm'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Test to confirm the root file was placed - output, err = e2e.runSSHCommand(`sudo bash -c '/usr/sbin/kubectl -n demo exec data-injection -- ls /test | grep this-is-an-example'`) - require.NoError(e2e.testing, err, output) - - // Test to confirm the subdirectory file was placed - output, err = e2e.runSSHCommand(`sudo bash -c '/usr/sbin/kubectl -n demo exec data-injection -- ls /test/subdirectory-test | grep this-is-an-example'`) - require.NoError(e2e.testing, err, output) - }) - -} diff --git a/test/e2e/e2e_example_game_test.go b/test/e2e/e2e_example_game_test.go deleted file mode 100644 index 5a9e3852b5..0000000000 --- a/test/e2e/e2e_example_game_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package test - -import ( - "fmt" - "testing" - "time" - - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" -) - -func TestE2eExampleGame(t *testing.T) { - - e2e := NewE2ETest(t) - - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) - - // Upload the Zarf artifacts - teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { - e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") - e2e.syncFileToRemoteServer("../../build/zarf-package-appliance-demo-multi-games.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-appliance-demo-multi-games.tar.zst", e2e.username), "0600") - }) - - teststructure.RunTestStage(e2e.testing, "TEST", func() { - // Make sure `zarf --help` doesn't error - output, err := e2e.runSSHCommand("sudo /home/%s/build/zarf --help", e2e.username) - require.NoError(e2e.testing, err, output) - - // run `zarf init` - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Deploy the game - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-appliance-demo-multi-games.tar.zst --confirm'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Establish the port-forward into the game service; give the service a few seconds to come up since this is not a command we can retry - time.Sleep(5 * time.Second) - output, err = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect doom --local-port 22333 &> /dev/nul &)'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Right now we're just checking that `curl` returns 0. It can be enhanced by scraping the HTML that gets returned or something. - output, err = e2e.runSSHCommand("bash -c '[[ $(curl -sfSL --retry 15 --retry-connrefused --retry-delay 5 -o /dev/null -w \"%%{http_code}\" 'http://127.0.0.1:22333?doom') == 200 ]]'") - require.NoError(e2e.testing, err, output) - - // Run `zarf destroy` to make sure that works correctly - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf destroy --confirm'", e2e.username) - require.NoError(e2e.testing, err, output) - }) - -} diff --git a/test/e2e/e2e_general_cli_test.go b/test/e2e/e2e_general_cli_test.go index 03659ac76f..df059e2806 100644 --- a/test/e2e/e2e_general_cli_test.go +++ b/test/e2e/e2e_general_cli_test.go @@ -2,91 +2,95 @@ package test import ( "fmt" + "os" + "os/exec" "testing" - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func TestGeneralCli(t *testing.T) { - - e2e := NewE2ETest(t) - - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) - - // Upload the Zarf artifacts - teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { - e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-package-kafka-strimzi-demo.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-kafka-strimzi-demo.tar.zst", e2e.username), "0700") - }) - - teststructure.RunTestStage(e2e.testing, "TEST", func() { - // Test `zarf prepare sha256sum` for a local asset - expectedShasum := "61b50898f982d015ed87093ba822de0fe011cec6dd67db39f99d8c56391a6109\n" - output, err := e2e.runSSHCommand("cd /home/%s/build && echo 'random test data 🦄' > shasum-test-file", e2e.username) - require.NoError(e2e.testing, err, output) - - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf prepare sha256sum shasum-test-file 2> /dev/null", e2e.username) - require.NoError(e2e.testing, err, output) - assert.Equal(e2e.testing, expectedShasum, output, "The expected SHASUM should equal the actual SHASUM") - - // Test `zarf prepare sha256sum` for a remote asset - expectedShasum = "c3cdea0573ba5a058ec090b5d2683bf398e8b1614c37ec81136ed03b78167617\n" - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf prepare sha256sum https://zarf-public.s3-us-gov-west-1.amazonaws.com/pipelines/zarf-prepare-shasum-remote-test-file.txt 2> /dev/null", e2e.username) - require.NoError(e2e.testing, err, output) - assert.Equal(e2e.testing, expectedShasum, output, "The expected SHASUM should equal the actual SHASUM") - - // Test `zarf version` - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf version", e2e.username) - require.NoError(e2e.testing, err, output) - assert.NotNil(e2e.testing, output) - assert.NotEqual(e2e.testing, len(output), 0, "Zarf version should not be an empty string") - assert.NotEqual(e2e.testing, string(output), "UnknownVersion", "Zarf version should not be the default value") - - // Test for expected failure when given a bad component input - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf init --confirm --components k3s,foo,logging", e2e.username) - require.Error(e2e.testing, err, output) - - // Test for expected failure when given invalid hostnames - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf init --confirm --host localhost", e2e.username) - require.Error(e2e.testing, err, output) - - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf pki regenerate --host zarf@server", e2e.username) - require.Error(e2e.testing, err, output) - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf pki regenerate --host some_unique_server", e2e.username) - require.Error(e2e.testing, err, output) - - // Initialize Zarf for the next set of tests - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Verify that we do not timeout when passing the `--confirm` flag without specifying the `--components` flag - output, err = e2e.runSSHCommand("sudo timeout 120 sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-kafka-strimzi-demo.tar.zst --confirm' || false", e2e.username) - require.NoError(e2e.testing, err, output) - - // Test that Zarf checks the $KUBECONFIG env variable - output, err = e2e.runSSHCommand("sudo timeout 120 sudo bash -c 'rm -rf /tmp/zarf-* && mv /root/.kube/config /home/%s/zarf-kube-config && export KUBECONFIG=/home/%s/zarf-kube-config && echo 'JPERRYISSTINKY' && echo $KUBECONFIG && cd /home/%s/build && ./zarf package deploy zarf-package-kafka-strimzi-demo.tar.zst -l trace --confirm' || false", e2e.username, e2e.username, e2e.username) - require.NoError(e2e.testing, err, output) - - // Test that `zarf package deploy` doesn't die when given a URL - // NOTE: Temporarily commenting this out because this seems out of scope for a general cli test. Having this included also means we would have to fully standup a `zarf init` command. - // TODO: Move this to it's own e2e test. - // output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo bash -c 'cd /home/%s/build && ./zarf package deploy https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom.tar.zst --confirm --insecure'", username)) - // require.NoError(t, err, output) - // output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo bash -c 'cd /home/%s/build && ./zarf package deploy https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom.tar.zst --confirm --shasum e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'", username)) - // require.NoError(t, err, output) - - // Test that `zarf package deploy` gives an error if deploying a remote package without the --insecure or --shasum flags - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom-20210125.tar.zst --confirm'", e2e.username) - require.Error(e2e.testing, err, output) - - // Test that changing the log level actually applies the requested level - output, _ = e2e.runSSHCommand("cd /home/%s/build && ./zarf version --log-level warn 1> /dev/null", e2e.username) - expectedOutString := "Log level set to warn" - require.Contains(e2e.testing, output, expectedOutString, "The log level should be changed to 'warn'") - }) +var ( + e2e ZarfE2ETest +) + +// TestMain will exec each test, one by one +func TestMain(m *testing.M) { + // Create a kubeconfig and start up a KinD cluster + err := e2e.setUp() + if err != nil { + fmt.Printf("Unable to setup environment to run the e2e test because of err: %v\n", err) + os.Exit(1) + } + + // exec test and this returns an exit code to pass to os + retCode := m.Run() + + // Unless told to skip, destroy the KinD Cluster and delete the generated kubeconfig + if os.Getenv("SKIP_TEARDOWN") == "" && !e2e.clusterAlreadyExists { + err = e2e.tearDown() + if err != nil { + fmt.Printf("Unable to teardown test environment after completion of tests: %v\n", err) + } + } + + // If exit code is distinct of zero, the test will be failed (red) + os.Exit(retCode) +} + +func TestGeneralCLI(t *testing.T) { + // Test `zarf prepare sha256sum` for a local asset + expectedShasum := "61b50898f982d015ed87093ba822de0fe011cec6dd67db39f99d8c56391a6109\n" + + // TODO: There has to be a better way to pipe this output to the file.. For some reason exec.Command( ... > file ).Output() couldn't pipe to file + // output, err = exec.Command("bash", "-c", "\"echo 'random test data 🦄' > shasum-test-file\"").Output() + shasumTestFilePath := "shasum-test-file" + testfile, _ := os.Create(shasumTestFilePath) + cmd := exec.Command("echo", "random test data 🦄") + cmd.Stdout = testfile + cmd.Run() + + output, err := exec.Command(e2e.zarfBinPath, "prepare", "sha256sum", shasumTestFilePath).Output() + assert.NoError(t, err, output) + assert.Equal(t, expectedShasum, string(output), "The expected SHASUM should equal the actual SHASUM") + os.Remove(shasumTestFilePath) + + // Test `zarf prepare sha256sum` for a remote asset + expectedShasum = "c3cdea0573ba5a058ec090b5d2683bf398e8b1614c37ec81136ed03b78167617\n" + output, err = exec.Command(e2e.zarfBinPath, "prepare", "sha256sum", "https://zarf-public.s3-us-gov-west-1.amazonaws.com/pipelines/zarf-prepare-shasum-remote-test-file.txt").Output() + assert.NoError(t, err, output) + assert.Equal(t, expectedShasum, string(output), "The expected SHASUM should equal the actual SHASUM") + + // Test `zarf version` + output, err = exec.Command(e2e.zarfBinPath, "version").Output() + assert.NoError(t, err) + assert.NotEqual(t, len(output), 0, "Zarf version should not be an empty string") + assert.NotEqual(t, string(output), "UnknownVersion", "Zarf version should not be the default value") + + // Test for expected failure when given a bad componenet input + output, err = exec.Command(e2e.zarfBinPath, "init", "--confirm", "--components=k3s,foo,logging").Output() + assert.Error(t, err) + + // Test for expected failure when given invalid hostnames + output, err = exec.Command(e2e.zarfBinPath, "pki", "regenerate", "--host", "zarf@server").Output() + assert.Error(t, err, output) + output, err = exec.Command(e2e.zarfBinPath, "pki", "regenerate", "--host=some_unique_server").Output() + assert.Error(t, err, output) + + // Test that changing the log level actually applies the requested level + output, _ = exec.Command(e2e.zarfBinPath, "version", "--log-level=warn").CombinedOutput() + expectedOutString := "Log level set to warn" + require.Contains(t, string(output), expectedOutString, "The log level should be changed to 'warn'") +} + +func TestInitZarf(t *testing.T) { + + // Initialize Zarf for the next set of tests + // This also confirms that using the `--confirm` flags does not hang when not also specifying the `--components` flag + output, err := exec.Command(e2e.zarfBinPath, "init", "--confirm").CombinedOutput() + assert.NoError(t, err, string(output)) + // Test that `zarf package deploy` gives an error if deploying a remote package without the --insecure or --shasum flags + output, err = exec.Command(e2e.zarfBinPath, "package", "deploy", "https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom-20210125.tar.zst", "--confirm").Output() + assert.Error(t, err, string(output)) } diff --git a/test/e2e/e2e_gitea_and_grafana_test.go b/test/e2e/e2e_gitea_and_grafana_test.go deleted file mode 100644 index ab77305ff8..0000000000 --- a/test/e2e/e2e_gitea_and_grafana_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package test - -import ( - "fmt" - "testing" - "time" - - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" -) - -func TestGiteaAndGrafana(t *testing.T) { - e2e := NewE2ETest(t) - - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) - - // Upload the Zarf artifacts - teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { - e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") - }) - - teststructure.RunTestStage(e2e.testing, "TEST", func() { - // run `zarf init` - output, err := e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s,logging,gitops-service'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Establish the port-forward into the gitea service; give the service a few seconds to come up since this is not a command we can retry - time.Sleep(15 * time.Second) - _, _ = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect git &> /dev/nul &)'", e2e.username) - - // Make sure Gitea comes up cleanly - output, err = e2e.runSSHCommand(`bash -c '[[ $(curl -sfSL -o /dev/null -w '%%{http_code}' 'http://127.0.0.1:45003/explore/repos') == 200 ]]'`) - require.NoError(e2e.testing, err, output) - - // Establish the port-forward into the logging service - _, _ = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect logging &> /dev/nul &)'", e2e.username) - - // // Make sure Grafana comes up cleanly - output, err = e2e.runSSHCommand(`bash -c '[[ $(curl -sfSL -o /dev/null -w '%%{http_code}' 'http://127.0.0.1:45002/monitor/login') == 200 ]]'`) - require.NoError(e2e.testing, err, output) - }) - -} diff --git a/test/e2e/e2e_gitops_example_test.go b/test/e2e/e2e_gitops_example_test.go deleted file mode 100644 index 6d15e61701..0000000000 --- a/test/e2e/e2e_gitops_example_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package test - -import ( - "fmt" - "testing" - - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" -) - -func TestGitopsExample(t *testing.T) { - e2e := NewE2ETest(t) - - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) - - // Upload the Zarf artifacts - teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { - e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") - e2e.syncFileToRemoteServer("../../build/zarf-package-gitops-service-data.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-gitops-service-data.tar.zst", e2e.username), "0600") - }) - - teststructure.RunTestStage(t, "TEST", func() { - // run `zarf init` - output, err := e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s,logging,gitops-service --host 127.0.0.1'", e2e.username) - require.NoError(t, err, output) - - // Deploy the gitops example - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-gitops-service-data.tar.zst --confirm'", e2e.username) - require.NoError(t, err, output) - - // Create a tunnel to the git resources - output, err = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect git &> /dev/nul &)'", e2e.username) - require.NoError(t, err, output) - - // Check for full git repo mirror(foo.git) from https://github.com/stefanprodan/podinfo.git - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && git clone http://zarf-git-user:$(./zarf tools get-admin-password)@127.0.0.1:45003/zarf-git-user/mirror__github.com__stefanprodan__podinfo.git'", e2e.username) - require.NoError(t, err, output) - - // Check for tagged git repo mirror (foo.git@1.2.3) from https://github.com/defenseunicorns/zarf.git@v0.15.0 - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && git clone http://zarf-git-user:$(./zarf tools get-admin-password)@127.0.0.1:45003/zarf-git-user/mirror__github.com__defenseunicorns__zarf.git'", e2e.username) - require.NoError(t, err, output) - - // Check for correct tag - expectedTag := "v0.15.0\n" - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build/mirror__github.com__defenseunicorns__zarf && git tag'", e2e.username) - require.NoError(t, err, output) - require.Equal(t, expectedTag, output, "Expected tag should match output") - - // Check for correct commits - expectedCommits := "9eb207e\n7636dd0\ne02cec9" - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build/mirror__github.com__defenseunicorns__zarf && git log -3 --oneline --pretty=format:\"%%h\"'", e2e.username) - require.NoError(t, err, output) - require.Equal(t, expectedCommits, output, "Expected commits should match output") - - // Check for existence of tags without specifying them, signifying that not using '@1.2.3' syntax brought over the whole repo - expectedTag = "0.2.2" - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build/mirror__github.com__stefanprodan__podinfo && git tag'", e2e.username) - require.NoError(t, err, output) - require.Contains(t, output, expectedTag, "Output should contain expected tag") - }) -} From 865e70f20bf6949618e0671a7b82492fcf778758 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Wed, 16 Feb 2022 11:58:18 -0500 Subject: [PATCH 02/25] adding the rest of the old e2e tests --- test/e2e/adr.md | 24 +++ test/e2e/common.go | 74 ++++++++ test/e2e/e2e_data_injection_test.go | 51 ++++++ test/e2e/e2e_example_game_test.go | 40 +++++ test/e2e/e2e_general_cli_test.go | 31 +--- test/e2e/e2e_gitea_and_grafana_test.go | 45 +++++ test/e2e/e2e_gitops_example_test.go | 73 ++++++++ test/e2e/main_test.go | 36 ++++ test/old-e2e/common.go | 187 +++++++++++++++++++++ test/old-e2e/e2e_data_injection_test.go | 43 +++++ test/old-e2e/e2e_example_game_test.go | 53 ++++++ test/old-e2e/e2e_general_cli_test.go | 88 ++++++++++ test/old-e2e/e2e_gitea_and_grafana_test.go | 45 +++++ test/old-e2e/e2e_gitops_example_test.go | 63 +++++++ 14 files changed, 824 insertions(+), 29 deletions(-) create mode 100644 test/e2e/adr.md create mode 100644 test/e2e/e2e_data_injection_test.go create mode 100644 test/e2e/e2e_example_game_test.go create mode 100644 test/e2e/e2e_gitea_and_grafana_test.go create mode 100644 test/e2e/e2e_gitops_example_test.go create mode 100644 test/e2e/main_test.go create mode 100644 test/old-e2e/common.go create mode 100644 test/old-e2e/e2e_data_injection_test.go create mode 100644 test/old-e2e/e2e_example_game_test.go create mode 100644 test/old-e2e/e2e_general_cli_test.go create mode 100644 test/old-e2e/e2e_gitea_and_grafana_test.go create mode 100644 test/old-e2e/e2e_gitops_example_test.go diff --git a/test/e2e/adr.md b/test/e2e/adr.md new file mode 100644 index 0000000000..e11864e89e --- /dev/null +++ b/test/e2e/adr.md @@ -0,0 +1,24 @@ +# Zarf E2E Approach ADR + +This is the template in [Documenting architecture decisions - Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions). +You can use [adr-tools](https://github.com/npryce/adr-tools) for managing the ADR files. + +In each ADR file, write these sections: + +# Title + +## Status + +What is the status, such as proposed, accepted, rejected, deprecated, superseded, etc.? + +## Context + +What is the issue that we're seeing that is motivating this decision or change? + +## Decision + +What is the change that we're proposing and/or doing? + +## Consequences + +What becomes easier or more difficult to do because of this change? diff --git a/test/e2e/common.go b/test/e2e/common.go index dda89c7093..8cbea77c2b 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -5,14 +5,21 @@ import ( "errors" "fmt" "os" + "os/exec" "path" "runtime" + "strings" + "testing" "time" + "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" restclient "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/tools/remotecommand" "sigs.k8s.io/kind/pkg/cluster" kindcmd "sigs.k8s.io/kind/pkg/cmd" ) @@ -22,6 +29,8 @@ type ZarfE2ETest struct { clusterName string `default: "test-cluster"` kubeconfigPath string + filesToRemove []string + cmdsToKill []*exec.Cmd kubeconfig *os.File provider *cluster.Provider restConfig *restclient.Config @@ -134,3 +143,68 @@ func getCLIName() string { } return binaryName } + +func (e2e *ZarfE2ETest) cleanupAfterTest(t *testing.T) { + fmt.Println("Test is finished, cleaning up now") + + // Use Zarf to perform chart uninstallation + _, err := exec.Command(e2e.zarfBinPath, "destroy", "--confirm", "--remove-components", "-l=trace").CombinedOutput() + require.NoError(t, err, "unable to destroy the zarf cluster when cleaning up after a test") + + // Remove files created for the test + for _, filePath := range e2e.filesToRemove { + err = os.RemoveAll(filePath) + require.NoError(t, err, "unable to remove file when cleaning up after a test") + } + e2e.filesToRemove = []string{} + + // Kill background processes spawned during the test + for _, cmd := range e2e.cmdsToKill { + if cmd.Process != nil { + err = cmd.Process.Kill() + require.NoError(t, err, "unable to kill background cmd when cleaning up after a test") + } + } + e2e.cmdsToKill = []*exec.Cmd{} + + fmt.Println("sleeping for 10 seconds after clean up.. for reasons..") + time.Sleep(10 * time.Second) + fmt.Println("done sleeping!") + +} + +func (e2e *ZarfE2ETest) execCommandInPod(podname, namespace string, cmd []string) (string, string, error) { + stdoutBuffer := &strings.Builder{} + stderrBuffer := &strings.Builder{} + + req := e2e.clientset.CoreV1().RESTClient().Post().Resource("pods").Name(podname).Namespace(namespace).SubResource("exec") + option := &v1.PodExecOptions{ + Command: cmd, + Stdin: true, + Stdout: true, + Stderr: true, + TTY: true, + } + req.VersionedParams(option, scheme.ParameterCodec) + + exec, err := remotecommand.NewSPDYExecutor(e2e.restConfig, "POST", req.URL()) + if err != nil { + fmt.Println("@JPERRY something was broken with the spdy executor...") + return "", "", err + } + + err = exec.Stream(remotecommand.StreamOptions{ + Stdin: os.Stdin, + Stdout: stdoutBuffer, + Stderr: stderrBuffer, + }) + + return stdoutBuffer.String(), stderrBuffer.String(), err +} + +func (e2e *ZarfE2ETest) execZarfCommand(commandString ...string) error { + cmd := exec.Command(e2e.zarfBinPath, commandString...) + // cmd.Stdout = os.Stdout + // cmd.Stderr = os.Stderr + return cmd.Run() +} diff --git a/test/e2e/e2e_data_injection_test.go b/test/e2e/e2e_data_injection_test.go new file mode 100644 index 0000000000..df26a25a85 --- /dev/null +++ b/test/e2e/e2e_data_injection_test.go @@ -0,0 +1,51 @@ +package test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestDataInjection(t *testing.T) { + + // run `zarf init` + err := e2e.execZarfCommand("init", "--confirm", "-l=trace") + // output, err := exec.Command(e2e.zarfBinPath, "init", "--confirm", "-l=trace").CombinedOutput() + assert.NoError(t, err, "unable to init") + + // Deploy the data injection example + err = e2e.execZarfCommand("package", "deploy", "../../build/zarf-package-data-injection-demo.tar", "--confirm", "-l=trace") + // output, err = exec.Command(e2e.zarfBinPath, "package", "deploy", "../../build/zarf-package-data-injection-demo.tar", "--confirm", "-l=trace").CombinedOutput() + assert.NoError(t, err, "unable to deploy data-injection package") + + // time.Sleep(5 * time.Second) + + // Test to confirm the root file was placed + var execStdOut string + // var execStdErr string + attempt := 0 + for attempt < 5 && execStdOut == "" { + execStdOut, _, err = e2e.execCommandInPod("data-injection", "demo", []string{"ls", "/test"}) + attempt++ + // fmt.Printf("stdout after %v attempts: %v\n", attempt, execStdOut) + time.Sleep(2 * time.Second) + } + assert.NoError(t, err) + assert.Contains(t, execStdOut, "subdirectory-test") + + attempt = 0 + execStdOut = "" + + // Test to confirm the subdirectory file was placed + for attempt < 5 && execStdOut == "" { + execStdOut, _, err = e2e.execCommandInPod("data-injection", "demo", []string{"ls", "/test/subdirectory-test"}) + attempt++ + // fmt.Printf("stdout after %v attempts: %v\n", attempt, execStdOut) + time.Sleep(2 * time.Second) + } + assert.NoError(t, err) + assert.Contains(t, execStdOut, "this-is-an-example-file.txt") + + e2e.cleanupAfterTest(t) +} diff --git a/test/e2e/e2e_example_game_test.go b/test/e2e/e2e_example_game_test.go new file mode 100644 index 0000000000..754821dab7 --- /dev/null +++ b/test/e2e/e2e_example_game_test.go @@ -0,0 +1,40 @@ +package test + +import ( + "net/http" + "os/exec" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestE2eExampleGame(t *testing.T) { + + //run `zarf init` + output, err := exec.Command(e2e.zarfBinPath, "init", "--confirm").CombinedOutput() + assert.NoError(t, err, string(output)) + + // Deploy the game + output, err = exec.Command(e2e.zarfBinPath, "package", "deploy", "../../build/zarf-package-appliance-demo-multi-games.tar.zst", "--confirm").CombinedOutput() + assert.NoError(t, err, string(output)) + + // Establish the port-forward into the game service + cmd := exec.Command(e2e.zarfBinPath, "connect", "doom", "--local-port=22333") + e2e.cmdsToKill = append(e2e.cmdsToKill, cmd) + err = cmd.Start() + assert.NoError(t, err, "unable to connect to the doom port-forward") + + // Give the port-forward a second to establish. + // Since the `connect` command gets executed in the background, it can take a few milliseconds for the tunnel to be created + time.Sleep(1 * time.Second) + + // Check that 'curl' returns something. + // Right now we're just checking that `curl` returns 0. It can be enhanced by scraping the HTML that gets returned or something. + resp, err := http.Get("http://127.0.0.1:22333?doom") + assert.NoError(t, err, resp) + assert.Equal(t, 200, resp.StatusCode) + + // Clean up after this test (incase other tests cases will be run afterwards) + e2e.cleanupAfterTest(t) +} diff --git a/test/e2e/e2e_general_cli_test.go b/test/e2e/e2e_general_cli_test.go index df059e2806..a407ca570e 100644 --- a/test/e2e/e2e_general_cli_test.go +++ b/test/e2e/e2e_general_cli_test.go @@ -1,7 +1,6 @@ package test import ( - "fmt" "os" "os/exec" "testing" @@ -10,34 +9,6 @@ import ( "github.com/stretchr/testify/require" ) -var ( - e2e ZarfE2ETest -) - -// TestMain will exec each test, one by one -func TestMain(m *testing.M) { - // Create a kubeconfig and start up a KinD cluster - err := e2e.setUp() - if err != nil { - fmt.Printf("Unable to setup environment to run the e2e test because of err: %v\n", err) - os.Exit(1) - } - - // exec test and this returns an exit code to pass to os - retCode := m.Run() - - // Unless told to skip, destroy the KinD Cluster and delete the generated kubeconfig - if os.Getenv("SKIP_TEARDOWN") == "" && !e2e.clusterAlreadyExists { - err = e2e.tearDown() - if err != nil { - fmt.Printf("Unable to teardown test environment after completion of tests: %v\n", err) - } - } - - // If exit code is distinct of zero, the test will be failed (red) - os.Exit(retCode) -} - func TestGeneralCLI(t *testing.T) { // Test `zarf prepare sha256sum` for a local asset expectedShasum := "61b50898f982d015ed87093ba822de0fe011cec6dd67db39f99d8c56391a6109\n" @@ -93,4 +64,6 @@ func TestInitZarf(t *testing.T) { // Test that `zarf package deploy` gives an error if deploying a remote package without the --insecure or --shasum flags output, err = exec.Command(e2e.zarfBinPath, "package", "deploy", "https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom-20210125.tar.zst", "--confirm").Output() assert.Error(t, err, string(output)) + + e2e.cleanupAfterTest(t) } diff --git a/test/e2e/e2e_gitea_and_grafana_test.go b/test/e2e/e2e_gitea_and_grafana_test.go new file mode 100644 index 0000000000..2e4b5c5e1f --- /dev/null +++ b/test/e2e/e2e_gitea_and_grafana_test.go @@ -0,0 +1,45 @@ +package test + +import ( + "net/http" + "os/exec" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSomething(t *testing.T) { + + // run `zarf init` + output, err := exec.Command(e2e.zarfBinPath, "init", "--components=gitops-service,logging", "--confirm").CombinedOutput() + require.NoError(t, err, string(output)) + + // Establish the port-forward into the gitea service; give the service a few seconds to come up since this is not a command we can retry + time.Sleep(5 * time.Second) + tunnelCmd := exec.Command(e2e.zarfBinPath, "connect", "git") + err = tunnelCmd.Start() + require.NoError(t, err, "unable to establish tunnel to git") + e2e.cmdsToKill = append(e2e.cmdsToKill, tunnelCmd) + time.Sleep(1 * time.Second) + + // Make sure Gitea comes up cleanly + resp, err := http.Get("http://127.0.0.1:45003/explore/repos") + require.NoError(t, err) + assert.Equal(t, 200, resp.StatusCode) + + // Establish the port-forward into the logging service + tunnelCmd = exec.Command(e2e.zarfBinPath, "connect", "logging") + err = tunnelCmd.Start() + require.NoError(t, err, "unable to establish tunnel to logging") + e2e.cmdsToKill = append(e2e.cmdsToKill, tunnelCmd) + time.Sleep(1 * time.Second) + + // Make sure Grafana comes up cleanly + resp, err = http.Get("http://127.0.0.1:45002/monitor/login") + require.NoError(t, err) + assert.Equal(t, 200, resp.StatusCode) + + e2e.cleanupAfterTest(t) +} diff --git a/test/e2e/e2e_gitops_example_test.go b/test/e2e/e2e_gitops_example_test.go new file mode 100644 index 0000000000..744584dfae --- /dev/null +++ b/test/e2e/e2e_gitops_example_test.go @@ -0,0 +1,73 @@ +package test + +import ( + "fmt" + "os" + "os/exec" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGitopsExample(t *testing.T) { + // run `zarf init` + output, err := exec.Command(e2e.zarfBinPath, "init", "--confirm", "--components=gitops-service").CombinedOutput() + require.NoError(t, err, string(output)) + + // Deploy the gitops example + output, err = exec.Command(e2e.zarfBinPath, "package", "deploy", "../../build/zarf-package-gitops-service-data.tar.zst", "--confirm").CombinedOutput() + require.NoError(t, err, string(output)) + + time.Sleep(5 * time.Second) + + // Create a tunnel to the git resources + tunnelCmd := exec.Command(e2e.zarfBinPath, "connect", "git") + err = tunnelCmd.Start() + require.NoError(t, err, "unable to establish tunnel to git") + e2e.cmdsToKill = append(e2e.cmdsToKill, tunnelCmd) + time.Sleep(1 * time.Second) + + // Check for full git repo mirror (foo.git) from https://github.com/stefanprodan/podinfo.git + adminPassword, err := exec.Command(e2e.zarfBinPath, "tools", "get-admin-password").Output() + require.NoError(t, err, "Unable to get admin password for gitea instance") + + cloneCommand := fmt.Sprintf("http://zarf-git-user:%s@127.0.0.1:45003/zarf-git-user/mirror__github.com__stefanprodan__podinfo.git", strings.TrimSpace(string(adminPassword))) + output, err = exec.Command("git", "clone", cloneCommand).CombinedOutput() + require.NoError(t, err, string(output)) + e2e.filesToRemove = append(e2e.filesToRemove, "mirror__github.com__stefanprodan__podinfo") + + // Check for tagged git repo mirror (foo.git@1.2.3) from https://github.com/defenseunicorns/zarf.git@v0.15.0 + cloneCommand = fmt.Sprintf("http://zarf-git-user:%s@127.0.0.1:45003/zarf-git-user/mirror__github.com__defenseunicorns__zarf.git", strings.TrimSpace(string(adminPassword))) + output, err = exec.Command("git", "clone", cloneCommand).CombinedOutput() + require.NoError(t, err, string(output)) + e2e.filesToRemove = append(e2e.filesToRemove, "mirror__github.com__defenseunicorns__zarf") + + // Check for correct tag + expectedTag := "v0.15.0\n" + err = os.Chdir("mirror__github.com__defenseunicorns__zarf") + require.NoError(t, err) + output, err = exec.Command("git", "tag").Output() + assert.Equal(t, expectedTag, string(output), "Expected tag should match output") + + // Check for correct commits + expectedCommits := "9eb207e\n7636dd0\ne02cec9" + output, err = exec.Command("git", "log", "-3", "--oneline", "--pretty=format:%h").CombinedOutput() + require.NoError(t, err, string(output)) + assert.Equal(t, expectedCommits, string(output), "Expected commits should match output") + + // Check for existence of tags without specifying them, signifying that not using '@1.2.3' syntax brought over the whole repo + expectedTag = "0.2.2" + err = os.Chdir("../mirror__github.com__stefanprodan__podinfo") + require.NoError(t, err) + output, err = exec.Command("git", "tag").CombinedOutput() + require.NoError(t, err, string(output)) + assert.Contains(t, string(output), expectedTag) + + err = os.Chdir("..") + require.NoError(t, err, "unable to change directories back to blah blah blah") + + e2e.cleanupAfterTest(t) +} diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go new file mode 100644 index 0000000000..ffa504ee47 --- /dev/null +++ b/test/e2e/main_test.go @@ -0,0 +1,36 @@ +package test + +import ( + "fmt" + "os" + "testing" +) + +var ( + e2e ZarfE2ETest +) + +// TestMain will exec each test, one by one +func TestMain(m *testing.M) { + // Create a kubeconfig and start up a KinD cluster + err := e2e.setUp() + if err != nil { + fmt.Printf("Unable to setup environment to run the e2e test because of err: %v\n", err) + os.Exit(1) + } + + // exec test and this returns an exit code to pass to os + retCode := m.Run() + + // Unless told to skip, destroy the KinD Cluster and delete the generated kubeconfig + // TODO: Should add some defer logic here so that this gets executed even if there is a fatal error in the tests + if os.Getenv("SKIP_TEARDOWN") == "" && !e2e.clusterAlreadyExists { + err = e2e.tearDown() + if err != nil { + fmt.Printf("Unable to teardown test environment after completion of tests: %v\n", err) + } + } + + // If exit code is distinct of zero, the test will be failed (red) + os.Exit(retCode) +} diff --git a/test/old-e2e/common.go b/test/old-e2e/common.go new file mode 100644 index 0000000000..2949ce959c --- /dev/null +++ b/test/old-e2e/common.go @@ -0,0 +1,187 @@ +package test + +import ( + "bufio" + "encoding/base64" + "fmt" + "github.com/gruntwork-io/terratest/modules/random" + "github.com/gruntwork-io/terratest/modules/retry" + teststructure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/require" + "io/ioutil" + "os" + "testing" + "time" + + "github.com/gruntwork-io/terratest/modules/aws" + "github.com/gruntwork-io/terratest/modules/ssh" + "github.com/gruntwork-io/terratest/modules/terraform" +) + +type ZarfE2ETest struct { + testing *testing.T + tempFolder string + username string + terraformOptions *terraform.Options + keyPair *aws.Ec2Keypair + publicIP string + publicHost ssh.Host +} + +func NewE2ETest(testing *testing.T) *ZarfE2ETest { + + testing.Parallel() + + // Copy the terraform folder to a temp directory so we can run multiple tests in parallel + tempFolder := teststructure.CopyTerraformFolderToTemp(testing, "..", "tf/public-ec2-instance") + + e2e := ZarfE2ETest{ + testing: testing, + tempFolder: tempFolder, + // Our SSH username, will change based on which AMI we use + username: "ubuntu", + } + + // Deploy the terraform infra + teststructure.RunTestStage(testing, "SETUP", e2e.setup) + + return &e2e +} + +func (e2e *ZarfE2ETest) runSSHCommand(format string, a ...interface{}) (string, error) { + command := fmt.Sprintf(format, a...) + return ssh.CheckSshCommandE(e2e.testing, e2e.publicHost, command) +} + +func (e2e *ZarfE2ETest) teardown() { + keyPair := teststructure.LoadEc2KeyPair(e2e.testing, e2e.tempFolder) + aws.DeleteEC2KeyPair(e2e.testing, keyPair) + + terraformOptions := teststructure.LoadTerraformOptions(e2e.testing, e2e.tempFolder) + terraform.Destroy(e2e.testing, terraformOptions) +} + +func (e2e *ZarfE2ETest) setup() { + terraformOptions, keyPair, err := e2e.configureTerraformOptions() + require.NoError(e2e.testing, err) + + // Save the options and key pair so later test stages can use them + teststructure.SaveTerraformOptions(e2e.testing, e2e.tempFolder, terraformOptions) + teststructure.SaveEc2KeyPair(e2e.testing, e2e.tempFolder, keyPair) + + // This will run `terraform init` and `terraform apply` and fail the test if there are any errors + terraform.InitAndApply(e2e.testing, terraformOptions) + + // Run `terraform output` to get the value of an output variable + e2e.publicIP = terraform.Output(e2e.testing, terraformOptions, "public_instance_ip") + e2e.terraformOptions = terraformOptions + e2e.keyPair = keyPair + + // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", + // as we know the Instance is running an Ubuntu AMI that has such a user + e2e.publicHost = ssh.Host{ + Hostname: e2e.publicIP, + SshKeyPair: e2e.keyPair.KeyPair, + SshUserName: e2e.username, + } +} + +func (e2e *ZarfE2ETest) configureTerraformOptions() (*terraform.Options, *aws.Ec2Keypair, error) { + // A unique ID we can use to namespace resources so we don't clash with anything already in the AWS account or + // tests running in parallel + uniqueID := random.UniqueId() + namespace := "zarf" + stage := "terratest" + name := fmt.Sprintf("e2e-%s", uniqueID) + + // Get the region to use from the system's environment + awsRegion, err := getAwsRegion() + if err != nil { + return nil, nil, err + } + + instanceType := "t3a.large" + + // Create an EC2 KeyPair that we can use for SSH access + keyPairName := fmt.Sprintf("%s-%s-%s", namespace, stage, name) + keyPair := aws.CreateAndImportEC2KeyPair(e2e.testing, awsRegion, keyPairName) + + // Construct the terraform options with default retryable errors to handle the most common retryable errors in + // terraform testing. + terraformOptions := terraform.WithDefaultRetryableErrors(e2e.testing, &terraform.Options{ + // The path to where our Terraform code is located + TerraformDir: e2e.tempFolder, + + // Variables to pass to our Terraform code using -var options + Vars: map[string]interface{}{ + "aws_region": awsRegion, + "namespace": namespace, + "stage": stage, + "name": name, + "instance_type": instanceType, + "key_pair_name": keyPairName, + }, + }) + + return terraformOptions, keyPair, nil +} + +// syncFileToRemoteServer uses SCP to sync a file from source to destination. `destPath` can be absolute or relative to +// the SSH user's home directory. It has to be in a directory that the SSH user is allowed to write to. +func (e2e *ZarfE2ETest) syncFileToRemoteServer(srcPath string, destPath string, chmod string) { + // Run `terraform output` to get the value of an output variable + publicInstanceIP := terraform.Output(e2e.testing, e2e.terraformOptions, "public_instance_ip") + + // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", + // as we know the Instance is running an Ubuntu AMI that has such a user + host := ssh.Host{ + Hostname: publicInstanceIP, + SshKeyPair: e2e.keyPair.KeyPair, + SshUserName: e2e.username, + } + + // It can take a minute or so for the Instance to boot up, so retry a few times + maxRetries := 15 + timeBetweenRetries, err := time.ParseDuration("5s") + require.NoError(e2e.testing, err) + + // Wait for the instance to be ready + _, err = retry.DoWithRetryE(e2e.testing, "Wait for the instance to be ready", maxRetries, timeBetweenRetries, func() (string, error) { + _, err := ssh.CheckSshCommandE(e2e.testing, host, "whoami") + if err != nil { + return "", err + } + return "", nil + }) + require.NoError(e2e.testing, err) + + // Create the folder structure + output, err := ssh.CheckSshCommandE(e2e.testing, host, fmt.Sprintf("bash -c 'install -m 644 -D /dev/null \"%s\"'", destPath)) + require.NoError(e2e.testing, err, output) + + // The ssh lib only supports sending strings so we'll base64encode it first + f, err := os.Open(srcPath) + require.NoError(e2e.testing, err) + reader := bufio.NewReader(f) + content, err := ioutil.ReadAll(reader) + require.NoError(e2e.testing, err) + encodedContent := base64.StdEncoding.EncodeToString(content) + err = ssh.ScpFileToE(e2e.testing, host, 0600, fmt.Sprintf("%s.b64", destPath), encodedContent) + require.NoError(e2e.testing, err) + output, err = ssh.CheckSshCommandE(e2e.testing, host, fmt.Sprintf("base64 -d \"%s.b64\" > \"%s\" && chmod \"%s\" \"%s\"", destPath, destPath, chmod, destPath)) + require.NoError(e2e.testing, err, output) +} + +// getAwsRegion returns the desired AWS region to use by first checking the env var AWS_REGION, then checking +// AWS_DEFAULT_REGION if AWS_REGION isn't set. If neither is set it returns an error +func getAwsRegion() (string, error) { + val, present := os.LookupEnv("AWS_REGION") + if !present { + val, present = os.LookupEnv("AWS_DEFAULT_REGION") + } + if !present { + return "", fmt.Errorf("expected either AWS_REGION or AWS_DEFAULT_REGION env var to be set, but they were not") + } else { + return val, nil + } +} diff --git a/test/old-e2e/e2e_data_injection_test.go b/test/old-e2e/e2e_data_injection_test.go new file mode 100644 index 0000000000..f7b6af82ae --- /dev/null +++ b/test/old-e2e/e2e_data_injection_test.go @@ -0,0 +1,43 @@ +package test + +import ( + "fmt" + "testing" + + teststructure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/require" +) + +func TestDataInjection(t *testing.T) { + + e2e := NewE2ETest(t) + + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) + + // Upload the Zarf artifacts + teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { + e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") + e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") + e2e.syncFileToRemoteServer("../../build/zarf-package-data-injection-demo.tar", fmt.Sprintf("/home/%s/build/zarf-package-data-injection-demo.tar", e2e.username), "0600") + }) + + teststructure.RunTestStage(e2e.testing, "TEST", func() { + // run `zarf init` + output, err := e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s'", e2e.username) + require.NoError(e2e.testing, err, output) + + // Deploy the data injection example + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-data-injection-demo.tar --confirm'", e2e.username) + require.NoError(e2e.testing, err, output) + + // Test to confirm the root file was placed + output, err = e2e.runSSHCommand(`sudo bash -c '/usr/sbin/kubectl -n demo exec data-injection -- ls /test | grep this-is-an-example'`) + require.NoError(e2e.testing, err, output) + + // Test to confirm the subdirectory file was placed + output, err = e2e.runSSHCommand(`sudo bash -c '/usr/sbin/kubectl -n demo exec data-injection -- ls /test/subdirectory-test | grep this-is-an-example'`) + require.NoError(e2e.testing, err, output) + }) + +} diff --git a/test/old-e2e/e2e_example_game_test.go b/test/old-e2e/e2e_example_game_test.go new file mode 100644 index 0000000000..5a9e3852b5 --- /dev/null +++ b/test/old-e2e/e2e_example_game_test.go @@ -0,0 +1,53 @@ +package test + +import ( + "fmt" + "testing" + "time" + + teststructure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/require" +) + +func TestE2eExampleGame(t *testing.T) { + + e2e := NewE2ETest(t) + + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) + + // Upload the Zarf artifacts + teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { + e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") + e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") + e2e.syncFileToRemoteServer("../../build/zarf-package-appliance-demo-multi-games.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-appliance-demo-multi-games.tar.zst", e2e.username), "0600") + }) + + teststructure.RunTestStage(e2e.testing, "TEST", func() { + // Make sure `zarf --help` doesn't error + output, err := e2e.runSSHCommand("sudo /home/%s/build/zarf --help", e2e.username) + require.NoError(e2e.testing, err, output) + + // run `zarf init` + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s'", e2e.username) + require.NoError(e2e.testing, err, output) + + // Deploy the game + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-appliance-demo-multi-games.tar.zst --confirm'", e2e.username) + require.NoError(e2e.testing, err, output) + + // Establish the port-forward into the game service; give the service a few seconds to come up since this is not a command we can retry + time.Sleep(5 * time.Second) + output, err = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect doom --local-port 22333 &> /dev/nul &)'", e2e.username) + require.NoError(e2e.testing, err, output) + + // Right now we're just checking that `curl` returns 0. It can be enhanced by scraping the HTML that gets returned or something. + output, err = e2e.runSSHCommand("bash -c '[[ $(curl -sfSL --retry 15 --retry-connrefused --retry-delay 5 -o /dev/null -w \"%%{http_code}\" 'http://127.0.0.1:22333?doom') == 200 ]]'") + require.NoError(e2e.testing, err, output) + + // Run `zarf destroy` to make sure that works correctly + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf destroy --confirm'", e2e.username) + require.NoError(e2e.testing, err, output) + }) + +} diff --git a/test/old-e2e/e2e_general_cli_test.go b/test/old-e2e/e2e_general_cli_test.go new file mode 100644 index 0000000000..74afbe1316 --- /dev/null +++ b/test/old-e2e/e2e_general_cli_test.go @@ -0,0 +1,88 @@ +package test + +import ( + "fmt" + "testing" + + teststructure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGeneralCli(t *testing.T) { + + e2e := NewE2ETest(t) + + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) + + // Upload the Zarf artifacts + teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { + e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") + e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0700") + e2e.syncFileToRemoteServer("../../build/zarf-package-kafka-strimzi-demo.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-kafka-strimzi-demo.tar.zst", e2e.username), "0700") + }) + + teststructure.RunTestStage(e2e.testing, "TEST", func() { + // Test `zarf prepare sha256sum` for a local asset + expectedShasum := "61b50898f982d015ed87093ba822de0fe011cec6dd67db39f99d8c56391a6109\n" + output, err := e2e.runSSHCommand("cd /home/%s/build && echo 'random test data 🦄' > shasum-test-file", e2e.username) + require.NoError(e2e.testing, err, output) + + output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf prepare sha256sum shasum-test-file 2> /dev/null", e2e.username) + require.NoError(e2e.testing, err, output) + assert.Equal(e2e.testing, expectedShasum, output, "The expected SHASUM should equal the actual SHASUM") + + // Test `zarf prepare sha256sum` for a remote asset + expectedShasum = "c3cdea0573ba5a058ec090b5d2683bf398e8b1614c37ec81136ed03b78167617\n" + output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf prepare sha256sum https://zarf-public.s3-us-gov-west-1.amazonaws.com/pipelines/zarf-prepare-shasum-remote-test-file.txt 2> /dev/null", e2e.username) + require.NoError(e2e.testing, err, output) + assert.Equal(e2e.testing, expectedShasum, output, "The expected SHASUM should equal the actual SHASUM") + + // Test `zarf version` + output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf version", e2e.username) + require.NoError(e2e.testing, err, output) + assert.NotNil(e2e.testing, output) + assert.NotEqual(e2e.testing, len(output), 0, "Zarf version should not be an empty string") + assert.NotEqual(e2e.testing, string(output), "UnknownVersion", "Zarf version should not be the default value") + + // Test for expected failure when given a bad component input + output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf init --confirm --components k3s,foo,logging", e2e.username) + require.Error(e2e.testing, err, output) + + // Test for expected failure when given invalid hostnames + output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf init --confirm --host localhost", e2e.username) + require.Error(e2e.testing, err, output) + + output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf pki regenerate --host zarf@server", e2e.username) + require.Error(e2e.testing, err, output) + output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf pki regenerate --host some_unique_server", e2e.username) + require.Error(e2e.testing, err, output) + + // Initialize Zarf for the next set of tests + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s'", e2e.username) + require.NoError(e2e.testing, err, output) + + // Verify that we do not timeout when passing the `--confirm` flag without specifying the `--components` flag + output, err = e2e.runSSHCommand("sudo timeout 120 sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-kafka-strimzi-demo.tar.zst --confirm' || false", e2e.username) + require.NoError(e2e.testing, err, output) + + // Test that `zarf package deploy` doesn't die when given a URL + // NOTE: Temporarily commenting this out because this seems out of scope for a general cli test. Having this included also means we would have to fully standup a `zarf init` command. + // TODO: Move this to it's own e2e test. + // output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo bash -c 'cd /home/%s/build && ./zarf package deploy https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom.tar.zst --confirm --insecure'", username)) + // require.NoError(t, err, output) + // output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo bash -c 'cd /home/%s/build && ./zarf package deploy https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom.tar.zst --confirm --shasum e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'", username)) + // require.NoError(t, err, output) + + // Test that `zarf package deploy` gives an error if deploying a remote package without the --insecure or --shasum flags + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom-20210125.tar.zst --confirm'", e2e.username) + require.Error(e2e.testing, err, output) + + // Test that changing the log level actually applies the requested level + output, _ = e2e.runSSHCommand("cd /home/%s/build && ./zarf version --log-level warn 1> /dev/null", e2e.username) + expectedOutString := "Log level set to warn" + require.Contains(e2e.testing, output, expectedOutString, "The log level should be changed to 'warn'") + }) + +} diff --git a/test/old-e2e/e2e_gitea_and_grafana_test.go b/test/old-e2e/e2e_gitea_and_grafana_test.go new file mode 100644 index 0000000000..ab77305ff8 --- /dev/null +++ b/test/old-e2e/e2e_gitea_and_grafana_test.go @@ -0,0 +1,45 @@ +package test + +import ( + "fmt" + "testing" + "time" + + teststructure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/require" +) + +func TestGiteaAndGrafana(t *testing.T) { + e2e := NewE2ETest(t) + + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) + + // Upload the Zarf artifacts + teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { + e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") + e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") + }) + + teststructure.RunTestStage(e2e.testing, "TEST", func() { + // run `zarf init` + output, err := e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s,logging,gitops-service'", e2e.username) + require.NoError(e2e.testing, err, output) + + // Establish the port-forward into the gitea service; give the service a few seconds to come up since this is not a command we can retry + time.Sleep(15 * time.Second) + _, _ = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect git &> /dev/nul &)'", e2e.username) + + // Make sure Gitea comes up cleanly + output, err = e2e.runSSHCommand(`bash -c '[[ $(curl -sfSL -o /dev/null -w '%%{http_code}' 'http://127.0.0.1:45003/explore/repos') == 200 ]]'`) + require.NoError(e2e.testing, err, output) + + // Establish the port-forward into the logging service + _, _ = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect logging &> /dev/nul &)'", e2e.username) + + // // Make sure Grafana comes up cleanly + output, err = e2e.runSSHCommand(`bash -c '[[ $(curl -sfSL -o /dev/null -w '%%{http_code}' 'http://127.0.0.1:45002/monitor/login') == 200 ]]'`) + require.NoError(e2e.testing, err, output) + }) + +} diff --git a/test/old-e2e/e2e_gitops_example_test.go b/test/old-e2e/e2e_gitops_example_test.go new file mode 100644 index 0000000000..6d15e61701 --- /dev/null +++ b/test/old-e2e/e2e_gitops_example_test.go @@ -0,0 +1,63 @@ +package test + +import ( + "fmt" + "testing" + + teststructure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/require" +) + +func TestGitopsExample(t *testing.T) { + e2e := NewE2ETest(t) + + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) + + // Upload the Zarf artifacts + teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { + e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") + e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") + e2e.syncFileToRemoteServer("../../build/zarf-package-gitops-service-data.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-gitops-service-data.tar.zst", e2e.username), "0600") + }) + + teststructure.RunTestStage(t, "TEST", func() { + // run `zarf init` + output, err := e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s,logging,gitops-service --host 127.0.0.1'", e2e.username) + require.NoError(t, err, output) + + // Deploy the gitops example + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-gitops-service-data.tar.zst --confirm'", e2e.username) + require.NoError(t, err, output) + + // Create a tunnel to the git resources + output, err = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect git &> /dev/nul &)'", e2e.username) + require.NoError(t, err, output) + + // Check for full git repo mirror(foo.git) from https://github.com/stefanprodan/podinfo.git + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && git clone http://zarf-git-user:$(./zarf tools get-admin-password)@127.0.0.1:45003/zarf-git-user/mirror__github.com__stefanprodan__podinfo.git'", e2e.username) + require.NoError(t, err, output) + + // Check for tagged git repo mirror (foo.git@1.2.3) from https://github.com/defenseunicorns/zarf.git@v0.15.0 + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && git clone http://zarf-git-user:$(./zarf tools get-admin-password)@127.0.0.1:45003/zarf-git-user/mirror__github.com__defenseunicorns__zarf.git'", e2e.username) + require.NoError(t, err, output) + + // Check for correct tag + expectedTag := "v0.15.0\n" + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build/mirror__github.com__defenseunicorns__zarf && git tag'", e2e.username) + require.NoError(t, err, output) + require.Equal(t, expectedTag, output, "Expected tag should match output") + + // Check for correct commits + expectedCommits := "9eb207e\n7636dd0\ne02cec9" + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build/mirror__github.com__defenseunicorns__zarf && git log -3 --oneline --pretty=format:\"%%h\"'", e2e.username) + require.NoError(t, err, output) + require.Equal(t, expectedCommits, output, "Expected commits should match output") + + // Check for existence of tags without specifying them, signifying that not using '@1.2.3' syntax brought over the whole repo + expectedTag = "0.2.2" + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build/mirror__github.com__stefanprodan__podinfo && git tag'", e2e.username) + require.NoError(t, err, output) + require.Contains(t, output, expectedTag, "Output should contain expected tag") + }) +} From a439a6a4026a168195a8de47b4f324a812ca96cf Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Thu, 17 Feb 2022 21:31:43 -0500 Subject: [PATCH 03/25] wip: cleaning up tests --- Makefile | 2 +- test/e2e/e2e_data_injection_test.go | 17 +++------ test/e2e/e2e_example_game_test.go | 21 ++++------- test/e2e/e2e_general_cli_test.go | 35 +++++++++-------- test/e2e/e2e_gitea_and_grafana_test.go | 27 +++++-------- test/e2e/e2e_gitops_example_test.go | 52 ++++++++++++-------------- test/e2e/main_test.go | 24 ++++++++---- 7 files changed, 81 insertions(+), 97 deletions(-) diff --git a/Makefile b/Makefile index c3c31ac00c..10b4f36d76 100644 --- a/Makefile +++ b/Makefile @@ -103,7 +103,7 @@ test-e2e: package-example-game test-cloud-e2e-example-game ## DEPRECATED - to be .PHONY: build-and-test-e2e -build-and-test-e2e: build-cli init-package test-new-e2e ## Builds the cli and init package and runs the local e2e tests +build-and-test-e2e: build-cli init-package package-example-game package-example-gitops-data package-example-data-injection test-new-e2e ## Builds the cli and init package and runs the local e2e tests # TODO: Rename this once we are certain this is the e2e approach we are going to be taking # TODO: I'm pretty sure there's some way Makefiles could be setup to not run dependant steps if their results are already cached or something diff --git a/test/e2e/e2e_data_injection_test.go b/test/e2e/e2e_data_injection_test.go index df26a25a85..57538e37ef 100644 --- a/test/e2e/e2e_data_injection_test.go +++ b/test/e2e/e2e_data_injection_test.go @@ -5,30 +5,26 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestDataInjection(t *testing.T) { // run `zarf init` - err := e2e.execZarfCommand("init", "--confirm", "-l=trace") - // output, err := exec.Command(e2e.zarfBinPath, "init", "--confirm", "-l=trace").CombinedOutput() - assert.NoError(t, err, "unable to init") + output, err := e2e.execZarfCommand("init", "--confirm", "-l=trace") + require.NoError(t, err, output) // Deploy the data injection example - err = e2e.execZarfCommand("package", "deploy", "../../build/zarf-package-data-injection-demo.tar", "--confirm", "-l=trace") - // output, err = exec.Command(e2e.zarfBinPath, "package", "deploy", "../../build/zarf-package-data-injection-demo.tar", "--confirm", "-l=trace").CombinedOutput() - assert.NoError(t, err, "unable to deploy data-injection package") - - // time.Sleep(5 * time.Second) + output, err = e2e.execZarfCommand("package", "deploy", "../../build/zarf-package-data-injection-demo.tar", "--confirm", "-l=trace") + require.NoError(t, err, output) // Test to confirm the root file was placed + // TODO: This retry is disgusting, but race condition... var execStdOut string - // var execStdErr string attempt := 0 for attempt < 5 && execStdOut == "" { execStdOut, _, err = e2e.execCommandInPod("data-injection", "demo", []string{"ls", "/test"}) attempt++ - // fmt.Printf("stdout after %v attempts: %v\n", attempt, execStdOut) time.Sleep(2 * time.Second) } assert.NoError(t, err) @@ -41,7 +37,6 @@ func TestDataInjection(t *testing.T) { for attempt < 5 && execStdOut == "" { execStdOut, _, err = e2e.execCommandInPod("data-injection", "demo", []string{"ls", "/test/subdirectory-test"}) attempt++ - // fmt.Printf("stdout after %v attempts: %v\n", attempt, execStdOut) time.Sleep(2 * time.Second) } assert.NoError(t, err) diff --git a/test/e2e/e2e_example_game_test.go b/test/e2e/e2e_example_game_test.go index 754821dab7..d81d77ef4b 100644 --- a/test/e2e/e2e_example_game_test.go +++ b/test/e2e/e2e_example_game_test.go @@ -2,32 +2,25 @@ package test import ( "net/http" - "os/exec" "testing" - "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestE2eExampleGame(t *testing.T) { //run `zarf init` - output, err := exec.Command(e2e.zarfBinPath, "init", "--confirm").CombinedOutput() - assert.NoError(t, err, string(output)) + output, err := e2e.execZarfCommand("init", "--confirm") + require.NoError(t, err, output) // Deploy the game - output, err = exec.Command(e2e.zarfBinPath, "package", "deploy", "../../build/zarf-package-appliance-demo-multi-games.tar.zst", "--confirm").CombinedOutput() - assert.NoError(t, err, string(output)) + output, err = e2e.execZarfCommand("package", "deploy", "../../build/zarf-package-appliance-demo-multi-games.tar.zst", "--confirm") + require.NoError(t, err, output) // Establish the port-forward into the game service - cmd := exec.Command(e2e.zarfBinPath, "connect", "doom", "--local-port=22333") - e2e.cmdsToKill = append(e2e.cmdsToKill, cmd) - err = cmd.Start() - assert.NoError(t, err, "unable to connect to the doom port-forward") - - // Give the port-forward a second to establish. - // Since the `connect` command gets executed in the background, it can take a few milliseconds for the tunnel to be created - time.Sleep(1 * time.Second) + err = e2e.execZarfBackgroundCommand("connect", "doom", "--local-port=22333") + require.NoError(t, err, "unable to connect to the doom port-forward") // Check that 'curl' returns something. // Right now we're just checking that `curl` returns 0. It can be enhanced by scraping the HTML that gets returned or something. diff --git a/test/e2e/e2e_general_cli_test.go b/test/e2e/e2e_general_cli_test.go index a407ca570e..88a8409677 100644 --- a/test/e2e/e2e_general_cli_test.go +++ b/test/e2e/e2e_general_cli_test.go @@ -20,50 +20,53 @@ func TestGeneralCLI(t *testing.T) { cmd := exec.Command("echo", "random test data 🦄") cmd.Stdout = testfile cmd.Run() + e2e.filesToRemove = append(e2e.filesToRemove, shasumTestFilePath) - output, err := exec.Command(e2e.zarfBinPath, "prepare", "sha256sum", shasumTestFilePath).Output() + output, err := e2e.execZarfCommand("prepare", "sha256sum", shasumTestFilePath) assert.NoError(t, err, output) - assert.Equal(t, expectedShasum, string(output), "The expected SHASUM should equal the actual SHASUM") - os.Remove(shasumTestFilePath) + assert.Equal(t, expectedShasum, output, "The expected SHASUM should equal the actual SHASUM") // Test `zarf prepare sha256sum` for a remote asset expectedShasum = "c3cdea0573ba5a058ec090b5d2683bf398e8b1614c37ec81136ed03b78167617\n" - output, err = exec.Command(e2e.zarfBinPath, "prepare", "sha256sum", "https://zarf-public.s3-us-gov-west-1.amazonaws.com/pipelines/zarf-prepare-shasum-remote-test-file.txt").Output() + + output, err = e2e.execZarfCommand("prepare", "sha256sum", "https://zarf-public.s3-us-gov-west-1.amazonaws.com/pipelines/zarf-prepare-shasum-remote-test-file.txt") assert.NoError(t, err, output) - assert.Equal(t, expectedShasum, string(output), "The expected SHASUM should equal the actual SHASUM") + assert.Contains(t, output, expectedShasum, "The expected SHASUM should equal the actual SHASUM") // Test `zarf version` - output, err = exec.Command(e2e.zarfBinPath, "version").Output() + output, err = e2e.execZarfCommand("version") assert.NoError(t, err) assert.NotEqual(t, len(output), 0, "Zarf version should not be an empty string") - assert.NotEqual(t, string(output), "UnknownVersion", "Zarf version should not be the default value") + assert.NotEqual(t, output, "UnknownVersion", "Zarf version should not be the default value") // Test for expected failure when given a bad componenet input - output, err = exec.Command(e2e.zarfBinPath, "init", "--confirm", "--components=k3s,foo,logging").Output() + output, err = e2e.execZarfCommand("init", "--confirm", "--components=k3s,foo,logging") assert.Error(t, err) // Test for expected failure when given invalid hostnames - output, err = exec.Command(e2e.zarfBinPath, "pki", "regenerate", "--host", "zarf@server").Output() + output, err = e2e.execZarfCommand("pki", "regenerate", "--host", "zarf@server") assert.Error(t, err, output) - output, err = exec.Command(e2e.zarfBinPath, "pki", "regenerate", "--host=some_unique_server").Output() + output, err = e2e.execZarfCommand("pki", "regenerate", "--host=some_unique_server") assert.Error(t, err, output) // Test that changing the log level actually applies the requested level - output, _ = exec.Command(e2e.zarfBinPath, "version", "--log-level=warn").CombinedOutput() + output, _ = e2e.execZarfCommand("version", "--log-level=warn") expectedOutString := "Log level set to warn" - require.Contains(t, string(output), expectedOutString, "The log level should be changed to 'warn'") + require.Contains(t, output, expectedOutString, "The log level should be changed to 'warn'") + + e2e.cleanupAfterTest(t) } func TestInitZarf(t *testing.T) { // Initialize Zarf for the next set of tests // This also confirms that using the `--confirm` flags does not hang when not also specifying the `--components` flag - output, err := exec.Command(e2e.zarfBinPath, "init", "--confirm").CombinedOutput() - assert.NoError(t, err, string(output)) + output, err := e2e.execZarfCommand("init", "--confirm", "-l=trace") + assert.NoError(t, err, output) // Test that `zarf package deploy` gives an error if deploying a remote package without the --insecure or --shasum flags - output, err = exec.Command(e2e.zarfBinPath, "package", "deploy", "https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom-20210125.tar.zst", "--confirm").Output() - assert.Error(t, err, string(output)) + output, err = e2e.execZarfCommand("package", "deploy", "https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom-20210125.tar.zst", "--confirm", "-l=trace") + assert.Error(t, err, output) e2e.cleanupAfterTest(t) } diff --git a/test/e2e/e2e_gitea_and_grafana_test.go b/test/e2e/e2e_gitea_and_grafana_test.go index 2e4b5c5e1f..c98776c82b 100644 --- a/test/e2e/e2e_gitea_and_grafana_test.go +++ b/test/e2e/e2e_gitea_and_grafana_test.go @@ -2,43 +2,34 @@ package test import ( "net/http" - "os/exec" "testing" - "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func TestSomething(t *testing.T) { +func TestGiteaAndGrafana(t *testing.T) { // run `zarf init` - output, err := exec.Command(e2e.zarfBinPath, "init", "--components=gitops-service,logging", "--confirm").CombinedOutput() - require.NoError(t, err, string(output)) + output, err := e2e.execZarfCommand("init", "--components=gitops-service,logging", "--confirm") + require.NoError(t, err, output) // Establish the port-forward into the gitea service; give the service a few seconds to come up since this is not a command we can retry - time.Sleep(5 * time.Second) - tunnelCmd := exec.Command(e2e.zarfBinPath, "connect", "git") - err = tunnelCmd.Start() - require.NoError(t, err, "unable to establish tunnel to git") - e2e.cmdsToKill = append(e2e.cmdsToKill, tunnelCmd) - time.Sleep(1 * time.Second) + err = e2e.execZarfBackgroundCommand("connect", "git") + assert.NoError(t, err, "unable to establish tunnel to git") // Make sure Gitea comes up cleanly resp, err := http.Get("http://127.0.0.1:45003/explore/repos") - require.NoError(t, err) + assert.NoError(t, err) assert.Equal(t, 200, resp.StatusCode) // Establish the port-forward into the logging service - tunnelCmd = exec.Command(e2e.zarfBinPath, "connect", "logging") - err = tunnelCmd.Start() - require.NoError(t, err, "unable to establish tunnel to logging") - e2e.cmdsToKill = append(e2e.cmdsToKill, tunnelCmd) - time.Sleep(1 * time.Second) + err = e2e.execZarfBackgroundCommand("connect", "logging") + assert.NoError(t, err, "unable to establish tunnel to logging") // Make sure Grafana comes up cleanly resp, err = http.Get("http://127.0.0.1:45002/monitor/login") - require.NoError(t, err) + assert.NoError(t, err) assert.Equal(t, 200, resp.StatusCode) e2e.cleanupAfterTest(t) diff --git a/test/e2e/e2e_gitops_example_test.go b/test/e2e/e2e_gitops_example_test.go index 744584dfae..3d3892eed8 100644 --- a/test/e2e/e2e_gitops_example_test.go +++ b/test/e2e/e2e_gitops_example_test.go @@ -6,7 +6,6 @@ import ( "os/exec" "strings" "testing" - "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -14,60 +13,55 @@ import ( func TestGitopsExample(t *testing.T) { // run `zarf init` - output, err := exec.Command(e2e.zarfBinPath, "init", "--confirm", "--components=gitops-service").CombinedOutput() - require.NoError(t, err, string(output)) + output, err := e2e.execZarfCommand("init", "--confirm", "--components=gitops-service") + require.NoError(t, err, output) // Deploy the gitops example - output, err = exec.Command(e2e.zarfBinPath, "package", "deploy", "../../build/zarf-package-gitops-service-data.tar.zst", "--confirm").CombinedOutput() - require.NoError(t, err, string(output)) - - time.Sleep(5 * time.Second) + output, err = e2e.execZarfCommand("package", "deploy", "../../build/zarf-package-gitops-service-data.tar.zst", "--confirm") + require.NoError(t, err, output) // Create a tunnel to the git resources - tunnelCmd := exec.Command(e2e.zarfBinPath, "connect", "git") - err = tunnelCmd.Start() - require.NoError(t, err, "unable to establish tunnel to git") - e2e.cmdsToKill = append(e2e.cmdsToKill, tunnelCmd) - time.Sleep(1 * time.Second) + err = e2e.execZarfBackgroundCommand("connect", "git") + assert.NoError(t, err, "unable to establish tunnel to git") // Check for full git repo mirror (foo.git) from https://github.com/stefanprodan/podinfo.git - adminPassword, err := exec.Command(e2e.zarfBinPath, "tools", "get-admin-password").Output() - require.NoError(t, err, "Unable to get admin password for gitea instance") + adminPassword, err := e2e.execZarfCommand("tools", "get-admin-password") + assert.NoError(t, err, "Unable to get admin password for gitea instance") cloneCommand := fmt.Sprintf("http://zarf-git-user:%s@127.0.0.1:45003/zarf-git-user/mirror__github.com__stefanprodan__podinfo.git", strings.TrimSpace(string(adminPassword))) - output, err = exec.Command("git", "clone", cloneCommand).CombinedOutput() - require.NoError(t, err, string(output)) + gitOutput, err := exec.Command("git", "clone", cloneCommand).CombinedOutput() + assert.NoError(t, err, string(gitOutput)) e2e.filesToRemove = append(e2e.filesToRemove, "mirror__github.com__stefanprodan__podinfo") // Check for tagged git repo mirror (foo.git@1.2.3) from https://github.com/defenseunicorns/zarf.git@v0.15.0 cloneCommand = fmt.Sprintf("http://zarf-git-user:%s@127.0.0.1:45003/zarf-git-user/mirror__github.com__defenseunicorns__zarf.git", strings.TrimSpace(string(adminPassword))) - output, err = exec.Command("git", "clone", cloneCommand).CombinedOutput() - require.NoError(t, err, string(output)) + gitOutput, err = exec.Command("git", "clone", cloneCommand).CombinedOutput() + assert.NoError(t, err, string(gitOutput)) e2e.filesToRemove = append(e2e.filesToRemove, "mirror__github.com__defenseunicorns__zarf") // Check for correct tag expectedTag := "v0.15.0\n" err = os.Chdir("mirror__github.com__defenseunicorns__zarf") - require.NoError(t, err) - output, err = exec.Command("git", "tag").Output() - assert.Equal(t, expectedTag, string(output), "Expected tag should match output") + assert.NoError(t, err) + gitOutput, err = exec.Command("git", "tag").Output() + assert.Equal(t, expectedTag, string(gitOutput), "Expected tag should match output") // Check for correct commits expectedCommits := "9eb207e\n7636dd0\ne02cec9" - output, err = exec.Command("git", "log", "-3", "--oneline", "--pretty=format:%h").CombinedOutput() - require.NoError(t, err, string(output)) - assert.Equal(t, expectedCommits, string(output), "Expected commits should match output") + gitOutput, err = exec.Command("git", "log", "-3", "--oneline", "--pretty=format:%h").CombinedOutput() + assert.NoError(t, err, string(gitOutput)) + assert.Equal(t, expectedCommits, string(gitOutput), "Expected commits should match output") // Check for existence of tags without specifying them, signifying that not using '@1.2.3' syntax brought over the whole repo expectedTag = "0.2.2" err = os.Chdir("../mirror__github.com__stefanprodan__podinfo") - require.NoError(t, err) - output, err = exec.Command("git", "tag").CombinedOutput() - require.NoError(t, err, string(output)) - assert.Contains(t, string(output), expectedTag) + assert.NoError(t, err) + gitOutput, err = exec.Command("git", "tag").CombinedOutput() + assert.NoError(t, err, string(gitOutput)) + assert.Contains(t, string(gitOutput), expectedTag) err = os.Chdir("..") - require.NoError(t, err, "unable to change directories back to blah blah blah") + assert.NoError(t, err, "unable to change directories back to blah blah blah") e2e.cleanupAfterTest(t) } diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go index ffa504ee47..a3e8125e50 100644 --- a/test/e2e/main_test.go +++ b/test/e2e/main_test.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "testing" + "time" ) var ( @@ -13,24 +14,31 @@ var ( // TestMain will exec each test, one by one func TestMain(m *testing.M) { // Create a kubeconfig and start up a KinD cluster - err := e2e.setUp() + err := e2e.setUpKind() if err != nil { fmt.Printf("Unable to setup environment to run the e2e test because of err: %v\n", err) os.Exit(1) } + // This defer teardown still runs if a panic/fatal happens while running the tests + defer e2e.tearDownKind() + // exec test and this returns an exit code to pass to os retCode := m.Run() - // Unless told to skip, destroy the KinD Cluster and delete the generated kubeconfig - // TODO: Should add some defer logic here so that this gets executed even if there is a fatal error in the tests - if os.Getenv("SKIP_TEARDOWN") == "" && !e2e.clusterAlreadyExists { - err = e2e.tearDown() - if err != nil { - fmt.Printf("Unable to teardown test environment after completion of tests: %v\n", err) - } + // Teardown the cluster now that tests are completed + e2e.tearDownKind() + + time.Sleep(15 * time.Second) + + err = e2e.setUpK3D() + if err != nil { + fmt.Printf("unable to set up k3d environment to run the e2e tests on") } + retCode = m.Run() + e2e.tearDownK3D() + // If exit code is distinct of zero, the test will be failed (red) os.Exit(retCode) } From 1c7e083c8625fb60898cf3e811b9120476933683 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Thu, 17 Feb 2022 22:21:59 -0500 Subject: [PATCH 04/25] wip k3d, silly go mod --- test/e2e/common.go | 99 ++++++++++++++++++++++++++++++++++--------- test/e2e/main_test.go | 15 +++---- 2 files changed, 86 insertions(+), 28 deletions(-) diff --git a/test/e2e/common.go b/test/e2e/common.go index 8cbea77c2b..88fb4e5d42 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -12,6 +12,7 @@ import ( "testing" "time" + // k3dcluster "github.com/rancher/k3d/v5/cmd/cluster" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -39,7 +40,7 @@ type ZarfE2ETest struct { } func getKubeconfigPath() (string, error) { - + // k3dcluster.NewCmdClusterCreate() // Check if the $KUBECONFIG env is set // TODO: It would probably be good to verify a useable kubeconfig lives here kubeconfigEnv := os.Getenv("KUBECONFIG") @@ -62,7 +63,7 @@ func getKubeconfigPath() (string, error) { return kubeconfigPath, err } -func (e2e *ZarfE2ETest) setUp() error { +func (e2e *ZarfE2ETest) setUpKind() error { // Determine what the name of the zarfBinary should be e2e.zarfBinPath = path.Join("../../build", getCLIName()) @@ -102,7 +103,6 @@ func (e2e *ZarfE2ETest) setUp() error { } // Wait for the cluster to have pods before we let the test suite run - // TODO: Pretty sure there's a cleaner way to do this attempt := 0 for attempt < 10 { pods, err := e2e.clientset.CoreV1().Pods("kube-system").List(context.TODO(), metav1.ListOptions{}) @@ -121,15 +121,73 @@ func (e2e *ZarfE2ETest) setUp() error { return err } -func (e2e *ZarfE2ETest) tearDown() error { +func (e2e *ZarfE2ETest) tearDownKind() error { + if os.Getenv("SKIP_TEARDOWN") != "" || e2e.clusterAlreadyExists { + return nil + } + + // k3dcluster.NewCmdClusterCreate() + // Delete the cluster and kubeconfig file provider := cluster.NewProvider(cluster.ProviderWithLogger(kindcmd.NewLogger())) err := provider.Delete(e2e.clusterName, e2e.kubeconfigPath) os.Remove(e2e.kubeconfigPath) - return err } +// func (e2e *ZarfE2ETest) setUpK3D() error { + +// // Determine what the name of the zarfBinary should be +// e2e.zarfBinPath = path.Join("../../build", getCLIName()) + +// var err error +// // Create or get the kubeconfig +// e2e.kubeconfigPath, err = getKubeconfigPath() +// if err != nil { +// return err +// } + +// createClusterCommand := k3dcluster.NewCmdClusterCreate() +// err = createClusterCommand.ExecuteContext(context.TODO()) +// if err != nil { +// fmt.Println("ERROR WHEN TRYING TO SET UP K3D CLUSTER") +// return err +// } + +// // Get config and client for the k8s cluster +// e2e.restConfig, err = clientcmd.BuildConfigFromFlags("", e2e.kubeconfigPath) +// if err != nil { +// return err +// } +// e2e.clientset, err = kubernetes.NewForConfig(e2e.restConfig) +// if err != nil { +// return err +// } + +// // Wait for the cluster to have pods before we let the test suite run +// attempt := 0 +// for attempt < 10 { +// pods, err := e2e.clientset.CoreV1().Pods("kube-system").List(context.TODO(), metav1.ListOptions{}) +// if err == nil && len(pods.Items) >= 0 { +// fmt.Printf("💥 Cluster %s ready. You can access it by setting:\nexport KUBECONFIG='%s'\n", e2e.clusterName, e2e.kubeconfigPath) +// break +// } + +// time.Sleep(1 * time.Second) +// attempt++ +// if attempt > 15 { +// return errors.New("unable to connect to KinD cluster for e2e tests") +// } +// } +// return nil +// } + +// func (e2e *ZarfE2ETest) tearDownK3D() error { +// deleteClusterCommand := k3dcluster.NewCmdClusterDelete() +// err := deleteClusterCommand.ExecuteContext(context.TODO()) +// return err +// } + func getCLIName() string { var binaryName string if runtime.GOOS == "linux" { @@ -145,11 +203,9 @@ func getCLIName() string { } func (e2e *ZarfE2ETest) cleanupAfterTest(t *testing.T) { - fmt.Println("Test is finished, cleaning up now") - // Use Zarf to perform chart uninstallation - _, err := exec.Command(e2e.zarfBinPath, "destroy", "--confirm", "--remove-components", "-l=trace").CombinedOutput() - require.NoError(t, err, "unable to destroy the zarf cluster when cleaning up after a test") + output, err := e2e.execZarfCommand("destroy", "--confirm", "--remove-components", "-l=trace") + require.NoError(t, err, output) // Remove files created for the test for _, filePath := range e2e.filesToRemove { @@ -166,11 +222,6 @@ func (e2e *ZarfE2ETest) cleanupAfterTest(t *testing.T) { } } e2e.cmdsToKill = []*exec.Cmd{} - - fmt.Println("sleeping for 10 seconds after clean up.. for reasons..") - time.Sleep(10 * time.Second) - fmt.Println("done sleeping!") - } func (e2e *ZarfE2ETest) execCommandInPod(podname, namespace string, cmd []string) (string, string, error) { @@ -189,7 +240,6 @@ func (e2e *ZarfE2ETest) execCommandInPod(podname, namespace string, cmd []string exec, err := remotecommand.NewSPDYExecutor(e2e.restConfig, "POST", req.URL()) if err != nil { - fmt.Println("@JPERRY something was broken with the spdy executor...") return "", "", err } @@ -202,9 +252,18 @@ func (e2e *ZarfE2ETest) execCommandInPod(podname, namespace string, cmd []string return stdoutBuffer.String(), stderrBuffer.String(), err } -func (e2e *ZarfE2ETest) execZarfCommand(commandString ...string) error { - cmd := exec.Command(e2e.zarfBinPath, commandString...) - // cmd.Stdout = os.Stdout - // cmd.Stderr = os.Stderr - return cmd.Run() +// TODO: It might be a nice feature to read some flag/env and change the stdout and stderr to pipe to the terminal running the test +func (e2e *ZarfE2ETest) execZarfCommand(commandString ...string) (string, error) { + output, err := exec.Command(e2e.zarfBinPath, commandString...).CombinedOutput() + return string(output), err +} + +func (e2e *ZarfE2ETest) execZarfBackgroundCommand(commandString ...string) error { + // Create a tunnel to the git resources + tunnelCmd := exec.Command(e2e.zarfBinPath, commandString...) + err := tunnelCmd.Start() + e2e.cmdsToKill = append(e2e.cmdsToKill, tunnelCmd) + time.Sleep(1 * time.Second) + + return err } diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go index a3e8125e50..bbf6f8732b 100644 --- a/test/e2e/main_test.go +++ b/test/e2e/main_test.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "testing" - "time" ) var ( @@ -29,15 +28,15 @@ func TestMain(m *testing.M) { // Teardown the cluster now that tests are completed e2e.tearDownKind() - time.Sleep(15 * time.Second) + // time.Sleep(15 * time.Second) - err = e2e.setUpK3D() - if err != nil { - fmt.Printf("unable to set up k3d environment to run the e2e tests on") - } + // err = e2e.setUpK3D() + // if err != nil { + // fmt.Printf("unable to set up k3d environment to run the e2e tests on") + // } - retCode = m.Run() - e2e.tearDownK3D() + // retCode = m.Run() + // e2e.tearDownK3D() // If exit code is distinct of zero, the test will be failed (red) os.Exit(retCode) From fb82c4b997d6f0646529886efd1c762875fe8570 Mon Sep 17 00:00:00 2001 From: Jeff McCoy Date: Fri, 18 Feb 2022 00:03:03 -0600 Subject: [PATCH 05/25] dear diary, did I do good? --- go.mod | 30 +---- go.sum | 316 +++++++++++++++++++++++++++++++++++++++++---- test/e2e/common.go | 106 +++++++-------- 3 files changed, 345 insertions(+), 107 deletions(-) diff --git a/go.mod b/go.mod index bed758af68..fc66fbe47d 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/mholt/archiver/v3 v3.5.1 github.com/otiai10/copy v1.7.0 github.com/pterm/pterm v0.12.33 + github.com/rancher/k3d/v5 v5.2.0 github.com/spf13/cobra v1.3.0 github.com/stretchr/testify v1.7.0 golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e @@ -31,32 +32,3 @@ require ( sigs.k8s.io/kustomize/kyaml v0.11.0 sigs.k8s.io/yaml v1.3.0 ) - -replace ( - // https://github.com/kubernetes/kubernetes/issues/79384#issuecomment-505627280 - k8s.io/api => k8s.io/api v0.22.5 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.22.5 // indirect - k8s.io/apimachinery => k8s.io/apimachinery v0.22.5 // indirect - k8s.io/apiserver => k8s.io/apiserver v0.22.5 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.22.5 - k8s.io/client-go => k8s.io/client-go v0.22.5 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.22.5 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.22.5 - k8s.io/code-generator => k8s.io/code-generator v0.22.5 - k8s.io/component-base => k8s.io/component-base v0.22.5 - k8s.io/component-helpers => k8s.io/component-helpers v0.22.5 - k8s.io/controller-manager => k8s.io/controller-manager v0.22.5 - k8s.io/cri-api => k8s.io/cri-api v0.22.5 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.22.5 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.22.5 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.22.5 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.22.5 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.22.5 - k8s.io/kubectl => k8s.io/kubectl v0.22.5 - k8s.io/kubelet => k8s.io/kubelet v0.22.5 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.22.5 - k8s.io/metrics => k8s.io/metrics v0.22.5 - k8s.io/mount-utils => k8s.io/mount-utils v0.22.5 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.22.5 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.22.5 -) diff --git a/go.sum b/go.sum index f5167e6750..29aa3163f4 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,5 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= +bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -38,6 +39,7 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.6.0/go.mod h1:afJwI0vaXwAG54kI7A//lP/lSPDkQORQuMkv56TxEPU= cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= @@ -59,15 +61,19 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOEl github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/adal v0.9.11/go.mod h1:nBKAnTomx8gDtl+3ZCJv2v0KACFHWTB2drffI1B68Pk= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/azure/auth v0.5.8/go.mod h1:kxyKZTSfKh8OVFWPAgOgQ/frrJgeYQJPyR5fLFmXko4= github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= @@ -122,8 +128,9 @@ github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2 github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= -github.com/Microsoft/hcsshim v0.8.23 h1:47MSwtKGXet80aIn+7h4YI6fwPmwIghAnsx2aOUrG2M= github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= +github.com/Microsoft/hcsshim v0.9.1 h1:VfDCj+QnY19ktX5TsH22JHcjaZ05RWQiwDbOyEg5ziM= +github.com/Microsoft/hcsshim v0.9.1/go.mod h1:Y/0uV2jUab5kBI7SQgl62at0AVX7uaruzADAVmxm3eM= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -133,10 +140,14 @@ github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -150,6 +161,7 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/jsonschema v0.0.0-20211228220459-151e3c21f49d h1:4BQNwS4T13UU3Yee4GfzZH3Q9SNpKeJvLigfw8fDjX0= github.com/alecthomas/jsonschema v0.0.0-20211228220459-151e3c21f49d/go.mod h1:/n6+1/DWPltRLWL/VKyUxg6tzsl5kHUCcraimt4vr60= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -160,6 +172,7 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= @@ -181,6 +194,7 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY= github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= @@ -197,12 +211,14 @@ github.com/aws/aws-sdk-go v1.40.56 h1:FM2yjR0UUYFzDTMx+mH9Vyw1k1EUUxsAFzk+BjkzAN github.com/aws/aws-sdk-go v1.40.56/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= +github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw= github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= @@ -217,8 +233,9 @@ github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0 h1:s7+5BfS4WFJoVF9pnB8kBk03S7pZXRdKamnV0FOl5Sc= +github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= @@ -253,6 +270,8 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ= +github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -281,8 +300,9 @@ github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1 github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.1 h1:iJnMvco9XGvKUvNQkv88bE4uJXxRQH18efbKo9w5vHQ= github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= +github.com/containerd/cgroups v1.0.2 h1:mZBclaSgNDfPWtfhj2xJY28LZ9nYIgzB0pwSURPl6JM= +github.com/containerd/cgroups v1.0.2/go.mod h1:qpbpJ1jmlqsR9f2IyaLPsdkCdnt0rbDVqIDlhuu5tRY= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= @@ -313,6 +333,8 @@ github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cE github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= +github.com/containerd/continuity v0.2.1 h1:/EeEo2EtN3umhbbgCveyjifoMYg0pS+nMMEemaYw634= +github.com/containerd/continuity v0.2.1/go.mod h1:wCYX+dRqZdImhGucXOqTQn05AhX6EUDaGEMUzTFFpLg= github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= @@ -333,6 +355,7 @@ github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJ github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM= github.com/containerd/stargz-snapshotter/estargz v0.7.0/go.mod h1:83VWDqHnurTKliEB0YvWMiCfLDwv4Cjj1X9Vk98GJZw= github.com/containerd/stargz-snapshotter/estargz v0.10.1 h1:hd1EoVjI2Ax8Cr64tdYqnJ4i4pZU49FkEf5kU8KxQng= github.com/containerd/stargz-snapshotter/estargz v0.10.1/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0= @@ -394,6 +417,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= +github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/derailed/k9s v0.25.18 h1:wvTQ56NdJ2GALD1OQjQL34yhcB7sPRuDYo9py1Md+Vw= @@ -410,20 +434,26 @@ github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/ github.com/distribution/distribution/v3 v3.0.0-20210804104954-38ab4c606ee3 h1:rEK0juuU5idazw//KzUcL3yYwUU3DIe2OnfJwjDBqno= github.com/distribution/distribution/v3 v3.0.0-20210804104954-38ab4c606ee3/go.mod h1:gt38b7cvVKazi5XkHvINNytZXgTEntyhtyM3HQz46Nk= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v20.10.7+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v20.10.10+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli v20.10.12+incompatible h1:lZlz0uzG+GH+c0plStMUdF/qk3ppmgnswpR5EbqzVGA= github.com/docker/cli v20.10.12+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.10+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.12+incompatible h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U= github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o= github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= +github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= +github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= @@ -432,10 +462,13 @@ github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6Uezg github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= +github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= @@ -443,6 +476,8 @@ github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj6 github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= @@ -467,6 +502,9 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.2.0 h1:8ozOH5xxoMYDt5/u+yMTsVXydVCbTORFnOOoq2lumco= @@ -504,10 +542,13 @@ github.com/gdamore/tcell/v2 v2.2.1/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6o github.com/gdamore/tcell/v2 v2.4.0 h1:W6dxJEmaxYvhICFoTY3WrLLEXsQ11SaFnKGVEXW57KM= github.com/gdamore/tcell/v2 v2.4.0/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU= github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 h1:skJKxRtNmevLqnayafdLe2AsenqRupVmzZSqrvb5caU= github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -537,15 +578,57 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= @@ -553,14 +636,17 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87 github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= github.com/gobuffalo/logger v1.0.3 h1:YaXOTHNPCvkqqA7w05A4v0k2tCdpr+sgFlgINbQ6gqc= github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM= github.com/gobuffalo/packd v1.0.0 h1:6ERZvJHfe24rfFmA9OaoKBdC7+c9sydrytMg8SdFGBM= @@ -582,9 +668,11 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= +github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -637,6 +725,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93 h1:jc2UWq7CbdszqeH6qu1ougXMIUBfSy8Pbh/anURYbGI= +github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -650,6 +740,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-containerregistry v0.6.0/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw= github.com/google/go-containerregistry v0.8.0 h1:mtR24eN6rapCN+shds82qFEIWWmg64NPMuyCNT7/Ogc= github.com/google/go-containerregistry v0.8.0/go.mod h1:wW5v71NHGnQyb4k+gSshjxidrC7lN33MdWEn+Mz9TsI= @@ -686,6 +777,7 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= @@ -697,6 +789,7 @@ github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= @@ -719,8 +812,11 @@ github.com/gruntwork-io/go-commons v0.8.0 h1:k/yypwrPqSeYHevLlEDmvmgQzcyTwrlZGRa github.com/gruntwork-io/go-commons v0.8.0/go.mod h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78= github.com/gruntwork-io/terratest v0.38.2 h1:XgDGMxX+dE8Aw96wI8QH6oIzveej01Yk4bTjt6dtzIU= github.com/gruntwork-io/terratest v0.38.2/go.mod h1:XzW8PL9pAGbLyiBdQ5OiAeWSNpZ/9ycItjYstSS2PV8= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= @@ -798,6 +894,11 @@ github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJS github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o= github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= +github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8 h1:CZkYfurY6KGhVtlalI4QwQ6T0Cu6iuY3e0x5RLu96WE= +github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo= +github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d h1:jRQLvyVGL+iVtDElaEIDdKwpPqUIZJfzkNLV34htpEc= +github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -808,6 +909,7 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.3.1 h1:aLN7YINNZ7cYOPK3QC83dbM6KT0NMqVMw961TqrejlE= github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= +github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -824,6 +926,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 h1:UUHMLvzt/31azWTN/ifGWef4WUqvXk0iRqdhdy/2uzI= +github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/karrick/godirwalk v1.15.8 h1:7+rWAZPn9zuRxaIqqT8Ohs2Q2Ac0msBqwRdxNCr2VVs= @@ -858,8 +962,9 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ= github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -872,6 +977,7 @@ github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhR github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.0 h1:Zx5DJFEYQXio93kgXnQ09fXNiUKsqv4OUEu2UtGcB1E= github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= @@ -879,16 +985,21 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhn github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= @@ -898,6 +1009,7 @@ github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= +github.com/markbates/pkger v0.17.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI= github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= @@ -928,7 +1040,9 @@ github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRC github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= +github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= @@ -937,6 +1051,7 @@ github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJc github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= @@ -945,6 +1060,8 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -964,11 +1081,13 @@ github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQ github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f h1:2+myh5ml7lgEU/51gbeLHfKGNfgEQQIWrlbdaOsidbQ= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= @@ -978,13 +1097,18 @@ github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/sys/mount v0.3.0 h1:bXZYMmq7DBQPwHRxH/MG+u9+XF90ZOwoXpHTOznMGp0= +github.com/moby/sys/mount v0.3.0/go.mod h1:U2Z3ur2rXPFrFmy4q6WMwWrBOAQGYtYTRVM8BIvzbwk= github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= +github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= -github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 h1:yH0SvLzcbZxcJXho2yh7CqdENGMQe73Cw3woZBpPli0= github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= +github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= +github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1025,16 +1149,21 @@ github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= @@ -1054,6 +1183,7 @@ github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59P github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= +github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg= github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -1068,6 +1198,7 @@ github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xA github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= @@ -1117,6 +1248,7 @@ github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prY github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok= github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= @@ -1158,6 +1290,7 @@ github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= @@ -1169,6 +1302,8 @@ github.com/pterm/pterm v0.12.33 h1:XiT50Pvdqn5O8FAiIqZMpXP6NkVEcmlUa+mkA1yWVCg= github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= github.com/rakyll/hey v0.1.4 h1:hhc8GIqHN4+rPFZvkM9lkCQGi7da0sINM83xxpFkbPA= github.com/rakyll/hey v0.1.4/go.mod h1:nAOTOo+L52KB9SZq/M6J18kxjto4yVtXQDjU2HgjUPI= +github.com/rancher/k3d/v5 v5.2.0 h1:5kQQkdKxy/iAEFNTS5blVHDhM0M2zUKz4BGq3eguo+0= +github.com/rancher/k3d/v5 v5.2.0/go.mod h1:wf9CUngX+Klerdc1rKlQV5OKzTQesCwoYGDMcB56DLQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= @@ -1192,11 +1327,13 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/sagikazarmark/crypt v0.1.0/go.mod h1:B/mN0msZuINBtQ1zZLEQcegFJJf9vnYIR88KRMEuODE= github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI= github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= @@ -1225,11 +1362,14 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= @@ -1239,18 +1379,24 @@ github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSW github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/cobra v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0= github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= +github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= +github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= +github.com/spf13/viper v1.10.0 h1:mXH0UwHS4D2HwWZa75im4xIQynLfblmWV7qcWpfv0yk= github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= @@ -1272,17 +1418,22 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= +github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c= +github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmccombs/hcl2json v0.3.3 h1:+DLNYqpWE0CsOQiEZu+OZm5ZBImake3wtITYxQ8uLFQ= github.com/tmccombs/hcl2json v0.3.3/go.mod h1:Y2chtz2x9bAeRTvSibVRVgbLJhLJXKlUeIvjeVdnm4w= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I= @@ -1295,6 +1446,7 @@ github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= @@ -1308,8 +1460,9 @@ github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= @@ -1350,6 +1503,7 @@ go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= @@ -1360,6 +1514,9 @@ go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lL go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -1397,28 +1554,38 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +go4.org/intern v0.0.0-20210108033219-3eb7198706b2 h1:VFTf+jjIgsldaz/Mr00VaCSswHJrI2hIjQygE/W4IMg= +go4.org/intern v0.0.0-20210108033219-3eb7198706b2/go.mod h1:vLqJ+12kCw61iCWsPto0EOHhBS+o4rO5VIucbc9g2Cc= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222175341-b30ae309168e/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063 h1:1tk03FUNpulq2cuWpXZWj649rwJpk0d20rxWiopKRmc= +go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -1458,6 +1625,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -1467,6 +1635,7 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181017193950-04a2e542c03f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1477,6 +1646,7 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1521,11 +1691,14 @@ golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5o golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211111160137-58aab5ef257a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1571,6 +1744,7 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1583,6 +1757,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1634,6 +1809,7 @@ golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1670,6 +1846,7 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211112143042-c6105e7cf70d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= @@ -1697,14 +1874,18 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1714,9 +1895,12 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1751,12 +1935,14 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1850,6 +2036,7 @@ google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1857,6 +2044,7 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1883,6 +2071,7 @@ google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEc google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211112145013-271947fe86fd/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= @@ -1890,6 +2079,7 @@ google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1942,6 +2132,8 @@ google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+Rur google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII= +gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1960,9 +2152,14 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.64.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1 h1:d4KQkxAaAiRY2h5Zqis161Pv91A37uZyJOx73duwUwM= +gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1/go.mod h1:WbjuEoo1oadwzQ4apSDU+JTvmllEHtsNHS6y7vFc7iw= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= @@ -1976,6 +2173,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -2000,41 +2198,101 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +inet.af/netaddr v0.0.0-20210903134321-85fa6c94624e h1:tvgqez5ZQoBBiBAGNU/fmJy247yB/7++kcLOEoMYup0= +inet.af/netaddr v0.0.0-20210903134321-85fa6c94624e/go.mod h1:z0nx+Dh+7N7CC8V5ayHtHGpZpxLQZZxkIaaz6HN65Ls= +k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= +k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= +k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= +k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU= +k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY= +k8s.io/api v0.22.3/go.mod h1:azgiXFiXqiWyLCfI62/eYBOu19rj2LKmIhFPP4+33fs= +k8s.io/api v0.22.4/go.mod h1:Rgs+9gIGYC5laXQSZZ9JqT5NevNgoGiOdVWi1BAB3qk= k8s.io/api v0.22.5 h1:xk7C+rMjF/EGELiD560jdmwzrB788mfcHiNbMQLIVI8= k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs= -k8s.io/apiextensions-apiserver v0.22.5 h1:ML0QqT7FIlmZHN+9+2EtARJ3cJVHeoizt6GCteFRE0o= -k8s.io/apiextensions-apiserver v0.22.5/go.mod h1:tIXeZ0BrDxUb1PoAz+tgOz43Zi1Bp4BEEqVtUccMJbE= +k8s.io/apiextensions-apiserver v0.22.1/go.mod h1:HeGmorjtRmRLE+Q8dJu6AYRoZccvCMsghwS8XTUYb2c= +k8s.io/apiextensions-apiserver v0.22.4 h1:2iGpcVyw4MnAyyXVJU2Xg6ZsbIxAOfRHo0LF5A5J0RA= +k8s.io/apiextensions-apiserver v0.22.4/go.mod h1:kH9lxD8dbJ+k0ZizGET55lFgdGjO8t45fgZnCVdZEpw= +k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= +k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM= +k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= +k8s.io/apimachinery v0.22.3/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= +k8s.io/apimachinery v0.22.4/go.mod h1:yU6oA6Gnax9RrxGzVvPFFJ+mpnW6PBSqp0sx0I0HHW0= k8s.io/apimachinery v0.22.5 h1:cIPwldOYm1Slq9VLBRPtEYpyhjIm1C6aAMAoENuvN9s= k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U= -k8s.io/apiserver v0.22.5 h1:71krQxCUz218ecb+nPhfDsNB6QgP1/4EMvi1a2uYBlg= -k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ= -k8s.io/cli-runtime v0.22.5 h1:bZqLgx1INiPgXyMk/Hu3o5NFmdfvlvtsoE+wHJuKA2U= -k8s.io/cli-runtime v0.22.5/go.mod h1:12ah4O0kaevIYHsRcFGt8RKER0wlTN2yCgHp1c4Uxp4= +k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= +k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= +k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= +k8s.io/apiserver v0.21.2/go.mod h1:lN4yBoGyiNT7SC1dmNk0ue6a5Wi6O3SWOIw91TsucQw= +k8s.io/apiserver v0.22.1/go.mod h1:2mcM6dzSt+XndzVQJX21Gx0/Klo7Aen7i0Ai6tIa400= +k8s.io/apiserver v0.22.4 h1:L+220cy+94UWmyBl1kiVTklBXrBtKsbjlPV60eL2u6s= +k8s.io/apiserver v0.22.4/go.mod h1:38WmcUZiiy41A7Aty8/VorWRa8vDGqoUzDf2XYlku0E= +k8s.io/cli-runtime v0.21.2/go.mod h1:8u/jFcM0QpoI28f6sfrAAIslLCXUYKD5SsPPMWiHYrI= +k8s.io/cli-runtime v0.22.1/go.mod h1:YqwGrlXeEk15Yn3em2xzr435UGwbrCw5x+COQoTYfoo= +k8s.io/cli-runtime v0.22.3/go.mod h1:um6JvCxV9Hrhq0zCUxcqYoY7/wF64g6IYgOViI8sg6Q= +k8s.io/cli-runtime v0.22.4 h1:uFSVSdW14JP53BCtMRsw1hB9ba21TBuUb5m7RvEsH0Y= +k8s.io/cli-runtime v0.22.4/go.mod h1:x35r0ERHXr/MrbR1C6MPJxQ3xKG6+hXi9m2xLzlMPZA= +k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= +k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= +k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= +k8s.io/client-go v0.21.2/go.mod h1:HdJ9iknWpbl3vMGtib6T2PyI/VYxiZfq936WNVHBRrA= +k8s.io/client-go v0.22.1/go.mod h1:BquC5A4UOo4qVDUtoc04/+Nxp1MeHcVc1HJm1KmG8kk= +k8s.io/client-go v0.22.3/go.mod h1:ElDjYf8gvZsKDYexmsmnMQ0DYO8W9RwBjfQ1PI53yow= +k8s.io/client-go v0.22.4/go.mod h1:Yzw4e5e7h1LNHA4uqnMVrpEpUs1hJOiuBsJKIlRCHDA= k8s.io/client-go v0.22.5 h1:I8Zn/UqIdi2r02aZmhaJ1hqMxcpfJ3t5VqvHtctHYFo= k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y= -k8s.io/code-generator v0.22.5/go.mod h1:sbdWCOVob+KaQ5O7xs8PNNaCTpbWVqNgA6EPwLOmRNk= -k8s.io/component-base v0.22.5 h1:U0eHqZm7mAFE42hFwYhY6ze/MmVaW00JpMrzVsQmzYE= -k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI= -k8s.io/component-helpers v0.22.5/go.mod h1:UK4H16PcV6pTInkhAOfkPbN/aXHPXPX2/ZI4lfCXH4I= -k8s.io/cri-api v0.22.5/go.mod h1:uAw9CICQq20/1yB4ZnWT2TjJyMMROl4typFfWaURLwQ= +k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= +k8s.io/code-generator v0.21.2/go.mod h1:8mXJDCB7HcRo1xiEQstcguZkbxZaqeUOrO9SsicWs3U= +k8s.io/code-generator v0.22.1/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= +k8s.io/code-generator v0.22.3/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o= +k8s.io/code-generator v0.22.4/go.mod h1:qjYl54pQ/emhkT0UxbufbREYJMWsHNNV/jSVwhYZQGw= +k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= +k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= +k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= +k8s.io/component-base v0.21.2/go.mod h1:9lvmIThzdlrJj5Hp8Z/TOgIkdfsNARQ1pT+3PByuiuc= +k8s.io/component-base v0.22.1/go.mod h1:0D+Bl8rrnsPN9v0dyYvkqFfBeAd4u7n77ze+p8CMiPo= +k8s.io/component-base v0.22.3/go.mod h1:kuybv1miLCMoOk3ebrqF93GbQHQx6W2287FC0YEQY6s= +k8s.io/component-base v0.22.4 h1:7qwLJnua2ppGNZrRGDQ0vhsFebI39VGbZ4zdR5ArViI= +k8s.io/component-base v0.22.4/go.mod h1:MrSaQy4a3tFVViff8TZL6JHYSewNCLshZCwHYM58v5A= +k8s.io/component-helpers v0.22.1/go.mod h1:QvBcDbX+qU5I2tMZABBF5fRwAlQwiv771IGBHK9WYh4= +k8s.io/component-helpers v0.22.3/go.mod h1:7OVySVH5elhHKuJKUOxZEfpT1Bm3ChmBQZHmuFfbGHk= +k8s.io/component-helpers v0.22.4/go.mod h1:A50qTyczDFbhZDifIfS2zFrHuPk9UNOWPpvNZ+3RSIs= +k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= +k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.40.1 h1:P4RRucWk/lFOlDdkAr3mc7iWFkgKrZY9qZMAgek06S4= k8s.io/klog/v2 v2.40.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= +k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c h1:jvamsI1tn9V0S8jicyX82qaFC0H/NKxv2e5mbqsgR80= k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kubectl v0.22.5 h1:diivOcs6dyDjpBqOpy9iiI3srZnW1khJDWwsFSapFt8= -k8s.io/kubectl v0.22.5/go.mod h1:uwKSKhaC6HOwnbk1cVLxVPYwfvazj9x06oZAOsL43N8= +k8s.io/kubectl v0.22.1/go.mod h1:mjAOgEbMNMtZWxnfM6jd+nPjPsaoLqO5xanc78WcSbw= +k8s.io/kubectl v0.22.3/go.mod h1:gcpQHPOx+Jke9Og6Li7YxR/ZuaOtFUeJw7xHH617tHs= +k8s.io/kubectl v0.22.4 h1:ECUO1QWyZ70DiIKEfgBx+8i9D98uspVOwgc1APs/07w= +k8s.io/kubectl v0.22.4/go.mod h1:ok2qRT6y2Gy4+y+mniJVyUMKeBHP4OWS9Rdtf/QTM5I= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/metrics v0.22.5 h1:2wNbA+Pk00Y+eJrfToksvckirugfbdWm3HQinwqDQFw= -k8s.io/metrics v0.22.5/go.mod h1:dCqOkoZQWLSfBhUtPFMiDrzJaPtXJlVePVuJbEx0hW8= +k8s.io/metrics v0.21.2/go.mod h1:wzlOINZMCtWq8dR9gHlyaOemmYlOpAoldEIXE82gAhI= +k8s.io/metrics v0.22.1/go.mod h1:i/ZNap89UkV1gLa26dn7fhKAdheJaKy+moOqJbiif7E= +k8s.io/metrics v0.22.3/go.mod h1:HbLFLRKtXzoC/6tHLQAlO9AeOBXZp2eB6SsgkbujoNI= +k8s.io/metrics v0.22.4 h1:NNJ9d5ez7DfueE00bWmOkEvmpbCramppzDLw7L7XwRQ= +k8s.io/metrics v0.22.4/go.mod h1:6F/iwuYb1w2QDCoHkeMFLf4pwHBcYKLm4mPtVHKYrIw= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a h1:8dYfu/Fc9Gz2rNJKB9IQRGgQOh2clmRzNIPPY1xLY5g= k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= oras.land/oras-go v0.4.0 h1:u6+7D+raZDYHwlz/uOwNANiRmyYDSSMW7A9E1xXycUQ= @@ -2044,16 +2302,24 @@ rsc.io/letsencrypt v0.0.3 h1:H7xDfhkaFFSYEJlKeq38RwX2jYcnTeHuDQyT+mMNMwM= rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/kind v0.11.1 h1:pVzOkhUwMBrCB0Q/WllQDO3v14Y+o2V0tFgjTqIUjwA= sigs.k8s.io/kind v0.11.1/go.mod h1:fRpgVhtqAWrtLB9ED7zQahUimpUXuG/iHT88xYqEGIA= +sigs.k8s.io/kustomize/api v0.8.8/go.mod h1:He1zoK0nk43Pc6NlV085xDXDXTNprtcyKZVm3swsdNY= sigs.k8s.io/kustomize/api v0.8.11 h1:LzQzlq6Z023b+mBtc6v72N2mSHYmN8x7ssgbf/hv0H8= sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g= sigs.k8s.io/kustomize/cmd/config v0.9.13/go.mod h1:7547FLF8W/lTaDf0BDqFTbZxM9zqwEJqCKN9sSR0xSs= sigs.k8s.io/kustomize/kustomize/v4 v4.2.0/go.mod h1:MOkR6fmhwG7hEDRXBYELTi5GSFcLwfqwzTRHW3kv5go= +sigs.k8s.io/kustomize/kyaml v0.10.17/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg= sigs.k8s.io/kustomize/kyaml v0.11.0 h1:9KhiCPKaVyuPcgOLJXkvytOvjMJLoxpjodiycb4gHsA= sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.2 h1:Hr/htKFmJEbtMgS/UD0N+gtgctAqz81t3nu+sPzynno= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/test/e2e/common.go b/test/e2e/common.go index 88fb4e5d42..6dac98bcad 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -12,7 +12,7 @@ import ( "testing" "time" - // k3dcluster "github.com/rancher/k3d/v5/cmd/cluster" + k3dcluster "github.com/rancher/k3d/v5/cmd/cluster" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -135,58 +135,58 @@ func (e2e *ZarfE2ETest) tearDownKind() error { return err } -// func (e2e *ZarfE2ETest) setUpK3D() error { - -// // Determine what the name of the zarfBinary should be -// e2e.zarfBinPath = path.Join("../../build", getCLIName()) - -// var err error -// // Create or get the kubeconfig -// e2e.kubeconfigPath, err = getKubeconfigPath() -// if err != nil { -// return err -// } - -// createClusterCommand := k3dcluster.NewCmdClusterCreate() -// err = createClusterCommand.ExecuteContext(context.TODO()) -// if err != nil { -// fmt.Println("ERROR WHEN TRYING TO SET UP K3D CLUSTER") -// return err -// } - -// // Get config and client for the k8s cluster -// e2e.restConfig, err = clientcmd.BuildConfigFromFlags("", e2e.kubeconfigPath) -// if err != nil { -// return err -// } -// e2e.clientset, err = kubernetes.NewForConfig(e2e.restConfig) -// if err != nil { -// return err -// } - -// // Wait for the cluster to have pods before we let the test suite run -// attempt := 0 -// for attempt < 10 { -// pods, err := e2e.clientset.CoreV1().Pods("kube-system").List(context.TODO(), metav1.ListOptions{}) -// if err == nil && len(pods.Items) >= 0 { -// fmt.Printf("💥 Cluster %s ready. You can access it by setting:\nexport KUBECONFIG='%s'\n", e2e.clusterName, e2e.kubeconfigPath) -// break -// } - -// time.Sleep(1 * time.Second) -// attempt++ -// if attempt > 15 { -// return errors.New("unable to connect to KinD cluster for e2e tests") -// } -// } -// return nil -// } - -// func (e2e *ZarfE2ETest) tearDownK3D() error { -// deleteClusterCommand := k3dcluster.NewCmdClusterDelete() -// err := deleteClusterCommand.ExecuteContext(context.TODO()) -// return err -// } +func (e2e *ZarfE2ETest) setUpK3D() error { + + // Determine what the name of the zarfBinary should be + e2e.zarfBinPath = path.Join("../../build", getCLIName()) + + var err error + // Create or get the kubeconfig + e2e.kubeconfigPath, err = getKubeconfigPath() + if err != nil { + return err + } + + createClusterCommand := k3dcluster.NewCmdClusterCreate() + err = createClusterCommand.ExecuteContext(context.TODO()) + if err != nil { + fmt.Println("ERROR WHEN TRYING TO SET UP K3D CLUSTER") + return err + } + + // Get config and client for the k8s cluster + e2e.restConfig, err = clientcmd.BuildConfigFromFlags("", e2e.kubeconfigPath) + if err != nil { + return err + } + e2e.clientset, err = kubernetes.NewForConfig(e2e.restConfig) + if err != nil { + return err + } + + // Wait for the cluster to have pods before we let the test suite run + attempt := 0 + for attempt < 10 { + pods, err := e2e.clientset.CoreV1().Pods("kube-system").List(context.TODO(), metav1.ListOptions{}) + if err == nil && len(pods.Items) >= 0 { + fmt.Printf("💥 Cluster %s ready. You can access it by setting:\nexport KUBECONFIG='%s'\n", e2e.clusterName, e2e.kubeconfigPath) + break + } + + time.Sleep(1 * time.Second) + attempt++ + if attempt > 15 { + return errors.New("unable to connect to KinD cluster for e2e tests") + } + } + return nil +} + +func (e2e *ZarfE2ETest) tearDownK3D() error { + deleteClusterCommand := k3dcluster.NewCmdClusterDelete() + err := deleteClusterCommand.ExecuteContext(context.TODO()) + return err +} func getCLIName() string { var binaryName string From d04a07b1ff862eab5bd1497f16652e23c7d82091 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Fri, 18 Feb 2022 14:08:34 -0500 Subject: [PATCH 06/25] change k3d version for testing to 5.2.1 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fc66fbe47d..7e4f6a1435 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/mholt/archiver/v3 v3.5.1 github.com/otiai10/copy v1.7.0 github.com/pterm/pterm v0.12.33 - github.com/rancher/k3d/v5 v5.2.0 + github.com/rancher/k3d/v5 v5.2.1 github.com/spf13/cobra v1.3.0 github.com/stretchr/testify v1.7.0 golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e diff --git a/go.sum b/go.sum index 29aa3163f4..84da83e9a1 100644 --- a/go.sum +++ b/go.sum @@ -1302,8 +1302,8 @@ github.com/pterm/pterm v0.12.33 h1:XiT50Pvdqn5O8FAiIqZMpXP6NkVEcmlUa+mkA1yWVCg= github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= github.com/rakyll/hey v0.1.4 h1:hhc8GIqHN4+rPFZvkM9lkCQGi7da0sINM83xxpFkbPA= github.com/rakyll/hey v0.1.4/go.mod h1:nAOTOo+L52KB9SZq/M6J18kxjto4yVtXQDjU2HgjUPI= -github.com/rancher/k3d/v5 v5.2.0 h1:5kQQkdKxy/iAEFNTS5blVHDhM0M2zUKz4BGq3eguo+0= -github.com/rancher/k3d/v5 v5.2.0/go.mod h1:wf9CUngX+Klerdc1rKlQV5OKzTQesCwoYGDMcB56DLQ= +github.com/rancher/k3d/v5 v5.2.1 h1:xuqyynhAySBX30ojO3A9zwpYwJA+ZPpkZENE6K0JP2g= +github.com/rancher/k3d/v5 v5.2.1/go.mod h1:wf9CUngX+Klerdc1rKlQV5OKzTQesCwoYGDMcB56DLQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= From 777dd64271278a0f5a8ccffc568e52ad5e4853cd Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Fri, 18 Feb 2022 14:09:07 -0500 Subject: [PATCH 07/25] cleanup e2e test for multi distro testing --- test/e2e/common.go | 72 ++++++++++++++++++++++++++++++------------- test/e2e/main_test.go | 72 +++++++++++++++++++++++++++++++------------ 2 files changed, 103 insertions(+), 41 deletions(-) diff --git a/test/e2e/common.go b/test/e2e/common.go index 6dac98bcad..45a8e5ee36 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -28,7 +28,7 @@ import ( type ZarfE2ETest struct { zarfBinPath string - clusterName string `default: "test-cluster"` + clusterName string kubeconfigPath string filesToRemove []string cmdsToKill []*exec.Cmd @@ -37,34 +37,33 @@ type ZarfE2ETest struct { restConfig *restclient.Config clientset *kubernetes.Clientset clusterAlreadyExists bool + initWithK3s bool } func getKubeconfigPath() (string, error) { - // k3dcluster.NewCmdClusterCreate() // Check if the $KUBECONFIG env is set - // TODO: It would probably be good to verify a useable kubeconfig lives here kubeconfigEnv := os.Getenv("KUBECONFIG") if kubeconfigEnv != "" { return kubeconfigEnv, nil } + // Get the kubeconfig in ~/.kube/config userHomeDir, err := os.UserHomeDir() if err != nil { return "", err } - configBaseDir := path.Join(userHomeDir, ".kube") if err := os.MkdirAll(configBaseDir, 0700); err != nil { return "", err } + // Get (or create) the config file kubeconfigPath := path.Join(configBaseDir, "config") _, err = os.OpenFile(kubeconfigPath, os.O_RDWR|os.O_CREATE, 0755) return kubeconfigPath, err } func (e2e *ZarfE2ETest) setUpKind() error { - // Determine what the name of the zarfBinary should be e2e.zarfBinPath = path.Join("../../build", getCLIName()) @@ -93,14 +92,7 @@ func (e2e *ZarfE2ETest) setUpKind() error { } // Get config and client for the k8s cluster - e2e.restConfig, err = clientcmd.BuildConfigFromFlags("", e2e.kubeconfigPath) - if err != nil { - return err - } - e2e.clientset, err = kubernetes.NewForConfig(e2e.restConfig) - if err != nil { - return err - } + err = e2e.buildConfigAndClientset() // Wait for the cluster to have pods before we let the test suite run attempt := 0 @@ -121,13 +113,22 @@ func (e2e *ZarfE2ETest) setUpKind() error { return err } +func (e2e *ZarfE2ETest) buildConfigAndClientset() error { + var err error + e2e.restConfig, err = clientcmd.BuildConfigFromFlags("", e2e.kubeconfigPath) + if err != nil { + return err + } + e2e.clientset, err = kubernetes.NewForConfig(e2e.restConfig) + + return err +} + func (e2e *ZarfE2ETest) tearDownKind() error { if os.Getenv("SKIP_TEARDOWN") != "" || e2e.clusterAlreadyExists { return nil } - // k3dcluster.NewCmdClusterCreate() - // Delete the cluster and kubeconfig file provider := cluster.NewProvider(cluster.ProviderWithLogger(kindcmd.NewLogger())) err := provider.Delete(e2e.clusterName, e2e.kubeconfigPath) @@ -136,7 +137,6 @@ func (e2e *ZarfE2ETest) tearDownKind() error { } func (e2e *ZarfE2ETest) setUpK3D() error { - // Determine what the name of the zarfBinary should be e2e.zarfBinPath = path.Join("../../build", getCLIName()) @@ -155,11 +155,7 @@ func (e2e *ZarfE2ETest) setUpK3D() error { } // Get config and client for the k8s cluster - e2e.restConfig, err = clientcmd.BuildConfigFromFlags("", e2e.kubeconfigPath) - if err != nil { - return err - } - e2e.clientset, err = kubernetes.NewForConfig(e2e.restConfig) + err = e2e.buildConfigAndClientset() if err != nil { return err } @@ -188,6 +184,16 @@ func (e2e *ZarfE2ETest) tearDownK3D() error { return err } +func (e2e *ZarfE2ETest) setUpK3s() error { + e2e.initWithK3s = true + return nil +} + +func (e2e *ZarfE2ETest) tearDownK3s() error { + e2e.initWithK3s = false + return nil +} + func getCLIName() string { var binaryName string if runtime.GOOS == "linux" { @@ -227,6 +233,14 @@ func (e2e *ZarfE2ETest) cleanupAfterTest(t *testing.T) { func (e2e *ZarfE2ETest) execCommandInPod(podname, namespace string, cmd []string) (string, string, error) { stdoutBuffer := &strings.Builder{} stderrBuffer := &strings.Builder{} + var err error + + if e2e.clientset == nil { + err = e2e.buildConfigAndClientset() + if err != nil { + return "", "", err + } + } req := e2e.clientset.CoreV1().RESTClient().Post().Resource("pods").Name(podname).Namespace(namespace).SubResource("exec") option := &v1.PodExecOptions{ @@ -254,6 +268,22 @@ func (e2e *ZarfE2ETest) execCommandInPod(podname, namespace string, cmd []string // TODO: It might be a nice feature to read some flag/env and change the stdout and stderr to pipe to the terminal running the test func (e2e *ZarfE2ETest) execZarfCommand(commandString ...string) (string, error) { + // Check if we need to deploy the k3s component + if e2e.initWithK3s && commandString[0] == "init" { + componentAdded := false + for idx, str := range commandString { + if strings.Contains(str, "components") { + commandString[idx] = str + ",k3s" + componentAdded = true + break + } + } + + if !componentAdded { + commandString = append(commandString, "--components=k3s") + } + } + output, err := exec.Command(e2e.zarfBinPath, commandString...).CombinedOutput() return string(output), err } diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go index bbf6f8732b..4e26b8e0a7 100644 --- a/test/e2e/main_test.go +++ b/test/e2e/main_test.go @@ -3,40 +3,72 @@ package test import ( "fmt" "os" + "strings" "testing" ) +type testSuite struct { + setupFunction func() error + cleanupFunction func() error +} + var ( e2e ZarfE2ETest + + distroTests = map[string]testSuite{ + "k3d": { + setupFunction: e2e.setUpK3D, + cleanupFunction: e2e.tearDownK3D, + }, + "kind": { + setupFunction: e2e.setUpKind, + cleanupFunction: e2e.tearDownKind, + }, + "k3s": { + setupFunction: e2e.setUpK3s, + cleanupFunction: e2e.tearDownK3s, + }, + } ) // TestMain will exec each test, one by one func TestMain(m *testing.M) { - // Create a kubeconfig and start up a KinD cluster - err := e2e.setUpKind() - if err != nil { - fmt.Printf("Unable to setup environment to run the e2e test because of err: %v\n", err) - os.Exit(1) - } - - // This defer teardown still runs if a panic/fatal happens while running the tests - defer e2e.tearDownKind() + retCode := 0 - // exec test and this returns an exit code to pass to os - retCode := m.Run() + distroToUse := strings.Split(os.Getenv("TESTDISTRO"), ",") + if len(distroToUse) == 0 { + // Use all the distros + for key := range distroTests { + distroToUse = append(distroToUse, key) + } + } - // Teardown the cluster now that tests are completed - e2e.tearDownKind() + for _, distroName := range distroToUse { + testSuiteFunctions, exists := distroTests[distroName] + if !exists { + fmt.Printf("Provided distro %v is not recognized, continuing tests but reporting as failure\n", distroName) + retCode = 1 + continue + } - // time.Sleep(15 * time.Second) + // Setup the cluster + err := testSuiteFunctions.setupFunction() + defer testSuiteFunctions.cleanupFunction() + if err != nil { + fmt.Printf("Unable to setup %s environment to run the e2e test because of err: %v\n", distroName, err) + os.Exit(1) + } - // err = e2e.setUpK3D() - // if err != nil { - // fmt.Printf("unable to set up k3d environment to run the e2e tests on") - // } + // exec test and capture exit code to pass to os + testCode := m.Run() + retCode = testCode | retCode - // retCode = m.Run() - // e2e.tearDownK3D() + // Teardown the cluster now that tests are completed + err = testSuiteFunctions.cleanupFunction() + if err != nil { + fmt.Printf("Unable to cleanly teardown %s environment because of err: %v\n", distroName, err) + } + } // If exit code is distinct of zero, the test will be failed (red) os.Exit(retCode) From 81df250ea4ccc5643e8559aa0e521b5557f2905a Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Fri, 18 Feb 2022 14:09:52 -0500 Subject: [PATCH 08/25] add unique github action for testing each e2e distro --- .github/workflows/test-k3d.yml | 23 +++++++++++++++++++ .github/workflows/test-k3s.yml | 23 +++++++++++++++++++ .../{test-command.yml => test-kind.yml} | 7 ++---- 3 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/test-k3d.yml create mode 100644 .github/workflows/test-k3s.yml rename .github/workflows/{test-command.yml => test-kind.yml} (80%) diff --git a/.github/workflows/test-k3d.yml b/.github/workflows/test-k3d.yml new file mode 100644 index 0000000000..ce8e676165 --- /dev/null +++ b/.github/workflows/test-k3d.yml @@ -0,0 +1,23 @@ +name: e2e-k3d +on: + - pull_request + +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - name: Install GoLang + uses: actions/setup-go@v2 + with: + go-version: 1.16.x + - name: Checkout Repo + uses: actions/checkout@v2 + - name: Build CLI + run: make build-cli-linux + - name: Sign into Repo1 + run: ./build/zarf tools registry login registry1.dso.mil -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} + - name: Make Packages + run: make init-package + + - name: Run Tests + run: TESTDISTRO=k3d make test-new-e2e diff --git a/.github/workflows/test-k3s.yml b/.github/workflows/test-k3s.yml new file mode 100644 index 0000000000..2b69746044 --- /dev/null +++ b/.github/workflows/test-k3s.yml @@ -0,0 +1,23 @@ +name: e2e-k3s +on: + - pull_request + +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - name: Install GoLang + uses: actions/setup-go@v2 + with: + go-version: 1.16.x + - name: Checkout Repo + uses: actions/checkout@v2 + - name: Build CLI + run: make build-cli-linux + - name: Sign into Repo1 + run: ./build/zarf tools registry login registry1.dso.mil -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} + - name: Make Packages + run: make init-package + + - name: Run Tests + run: TESTDISTRO=k3s make test-new-e2e diff --git a/.github/workflows/test-command.yml b/.github/workflows/test-kind.yml similarity index 80% rename from .github/workflows/test-command.yml rename to .github/workflows/test-kind.yml index 58ca2a4ab2..7c6f399d1c 100644 --- a/.github/workflows/test-command.yml +++ b/.github/workflows/test-kind.yml @@ -1,7 +1,4 @@ -# Attribution for a bunch of this goes to CloudPosse -# https://github.com/cloudposse/actions/blob/master/.github/workflows/test-command.yml - -name: e2e +name: e2e-kind on: - pull_request @@ -30,4 +27,4 @@ jobs: name: test-cluster - name: Run Tests - run: make test-new-e2e + run: TESTDISTRO=kind make test-new-e2e From 953d4802b55bae83ff77facf90e5ae57b78cd342 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Fri, 18 Feb 2022 14:27:01 -0500 Subject: [PATCH 09/25] turns out its useful to build dependencies --- .github/workflows/test-k3d.yml | 2 +- .github/workflows/test-k3s.yml | 2 +- .github/workflows/test-kind.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-k3d.yml b/.github/workflows/test-k3d.yml index ce8e676165..b2dcfa2733 100644 --- a/.github/workflows/test-k3d.yml +++ b/.github/workflows/test-k3d.yml @@ -20,4 +20,4 @@ jobs: run: make init-package - name: Run Tests - run: TESTDISTRO=k3d make test-new-e2e + run: TESTDISTRO=k3d make build-and-test-e2e diff --git a/.github/workflows/test-k3s.yml b/.github/workflows/test-k3s.yml index 2b69746044..dee4d0b9d4 100644 --- a/.github/workflows/test-k3s.yml +++ b/.github/workflows/test-k3s.yml @@ -20,4 +20,4 @@ jobs: run: make init-package - name: Run Tests - run: TESTDISTRO=k3s make test-new-e2e + run: TESTDISTRO=k3s make build-and-test-e2e diff --git a/.github/workflows/test-kind.yml b/.github/workflows/test-kind.yml index 7c6f399d1c..3d457e31bb 100644 --- a/.github/workflows/test-kind.yml +++ b/.github/workflows/test-kind.yml @@ -27,4 +27,4 @@ jobs: name: test-cluster - name: Run Tests - run: TESTDISTRO=kind make test-new-e2e + run: TESTDISTRO=kind make build-and-test-e2e From 7390004a8a4699557e0db180850916a7d4309e22 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Fri, 18 Feb 2022 17:49:40 -0500 Subject: [PATCH 10/25] fix setup for k3s testing --- test/e2e/common.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/e2e/common.go b/test/e2e/common.go index 45a8e5ee36..de63835908 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -185,6 +185,16 @@ func (e2e *ZarfE2ETest) tearDownK3D() error { } func (e2e *ZarfE2ETest) setUpK3s() error { + // Determine what the name of the zarfBinary should be + e2e.zarfBinPath = path.Join("../../build", getCLIName()) + + var err error + // Create or get the kubeconfig + e2e.kubeconfigPath, err = getKubeconfigPath() + if err != nil { + return err + } + e2e.initWithK3s = true return nil } From fc8f9e07cbced8330fa95f778fb766c43d836018 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Fri, 18 Feb 2022 21:06:51 -0500 Subject: [PATCH 11/25] try to make k3s run as root during e2e pileine --- .github/workflows/test-k3s.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test-k3s.yml b/.github/workflows/test-k3s.yml index dee4d0b9d4..ff6c580396 100644 --- a/.github/workflows/test-k3s.yml +++ b/.github/workflows/test-k3s.yml @@ -19,5 +19,7 @@ jobs: - name: Make Packages run: make init-package + - name: Try becoming root to run the tests + run: sudo su - name: Run Tests run: TESTDISTRO=k3s make build-and-test-e2e From 718a372d4df3ff15be89fb2db1b6a71d53e4113b Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Mon, 21 Feb 2022 18:01:47 +0000 Subject: [PATCH 12/25] make sure we clean up kubeconfig after e2e test --- test/e2e/common.go | 2 ++ test/e2e/e2e_general_cli_test.go | 1 - test/e2e/main_test.go | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/test/e2e/common.go b/test/e2e/common.go index de63835908..004f595e16 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -181,6 +181,7 @@ func (e2e *ZarfE2ETest) setUpK3D() error { func (e2e *ZarfE2ETest) tearDownK3D() error { deleteClusterCommand := k3dcluster.NewCmdClusterDelete() err := deleteClusterCommand.ExecuteContext(context.TODO()) + os.Remove(e2e.kubeconfigPath) return err } @@ -201,6 +202,7 @@ func (e2e *ZarfE2ETest) setUpK3s() error { func (e2e *ZarfE2ETest) tearDownK3s() error { e2e.initWithK3s = false + os.Remove(e2e.kubeconfigPath) return nil } diff --git a/test/e2e/e2e_general_cli_test.go b/test/e2e/e2e_general_cli_test.go index 88a8409677..539c0769a9 100644 --- a/test/e2e/e2e_general_cli_test.go +++ b/test/e2e/e2e_general_cli_test.go @@ -54,7 +54,6 @@ func TestGeneralCLI(t *testing.T) { expectedOutString := "Log level set to warn" require.Contains(t, output, expectedOutString, "The log level should be changed to 'warn'") - e2e.cleanupAfterTest(t) } func TestInitZarf(t *testing.T) { diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go index 4e26b8e0a7..9267929df5 100644 --- a/test/e2e/main_test.go +++ b/test/e2e/main_test.go @@ -36,7 +36,7 @@ func TestMain(m *testing.M) { retCode := 0 distroToUse := strings.Split(os.Getenv("TESTDISTRO"), ",") - if len(distroToUse) == 0 { + if len(distroToUse) == 1 && distroToUse[0] == "" { // Use all the distros for key := range distroTests { distroToUse = append(distroToUse, key) From 20834653286610826241385cdc35a6d86ace7d05 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Mon, 21 Feb 2022 18:02:40 +0000 Subject: [PATCH 13/25] run k3s e2e test as root --- .github/workflows/test-k3s.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/test-k3s.yml b/.github/workflows/test-k3s.yml index ff6c580396..7112387743 100644 --- a/.github/workflows/test-k3s.yml +++ b/.github/workflows/test-k3s.yml @@ -18,8 +18,5 @@ jobs: run: ./build/zarf tools registry login registry1.dso.mil -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} - name: Make Packages run: make init-package - - - name: Try becoming root to run the tests - run: sudo su - name: Run Tests - run: TESTDISTRO=k3s make build-and-test-e2e + run: sudo TESTDISTRO=k3s make build-and-test-e2e From 3bbde2dd10d045586f1c3de5722c9454f01122f8 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Mon, 21 Feb 2022 18:25:49 +0000 Subject: [PATCH 14/25] wip, extend time and break apart build steps --- .github/workflows/test-k3s.yml | 4 ++-- Makefile | 5 ++++- test/e2e/e2e_data_injection_test.go | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-k3s.yml b/.github/workflows/test-k3s.yml index 7112387743..dd23d89ea0 100644 --- a/.github/workflows/test-k3s.yml +++ b/.github/workflows/test-k3s.yml @@ -17,6 +17,6 @@ jobs: - name: Sign into Repo1 run: ./build/zarf tools registry login registry1.dso.mil -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} - name: Make Packages - run: make init-package + run: make build-packages-for-e2e - name: Run Tests - run: sudo TESTDISTRO=k3s make build-and-test-e2e + run: sudo TESTDISTRO=k3s make test-new-e2e diff --git a/Makefile b/Makefile index 10b4f36d76..a110158cfe 100644 --- a/Makefile +++ b/Makefile @@ -105,10 +105,13 @@ test-e2e: package-example-game test-cloud-e2e-example-game ## DEPRECATED - to be .PHONY: build-and-test-e2e build-and-test-e2e: build-cli init-package package-example-game package-example-gitops-data package-example-data-injection test-new-e2e ## Builds the cli and init package and runs the local e2e tests +.PHONY: build-packages-for-e2e +build-packages-for-e2e: build-cli init-package package-example-game package-example-gitops-data package-example-data-injection + # TODO: Rename this once we are certain this is the e2e approach we are going to be taking # TODO: I'm pretty sure there's some way Makefiles could be setup to not run dependant steps if their results are already cached or something # That way we wouldn't need this target and can just call build-and-test-e2e and not have to wait for the build if it was already built. # TODO: This can be cleaned up a little more when `zarf init` is able to provide the path to the `zarf-init.tar.zst` .PHONY: test-new-e2e test-new-e2e: ## Run e2e tests on a KiND cluster. All dependencies are assumed to be built and in the ./build directory - cd test/e2e && cp ../../build/zarf-init.tar.zst . && go test ./... -v -timeout 1200s && rm zarf-init.tar.zst + cd test/e2e && cp ../../build/zarf-init.tar.zst . && go test ./... -v -timeout 2400s && rm zarf-init.tar.zst diff --git a/test/e2e/e2e_data_injection_test.go b/test/e2e/e2e_data_injection_test.go index 57538e37ef..16924b13f7 100644 --- a/test/e2e/e2e_data_injection_test.go +++ b/test/e2e/e2e_data_injection_test.go @@ -22,7 +22,7 @@ func TestDataInjection(t *testing.T) { // TODO: This retry is disgusting, but race condition... var execStdOut string attempt := 0 - for attempt < 5 && execStdOut == "" { + for attempt < 10 && execStdOut == "" { execStdOut, _, err = e2e.execCommandInPod("data-injection", "demo", []string{"ls", "/test"}) attempt++ time.Sleep(2 * time.Second) From 3ae1afe1e13cebd5a05009bc489a6fac73545c58 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Mon, 21 Feb 2022 18:36:54 +0000 Subject: [PATCH 15/25] doanlod dependencies early for k3s --- .github/workflows/test-k3s.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test-k3s.yml b/.github/workflows/test-k3s.yml index dd23d89ea0..c151141fb8 100644 --- a/.github/workflows/test-k3s.yml +++ b/.github/workflows/test-k3s.yml @@ -12,6 +12,10 @@ jobs: go-version: 1.16.x - name: Checkout Repo uses: actions/checkout@v2 + - name: Download dependences + run: | + go mod download + sudo go mod download - name: Build CLI run: make build-cli-linux - name: Sign into Repo1 From bf77ced6521275efae432f0f4f8636919365c9aa Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Tue, 22 Feb 2022 13:20:09 -0500 Subject: [PATCH 16/25] remove old e2e content --- .github/workflows/test-k3s.yml | 26 --- test/e2e/adr.md | 24 --- test/old-e2e/common.go | 187 --------------------- test/old-e2e/e2e_data_injection_test.go | 43 ----- test/old-e2e/e2e_example_game_test.go | 53 ------ test/old-e2e/e2e_general_cli_test.go | 88 ---------- test/old-e2e/e2e_gitea_and_grafana_test.go | 45 ----- test/old-e2e/e2e_gitops_example_test.go | 63 ------- 8 files changed, 529 deletions(-) delete mode 100644 .github/workflows/test-k3s.yml delete mode 100644 test/e2e/adr.md delete mode 100644 test/old-e2e/common.go delete mode 100644 test/old-e2e/e2e_data_injection_test.go delete mode 100644 test/old-e2e/e2e_example_game_test.go delete mode 100644 test/old-e2e/e2e_general_cli_test.go delete mode 100644 test/old-e2e/e2e_gitea_and_grafana_test.go delete mode 100644 test/old-e2e/e2e_gitops_example_test.go diff --git a/.github/workflows/test-k3s.yml b/.github/workflows/test-k3s.yml deleted file mode 100644 index c151141fb8..0000000000 --- a/.github/workflows/test-k3s.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: e2e-k3s -on: - - pull_request - -jobs: - build-and-test: - runs-on: ubuntu-latest - steps: - - name: Install GoLang - uses: actions/setup-go@v2 - with: - go-version: 1.16.x - - name: Checkout Repo - uses: actions/checkout@v2 - - name: Download dependences - run: | - go mod download - sudo go mod download - - name: Build CLI - run: make build-cli-linux - - name: Sign into Repo1 - run: ./build/zarf tools registry login registry1.dso.mil -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} - - name: Make Packages - run: make build-packages-for-e2e - - name: Run Tests - run: sudo TESTDISTRO=k3s make test-new-e2e diff --git a/test/e2e/adr.md b/test/e2e/adr.md deleted file mode 100644 index e11864e89e..0000000000 --- a/test/e2e/adr.md +++ /dev/null @@ -1,24 +0,0 @@ -# Zarf E2E Approach ADR - -This is the template in [Documenting architecture decisions - Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions). -You can use [adr-tools](https://github.com/npryce/adr-tools) for managing the ADR files. - -In each ADR file, write these sections: - -# Title - -## Status - -What is the status, such as proposed, accepted, rejected, deprecated, superseded, etc.? - -## Context - -What is the issue that we're seeing that is motivating this decision or change? - -## Decision - -What is the change that we're proposing and/or doing? - -## Consequences - -What becomes easier or more difficult to do because of this change? diff --git a/test/old-e2e/common.go b/test/old-e2e/common.go deleted file mode 100644 index 2949ce959c..0000000000 --- a/test/old-e2e/common.go +++ /dev/null @@ -1,187 +0,0 @@ -package test - -import ( - "bufio" - "encoding/base64" - "fmt" - "github.com/gruntwork-io/terratest/modules/random" - "github.com/gruntwork-io/terratest/modules/retry" - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" - "io/ioutil" - "os" - "testing" - "time" - - "github.com/gruntwork-io/terratest/modules/aws" - "github.com/gruntwork-io/terratest/modules/ssh" - "github.com/gruntwork-io/terratest/modules/terraform" -) - -type ZarfE2ETest struct { - testing *testing.T - tempFolder string - username string - terraformOptions *terraform.Options - keyPair *aws.Ec2Keypair - publicIP string - publicHost ssh.Host -} - -func NewE2ETest(testing *testing.T) *ZarfE2ETest { - - testing.Parallel() - - // Copy the terraform folder to a temp directory so we can run multiple tests in parallel - tempFolder := teststructure.CopyTerraformFolderToTemp(testing, "..", "tf/public-ec2-instance") - - e2e := ZarfE2ETest{ - testing: testing, - tempFolder: tempFolder, - // Our SSH username, will change based on which AMI we use - username: "ubuntu", - } - - // Deploy the terraform infra - teststructure.RunTestStage(testing, "SETUP", e2e.setup) - - return &e2e -} - -func (e2e *ZarfE2ETest) runSSHCommand(format string, a ...interface{}) (string, error) { - command := fmt.Sprintf(format, a...) - return ssh.CheckSshCommandE(e2e.testing, e2e.publicHost, command) -} - -func (e2e *ZarfE2ETest) teardown() { - keyPair := teststructure.LoadEc2KeyPair(e2e.testing, e2e.tempFolder) - aws.DeleteEC2KeyPair(e2e.testing, keyPair) - - terraformOptions := teststructure.LoadTerraformOptions(e2e.testing, e2e.tempFolder) - terraform.Destroy(e2e.testing, terraformOptions) -} - -func (e2e *ZarfE2ETest) setup() { - terraformOptions, keyPair, err := e2e.configureTerraformOptions() - require.NoError(e2e.testing, err) - - // Save the options and key pair so later test stages can use them - teststructure.SaveTerraformOptions(e2e.testing, e2e.tempFolder, terraformOptions) - teststructure.SaveEc2KeyPair(e2e.testing, e2e.tempFolder, keyPair) - - // This will run `terraform init` and `terraform apply` and fail the test if there are any errors - terraform.InitAndApply(e2e.testing, terraformOptions) - - // Run `terraform output` to get the value of an output variable - e2e.publicIP = terraform.Output(e2e.testing, terraformOptions, "public_instance_ip") - e2e.terraformOptions = terraformOptions - e2e.keyPair = keyPair - - // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", - // as we know the Instance is running an Ubuntu AMI that has such a user - e2e.publicHost = ssh.Host{ - Hostname: e2e.publicIP, - SshKeyPair: e2e.keyPair.KeyPair, - SshUserName: e2e.username, - } -} - -func (e2e *ZarfE2ETest) configureTerraformOptions() (*terraform.Options, *aws.Ec2Keypair, error) { - // A unique ID we can use to namespace resources so we don't clash with anything already in the AWS account or - // tests running in parallel - uniqueID := random.UniqueId() - namespace := "zarf" - stage := "terratest" - name := fmt.Sprintf("e2e-%s", uniqueID) - - // Get the region to use from the system's environment - awsRegion, err := getAwsRegion() - if err != nil { - return nil, nil, err - } - - instanceType := "t3a.large" - - // Create an EC2 KeyPair that we can use for SSH access - keyPairName := fmt.Sprintf("%s-%s-%s", namespace, stage, name) - keyPair := aws.CreateAndImportEC2KeyPair(e2e.testing, awsRegion, keyPairName) - - // Construct the terraform options with default retryable errors to handle the most common retryable errors in - // terraform testing. - terraformOptions := terraform.WithDefaultRetryableErrors(e2e.testing, &terraform.Options{ - // The path to where our Terraform code is located - TerraformDir: e2e.tempFolder, - - // Variables to pass to our Terraform code using -var options - Vars: map[string]interface{}{ - "aws_region": awsRegion, - "namespace": namespace, - "stage": stage, - "name": name, - "instance_type": instanceType, - "key_pair_name": keyPairName, - }, - }) - - return terraformOptions, keyPair, nil -} - -// syncFileToRemoteServer uses SCP to sync a file from source to destination. `destPath` can be absolute or relative to -// the SSH user's home directory. It has to be in a directory that the SSH user is allowed to write to. -func (e2e *ZarfE2ETest) syncFileToRemoteServer(srcPath string, destPath string, chmod string) { - // Run `terraform output` to get the value of an output variable - publicInstanceIP := terraform.Output(e2e.testing, e2e.terraformOptions, "public_instance_ip") - - // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", - // as we know the Instance is running an Ubuntu AMI that has such a user - host := ssh.Host{ - Hostname: publicInstanceIP, - SshKeyPair: e2e.keyPair.KeyPair, - SshUserName: e2e.username, - } - - // It can take a minute or so for the Instance to boot up, so retry a few times - maxRetries := 15 - timeBetweenRetries, err := time.ParseDuration("5s") - require.NoError(e2e.testing, err) - - // Wait for the instance to be ready - _, err = retry.DoWithRetryE(e2e.testing, "Wait for the instance to be ready", maxRetries, timeBetweenRetries, func() (string, error) { - _, err := ssh.CheckSshCommandE(e2e.testing, host, "whoami") - if err != nil { - return "", err - } - return "", nil - }) - require.NoError(e2e.testing, err) - - // Create the folder structure - output, err := ssh.CheckSshCommandE(e2e.testing, host, fmt.Sprintf("bash -c 'install -m 644 -D /dev/null \"%s\"'", destPath)) - require.NoError(e2e.testing, err, output) - - // The ssh lib only supports sending strings so we'll base64encode it first - f, err := os.Open(srcPath) - require.NoError(e2e.testing, err) - reader := bufio.NewReader(f) - content, err := ioutil.ReadAll(reader) - require.NoError(e2e.testing, err) - encodedContent := base64.StdEncoding.EncodeToString(content) - err = ssh.ScpFileToE(e2e.testing, host, 0600, fmt.Sprintf("%s.b64", destPath), encodedContent) - require.NoError(e2e.testing, err) - output, err = ssh.CheckSshCommandE(e2e.testing, host, fmt.Sprintf("base64 -d \"%s.b64\" > \"%s\" && chmod \"%s\" \"%s\"", destPath, destPath, chmod, destPath)) - require.NoError(e2e.testing, err, output) -} - -// getAwsRegion returns the desired AWS region to use by first checking the env var AWS_REGION, then checking -// AWS_DEFAULT_REGION if AWS_REGION isn't set. If neither is set it returns an error -func getAwsRegion() (string, error) { - val, present := os.LookupEnv("AWS_REGION") - if !present { - val, present = os.LookupEnv("AWS_DEFAULT_REGION") - } - if !present { - return "", fmt.Errorf("expected either AWS_REGION or AWS_DEFAULT_REGION env var to be set, but they were not") - } else { - return val, nil - } -} diff --git a/test/old-e2e/e2e_data_injection_test.go b/test/old-e2e/e2e_data_injection_test.go deleted file mode 100644 index f7b6af82ae..0000000000 --- a/test/old-e2e/e2e_data_injection_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package test - -import ( - "fmt" - "testing" - - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" -) - -func TestDataInjection(t *testing.T) { - - e2e := NewE2ETest(t) - - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) - - // Upload the Zarf artifacts - teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { - e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") - e2e.syncFileToRemoteServer("../../build/zarf-package-data-injection-demo.tar", fmt.Sprintf("/home/%s/build/zarf-package-data-injection-demo.tar", e2e.username), "0600") - }) - - teststructure.RunTestStage(e2e.testing, "TEST", func() { - // run `zarf init` - output, err := e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Deploy the data injection example - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-data-injection-demo.tar --confirm'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Test to confirm the root file was placed - output, err = e2e.runSSHCommand(`sudo bash -c '/usr/sbin/kubectl -n demo exec data-injection -- ls /test | grep this-is-an-example'`) - require.NoError(e2e.testing, err, output) - - // Test to confirm the subdirectory file was placed - output, err = e2e.runSSHCommand(`sudo bash -c '/usr/sbin/kubectl -n demo exec data-injection -- ls /test/subdirectory-test | grep this-is-an-example'`) - require.NoError(e2e.testing, err, output) - }) - -} diff --git a/test/old-e2e/e2e_example_game_test.go b/test/old-e2e/e2e_example_game_test.go deleted file mode 100644 index 5a9e3852b5..0000000000 --- a/test/old-e2e/e2e_example_game_test.go +++ /dev/null @@ -1,53 +0,0 @@ -package test - -import ( - "fmt" - "testing" - "time" - - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" -) - -func TestE2eExampleGame(t *testing.T) { - - e2e := NewE2ETest(t) - - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) - - // Upload the Zarf artifacts - teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { - e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") - e2e.syncFileToRemoteServer("../../build/zarf-package-appliance-demo-multi-games.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-appliance-demo-multi-games.tar.zst", e2e.username), "0600") - }) - - teststructure.RunTestStage(e2e.testing, "TEST", func() { - // Make sure `zarf --help` doesn't error - output, err := e2e.runSSHCommand("sudo /home/%s/build/zarf --help", e2e.username) - require.NoError(e2e.testing, err, output) - - // run `zarf init` - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Deploy the game - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-appliance-demo-multi-games.tar.zst --confirm'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Establish the port-forward into the game service; give the service a few seconds to come up since this is not a command we can retry - time.Sleep(5 * time.Second) - output, err = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect doom --local-port 22333 &> /dev/nul &)'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Right now we're just checking that `curl` returns 0. It can be enhanced by scraping the HTML that gets returned or something. - output, err = e2e.runSSHCommand("bash -c '[[ $(curl -sfSL --retry 15 --retry-connrefused --retry-delay 5 -o /dev/null -w \"%%{http_code}\" 'http://127.0.0.1:22333?doom') == 200 ]]'") - require.NoError(e2e.testing, err, output) - - // Run `zarf destroy` to make sure that works correctly - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf destroy --confirm'", e2e.username) - require.NoError(e2e.testing, err, output) - }) - -} diff --git a/test/old-e2e/e2e_general_cli_test.go b/test/old-e2e/e2e_general_cli_test.go deleted file mode 100644 index 74afbe1316..0000000000 --- a/test/old-e2e/e2e_general_cli_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package test - -import ( - "fmt" - "testing" - - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestGeneralCli(t *testing.T) { - - e2e := NewE2ETest(t) - - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) - - // Upload the Zarf artifacts - teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { - e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-package-kafka-strimzi-demo.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-kafka-strimzi-demo.tar.zst", e2e.username), "0700") - }) - - teststructure.RunTestStage(e2e.testing, "TEST", func() { - // Test `zarf prepare sha256sum` for a local asset - expectedShasum := "61b50898f982d015ed87093ba822de0fe011cec6dd67db39f99d8c56391a6109\n" - output, err := e2e.runSSHCommand("cd /home/%s/build && echo 'random test data 🦄' > shasum-test-file", e2e.username) - require.NoError(e2e.testing, err, output) - - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf prepare sha256sum shasum-test-file 2> /dev/null", e2e.username) - require.NoError(e2e.testing, err, output) - assert.Equal(e2e.testing, expectedShasum, output, "The expected SHASUM should equal the actual SHASUM") - - // Test `zarf prepare sha256sum` for a remote asset - expectedShasum = "c3cdea0573ba5a058ec090b5d2683bf398e8b1614c37ec81136ed03b78167617\n" - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf prepare sha256sum https://zarf-public.s3-us-gov-west-1.amazonaws.com/pipelines/zarf-prepare-shasum-remote-test-file.txt 2> /dev/null", e2e.username) - require.NoError(e2e.testing, err, output) - assert.Equal(e2e.testing, expectedShasum, output, "The expected SHASUM should equal the actual SHASUM") - - // Test `zarf version` - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf version", e2e.username) - require.NoError(e2e.testing, err, output) - assert.NotNil(e2e.testing, output) - assert.NotEqual(e2e.testing, len(output), 0, "Zarf version should not be an empty string") - assert.NotEqual(e2e.testing, string(output), "UnknownVersion", "Zarf version should not be the default value") - - // Test for expected failure when given a bad component input - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf init --confirm --components k3s,foo,logging", e2e.username) - require.Error(e2e.testing, err, output) - - // Test for expected failure when given invalid hostnames - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf init --confirm --host localhost", e2e.username) - require.Error(e2e.testing, err, output) - - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf pki regenerate --host zarf@server", e2e.username) - require.Error(e2e.testing, err, output) - output, err = e2e.runSSHCommand("cd /home/%s/build && ./zarf pki regenerate --host some_unique_server", e2e.username) - require.Error(e2e.testing, err, output) - - // Initialize Zarf for the next set of tests - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Verify that we do not timeout when passing the `--confirm` flag without specifying the `--components` flag - output, err = e2e.runSSHCommand("sudo timeout 120 sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-kafka-strimzi-demo.tar.zst --confirm' || false", e2e.username) - require.NoError(e2e.testing, err, output) - - // Test that `zarf package deploy` doesn't die when given a URL - // NOTE: Temporarily commenting this out because this seems out of scope for a general cli test. Having this included also means we would have to fully standup a `zarf init` command. - // TODO: Move this to it's own e2e test. - // output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo bash -c 'cd /home/%s/build && ./zarf package deploy https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom.tar.zst --confirm --insecure'", username)) - // require.NoError(t, err, output) - // output, err = ssh.CheckSshCommandE(t, publicHost, fmt.Sprintf("sudo bash -c 'cd /home/%s/build && ./zarf package deploy https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom.tar.zst --confirm --shasum e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'", username)) - // require.NoError(t, err, output) - - // Test that `zarf package deploy` gives an error if deploying a remote package without the --insecure or --shasum flags - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy https://zarf-examples.s3.amazonaws.com/zarf-package-appliance-demo-doom-20210125.tar.zst --confirm'", e2e.username) - require.Error(e2e.testing, err, output) - - // Test that changing the log level actually applies the requested level - output, _ = e2e.runSSHCommand("cd /home/%s/build && ./zarf version --log-level warn 1> /dev/null", e2e.username) - expectedOutString := "Log level set to warn" - require.Contains(e2e.testing, output, expectedOutString, "The log level should be changed to 'warn'") - }) - -} diff --git a/test/old-e2e/e2e_gitea_and_grafana_test.go b/test/old-e2e/e2e_gitea_and_grafana_test.go deleted file mode 100644 index ab77305ff8..0000000000 --- a/test/old-e2e/e2e_gitea_and_grafana_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package test - -import ( - "fmt" - "testing" - "time" - - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" -) - -func TestGiteaAndGrafana(t *testing.T) { - e2e := NewE2ETest(t) - - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) - - // Upload the Zarf artifacts - teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { - e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") - }) - - teststructure.RunTestStage(e2e.testing, "TEST", func() { - // run `zarf init` - output, err := e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s,logging,gitops-service'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Establish the port-forward into the gitea service; give the service a few seconds to come up since this is not a command we can retry - time.Sleep(15 * time.Second) - _, _ = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect git &> /dev/nul &)'", e2e.username) - - // Make sure Gitea comes up cleanly - output, err = e2e.runSSHCommand(`bash -c '[[ $(curl -sfSL -o /dev/null -w '%%{http_code}' 'http://127.0.0.1:45003/explore/repos') == 200 ]]'`) - require.NoError(e2e.testing, err, output) - - // Establish the port-forward into the logging service - _, _ = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect logging &> /dev/nul &)'", e2e.username) - - // // Make sure Grafana comes up cleanly - output, err = e2e.runSSHCommand(`bash -c '[[ $(curl -sfSL -o /dev/null -w '%%{http_code}' 'http://127.0.0.1:45002/monitor/login') == 200 ]]'`) - require.NoError(e2e.testing, err, output) - }) - -} diff --git a/test/old-e2e/e2e_gitops_example_test.go b/test/old-e2e/e2e_gitops_example_test.go deleted file mode 100644 index 6d15e61701..0000000000 --- a/test/old-e2e/e2e_gitops_example_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package test - -import ( - "fmt" - "testing" - - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" -) - -func TestGitopsExample(t *testing.T) { - e2e := NewE2ETest(t) - - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) - - // Upload the Zarf artifacts - teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { - e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") - e2e.syncFileToRemoteServer("../../build/zarf-package-gitops-service-data.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-gitops-service-data.tar.zst", e2e.username), "0600") - }) - - teststructure.RunTestStage(t, "TEST", func() { - // run `zarf init` - output, err := e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s,logging,gitops-service --host 127.0.0.1'", e2e.username) - require.NoError(t, err, output) - - // Deploy the gitops example - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-gitops-service-data.tar.zst --confirm'", e2e.username) - require.NoError(t, err, output) - - // Create a tunnel to the git resources - output, err = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect git &> /dev/nul &)'", e2e.username) - require.NoError(t, err, output) - - // Check for full git repo mirror(foo.git) from https://github.com/stefanprodan/podinfo.git - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && git clone http://zarf-git-user:$(./zarf tools get-admin-password)@127.0.0.1:45003/zarf-git-user/mirror__github.com__stefanprodan__podinfo.git'", e2e.username) - require.NoError(t, err, output) - - // Check for tagged git repo mirror (foo.git@1.2.3) from https://github.com/defenseunicorns/zarf.git@v0.15.0 - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && git clone http://zarf-git-user:$(./zarf tools get-admin-password)@127.0.0.1:45003/zarf-git-user/mirror__github.com__defenseunicorns__zarf.git'", e2e.username) - require.NoError(t, err, output) - - // Check for correct tag - expectedTag := "v0.15.0\n" - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build/mirror__github.com__defenseunicorns__zarf && git tag'", e2e.username) - require.NoError(t, err, output) - require.Equal(t, expectedTag, output, "Expected tag should match output") - - // Check for correct commits - expectedCommits := "9eb207e\n7636dd0\ne02cec9" - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build/mirror__github.com__defenseunicorns__zarf && git log -3 --oneline --pretty=format:\"%%h\"'", e2e.username) - require.NoError(t, err, output) - require.Equal(t, expectedCommits, output, "Expected commits should match output") - - // Check for existence of tags without specifying them, signifying that not using '@1.2.3' syntax brought over the whole repo - expectedTag = "0.2.2" - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build/mirror__github.com__stefanprodan__podinfo && git tag'", e2e.username) - require.NoError(t, err, output) - require.Contains(t, output, expectedTag, "Output should contain expected tag") - }) -} From 107f10f1cb5500214cbe729f312eaeaf978d4791 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Tue, 22 Feb 2022 13:22:17 -0500 Subject: [PATCH 17/25] misc test code cleanup --- .github/workflows/test-k3d.yml | 2 +- .github/workflows/test-kind.yml | 9 +---- Makefile | 54 ++++++++++------------------- test/e2e/common.go | 1 - test/e2e/e2e_data_injection_test.go | 5 ++- test/e2e/main_test.go | 37 ++++++++++++-------- 6 files changed, 45 insertions(+), 63 deletions(-) diff --git a/.github/workflows/test-k3d.yml b/.github/workflows/test-k3d.yml index b2dcfa2733..0d5cc32d60 100644 --- a/.github/workflows/test-k3d.yml +++ b/.github/workflows/test-k3d.yml @@ -20,4 +20,4 @@ jobs: run: make init-package - name: Run Tests - run: TESTDISTRO=k3d make build-and-test-e2e + run: TESTDISTRO=k3d make test-e2e diff --git a/.github/workflows/test-kind.yml b/.github/workflows/test-kind.yml index 3d457e31bb..d627f44d69 100644 --- a/.github/workflows/test-kind.yml +++ b/.github/workflows/test-kind.yml @@ -19,12 +19,5 @@ jobs: - name: Make Packages run: make init-package - - uses: engineerd/setup-kind@v0.5.0 - with: - wait: 300s - version: v0.11.1 - image: kindest/node:v1.21.1 - name: test-cluster - - name: Run Tests - run: TESTDISTRO=kind make build-and-test-e2e + run: TESTDISTRO=kind make test-e2e diff --git a/Makefile b/Makefile index a110158cfe..edf779ba0e 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ build-cli-linux: ## Build the Linux CLI build-cli-mac: ## Build the Mac CLI cd cli && $(MAKE) build-mac -build-cli: clean build-cli-linux build-cli-mac ## Build the CLI +build-cli: build-cli-linux build-cli-mac ## Build the CLI init-package: ## Create the zarf init package, macos "brew install coreutils" first $(ZARF_BIN) package create --confirm @@ -78,40 +78,24 @@ package-example-gitops-data: package-example-tiny-kafka: cd examples/tiny-kafka && ../../$(ZARF_BIN) package create --confirm && mv zarf-package-* ../../build/ -.PHONY: test-cloud-e2e-example-game -test-cloud-e2e-example-game: ## Runs the Doom game as an E2E test in the cloud. Requires access to an AWS account. Costs money. Make sure you ran the `build-cli`, `init-package`, and `package-example-game` targets first - cd test/e2e && go test ./... -run TestE2eExampleGame -v -timeout 1200s - -.PHONY: test-cloud-e2e-gitea-and-grafana -test-cloud-e2e-gitea-and-grafana: ## E2E test of Gitea & Grafana. Requires access to an AWS account. Costs money. Make sure you ran the `build-cli` and `init-package` targets first - cd test/e2e && go test ./... -run TestGiteaAndGrafana -v -timeout 1200s - -.PHONY: test-cloud-e2e-gitops -test-cloud-e2e-gitops: package-example-gitops-data ## E2E test of Gitops example. Requires access to an AWS account. Costs money. Make sure you ran the `build-cli` and `init-package` targets first - cd test/e2e && go test ./... -run TestGitopsExample -v -timeout 1200s - -.PHONY: test-cloud-e2e-data-injection -test-cloud-e2e-data-injection: package-example-data-injection ## E2E test of the Data Injection example. Requires access to an AWS account. Costs money. Make sure you ran the `build-cli` and `init-package` targets first - cd test/e2e && go test ./... -run TestDataInjection -v -timeout 1200s - -.PHONY: test-cloud-e2e-general-cli -test-cloud-e2e-general-cli: package-example-tiny-kafka ## Runs tests of the CLI that don't need a cluster - cd test/e2e && go test ./... -run TestGeneralCli -v -timeout 1200s - -.PHONY: test-e2e -test-e2e: package-example-game test-cloud-e2e-example-game ## DEPRECATED - to be replaced by individual e2e test targets - - -.PHONY: build-and-test-e2e -build-and-test-e2e: build-cli init-package package-example-game package-example-gitops-data package-example-data-injection test-new-e2e ## Builds the cli and init package and runs the local e2e tests - -.PHONY: build-packages-for-e2e -build-packages-for-e2e: build-cli init-package package-example-game package-example-gitops-data package-example-data-injection - -# TODO: Rename this once we are certain this is the e2e approach we are going to be taking -# TODO: I'm pretty sure there's some way Makefiles could be setup to not run dependant steps if their results are already cached or something -# That way we wouldn't need this target and can just call build-and-test-e2e and not have to wait for the build if it was already built. # TODO: This can be cleaned up a little more when `zarf init` is able to provide the path to the `zarf-init.tar.zst` .PHONY: test-new-e2e -test-new-e2e: ## Run e2e tests on a KiND cluster. All dependencies are assumed to be built and in the ./build directory +test-e2e: ## Run e2e tests on a KiND cluster. All dependencies are assumed to be built and in the ./build directory + @ #Check to make sure all the packages we need exist + @if [ ! -f $(ZARF_BIN) ]; then\ + $(MAKE) build-cli;\ + fi + @if [ ! -f ./build/zarf-init.tar.zst ]; then\ + $(MAKE) init-package;\ + fi + @if [ ! -f ./build/zarf-package-appliance-demo-multi-games.tar.zst ]; then\ + $(MAKE) package-example-game;\ + fi + @if [ ! -f ./build/zarf-package-data-injection-demo.tar ]; then\ + $(MAKE) package-example-data-injection;\ + fi + @if [ ! -f ./build/zarf-package-gitops-service-data.tar.zst ]; then\ + $(MAKE) package-example-gitops-data;\ + fi + cd test/e2e && cp ../../build/zarf-init.tar.zst . && go test ./... -v -timeout 2400s && rm zarf-init.tar.zst diff --git a/test/e2e/common.go b/test/e2e/common.go index 004f595e16..3d7a0d9e52 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -32,7 +32,6 @@ type ZarfE2ETest struct { kubeconfigPath string filesToRemove []string cmdsToKill []*exec.Cmd - kubeconfig *os.File provider *cluster.Provider restConfig *restclient.Config clientset *kubernetes.Clientset diff --git a/test/e2e/e2e_data_injection_test.go b/test/e2e/e2e_data_injection_test.go index 16924b13f7..95c85d581f 100644 --- a/test/e2e/e2e_data_injection_test.go +++ b/test/e2e/e2e_data_injection_test.go @@ -30,10 +30,9 @@ func TestDataInjection(t *testing.T) { assert.NoError(t, err) assert.Contains(t, execStdOut, "subdirectory-test") - attempt = 0 - execStdOut = "" - // Test to confirm the subdirectory file was placed + execStdOut = "" + attempt = 0 for attempt < 5 && execStdOut == "" { execStdOut, _, err = e2e.execCommandInPod("data-injection", "demo", []string{"ls", "/test/subdirectory-test"}) attempt++ diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go index 9267929df5..9558930a7a 100644 --- a/test/e2e/main_test.go +++ b/test/e2e/main_test.go @@ -8,25 +8,29 @@ import ( ) type testSuite struct { - setupFunction func() error - cleanupFunction func() error + standard bool + setupFunction func() error + tearDownFunction func() error } var ( - e2e ZarfE2ETest - + e2e ZarfE2ETest + static string distroTests = map[string]testSuite{ "k3d": { - setupFunction: e2e.setUpK3D, - cleanupFunction: e2e.tearDownK3D, + standard: true, + setupFunction: e2e.setUpK3D, + tearDownFunction: e2e.tearDownK3D, }, "kind": { - setupFunction: e2e.setUpKind, - cleanupFunction: e2e.tearDownKind, + standard: true, + setupFunction: e2e.setUpKind, + tearDownFunction: e2e.tearDownKind, }, "k3s": { - setupFunction: e2e.setUpK3s, - cleanupFunction: e2e.tearDownK3s, + standard: false, + setupFunction: e2e.setUpK3s, + tearDownFunction: e2e.tearDownK3s, }, } ) @@ -37,9 +41,12 @@ func TestMain(m *testing.M) { distroToUse := strings.Split(os.Getenv("TESTDISTRO"), ",") if len(distroToUse) == 1 && distroToUse[0] == "" { - // Use all the distros - for key := range distroTests { - distroToUse = append(distroToUse, key) + distroToUse = []string{} + // Use all the standard distros + for key, value := range distroTests { + if value.standard { + distroToUse = append(distroToUse, key) + } } } @@ -53,7 +60,7 @@ func TestMain(m *testing.M) { // Setup the cluster err := testSuiteFunctions.setupFunction() - defer testSuiteFunctions.cleanupFunction() + defer testSuiteFunctions.tearDownFunction() if err != nil { fmt.Printf("Unable to setup %s environment to run the e2e test because of err: %v\n", distroName, err) os.Exit(1) @@ -64,7 +71,7 @@ func TestMain(m *testing.M) { retCode = testCode | retCode // Teardown the cluster now that tests are completed - err = testSuiteFunctions.cleanupFunction() + err = testSuiteFunctions.tearDownFunction() if err != nil { fmt.Printf("Unable to cleanly teardown %s environment because of err: %v\n", distroName, err) } From e6045473e146890eca762e96ab390544f3183d19 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Tue, 1 Mar 2022 13:04:16 -0500 Subject: [PATCH 18/25] more test code cleanup --- test/e2e/common.go | 150 +++++++++++++++++++++--------------------- test/e2e/main_test.go | 22 ++++++- 2 files changed, 95 insertions(+), 77 deletions(-) diff --git a/test/e2e/common.go b/test/e2e/common.go index 3d7a0d9e52..11b1ef51b9 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -62,16 +62,33 @@ func getKubeconfigPath() (string, error) { return kubeconfigPath, err } -func (e2e *ZarfE2ETest) setUpKind() error { - // Determine what the name of the zarfBinary should be - e2e.zarfBinPath = path.Join("../../build", getCLIName()) +func getCLIName() string { + var binaryName string + if runtime.GOOS == "linux" { + binaryName = "zarf" + } else if runtime.GOOS == "darwin" { + if runtime.GOARCH == "arm64" { + binaryName = "zarf-mac-apple" + } else { + binaryName = "zarf-mac-intel" + } + } + return binaryName +} +func (e2e *ZarfE2ETest) buildConfigAndClientset() error { var err error - // Create or get the kubeconfig - e2e.kubeconfigPath, err = getKubeconfigPath() + e2e.restConfig, err = clientcmd.BuildConfigFromFlags("", e2e.kubeconfigPath) if err != nil { return err } + e2e.clientset, err = kubernetes.NewForConfig(e2e.restConfig) + + return err +} + +func (e2e *ZarfE2ETest) setUpKind() error { + var err error // Set up a KinD cluster if necessary e2e.provider = cluster.NewProvider(cluster.ProviderWithLogger(kindcmd.NewLogger())) @@ -88,37 +105,19 @@ func (e2e *ZarfE2ETest) setUpKind() error { cluster.CreateWithKubeconfigPath(e2e.kubeconfigPath), cluster.CreateWithDisplayUsage(false), ) + if err != nil { + return err + } } // Get config and client for the k8s cluster err = e2e.buildConfigAndClientset() - - // Wait for the cluster to have pods before we let the test suite run - attempt := 0 - for attempt < 10 { - pods, err := e2e.clientset.CoreV1().Pods("kube-system").List(context.TODO(), metav1.ListOptions{}) - if err == nil && len(pods.Items) >= 0 { - fmt.Printf("💥 Cluster %s ready. You can access it by setting:\nexport KUBECONFIG='%s'\n", e2e.clusterName, e2e.kubeconfigPath) - break - } - - time.Sleep(1 * time.Second) - attempt++ - if attempt > 15 { - return errors.New("unable to connect to KinD cluster for e2e tests") - } - } - - return err -} - -func (e2e *ZarfE2ETest) buildConfigAndClientset() error { - var err error - e2e.restConfig, err = clientcmd.BuildConfigFromFlags("", e2e.kubeconfigPath) if err != nil { return err } - e2e.clientset, err = kubernetes.NewForConfig(e2e.restConfig) + + // Wait for the cluster to have pods before we let the test suite run + err = e2e.waitForHealthyCluster() return err } @@ -136,20 +135,11 @@ func (e2e *ZarfE2ETest) tearDownKind() error { } func (e2e *ZarfE2ETest) setUpK3D() error { - // Determine what the name of the zarfBinary should be - e2e.zarfBinPath = path.Join("../../build", getCLIName()) - var err error - // Create or get the kubeconfig - e2e.kubeconfigPath, err = getKubeconfigPath() - if err != nil { - return err - } createClusterCommand := k3dcluster.NewCmdClusterCreate() err = createClusterCommand.ExecuteContext(context.TODO()) if err != nil { - fmt.Println("ERROR WHEN TRYING TO SET UP K3D CLUSTER") return err } @@ -160,21 +150,9 @@ func (e2e *ZarfE2ETest) setUpK3D() error { } // Wait for the cluster to have pods before we let the test suite run - attempt := 0 - for attempt < 10 { - pods, err := e2e.clientset.CoreV1().Pods("kube-system").List(context.TODO(), metav1.ListOptions{}) - if err == nil && len(pods.Items) >= 0 { - fmt.Printf("💥 Cluster %s ready. You can access it by setting:\nexport KUBECONFIG='%s'\n", e2e.clusterName, e2e.kubeconfigPath) - break - } + err = e2e.waitForHealthyCluster() - time.Sleep(1 * time.Second) - attempt++ - if attempt > 15 { - return errors.New("unable to connect to KinD cluster for e2e tests") - } - } - return nil + return err } func (e2e *ZarfE2ETest) tearDownK3D() error { @@ -185,16 +163,6 @@ func (e2e *ZarfE2ETest) tearDownK3D() error { } func (e2e *ZarfE2ETest) setUpK3s() error { - // Determine what the name of the zarfBinary should be - e2e.zarfBinPath = path.Join("../../build", getCLIName()) - - var err error - // Create or get the kubeconfig - e2e.kubeconfigPath, err = getKubeconfigPath() - if err != nil { - return err - } - e2e.initWithK3s = true return nil } @@ -205,20 +173,6 @@ func (e2e *ZarfE2ETest) tearDownK3s() error { return nil } -func getCLIName() string { - var binaryName string - if runtime.GOOS == "linux" { - binaryName = "zarf" - } else if runtime.GOOS == "darwin" { - if runtime.GOARCH == "arm64" { - binaryName = "zarf-mac-apple" - } else { - binaryName = "zarf-mac-intel" - } - } - return binaryName -} - func (e2e *ZarfE2ETest) cleanupAfterTest(t *testing.T) { // Use Zarf to perform chart uninstallation output, err := e2e.execZarfCommand("destroy", "--confirm", "--remove-components", "-l=trace") @@ -299,6 +253,7 @@ func (e2e *ZarfE2ETest) execZarfCommand(commandString ...string) (string, error) return string(output), err } +// Kill any background 'zarf connect ...' processes spawned during the tests func (e2e *ZarfE2ETest) execZarfBackgroundCommand(commandString ...string) error { // Create a tunnel to the git resources tunnelCmd := exec.Command(e2e.zarfBinPath, commandString...) @@ -308,3 +263,46 @@ func (e2e *ZarfE2ETest) execZarfBackgroundCommand(commandString ...string) error return err } + +// Check if any pods exist in the 'kube-system' namespace +func (e2e *ZarfE2ETest) checkIfClusterRunning() bool { + err := e2e.buildConfigAndClientset() + if err != nil { + return false + } + + pods, err := e2e.clientset.CoreV1().Pods("kube-system").List(context.TODO(), metav1.ListOptions{}) + if err == nil && len(pods.Items) > 0 { + return true + } + + return false +} + +func (e2e *ZarfE2ETest) waitForHealthyCluster() error { + attempt := 0 + for attempt < 10 { + pods, err := e2e.clientset.CoreV1().Pods("kube-system").List(context.TODO(), metav1.ListOptions{}) + if err == nil && len(pods.Items) >= 0 { + allPodsHealthy := true + + // Make sure at the pods are in the 'succeeded' or 'running' state + for _, pod := range pods.Items { + if !(pod.Status.Phase == v1.PodSucceeded || pod.Status.Phase == v1.PodRunning) { + allPodsHealthy = false + break + } + } + + if allPodsHealthy { + fmt.Printf("💥 Cluster %s ready. You can access it by setting:\nexport KUBECONFIG='%s'\n", e2e.clusterName, e2e.kubeconfigPath) + return nil + } + } + + time.Sleep(1 * time.Second) + attempt++ + } + + return errors.New("unable to connect to cluster for e2e tests") +} diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go index 9558930a7a..c54e38cfa3 100644 --- a/test/e2e/main_test.go +++ b/test/e2e/main_test.go @@ -3,6 +3,7 @@ package test import ( "fmt" "os" + "path" "strings" "testing" ) @@ -37,12 +38,31 @@ var ( // TestMain will exec each test, one by one func TestMain(m *testing.M) { + var err error retCode := 0 + // Set up constants for the tests + e2e.zarfBinPath = path.Join("../../build", getCLIName()) + e2e.kubeconfigPath, err = getKubeconfigPath() + if err != nil { + fmt.Printf("Unable to get the kubeconfig path for running the e2e tests because of err :%v\n", err) + os.Exit(1) + } + + // Check if a valid kubeconfig exists + validCubeConfig := e2e.checkIfClusterRunning() + + // If the current kubeconfig points to an existing cluster run the tests against that cluster + if validCubeConfig { + retCode = m.Run() + os.Exit(retCode) + } + + // Run the tests against all the distros provided distroToUse := strings.Split(os.Getenv("TESTDISTRO"), ",") if len(distroToUse) == 1 && distroToUse[0] == "" { distroToUse = []string{} - // Use all the standard distros + // No distros were specified; Use all the standard distros for key, value := range distroTests { if value.standard { distroToUse = append(distroToUse, key) From e4874b7d2e17ed0da15858fd2e40f9cae6ddbd02 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Tue, 1 Mar 2022 14:59:52 -0500 Subject: [PATCH 19/25] add more docs to e2e README --- test/e2e/README.md | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/test/e2e/README.md b/test/e2e/README.md index 796aaec355..d796b52712 100644 --- a/test/e2e/README.md +++ b/test/e2e/README.md @@ -1,28 +1,40 @@ # Zarf End-To-End Tests -This directory holds all of our e2e tests that we use to verify Zarf functionality in an environment that replicates a live setting. The tests in this directory are automatically run whenever a PR is opened against the repo and the passing of all of the tests is a pre-condition to having a PR merged into the baseline. The e2e tests stand up a KinD cluster for Zarf to use during the testing. +This directory holds all of our e2e tests that we use to verify Zarf functionality in an environment that replicates a live setting. The tests in this directory are automatically run against all the default K8s distros whenever a PR is opened against the repo. -## Running Tests Locally +# Running Tests Locally +The tests in this directory are also able to be run locally! -### Dependencies +## Dependencies Running the tests locally have the same prerequisites as running and building Zarf: 1. GoLang >= `1.16.x` 2. Make + 3. Docker -### Local K8s Cluster -If you have a cluster already running on your local machine, great! As long as your kubeconfig is accessible at `~/.kube/.config` or is exposed in your `$KUBECONFIG` environment variable, the e2e tests will be able to use your cluster to run your tests. If you do not have a local cluster running, still great! The e2e tests use the `sigs.k8s.io/kind` library to stand up a local KinD cluster to test against. -> NOTE: Your existing local cluster needs to have the cluster name `test-cluster` for the e2e tests to use it -If your cluster existed before the e2e test ran, your cluster will still be up after the tests are completed. Just note that since the tests are actively using your cluster it might be in a very different state. +### Existing K8s Cluster +If you have a cluster already running, great! As long as your kubeconfig is accessible at `~/.kube/.config` or is exposed in your `$KUBECONFIG` environment variable, the e2e tests will be able to use your cluster to run your tests. This means that you can even test remote distros like EKS, AKS, and GKE. When the tests are completed, your cluster will still be accessible but note that since the tests are actively using your cluster it might be in a very different state. + + +### No Existing K8s Cluster +If you do not have a local cluster running, no worries! The e2e tests use the `sigs.k8s.io/kind` and `github.com/rancher/k3d/v5` libraries to stand up local clusters to test against. + +If you want to specify which distros to run the tests against you can set the `TESTDISTRO` environment variable with a comma separated list of K8s distros to use for the testing, each distro is run iteratively. The list of potential distros lists in the `distroTests` struct in `main_test.go`. If nothing is specified, it all 'default' distros are run. + +> NOTE: If running against the k3s distro you have to be 'root' to successfully create the cluster. + If you did not have a local cluster running before the e2e test but you want to keep it up afterwards to do some debugging, you can set the `SKIP_TEARDOWN` environment variable and the e2e tests will leave the create cluster up after all testing is completed. ### Actually Running The Test -Recommend running the tests by going to the directory of the Zarf repo and running `make test-new-e2e` this will guarantee all the necessary packages are built and in the right place for the test to find. If you already built everything you can run the tests by staying in this directory and using the command `go test ./... -v` +We recommend running the tests by going to the main directory of the Zarf repo and running `make test-e2e` this will guarantee all the necessary packages are built and in the right place for the test to find. If you already built everything you can run the tests by staying in this directory and using the command `go test ./... -v` + +> NOTE: The zarf binary and built packages need to live in the ./build directory but if you're trying to run the tests locally with 'go test ./...' then the zarf-init package will need to be in this directory. ## Adding More Tests -> NOTE: Since all of the tests use the same K8s cluster, do not write new tests to be executed in parallel and remember to cleanup the cluster after each test by executing `zarf destroy --confirm --remove-components`. An example can be found [TODO PLACE LINK] +> NOTE: Since all of the tests use the same K8s cluster, do not write new tests to be executed in parallel and remember to cleanup the cluster after each test by executing `e2e.cleanupAfterTest(t)`. This runs a `zarf destroy --confirm --remove-components` so that the cluster is in a good enough state to run the next test against. + -In the future, our goals is to be able to run all of the tests while using an exhaustive combination of different k8s distros and base operating systems. +Coming Soon: In the future, our goals is to be able to run all of the tests while using an exhaustive combination of different k8s distros and base operating systems. From 9a9e7100aa458f3843d5fe85fd5223163ed65974 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Tue, 1 Mar 2022 16:10:30 -0500 Subject: [PATCH 20/25] update key for registry1 e2e login --- .github/workflows/test-k3d.yml | 2 +- .github/workflows/test-kind.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-k3d.yml b/.github/workflows/test-k3d.yml index 0d5cc32d60..3aaf007fbe 100644 --- a/.github/workflows/test-k3d.yml +++ b/.github/workflows/test-k3d.yml @@ -15,7 +15,7 @@ jobs: - name: Build CLI run: make build-cli-linux - name: Sign into Repo1 - run: ./build/zarf tools registry login registry1.dso.mil -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} + run: ./build/zarf tools registry login registry1.dso.mil -u ${{ secrets.REGISTRY_USERNAME_ZARF_ROBOT }} -p ${{ secrets.REGISTRY_PASSWORD_ZARF_ROBOT }} - name: Make Packages run: make init-package diff --git a/.github/workflows/test-kind.yml b/.github/workflows/test-kind.yml index d627f44d69..546aa6d9bd 100644 --- a/.github/workflows/test-kind.yml +++ b/.github/workflows/test-kind.yml @@ -15,7 +15,7 @@ jobs: - name: Build CLI run: make build-cli-linux - name: Sign into Repo1 - run: ./build/zarf tools registry login registry1.dso.mil -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} + run: ./build/zarf tools registry login registry1.dso.mil -u ${{ secrets.REGISTRY_USERNAME_ZARF_ROBOT }} -p ${{ secrets.REGISTRY_PASSWORD_ZARF_ROBOT }} - name: Make Packages run: make init-package From d9b7a6cb2a47c4bff1835b0ef2ce5c8f0a3d3520 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Thu, 3 Mar 2022 01:10:52 -0500 Subject: [PATCH 21/25] Re-add cloud e2e test for the game example This commit brings back the terratest supported test for the example game package. This verifies zarf can init with k3s as a component and deploy a package on it --- .github/workflows/slash-command-dispatch.yml | 15 ++ .github/workflows/test-command.yml | 103 ++++++++++ Makefile | 14 ++ test/cloud-e2e/cloud_common.go | 187 ++++++++++++++++++ test/cloud-e2e/cloud_e2e_example_game_test.go | 52 +++++ 5 files changed, 371 insertions(+) create mode 100644 .github/workflows/slash-command-dispatch.yml create mode 100644 .github/workflows/test-command.yml create mode 100644 test/cloud-e2e/cloud_common.go create mode 100644 test/cloud-e2e/cloud_e2e_example_game_test.go diff --git a/.github/workflows/slash-command-dispatch.yml b/.github/workflows/slash-command-dispatch.yml new file mode 100644 index 0000000000..9de4ef5d63 --- /dev/null +++ b/.github/workflows/slash-command-dispatch.yml @@ -0,0 +1,15 @@ +name: Slash Command Dispatch +on: + issue_comment: + types: [created] +jobs: + slashCommandDispatch: + runs-on: ubuntu-latest + steps: + - name: Slash Command Dispatch + uses: peter-evans/slash-command-dispatch@v2 + with: + token: ${{ secrets.PAT }} + commands: test + permission: write + issue-type: pull-request diff --git a/.github/workflows/test-command.yml b/.github/workflows/test-command.yml new file mode 100644 index 0000000000..757d4b5f95 --- /dev/null +++ b/.github/workflows/test-command.yml @@ -0,0 +1,103 @@ +# Attribution for a bunch of this goes to CloudPosse +# https://github.com/cloudposse/actions/blob/master/.github/workflows/test-command.yml + +name: test +on: + repository_dispatch: + types: [test-command] + +defaults: + run: + # We need -e -o pipefail for consistency with GitHub Actions' default behavior + shell: bash -e -o pipefail {0} + +jobs: + # Run the Game E2E test + e2e-game: + runs-on: ubuntu-latest + container: cloudposse/test-harness:latest + steps: + # Update GitHub status for pending pipeline run + - name: "Update GitHub Status for pending" + uses: docker://cloudposse/github-status-updater + with: + args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + GITHUB_STATE: pending + GITHUB_CONTEXT: "/test e2e - Game Example" + GITHUB_DESCRIPTION: "started by @${{ github.event.client_payload.github.actor }}" + GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} + GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} + + # Checkout the code from GitHub Pull Request + - name: "Checkout the code" + uses: actions/checkout@v2 + with: + token: ${{ secrets.PAT }} + repository: ${{ github.event.client_payload.pull_request.head.repo.full_name }} + ref: ${{ github.event.client_payload.pull_request.head.ref }} + + - name: "Run E2E tests" + shell: bash -x -e -o pipefail {0} + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} + AWS_DEFAULT_REGION: us-east-1 + run: | + # cloudposse/test-harness has golang 1.15, we need 1.16. This is the easiest way I know to do it. This should definitely be revisited and cleaned up. + git clone --branch v0.8.0 --depth 1 https://github.com/asdf-vm/asdf.git $HOME/.asdf + source ~/.asdf/asdf.sh + export PATH="$HOME/.asdf/bin:$PATH" + asdf plugin-add golang https://github.com/kennyp/asdf-golang.git + asdf install golang 1.16.7 + asdf global golang 1.16.7 + export GOPATH="$HOME/go" + export PATH="$PATH:$GOPATH/bin" + make build-cli-linux + make test-cloud-e2e-example-game + + # Update GitHub status for failing pipeline run + - name: "Update GitHub Status for failure" + if: ${{ failure() }} + uses: docker://cloudposse/github-status-updater + with: + args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + GITHUB_STATE: failure + GITHUB_CONTEXT: "/test e2e - Game Example" + GITHUB_DESCRIPTION: "run failed" + GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} + GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} + + # Update GitHub status for successful pipeline run + - name: "Update GitHub Status for success" + uses: docker://cloudposse/github-status-updater + with: + args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + GITHUB_STATE: success + GITHUB_CONTEXT: "/test e2e - Game Example" + GITHUB_DESCRIPTION: "run passed" + GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} + GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} + + # Update GitHub status for cancelled pipeline run + - name: "Update GitHub Status for cancelled" + if: ${{ cancelled() }} + uses: docker://cloudposse/github-status-updater + with: + args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + GITHUB_STATE: error + GITHUB_CONTEXT: "/test e2e - Game Example" + GITHUB_DESCRIPTION: "run cancelled" + GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} + GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} diff --git a/Makefile b/Makefile index edf779ba0e..77adc37dd8 100644 --- a/Makefile +++ b/Makefile @@ -99,3 +99,17 @@ test-e2e: ## Run e2e tests on a KiND cluster. All dependencies are assumed to be fi cd test/e2e && cp ../../build/zarf-init.tar.zst . && go test ./... -v -timeout 2400s && rm zarf-init.tar.zst + +.PHONY: test-cloud-e2e-example-game +test-cloud-e2e-example-game: ## Run e2e game example.. + @if [ ! -f $(ZARF_BIN) ]; then\ + $(MAKE) build-cli;\ + fi + @if [ ! -f ./build/zarf-init.tar.zst ]; then\ + $(MAKE) init-package;\ + fi + @if [ ! -f ./build/zarf-package-appliance-demo-multi-games.tar.zst ]; then\ + $(MAKE) package-example-game;\ + fi + + cd test/cloud-e2e && go test ./... -run TestCloudE2EExampleGame -v -timeout 1200s diff --git a/test/cloud-e2e/cloud_common.go b/test/cloud-e2e/cloud_common.go new file mode 100644 index 0000000000..4f66a17fda --- /dev/null +++ b/test/cloud-e2e/cloud_common.go @@ -0,0 +1,187 @@ +package testcloud + +import ( + "bufio" + "encoding/base64" + "fmt" + "io/ioutil" + "os" + "testing" + "time" + + "github.com/gruntwork-io/terratest/modules/aws" + "github.com/gruntwork-io/terratest/modules/random" + "github.com/gruntwork-io/terratest/modules/retry" + "github.com/gruntwork-io/terratest/modules/ssh" + "github.com/gruntwork-io/terratest/modules/terraform" + teststructure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/require" +) + +type CloudZarfE2ETest struct { + testing *testing.T + tempFolder string + username string + terraformOptions *terraform.Options + keyPair *aws.Ec2Keypair + publicIP string + publicHost ssh.Host +} + +func NewCloudE2ETest(testing *testing.T) *CloudZarfE2ETest { + + testing.Parallel() + + // Copy the terraform folder to a temp directory so we can run multiple tests in parallel + tempFolder := teststructure.CopyTerraformFolderToTemp(testing, "..", "tf/public-ec2-instance") + + e2e := CloudZarfE2ETest{ + testing: testing, + tempFolder: tempFolder, + // Our SSH username, will change based on which AMI we use + username: "ubuntu", + } + + // Deploy the terraform infra + teststructure.RunTestStage(testing, "SETUP", e2e.setup) + + return &e2e +} + +func (e2e *CloudZarfE2ETest) runSSHCommand(format string, a ...interface{}) (string, error) { + command := fmt.Sprintf(format, a...) + return ssh.CheckSshCommandE(e2e.testing, e2e.publicHost, command) +} + +func (e2e *CloudZarfE2ETest) teardown() { + keyPair := teststructure.LoadEc2KeyPair(e2e.testing, e2e.tempFolder) + aws.DeleteEC2KeyPair(e2e.testing, keyPair) + + terraformOptions := teststructure.LoadTerraformOptions(e2e.testing, e2e.tempFolder) + terraform.Destroy(e2e.testing, terraformOptions) +} + +func (e2e *CloudZarfE2ETest) setup() { + terraformOptions, keyPair, err := e2e.configureTerraformOptions() + require.NoError(e2e.testing, err) + + // Save the options and key pair so later test stages can use them + teststructure.SaveTerraformOptions(e2e.testing, e2e.tempFolder, terraformOptions) + teststructure.SaveEc2KeyPair(e2e.testing, e2e.tempFolder, keyPair) + + // This will run `terraform init` and `terraform apply` and fail the test if there are any errors + terraform.InitAndApply(e2e.testing, terraformOptions) + + // Run `terraform output` to get the value of an output variable + e2e.publicIP = terraform.Output(e2e.testing, terraformOptions, "public_instance_ip") + e2e.terraformOptions = terraformOptions + e2e.keyPair = keyPair + + // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", + // as we know the Instance is running an Ubuntu AMI that has such a user + e2e.publicHost = ssh.Host{ + Hostname: e2e.publicIP, + SshKeyPair: e2e.keyPair.KeyPair, + SshUserName: e2e.username, + } +} + +func (e2e *CloudZarfE2ETest) configureTerraformOptions() (*terraform.Options, *aws.Ec2Keypair, error) { + // A unique ID we can use to namespace resources so we don't clash with anything already in the AWS account or + // tests running in parallel + uniqueID := random.UniqueId() + namespace := "zarf" + stage := "terratest" + name := fmt.Sprintf("e2e-%s", uniqueID) + + // Get the region to use from the system's environment + awsRegion, err := getAwsRegion() + if err != nil { + return nil, nil, err + } + + instanceType := "t3a.large" + + // Create an EC2 KeyPair that we can use for SSH access + keyPairName := fmt.Sprintf("%s-%s-%s", namespace, stage, name) + keyPair := aws.CreateAndImportEC2KeyPair(e2e.testing, awsRegion, keyPairName) + + // Construct the terraform options with default retryable errors to handle the most common retryable errors in + // terraform testing. + terraformOptions := terraform.WithDefaultRetryableErrors(e2e.testing, &terraform.Options{ + // The path to where our Terraform code is located + TerraformDir: e2e.tempFolder, + + // Variables to pass to our Terraform code using -var options + Vars: map[string]interface{}{ + "aws_region": awsRegion, + "namespace": namespace, + "stage": stage, + "name": name, + "instance_type": instanceType, + "key_pair_name": keyPairName, + }, + }) + + return terraformOptions, keyPair, nil +} + +// syncFileToRemoteServer uses SCP to sync a file from source to destination. `destPath` can be absolute or relative to +// the SSH user's home directory. It has to be in a directory that the SSH user is allowed to write to. +func (e2e *CloudZarfE2ETest) syncFileToRemoteServer(srcPath string, destPath string, chmod string) { + // Run `terraform output` to get the value of an output variable + publicInstanceIP := terraform.Output(e2e.testing, e2e.terraformOptions, "public_instance_ip") + + // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", + // as we know the Instance is running an Ubuntu AMI that has such a user + host := ssh.Host{ + Hostname: publicInstanceIP, + SshKeyPair: e2e.keyPair.KeyPair, + SshUserName: e2e.username, + } + + // It can take a minute or so for the Instance to boot up, so retry a few times + maxRetries := 15 + timeBetweenRetries, err := time.ParseDuration("5s") + require.NoError(e2e.testing, err) + + // Wait for the instance to be ready + _, err = retry.DoWithRetryE(e2e.testing, "Wait for the instance to be ready", maxRetries, timeBetweenRetries, func() (string, error) { + _, err := ssh.CheckSshCommandE(e2e.testing, host, "whoami") + if err != nil { + return "", err + } + return "", nil + }) + require.NoError(e2e.testing, err) + + // Create the folder structure + output, err := ssh.CheckSshCommandE(e2e.testing, host, fmt.Sprintf("bash -c 'install -m 644 -D /dev/null \"%s\"'", destPath)) + require.NoError(e2e.testing, err, output) + + // The ssh lib only supports sending strings so we'll base64encode it first + f, err := os.Open(srcPath) + require.NoError(e2e.testing, err) + reader := bufio.NewReader(f) + content, err := ioutil.ReadAll(reader) + require.NoError(e2e.testing, err) + encodedContent := base64.StdEncoding.EncodeToString(content) + err = ssh.ScpFileToE(e2e.testing, host, 0600, fmt.Sprintf("%s.b64", destPath), encodedContent) + require.NoError(e2e.testing, err) + output, err = ssh.CheckSshCommandE(e2e.testing, host, fmt.Sprintf("base64 -d \"%s.b64\" > \"%s\" && chmod \"%s\" \"%s\"", destPath, destPath, chmod, destPath)) + require.NoError(e2e.testing, err, output) +} + +// getAwsRegion returns the desired AWS region to use by first checking the env var AWS_REGION, then checking +// AWS_DEFAULT_REGION if AWS_REGION isn't set. If neither is set it returns an error +func getAwsRegion() (string, error) { + val, present := os.LookupEnv("AWS_REGION") + if !present { + val, present = os.LookupEnv("AWS_DEFAULT_REGION") + } + if !present { + return "", fmt.Errorf("expected either AWS_REGION or AWS_DEFAULT_REGION env var to be set, but they were not") + } else { + return val, nil + } +} diff --git a/test/cloud-e2e/cloud_e2e_example_game_test.go b/test/cloud-e2e/cloud_e2e_example_game_test.go new file mode 100644 index 0000000000..d83f0248b0 --- /dev/null +++ b/test/cloud-e2e/cloud_e2e_example_game_test.go @@ -0,0 +1,52 @@ +package testcloud + +import ( + "fmt" + "testing" + "time" + + teststructure "github.com/gruntwork-io/terratest/modules/test-structure" + "github.com/stretchr/testify/require" +) + +func TestCloudE2EExampleGame(t *testing.T) { + + e2e := NewCloudE2ETest(t) + + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) + + // Upload the Zarf artifacts + teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { + e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") + e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") + e2e.syncFileToRemoteServer("../../build/zarf-package-appliance-demo-multi-games.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-appliance-demo-multi-games.tar.zst", e2e.username), "0600") + }) + + teststructure.RunTestStage(e2e.testing, "TEST", func() { + // Make sure `zarf --help` doesn't error + output, err := e2e.runSSHCommand("sudo /home/%s/build/zarf --help", e2e.username) + require.NoError(e2e.testing, err, output) + + // run `zarf init` + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s'", e2e.username) + require.NoError(e2e.testing, err, output) + + // Deploy the game + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-appliance-demo-multi-games.tar.zst --confirm'", e2e.username) + require.NoError(e2e.testing, err, output) + + // Establish the port-forward into the game service; give the service a few seconds to come up since this is not a command we can retry + time.Sleep(5 * time.Second) + output, err = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect doom --local-port 22333 &> /dev/nul &)'", e2e.username) + require.NoError(e2e.testing, err, output) + + // Right now we're just checking that `curl` returns 0. It can be enhanced by scraping the HTML that gets returned or something. + output, err = e2e.runSSHCommand("bash -c '[[ $(curl -sfSL --retry 15 --retry-connrefused --retry-delay 5 -o /dev/null -w \"%%{http_code}\" 'http://127.0.0.1:22333?doom') == 200 ]]'") + require.NoError(e2e.testing, err, output) + + // Run `zarf destroy` to make sure that works correctly + output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf destroy --confirm'", e2e.username) + require.NoError(e2e.testing, err, output) + }) +} From c13b70a8c9408d526d8bd4cd260d7297487ad677 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Thu, 3 Mar 2022 02:19:16 -0500 Subject: [PATCH 22/25] add k3s e2e workflow --- .github/workflows/test-k3d.yml | 5 +---- .github/workflows/test-k3s.yml | 21 +++++++++++++++++++++ .github/workflows/test-kind.yml | 5 +---- 3 files changed, 23 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/test-k3s.yml diff --git a/.github/workflows/test-k3d.yml b/.github/workflows/test-k3d.yml index 3aaf007fbe..ec739e4a46 100644 --- a/.github/workflows/test-k3d.yml +++ b/.github/workflows/test-k3d.yml @@ -14,10 +14,7 @@ jobs: uses: actions/checkout@v2 - name: Build CLI run: make build-cli-linux - - name: Sign into Repo1 - run: ./build/zarf tools registry login registry1.dso.mil -u ${{ secrets.REGISTRY_USERNAME_ZARF_ROBOT }} -p ${{ secrets.REGISTRY_PASSWORD_ZARF_ROBOT }} - name: Make Packages - run: make init-package - + run: make init-package package-example-game package-example-data-injection package-example-gitops-data - name: Run Tests run: TESTDISTRO=k3d make test-e2e diff --git a/.github/workflows/test-k3s.yml b/.github/workflows/test-k3s.yml new file mode 100644 index 0000000000..b2a53f57c8 --- /dev/null +++ b/.github/workflows/test-k3s.yml @@ -0,0 +1,21 @@ +name: e2e-k3s +on: + - pull_request + +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - name: Install GoLang + uses: actions/setup-go@v2 + with: + go-version: 1.16.x + - name: Checkout Repo + uses: actions/checkout@v2 + - name: Build CLI + run: make build-cli-linux + - name: Make Packages + run: make init-package package-example-game package-example-data-injection package-example-gitops-data + - name: Run Tests + # NOTE: "PATH=$PATH" preserves the default user $PATH. This is needed to maintain the version of go installed in a previous step + run: sudo env "PATH=$PATH" TESTDISTRO=k3s make test-e2e diff --git a/.github/workflows/test-kind.yml b/.github/workflows/test-kind.yml index 546aa6d9bd..c0ba17cfdf 100644 --- a/.github/workflows/test-kind.yml +++ b/.github/workflows/test-kind.yml @@ -14,10 +14,7 @@ jobs: uses: actions/checkout@v2 - name: Build CLI run: make build-cli-linux - - name: Sign into Repo1 - run: ./build/zarf tools registry login registry1.dso.mil -u ${{ secrets.REGISTRY_USERNAME_ZARF_ROBOT }} -p ${{ secrets.REGISTRY_PASSWORD_ZARF_ROBOT }} - name: Make Packages - run: make init-package - + run: make init-package package-example-game package-example-data-injection package-example-gitops-data - name: Run Tests run: TESTDISTRO=kind make test-e2e From d077518e2de17cd2d50acf2621229294e507108f Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Fri, 4 Mar 2022 11:31:42 -0500 Subject: [PATCH 23/25] remove chat based e2e test --- .github/workflows/slash-command-dispatch.yml | 15 -- .github/workflows/test-command.yml | 103 ---------- Makefile | 14 -- test/cloud-e2e/cloud_common.go | 187 ------------------ test/cloud-e2e/cloud_e2e_example_game_test.go | 52 ----- 5 files changed, 371 deletions(-) delete mode 100644 .github/workflows/slash-command-dispatch.yml delete mode 100644 .github/workflows/test-command.yml delete mode 100644 test/cloud-e2e/cloud_common.go delete mode 100644 test/cloud-e2e/cloud_e2e_example_game_test.go diff --git a/.github/workflows/slash-command-dispatch.yml b/.github/workflows/slash-command-dispatch.yml deleted file mode 100644 index 9de4ef5d63..0000000000 --- a/.github/workflows/slash-command-dispatch.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: Slash Command Dispatch -on: - issue_comment: - types: [created] -jobs: - slashCommandDispatch: - runs-on: ubuntu-latest - steps: - - name: Slash Command Dispatch - uses: peter-evans/slash-command-dispatch@v2 - with: - token: ${{ secrets.PAT }} - commands: test - permission: write - issue-type: pull-request diff --git a/.github/workflows/test-command.yml b/.github/workflows/test-command.yml deleted file mode 100644 index 757d4b5f95..0000000000 --- a/.github/workflows/test-command.yml +++ /dev/null @@ -1,103 +0,0 @@ -# Attribution for a bunch of this goes to CloudPosse -# https://github.com/cloudposse/actions/blob/master/.github/workflows/test-command.yml - -name: test -on: - repository_dispatch: - types: [test-command] - -defaults: - run: - # We need -e -o pipefail for consistency with GitHub Actions' default behavior - shell: bash -e -o pipefail {0} - -jobs: - # Run the Game E2E test - e2e-game: - runs-on: ubuntu-latest - container: cloudposse/test-harness:latest - steps: - # Update GitHub status for pending pipeline run - - name: "Update GitHub Status for pending" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: pending - GITHUB_CONTEXT: "/test e2e - Game Example" - GITHUB_DESCRIPTION: "started by @${{ github.event.client_payload.github.actor }}" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Checkout the code from GitHub Pull Request - - name: "Checkout the code" - uses: actions/checkout@v2 - with: - token: ${{ secrets.PAT }} - repository: ${{ github.event.client_payload.pull_request.head.repo.full_name }} - ref: ${{ github.event.client_payload.pull_request.head.ref }} - - - name: "Run E2E tests" - shell: bash -x -e -o pipefail {0} - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEFENSEUNICORNS_COMMERCIAL_SA_ZARF }} - AWS_DEFAULT_REGION: us-east-1 - run: | - # cloudposse/test-harness has golang 1.15, we need 1.16. This is the easiest way I know to do it. This should definitely be revisited and cleaned up. - git clone --branch v0.8.0 --depth 1 https://github.com/asdf-vm/asdf.git $HOME/.asdf - source ~/.asdf/asdf.sh - export PATH="$HOME/.asdf/bin:$PATH" - asdf plugin-add golang https://github.com/kennyp/asdf-golang.git - asdf install golang 1.16.7 - asdf global golang 1.16.7 - export GOPATH="$HOME/go" - export PATH="$PATH:$GOPATH/bin" - make build-cli-linux - make test-cloud-e2e-example-game - - # Update GitHub status for failing pipeline run - - name: "Update GitHub Status for failure" - if: ${{ failure() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: failure - GITHUB_CONTEXT: "/test e2e - Game Example" - GITHUB_DESCRIPTION: "run failed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for successful pipeline run - - name: "Update GitHub Status for success" - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: success - GITHUB_CONTEXT: "/test e2e - Game Example" - GITHUB_DESCRIPTION: "run passed" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} - - # Update GitHub status for cancelled pipeline run - - name: "Update GitHub Status for cancelled" - if: ${{ cancelled() }} - uses: docker://cloudposse/github-status-updater - with: - args: "-action update_state -ref ${{ github.event.client_payload.pull_request.head.sha }} -repo ${{ github.event.client_payload.github.payload.repository.name }}" - env: - GITHUB_TOKEN: ${{ secrets.PAT }} - GITHUB_STATE: error - GITHUB_CONTEXT: "/test e2e - Game Example" - GITHUB_DESCRIPTION: "run cancelled" - GITHUB_TARGET_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - GITHUB_REF: ${{ github.event.client_payload.pull_request.head.ref }} - GITHUB_OWNER: ${{ github.event.client_payload.github.payload.repository.owner.login }} diff --git a/Makefile b/Makefile index 77adc37dd8..edf779ba0e 100644 --- a/Makefile +++ b/Makefile @@ -99,17 +99,3 @@ test-e2e: ## Run e2e tests on a KiND cluster. All dependencies are assumed to be fi cd test/e2e && cp ../../build/zarf-init.tar.zst . && go test ./... -v -timeout 2400s && rm zarf-init.tar.zst - -.PHONY: test-cloud-e2e-example-game -test-cloud-e2e-example-game: ## Run e2e game example.. - @if [ ! -f $(ZARF_BIN) ]; then\ - $(MAKE) build-cli;\ - fi - @if [ ! -f ./build/zarf-init.tar.zst ]; then\ - $(MAKE) init-package;\ - fi - @if [ ! -f ./build/zarf-package-appliance-demo-multi-games.tar.zst ]; then\ - $(MAKE) package-example-game;\ - fi - - cd test/cloud-e2e && go test ./... -run TestCloudE2EExampleGame -v -timeout 1200s diff --git a/test/cloud-e2e/cloud_common.go b/test/cloud-e2e/cloud_common.go deleted file mode 100644 index 4f66a17fda..0000000000 --- a/test/cloud-e2e/cloud_common.go +++ /dev/null @@ -1,187 +0,0 @@ -package testcloud - -import ( - "bufio" - "encoding/base64" - "fmt" - "io/ioutil" - "os" - "testing" - "time" - - "github.com/gruntwork-io/terratest/modules/aws" - "github.com/gruntwork-io/terratest/modules/random" - "github.com/gruntwork-io/terratest/modules/retry" - "github.com/gruntwork-io/terratest/modules/ssh" - "github.com/gruntwork-io/terratest/modules/terraform" - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" -) - -type CloudZarfE2ETest struct { - testing *testing.T - tempFolder string - username string - terraformOptions *terraform.Options - keyPair *aws.Ec2Keypair - publicIP string - publicHost ssh.Host -} - -func NewCloudE2ETest(testing *testing.T) *CloudZarfE2ETest { - - testing.Parallel() - - // Copy the terraform folder to a temp directory so we can run multiple tests in parallel - tempFolder := teststructure.CopyTerraformFolderToTemp(testing, "..", "tf/public-ec2-instance") - - e2e := CloudZarfE2ETest{ - testing: testing, - tempFolder: tempFolder, - // Our SSH username, will change based on which AMI we use - username: "ubuntu", - } - - // Deploy the terraform infra - teststructure.RunTestStage(testing, "SETUP", e2e.setup) - - return &e2e -} - -func (e2e *CloudZarfE2ETest) runSSHCommand(format string, a ...interface{}) (string, error) { - command := fmt.Sprintf(format, a...) - return ssh.CheckSshCommandE(e2e.testing, e2e.publicHost, command) -} - -func (e2e *CloudZarfE2ETest) teardown() { - keyPair := teststructure.LoadEc2KeyPair(e2e.testing, e2e.tempFolder) - aws.DeleteEC2KeyPair(e2e.testing, keyPair) - - terraformOptions := teststructure.LoadTerraformOptions(e2e.testing, e2e.tempFolder) - terraform.Destroy(e2e.testing, terraformOptions) -} - -func (e2e *CloudZarfE2ETest) setup() { - terraformOptions, keyPair, err := e2e.configureTerraformOptions() - require.NoError(e2e.testing, err) - - // Save the options and key pair so later test stages can use them - teststructure.SaveTerraformOptions(e2e.testing, e2e.tempFolder, terraformOptions) - teststructure.SaveEc2KeyPair(e2e.testing, e2e.tempFolder, keyPair) - - // This will run `terraform init` and `terraform apply` and fail the test if there are any errors - terraform.InitAndApply(e2e.testing, terraformOptions) - - // Run `terraform output` to get the value of an output variable - e2e.publicIP = terraform.Output(e2e.testing, terraformOptions, "public_instance_ip") - e2e.terraformOptions = terraformOptions - e2e.keyPair = keyPair - - // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", - // as we know the Instance is running an Ubuntu AMI that has such a user - e2e.publicHost = ssh.Host{ - Hostname: e2e.publicIP, - SshKeyPair: e2e.keyPair.KeyPair, - SshUserName: e2e.username, - } -} - -func (e2e *CloudZarfE2ETest) configureTerraformOptions() (*terraform.Options, *aws.Ec2Keypair, error) { - // A unique ID we can use to namespace resources so we don't clash with anything already in the AWS account or - // tests running in parallel - uniqueID := random.UniqueId() - namespace := "zarf" - stage := "terratest" - name := fmt.Sprintf("e2e-%s", uniqueID) - - // Get the region to use from the system's environment - awsRegion, err := getAwsRegion() - if err != nil { - return nil, nil, err - } - - instanceType := "t3a.large" - - // Create an EC2 KeyPair that we can use for SSH access - keyPairName := fmt.Sprintf("%s-%s-%s", namespace, stage, name) - keyPair := aws.CreateAndImportEC2KeyPair(e2e.testing, awsRegion, keyPairName) - - // Construct the terraform options with default retryable errors to handle the most common retryable errors in - // terraform testing. - terraformOptions := terraform.WithDefaultRetryableErrors(e2e.testing, &terraform.Options{ - // The path to where our Terraform code is located - TerraformDir: e2e.tempFolder, - - // Variables to pass to our Terraform code using -var options - Vars: map[string]interface{}{ - "aws_region": awsRegion, - "namespace": namespace, - "stage": stage, - "name": name, - "instance_type": instanceType, - "key_pair_name": keyPairName, - }, - }) - - return terraformOptions, keyPair, nil -} - -// syncFileToRemoteServer uses SCP to sync a file from source to destination. `destPath` can be absolute or relative to -// the SSH user's home directory. It has to be in a directory that the SSH user is allowed to write to. -func (e2e *CloudZarfE2ETest) syncFileToRemoteServer(srcPath string, destPath string, chmod string) { - // Run `terraform output` to get the value of an output variable - publicInstanceIP := terraform.Output(e2e.testing, e2e.terraformOptions, "public_instance_ip") - - // We're going to try to SSH to the instance IP, using the Key Pair we created earlier, and the user "ubuntu", - // as we know the Instance is running an Ubuntu AMI that has such a user - host := ssh.Host{ - Hostname: publicInstanceIP, - SshKeyPair: e2e.keyPair.KeyPair, - SshUserName: e2e.username, - } - - // It can take a minute or so for the Instance to boot up, so retry a few times - maxRetries := 15 - timeBetweenRetries, err := time.ParseDuration("5s") - require.NoError(e2e.testing, err) - - // Wait for the instance to be ready - _, err = retry.DoWithRetryE(e2e.testing, "Wait for the instance to be ready", maxRetries, timeBetweenRetries, func() (string, error) { - _, err := ssh.CheckSshCommandE(e2e.testing, host, "whoami") - if err != nil { - return "", err - } - return "", nil - }) - require.NoError(e2e.testing, err) - - // Create the folder structure - output, err := ssh.CheckSshCommandE(e2e.testing, host, fmt.Sprintf("bash -c 'install -m 644 -D /dev/null \"%s\"'", destPath)) - require.NoError(e2e.testing, err, output) - - // The ssh lib only supports sending strings so we'll base64encode it first - f, err := os.Open(srcPath) - require.NoError(e2e.testing, err) - reader := bufio.NewReader(f) - content, err := ioutil.ReadAll(reader) - require.NoError(e2e.testing, err) - encodedContent := base64.StdEncoding.EncodeToString(content) - err = ssh.ScpFileToE(e2e.testing, host, 0600, fmt.Sprintf("%s.b64", destPath), encodedContent) - require.NoError(e2e.testing, err) - output, err = ssh.CheckSshCommandE(e2e.testing, host, fmt.Sprintf("base64 -d \"%s.b64\" > \"%s\" && chmod \"%s\" \"%s\"", destPath, destPath, chmod, destPath)) - require.NoError(e2e.testing, err, output) -} - -// getAwsRegion returns the desired AWS region to use by first checking the env var AWS_REGION, then checking -// AWS_DEFAULT_REGION if AWS_REGION isn't set. If neither is set it returns an error -func getAwsRegion() (string, error) { - val, present := os.LookupEnv("AWS_REGION") - if !present { - val, present = os.LookupEnv("AWS_DEFAULT_REGION") - } - if !present { - return "", fmt.Errorf("expected either AWS_REGION or AWS_DEFAULT_REGION env var to be set, but they were not") - } else { - return val, nil - } -} diff --git a/test/cloud-e2e/cloud_e2e_example_game_test.go b/test/cloud-e2e/cloud_e2e_example_game_test.go deleted file mode 100644 index d83f0248b0..0000000000 --- a/test/cloud-e2e/cloud_e2e_example_game_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package testcloud - -import ( - "fmt" - "testing" - "time" - - teststructure "github.com/gruntwork-io/terratest/modules/test-structure" - "github.com/stretchr/testify/require" -) - -func TestCloudE2EExampleGame(t *testing.T) { - - e2e := NewCloudE2ETest(t) - - // At the end of the test, run `terraform destroy` to clean up any resources that were created - defer teststructure.RunTestStage(e2e.testing, "TEARDOWN", e2e.teardown) - - // Upload the Zarf artifacts - teststructure.RunTestStage(e2e.testing, "UPLOAD", func() { - e2e.syncFileToRemoteServer("../../build/zarf", fmt.Sprintf("/home/%s/build/zarf", e2e.username), "0700") - e2e.syncFileToRemoteServer("../../build/zarf-init.tar.zst", fmt.Sprintf("/home/%s/build/zarf-init.tar.zst", e2e.username), "0600") - e2e.syncFileToRemoteServer("../../build/zarf-package-appliance-demo-multi-games.tar.zst", fmt.Sprintf("/home/%s/build/zarf-package-appliance-demo-multi-games.tar.zst", e2e.username), "0600") - }) - - teststructure.RunTestStage(e2e.testing, "TEST", func() { - // Make sure `zarf --help` doesn't error - output, err := e2e.runSSHCommand("sudo /home/%s/build/zarf --help", e2e.username) - require.NoError(e2e.testing, err, output) - - // run `zarf init` - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf init --confirm --components k3s'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Deploy the game - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf package deploy zarf-package-appliance-demo-multi-games.tar.zst --confirm'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Establish the port-forward into the game service; give the service a few seconds to come up since this is not a command we can retry - time.Sleep(5 * time.Second) - output, err = e2e.runSSHCommand("sudo bash -c '(/home/%s/build/zarf connect doom --local-port 22333 &> /dev/nul &)'", e2e.username) - require.NoError(e2e.testing, err, output) - - // Right now we're just checking that `curl` returns 0. It can be enhanced by scraping the HTML that gets returned or something. - output, err = e2e.runSSHCommand("bash -c '[[ $(curl -sfSL --retry 15 --retry-connrefused --retry-delay 5 -o /dev/null -w \"%%{http_code}\" 'http://127.0.0.1:22333?doom') == 200 ]]'") - require.NoError(e2e.testing, err, output) - - // Run `zarf destroy` to make sure that works correctly - output, err = e2e.runSSHCommand("sudo bash -c 'cd /home/%s/build && ./zarf destroy --confirm'", e2e.username) - require.NoError(e2e.testing, err, output) - }) -} From e2bfd36424e4d42e0231f2237c4d7a1d80345ea7 Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Fri, 4 Mar 2022 11:34:03 -0500 Subject: [PATCH 24/25] cleanup of e2e test code --- go.mod | 5 +- go.sum | 76 ----------------------------- test/e2e/common.go | 26 ++++------ test/e2e/e2e_data_injection_test.go | 2 +- test/e2e/main_test.go | 65 ++++++++++++------------ 5 files changed, 46 insertions(+), 128 deletions(-) diff --git a/go.mod b/go.mod index 7e4f6a1435..b038b383d4 100644 --- a/go.mod +++ b/go.mod @@ -5,17 +5,20 @@ go 1.16 require ( github.com/AlecAivazis/survey/v2 v2.3.2 github.com/alecthomas/jsonschema v0.0.0-20211228220459-151e3c21f49d + github.com/aws/aws-sdk-go v1.40.56 // indirect github.com/derailed/k9s v0.25.18 github.com/distribution/distribution/v3 v3.0.0-20210804104954-38ab4c606ee3 github.com/docker/cli v20.10.12+incompatible + github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1 // indirect github.com/fatih/color v1.13.0 + github.com/go-errors/errors v1.0.2-0.20180813162953-d98b870cc4e0 // indirect github.com/go-git/go-git/v5 v5.4.2 github.com/go-logr/logr v1.2.2 github.com/goccy/go-yaml v1.9.5 github.com/google/go-containerregistry v0.8.0 - github.com/gruntwork-io/terratest v0.38.2 github.com/mattn/go-colorable v0.1.12 github.com/mholt/archiver/v3 v3.5.1 + github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/otiai10/copy v1.7.0 github.com/pterm/pterm v0.12.33 github.com/rancher/k3d/v5 v5.2.1 diff --git a/go.sum b/go.sum index 84da83e9a1..ee5d651dd1 100644 --- a/go.sum +++ b/go.sum @@ -28,7 +28,6 @@ cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+Y cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= -cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= @@ -54,7 +53,6 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/AlecAivazis/survey/v2 v2.3.2 h1:TqTB+aDDCLYhf9/bD2TwSO8u8jDSmMUd2SUVO4gCnU8= github.com/AlecAivazis/survey/v2 v2.3.2/go.mod h1:TH2kPCDU3Kqq7pLbnCWwZXDBjnhZtmsCle5EiYDJ2fg= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v50.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= @@ -63,20 +61,13 @@ github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSW github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= -github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/adal v0.9.11/go.mod h1:nBKAnTomx8gDtl+3ZCJv2v0KACFHWTB2drffI1B68Pk= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.8/go.mod h1:kxyKZTSfKh8OVFWPAgOgQ/frrJgeYQJPyR5fLFmXko4= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= -github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= @@ -117,7 +108,6 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= @@ -158,9 +148,6 @@ github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= -github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/jsonschema v0.0.0-20211228220459-151e3c21f49d h1:4BQNwS4T13UU3Yee4GfzZH3Q9SNpKeJvLigfw8fDjX0= github.com/alecthomas/jsonschema v0.0.0-20211228220459-151e3c21f49d/go.mod h1:/n6+1/DWPltRLWL/VKyUxg6tzsl5kHUCcraimt4vr60= @@ -180,11 +167,6 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= -github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= -github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= -github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= -github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -227,8 +209,6 @@ github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqO github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= -github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= @@ -356,7 +336,6 @@ github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFY github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM= -github.com/containerd/stargz-snapshotter/estargz v0.7.0/go.mod h1:83VWDqHnurTKliEB0YvWMiCfLDwv4Cjj1X9Vk98GJZw= github.com/containerd/stargz-snapshotter/estargz v0.10.1 h1:hd1EoVjI2Ax8Cr64tdYqnJ4i4pZU49FkEf5kU8KxQng= github.com/containerd/stargz-snapshotter/estargz v0.10.1/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= @@ -400,7 +379,6 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -429,8 +407,6 @@ github.com/derailed/tview v0.6.6/go.mod h1:A1LXWlbx/YDMXr3GVTy+IgclAkBssJpw/FiZ7 github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= -github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/distribution/distribution/v3 v3.0.0-20210804104954-38ab4c606ee3 h1:rEK0juuU5idazw//KzUcL3yYwUU3DIe2OnfJwjDBqno= github.com/distribution/distribution/v3 v3.0.0-20210804104954-38ab4c606ee3/go.mod h1:gt38b7cvVKazi5XkHvINNytZXgTEntyhtyM3HQz46Nk= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= @@ -445,7 +421,6 @@ github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BU github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.10+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.12+incompatible h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U= github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= @@ -469,7 +444,6 @@ github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNE github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= -github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY= github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= @@ -638,12 +612,9 @@ github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7a github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= @@ -695,7 +666,6 @@ github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -741,7 +711,6 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= -github.com/google/go-containerregistry v0.6.0/go.mod h1:euCCtNbZ6tKqi1E72vwDj2xZcN5ttKpZLfa/wSo5iLw= github.com/google/go-containerregistry v0.8.0 h1:mtR24eN6rapCN+shds82qFEIWWmg64NPMuyCNT7/Ogc= github.com/google/go-containerregistry v0.8.0/go.mod h1:wW5v71NHGnQyb4k+gSshjxidrC7lN33MdWEn+Mz9TsI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -808,10 +777,6 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/gruntwork-io/go-commons v0.8.0 h1:k/yypwrPqSeYHevLlEDmvmgQzcyTwrlZGRaxEM6G0ro= -github.com/gruntwork-io/go-commons v0.8.0/go.mod h1:gtp0yTtIBExIZp7vyIV9I0XQkVwiQZze678hvDXof78= -github.com/gruntwork-io/terratest v0.38.2 h1:XgDGMxX+dE8Aw96wI8QH6oIzveej01Yk4bTjt6dtzIU= -github.com/gruntwork-io/terratest v0.38.2/go.mod h1:XzW8PL9pAGbLyiBdQ5OiAeWSNpZ/9ycItjYstSS2PV8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -822,7 +787,6 @@ github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyN github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -834,7 +798,6 @@ github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= @@ -844,16 +807,12 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= -github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcl/v2 v2.9.1 h1:eOy4gREY0/ZQHNItlfuEZqtcQbXIxzojlP301hDpnac= -github.com/hashicorp/hcl/v2 v2.9.1/go.mod h1:FwWsfWEjyV/CMj8s/gqAuiviY72rJ1/oayI9WftqcKg= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= @@ -864,8 +823,6 @@ github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hashicorp/terraform-json v0.12.0 h1:8czPgEEWWPROStjkWPUnTQDXmpmZPlkQAwYYLETaTvw= -github.com/hashicorp/terraform-json v0.12.0/go.mod h1:pmbq9o4EuL43db5+0ogX10Yofv1nozM+wskr/bGFJpI= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -892,8 +849,6 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o= -github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s= github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8 h1:CZkYfurY6KGhVtlalI4QwQ6T0Cu6iuY3e0x5RLu96WE= github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo= github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d h1:jRQLvyVGL+iVtDElaEIDdKwpPqUIZJfzkNLV34htpEc= @@ -944,8 +899,6 @@ github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.0/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= @@ -968,7 +921,6 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= @@ -1045,9 +997,6 @@ github.com/mattn/go-shellwords v1.0.11/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lL github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= -github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326 h1:ofNAzWCcyTALn2Zv40+8XitdzCgXY6e9qvXwN9W0YXg= -github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -1058,7 +1007,6 @@ github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Cl github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw= @@ -1075,7 +1023,6 @@ github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= @@ -1204,7 +1151,6 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -1245,8 +1191,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= -github.com/pquerna/otp v1.2.0 h1:/A3+Jn+cagqayeR3iHs/L62m5ue7710D35zl1zJ1kok= -github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -1323,7 +1267,6 @@ github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc/go.mod h1:HFLT6 github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= @@ -1335,7 +1278,6 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0 github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= @@ -1387,7 +1329,6 @@ github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzu github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -1430,8 +1371,6 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmccombs/hcl2json v0.3.3 h1:+DLNYqpWE0CsOQiEZu+OZm5ZBImake3wtITYxQ8uLFQ= -github.com/tmccombs/hcl2json v0.3.3/go.mod h1:Y2chtz2x9bAeRTvSibVRVgbLJhLJXKlUeIvjeVdnm4w= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -1442,7 +1381,6 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= @@ -1453,9 +1391,6 @@ github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:tw github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= -github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= @@ -1489,12 +1424,6 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMzt github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= -github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8= -github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= -github.com/zclconf/go-cty v1.8.1 h1:SI0LqNeNxAgv2WWqWJMlG2/Ad/6aYJ7IVYYMigmfkuI= -github.com/zclconf/go-cty v1.8.1/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= -github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= @@ -1567,7 +1496,6 @@ golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1632,7 +1560,6 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1692,7 +1619,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1748,7 +1674,6 @@ golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1915,7 +1840,6 @@ golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= diff --git a/test/e2e/common.go b/test/e2e/common.go index 11b1ef51b9..8cbaf61ad5 100644 --- a/test/e2e/common.go +++ b/test/e2e/common.go @@ -28,15 +28,14 @@ import ( type ZarfE2ETest struct { zarfBinPath string - clusterName string - kubeconfigPath string - filesToRemove []string - cmdsToKill []*exec.Cmd - provider *cluster.Provider - restConfig *restclient.Config - clientset *kubernetes.Clientset - clusterAlreadyExists bool - initWithK3s bool + clusterName string + kubeconfigPath string + filesToRemove []string + cmdsToKill []*exec.Cmd + provider *cluster.Provider + restConfig *restclient.Config + clientset *kubernetes.Clientset + initWithK3s bool } func getKubeconfigPath() (string, error) { @@ -93,10 +92,7 @@ func (e2e *ZarfE2ETest) setUpKind() error { // Set up a KinD cluster if necessary e2e.provider = cluster.NewProvider(cluster.ProviderWithLogger(kindcmd.NewLogger())) nodes, err := e2e.provider.ListNodes(e2e.clusterName) - if len(nodes) > 0 { - // There already is a cluster up!! yay!! - e2e.clusterAlreadyExists = true - } else { + if len(nodes) == 0 { err = e2e.provider.Create( e2e.clusterName, cluster.CreateWithNodeImage(""), @@ -123,10 +119,6 @@ func (e2e *ZarfE2ETest) setUpKind() error { } func (e2e *ZarfE2ETest) tearDownKind() error { - if os.Getenv("SKIP_TEARDOWN") != "" || e2e.clusterAlreadyExists { - return nil - } - // Delete the cluster and kubeconfig file provider := cluster.NewProvider(cluster.ProviderWithLogger(kindcmd.NewLogger())) err := provider.Delete(e2e.clusterName, e2e.kubeconfigPath) diff --git a/test/e2e/e2e_data_injection_test.go b/test/e2e/e2e_data_injection_test.go index 95c85d581f..9564d9832f 100644 --- a/test/e2e/e2e_data_injection_test.go +++ b/test/e2e/e2e_data_injection_test.go @@ -33,7 +33,7 @@ func TestDataInjection(t *testing.T) { // Test to confirm the subdirectory file was placed execStdOut = "" attempt = 0 - for attempt < 5 && execStdOut == "" { + for attempt < 10 && execStdOut == "" { execStdOut, _, err = e2e.execCommandInPod("data-injection", "demo", []string{"ls", "/test/subdirectory-test"}) attempt++ time.Sleep(2 * time.Second) diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go index c54e38cfa3..aaf572751a 100644 --- a/test/e2e/main_test.go +++ b/test/e2e/main_test.go @@ -55,45 +55,44 @@ func TestMain(m *testing.M) { // If the current kubeconfig points to an existing cluster run the tests against that cluster if validCubeConfig { retCode = m.Run() - os.Exit(retCode) - } - - // Run the tests against all the distros provided - distroToUse := strings.Split(os.Getenv("TESTDISTRO"), ",") - if len(distroToUse) == 1 && distroToUse[0] == "" { - distroToUse = []string{} - // No distros were specified; Use all the standard distros - for key, value := range distroTests { - if value.standard { - distroToUse = append(distroToUse, key) + } else { + // Run the tests against all the distros provided + distroToUse := strings.Split(os.Getenv("TESTDISTRO"), ",") + if len(distroToUse) == 1 && distroToUse[0] == "" { + distroToUse = []string{} + // No distros were specified; Use all the standard distros + for key, value := range distroTests { + if value.standard { + distroToUse = append(distroToUse, key) + } } } - } - for _, distroName := range distroToUse { - testSuiteFunctions, exists := distroTests[distroName] - if !exists { - fmt.Printf("Provided distro %v is not recognized, continuing tests but reporting as failure\n", distroName) - retCode = 1 - continue - } + for _, distroName := range distroToUse { + testSuiteFunctions, exists := distroTests[distroName] + if !exists { + fmt.Printf("Provided distro %v is not recognized, continuing tests but reporting as failure\n", distroName) + retCode = 1 + continue + } - // Setup the cluster - err := testSuiteFunctions.setupFunction() - defer testSuiteFunctions.tearDownFunction() - if err != nil { - fmt.Printf("Unable to setup %s environment to run the e2e test because of err: %v\n", distroName, err) - os.Exit(1) - } + // Setup the cluster + err := testSuiteFunctions.setupFunction() + defer testSuiteFunctions.tearDownFunction() + if err != nil { + fmt.Printf("Unable to setup %s environment to run the e2e test because of err: %v\n", distroName, err) + os.Exit(1) + } - // exec test and capture exit code to pass to os - testCode := m.Run() - retCode = testCode | retCode + // exec test and capture exit code to pass to os + testCode := m.Run() + retCode = testCode | retCode - // Teardown the cluster now that tests are completed - err = testSuiteFunctions.tearDownFunction() - if err != nil { - fmt.Printf("Unable to cleanly teardown %s environment because of err: %v\n", distroName, err) + // Teardown the cluster now that tests are completed + err = testSuiteFunctions.tearDownFunction() + if err != nil { + fmt.Printf("Unable to cleanly teardown %s environment because of err: %v\n", distroName, err) + } } } From f915f8a3159c5a87e22b0ec882ecc5fafa5e4fbb Mon Sep 17 00:00:00 2001 From: Jon Perry Date: Sat, 5 Mar 2022 05:44:57 -0500 Subject: [PATCH 25/25] adr for e2e testing --- ...02-moving-e2e-tests-away-from-terratest.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 docs/adr/0002-moving-e2e-tests-away-from-terratest.md diff --git a/docs/adr/0002-moving-e2e-tests-away-from-terratest.md b/docs/adr/0002-moving-e2e-tests-away-from-terratest.md new file mode 100644 index 0000000000..8d6fd31c02 --- /dev/null +++ b/docs/adr/0002-moving-e2e-tests-away-from-terratest.md @@ -0,0 +1,36 @@ +# 2. Moving E2E Tests Away From Terratest + +Date: 2022-03-04 + +## Status + +Accepted + +## Context + +In previous releases of Zarf, the creation of the initialization package at the core of many of our E2E tests required repository secrets to login to registry1. Since this is an open-source project, anyone could submit a change to one of our GitHub workflows that could steal our secrets. In order to protect our secrets from any bad-actors we used [peter-evans/slash-command-dispatch@v2](https://github.com/peter-evans/slash-command-dispatch) so that only a maintainer would have the ability to run the E2E tests when a PR is submitted for review. + +In the current version of Zarf (v0.15) images from registry1 are no longer needed to create the zarf-init.tar.zst. This means, given our current span of E2E tests, we no longer need to use repository secrets when running tests. This gives us the ability to reassess the way we do our E2E testing. + +When considering how to handle the tests, some of the important additions we were considering were: + 1. Ability to test against different kubernetes distributions + 2. Ability to test against different linux distributions + 3. Ability to run (at least some of) the E2E tests locally without relying on an ec2 instance - for quicker feedback loops when developing new features + +## Decision + +The previous E2E test code was not extensible enough to be reused to test Zarf against different kubernetes distributions. The test suite was refactored so that we could write a setup and teardown function for each kubernetes distribution we wanted to verify against and the test suite was then responsible for cycling through the different distributions. This gives us the ability to test multiple kubernetes distributions against the same exact test cases. + +The individual test cases were also rewritten to not rely on terratest running a bash command over ssh. Instead, the test uses the locally built Zarf binary and example packages to validate expected behavior. This approach works both on local dev machines (linux/mac) and on the Ubuntu GitHub Runner that gets triggered when a pull request is created. This also has the positive side effect of not needing to wait several minutes for an ec2 instance to spin up for testing. + +Since we no longer need repository secrets to run the E2E tests, we removed the requirement for a maintainer to use a `/test all` chatops command to dispatch the tests. Instead, there is a new test workflow defined for each kubernetes distribution we are verifying against and the tests get run automatically whenever a PR is created or updated. + +When looking back at the list of 'important additions' we were considering above. All three are addressed with this approach. Testing against different kubernetes distributions is as simple as defining how to create and destroy the cluster. All of the test cases are runnable locally and then because of that testing on a linux distribution is possible by just switching over to another machine and running the same `make test-e2e` there. This also gives us the ability to test against cloud distributions like EKS! All you need is a valid kubeconfig and running `go test ./...` in the `./test/e2e` directory will run all of the test cases against the EKS cluster. + +## Consequences + +While it was not something we were doing before, testing directly on the GitHub Runner instead of using Terratest to test on an ec2 instance means that when we get around to adding automated testing of Zarf against different linux distrobutions we will want to have more discussions on if we want to use self-hosted runners of different OS's or if we want to go back to Terratest to stand up ec2 instances with different AMIs. + +In the future, we will likely want to write E2E tests that use images that require repository secrets to access. When that happens we will want to bring back some form of 'maintainer action' to initiate the test workflow. Going back to [peter-evans/slash-command-dispatch@v2](https://github.com/peter-evans/slash-command-dispatch) might be the right answer for that but there will need to be more discussion to make sure the team agrees that's the best solution first. + +As the amount of E2E tests we have grows, the longer it will take to get results back on each PR. Duhh! Paralyzing the tests on a single host will be difficult (but not impossible) because it means more logic will be needed in the test suite to make sure the host has enough resources to handle multiple clusters being run in parallel. The simpler solution would be to break out each of our tests into a new GitHub Workflow. This will easily mitigate the issue of tests taking long to run but also give us a lot more yaml to maintain. Either solution is valid but more team discussions will be needed as we get closer to needing it.