Run CI tests in docker instead of a machine. (#8948)

This commit is contained in:
ncabatoff
2020-09-15 10:01:26 -04:00
committed by GitHub
parent 75b2f42ef2
commit 2b3aef242b
149 changed files with 3451 additions and 2448 deletions

634
.circleci/config.yml generated
View File

@@ -676,6 +676,140 @@ jobs:
key: cache002-warm-go-build-vendor-cache_6876_{{checksum ".buildcache/cache-keys/warm-go-build-vendor-cache-6876aa566f90846d4627c4a1c86ca155ccde2f1c"}}
paths:
- .buildcache/archives/08-warm-go-build-vendor-cache-6876aa566f90846d4627c4a1c86ca155ccde2f1c.tar.gz
test-go-remote-docker:
docker:
- image: circleci/golang:1.14.7-stretch
resource_class: large
working_directory: /go/src/github.com/hashicorp/vault
parallelism: 8
steps:
- run:
command: |
# If the branch being tested starts with ui/ or docs/ we want to exit the job without failing
[[ "$CIRCLE_BRANCH" = ui/* || "$CIRCLE_BRANCH" = docs/* ]] && {
# stop the job from this step
circleci-agent step halt
}
# exit with success either way
exit 0
name: Check branch name
working_directory: ~/
- checkout
- setup_remote_docker:
docker_layer_caching: true
version: 18.09.3
- run:
command: |
TZ=GMT date '+%Y%m%d' > /tmp/go-cache-key
name: Compute test cache key
- restore_cache:
keys:
- go-test-cache-date-v1-{{ checksum "/tmp/go-cache-key" }}
- run:
command: |
set -x
case "" in
*-race*) export VAULT_CI_GO_TEST_RACE=1;;
esac
# Install CircleCI CLI
curl -sSL \
"https://github.com/CircleCI-Public/circleci-cli/releases/download/v${CIRCLECI_CLI_VERSION}/circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64.tar.gz" \
| sudo tar --overwrite -xz \
-C /usr/local/bin \
"circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64/circleci"
USE_DOCKER=0
USE_DOCKER=1
# Split Go tests by prior test times. If use_docker is true, only run
# tests that depend on docker, otherwise only those that don't.
if [ $USE_DOCKER == 1 ]; then
package_names=$(go list -test -json ./... |
jq -r 'select(.Deps != null) |
select(any(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker"))) |
.ForTest | select(. != null)' |
sort -u | circleci tests split --split-by=timings --timings-type=classname)
else
package_names=$(go list -test -json ./... |
jq -r 'select(.Deps != null) |
select(all(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker")|not)) |
.ForTest | select(. != null)' |
sort -u | circleci tests split --split-by=timings --timings-type=classname)
fi
# After running tests split step, we are now running the following steps
# in multiple different containers, each getting a different subset of
# the test packages in their package_names variable. Each container
# has its own remote docker VM.
make prep
mkdir -p test-results/go-test
# Create a docker network for our testcontainer
if [ $USE_DOCKER == 1 ]; then
export TEST_DOCKER_NETWORK_ID=$(docker network list -q -f 'name=vaulttest')
if [ -z $TEST_DOCKER_NETWORK_ID ]; then
TEST_DOCKER_NETWORK_ID=$(docker network create vaulttest)
fi
# Start a docker testcontainer to run the tests in
docker run -d -e TEST_DOCKER_NETWORK_ID \
-e DOCKER_CERT_PATH -e DOCKER_HOST -e DOCKER_MACHINE_NAME -e DOCKER_TLS_VERIFY -e NO_PROXY \
-e VAULT_TEST_LOG_DIR=/tmp/testlogs \
--network vaulttest --name \
testcontainer circleci/golang:1.14.7-stretch \
tail -f /dev/null
# Run tests
docker cp /tmp/go-cache testcontainer:/tmp/gocache
docker exec testcontainer sh -c 'mkdir -p /go/src/github.com/hashicorp/vault'
docker cp . testcontainer:/go/src/github.com/hashicorp/vault/
docker cp $DOCKER_CERT_PATH/ testcontainer:$DOCKER_CERT_PATH
docker exec -w /go/src/github.com/hashicorp/vault/ \
-e GO111MODULE -e CIRCLECI -e GOCACHE=/tmp/gocache -e VAULT_CI_GO_TEST_RACE \
testcontainer \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=15m \
-parallel=20 \
\
${package_names}
else
GOCACHE=/tmp/go-cache \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=60m \
-parallel=20 \
\
${package_names}
fi
name: Run Go tests
no_output_timeout: 60m
- run:
command: |
docker cp testcontainer:/go/src/github.com/hashicorp/vault/test-results .
docker cp testcontainer:/tmp/gocache /tmp/go-cache
name: Copy test results
when: always
- store_artifacts:
path: test-results
- store_test_results:
path: test-results
- store_artifacts:
path: /tmp/testlogs
environment:
- CIRCLECI_CLI_VERSION: 0.1.5546
- GO_TAGS: ''
- GO111MODULE: 'off'
freebsd_386_package:
docker:
- image: circleci/buildpack-deps
@@ -740,26 +874,22 @@ jobs:
paths:
- .buildcache/archives/08-warm-go-build-vendor-cache-0245576886d78da53ffbd161a95bd0ca099e5fc1.tar.gz
test-go-race:
machine: true
shell: /usr/bin/env bash -euo pipefail -c
docker:
- image: circleci/golang:1.14.7-stretch
resource_class: xlarge
working_directory: /go/src/github.com/hashicorp/vault
parallelism: 8
steps:
- run:
command: |
[ -n "$GO_VERSION" ] || { echo "You must set GO_VERSION"; exit 1; }
# Install Go
curl -sSLO "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go${GO_VERSION}.linux-amd64.tar.gz"
rm -f "go${GO_VERSION}.linux-amd64.tar.gz"
GOPATH="/go"
mkdir $GOPATH 2>/dev/null || { sudo mkdir $GOPATH && sudo chmod 777 $GOPATH; }
echo "export GOPATH='$GOPATH'" >> "$BASH_ENV"
echo "export PATH='$PATH:$GOPATH/bin:/usr/local/go/bin'" >> "$BASH_ENV"
echo "$ go version"
go version
name: Setup Go
# If the branch being tested starts with ui/ or docs/ we want to exit the job without failing
[[ "$CIRCLE_BRANCH" = ui/* || "$CIRCLE_BRANCH" = docs/* ]] && {
# stop the job from this step
circleci-agent step halt
}
# exit with success either way
exit 0
name: Check branch name
working_directory: ~/
- checkout
- run:
@@ -774,7 +904,7 @@ jobs:
set -x
case "-race" in
*-race*) VAULT_CI_GO_TEST_RACE=1;;
*-race*) export VAULT_CI_GO_TEST_RACE=1;;
esac
# Install CircleCI CLI
@@ -784,38 +914,77 @@ jobs:
-C /usr/local/bin \
"circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64/circleci"
# Split Go tests by prior test times
package_names=$(go list \
-tags "${GO_TAGS}" \
./... \
| grep -v /integ \
| grep -v /vendor/ \
| sort \
| circleci tests split --split-by=timings --timings-type=classname)
USE_DOCKER=0
# Install gotestsum
curl -sSL "https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_linux_amd64.tar.gz" \
| sudo tar --overwrite -xz -C /usr/local/bin gotestsum
# Split Go tests by prior test times. If use_docker is true, only run
# tests that depend on docker, otherwise only those that don't.
if [ $USE_DOCKER == 1 ]; then
package_names=$(go list -test -json ./... |
jq -r 'select(.Deps != null) |
select(any(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker"))) |
.ForTest | select(. != null)' |
sort -u | circleci tests split --split-by=timings --timings-type=classname)
else
package_names=$(go list -test -json ./... |
jq -r 'select(.Deps != null) |
select(all(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker")|not)) |
.ForTest | select(. != null)' |
sort -u | circleci tests split --split-by=timings --timings-type=classname)
fi
# After running tests split step, we are now running the following steps
# in multiple different containers, each getting a different subset of
# the test packages in their package_names variable. Each container
# has its own remote docker VM.
# Run tests
make prep
mkdir -p test-results/go-test
CGO_ENABLED= \
VAULT_ADDR= \
VAULT_TOKEN= \
VAULT_DEV_ROOT_TOKEN_ID= \
VAULT_ACC= \
# Create a docker network for our testcontainer
if [ $USE_DOCKER == 1 ]; then
export TEST_DOCKER_NETWORK_ID=$(docker network list -q -f 'name=vaulttest')
if [ -z $TEST_DOCKER_NETWORK_ID ]; then
TEST_DOCKER_NETWORK_ID=$(docker network create vaulttest)
fi
# Start a docker testcontainer to run the tests in
docker run -d -e TEST_DOCKER_NETWORK_ID \
-e DOCKER_CERT_PATH -e DOCKER_HOST -e DOCKER_MACHINE_NAME -e DOCKER_TLS_VERIFY -e NO_PROXY \
-e VAULT_TEST_LOG_DIR=/tmp/testlogs \
--network vaulttest --name \
testcontainer circleci/golang:1.14.7-stretch \
tail -f /dev/null
# Run tests
docker cp /tmp/go-cache testcontainer:/tmp/gocache
docker exec testcontainer sh -c 'mkdir -p /go/src/github.com/hashicorp/vault'
docker cp . testcontainer:/go/src/github.com/hashicorp/vault/
docker cp $DOCKER_CERT_PATH/ testcontainer:$DOCKER_CERT_PATH
docker exec -w /go/src/github.com/hashicorp/vault/ \
-e GO111MODULE -e CIRCLECI -e GOCACHE=/tmp/gocache -e VAULT_CI_GO_TEST_RACE \
testcontainer \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=15m \
-parallel=20 \
-race \
${package_names}
else
GOCACHE=/tmp/go-cache \
VAULT_TEST_LOG_DIR=/tmp/testlogs \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=60m \
-parallel=20 \
-race \
${package_names}
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=60m \
-parallel=20 \
-race \
${package_names}
fi
name: Run Go tests
no_output_timeout: 60m
- store_artifacts:
@@ -827,9 +996,7 @@ jobs:
environment:
- CIRCLECI_CLI_VERSION: 0.1.5546
- GO_TAGS: ''
- GO_VERSION: 1.14.7
- GO111MODULE: 'off'
- GOTESTSUM_VERSION: 0.5.2
freebsd_amd64_package:
docker:
- image: circleci/buildpack-deps
@@ -1106,10 +1273,11 @@ jobs:
paths:
- .buildcache/archives/08-warm-go-build-vendor-cache-a0884ebd3bcd667787991bce276f3a9be2061998.tar.gz
test-go:
machine: true
shell: /usr/bin/env bash -euo pipefail -c
docker:
- image: circleci/golang:1.14.7-stretch
resource_class: large
working_directory: /go/src/github.com/hashicorp/vault
parallelism: 2
parallelism: 8
steps:
- run:
command: |
@@ -1122,23 +1290,6 @@ jobs:
exit 0
name: Check branch name
working_directory: ~/
- run:
command: |
[ -n "$GO_VERSION" ] || { echo "You must set GO_VERSION"; exit 1; }
# Install Go
curl -sSLO "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go${GO_VERSION}.linux-amd64.tar.gz"
rm -f "go${GO_VERSION}.linux-amd64.tar.gz"
GOPATH="/go"
mkdir $GOPATH 2>/dev/null || { sudo mkdir $GOPATH && sudo chmod 777 $GOPATH; }
echo "export GOPATH='$GOPATH'" >> "$BASH_ENV"
echo "export PATH='$PATH:$GOPATH/bin:/usr/local/go/bin'" >> "$BASH_ENV"
echo "$ go version"
go version
name: Setup Go
working_directory: ~/
- checkout
- run:
command: |
@@ -1152,7 +1303,7 @@ jobs:
set -x
case "" in
*-race*) VAULT_CI_GO_TEST_RACE=1;;
*-race*) export VAULT_CI_GO_TEST_RACE=1;;
esac
# Install CircleCI CLI
@@ -1162,38 +1313,77 @@ jobs:
-C /usr/local/bin \
"circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64/circleci"
# Split Go tests by prior test times
package_names=$(go list \
-tags "${GO_TAGS}" \
./... \
| grep -v /integ \
| grep -v /vendor/ \
| sort \
| circleci tests split --split-by=timings --timings-type=classname)
USE_DOCKER=0
# Install gotestsum
curl -sSL "https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_linux_amd64.tar.gz" \
| sudo tar --overwrite -xz -C /usr/local/bin gotestsum
# Split Go tests by prior test times. If use_docker is true, only run
# tests that depend on docker, otherwise only those that don't.
if [ $USE_DOCKER == 1 ]; then
package_names=$(go list -test -json ./... |
jq -r 'select(.Deps != null) |
select(any(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker"))) |
.ForTest | select(. != null)' |
sort -u | circleci tests split --split-by=timings --timings-type=classname)
else
package_names=$(go list -test -json ./... |
jq -r 'select(.Deps != null) |
select(all(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker")|not)) |
.ForTest | select(. != null)' |
sort -u | circleci tests split --split-by=timings --timings-type=classname)
fi
# After running tests split step, we are now running the following steps
# in multiple different containers, each getting a different subset of
# the test packages in their package_names variable. Each container
# has its own remote docker VM.
# Run tests
make prep
mkdir -p test-results/go-test
CGO_ENABLED= \
VAULT_ADDR= \
VAULT_TOKEN= \
VAULT_DEV_ROOT_TOKEN_ID= \
VAULT_ACC= \
# Create a docker network for our testcontainer
if [ $USE_DOCKER == 1 ]; then
export TEST_DOCKER_NETWORK_ID=$(docker network list -q -f 'name=vaulttest')
if [ -z $TEST_DOCKER_NETWORK_ID ]; then
TEST_DOCKER_NETWORK_ID=$(docker network create vaulttest)
fi
# Start a docker testcontainer to run the tests in
docker run -d -e TEST_DOCKER_NETWORK_ID \
-e DOCKER_CERT_PATH -e DOCKER_HOST -e DOCKER_MACHINE_NAME -e DOCKER_TLS_VERIFY -e NO_PROXY \
-e VAULT_TEST_LOG_DIR=/tmp/testlogs \
--network vaulttest --name \
testcontainer circleci/golang:1.14.7-stretch \
tail -f /dev/null
# Run tests
docker cp /tmp/go-cache testcontainer:/tmp/gocache
docker exec testcontainer sh -c 'mkdir -p /go/src/github.com/hashicorp/vault'
docker cp . testcontainer:/go/src/github.com/hashicorp/vault/
docker cp $DOCKER_CERT_PATH/ testcontainer:$DOCKER_CERT_PATH
docker exec -w /go/src/github.com/hashicorp/vault/ \
-e GO111MODULE -e CIRCLECI -e GOCACHE=/tmp/gocache -e VAULT_CI_GO_TEST_RACE \
testcontainer \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=15m \
-parallel=20 \
\
${package_names}
else
GOCACHE=/tmp/go-cache \
VAULT_TEST_LOG_DIR=/tmp/testlogs \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=60m \
-parallel=20 \
\
${package_names}
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=60m \
-parallel=20 \
\
${package_names}
fi
name: Run Go tests
no_output_timeout: 60m
- store_artifacts:
@@ -1205,9 +1395,7 @@ jobs:
environment:
- CIRCLECI_CLI_VERSION: 0.1.5546
- GO_TAGS: ''
- GO_VERSION: 1.14.7
- GO111MODULE: 'off'
- GOTESTSUM_VERSION: 0.5.2
test-go-nightly:
machine: true
shell: /usr/bin/env bash -euo pipefail -c
@@ -1254,7 +1442,7 @@ jobs:
set -x
case "" in
*-race*) VAULT_CI_GO_TEST_RACE=1;;
*-race*) export VAULT_CI_GO_TEST_RACE=1;;
esac
# Install CircleCI CLI
@@ -1264,38 +1452,77 @@ jobs:
-C /usr/local/bin \
"circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64/circleci"
# Split Go tests by prior test times
package_names=$(go list \
-tags "${GO_TAGS}" \
./... \
| grep -v /integ \
| grep -v /vendor/ \
| sort \
| circleci tests split --split-by=timings --timings-type=classname)
USE_DOCKER=0
# Install gotestsum
curl -sSL "https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_linux_amd64.tar.gz" \
| sudo tar --overwrite -xz -C /usr/local/bin gotestsum
# Split Go tests by prior test times. If use_docker is true, only run
# tests that depend on docker, otherwise only those that don't.
if [ $USE_DOCKER == 1 ]; then
package_names=$(go list -test -json ./... |
jq -r 'select(.Deps != null) |
select(any(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker"))) |
.ForTest | select(. != null)' |
sort -u | circleci tests split --split-by=timings --timings-type=classname)
else
package_names=$(go list -test -json ./... |
jq -r 'select(.Deps != null) |
select(all(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker")|not)) |
.ForTest | select(. != null)' |
sort -u | circleci tests split --split-by=timings --timings-type=classname)
fi
# After running tests split step, we are now running the following steps
# in multiple different containers, each getting a different subset of
# the test packages in their package_names variable. Each container
# has its own remote docker VM.
# Run tests
make prep
mkdir -p test-results/go-test
CGO_ENABLED= \
VAULT_ADDR= \
VAULT_TOKEN= \
VAULT_DEV_ROOT_TOKEN_ID= \
VAULT_ACC= \
# Create a docker network for our testcontainer
if [ $USE_DOCKER == 1 ]; then
export TEST_DOCKER_NETWORK_ID=$(docker network list -q -f 'name=vaulttest')
if [ -z $TEST_DOCKER_NETWORK_ID ]; then
TEST_DOCKER_NETWORK_ID=$(docker network create vaulttest)
fi
# Start a docker testcontainer to run the tests in
docker run -d -e TEST_DOCKER_NETWORK_ID \
-e DOCKER_CERT_PATH -e DOCKER_HOST -e DOCKER_MACHINE_NAME -e DOCKER_TLS_VERIFY -e NO_PROXY \
-e VAULT_TEST_LOG_DIR=/tmp/testlogs \
--network vaulttest --name \
testcontainer circleci/golang:1.14.7-stretch \
tail -f /dev/null
# Run tests
docker cp /tmp/go-cache testcontainer:/tmp/gocache
docker exec testcontainer sh -c 'mkdir -p /go/src/github.com/hashicorp/vault'
docker cp . testcontainer:/go/src/github.com/hashicorp/vault/
docker cp $DOCKER_CERT_PATH/ testcontainer:$DOCKER_CERT_PATH
docker exec -w /go/src/github.com/hashicorp/vault/ \
-e GO111MODULE -e CIRCLECI -e GOCACHE=/tmp/gocache -e VAULT_CI_GO_TEST_RACE \
testcontainer \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=15m \
-parallel=20 \
\
${package_names}
else
GOCACHE=/tmp/go-cache \
VAULT_TEST_LOG_DIR=/tmp/testlogs \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=60m \
-parallel=20 \
\
${package_names}
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=60m \
-parallel=20 \
\
${package_names}
fi
name: Run Go tests
no_output_timeout: 60m
- save_cache:
@@ -1757,6 +1984,140 @@ jobs:
environment:
- AUTO_INSTALL_TOOLS: 'YES'
- PRODUCT_REVISION: ''
test-go-race-remote-docker:
docker:
- image: circleci/golang:1.14.7-stretch
resource_class: xlarge
working_directory: /go/src/github.com/hashicorp/vault
parallelism: 8
steps:
- run:
command: |
# If the branch being tested starts with ui/ or docs/ we want to exit the job without failing
[[ "$CIRCLE_BRANCH" = ui/* || "$CIRCLE_BRANCH" = docs/* ]] && {
# stop the job from this step
circleci-agent step halt
}
# exit with success either way
exit 0
name: Check branch name
working_directory: ~/
- checkout
- setup_remote_docker:
docker_layer_caching: true
version: 18.09.3
- run:
command: |
TZ=GMT date '+%Y%m%d' > /tmp/go-cache-key
name: Compute test cache key
- restore_cache:
keys:
- go-test-cache-date-v1-{{ checksum "/tmp/go-cache-key" }}
- run:
command: |
set -x
case "-race" in
*-race*) export VAULT_CI_GO_TEST_RACE=1;;
esac
# Install CircleCI CLI
curl -sSL \
"https://github.com/CircleCI-Public/circleci-cli/releases/download/v${CIRCLECI_CLI_VERSION}/circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64.tar.gz" \
| sudo tar --overwrite -xz \
-C /usr/local/bin \
"circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64/circleci"
USE_DOCKER=0
USE_DOCKER=1
# Split Go tests by prior test times. If use_docker is true, only run
# tests that depend on docker, otherwise only those that don't.
if [ $USE_DOCKER == 1 ]; then
package_names=$(go list -test -json ./... |
jq -r 'select(.Deps != null) |
select(any(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker"))) |
.ForTest | select(. != null)' |
sort -u | circleci tests split --split-by=timings --timings-type=classname)
else
package_names=$(go list -test -json ./... |
jq -r 'select(.Deps != null) |
select(all(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker")|not)) |
.ForTest | select(. != null)' |
sort -u | circleci tests split --split-by=timings --timings-type=classname)
fi
# After running tests split step, we are now running the following steps
# in multiple different containers, each getting a different subset of
# the test packages in their package_names variable. Each container
# has its own remote docker VM.
make prep
mkdir -p test-results/go-test
# Create a docker network for our testcontainer
if [ $USE_DOCKER == 1 ]; then
export TEST_DOCKER_NETWORK_ID=$(docker network list -q -f 'name=vaulttest')
if [ -z $TEST_DOCKER_NETWORK_ID ]; then
TEST_DOCKER_NETWORK_ID=$(docker network create vaulttest)
fi
# Start a docker testcontainer to run the tests in
docker run -d -e TEST_DOCKER_NETWORK_ID \
-e DOCKER_CERT_PATH -e DOCKER_HOST -e DOCKER_MACHINE_NAME -e DOCKER_TLS_VERIFY -e NO_PROXY \
-e VAULT_TEST_LOG_DIR=/tmp/testlogs \
--network vaulttest --name \
testcontainer circleci/golang:1.14.7-stretch \
tail -f /dev/null
# Run tests
docker cp /tmp/go-cache testcontainer:/tmp/gocache
docker exec testcontainer sh -c 'mkdir -p /go/src/github.com/hashicorp/vault'
docker cp . testcontainer:/go/src/github.com/hashicorp/vault/
docker cp $DOCKER_CERT_PATH/ testcontainer:$DOCKER_CERT_PATH
docker exec -w /go/src/github.com/hashicorp/vault/ \
-e GO111MODULE -e CIRCLECI -e GOCACHE=/tmp/gocache -e VAULT_CI_GO_TEST_RACE \
testcontainer \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=15m \
-parallel=20 \
-race \
${package_names}
else
GOCACHE=/tmp/go-cache \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=60m \
-parallel=20 \
-race \
${package_names}
fi
name: Run Go tests
no_output_timeout: 60m
- run:
command: |
docker cp testcontainer:/go/src/github.com/hashicorp/vault/test-results .
docker cp testcontainer:/tmp/gocache /tmp/go-cache
name: Copy test results
when: always
- store_artifacts:
path: test-results
- store_test_results:
path: test-results
- store_artifacts:
path: /tmp/testlogs
environment:
- CIRCLECI_CLI_VERSION: 0.1.5546
- GO_TAGS: ''
- GO111MODULE: 'off'
workflows:
build-standalone:
jobs:
@@ -1853,8 +2214,21 @@ workflows:
- install-ui-dependencies
- build-go-dev
- test-go:
filters:
branches:
ignore:
- /^docs\/.*/
- /^ui\/.*/
requires:
- build-go-dev
- pre-flight-checks
- test-go-remote-docker:
filters:
branches:
ignore:
- /^docs\/.*/
- /^ui\/.*/
requires:
- pre-flight-checks
- test-go-race:
filters:
branches:
@@ -1862,7 +2236,15 @@ workflows:
- /^docs\/.*/
- /^ui\/.*/
requires:
- build-go-dev
- pre-flight-checks
- test-go-race-remote-docker:
filters:
branches:
ignore:
- /^docs\/.*/
- /^ui\/.*/
requires:
- pre-flight-checks
- website-docker-image:
filters:
branches:

View File

@@ -3,4 +3,3 @@ version: 2.1
orbs:
slack: circleci/slack@3.2.0

View File

@@ -12,6 +12,12 @@ parameters:
save_cache:
type: boolean
default: false
go_image:
type: string
default: "circleci/golang:1.14.7-stretch"
use_docker:
type: boolean
default: false
steps:
- run:
name: Compute test cache key
@@ -27,7 +33,7 @@ steps:
set -x
case "<< parameters.extra_flags >>" in
*-race*) VAULT_CI_GO_TEST_RACE=1;;
*-race*) export VAULT_CI_GO_TEST_RACE=1;;
esac
# Install CircleCI CLI
@@ -37,39 +43,90 @@ steps:
-C /usr/local/bin \
"circleci-cli_${CIRCLECI_CLI_VERSION}_linux_amd64/circleci"
# Split Go tests by prior test times
package_names=$(go list \
-tags "${GO_TAGS}" \
./... \
| grep -v /integ \
| grep -v /vendor/ \
| sort \
| circleci tests split --split-by=timings --timings-type=classname)
USE_DOCKER=0
<<# parameters.use_docker >>
USE_DOCKER=1
<</ parameters.use_docker >>
# Install gotestsum
curl -sSL "https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_linux_amd64.tar.gz" \
| sudo tar --overwrite -xz -C /usr/local/bin gotestsum
# Split Go tests by prior test times. If use_docker is true, only run
# tests that depend on docker, otherwise only those that don't.
if [ $USE_DOCKER == 1 ]; then
package_names=$(go list -test -json ./... |
jq -r 'select(.Deps != null) |
select(any(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker"))) |
.ForTest | select(. != null)' |
sort -u | circleci tests split --split-by=timings --timings-type=classname)
else
package_names=$(go list -test -json ./... |
jq -r 'select(.Deps != null) |
select(all(.Deps[] ; contains("github.com/hashicorp/vault/helper/testhelpers/docker")|not)) |
.ForTest | select(. != null)' |
sort -u | circleci tests split --split-by=timings --timings-type=classname)
fi
# After running tests split step, we are now running the following steps
# in multiple different containers, each getting a different subset of
# the test packages in their package_names variable. Each container
# has its own remote docker VM.
# Run tests
make prep
mkdir -p test-results/go-test
CGO_ENABLED= \
VAULT_ADDR= \
VAULT_TOKEN= \
VAULT_DEV_ROOT_TOKEN_ID= \
VAULT_ACC= \
GOCACHE=<< parameters.cache_dir >> \
VAULT_TEST_LOG_DIR=<< parameters.log_dir >> \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=60m \
-parallel=20 \
<< parameters.extra_flags >> \
${package_names}
# Create a docker network for our testcontainer
if [ $USE_DOCKER == 1 ]; then
export TEST_DOCKER_NETWORK_ID=$(docker network list -q -f 'name=vaulttest')
if [ -z $TEST_DOCKER_NETWORK_ID ]; then
TEST_DOCKER_NETWORK_ID=$(docker network create vaulttest)
fi
# Start a docker testcontainer to run the tests in
docker run -d -e TEST_DOCKER_NETWORK_ID \
-e DOCKER_CERT_PATH -e DOCKER_HOST -e DOCKER_MACHINE_NAME -e DOCKER_TLS_VERIFY -e NO_PROXY \
-e VAULT_TEST_LOG_DIR=<< parameters.log_dir >> \
--network vaulttest --name \
testcontainer << parameters.go_image >> \
tail -f /dev/null
# Run tests
docker cp << parameters.cache_dir >> testcontainer:/tmp/gocache
docker exec testcontainer sh -c 'mkdir -p /go/src/github.com/hashicorp/vault'
docker cp . testcontainer:/go/src/github.com/hashicorp/vault/
docker cp $DOCKER_CERT_PATH/ testcontainer:$DOCKER_CERT_PATH
docker exec -w /go/src/github.com/hashicorp/vault/ \
-e GO111MODULE -e CIRCLECI -e GOCACHE=/tmp/gocache -e VAULT_CI_GO_TEST_RACE \
testcontainer \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=15m \
-parallel=20 \
<< parameters.extra_flags >> \
${package_names}
else
GOCACHE=<< parameters.cache_dir >> \
gotestsum --format=short-verbose \
--junitfile test-results/go-test/results.xml \
--jsonfile test-results/go-test/results.json \
-- \
-tags "${GO_TAGS}" \
-timeout=60m \
-parallel=20 \
<< parameters.extra_flags >> \
${package_names}
fi
- when:
condition: << parameters.use_docker >>
steps:
- run:
name: Copy test results
when: always
command: |
docker cp testcontainer:/go/src/github.com/hashicorp/vault/test-results .
docker cp testcontainer:/tmp/gocache << parameters.cache_dir >>
- when:
condition: << parameters.save_cache >>
steps:

View File

@@ -23,3 +23,21 @@ alpine:
- image: alpine:3.10.2
shell: /bin/sh
working_directory: /go/src/github.com/hashicorp/vault
docker-env-large:
resource_class: large
docker:
- image: "circleci/golang:1.14.7-stretch"
environment:
GO111MODULE: "off"
CIRCLECI_CLI_VERSION: 0.1.5546 # Pin CircleCI CLI to patch version (ex: 1.2.3)
GO_TAGS: ""
working_directory: /go/src/github.com/hashicorp/vault
docker-env-xlarge:
resource_class: xlarge
docker:
- image: "circleci/golang:1.14.7-stretch"
environment:
GO111MODULE: "off"
CIRCLECI_CLI_VERSION: 0.1.5546 # Pin CircleCI CLI to patch version (ex: 1.2.3)
GO_TAGS: ""
working_directory: /go/src/github.com/hashicorp/vault

View File

@@ -0,0 +1,18 @@
executor: docker-env-xlarge
parallelism: 8
steps:
- check-branch-name
- checkout
- setup_remote_docker:
version: 18.09.3
docker_layer_caching: true
- go_test:
extra_flags: "-race"
log_dir: "/tmp/testlogs"
use_docker: true
- store_artifacts:
path: test-results
- store_test_results:
path: test-results
- store_artifacts:
path: "/tmp/testlogs"

View File

@@ -1,6 +1,7 @@
executor: go-machine
executor: docker-env-xlarge
parallelism: 8
steps:
- setup-go
- check-branch-name
- checkout
- go_test:
extra_flags: "-race"

View File

@@ -0,0 +1,17 @@
executor: docker-env-large
parallelism: 8
steps:
- check-branch-name
- checkout
- setup_remote_docker:
version: 18.09.3
docker_layer_caching: true
- go_test:
log_dir: "/tmp/testlogs"
use_docker: true
- store_artifacts:
path: test-results
- store_test_results:
path: test-results
- store_artifacts:
path: "/tmp/testlogs"

View File

@@ -1,8 +1,7 @@
executor: go-machine
parallelism: 2
executor: docker-env-large
parallelism: 8
steps:
- check-branch-name
- setup-go
- checkout
- go_test:
log_dir: "/tmp/testlogs"

View File

@@ -20,10 +20,34 @@ jobs:
ignore: /pull\/[0-9]+/
- test-go:
requires:
- build-go-dev
- pre-flight-checks
filters:
branches:
# UI and Docs-only branches should skip go tests
ignore:
- /^docs\/.*/
- /^ui\/.*/
- test-go-remote-docker:
requires:
- pre-flight-checks
filters:
branches:
# UI and Docs-only branches should skip go tests
ignore:
- /^docs\/.*/
- /^ui\/.*/
- test-go-race:
requires:
- build-go-dev
- pre-flight-checks
filters:
branches:
# UI and Docs-only branches should skip go tests
ignore:
- /^docs\/.*/
- /^ui\/.*/
- test-go-race-remote-docker:
requires:
- pre-flight-checks
filters:
branches:
# UI and Docs-only branches should skip go tests

View File

@@ -18,6 +18,7 @@ import (
)
const amzHeaderPrefix = "X-Amz-"
var defaultAllowedSTSRequestHeaders = []string{
"X-Amz-Date",
"X-Amz-Credential",

View File

@@ -336,7 +336,7 @@ type clientConfig struct {
func (c *clientConfig) validateAllowedSTSHeaderValues(headers http.Header) error {
for k := range headers {
h := textproto.CanonicalMIMEHeaderKey(k)
if strings.HasPrefix(h, amzHeaderPrefix) &&
if strings.HasPrefix(h, amzHeaderPrefix) &&
!strutil.StrListContains(defaultAllowedSTSRequestHeaders, h) &&
!strutil.StrListContains(c.AllowedSTSHeaderValues, h) {
return errors.New("invalid request header: " + k)

View File

@@ -6,13 +6,13 @@ import (
"os"
"reflect"
"strconv"
"strings"
"testing"
"time"
"github.com/hashicorp/vault/helper/testhelpers/docker"
logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical"
"github.com/hashicorp/vault/sdk/logical"
"github.com/ory/dockertest"
)
const (
@@ -32,40 +32,30 @@ func prepareRadiusTestContainer(t *testing.T) (func(), string, int) {
return func() {}, os.Getenv(envRadiusRadiusHost), port
}
pool, err := dockertest.NewPool("")
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "jumanjiman/radiusd",
ImageTag: "latest",
ContainerName: "radiusd",
Cmd: []string{"-f", "-l", "stdout"},
Ports: []string{"1812/udp"},
})
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
t.Fatalf("Could not start docker radiusd: %s", err)
}
runOpts := &dockertest.RunOptions{
Repository: "jumanjiman/radiusd",
Cmd: []string{"-f", "-l", "stdout"},
ExposedPorts: []string{"1812/udp"},
Tag: "latest",
}
resource, err := pool.RunWithOptions(runOpts)
if err != nil {
t.Fatalf("Could not start local radius docker container: %s", err)
}
cleanup := func() {
docker.CleanupResource(t, pool, resource)
}
port, _ := strconv.Atoi(resource.GetPort("1812/udp"))
address := fmt.Sprintf("127.0.0.1")
// exponential backoff-retry
if err = pool.Retry(func() error {
svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
// There's no straightfoward way to check the state, but the server starts
// up quick so a 2 second sleep should be enough.
time.Sleep(2 * time.Second)
return nil
}); err != nil {
cleanup()
t.Fatalf("Could not connect to radius docker container: %s", err)
return docker.NewServiceHostPort(host, port), nil
})
if err != nil {
t.Fatalf("Could not start docker radiusd: %s", err)
}
return cleanup, address, port
pieces := strings.Split(svc.Config.Address(), ":")
port, _ := strconv.Atoi(pieces[1])
return svc.Cleanup, pieces[0], port
}
func TestBackend_Config(t *testing.T) {

View File

@@ -4,81 +4,15 @@ import (
"context"
"fmt"
"log"
"os"
"strconv"
"sync"
"testing"
"github.com/gocql/gocql"
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/hashicorp/vault/helper/testhelpers/cassandra"
logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical"
"github.com/hashicorp/vault/sdk/logical"
"github.com/mitchellh/mapstructure"
"github.com/ory/dockertest"
)
var (
testImagePull sync.Once
)
func prepareCassandraTestContainer(t *testing.T) (func(), string, int) {
if os.Getenv("CASSANDRA_HOST") != "" {
return func() {}, os.Getenv("CASSANDRA_HOST"), 0
}
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
}
cwd, _ := os.Getwd()
cassandraMountPath := fmt.Sprintf("%s/test-fixtures/:/etc/cassandra/", cwd)
ro := &dockertest.RunOptions{
Repository: "cassandra",
Tag: "latest",
Env: []string{"CASSANDRA_BROADCAST_ADDRESS=127.0.0.1"},
Mounts: []string{cassandraMountPath},
}
resource, err := pool.RunWithOptions(ro)
if err != nil {
t.Fatalf("Could not start local cassandra docker container: %s", err)
}
cleanup := func() {
docker.CleanupResource(t, pool, resource)
}
port, _ := strconv.Atoi(resource.GetPort("9042/tcp"))
address := fmt.Sprintf("127.0.0.1:%d", port)
// exponential backoff-retry
if err = pool.Retry(func() error {
clusterConfig := gocql.NewCluster(address)
clusterConfig.Authenticator = gocql.PasswordAuthenticator{
Username: "cassandra",
Password: "cassandra",
}
clusterConfig.ProtoVersion = 4
clusterConfig.Port = port
session, err := clusterConfig.CreateSession()
if err != nil {
return fmt.Errorf("error creating session: %s", err)
}
defer session.Close()
return nil
}); err != nil {
cleanup()
t.Fatalf("Could not connect to cassandra docker container: %s", err)
}
return cleanup, address, port
}
func TestBackend_basic(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
config := logical.TestBackendConfig()
config.StorageView = &logical.InmemStorage{}
b, err := Factory(context.Background(), config)
@@ -86,7 +20,7 @@ func TestBackend_basic(t *testing.T) {
t.Fatal(err)
}
cleanup, hostname, _ := prepareCassandraTestContainer(t)
cleanup, hostname := cassandra.PrepareTestContainer(t, "latest")
defer cleanup()
logicaltest.Test(t, logicaltest.TestCase{
@@ -100,9 +34,6 @@ func TestBackend_basic(t *testing.T) {
}
func TestBackend_roleCrud(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
config := logical.TestBackendConfig()
config.StorageView = &logical.InmemStorage{}
b, err := Factory(context.Background(), config)
@@ -110,7 +41,7 @@ func TestBackend_roleCrud(t *testing.T) {
t.Fatal(err)
}
cleanup, hostname, _ := prepareCassandraTestContainer(t)
cleanup, hostname := cassandra.PrepareTestContainer(t, "latest")
defer cleanup()
logicaltest.Test(t, logicaltest.TestCase{
@@ -129,12 +60,6 @@ func TestBackend_roleCrud(t *testing.T) {
})
}
func testAccPreCheck(t *testing.T) {
if v := os.Getenv("CASSANDRA_HOST"); v == "" {
t.Fatal("CASSANDRA_HOST must be set for acceptance tests")
}
}
func testAccStepConfig(t *testing.T, hostname string) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.UpdateOperation,

View File

@@ -38,12 +38,12 @@ func testBackendConfigAccess(t *testing.T, version string) {
t.Fatal(err)
}
cleanup, connURL, connToken := consul.PrepareTestContainer(t, version)
cleanup, consulConfig := consul.PrepareTestContainer(t, version)
defer cleanup()
connData := map[string]interface{}{
"address": connURL,
"token": connToken,
"address": consulConfig.Address(),
"token": consulConfig.Token,
}
confReq := &logical.Request{
@@ -103,11 +103,12 @@ func testBackendRenewRevoke(t *testing.T, version string) {
t.Fatal(err)
}
cleanup, connURL, connToken := consul.PrepareTestContainer(t, version)
cleanup, consulConfig := consul.PrepareTestContainer(t, version)
defer cleanup()
connData := map[string]interface{}{
"address": connURL,
"token": connToken,
"address": consulConfig.Address(),
"token": consulConfig.Token,
}
req := &logical.Request{
@@ -208,11 +209,12 @@ func testBackendRenewRevoke14(t *testing.T, version string) {
t.Fatal(err)
}
cleanup, connURL, connToken := consul.PrepareTestContainer(t, version)
cleanup, consulConfig := consul.PrepareTestContainer(t, version)
defer cleanup()
connData := map[string]interface{}{
"address": connURL,
"token": connToken,
"address": consulConfig.Address(),
"token": consulConfig.Token,
}
req := &logical.Request{
@@ -317,11 +319,12 @@ func TestBackend_LocalToken(t *testing.T) {
t.Fatal(err)
}
cleanup, connURL, connToken := consul.PrepareTestContainer(t, "")
cleanup, consulConfig := consul.PrepareTestContainer(t, "")
defer cleanup()
connData := map[string]interface{}{
"address": connURL,
"token": connToken,
"address": consulConfig.Address(),
"token": consulConfig.Token,
}
req := &logical.Request{
@@ -459,11 +462,12 @@ func testBackendManagement(t *testing.T, version string) {
t.Fatal(err)
}
cleanup, connURL, connToken := consul.PrepareTestContainer(t, version)
cleanup, consulConfig := consul.PrepareTestContainer(t, version)
defer cleanup()
connData := map[string]interface{}{
"address": connURL,
"token": connToken,
"address": consulConfig.Address(),
"token": consulConfig.Token,
}
logicaltest.Test(t, logicaltest.TestCase{
@@ -503,11 +507,12 @@ func testBackendBasic(t *testing.T, version string) {
t.Fatal(err)
}
cleanup, connURL, connToken := consul.PrepareTestContainer(t, version)
cleanup, consulConfig := consul.PrepareTestContainer(t, version)
defer cleanup()
connData := map[string]interface{}{
"address": connURL,
"token": connToken,
"address": consulConfig.Address(),
"token": consulConfig.Token,
}
logicaltest.Test(t, logicaltest.TestCase{

View File

@@ -3,12 +3,10 @@ package database
import (
"context"
"database/sql"
"fmt"
"log"
"os"
"reflect"
"strings"
"sync"
"testing"
"time"
@@ -16,7 +14,7 @@ import (
"github.com/hashicorp/vault-plugin-database-mongodbatlas"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/helper/testhelpers/docker"
postgreshelper "github.com/hashicorp/vault/helper/testhelpers/postgresql"
vaulthttp "github.com/hashicorp/vault/http"
"github.com/hashicorp/vault/plugins/database/mongodb"
"github.com/hashicorp/vault/plugins/database/postgresql"
@@ -29,64 +27,8 @@ import (
"github.com/hashicorp/vault/vault"
"github.com/lib/pq"
"github.com/mitchellh/mapstructure"
"github.com/ory/dockertest"
)
var (
testImagePull sync.Once
)
func preparePostgresTestContainer(t *testing.T, s logical.Storage, b logical.Backend) (cleanup func(), retURL string) {
t.Helper()
if os.Getenv("PG_URL") != "" {
return func() {}, os.Getenv("PG_URL")
}
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
}
resource, err := pool.Run("postgres", "latest", []string{"POSTGRES_PASSWORD=secret", "POSTGRES_DB=database"})
if err != nil {
t.Fatalf("Could not start local PostgreSQL docker container: %s", err)
}
cleanup = func() {
docker.CleanupResource(t, pool, resource)
}
retURL = fmt.Sprintf("postgres://postgres:secret@localhost:%s/database?sslmode=disable", resource.GetPort("5432/tcp"))
// Exponential backoff-retry
if err = pool.Retry(func() error {
// This will cause a validation to run
resp, err := b.HandleRequest(namespace.RootContext(nil), &logical.Request{
Storage: s,
Operation: logical.UpdateOperation,
Path: "config/postgresql",
Data: map[string]interface{}{
"plugin_name": "postgresql-database-plugin",
"connection_url": retURL,
},
})
if err != nil || (resp != nil && resp.IsError()) {
// It's likely not up and running yet, so return error and try again
return fmt.Errorf("err:%#v resp:%+v", err, resp)
}
if resp == nil {
t.Fatal("expected warning")
}
return nil
}); err != nil {
cleanup()
t.Fatalf("Could not connect to PostgreSQL docker container: %s", err)
}
return
}
func getCluster(t *testing.T) (*vault.TestCluster, logical.SystemView) {
coreConfig := &vault.CoreConfig{
LogicalBackends: map[string]logical.Factory{
@@ -425,7 +367,7 @@ func TestBackend_BadConnectionString(t *testing.T) {
}
defer b.Cleanup(context.Background())
cleanup, _ := preparePostgresTestContainer(t, config.StorageView, b)
cleanup, _ := postgreshelper.PrepareTestContainer(t, "latest")
defer cleanup()
respCheck := func(req *logical.Request) {
@@ -474,7 +416,7 @@ func TestBackend_basic(t *testing.T) {
}
defer b.Cleanup(context.Background())
cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b)
cleanup, connURL := postgreshelper.PrepareTestContainer(t, "latest")
defer cleanup()
// Configure a connection
@@ -681,7 +623,7 @@ func TestBackend_connectionCrud(t *testing.T) {
}
defer b.Cleanup(context.Background())
cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b)
cleanup, connURL := postgreshelper.PrepareTestContainer(t, "latest")
defer cleanup()
// Configure a connection
@@ -859,7 +801,7 @@ func TestBackend_roleCrud(t *testing.T) {
}
defer b.Cleanup(context.Background())
cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b)
cleanup, connURL := postgreshelper.PrepareTestContainer(t, "latest")
defer cleanup()
// Configure a connection
@@ -1107,7 +1049,7 @@ func TestBackend_allowedRoles(t *testing.T) {
}
defer b.Cleanup(context.Background())
cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b)
cleanup, connURL := postgreshelper.PrepareTestContainer(t, "latest")
defer cleanup()
// Configure a connection
@@ -1304,7 +1246,7 @@ func TestBackend_RotateRootCredentials(t *testing.T) {
}
defer b.Cleanup(context.Background())
cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b)
cleanup, connURL := postgreshelper.PrepareTestContainer(t, "latest")
defer cleanup()
connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1)

View File

@@ -8,6 +8,7 @@ import (
"github.com/go-test/deep"
"github.com/hashicorp/vault/helper/namespace"
postgreshelper "github.com/hashicorp/vault/helper/testhelpers/postgresql"
"github.com/hashicorp/vault/sdk/logical"
)
@@ -31,7 +32,7 @@ func TestBackend_StaticRole_Config(t *testing.T) {
}
defer b.Cleanup(context.Background())
cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b)
cleanup, connURL := postgreshelper.PrepareTestContainer(t, "")
defer cleanup()
// create the database user
@@ -201,7 +202,7 @@ func TestBackend_StaticRole_Updates(t *testing.T) {
}
defer b.Cleanup(context.Background())
cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b)
cleanup, connURL := postgreshelper.PrepareTestContainer(t, "")
defer cleanup()
// create the database user
@@ -394,7 +395,7 @@ func TestBackend_StaticRole_Role_name_check(t *testing.T) {
}
defer b.Cleanup(context.Background())
cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, b)
cleanup, connURL := postgreshelper.PrepareTestContainer(t, "")
defer cleanup()
// create the database user

View File

@@ -6,6 +6,7 @@ import (
"testing"
"github.com/hashicorp/vault/helper/namespace"
postgreshelper "github.com/hashicorp/vault/helper/testhelpers/postgresql"
"github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical"
@@ -39,7 +40,7 @@ func TestBackend_RotateRootCredentials_WAL_rollback(t *testing.T) {
}
defer lb.Cleanup(context.Background())
cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, lb)
cleanup, connURL := postgreshelper.PrepareTestContainer(t, "")
defer cleanup()
connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1)
@@ -174,7 +175,7 @@ func TestBackend_RotateRootCredentials_WAL_no_rollback_1(t *testing.T) {
}
defer lb.Cleanup(context.Background())
cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, lb)
cleanup, connURL := postgreshelper.PrepareTestContainer(t, "")
defer cleanup()
connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1)
@@ -282,7 +283,7 @@ func TestBackend_RotateRootCredentials_WAL_no_rollback_2(t *testing.T) {
}
defer lb.Cleanup(context.Background())
cleanup, connURL := preparePostgresTestContainer(t, config.StorageView, lb)
cleanup, connURL := postgreshelper.PrepareTestContainer(t, "")
defer cleanup()
connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1)

View File

@@ -2,59 +2,17 @@ package mysql
import (
"context"
"database/sql"
"fmt"
"log"
"os"
"reflect"
"testing"
"github.com/hashicorp/vault/helper/testhelpers/docker"
logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical"
mysqlhelper "github.com/hashicorp/vault/helper/testhelpers/mysql"
"github.com/hashicorp/vault/sdk/logical"
"github.com/mitchellh/mapstructure"
"github.com/ory/dockertest"
)
func prepareTestContainer(t *testing.T) (func(), string) {
if os.Getenv("MYSQL_URL") != "" {
return func() {}, os.Getenv("MYSQL_URL")
}
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
}
resource, err := pool.Run("mysql", "5.7", []string{"MYSQL_ROOT_PASSWORD=secret"})
if err != nil {
t.Fatalf("Could not start local MySQL docker container: %s", err)
}
cleanup := func() {
docker.CleanupResource(t, pool, resource)
}
retURL := fmt.Sprintf("root:secret@(localhost:%s)/mysql?parseTime=true", resource.GetPort("3306/tcp"))
// exponential backoff-retry
if err = pool.Retry(func() error {
var err error
var db *sql.DB
db, err = sql.Open("mysql", retURL)
if err != nil {
return err
}
defer db.Close()
return db.Ping()
}); err != nil {
cleanup()
t.Fatalf("Could not connect to MySQL docker container: %s", err)
}
return cleanup, retURL
}
func TestBackend_config_connection(t *testing.T) {
var resp *logical.Response
var err error
@@ -104,7 +62,7 @@ func TestBackend_basic(t *testing.T) {
t.Fatal(err)
}
cleanup, connURL := prepareTestContainer(t)
cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret")
defer cleanup()
connData := map[string]interface{}{
@@ -130,7 +88,7 @@ func TestBackend_basicHostRevoke(t *testing.T) {
t.Fatal(err)
}
cleanup, connURL := prepareTestContainer(t)
cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret")
defer cleanup()
connData := map[string]interface{}{
@@ -156,7 +114,7 @@ func TestBackend_roleCrud(t *testing.T) {
t.Fatal(err)
}
cleanup, connURL := prepareTestContainer(t)
cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret")
defer cleanup()
connData := map[string]interface{}{
@@ -187,7 +145,7 @@ func TestBackend_leaseWriteRead(t *testing.T) {
t.Fatal(err)
}
cleanup, connURL := prepareTestContainer(t)
cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret")
defer cleanup()
connData := map[string]interface{}{

View File

@@ -13,52 +13,53 @@ import (
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/hashicorp/vault/sdk/logical"
"github.com/mitchellh/mapstructure"
"github.com/ory/dockertest"
)
func prepareTestContainer(t *testing.T) (cleanup func(), retAddress string, nomadToken string) {
nomadToken = os.Getenv("NOMAD_TOKEN")
type Config struct {
docker.ServiceURL
Token string
}
retAddress = os.Getenv("NOMAD_ADDR")
func (c *Config) APIConfig() *nomadapi.Config {
apiConfig := nomadapi.DefaultConfig()
apiConfig.Address = c.URL().String()
apiConfig.SecretID = c.Token
return apiConfig
}
if retAddress != "" {
return func() {}, retAddress, nomadToken
func prepareTestContainer(t *testing.T) (func(), *Config) {
if retAddress := os.Getenv("NOMAD_ADDR"); retAddress != "" {
s, err := docker.NewServiceURLParse(retAddress)
if err != nil {
t.Fatal(err)
}
return func() {}, &Config{*s, os.Getenv("NOMAD_TOKEN")}
}
pool, err := dockertest.NewPool("")
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "catsby/nomad",
ImageTag: "0.8.4",
ContainerName: "nomad",
Ports: []string{"4646/tcp"},
Cmd: []string{"agent", "-dev"},
Env: []string{`NOMAD_LOCAL_CONFIG=bind_addr = "0.0.0.0" acl { enabled = true }`},
})
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
t.Fatalf("Could not start docker Nomad: %s", err)
}
dockerOptions := &dockertest.RunOptions{
Repository: "catsby/nomad",
Tag: "0.8.4",
Cmd: []string{"agent", "-dev"},
Env: []string{`NOMAD_LOCAL_CONFIG=bind_addr = "0.0.0.0" acl { enabled = true }`},
}
resource, err := pool.RunWithOptions(dockerOptions)
if err != nil {
t.Fatalf("Could not start local Nomad docker container: %s", err)
}
cleanup = func() {
docker.CleanupResource(t, pool, resource)
}
retAddress = fmt.Sprintf("http://localhost:%s/", resource.GetPort("4646/tcp"))
// exponential backoff-retry
if err = pool.Retry(func() error {
var nomadToken string
svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
var err error
nomadapiConfig := nomadapi.DefaultConfig()
nomadapiConfig.Address = retAddress
nomadapiConfig.Address = fmt.Sprintf("http://%s:%d/", host, port)
nomad, err := nomadapi.NewClient(nomadapiConfig)
if err != nil {
return err
return nil, err
}
aclbootstrap, _, err := nomad.ACLTokens().Bootstrap(nil)
if err != nil {
return err
return nil, err
}
nomadToken = aclbootstrap.SecretID
t.Logf("[WARN] Generated Master token: %s", nomadToken)
@@ -85,23 +86,29 @@ func prepareTestContainer(t *testing.T) (cleanup func(), retAddress string, noma
`,
}
nomadAuthConfig := nomadapi.DefaultConfig()
nomadAuthConfig.Address = retAddress
nomadAuthConfig.Address = nomad.Address()
nomadAuthConfig.SecretID = nomadToken
nomadAuth, err := nomadapi.NewClient(nomadAuthConfig)
_, err = nomadAuth.ACLPolicies().Upsert(policy, nil)
if err != nil {
return err
return nil, err
}
_, err = nomadAuth.ACLPolicies().Upsert(anonPolicy, nil)
if err != nil {
return err
return nil, err
}
return nil
}); err != nil {
cleanup()
t.Fatalf("Could not connect to docker: %s", err)
u, _ := docker.NewServiceURLParse(nomadapiConfig.Address)
return &Config{
ServiceURL: *u,
Token: nomadToken,
}, nil
})
if err != nil {
t.Fatalf("Could not start docker Nomad: %s", err)
}
return cleanup, retAddress, nomadToken
return svc.Cleanup, svc.Config.(*Config)
}
func TestBackend_config_access(t *testing.T) {
@@ -112,12 +119,12 @@ func TestBackend_config_access(t *testing.T) {
t.Fatal(err)
}
cleanup, connURL, connToken := prepareTestContainer(t)
cleanup, svccfg := prepareTestContainer(t)
defer cleanup()
connData := map[string]interface{}{
"address": connURL,
"token": connToken,
"address": svccfg.URL().String(),
"token": svccfg.Token,
}
confReq := &logical.Request{
@@ -158,11 +165,12 @@ func TestBackend_renew_revoke(t *testing.T) {
t.Fatal(err)
}
cleanup, connURL, connToken := prepareTestContainer(t)
cleanup, svccfg := prepareTestContainer(t)
defer cleanup()
connData := map[string]interface{}{
"address": connURL,
"token": connToken,
"address": svccfg.URL().String(),
"token": svccfg.Token,
}
req := &logical.Request{
@@ -267,7 +275,7 @@ func TestBackend_CredsCreateEnvVar(t *testing.T) {
t.Fatal(err)
}
cleanup, connURL, connToken := prepareTestContainer(t)
cleanup, svccfg := prepareTestContainer(t)
defer cleanup()
req := logical.TestRequest(t, logical.UpdateOperation, "role/test")
@@ -280,9 +288,9 @@ func TestBackend_CredsCreateEnvVar(t *testing.T) {
t.Fatal(err)
}
os.Setenv("NOMAD_TOKEN", connToken)
os.Setenv("NOMAD_TOKEN", svccfg.Token)
defer os.Unsetenv("NOMAD_TOKEN")
os.Setenv("NOMAD_ADDR", connURL)
os.Setenv("NOMAD_ADDR", svccfg.URL().String())
defer os.Unsetenv("NOMAD_ADDR")
req.Operation = logical.ReadOperation
@@ -307,7 +315,7 @@ func TestBackend_max_token_name_length(t *testing.T) {
t.Fatal(err)
}
cleanup, connURL, connToken := prepareTestContainer(t)
cleanup, svccfg := prepareTestContainer(t)
defer cleanup()
testCases := []struct {
@@ -337,12 +345,12 @@ func TestBackend_max_token_name_length(t *testing.T) {
t.Run(tc.title, func(t *testing.T) {
// setup config/access
connData := map[string]interface{}{
"address": connURL,
"token": connToken,
"address": svccfg.URL().String(),
"token": svccfg.Token,
"max_token_name_length": tc.tokenLength,
}
expected := map[string]interface{}{
"address": connURL,
"address": svccfg.URL().String(),
"max_token_name_length": tc.tokenLength,
}

View File

@@ -2797,8 +2797,8 @@ func TestBackend_AllowedDomainsTemplate(t *testing.T) {
// Write role PKI.
_, err = client.Logical().Write("pki/roles/test", map[string]interface{}{
"allowed_domains": []string{"foobar.com", "zipzap.com", "{{identity.entity.aliases." + userpassAccessor + ".name}}",
"foo.{{identity.entity.aliases." + userpassAccessor + ".name}}.example.com"},
"allowed_domains": []string{"foobar.com", "zipzap.com", "{{identity.entity.aliases." + userpassAccessor + ".name}}",
"foo.{{identity.entity.aliases." + userpassAccessor + ".name}}.example.com"},
"allowed_domains_template": true,
"allow_bare_domains": true,
})

View File

@@ -5,17 +5,15 @@ import (
"fmt"
"log"
"os"
"strconv"
"testing"
"github.com/hashicorp/vault/helper/testhelpers/docker"
logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical"
"github.com/hashicorp/vault/sdk/helper/base62"
"github.com/hashicorp/vault/sdk/helper/jsonutil"
"github.com/hashicorp/vault/sdk/logical"
logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical"
rabbithole "github.com/michaelklishin/rabbit-hole"
"github.com/mitchellh/mapstructure"
"github.com/ory/dockertest"
)
const (
@@ -32,60 +30,45 @@ const (
roleName = "web"
)
func prepareRabbitMQTestContainer(t *testing.T) (func(), string, int) {
func prepareRabbitMQTestContainer(t *testing.T) (func(), string) {
if os.Getenv(envRabbitMQConnectionURI) != "" {
return func() {}, os.Getenv(envRabbitMQConnectionURI), 0
return func() {}, os.Getenv(envRabbitMQConnectionURI)
}
pool, err := dockertest.NewPool("")
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "rabbitmq",
ImageTag: "3-management",
ContainerName: "rabbitmq",
Ports: []string{"15672/tcp"},
})
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
t.Fatalf("could not start docker rabbitmq: %s", err)
}
runOpts := &dockertest.RunOptions{
Repository: "rabbitmq",
Tag: "3-management",
}
resource, err := pool.RunWithOptions(runOpts)
if err != nil {
t.Fatalf("Could not start local rabbitmq docker container: %s", err)
}
cleanup := func() {
docker.CleanupResource(t, pool, resource)
}
port, _ := strconv.Atoi(resource.GetPort("15672/tcp"))
address := fmt.Sprintf("http://127.0.0.1:%d", port)
// exponential backoff-retry
if err = pool.Retry(func() error {
rmqc, err := rabbithole.NewClient(address, "guest", "guest")
svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
connURL := fmt.Sprintf("http://%s:%d", host, port)
rmqc, err := rabbithole.NewClient(connURL, "guest", "guest")
if err != nil {
return err
return nil, err
}
_, err = rmqc.Overview()
if err != nil {
return err
return nil, err
}
return nil
}); err != nil {
cleanup()
t.Fatalf("Could not connect to rabbitmq docker container: %s", err)
return docker.NewServiceURLParse(connURL)
})
if err != nil {
t.Fatalf("could not start docker rabbitmq: %s", err)
}
return cleanup, address, port
return svc.Cleanup, svc.Config.URL().String()
}
func TestBackend_basic(t *testing.T) {
if os.Getenv(logicaltest.TestEnvVar) == "" {
t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", logicaltest.TestEnvVar))
return
}
b, _ := Factory(context.Background(), logical.TestBackendConfig())
cleanup, uri, _ := prepareRabbitMQTestContainer(t)
cleanup, uri := prepareRabbitMQTestContainer(t)
defer cleanup()
logicaltest.Test(t, logicaltest.TestCase{
@@ -101,13 +84,9 @@ func TestBackend_basic(t *testing.T) {
}
func TestBackend_returnsErrs(t *testing.T) {
if os.Getenv(logicaltest.TestEnvVar) == "" {
t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", logicaltest.TestEnvVar))
return
}
b, _ := Factory(context.Background(), logical.TestBackendConfig())
cleanup, uri, _ := prepareRabbitMQTestContainer(t)
cleanup, uri := prepareRabbitMQTestContainer(t)
defer cleanup()
logicaltest.Test(t, logicaltest.TestCase{
@@ -134,13 +113,9 @@ func TestBackend_returnsErrs(t *testing.T) {
}
func TestBackend_roleCrud(t *testing.T) {
if os.Getenv(logicaltest.TestEnvVar) == "" {
t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", logicaltest.TestEnvVar))
return
}
b, _ := Factory(context.Background(), logical.TestBackendConfig())
cleanup, uri, _ := prepareRabbitMQTestContainer(t)
cleanup, uri := prepareRabbitMQTestContainer(t)
defer cleanup()
logicaltest.Test(t, logicaltest.TestCase{
@@ -169,7 +144,7 @@ func TestBackend_roleWithPasswordPolicy(t *testing.T) {
backendConfig.System.(*logical.StaticSystemView).SetPasswordPolicy("testpolicy", passGen)
b, _ := Factory(context.Background(), backendConfig)
cleanup, uri, _ := prepareRabbitMQTestContainer(t)
cleanup, uri := prepareRabbitMQTestContainer(t)
defer cleanup()
logicaltest.Test(t, logicaltest.TestCase{

View File

@@ -4,6 +4,8 @@ import (
"bytes"
"context"
"fmt"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/sdk/logical"
"net"
"reflect"
"strconv"
@@ -17,13 +19,10 @@ import (
"errors"
"strings"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/helper/testhelpers/docker"
logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical"
"github.com/hashicorp/vault/sdk/logical"
"github.com/hashicorp/vault/vault"
"github.com/mitchellh/mapstructure"
"github.com/ory/dockertest"
)
const (
@@ -126,44 +125,39 @@ SjOQL/GkH1nkRcDS9++aAAAAAmNhAQID
)
func prepareTestContainer(t *testing.T, tag, caPublicKeyPEM string) (func(), string) {
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
}
signer, err := ssh.ParsePrivateKey([]byte(testSharedPrivateKey))
if err != nil {
t.Fatal(err)
}
if tag == "" {
tag = dockerImageTagSupportsNoRSA1
}
resource, err := pool.RunWithOptions(&dockertest.RunOptions{
Repository: "linuxserver/openssh-server",
Tag: tag,
runner, err := docker.NewServiceRunner(docker.RunOptions{
ContainerName: "openssh",
ImageRepo: "linuxserver/openssh-server",
ImageTag: tag,
Env: []string{
"DOCKER_MODS=linuxserver/mods:openssh-server-openssh-client",
"PUBLIC_KEY=" + testPublicKeyInstall,
"SUDO_ACCESS=true",
"USER_NAME=vaultssh",
},
ExposedPorts: []string{"2222/tcp"},
Ports: []string{"2222/tcp"},
})
if err != nil {
t.Fatalf("Could not start local ssh docker container: %s", err)
}
cleanup := func() {
docker.CleanupResource(t, pool, resource)
}
svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
ipaddr, err := net.ResolveIPAddr("ip", host)
if err != nil {
return nil, err
}
sshAddress := fmt.Sprintf("%s:%d", ipaddr.String(), port)
sshAddress := fmt.Sprintf("127.0.0.1:%s", resource.GetPort("2222/tcp"))
signer, err := ssh.ParsePrivateKey([]byte(testSharedPrivateKey))
if err != nil {
return nil, err
}
// exponential backoff-retry
if err = pool.Retry(func() error {
// Install util-linux for non-busybox flock that supports timeout option
return testSSH(t, "vaultssh", sshAddress, ssh.PublicKeys(signer), fmt.Sprintf(`
err = testSSH("vaultssh", sshAddress, ssh.PublicKeys(signer), fmt.Sprintf(`
set -e;
sudo ln -s /config /home/vaultssh
sudo apk add util-linux;
@@ -172,15 +166,19 @@ func prepareTestContainer(t *testing.T, tag, caPublicKeyPEM string) (func(), str
kill -HUP $(cat /config/sshd.pid)
echo "%s" | sudo tee /config/ssh_host_keys/trusted-user-ca-keys.pem
`, caPublicKeyPEM))
}); err != nil {
cleanup()
t.Fatalf("Could not connect to SSH docker container: %s", err)
}
if err != nil {
return nil, err
}
return cleanup, sshAddress
return docker.NewServiceHostPort(ipaddr.String(), port), nil
})
if err != nil {
t.Fatalf("Could not start docker ssh server: %s", err)
}
return svc.Cleanup, svc.Config.Address()
}
func testSSH(t *testing.T, user, host string, auth ssh.AuthMethod, command string) error {
func testSSH(user, host string, auth ssh.AuthMethod, command string) error {
client, err := ssh.Dial("tcp", host, &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{auth},
@@ -199,7 +197,7 @@ func testSSH(t *testing.T, user, host string, auth ssh.AuthMethod, command strin
defer session.Close()
err = session.Run(command)
if err != nil {
t.Logf("command %v failed, error: %v, stderr: %v", command, err, stderr.String())
return fmt.Errorf("command %v failed, error: %v, stderr: %v", command, err, stderr.String())
}
return err
}
@@ -431,7 +429,7 @@ func TestSSHBackend_DynamicKeyCreate(t *testing.T) {
"key": testKeyName,
"admin_user": testAdminUser,
"default_user": testAdminUser,
"cidr_list": testCIDRList,
"cidr_list": host + "/32",
"port": port,
}
data := map[string]interface{}{
@@ -537,7 +535,7 @@ func TestSSHBackend_OTPCreate(t *testing.T) {
testOTPRoleData := map[string]interface{}{
"key_type": testOTPKeyType,
"default_user": testUserName,
"cidr_list": testCIDRList,
"cidr_list": host + "/32",
"port": port,
}
data := map[string]interface{}{
@@ -854,7 +852,7 @@ cKumubUxOfFdy1ZvAAAAEm5jY0BtYnAudWJudC5sb2NhbA==
return err
}
err = testSSH(t, testUserName, sshAddress, ssh.PublicKeys(certSigner), "date")
err = testSSH(testUserName, sshAddress, ssh.PublicKeys(certSigner), "date")
if expectError && err == nil {
return fmt.Errorf("expected error but got none")
}
@@ -978,7 +976,7 @@ cKumubUxOfFdy1ZvAAAAEm5jY0BtYnAudWJudC5sb2NhbA==
return err
}
err = testSSH(t, testUserName, sshAddress, ssh.PublicKeys(certSigner), "date")
err = testSSH(testUserName, sshAddress, ssh.PublicKeys(certSigner), "date")
if err != nil {
return err
}
@@ -1645,7 +1643,7 @@ func testCredsWrite(t *testing.T, roleName string, data map[string]interface{},
if err != nil {
return fmt.Errorf("generated key is invalid")
}
if err := testSSH(t, data["username"].(string), address, ssh.PublicKeys(privKey), "date"); err != nil {
if err := testSSH(data["username"].(string), address, ssh.PublicKeys(privKey), "date"); err != nil {
return fmt.Errorf("unable to SSH with new key (%s): %w", d.Key, err)
}
} else {

View File

@@ -23,6 +23,7 @@ import (
)
func TestAppRoleEndToEnd(t *testing.T) {
t.Parallel()
testCases := []struct {
removeSecretIDFile bool
@@ -54,6 +55,7 @@ func TestAppRoleEndToEnd(t *testing.T) {
secretFileAction = "remove"
}
t.Run(fmt.Sprintf("%s_secret_id_file bindSecretID=%v secretIDLess=%v expectToken=%v", secretFileAction, tc.bindSecretID, tc.secretIDLess, tc.expectToken), func(t *testing.T) {
t.Parallel()
testAppRoleEndToEnd(t, tc.removeSecretIDFile, tc.bindSecretID, tc.secretIDLess, tc.expectToken)
})
}

View File

@@ -138,11 +138,11 @@ func TestLoadConfigFile(t *testing.T) {
},
},
{
Type: "file",
WrapTTL: 5 * time.Minute,
DHType: "curve25519",
DHPath: "/tmp/file-foo-dhpath2",
AAD: "aad",
Type: "file",
WrapTTL: 5 * time.Minute,
DHType: "curve25519",
DHPath: "/tmp/file-foo-dhpath2",
AAD: "aad",
DeriveKey: true,
Config: map[string]interface{}{
"path": "/tmp/file-bar",

View File

@@ -154,10 +154,10 @@ func testJWTEndToEnd(t *testing.T, ahWrapping bool) {
}()
config := &sink.SinkConfig{
Logger: logger.Named("sink.file"),
AAD: "foobar",
DHType: "curve25519",
DHPath: dhpath,
Logger: logger.Named("sink.file"),
AAD: "foobar",
DHType: "curve25519",
DHPath: dhpath,
DeriveKey: true,
Config: map[string]interface{}{
"path": out,

View File

@@ -195,6 +195,11 @@ func TestAuditEnableCommand_Run(t *testing.T) {
t.Log("skipping syslog test on WSL")
continue
}
if os.Getenv("CIRCLECI") == "true" {
// TODO install syslog in docker image we run our tests in
t.Log("skipping syslog test on CircleCI")
continue
}
}
code := cmd.Run(args)
if exp := 0; code != exp {

View File

@@ -3,27 +3,27 @@ package server
import (
"context"
"fmt"
"net/url"
"path"
"reflect"
"strings"
"testing"
"time"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/hashicorp/vault/internalshared/configutil"
"github.com/ory/dockertest"
)
func TestTransitWrapper_Lifecycle(t *testing.T) {
cleanup, retAddress, token, mountPath, keyName, _ := prepareTestContainer(t)
cleanup, config := prepareTestContainer(t)
defer cleanup()
wrapperConfig := map[string]string{
"address": retAddress,
"token": token,
"mount_path": mountPath,
"key_name": keyName,
"address": config.URL().String(),
"token": config.token,
"mount_path": config.mountPath,
"key_name": config.keyName,
}
kms, _, err := configutil.GetTransitKMSFunc(nil, &configutil.KMS{Config: wrapperConfig})
@@ -49,21 +49,14 @@ func TestTransitWrapper_Lifecycle(t *testing.T) {
}
func TestTransitSeal_TokenRenewal(t *testing.T) {
cleanup, retAddress, token, mountPath, keyName, tlsConfig := prepareTestContainer(t)
cleanup, config := prepareTestContainer(t)
defer cleanup()
clientConfig := &api.Config{
Address: retAddress,
}
if err := clientConfig.ConfigureTLS(tlsConfig); err != nil {
t.Fatalf("err: %s", err)
}
remoteClient, err := api.NewClient(clientConfig)
remoteClient, err := api.NewClient(config.apiConfig())
if err != nil {
t.Fatalf("err: %s", err)
}
remoteClient.SetToken(token)
remoteClient.SetToken(config.token)
req := &api.TokenCreateRequest{
Period: "5s",
@@ -74,10 +67,10 @@ func TestTransitSeal_TokenRenewal(t *testing.T) {
}
wrapperConfig := map[string]string{
"address": retAddress,
"address": config.URL().String(),
"token": rsp.Auth.ClientToken,
"mount_path": mountPath,
"key_name": keyName,
"mount_path": config.mountPath,
"key_name": config.keyName,
}
kms, _, err := configutil.GetTransitKMSFunc(nil, &configutil.KMS{Config: wrapperConfig})
if err != nil {
@@ -103,8 +96,28 @@ func TestTransitSeal_TokenRenewal(t *testing.T) {
}
}
func prepareTestContainer(t *testing.T) (cleanup func(), retAddress, token, mountPath, keyName string, tlsConfig *api.TLSConfig) {
testToken, err := uuid.GenerateUUID()
type DockerVaultConfig struct {
docker.ServiceURL
token string
mountPath string
keyName string
tlsConfig *api.TLSConfig
}
func (c *DockerVaultConfig) apiConfig() *api.Config {
vaultConfig := api.DefaultConfig()
vaultConfig.Address = c.URL().String()
if err := vaultConfig.ConfigureTLS(c.tlsConfig); err != nil {
panic("unable to configure TLS")
}
return vaultConfig
}
var _ docker.ServiceConfig = &DockerVaultConfig{}
func prepareTestContainer(t *testing.T) (func(), *DockerVaultConfig) {
rootToken, err := uuid.GenerateUUID()
if err != nil {
t.Fatalf("err: %s", err)
}
@@ -117,72 +130,49 @@ func prepareTestContainer(t *testing.T) (cleanup func(), retAddress, token, moun
t.Fatalf("err: %s", err)
}
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
}
dockerOptions := &dockertest.RunOptions{
Repository: "vault",
Tag: "latest",
Cmd: []string{"server", "-log-level=trace", "-dev", fmt.Sprintf("-dev-root-token-id=%s", testToken),
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "vault",
ImageTag: "latest",
Cmd: []string{"server", "-log-level=trace", "-dev", fmt.Sprintf("-dev-root-token-id=%s", rootToken),
"-dev-listen-address=0.0.0.0:8200"},
}
resource, err := pool.RunWithOptions(dockerOptions)
Ports: []string{"8200/tcp"},
})
if err != nil {
t.Fatalf("Could not start local Vault docker container: %s", err)
t.Fatalf("could not start docker vault: %s", err)
}
cleanup = func() {
var err error
for i := 0; i < 10; i++ {
err = pool.Purge(resource)
if err == nil {
return
}
time.Sleep(1 * time.Second)
svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
c := &DockerVaultConfig{
ServiceURL: *docker.NewServiceURL(url.URL{Scheme: "http", Host: fmt.Sprintf("%s:%d", host, port)}),
tlsConfig: &api.TLSConfig{
Insecure: true,
},
token: rootToken,
mountPath: testMountPath,
keyName: testKeyName,
}
if strings.Contains(err.Error(), "No such container") {
return
}
t.Fatalf("Failed to cleanup local container: %s", err)
}
retAddress = fmt.Sprintf("http://127.0.0.1:%s", resource.GetPort("8200/tcp"))
tlsConfig = &api.TLSConfig{
Insecure: true,
}
// exponential backoff-retry
if err = pool.Retry(func() error {
vaultConfig := api.DefaultConfig()
vaultConfig.Address = retAddress
if err := vaultConfig.ConfigureTLS(tlsConfig); err != nil {
return err
}
vault, err := api.NewClient(vaultConfig)
vault, err := api.NewClient(c.apiConfig())
if err != nil {
return err
return nil, err
}
vault.SetToken(testToken)
vault.SetToken(rootToken)
// Set up transit
if err := vault.Sys().Mount(testMountPath, &api.MountInput{
Type: "transit",
}); err != nil {
return err
return nil, err
}
// Create default aesgcm key
if _, err := vault.Logical().Write(path.Join(testMountPath, "keys", testKeyName), map[string]interface{}{}); err != nil {
return err
return nil, err
}
return nil
}); err != nil {
cleanup()
t.Fatalf("Could not connect to vault: %s", err)
return c, nil
})
if err != nil {
t.Fatalf("could not start docker vault: %s", err)
}
return cleanup, retAddress, testToken, testMountPath, testKeyName, tlsConfig
return svc.Cleanup, svc.Config.(*DockerVaultConfig)
}

6
go.mod
View File

@@ -26,12 +26,17 @@ require (
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf
github.com/aws/aws-sdk-go v1.30.27
github.com/bitly/go-hostpool v0.1.0 // indirect
github.com/cenkalti/backoff/v3 v3.0.0
github.com/chrismalek/oktasdk-go v0.0.0-20181212195951-3430665dfaa0
github.com/client9/misspell v0.3.4
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c
github.com/containerd/containerd v1.3.4 // indirect
github.com/coreos/go-semver v0.2.0
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc
github.com/dnaeon/go-vcr v1.0.1 // indirect
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible
github.com/docker/go-connections v0.4.0
github.com/dsnet/compress v0.0.1 // indirect
github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74
github.com/elazarl/go-bindata-assetfs v1.0.1-0.20200509193318-234c15e7648f
@@ -120,6 +125,7 @@ require (
github.com/okta/okta-sdk-golang/v2 v2.0.0
github.com/oracle/oci-go-sdk v12.5.0+incompatible
github.com/ory/dockertest v3.3.5+incompatible
github.com/ory/dockertest/v3 v3.6.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
github.com/pkg/errors v0.9.1

132
go.sum
View File

@@ -17,15 +17,12 @@ cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbf
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.6.0 h1:ajp/DjpiCHO71SyIhwb83YsUGAyWuzVvMko+9xCsJLw=
cloud.google.com/go/bigquery v1.6.0/go.mod h1:hyFDG0qSGdHNz8Q6nDN8rYIkld0q/+5uBZaelxiDLfE=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
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=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/spanner v1.5.1 h1:dWyj10TLlaxH2No6+tXsSCaq9oWgrRbXy1N3x/bhMGU=
cloud.google.com/go/spanner v1.5.1/go.mod h1:e1+8M6PF3ntV9Xr57X2Gf+UhylXXYF6gI4WRZ1kfu2A=
@@ -64,7 +61,6 @@ github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSW
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8=
github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
@@ -86,7 +82,6 @@ github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E=
github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Microsoft/go-winio v0.4.13 h1:Hmi80lzZuI/CaYmlJp/b+FjZdRZhKu9c2mDVqKlLWVs=
github.com/Microsoft/go-winio v0.4.13/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
@@ -106,7 +101,6 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14=
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@@ -138,7 +132,6 @@ github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf h1:eg0MeVzs
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.30.27 h1:9gPjZWVDSoQrBO2AvqrWObS6KAZByfEJxQoCYo4ZfK0=
github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
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=
@@ -147,9 +140,7 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
github.com/bitly/go-hostpool v0.1.0 h1:XKmsF6k5el6xHG3WPJ8U0Ku/ye7njX7W81Ng7O2ioR0=
github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
@@ -158,6 +149,8 @@ github.com/briankassouf/jose v0.9.2-0.20180619214549-d2569464773f h1:ZMEzE7R0WNq
github.com/briankassouf/jose v0.9.2-0.20180619214549-d2569464773f/go.mod h1:HQhVmdUf7dBNwIIdBTivnCDxcf6IZY3/zrb+uKSJz6Y=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c=
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/centrify/cloud-golang-sdk v0.0.0-20190214225812-119110094d0f h1:gJzxrodnNd/CtPXjO3WYiakyNzHg3rtAi7rO74ejHYU=
github.com/centrify/cloud-golang-sdk v0.0.0-20190214225812-119110094d0f/go.mod h1:C0rtzmGXgN78pYR0tGJFhtHgkbAs0lIbHwkB81VxDQE=
@@ -179,22 +172,18 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 h1:rdRS5BT13Iae9ssvcslol66gfOOXjaLYwqerEn/cl9s=
github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381/go.mod h1:e5+USP2j8Le2M0Jo3qKPFnNhuo1wueU4nWHCXBOfQ14=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c h1:2zRrJWIt/f9c9HhNHAgrRgq0San5gRRUJTBXLkchal0=
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.4 h1:3o0smo5SKY7H6AJCmJhsnCjR2/V2T8VmiHt7seN2/kI=
github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20200709052629-daa8e1ccc0bc h1:lDK/G7OlwUnJW3O6nv/8M89bMupV6FuLK6FXmC3ueWc=
github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20200709052629-daa8e1ccc0bc/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe h1:PEmIrUvwG9Yyv+0WKZqjXfSFDeZjs/q15g0m08BYS9k=
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
@@ -211,12 +200,9 @@ github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHo
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28=
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/couchbase/gocb/v2 v2.1.4 h1:HRuVhqZpVNIck3FwzTxWh5TnmGXeTmSfjhxkjeradLg=
github.com/couchbase/gocb/v2 v2.1.4/go.mod h1:lESKM6wCEajrFVSZUewYuRzNtuNtnRey5wOfcZZsH90=
@@ -235,12 +221,12 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4=
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
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.20200319182547-c7ad2b866182 h1:Caj/qGJ9KyulC1WSksyPgp7r8+DKgTGfU39lmb2C5MQ=
github.com/docker/docker v1.4.2-0.20200319182547-c7ad2b866182/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible h1:G2hY8RD7jB9QaSmcb8mYEIg8QbEvVAB7se8+lXHZHfg=
github.com/docker/docker v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
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-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
@@ -253,7 +239,6 @@ github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdf
github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 h1:2MIhn2R6oXQbgW5yHfS+d6YqyMfXiu2L55rFZC4UD/M=
github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
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=
@@ -272,11 +257,8 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/frankban/quicktest v1.4.0/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ=
github.com/frankban/quicktest v1.4.1 h1:Wv2VwvNn73pAdFIVUQRXYDFp31lXKbqblIXo/Q5GPSg=
github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ=
github.com/frankban/quicktest v1.10.0 h1:Gfh+GAJZOAoKZsIZeZbdn2JF10kN1XHNvjsvQK8gVkE=
github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU=
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
@@ -301,7 +283,6 @@ github.com/go-ldap/ldap/v3 v3.1.10 h1:7WsKqasmPThNvdl0Q5GPpbTDD/ZD98CfuawrMIuh7q
github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
@@ -311,7 +292,6 @@ github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw=
github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
@@ -323,7 +303,6 @@ github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
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 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
@@ -332,7 +311,6 @@ github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZ
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -340,12 +318,10 @@ github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18h
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
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=
@@ -358,7 +334,6 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
@@ -367,7 +342,6 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
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=
@@ -385,7 +359,6 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@@ -393,7 +366,6 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -402,34 +374,24 @@ github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 h1:f0n1xnMSmBLzVfsMMvriDyA75NB/oBgILX2GcHXIQzY=
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYbQ=
github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI=
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.6.2/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
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=
@@ -438,7 +400,6 @@ github.com/hashicorp/consul-template v0.25.1/go.mod h1:/vUsrJvDuuQHcxEw0zik+YXTS
github.com/hashicorp/consul/api v1.4.0 h1:jfESivXnO5uLdH650JU/6AnjRoHrLhULq0FnC3Kp9EY=
github.com/hashicorp/consul/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/consul/sdk v0.4.0 h1:zBtCfKJZcJDBvSCkQJch4ulp59m1rATFLKwNo/LYY30=
github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM=
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=
@@ -447,7 +408,6 @@ github.com/hashicorp/go-bindata v3.0.8-0.20180209072458-bf7910af8997+incompatibl
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-gatedio v0.5.0 h1:Jm1X5yP4yCqqWj5L1TgW7iZwCVPGtVc+mro5r/XX7Tg=
github.com/hashicorp/go-gatedio v0.5.0/go.mod h1:Lr3t8L6IyxD3DAeaUxGcgl2JnRUpWMCsmBl4Omu/2t4=
github.com/hashicorp/go-gcp-common v0.5.0/go.mod h1:IDGUI2N/OS3PiU4qZcXJeWKPI6O/9Y8hOrbSiMcqyYw=
github.com/hashicorp/go-gcp-common v0.6.0 h1:m1X+DK003bj4WEjqOnv+Csepb3zpfN/bidboUeUSj68=
@@ -457,8 +417,6 @@ github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrj
github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.13.0 h1:Do32YnDMnq7v7FU50AgH+1ExKCOkl9HBxvSI1JWr+rA=
github.com/hashicorp/go-hclog v0.13.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU=
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
@@ -474,7 +432,6 @@ github.com/hashicorp/go-memdb v1.0.2/go.mod h1:I6dKdmYhZqU0RJSheVEWgTNWdVQH5QvTg
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI=
github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
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=
@@ -483,7 +440,6 @@ github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn
github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a h1:FmnBDwGwlTgugDGbVxwV8UavqSMACbGrUpfc98yFLR4=
github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a/go.mod h1:xbXnmKqX9/+RhPkJ4zrEx4738HacP72aaUPlT2RZ4sU=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-retryablehttp v0.6.2 h1:bHM2aVXwBtBJWxHtkSrWuI4umABCUczs52eiUS9nSiw=
github.com/hashicorp/go-retryablehttp v0.6.2/go.mod h1:gEx6HMUGxYYhJScX7W1Il64m6cc2C1mDaW3NQ9sY1FY=
github.com/hashicorp/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP3V9oNE4hmsM=
github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
@@ -502,7 +458,6 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
@@ -517,12 +472,10 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI
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/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/memberlist v0.1.4 h1:gkyML/r71w3FL8gUi74Vk76avkj/9lYAY9lvg0OcoGs=
github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/nomad/api v0.0.0-20191220223628-edc62acd919d h1:BXqsASWhyiAiEVm6FcltF0dg8XvoookQwmpHn8lstu8=
github.com/hashicorp/nomad/api v0.0.0-20191220223628-edc62acd919d/go.mod h1:WKCL+tLVhN1D+APwH3JiTRZoxcdwRk86bWu1LVCUPaE=
github.com/hashicorp/raft v1.0.1/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI=
github.com/hashicorp/raft v1.1.2-0.20191002163536-9c6bd3e3eb17 h1:p+2EISNdFCnD9R+B4xCiqSn429MCFtvM41aHJDJ6qW4=
github.com/hashicorp/raft v1.1.2-0.20191002163536-9c6bd3e3eb17/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8=
github.com/hashicorp/raft v1.1.3-0.20200914140732-b7cd2b346b06 h1:faxx3CU4pvdKtCZXsP62A5X0iV37eqLHgFObVkOplHQ=
github.com/hashicorp/raft v1.1.3-0.20200914140732-b7cd2b346b06/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8=
@@ -578,7 +531,6 @@ github.com/hashicorp/vault-plugin-secrets-openldap v0.1.5/go.mod h1:NM+5N+URHHg8
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huaweicloud/golangsdk v0.0.0-20200304081349-45ec0797f2a4/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@@ -586,7 +538,6 @@ github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4 h1:3K3KcD4S6/Y2hevi70EzUTNKOS3cryQyhUnkjE6Tz0w=
github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
github.com/jackc/pgx v3.3.0+incompatible h1:Wa90/+qsITBAPkAZjiByeIGHFcj3Ztu+VzrrIpHjL90=
github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
@@ -613,7 +564,6 @@ github.com/jefferai/jsonx v1.0.0/go.mod h1:OGmqmi2tTeI/PS+qQfBDToLHHJIy/RMp24fPo
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f h1:ENpDacvnr8faw5ugQmEF1QYk+f/Y9lXFvuYmRxykago=
github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f/go.mod h1:KDSfL7qe5ZfQqvlDMkVjCztbmcpp/c8M77vhQP8ZPvk=
@@ -627,10 +577,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM=
github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
@@ -641,28 +589,25 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
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/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/YNA/UnBk=
github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11 h1:YFh+sjyJTMQSYjKwM4dFKhJPJC/wfo98tPUc17HdoYw=
github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@@ -686,7 +631,6 @@ github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1
github.com/michaelklishin/rabbit-hole v0.0.0-20191008194146-93d9988f0cd5 h1:uA3b4GgZMZxAJsTkd+CVQ85b7KBlD7HLpd/FfTNlGN0=
github.com/michaelklishin/rabbit-hole v0.0.0-20191008194146-93d9988f0cd5/go.mod h1:+pmbihVqjC3GPdfWv1V2TnRSuVvwrWLKfEP/MZVB/Wc=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.15 h1:CSSIDtllwGLMoA6zjdKnaE6Tx6eVUxQ29LUgGetiDCI=
github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@@ -706,9 +650,7 @@ github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1D
github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg=
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
@@ -725,7 +667,6 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mongodb/go-client-mongodb-atlas v0.1.2 h1:qmUme1TlQBPZupmXMnpD8DxnfGXLVGs3w+0Z17HBiSA=
github.com/mongodb/go-client-mongodb-atlas v0.1.2/go.mod h1:LS8O0YLkA+sbtOb3fZLF10yY3tJM+1xATXMJ3oU35LU=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mwielbut/pointy v1.1.0 h1:U5/YEfoIkaGCHv0St3CgjduqXID4FNRoyZgLM1kY9vg=
github.com/mwielbut/pointy v1.1.0/go.mod h1:MvvO+uMFj9T5DMda33HlvogsFBX7pWWKAkFIn4teYwY=
@@ -748,26 +689,22 @@ github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:v
github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
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 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc9 h1:/k06BMULKF5hidyoZymkoDCzdJzltZpz/UU4LguQVtc=
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
@@ -777,10 +714,9 @@ github.com/oracle/oci-go-sdk v12.5.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35uk
github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2 h1:CXwSGu/LYmbjEab5aMCs5usQRVBGThelUKBNnoSOuso=
github.com/ory/dockertest/v3 v3.6.0/go.mod h1:4ZOpj8qBUmh8fcBSVzkH2bws2s91JdGvHUqan4GHEuQ=
github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/patrickmn/go-cache v0.0.0-20180815053127-5633e0862627/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
@@ -790,7 +726,6 @@ github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4 v2.2.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4 v2.2.6+incompatible h1:6aCX4/YZ9v8q69hTyiR7dNLnTA3fgtKHVVW5BCd5Znw=
github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI=
github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
@@ -857,28 +792,22 @@ github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06qF79/FKAJpBvFx3P8Ww4UTIMAe+lpNXDHziac=
github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sethvargo/go-limiter v0.3.0 h1:yRMc+Qs2yqw6YJp6UxrO2iUs6DOSq4zcnljbB7/rMns=
github.com/sethvargo/go-limiter v0.3.0/go.mod h1:C0kbSFbiriE5k2FFOe18M1YZbAR2Fiwf72uGu0CXCcU=
github.com/shirou/gopsutil v2.20.6-0.20200630091542-01afd763e6c0+incompatible h1:IYOqH6sML3rQGNVEQ5foLtpDt4TeW8PIUBuI9f8itkI=
github.com/shirou/gopsutil v2.20.6-0.20200630091542-01afd763e6c0+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/smartystreets/assertions v0.0.0-20180725160413-e900ae048470/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
@@ -890,18 +819,14 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
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.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/square/go-jose v2.4.1+incompatible h1:KFYc54wTtgnd3x4B/Y7Zr1s/QaEx2BNzRsB3Hae5LHo=
github.com/square/go-jose v2.4.1+incompatible/go.mod h1:7MxpAF/1WTVUu8Am+T5kNy+t0902CaLWM4Z745MkOa8=
github.com/square/go-jose/v3 v3.0.0-20200225220504-708a9fe87ddc/go.mod h1:JbpHhNyeVc538vtj/ECJ3gPYm1VEitNjsLhm4eJQQbg=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94 h1:0ngsPmuP6XIjiFRNFYlvKwSr5zff2v+uPHaffZ6/M4k=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -909,16 +834,13 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/tencentcloud/tencentcloud-sdk-go v3.0.171+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8=
github.com/tidwall/pretty v1.0.1/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 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8=
github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/ulikunitz/xz v0.5.7 h1:YvTNdFzX6+W5m9msiYg/zpkSURPPtOlzbqYjrFn7Yt4=
github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
@@ -930,7 +852,6 @@ github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -956,7 +877,6 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.14.1 h1:nYDKopTbvAPq/NrUVZwT15y2lpROBiLLyoRTbXOYWOo=
@@ -978,7 +898,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM=
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -1038,6 +957,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -1046,9 +966,7 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120 h1:EZ3cVSzKOlJxAd8e8YAJ7no8nNypTxexh/YE/xW3ZEY=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476 h1:E7ct1C6/33eOdrGZKMoyntcEvs2dwZnDe30crG5vpYU=
golang.org/x/net v0.0.0-20200519113804-d87ec0cfa476/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
@@ -1099,30 +1017,23 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200121082415-34d275377bf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HXxFpW2sdCiP8MJSKLQY=
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1135,7 +1046,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
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 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1182,7 +1092,6 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200409170454-77362c5149f0/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200416214402-fc959738d646 h1:7CEkhBsBejkW845gR1AmglqMfc1yGzn42FBmtM4jxyM=
golang.org/x/tools v0.0.0-20200416214402-fc959738d646/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200521155704-91d71f6c2f04 h1:LbW6ziLoA0vw8ZR4bmjKAzgEpunUBaEX1ia1Q1jEGC4=
golang.org/x/tools v0.0.0-20200521155704-91d71f6c2f04/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -1208,7 +1117,6 @@ google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.21.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0 h1:cG03eaksBzhfSIk7JRGctfp3lanklcOM/mTGvow7BbQ=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
@@ -1247,9 +1155,7 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200409111301-baae70f3302d/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200416231807-8751e049a2a0/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884 h1:fiNLklpBwWK1mth30Hlwk+fcdBmIALlgF5iy77O37Ig=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200519141106-08726f379972 h1:6ydLqG65DIMNJf6p97WudGsmd1w3Ickm/LiZnBrREPI=
google.golang.org/genproto v0.0.0-20200519141106-08726f379972/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
@@ -1268,7 +1174,6 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.28.1 h1:C1QC6KzgSiLyBabDi87BbjaGreoRgGUF5nOyvfrAZ1k=
google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
@@ -1277,9 +1182,7 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA=
@@ -1288,15 +1191,12 @@ google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
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/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
@@ -1306,7 +1206,6 @@ gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI=
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
gopkg.in/ldap.v3 v3.0.3 h1:YKRHW/2sIl05JsCtx/5ZuUueFuJyoj/6+DGXe3wp6ro=
gopkg.in/ldap.v3 v3.0.3/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
@@ -1315,23 +1214,19 @@ gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKek
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.3.0/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.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y=
gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/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 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
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 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -1354,5 +1249,4 @@ layeh.com/radius v0.0.0-20190322222518-890bc1058917/go.mod h1:fywZKyu//X7iRzaxLg
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
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/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

View File

@@ -55,15 +55,15 @@ func GenerateSharedSecret(ourPrivate, theirPublic []byte) ([]byte, error) {
func DeriveSharedKey(secret, ourPublic, theirPublic []byte) ([]byte, error) {
// Derive the final key from the HKDF of the secret and public keys.
/*
Internally, HKDF hashes the secret and two public keys. If Alice and Bob are doing DH key exchange, Alice calculates:
/*
Internally, HKDF hashes the secret and two public keys. If Alice and Bob are doing DH key exchange, Alice calculates:
HKDF(secret, A, B) since ourPublic is A.
HKDF(secret, A, B) since ourPublic is A.
Bob calculates HKDF(secret, B, A), since Bob's ours is B. That produces a different value. Now we only care
that both public keys participate in the derivation, so simply sorting them so they are in a consistent
numerical order (either one would do) arrives at an agreed value.
*/
Bob calculates HKDF(secret, B, A), since Bob's ours is B. That produces a different value. Now we only care
that both public keys participate in the derivation, so simply sorting them so they are in a consistent
numerical order (either one would do) arrives at an agreed value.
*/
var pub1 []byte
var pub2 []byte

View File

@@ -0,0 +1,88 @@
package cassandra
import (
"context"
"errors"
"fmt"
"github.com/gocql/gocql"
"github.com/hashicorp/vault/helper/testhelpers/docker"
"os"
"testing"
"time"
)
func PrepareTestContainer(t *testing.T, version string) (func(), string) {
t.Helper()
if os.Getenv("CASSANDRA_HOSTS") != "" {
return func() {}, os.Getenv("CASSANDRA_HOSTS")
}
if version == "" {
version = "3.11"
}
var copyFromTo map[string]string
cwd, _ := os.Getwd()
fixturePath := fmt.Sprintf("%s/test-fixtures/", cwd)
if _, err := os.Stat(fixturePath); err != nil {
if !errors.Is(err, os.ErrNotExist) {
// If it doesn't exist, no biggie
t.Fatal(err)
}
} else {
copyFromTo = map[string]string{
fixturePath: "/etc/cassandra",
}
}
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "cassandra",
ImageTag: version,
Ports: []string{"9042/tcp"},
CopyFromTo: copyFromTo,
Env: []string{"CASSANDRA_BROADCAST_ADDRESS=127.0.0.1"},
})
if err != nil {
t.Fatalf("Could not start docker cassandra: %s", err)
}
svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
cfg := docker.NewServiceHostPort(host, port)
clusterConfig := gocql.NewCluster(cfg.Address())
clusterConfig.Authenticator = gocql.PasswordAuthenticator{
Username: "cassandra",
Password: "cassandra",
}
clusterConfig.Timeout = 30 * time.Second
clusterConfig.ProtoVersion = 4
clusterConfig.Port = port
session, err := clusterConfig.CreateSession()
if err != nil {
return nil, fmt.Errorf("error creating session: %s", err)
}
defer session.Close()
// Create keyspace
q := session.Query(`CREATE KEYSPACE "vault" WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };`)
if err := q.Exec(); err != nil {
t.Fatalf("could not create cassandra keyspace: %v", err)
}
// Create table
q = session.Query(`CREATE TABLE "vault"."entries" (
bucket text,
key text,
value blob,
PRIMARY KEY (bucket, key)
) WITH CLUSTERING ORDER BY (key ASC);`)
if err := q.Exec(); err != nil {
t.Fatalf("could not create cassandra table: %v", err)
}
return cfg, nil
})
if err != nil {
t.Fatalf("Could not start docker cassandra: %s", err)
}
return svc.Cleanup, svc.Config.Address()
}

View File

@@ -1,32 +1,38 @@
package consul
import (
"fmt"
"context"
"os"
"strings"
"testing"
consulapi "github.com/hashicorp/consul/api"
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/ory/dockertest"
dc "github.com/ory/dockertest/docker"
)
type Config struct {
docker.ServiceHostPort
Token string
}
func (c *Config) APIConfig() *consulapi.Config {
apiConfig := consulapi.DefaultConfig()
apiConfig.Address = c.Address()
apiConfig.Token = c.Token
return apiConfig
}
// PrepareTestContainer creates a Consul docker container. If version is empty,
// the Consul version used will be given by the environment variable
// CONSUL_DOCKER_VERSION, or if that's empty, whatever we've hardcoded as the
// the latest Consul version.
func PrepareTestContainer(t *testing.T, version string) (cleanup func(), retAddress string, consulToken string) {
t.Logf("preparing test container")
consulToken = os.Getenv("CONSUL_HTTP_TOKEN")
retAddress = os.Getenv("CONSUL_HTTP_ADDR")
if retAddress != "" {
return func() {}, retAddress, consulToken
}
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
func PrepareTestContainer(t *testing.T, version string) (func(), *Config) {
if retAddress := os.Getenv("CONSUL_HTTP_ADDR"); retAddress != "" {
shp, err := docker.NewServiceHostPortParse(retAddress)
if err != nil {
t.Fatal(err)
}
return func() {}, &Config{ServiceHostPort: *shp, Token: os.Getenv("CONSUL_HTTP_TOKEN")}
}
config := `acl { enabled = true default_policy = "deny" }`
@@ -42,43 +48,32 @@ func PrepareTestContainer(t *testing.T, version string) (cleanup func(), retAddr
config = `datacenter = "test" acl_default_policy = "deny" acl_datacenter = "test" acl_master_token = "test"`
}
dockerOptions := &dockertest.RunOptions{
Repository: "consul",
Tag: version,
Cmd: []string{"agent", "-dev", "-client", "0.0.0.0", "-hcl", config},
}
consulRepo := os.Getenv("CONSUL_DOCKER_REPO")
if consulRepo != "" {
dockerOptions.Repository = consulRepo
dockerOptions.Auth = dc.AuthConfiguration{
Username: os.Getenv("CONSUL_DOCKER_USERNAME"),
Password: os.Getenv("CONSUL_DOCKER_PASSWORD"),
}
}
resource, err := pool.RunWithOptions(dockerOptions)
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "consul",
ImageTag: version,
Cmd: []string{"agent", "-dev", "-client", "0.0.0.0", "-hcl", config},
Ports: []string{"8500/tcp"},
// TODO auth untested on this branch
Repository: os.Getenv("CONSUL_DOCKER_REPO"),
AuthUsername: os.Getenv("CONSUL_DOCKER_USERNAME"),
AuthPassword: os.Getenv("CONSUL_DOCKER_PASSWORD"),
})
if err != nil {
t.Fatalf("Could not start local Consul %s docker container: %s", version, err)
t.Fatalf("Could not start docker Consul: %s", err)
}
cleanup = func() {
docker.CleanupResource(t, pool, resource)
}
retAddress = fmt.Sprintf("localhost:%s", resource.GetPort("8500/tcp"))
// exponential backoff-retry
if err = pool.Retry(func() error {
var err error
consulConfig := consulapi.DefaultNonPooledConfig()
consulConfig.Address = retAddress
consul, err := consulapi.NewClient(consulConfig)
svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
shp := docker.NewServiceHostPort(host, port)
apiConfig := consulapi.DefaultNonPooledConfig()
apiConfig.Address = shp.Address()
consul, err := consulapi.NewClient(apiConfig)
if err != nil {
return err
return nil, err
}
// For version of Consul < 1.4
if strings.HasPrefix(version, "1.3") {
consulToken = "test"
consulToken := "test"
_, err = consul.KV().Put(&consulapi.KVPair{
Key: "setuptest",
Value: []byte("setuptest"),
@@ -86,18 +81,20 @@ func PrepareTestContainer(t *testing.T, version string) (cleanup func(), retAddr
Token: consulToken,
})
if err != nil {
return err
return nil, err
}
return nil
return &Config{
ServiceHostPort: *shp,
Token: consulToken,
}, nil
}
// New default behavior
aclbootstrap, _, err := consul.ACL().Bootstrap()
if err != nil {
return err
return nil, err
}
consulToken = aclbootstrap.SecretID
t.Logf("Generated Master token: %s", consulToken)
consulToken := aclbootstrap.SecretID
policy := &consulapi.ACLPolicy{
Name: "test",
Description: "test",
@@ -115,12 +112,15 @@ func PrepareTestContainer(t *testing.T, version string) (cleanup func(), retAddr
}
_, _, err = consul.ACL().PolicyCreate(policy, q)
if err != nil {
return err
return nil, err
}
return nil
}); err != nil {
cleanup()
t.Fatalf("Could not connect to docker: %s", err)
return &Config{
ServiceHostPort: *shp,
Token: consulToken,
}, nil
})
if err != nil {
t.Fatalf("Could not start docker Consul: %s", err)
}
return cleanup, retAddress, consulToken
return svc.Cleanup, svc.Config.(*Config)
}

View File

@@ -1,25 +1,309 @@
package docker
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"net/url"
"os"
"strconv"
"strings"
"time"
"github.com/mitchellh/go-testing-interface"
"github.com/ory/dockertest"
"github.com/cenkalti/backoff/v3"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
"github.com/docker/docker/pkg/archive"
"github.com/docker/go-connections/nat"
"github.com/hashicorp/go-uuid"
)
func CleanupResource(t testing.T, pool *dockertest.Pool, resource *dockertest.Resource) {
var err error
for i := 0; i < 10; i++ {
err = pool.Purge(resource)
if err == nil {
return
}
time.Sleep(1 * time.Second)
type Runner struct {
DockerAPI *client.Client
RunOptions RunOptions
}
type RunOptions struct {
ImageRepo string
ImageTag string
ContainerName string
Cmd []string
Env []string
NetworkID string
CopyFromTo map[string]string
Ports []string
DoNotAutoRemove bool
Repository string
AuthUsername string
AuthPassword string
}
func NewServiceRunner(opts RunOptions) (*Runner, error) {
dapi, err := client.NewClientWithOpts(client.FromEnv, client.WithVersion("1.39"))
if err != nil {
return nil, err
}
if strings.Contains(err.Error(), "No such container") {
return
if opts.NetworkID == "" {
opts.NetworkID = os.Getenv("TEST_DOCKER_NETWORK_ID")
}
t.Fatalf("Failed to cleanup local container: %s", err)
if opts.ContainerName == "" {
if strings.Contains(opts.ImageRepo, "/") {
return nil, fmt.Errorf("ContainerName is required for non-library images")
}
// If there's no slash in the repo it's almost certainly going to be
// a good container name.
opts.ContainerName = opts.ImageRepo
}
return &Runner{
DockerAPI: dapi,
RunOptions: opts,
}, nil
}
type ServiceConfig interface {
Address() string
URL() *url.URL
}
func NewServiceHostPort(host string, port int) *ServiceHostPort {
return &ServiceHostPort{address: fmt.Sprintf("%s:%d", host, port)}
}
func NewServiceHostPortParse(s string) (*ServiceHostPort, error) {
pieces := strings.Split(s, ":")
if len(pieces) != 2 {
return nil, fmt.Errorf("address must be of the form host:port, got: %v", s)
}
port, err := strconv.Atoi(pieces[1])
if err != nil || port < 1 {
return nil, fmt.Errorf("address must be of the form host:port, got: %v", s)
}
return &ServiceHostPort{s}, nil
}
type ServiceHostPort struct {
address string
}
func (s ServiceHostPort) Address() string {
return s.address
}
func (s ServiceHostPort) URL() *url.URL {
return &url.URL{Host: s.address}
}
func NewServiceURLParse(s string) (*ServiceURL, error) {
u, err := url.Parse(s)
if err != nil {
return nil, err
}
return &ServiceURL{u: *u}, nil
}
func NewServiceURL(u url.URL) *ServiceURL {
return &ServiceURL{u: u}
}
type ServiceURL struct {
u url.URL
}
func (s ServiceURL) Address() string {
return s.u.Host
}
func (s ServiceURL) URL() *url.URL {
return &s.u
}
// ServiceAdapter verifies connectivity to the service, then returns either the
// connection string (typically a URL) and nil, or empty string and an error.
type ServiceAdapter func(ctx context.Context, host string, port int) (ServiceConfig, error)
func (d *Runner) StartService(ctx context.Context, connect ServiceAdapter) (*Service, error) {
container, hostIPs, err := d.Start(context.Background())
if err != nil {
return nil, err
}
cleanup := func() {
for i := 0; i < 10; i++ {
err := d.DockerAPI.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{Force: true})
if err == nil {
return
}
time.Sleep(1 * time.Second)
}
}
bo := backoff.NewExponentialBackOff()
bo.MaxInterval = time.Second * 5
bo.MaxElapsedTime = time.Minute
pieces := strings.Split(hostIPs[0], ":")
portInt, err := strconv.Atoi(pieces[1])
if err != nil {
return nil, err
}
var config ServiceConfig
err = backoff.Retry(func() error {
c, err := connect(ctx, pieces[0], portInt)
if err != nil {
return err
}
if c == nil {
return fmt.Errorf("service adapter returned nil error and config")
}
config = c
return nil
}, bo)
if err != nil {
if !d.RunOptions.DoNotAutoRemove {
cleanup()
}
return nil, err
}
return &Service{
Config: config,
Cleanup: cleanup,
}, nil
}
type Service struct {
Config ServiceConfig
Cleanup func()
}
func (d *Runner) Start(ctx context.Context) (*types.ContainerJSON, []string, error) {
suffix, err := uuid.GenerateUUID()
if err != nil {
return nil, nil, err
}
name := d.RunOptions.ContainerName + "-" + suffix
cfg := &container.Config{
Hostname: name,
Image: fmt.Sprintf("%s:%s", d.RunOptions.ImageRepo, d.RunOptions.ImageTag),
Env: d.RunOptions.Env,
Cmd: d.RunOptions.Cmd,
}
if len(d.RunOptions.Ports) > 0 {
cfg.ExposedPorts = make(map[nat.Port]struct{})
for _, p := range d.RunOptions.Ports {
cfg.ExposedPorts[nat.Port(p)] = struct{}{}
}
}
hostConfig := &container.HostConfig{
AutoRemove: !d.RunOptions.DoNotAutoRemove,
PublishAllPorts: true,
}
netConfig := &network.NetworkingConfig{}
if d.RunOptions.NetworkID != "" {
netConfig.EndpointsConfig = map[string]*network.EndpointSettings{
d.RunOptions.NetworkID: &network.EndpointSettings{},
}
}
// best-effort pull
var opts types.ImageCreateOptions
if d.RunOptions.AuthUsername != "" && d.RunOptions.AuthPassword != "" {
var buf bytes.Buffer
auth := map[string]string{
"username": d.RunOptions.AuthUsername,
"password": d.RunOptions.AuthPassword,
}
if err := json.NewEncoder(&buf).Encode(auth); err != nil {
return nil, nil, err
}
opts.RegistryAuth = base64.URLEncoding.EncodeToString(buf.Bytes())
}
resp, _ := d.DockerAPI.ImageCreate(ctx, cfg.Image, opts)
if resp != nil {
_, _ = ioutil.ReadAll(resp)
}
container, err := d.DockerAPI.ContainerCreate(ctx, cfg, hostConfig, netConfig, cfg.Hostname)
if err != nil {
return nil, nil, fmt.Errorf("container create failed: %v", err)
}
for from, to := range d.RunOptions.CopyFromTo {
if err := copyToContainer(ctx, d.DockerAPI, container.ID, from, to); err != nil {
_ = d.DockerAPI.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{})
return nil, nil, err
}
}
err = d.DockerAPI.ContainerStart(ctx, container.ID, types.ContainerStartOptions{})
if err != nil {
_ = d.DockerAPI.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{})
return nil, nil, fmt.Errorf("container start failed: %v", err)
}
inspect, err := d.DockerAPI.ContainerInspect(ctx, container.ID)
if err != nil {
_ = d.DockerAPI.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{})
return nil, nil, err
}
var addrs []string
for _, port := range d.RunOptions.Ports {
pieces := strings.Split(port, "/")
if len(pieces) < 2 {
return nil, nil, fmt.Errorf("expected port of the form 1234/tcp, got: %s", port)
}
if d.RunOptions.NetworkID != "" {
addrs = append(addrs, fmt.Sprintf("%s:%s", cfg.Hostname, pieces[0]))
} else {
mapped, ok := inspect.NetworkSettings.Ports[nat.Port(port)]
if !ok || len(mapped) == 0 {
return nil, nil, fmt.Errorf("no port mapping found for %s", port)
}
addrs = append(addrs, fmt.Sprintf("127.0.0.1:%s", mapped[0].HostPort))
}
}
return &inspect, addrs, nil
}
func copyToContainer(ctx context.Context, dapi *client.Client, containerID, from, to string) error {
srcInfo, err := archive.CopyInfoSourcePath(from, false)
if err != nil {
return fmt.Errorf("error copying from source %q: %v", from, err)
}
srcArchive, err := archive.TarResource(srcInfo)
if err != nil {
return fmt.Errorf("error creating tar from source %q: %v", from, err)
}
defer srcArchive.Close()
dstInfo := archive.CopyInfo{Path: to}
dstDir, content, err := archive.PrepareArchiveCopy(srcArchive, srcInfo, dstInfo)
if err != nil {
return fmt.Errorf("error preparing copy from %q -> %q: %v", from, to, err)
}
defer content.Close()
err = dapi.CopyToContainer(ctx, containerID, dstDir, content, types.CopyToContainerOptions{})
if err != nil {
return fmt.Errorf("error copying from %q -> %q: %v", from, to, err)
}
return nil
}

View File

@@ -1,70 +1,63 @@
package ldap
import (
"context"
"fmt"
"testing"
hclog "github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/hashicorp/vault/sdk/helper/ldaputil"
"github.com/ory/dockertest"
)
func PrepareTestContainer(t *testing.T, version string) (cleanup func(), cfg *ldaputil.ConfigEntry) {
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
}
dockerOptions := &dockertest.RunOptions{
runner, err := docker.NewServiceRunner(docker.RunOptions{
// Currently set to "michelvocks" until https://github.com/rroemhild/docker-test-openldap/pull/14
// has been merged.
Repository: "michelvocks/docker-test-openldap",
Tag: version,
Privileged: true,
ImageRepo: "michelvocks/docker-test-openldap",
ImageTag: version,
ContainerName: "ldap",
Ports: []string{"389/tcp"},
//Env: []string{"LDAP_DEBUG_LEVEL=384"},
}
resource, err := pool.RunWithOptions(dockerOptions)
})
if err != nil {
t.Fatalf("Could not start local LDAP %s docker container: %s", version, err)
t.Fatalf("could not start local LDAP docker container: %s", err)
}
cleanup = func() {
docker.CleanupResource(t, pool, resource)
}
cfg = new(ldaputil.ConfigEntry)
cfg.UserDN = "ou=people,dc=planetexpress,dc=com"
cfg.UserAttr = "cn"
cfg.BindDN = "cn=admin,dc=planetexpress,dc=com"
cfg.BindPassword = "GoodNewsEveryone"
cfg.GroupDN = "ou=people,dc=planetexpress,dc=com"
cfg.GroupAttr = "cn"
cfg.RequestTimeout = 60
//pool.MaxWait = time.Second
// exponential backoff-retry
if err = pool.Retry(func() error {
svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
connURL := fmt.Sprintf("ldap://%s:%d", host, port)
cfg.Url = connURL
logger := hclog.New(nil)
client := ldaputil.Client{
LDAP: ldaputil.NewLDAP(),
Logger: logger,
}
cfg = new(ldaputil.ConfigEntry)
cfg.Url = fmt.Sprintf("ldap://localhost:%s", resource.GetPort("389/tcp"))
cfg.UserDN = "ou=people,dc=planetexpress,dc=com"
cfg.UserAttr = "cn"
cfg.BindDN = "cn=admin,dc=planetexpress,dc=com"
cfg.BindPassword = "GoodNewsEveryone"
cfg.GroupDN = "ou=people,dc=planetexpress,dc=com"
cfg.GroupAttr = "cn"
cfg.RequestTimeout = 60
conn, err := client.DialLDAP(cfg)
if err != nil {
return err
return nil, err
}
defer conn.Close()
if _, err := client.GetUserBindDN(cfg, conn, "Philip J. Fry"); err != nil {
return err
return nil, err
}
return nil
}); err != nil {
cleanup()
t.Fatalf("Could not connect to docker: %s", err)
return docker.NewServiceURLParse(connURL)
})
if err != nil {
t.Fatalf("could not start local LDAP docker container: %s", err)
}
return cleanup, cfg
return svc.Cleanup, cfg
}

View File

@@ -1,6 +1,7 @@
package mongodb
import (
"context"
"crypto/tls"
"errors"
"fmt"
@@ -12,7 +13,7 @@ import (
"testing"
"time"
"github.com/ory/dockertest"
"github.com/hashicorp/vault/helper/testhelpers/docker"
"gopkg.in/mgo.v2"
)
@@ -24,55 +25,51 @@ func PrepareTestContainer(t *testing.T, version string) (cleanup func(), retURL
// PrepareTestContainerWithDatabase configures a test container with a given
// database name, to test non-test/admin database configurations
func PrepareTestContainerWithDatabase(t *testing.T, version, dbName string) (cleanup func(), retURL string) {
func PrepareTestContainerWithDatabase(t *testing.T, version, dbName string) (func(), string) {
if os.Getenv("MONGODB_URL") != "" {
return func() {}, os.Getenv("MONGODB_URL")
}
pool, err := dockertest.NewPool("")
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "mongo",
ImageTag: version,
Ports: []string{"27017/tcp"},
})
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
t.Fatalf("could not start docker mongo: %s", err)
}
resource, err := pool.Run("mongo", version, []string{})
if err != nil {
t.Fatalf("Could not start local mongo docker container: %s", err)
}
cleanup = func() {
err := pool.Purge(resource)
if err != nil {
t.Fatalf("Failed to cleanup local container: %s", err)
svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
connURL := fmt.Sprintf("mongodb://%s:%d", host, port)
if dbName != "" {
connURL = fmt.Sprintf("%s/%s", connURL, dbName)
}
}
retURL = fmt.Sprintf("mongodb://localhost:%s", resource.GetPort("27017/tcp"))
if dbName != "" {
retURL = fmt.Sprintf("%s/%s", retURL, dbName)
}
// exponential backoff-retry
if err = pool.Retry(func() error {
var err error
dialInfo, err := ParseMongoURL(retURL)
dialInfo, err := ParseMongoURL(connURL)
if err != nil {
return err
return nil, err
}
session, err := mgo.DialWithInfo(dialInfo)
if err != nil {
return err
return nil, err
}
defer session.Close()
session.SetSyncTimeout(1 * time.Minute)
session.SetSocketTimeout(1 * time.Minute)
return session.Ping()
}); err != nil {
cleanup()
t.Fatalf("Could not connect to mongo docker container: %s", err)
err = session.Ping()
if err != nil {
return nil, err
}
return docker.NewServiceURLParse(connURL)
})
if err != nil {
t.Fatalf("could not start docker mongo: %s", err)
}
return
return svc.Cleanup, svc.Config.URL().String()
}
// ParseMongoURL will parse a connection string and return a configured dialer

View File

@@ -1,50 +1,58 @@
package mssqlhelper
import (
"context"
"database/sql"
"fmt"
"net/url"
"os"
"testing"
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/ory/dockertest"
)
const mssqlPassword = "yourStrong(!)Password"
func PrepareMSSQLTestContainer(t *testing.T) (cleanup func(), retURL string) {
if os.Getenv("MSSQL_URL") != "" {
return func() {}, os.Getenv("MSSQL_URL")
}
pool, err := dockertest.NewPool("")
runner, err := docker.NewServiceRunner(docker.RunOptions{
ContainerName: "sqlserver",
ImageRepo: "mcr.microsoft.com/mssql/server",
ImageTag: "2017-latest-ubuntu",
Env: []string{"ACCEPT_EULA=Y", "SA_PASSWORD=" + mssqlPassword},
Ports: []string{"1433/tcp"},
})
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
t.Fatalf("Could not start docker MSSQL: %s", err)
}
resource, err := pool.Run("mcr.microsoft.com/mssql/server", "2017-latest-ubuntu", []string{"ACCEPT_EULA=Y", "SA_PASSWORD=yourStrong(!)Password"})
svc, err := runner.StartService(context.Background(), connectMSSQL)
if err != nil {
t.Fatalf("Could not start local MSSQL docker container: %s", err)
t.Fatalf("Could not start docker MSSQL: %s", err)
}
cleanup = func() {
docker.CleanupResource(t, pool, resource)
}
retURL = fmt.Sprintf("sqlserver://sa:yourStrong(!)Password@127.0.0.1:%s", resource.GetPort("1433/tcp"))
// exponential backoff-retry
if err = pool.Retry(func() error {
var err error
var db *sql.DB
db, err = sql.Open("mssql", retURL)
if err != nil {
return err
}
defer db.Close()
return db.Ping()
}); err != nil {
cleanup()
t.Fatalf("Could not connect to MSSQL docker container: %s", err)
}
return
return svc.Cleanup, svc.Config.URL().String()
}
func connectMSSQL(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
u := url.URL{
Scheme: "sqlserver",
User: url.UserPassword("sa", mssqlPassword),
Host: fmt.Sprintf("%s:%d", host, port),
}
db, err := sql.Open("mssql", u.String())
if err != nil {
return nil, err
}
defer db.Close()
err = db.Ping()
if err != nil {
return nil, err
}
return docker.NewServiceURL(u), nil
}

View File

@@ -1,6 +1,7 @@
package mysqlhelper
import (
"context"
"database/sql"
"fmt"
"os"
@@ -8,51 +9,54 @@ import (
"testing"
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/ory/dockertest"
)
func PrepareMySQLTestContainer(t *testing.T, legacy bool, pw string) (cleanup func(), retURL string) {
type Config struct {
docker.ServiceHostPort
ConnString string
}
var _ docker.ServiceConfig = &Config{}
func PrepareTestContainer(t *testing.T, legacy bool, pw string) (func(), string) {
if os.Getenv("MYSQL_URL") != "" {
return func() {}, os.Getenv("MYSQL_URL")
}
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
}
imageVersion := "5.7"
if legacy {
imageVersion = "5.6"
}
resource, err := pool.Run("mysql", imageVersion, []string{"MYSQL_ROOT_PASSWORD=" + pw})
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "mysql",
ImageTag: imageVersion,
Ports: []string{"3306/tcp"},
Env: []string{"MYSQL_ROOT_PASSWORD=" + pw},
})
if err != nil {
t.Fatalf("Could not start local MySQL docker container: %s", err)
t.Fatalf("could not start docker mysql: %s", err)
}
cleanup = func() {
docker.CleanupResource(t, pool, resource)
}
retURL = fmt.Sprintf("root:%s@(localhost:%s)/mysql?parseTime=true", pw, resource.GetPort("3306/tcp"))
// exponential backoff-retry
if err = pool.Retry(func() error {
var err error
var db *sql.DB
db, err = sql.Open("mysql", retURL)
svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
hostIP := docker.NewServiceHostPort(host, port)
connString := fmt.Sprintf("root:%s@(%s)/mysql?parseTime=true", pw, hostIP.Address())
db, err := sql.Open("mysql", connString)
if err != nil {
return err
return nil, err
}
defer db.Close()
return db.Ping()
}); err != nil {
cleanup()
t.Fatalf("Could not connect to MySQL docker container: %s", err)
}
err = db.Ping()
if err != nil {
return nil, err
}
return &Config{ServiceHostPort: *hostIP, ConnString: connString}, nil
})
return
if err != nil {
t.Fatalf("could not start docker mysql: %s", err)
}
return svc.Cleanup, svc.Config.(*Config).ConnString
}
func TestCredsExist(t testing.TB, connURL, username, password string) error {

View File

@@ -1,53 +0,0 @@
package postgresql
import (
"database/sql"
"fmt"
"os"
"testing"
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/ory/dockertest"
)
func PrepareTestContainer(t *testing.T, version string) (cleanup func(), retURL string) {
if os.Getenv("PG_URL") != "" {
return func() {}, os.Getenv("PG_URL")
}
if version == "" {
version = "latest"
}
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
}
resource, err := pool.Run("postgres", "latest", []string{"POSTGRES_PASSWORD=secret", "POSTGRES_DB=database"})
if err != nil {
t.Fatalf("Could not start local PostgreSQL docker container: %s", err)
}
cleanup = func() {
docker.CleanupResource(t, pool, resource)
}
retURL = fmt.Sprintf("postgres://postgres:secret@localhost:%s/database?sslmode=disable", resource.GetPort("5432/tcp"))
// exponential backoff-retry
if err = pool.Retry(func() error {
var err error
var db *sql.DB
db, err = sql.Open("postgres", retURL)
if err != nil {
return err
}
defer db.Close()
return db.Ping()
}); err != nil {
cleanup()
t.Fatalf("Could not connect to PostgreSQL docker container: %s", err)
}
return
}

View File

@@ -0,0 +1,59 @@
package postgresql
import (
"context"
"database/sql"
"fmt"
"github.com/hashicorp/vault/helper/testhelpers/docker"
"net/url"
"os"
"testing"
)
func PrepareTestContainer(t *testing.T, version string) (func(), string) {
if os.Getenv("PG_URL") != "" {
return func() {}, os.Getenv("PG_URL")
}
if version == "" {
version = "11"
}
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "postgres",
ImageTag: version,
Env: []string{"POSTGRES_PASSWORD=secret", "POSTGRES_DB=database"},
Ports: []string{"5432/tcp"},
})
if err != nil {
t.Fatalf("Could not start docker Postgres: %s", err)
}
svc, err := runner.StartService(context.Background(), connectPostgres)
if err != nil {
t.Fatalf("Could not start docker Postgres: %s", err)
}
return svc.Cleanup, svc.Config.URL().String()
}
func connectPostgres(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
u := url.URL{
Scheme: "postgres",
User: url.UserPassword("postgres", "secret"),
Host: fmt.Sprintf("%s:%d", host, port),
Path: "postgres",
RawQuery: "sslmode=disable",
}
db, err := sql.Open("postgres", u.String())
if err != nil {
return nil, err
}
defer db.Close()
err = db.Ping()
if err != nil {
return nil, err
}
return docker.NewServiceURL(u), nil
}

View File

@@ -83,10 +83,11 @@ func MakeFileBackend(t testing.T, logger hclog.Logger) *vault.PhysicalBackendBun
}
func MakeConsulBackend(t testing.T, logger hclog.Logger) *vault.PhysicalBackendBundle {
cleanup, consulAddress, consulToken := consul.PrepareTestContainer(t.(*realtesting.T), "")
cleanup, config := consul.PrepareTestContainer(t.(*realtesting.T), "")
consulConf := map[string]string{
"address": consulAddress,
"token": consulToken,
"address": config.Address(),
"token": config.Token,
"max_parallel": "32",
}
consulBackend, err := physConsul.NewConsulBackend(consulConf, logger)
@@ -105,7 +106,7 @@ func MakeRaftBackend(t testing.T, coreIdx int, logger hclog.Logger) *vault.Physi
if err != nil {
t.Fatal(err)
}
t.Logf("raft dir: %s", raftDir)
//t.Logf("raft dir: %s", raftDir)
cleanupFunc := func() {
os.RemoveAll(raftDir)
}

View File

@@ -164,7 +164,7 @@ func makeRaftDir(t testing.T) string {
if err != nil {
t.Fatal(err)
}
t.Logf("raft dir: %s", raftDir)
//t.Logf("raft dir: %s", raftDir)
return raftDir
}

View File

@@ -1,27 +1,24 @@
package cassandra
import (
"fmt"
"os"
"reflect"
"strconv"
"testing"
"time"
"github.com/gocql/gocql"
log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/hashicorp/vault/helper/testhelpers/cassandra"
"github.com/hashicorp/vault/sdk/helper/logging"
"github.com/hashicorp/vault/sdk/physical"
"github.com/ory/dockertest"
"os"
"reflect"
"testing"
)
func TestCassandraBackend(t *testing.T) {
if testing.Short() {
t.Skipf("skipping in short mode")
}
if os.Getenv("VAULT_CI_GO_TEST_RACE") != "" {
t.Skip("skipping race test in CI pending https://github.com/gocql/gocql/pull/1474")
}
cleanup, hosts := prepareCassandraTestContainer(t)
cleanup, hosts := cassandra.PrepareTestContainer(t, "")
defer cleanup()
// Run vault tests
@@ -54,60 +51,3 @@ func TestCassandraBackendBuckets(t *testing.T) {
}
}
}
func prepareCassandraTestContainer(t *testing.T) (func(), string) {
if os.Getenv("CASSANDRA_HOSTS") != "" {
return func() {}, os.Getenv("CASSANDRA_HOSTS")
}
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("cassandra: failed to connect to docker: %s", err)
}
resource, err := pool.Run("cassandra", "3.11", []string{"CASSANDRA_BROADCAST_ADDRESS=127.0.0.1"})
if err != nil {
t.Fatalf("cassandra: could not start container: %s", err)
}
cleanup := func() {
docker.CleanupResource(t, pool, resource)
}
setup := func() error {
cluster := gocql.NewCluster("127.0.0.1")
p, _ := strconv.Atoi(resource.GetPort("9042/tcp"))
cluster.Port = p
cluster.Timeout = 15 * time.Second
sess, err := cluster.CreateSession()
if err != nil {
return err
}
defer sess.Close()
// Create keyspace
q := sess.Query(`CREATE KEYSPACE "vault" WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };`)
if err := q.Exec(); err != nil {
t.Fatalf("could not create cassandra keyspace: %v", err)
}
// Create table
q = sess.Query(`CREATE TABLE "vault"."entries" (
bucket text,
key text,
value blob,
PRIMARY KEY (bucket, key)
) WITH CLUSTERING ORDER BY (key ASC);`)
if err := q.Exec(); err != nil {
t.Fatalf("could not create cassandra table: %v", err)
}
return nil
}
if pool.Retry(setup); err != nil {
cleanup()
t.Fatalf("cassandra: could not setup container: %s", err)
}
return cleanup, fmt.Sprintf("127.0.0.1:%s", resource.GetPort("9042/tcp"))
}

View File

@@ -1,8 +1,10 @@
package cockroachdb
import (
"context"
"database/sql"
"fmt"
"net/url"
"os"
"testing"
@@ -10,72 +12,89 @@ import (
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/hashicorp/vault/sdk/helper/logging"
"github.com/hashicorp/vault/sdk/physical"
"github.com/ory/dockertest"
_ "github.com/lib/pq"
)
func prepareCockroachDBTestContainer(t *testing.T) (cleanup func(), retURL, tableName string) {
tableName = os.Getenv("CR_TABLE")
type Config struct {
docker.ServiceURL
TableName string
}
var _ docker.ServiceConfig = &Config{}
func prepareCockroachDBTestContainer(t *testing.T) (func(), *Config) {
if retURL := os.Getenv("CR_URL"); retURL != "" {
s, err := docker.NewServiceURLParse(retURL)
if err != nil {
t.Fatal(err)
}
tableName := os.Getenv("CR_TABLE")
if tableName == "" {
tableName = defaultTableName
}
return func() {}, &Config{*s, "vault." + tableName}
}
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "cockroachdb/cockroach",
ImageTag: "release-1.0",
ContainerName: "cockroachdb",
Cmd: []string{"start", "--insecure"},
Ports: []string{"26257/tcp"},
})
if err != nil {
t.Fatalf("Could not start docker CockroachDB: %s", err)
}
svc, err := runner.StartService(context.Background(), connectCockroachDB)
if err != nil {
t.Fatalf("Could not start docker CockroachDB: %s", err)
}
return svc.Cleanup, svc.Config.(*Config)
}
func connectCockroachDB(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
u := url.URL{
Scheme: "postgresql",
User: url.UserPassword("root", ""),
Host: fmt.Sprintf("%s:%d", host, port),
RawQuery: "sslmode=disable",
}
db, err := sql.Open("postgres", u.String())
if err != nil {
return nil, err
}
defer db.Close()
database := "vault"
_, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", database))
if err != nil {
return nil, err
}
tableName := os.Getenv("CR_TABLE")
if tableName == "" {
tableName = defaultTableName
}
t.Logf("Table name: %s", tableName)
retURL = os.Getenv("CR_URL")
if retURL != "" {
return func() {}, retURL, tableName
}
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
}
dockerOptions := &dockertest.RunOptions{
Repository: "cockroachdb/cockroach",
Tag: "release-1.0",
Cmd: []string{"start", "--insecure"},
}
resource, err := pool.RunWithOptions(dockerOptions)
if err != nil {
t.Fatalf("Could not start local CockroachDB docker container: %s", err)
}
cleanup = func() {
docker.CleanupResource(t, pool, resource)
}
retURL = fmt.Sprintf("postgresql://root@localhost:%s/?sslmode=disable", resource.GetPort("26257/tcp"))
database := "vault"
tableName = fmt.Sprintf("%s.%s", database, tableName)
// exponential backoff-retry
if err = pool.Retry(func() error {
var err error
db, err := sql.Open("postgres", retURL)
if err != nil {
return err
}
defer db.Close()
_, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", database))
return err
}); err != nil {
cleanup()
t.Fatalf("Could not connect to docker: %s", err)
}
return cleanup, retURL, tableName
return &Config{
ServiceURL: *docker.NewServiceURL(u),
TableName: database + "." + tableName,
}, nil
}
func TestCockroachDBBackend(t *testing.T) {
cleanup, connURL, table := prepareCockroachDBTestContainer(t)
cleanup, config := prepareCockroachDBTestContainer(t)
defer cleanup()
// Run vault tests
logger := logging.NewVaultLogger(log.Debug)
b, err := NewCockroachDBBackend(map[string]string{
"connection_url": connURL,
"table": table,
"connection_url": config.URL().String(),
"table": config.TableName,
}, logger)
if err != nil {

View File

@@ -4,7 +4,6 @@ import (
"context"
"fmt"
"math/rand"
"os"
"reflect"
"strings"
"testing"
@@ -158,18 +157,10 @@ func TestConsul_newConsulBackend(t *testing.T) {
}
func TestConsulBackend(t *testing.T) {
consulToken := os.Getenv("CONSUL_HTTP_TOKEN")
addr := os.Getenv("CONSUL_HTTP_ADDR")
if addr == "" {
cleanup, connURL, token := consul.PrepareTestContainer(t, "1.4.4")
defer cleanup()
addr, consulToken = connURL, token
}
cleanup, config := consul.PrepareTestContainer(t, "1.4.4")
defer cleanup()
conf := api.DefaultConfig()
conf.Address = addr
conf.Token = consulToken
client, err := api.NewClient(conf)
client, err := api.NewClient(config.APIConfig())
if err != nil {
t.Fatalf("err: %v", err)
}
@@ -182,10 +173,10 @@ func TestConsulBackend(t *testing.T) {
logger := logging.NewVaultLogger(log.Debug)
b, err := NewConsulBackend(map[string]string{
"address": conf.Address,
"address": config.Address(),
"token": config.Token,
"path": randPath,
"max_parallel": "256",
"token": conf.Token,
}, logger)
if err != nil {
t.Fatalf("err: %s", err)
@@ -196,18 +187,10 @@ func TestConsulBackend(t *testing.T) {
}
func TestConsul_TooLarge(t *testing.T) {
consulToken := os.Getenv("CONSUL_HTTP_TOKEN")
addr := os.Getenv("CONSUL_HTTP_ADDR")
if addr == "" {
cleanup, connURL, token := consul.PrepareTestContainer(t, "1.4.4")
defer cleanup()
addr, consulToken = connURL, token
}
cleanup, config := consul.PrepareTestContainer(t, "1.4.4")
defer cleanup()
conf := api.DefaultConfig()
conf.Address = addr
conf.Token = consulToken
client, err := api.NewClient(conf)
client, err := api.NewClient(config.APIConfig())
if err != nil {
t.Fatalf("err: %v", err)
}
@@ -220,10 +203,10 @@ func TestConsul_TooLarge(t *testing.T) {
logger := logging.NewVaultLogger(log.Debug)
b, err := NewConsulBackend(map[string]string{
"address": conf.Address,
"address": config.Address(),
"token": config.Token,
"path": randPath,
"max_parallel": "256",
"token": conf.Token,
}, logger)
if err != nil {
t.Fatalf("err: %s", err)
@@ -267,18 +250,10 @@ func TestConsul_TooLarge(t *testing.T) {
}
func TestConsulHABackend(t *testing.T) {
consulToken := os.Getenv("CONSUL_HTTP_TOKEN")
addr := os.Getenv("CONSUL_HTTP_ADDR")
if addr == "" {
cleanup, connURL, token := consul.PrepareTestContainer(t, "1.4.4")
defer cleanup()
addr, consulToken = connURL, token
}
cleanup, config := consul.PrepareTestContainer(t, "1.4.4")
defer cleanup()
conf := api.DefaultConfig()
conf.Address = addr
conf.Token = consulToken
client, err := api.NewClient(conf)
client, err := api.NewClient(config.APIConfig())
if err != nil {
t.Fatalf("err: %v", err)
}
@@ -289,19 +264,19 @@ func TestConsulHABackend(t *testing.T) {
}()
logger := logging.NewVaultLogger(log.Debug)
config := map[string]string{
"address": conf.Address,
backendConfig := map[string]string{
"address": config.Address(),
"token": config.Token,
"path": randPath,
"max_parallel": "-1",
"token": conf.Token,
}
b, err := NewConsulBackend(config, logger)
b, err := NewConsulBackend(backendConfig, logger)
if err != nil {
t.Fatalf("err: %s", err)
}
b2, err := NewConsulBackend(config, logger)
b2, err := NewConsulBackend(backendConfig, logger)
if err != nil {
t.Fatalf("err: %s", err)
}

View File

@@ -1,9 +1,11 @@
package couchdb
import (
"context"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"strings"
"testing"
@@ -13,19 +15,18 @@ import (
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/hashicorp/vault/sdk/helper/logging"
"github.com/hashicorp/vault/sdk/physical"
"github.com/ory/dockertest"
)
func TestCouchDBBackend(t *testing.T) {
cleanup, endpoint, username, password := prepareCouchdbDBTestContainer(t)
cleanup, config := prepareCouchdbDBTestContainer(t)
defer cleanup()
logger := logging.NewVaultLogger(log.Debug)
b, err := NewCouchDBBackend(map[string]string{
"endpoint": endpoint,
"username": username,
"password": password,
"endpoint": config.URL().String(),
"username": config.username,
"password": config.password,
}, logger)
if err != nil {
t.Fatalf("err: %s", err)
@@ -36,15 +37,15 @@ func TestCouchDBBackend(t *testing.T) {
}
func TestTransactionalCouchDBBackend(t *testing.T) {
cleanup, endpoint, username, password := prepareCouchdbDBTestContainer(t)
cleanup, config := prepareCouchdbDBTestContainer(t)
defer cleanup()
logger := logging.NewVaultLogger(log.Debug)
b, err := NewTransactionalCouchDBBackend(map[string]string{
"endpoint": endpoint,
"username": username,
"password": password,
"endpoint": config.URL().String(),
"username": config.username,
"password": config.password,
}, logger)
if err != nil {
t.Fatalf("err: %s", err)
@@ -54,77 +55,107 @@ func TestTransactionalCouchDBBackend(t *testing.T) {
physical.ExerciseBackend_ListPrefix(t, b)
}
func prepareCouchdbDBTestContainer(t *testing.T) (cleanup func(), retAddress, username, password string) {
type couchDB struct {
baseURL url.URL
dbname string
username string
password string
}
func (c couchDB) Address() string {
return c.baseURL.Host
}
func (c couchDB) URL() *url.URL {
u := c.baseURL
u.Path = c.dbname
return &u
}
var _ docker.ServiceConfig = &couchDB{}
func prepareCouchdbDBTestContainer(t *testing.T) (func(), *couchDB) {
// If environment variable is set, assume caller wants to target a real
// DynamoDB.
if os.Getenv("COUCHDB_ENDPOINT") != "" {
return func() {}, os.Getenv("COUCHDB_ENDPOINT"), os.Getenv("COUCHDB_USERNAME"), os.Getenv("COUCHDB_PASSWORD")
return func() {}, &couchDB{
baseURL: url.URL{Host: os.Getenv("COUCHDB_ENDPOINT")},
username: os.Getenv("COUCHDB_USERNAME"),
password: os.Getenv("COUCHDB_PASSWORD"),
}
}
pool, err := dockertest.NewPool("")
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "couchdb",
ImageTag: "1.6",
Ports: []string{"5984/tcp"},
DoNotAutoRemove: true,
})
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
t.Fatalf("Could not start local CouchDB: %s", err)
}
resource, err := pool.Run("couchdb", "1.6", []string{})
svc, err := runner.StartService(context.Background(), setupCouchDB)
if err != nil {
t.Fatalf("Could not start local DynamoDB: %s", err)
t.Fatalf("Could not start local CouchDB: %s", err)
}
retAddress = "http://localhost:" + resource.GetPort("5984/tcp")
cleanup = func() {
docker.CleanupResource(t, pool, resource)
return svc.Cleanup, svc.Config.(*couchDB)
}
func setupCouchDB(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
c := &couchDB{
baseURL: url.URL{Scheme: "http", Host: fmt.Sprintf("%s:%d", host, port)},
dbname: fmt.Sprintf("vault-test-%d", time.Now().Unix()),
username: "admin",
password: "admin",
}
// exponential backoff-retry, because the couchDB may not be able to accept
// connections yet
if err := pool.Retry(func() error {
var err error
resp, err := http.Get(retAddress)
{
resp, err := http.Get(c.baseURL.String())
if err != nil {
return err
return nil, err
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("expected couchdb to return status code 200, got (%s) instead.", resp.Status)
return nil, fmt.Errorf("expected couchdb to return status code 200, got (%s) instead", resp.Status)
}
return nil
}); err != nil {
t.Fatalf("Could not connect to docker: %s", err)
}
dbName := fmt.Sprintf("vault-test-%d", time.Now().Unix())
{
req, err := http.NewRequest("PUT", fmt.Sprintf("%s/%s", retAddress, dbName), nil)
req, err := http.NewRequest("PUT", c.URL().String(), nil)
if err != nil {
t.Fatalf("Could not create create database request: %q", err)
return nil, fmt.Errorf("could not create create database request: %q", err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatalf("Could not create database: %q", err)
return nil, fmt.Errorf("could not create database: %q", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated {
bs, _ := ioutil.ReadAll(resp.Body)
t.Fatalf("Failed to create database: %s %s\n", resp.Status, string(bs))
return nil, fmt.Errorf("failed to create database: %s %s\n", resp.Status, string(bs))
}
}
{
req, err := http.NewRequest("PUT", fmt.Sprintf("%s/_config/admins/admin", retAddress), strings.NewReader(`"admin"`))
u := c.baseURL
u.Path = fmt.Sprintf("_config/admins/%s", c.username)
req, err := http.NewRequest("PUT", u.String(), strings.NewReader(fmt.Sprintf(`"%s"`, c.password)))
if err != nil {
t.Fatalf("Could not create admin user request: %q", err)
return nil, fmt.Errorf("Could not create admin user request: %q", err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatalf("Could not create admin user: %q", err)
return nil, fmt.Errorf("Could not create admin user: %q", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
bs, _ := ioutil.ReadAll(resp.Body)
t.Fatalf("Failed to create admin user: %s %s\n", resp.Status, string(bs))
return nil, fmt.Errorf("Failed to create admin user: %s %s\n", resp.Status, string(bs))
}
}
return cleanup, retAddress + "/" + dbName, "admin", "admin"
return c, nil
}

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"math/rand"
"net/http"
"net/url"
"os"
"testing"
"time"
@@ -14,7 +15,6 @@ import (
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/hashicorp/vault/sdk/helper/logging"
"github.com/hashicorp/vault/sdk/physical"
"github.com/ory/dockertest"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
@@ -24,10 +24,10 @@ import (
)
func TestDynamoDBBackend(t *testing.T) {
cleanup, endpoint, credsProvider := prepareDynamoDBTestContainer(t)
cleanup, svccfg := prepareDynamoDBTestContainer(t)
defer cleanup()
creds, err := credsProvider.Get()
creds, err := svccfg.Credentials.Get()
if err != nil {
t.Fatalf("err: %v", err)
}
@@ -38,8 +38,8 @@ func TestDynamoDBBackend(t *testing.T) {
}
awsSession, err := session.NewSession(&aws.Config{
Credentials: credsProvider,
Endpoint: aws.String(endpoint),
Credentials: svccfg.Credentials,
Endpoint: aws.String(svccfg.URL().String()),
Region: aws.String(region),
})
if err != nil {
@@ -65,7 +65,7 @@ func TestDynamoDBBackend(t *testing.T) {
"session_token": creds.SessionToken,
"table": table,
"region": region,
"endpoint": endpoint,
"endpoint": svccfg.URL().String(),
}, logger)
if err != nil {
t.Fatalf("err: %s", err)
@@ -114,10 +114,10 @@ func TestDynamoDBBackend(t *testing.T) {
}
func TestDynamoDBHABackend(t *testing.T) {
cleanup, endpoint, credsProvider := prepareDynamoDBTestContainer(t)
cleanup, svccfg := prepareDynamoDBTestContainer(t)
defer cleanup()
creds, err := credsProvider.Get()
creds, err := svccfg.Credentials.Get()
if err != nil {
t.Fatalf("err: %v", err)
}
@@ -128,8 +128,8 @@ func TestDynamoDBHABackend(t *testing.T) {
}
awsSession, err := session.NewSession(&aws.Config{
Credentials: credsProvider,
Endpoint: aws.String(endpoint),
Credentials: svccfg.Credentials,
Endpoint: aws.String(svccfg.URL().String()),
Region: aws.String(region),
})
if err != nil {
@@ -154,7 +154,7 @@ func TestDynamoDBHABackend(t *testing.T) {
"session_token": creds.SessionToken,
"table": table,
"region": region,
"endpoint": endpoint,
"endpoint": svccfg.URL().String(),
}
b, err := NewDynamoDBBackend(config, logger)
@@ -362,43 +362,57 @@ func testDynamoDBLockRenewal(t *testing.T, ha physical.HABackend) {
newLock.Unlock()
}
func prepareDynamoDBTestContainer(t *testing.T) (cleanup func(), retAddress string, creds *credentials.Credentials) {
type Config struct {
docker.ServiceURL
Credentials *credentials.Credentials
}
var _ docker.ServiceConfig = &Config{}
func prepareDynamoDBTestContainer(t *testing.T) (func(), *Config) {
// If environment variable is set, assume caller wants to target a real
// DynamoDB.
if os.Getenv("AWS_DYNAMODB_ENDPOINT") != "" {
return func() {}, os.Getenv("AWS_DYNAMODB_ENDPOINT"), credentials.NewEnvCredentials()
if endpoint := os.Getenv("AWS_DYNAMODB_ENDPOINT"); endpoint != "" {
s, err := docker.NewServiceURLParse(endpoint)
if err != nil {
t.Fatal(err)
}
return func() {}, &Config{*s, credentials.NewEnvCredentials()}
}
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
}
resource, err := pool.Run("cnadiminti/dynamodb-local", "latest", []string{})
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "cnadiminti/dynamodb-local",
ImageTag: "latest",
ContainerName: "dynamodb",
Ports: []string{"8000/tcp"},
})
if err != nil {
t.Fatalf("Could not start local DynamoDB: %s", err)
}
retAddress = "http://localhost:" + resource.GetPort("8000/tcp")
cleanup = func() {
docker.CleanupResource(t, pool, resource)
svc, err := runner.StartService(context.Background(), connectDynamoDB)
if err != nil {
t.Fatalf("Could not start local DynamoDB: %s", err)
}
// exponential backoff-retry, because the DynamoDB may not be able to accept
// connections yet
if err := pool.Retry(func() error {
var err error
resp, err := http.Get(retAddress)
if err != nil {
return err
}
if resp.StatusCode != 400 {
return fmt.Errorf("expected DynamoDB to return status code 400, got (%s) instead", resp.Status)
}
return nil
}); err != nil {
cleanup()
t.Fatalf("Could not connect to docker: %s", err)
}
return cleanup, retAddress, credentials.NewStaticCredentials("fake", "fake", "")
return svc.Cleanup, svc.Config.(*Config)
}
func connectDynamoDB(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
u := url.URL{
Scheme: "http",
Host: fmt.Sprintf("%s:%d", host, port),
}
resp, err := http.Get(u.String())
if err != nil {
return nil, err
}
if resp.StatusCode != 400 {
return nil, err
}
return &Config{
ServiceURL: *docker.NewServiceURL(u),
Credentials: credentials.NewStaticCredentials("fake", "fake", ""),
}, nil
}

View File

@@ -162,7 +162,7 @@ func TestMySQLHABackend(t *testing.T) {
// https://github.com/hashicorp/vault/issues/8203 and patched in
// https://github.com/hashicorp/vault/pull/8229
func TestMySQLHABackend_LockFailPanic(t *testing.T) {
cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret")
cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret")
cfg, err := mysql.ParseDSN(connURL)
if err != nil {

View File

@@ -2,86 +2,27 @@ package cassandra
import (
"context"
"fmt"
"os"
"strconv"
"strings"
"testing"
"time"
"github.com/gocql/gocql"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/hashicorp/vault/helper/testhelpers/cassandra"
"github.com/hashicorp/vault/sdk/database/dbplugin"
"github.com/ory/dockertest"
)
func prepareCassandraTestContainer(t *testing.T) (func(), string, int) {
if os.Getenv("CASSANDRA_HOST") != "" {
return func() {}, os.Getenv("CASSANDRA_HOST"), 0
}
pool, err := dockertest.NewPool("")
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
}
cwd, _ := os.Getwd()
cassandraMountPath := fmt.Sprintf("%s/test-fixtures/:/etc/cassandra/", cwd)
ro := &dockertest.RunOptions{
Repository: "cassandra",
Tag: "latest",
Env: []string{"CASSANDRA_BROADCAST_ADDRESS=127.0.0.1"},
Mounts: []string{cassandraMountPath},
}
resource, err := pool.RunWithOptions(ro)
if err != nil {
t.Fatalf("Could not start local cassandra docker container: %s", err)
}
cleanup := func() {
docker.CleanupResource(t, pool, resource)
}
port, _ := strconv.Atoi(resource.GetPort("9042/tcp"))
address := fmt.Sprintf("127.0.0.1:%d", port)
// exponential backoff-retry
if err = pool.Retry(func() error {
clusterConfig := gocql.NewCluster(address)
clusterConfig.Authenticator = gocql.PasswordAuthenticator{
Username: "cassandra",
Password: "cassandra",
}
clusterConfig.ProtoVersion = 4
clusterConfig.Port = port
session, err := clusterConfig.CreateSession()
if err != nil {
return errwrap.Wrapf("error creating session: {{err}}", err)
}
defer session.Close()
return nil
}); err != nil {
cleanup()
t.Fatalf("Could not connect to cassandra docker container: %s", err)
}
return cleanup, address, port
}
func TestCassandra_Initialize(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
cleanup, address, port := prepareCassandraTestContainer(t)
defer cleanup()
func getCassandra(t *testing.T, protocolVersion interface{}) (*Cassandra, func()) {
cleanup, connURL := cassandra.PrepareTestContainer(t, "latest")
pieces := strings.Split(connURL, ":")
connectionDetails := map[string]interface{}{
"hosts": address,
"port": port,
"hosts": connURL,
"port": pieces[1],
"username": "cassandra",
"password": "cassandra",
"protocol_version": 4,
"protocol_version": protocolVersion,
"connect_timeout": "20s",
}
db := new()
@@ -93,48 +34,26 @@ func TestCassandra_Initialize(t *testing.T) {
if !db.Initialized {
t.Fatal("Database should be initialized")
}
return db, cleanup
}
err = db.Close()
func TestCassandra_Initialize(t *testing.T) {
db, cleanup := getCassandra(t, 4)
defer cleanup()
err := db.Close()
if err != nil {
t.Fatalf("err: %s", err)
}
// test a string protocol
connectionDetails = map[string]interface{}{
"hosts": address,
"port": strconv.Itoa(port),
"username": "cassandra",
"password": "cassandra",
"protocol_version": "4",
}
_, err = db.Init(context.Background(), connectionDetails, true)
if err != nil {
t.Fatalf("err: %s", err)
}
db, cleanup = getCassandra(t, "4")
defer cleanup()
}
func TestCassandra_CreateUser(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
cleanup, address, port := prepareCassandraTestContainer(t)
db, cleanup := getCassandra(t, 4)
defer cleanup()
connectionDetails := map[string]interface{}{
"hosts": address,
"port": port,
"username": "cassandra",
"password": "cassandra",
"protocol_version": 4,
}
db := new()
_, err := db.Init(context.Background(), connectionDetails, true)
if err != nil {
t.Fatalf("err: %s", err)
}
statements := dbplugin.Statements{
Creation: []string{testCassandraRole},
}
@@ -149,32 +68,15 @@ func TestCassandra_CreateUser(t *testing.T) {
t.Fatalf("err: %s", err)
}
if err := testCredsExist(t, address, port, username, password); err != nil {
if err := testCredsExist(db.Hosts, db.Port, username, password); err != nil {
t.Fatalf("Could not connect with new credentials: %s", err)
}
}
func TestMyCassandra_RenewUser(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
cleanup, address, port := prepareCassandraTestContainer(t)
db, cleanup := getCassandra(t, 4)
defer cleanup()
connectionDetails := map[string]interface{}{
"hosts": address,
"port": port,
"username": "cassandra",
"password": "cassandra",
"protocol_version": 4,
}
db := new()
_, err := db.Init(context.Background(), connectionDetails, true)
if err != nil {
t.Fatalf("err: %s", err)
}
statements := dbplugin.Statements{
Creation: []string{testCassandraRole},
}
@@ -189,7 +91,7 @@ func TestMyCassandra_RenewUser(t *testing.T) {
t.Fatalf("err: %s", err)
}
if err := testCredsExist(t, address, port, username, password); err != nil {
if err := testCredsExist(db.Hosts, db.Port, username, password); err != nil {
t.Fatalf("Could not connect with new credentials: %s", err)
}
@@ -200,26 +102,9 @@ func TestMyCassandra_RenewUser(t *testing.T) {
}
func TestCassandra_RevokeUser(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
cleanup, address, port := prepareCassandraTestContainer(t)
db, cleanup := getCassandra(t, 4)
defer cleanup()
connectionDetails := map[string]interface{}{
"hosts": address,
"port": port,
"username": "cassandra",
"password": "cassandra",
"protocol_version": 4,
}
db := new()
_, err := db.Init(context.Background(), connectionDetails, true)
if err != nil {
t.Fatalf("err: %s", err)
}
statements := dbplugin.Statements{
Creation: []string{testCassandraRole},
}
@@ -234,7 +119,7 @@ func TestCassandra_RevokeUser(t *testing.T) {
t.Fatalf("err: %s", err)
}
if err = testCredsExist(t, address, port, username, password); err != nil {
if err = testCredsExist(db.Hosts, db.Port, username, password); err != nil {
t.Fatalf("Could not connect with new credentials: %s", err)
}
@@ -244,36 +129,16 @@ func TestCassandra_RevokeUser(t *testing.T) {
t.Fatalf("err: %s", err)
}
if err = testCredsExist(t, address, port, username, password); err == nil {
if err = testCredsExist(db.Hosts, db.Port, username, password); err == nil {
t.Fatal("Credentials were not revoked")
}
}
func TestCassandra_RotateRootCredentials(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
cleanup, address, port := prepareCassandraTestContainer(t)
db, cleanup := getCassandra(t, 4)
defer cleanup()
connectionDetails := map[string]interface{}{
"hosts": address,
"port": port,
"username": "cassandra",
"password": "cassandra",
"protocol_version": 4,
}
db := new()
connProducer := db.cassandraConnectionProducer
_, err := db.Init(context.Background(), connectionDetails, true)
if err != nil {
t.Fatalf("err: %s", err)
}
if !connProducer.Initialized {
if !db.cassandraConnectionProducer.Initialized {
t.Fatal("Database should be initialized")
}
@@ -291,7 +156,7 @@ func TestCassandra_RotateRootCredentials(t *testing.T) {
}
}
func testCredsExist(t testing.TB, address string, port int, username, password string) error {
func testCredsExist(address string, port int, username, password string) error {
clusterConfig := gocql.NewCluster(address)
clusterConfig.Authenticator = gocql.PasswordAuthenticator{
Username: username,

View File

@@ -3,8 +3,10 @@ package influxdb
import (
"context"
"fmt"
"net/url"
"os"
"strconv"
"strings"
"testing"
"time"
@@ -12,77 +14,90 @@ import (
"github.com/hashicorp/vault/helper/testhelpers/docker"
"github.com/hashicorp/vault/sdk/database/dbplugin"
influx "github.com/influxdata/influxdb/client/v2"
"github.com/ory/dockertest"
)
const testInfluxRole = `CREATE USER "{{username}}" WITH PASSWORD '{{password}}';GRANT ALL ON "vault" TO "{{username}}";`
func prepareInfluxdbTestContainer(t *testing.T) (func(), string, int) {
if os.Getenv("INFLUXDB_HOST") != "" {
return func() {}, os.Getenv("INFLUXDB_HOST"), 0
type Config struct {
docker.ServiceURL
Username string
Password string
}
var _ docker.ServiceConfig = &Config{}
func (c *Config) apiConfig() influx.HTTPConfig {
return influx.HTTPConfig{
Addr: c.URL().String(),
Username: c.Username,
Password: c.Password,
}
}
func (c *Config) connectionParams() map[string]interface{} {
pieces := strings.Split(c.Address(), ":")
port, _ := strconv.Atoi(pieces[1])
return map[string]interface{}{
"host": pieces[0],
"port": port,
"username": c.Username,
"password": c.Password,
}
}
func prepareInfluxdbTestContainer(t *testing.T) (func(), *Config) {
c := &Config{
Username: "influx-root",
Password: "influx-root",
}
if host := os.Getenv("INFLUXDB_HOST"); host != "" {
c.ServiceURL = *docker.NewServiceURL(url.URL{Scheme: "http", Host: host})
return func() {}, c
}
pool, err := dockertest.NewPool("")
runner, err := docker.NewServiceRunner(docker.RunOptions{
ImageRepo: "influxdb",
ImageTag: "alpine",
Env: []string{
"INFLUXDB_DB=vault",
"INFLUXDB_ADMIN_USER=" + c.Username,
"INFLUXDB_ADMIN_PASSWORD=" + c.Password,
"INFLUXDB_HTTP_AUTH_ENABLED=true"},
Ports: []string{"8086/tcp"},
})
if err != nil {
t.Fatalf("Failed to connect to docker: %s", err)
t.Fatalf("Could not start docker InfluxDB: %s", err)
}
ro := &dockertest.RunOptions{
Repository: "influxdb",
Tag: "alpine",
Env: []string{"INFLUXDB_DB=vault", "INFLUXDB_ADMIN_USER=influx-root", "INFLUXDB_ADMIN_PASSWORD=influx-root", "INFLUXDB_HTTP_AUTH_ENABLED=true"},
}
resource, err := pool.RunWithOptions(ro)
if err != nil {
t.Fatalf("Could not start local influxdb docker container: %s", err)
}
cleanup := func() {
docker.CleanupResource(t, pool, resource)
}
port, _ := strconv.Atoi(resource.GetPort("8086/tcp"))
address := "127.0.0.1"
// exponential backoff-retry
if err = pool.Retry(func() error {
cli, err := influx.NewHTTPClient(influx.HTTPConfig{
Addr: fmt.Sprintf("http://%s:%d", address, port),
Username: "influx-root",
Password: "influx-root",
svc, err := runner.StartService(context.Background(), func(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
c.ServiceURL = *docker.NewServiceURL(url.URL{
Scheme: "http",
Host: fmt.Sprintf("%s:%d", host, port),
})
cli, err := influx.NewHTTPClient(c.apiConfig())
if err != nil {
return errwrap.Wrapf("Error creating InfluxDB Client: ", err)
return nil, errwrap.Wrapf("error creating InfluxDB client: {{err}}", err)
}
defer cli.Close()
_, _, err = cli.Ping(1)
if err != nil {
return errwrap.Wrapf("error checking cluster status: {{err}}", err)
return nil, errwrap.Wrapf("error checking cluster status: {{err}}", err)
}
return nil
}); err != nil {
cleanup()
t.Fatalf("Could not connect to influxdb docker container: %s", err)
return c, nil
})
if err != nil {
t.Fatalf("Could not start docker InfluxDB: %s", err)
}
return cleanup, address, port
return svc.Cleanup, svc.Config.(*Config)
}
func TestInfluxdb_Initialize(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
cleanup, address, port := prepareInfluxdbTestContainer(t)
cleanup, config := prepareInfluxdbTestContainer(t)
defer cleanup()
connectionDetails := map[string]interface{}{
"host": address,
"port": port,
"username": "influx-root",
"password": "influx-root",
}
db := new()
_, err := db.Init(context.Background(), connectionDetails, true)
_, err := db.Init(context.Background(), config.connectionParams(), true)
if err != nil {
t.Fatalf("err: %s", err)
}
@@ -96,36 +111,20 @@ func TestInfluxdb_Initialize(t *testing.T) {
t.Fatalf("err: %s", err)
}
// test a string protocol
connectionDetails = map[string]interface{}{
"host": address,
"port": strconv.Itoa(port),
"username": "influx-root",
"password": "influx-root",
}
_, err = db.Init(context.Background(), connectionDetails, true)
connectionParams := config.connectionParams()
connectionParams["port"] = strconv.Itoa(connectionParams["port"].(int))
_, err = db.Init(context.Background(), connectionParams, true)
if err != nil {
t.Fatalf("err: %s", err)
}
}
func TestInfluxdb_CreateUser(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
cleanup, address, port := prepareInfluxdbTestContainer(t)
cleanup, config := prepareInfluxdbTestContainer(t)
defer cleanup()
connectionDetails := map[string]interface{}{
"host": address,
"port": port,
"username": "influx-root",
"password": "influx-root",
}
db := new()
_, err := db.Init(context.Background(), connectionDetails, true)
_, err := db.Init(context.Background(), config.connectionParams(), true)
if err != nil {
t.Fatalf("err: %s", err)
}
@@ -144,27 +143,18 @@ func TestInfluxdb_CreateUser(t *testing.T) {
t.Fatalf("err: %s", err)
}
if err := testCredsExist(t, address, port, username, password); err != nil {
config.Username, config.Password = username, password
if err := testCredsExist(t, config); err != nil {
t.Fatalf("Could not connect with new credentials: %s", err)
}
}
func TestMyInfluxdb_RenewUser(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
cleanup, address, port := prepareInfluxdbTestContainer(t)
cleanup, config := prepareInfluxdbTestContainer(t)
defer cleanup()
connectionDetails := map[string]interface{}{
"host": address,
"port": port,
"username": "influx-root",
"password": "influx-root",
}
db := new()
_, err := db.Init(context.Background(), connectionDetails, true)
_, err := db.Init(context.Background(), config.connectionParams(), true)
if err != nil {
t.Fatalf("err: %s", err)
}
@@ -183,7 +173,8 @@ func TestMyInfluxdb_RenewUser(t *testing.T) {
t.Fatalf("err: %s", err)
}
if err := testCredsExist(t, address, port, username, password); err != nil {
config.Username, config.Password = username, password
if err = testCredsExist(t, config); err != nil {
t.Fatalf("Could not connect with new credentials: %s", err)
}
@@ -197,20 +188,11 @@ func TestMyInfluxdb_RenewUser(t *testing.T) {
// deleted externally. Guards against a panic, see
// https://github.com/hashicorp/vault/issues/6734
func TestInfluxdb_RevokeDeletedUser(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
cleanup, address, port := prepareInfluxdbTestContainer(t)
connectionDetails := map[string]interface{}{
"host": address,
"port": port,
"username": "influx-root",
"password": "influx-root",
}
cleanup, config := prepareInfluxdbTestContainer(t)
defer cleanup()
db := new()
_, err := db.Init(context.Background(), connectionDetails, true)
_, err := db.Init(context.Background(), config.connectionParams(), true)
if err != nil {
t.Fatalf("err: %s", err)
}
@@ -229,7 +211,8 @@ func TestInfluxdb_RevokeDeletedUser(t *testing.T) {
t.Fatalf("err: %s", err)
}
if err = testCredsExist(t, address, port, username, password); err != nil {
config.Username, config.Password = username, password
if err = testCredsExist(t, config); err != nil {
t.Fatalf("Could not connect with new credentials: %s", err)
}
@@ -244,21 +227,11 @@ func TestInfluxdb_RevokeDeletedUser(t *testing.T) {
}
func TestInfluxdb_RevokeUser(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
cleanup, address, port := prepareInfluxdbTestContainer(t)
cleanup, config := prepareInfluxdbTestContainer(t)
defer cleanup()
connectionDetails := map[string]interface{}{
"host": address,
"port": port,
"username": "influx-root",
"password": "influx-root",
}
db := new()
_, err := db.Init(context.Background(), connectionDetails, true)
_, err := db.Init(context.Background(), config.connectionParams(), true)
if err != nil {
t.Fatalf("err: %s", err)
}
@@ -277,39 +250,30 @@ func TestInfluxdb_RevokeUser(t *testing.T) {
t.Fatalf("err: %s", err)
}
if err = testCredsExist(t, address, port, username, password); err != nil {
config.Username, config.Password = username, password
if err = testCredsExist(t, config); err != nil {
t.Fatalf("Could not connect with new credentials: %s", err)
}
// Test default revoke statements
err = db.RevokeUser(context.Background(), statements, username)
err = db.RevokeUser(context.Background(), dbplugin.Statements{}, username)
if err != nil {
t.Fatalf("err: %s", err)
}
if err = testCredsExist(t, address, port, username, password); err == nil {
if err = testCredsExist(t, config); err == nil {
t.Fatal("Credentials were not revoked")
}
}
func TestInfluxdb_RotateRootCredentials(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}
cleanup, address, port := prepareInfluxdbTestContainer(t)
cleanup, config := prepareInfluxdbTestContainer(t)
defer cleanup()
connectionDetails := map[string]interface{}{
"host": address,
"port": port,
"username": "influx-root",
"password": "influx-root",
}
db := new()
connProducer := db.influxdbConnectionProducer
_, err := db.Init(context.Background(), connectionDetails, true)
_, err := db.Init(context.Background(), config.connectionParams(), true)
if err != nil {
t.Fatalf("err: %s", err)
}
@@ -332,12 +296,8 @@ func TestInfluxdb_RotateRootCredentials(t *testing.T) {
}
}
func testCredsExist(t testing.TB, address string, port int, username, password string) error {
cli, err := influx.NewHTTPClient(influx.HTTPConfig{
Addr: fmt.Sprintf("http://%s:%d", address, port),
Username: username,
Password: password,
})
func testCredsExist(t testing.TB, c *Config) error {
cli, err := influx.NewHTTPClient(c.apiConfig())
if err != nil {
return errwrap.Wrapf("Error creating InfluxDB Client: ", err)
}

View File

@@ -18,7 +18,7 @@ import (
var _ dbplugin.Database = (*MySQL)(nil)
func TestMySQL_Initialize(t *testing.T) {
cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret")
cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret")
defer cleanup()
connectionDetails := map[string]interface{}{
@@ -75,7 +75,7 @@ func TestMySQL_CreateUser(t *testing.T) {
t.Run("non-legacy", func(t *testing.T) {
// Shared test container for speed - there should not be any overlap between the tests
cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret")
cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret")
defer cleanup()
connectionDetails := map[string]interface{}{
@@ -93,7 +93,7 @@ func TestMySQL_CreateUser(t *testing.T) {
t.Run("legacy", func(t *testing.T) {
// Shared test container for speed - there should not be any overlap between the tests
cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, true, "secret")
cleanup, connURL := mysqlhelper.PrepareTestContainer(t, true, "secret")
defer cleanup()
connectionDetails := map[string]interface{}{
@@ -204,7 +204,7 @@ func TestMySQL_RotateRootCredentials(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret")
cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret")
defer cleanup()
connURL = strings.Replace(connURL, "root:secret", `{{username}}:{{password}}`, -1)
@@ -266,7 +266,7 @@ func TestMySQL_RevokeUser(t *testing.T) {
}
// Shared test container for speed - there should not be any overlap between the tests
cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret")
cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret")
defer cleanup()
connectionDetails := map[string]interface{}{
@@ -344,7 +344,7 @@ func TestMySQL_SetCredentials(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, "secret")
cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, "secret")
defer cleanup()
// create the database user and verify we can access
@@ -414,7 +414,7 @@ func TestMySQL_SetCredentials(t *testing.T) {
func TestMySQL_Initialize_ReservedChars(t *testing.T) {
pw := "#secret!%25#{@}"
cleanup, connURL := mysqlhelper.PrepareMySQLTestContainer(t, false, pw)
cleanup, connURL := mysqlhelper.PrepareTestContainer(t, false, pw)
defer cleanup()
// Revert password set to test replacement by db.Init

View File

@@ -122,6 +122,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=

View File

@@ -49,16 +49,12 @@ func testConsulServiceRegistrationConfig(t *testing.T, conf *consulConf) *servic
// TestConsul_ServiceRegistration tests whether consul ServiceRegistration works
func TestConsul_ServiceRegistration(t *testing.T) {
// Prepare a docker-based consul instance
cleanup, addr, token := consul.PrepareTestContainer(t, "")
cleanup, config := consul.PrepareTestContainer(t, "")
defer cleanup()
// Create a consul client
cfg := api.DefaultConfig()
cfg.Address = addr
cfg.Token = token
client, err := api.NewClient(cfg)
client, err := api.NewClient(config.APIConfig())
if err != nil {
t.Fatal(err)
}
@@ -93,8 +89,8 @@ func TestConsul_ServiceRegistration(t *testing.T) {
// Create a ServiceRegistration that points to our consul instance
logger := logging.NewVaultLogger(log.Trace)
sd, err := NewServiceRegistration(map[string]string{
"address": addr,
"token": token,
"address": config.Address(),
"token": config.Token,
}, logger, sr.State{})
if err != nil {
t.Fatal(err)

View File

@@ -127,6 +127,7 @@ func testRaftHANewCluster(t *testing.T, bundler teststorage.PhysicalBackendBundl
}
func TestRaft_HA_ExistingCluster(t *testing.T) {
t.Parallel()
conf := vault.CoreConfig{
DisablePerformanceStandby: true,
}

View File

@@ -35,6 +35,7 @@ func raftCluster(t testing.TB) *vault.TestCluster {
}
func TestRaft_Retry_Join(t *testing.T) {
t.Parallel()
var conf vault.CoreConfig
var opts = vault.TestClusterOptions{HandlerFunc: vaulthttp.Handler}
teststorage.RaftBackendSetup(&conf, &opts)
@@ -98,6 +99,7 @@ func TestRaft_Retry_Join(t *testing.T) {
}
func TestRaft_Join(t *testing.T) {
t.Parallel()
var conf vault.CoreConfig
var opts = vault.TestClusterOptions{HandlerFunc: vaulthttp.Handler}
teststorage.RaftBackendSetup(&conf, &opts)
@@ -160,6 +162,7 @@ func TestRaft_Join(t *testing.T) {
}
func TestRaft_RemovePeer(t *testing.T) {
t.Parallel()
cluster := raftCluster(t)
defer cluster.Cleanup()
@@ -202,6 +205,7 @@ func TestRaft_RemovePeer(t *testing.T) {
}
func TestRaft_Configuration(t *testing.T) {
t.Parallel()
cluster := raftCluster(t)
defer cluster.Cleanup()
@@ -248,6 +252,7 @@ func TestRaft_Configuration(t *testing.T) {
}
func TestRaft_ShamirUnseal(t *testing.T) {
t.Parallel()
cluster := raftCluster(t)
defer cluster.Cleanup()
@@ -259,6 +264,7 @@ func TestRaft_ShamirUnseal(t *testing.T) {
}
func TestRaft_SnapshotAPI(t *testing.T) {
t.Parallel()
cluster := raftCluster(t)
defer cluster.Cleanup()
@@ -691,6 +697,7 @@ func TestRaft_SnapshotAPI_RekeyRotate_Forward(t *testing.T) {
}
func TestRaft_SnapshotAPI_DifferentCluster(t *testing.T) {
t.Parallel()
cluster := raftCluster(t)
defer cluster.Cleanup()

View File

@@ -23,6 +23,7 @@ import (
// migration, using the pre-1.4 method of bring down the whole cluster to do
// the migration.
func TestSealMigration_TransitToShamir_Pre14(t *testing.T) {
t.Parallel()
// Note that we do not test integrated raft storage since this is
// a pre-1.4 test.
testVariousBackends(t, testSealMigrationTransitToShamir_Pre14, basePort_TransitToShamir_Pre14, false)

View File

@@ -92,6 +92,7 @@ func testVariousBackends(t *testing.T, tf testFunc, basePort int, includeRaft bo
// migration, using the pre-1.4 method of bring down the whole cluster to do
// the migration.
func TestSealMigration_ShamirToTransit_Pre14(t *testing.T) {
t.Parallel()
// Note that we do not test integrated raft storage since this is
// a pre-1.4 test.
testVariousBackends(t, testSealMigrationShamirToTransit_Pre14, basePort_ShamirToTransit_Pre14, false)
@@ -192,6 +193,7 @@ func migrateFromShamirToTransit_Pre14(t *testing.T, logger hclog.Logger, storage
// migration, using the post-1.4 method of bring individual nodes in the cluster
// to do the migration.
func TestSealMigration_ShamirToTransit_Post14(t *testing.T) {
t.Parallel()
testVariousBackends(t, testSealMigrationShamirToTransit_Post14, basePort_ShamirToTransit_Post14, true)
}
@@ -259,6 +261,7 @@ func migrateFromShamirToTransit_Post14(t *testing.T, logger hclog.Logger, storag
// migration, using the post-1.4 method of bring individual nodes in the
// cluster to do the migration.
func TestSealMigration_TransitToShamir_Post14(t *testing.T) {
t.Parallel()
testVariousBackends(t, testSealMigrationTransitToShamir_Post14, basePort_TransitToShamir_Post14, true)
}

View File

@@ -4,7 +4,6 @@ import (
"crypto/rand"
"crypto/rsa"
"encoding/json"
"fmt"
"testing"
"time"
@@ -254,7 +253,7 @@ func TestOIDC_Path_OIDCKeyKey(t *testing.T) {
Storage: storage,
})
expectSuccess(t, resp, err)
fmt.Printf("resp is:\n%#v", resp)
//fmt.Printf("resp is:\n%#v", resp)
// Delete test-key -- should fail because test-role depends on test-key
resp, err = c.identityStore.HandleRequest(ctx, &logical.Request{

22
vendor/github.com/cenkalti/backoff/v3/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,22 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe

10
vendor/github.com/cenkalti/backoff/v3/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,10 @@
language: go
go:
- 1.7
- 1.x
- tip
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
script:
- $HOME/gopath/bin/goveralls -service=travis-ci

20
vendor/github.com/cenkalti/backoff/v3/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2014 Cenk Altı
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

30
vendor/github.com/cenkalti/backoff/v3/README.md generated vendored Normal file
View File

@@ -0,0 +1,30 @@
# Exponential Backoff [![GoDoc][godoc image]][godoc] [![Build Status][travis image]][travis] [![Coverage Status][coveralls image]][coveralls]
This is a Go port of the exponential backoff algorithm from [Google's HTTP Client Library for Java][google-http-java-client].
[Exponential backoff][exponential backoff wiki]
is an algorithm that uses feedback to multiplicatively decrease the rate of some process,
in order to gradually find an acceptable rate.
The retries exponentially increase and stop increasing when a certain threshold is met.
## Usage
See https://godoc.org/github.com/cenkalti/backoff#pkg-examples
## Contributing
* I would like to keep this library as small as possible.
* Please don't send a PR without opening an issue and discussing it first.
* If proposed change is not a common use case, I will probably not accept it.
[godoc]: https://godoc.org/github.com/cenkalti/backoff
[godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png
[travis]: https://travis-ci.org/cenkalti/backoff
[travis image]: https://travis-ci.org/cenkalti/backoff.png?branch=master
[coveralls]: https://coveralls.io/github/cenkalti/backoff?branch=master
[coveralls image]: https://coveralls.io/repos/github/cenkalti/backoff/badge.svg?branch=master
[google-http-java-client]: https://github.com/google/google-http-java-client/blob/da1aa993e90285ec18579f1553339b00e19b3ab5/google-http-client/src/main/java/com/google/api/client/util/ExponentialBackOff.java
[exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff
[advanced example]: https://godoc.org/github.com/cenkalti/backoff#example_

66
vendor/github.com/cenkalti/backoff/v3/backoff.go generated vendored Normal file
View File

@@ -0,0 +1,66 @@
// Package backoff implements backoff algorithms for retrying operations.
//
// Use Retry function for retrying operations that may fail.
// If Retry does not meet your needs,
// copy/paste the function into your project and modify as you wish.
//
// There is also Ticker type similar to time.Ticker.
// You can use it if you need to work with channels.
//
// See Examples section below for usage examples.
package backoff
import "time"
// BackOff is a backoff policy for retrying an operation.
type BackOff interface {
// NextBackOff returns the duration to wait before retrying the operation,
// or backoff. Stop to indicate that no more retries should be made.
//
// Example usage:
//
// duration := backoff.NextBackOff();
// if (duration == backoff.Stop) {
// // Do not retry operation.
// } else {
// // Sleep for duration and retry operation.
// }
//
NextBackOff() time.Duration
// Reset to initial state.
Reset()
}
// Stop indicates that no more retries should be made for use in NextBackOff().
const Stop time.Duration = -1
// ZeroBackOff is a fixed backoff policy whose backoff time is always zero,
// meaning that the operation is retried immediately without waiting, indefinitely.
type ZeroBackOff struct{}
func (b *ZeroBackOff) Reset() {}
func (b *ZeroBackOff) NextBackOff() time.Duration { return 0 }
// StopBackOff is a fixed backoff policy that always returns backoff.Stop for
// NextBackOff(), meaning that the operation should never be retried.
type StopBackOff struct{}
func (b *StopBackOff) Reset() {}
func (b *StopBackOff) NextBackOff() time.Duration { return Stop }
// ConstantBackOff is a backoff policy that always returns the same backoff delay.
// This is in contrast to an exponential backoff policy,
// which returns a delay that grows longer as you call NextBackOff() over and over again.
type ConstantBackOff struct {
Interval time.Duration
}
func (b *ConstantBackOff) Reset() {}
func (b *ConstantBackOff) NextBackOff() time.Duration { return b.Interval }
func NewConstantBackOff(d time.Duration) *ConstantBackOff {
return &ConstantBackOff{Interval: d}
}

63
vendor/github.com/cenkalti/backoff/v3/context.go generated vendored Normal file
View File

@@ -0,0 +1,63 @@
package backoff
import (
"context"
"time"
)
// BackOffContext is a backoff policy that stops retrying after the context
// is canceled.
type BackOffContext interface {
BackOff
Context() context.Context
}
type backOffContext struct {
BackOff
ctx context.Context
}
// WithContext returns a BackOffContext with context ctx
//
// ctx must not be nil
func WithContext(b BackOff, ctx context.Context) BackOffContext {
if ctx == nil {
panic("nil context")
}
if b, ok := b.(*backOffContext); ok {
return &backOffContext{
BackOff: b.BackOff,
ctx: ctx,
}
}
return &backOffContext{
BackOff: b,
ctx: ctx,
}
}
func ensureContext(b BackOff) BackOffContext {
if cb, ok := b.(BackOffContext); ok {
return cb
}
return WithContext(b, context.Background())
}
func (b *backOffContext) Context() context.Context {
return b.ctx
}
func (b *backOffContext) NextBackOff() time.Duration {
select {
case <-b.ctx.Done():
return Stop
default:
}
next := b.BackOff.NextBackOff()
if deadline, ok := b.ctx.Deadline(); ok && deadline.Sub(time.Now()) < next {
return Stop
}
return next
}

153
vendor/github.com/cenkalti/backoff/v3/exponential.go generated vendored Normal file
View File

@@ -0,0 +1,153 @@
package backoff
import (
"math/rand"
"time"
)
/*
ExponentialBackOff is a backoff implementation that increases the backoff
period for each retry attempt using a randomization function that grows exponentially.
NextBackOff() is calculated using the following formula:
randomized interval =
RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor])
In other words NextBackOff() will range between the randomization factor
percentage below and above the retry interval.
For example, given the following parameters:
RetryInterval = 2
RandomizationFactor = 0.5
Multiplier = 2
the actual backoff period used in the next retry attempt will range between 1 and 3 seconds,
multiplied by the exponential, that is, between 2 and 6 seconds.
Note: MaxInterval caps the RetryInterval and not the randomized interval.
If the time elapsed since an ExponentialBackOff instance is created goes past the
MaxElapsedTime, then the method NextBackOff() starts returning backoff.Stop.
The elapsed time can be reset by calling Reset().
Example: Given the following default arguments, for 10 tries the sequence will be,
and assuming we go over the MaxElapsedTime on the 10th try:
Request # RetryInterval (seconds) Randomized Interval (seconds)
1 0.5 [0.25, 0.75]
2 0.75 [0.375, 1.125]
3 1.125 [0.562, 1.687]
4 1.687 [0.8435, 2.53]
5 2.53 [1.265, 3.795]
6 3.795 [1.897, 5.692]
7 5.692 [2.846, 8.538]
8 8.538 [4.269, 12.807]
9 12.807 [6.403, 19.210]
10 19.210 backoff.Stop
Note: Implementation is not thread-safe.
*/
type ExponentialBackOff struct {
InitialInterval time.Duration
RandomizationFactor float64
Multiplier float64
MaxInterval time.Duration
// After MaxElapsedTime the ExponentialBackOff stops.
// It never stops if MaxElapsedTime == 0.
MaxElapsedTime time.Duration
Clock Clock
currentInterval time.Duration
startTime time.Time
}
// Clock is an interface that returns current time for BackOff.
type Clock interface {
Now() time.Time
}
// Default values for ExponentialBackOff.
const (
DefaultInitialInterval = 500 * time.Millisecond
DefaultRandomizationFactor = 0.5
DefaultMultiplier = 1.5
DefaultMaxInterval = 60 * time.Second
DefaultMaxElapsedTime = 15 * time.Minute
)
// NewExponentialBackOff creates an instance of ExponentialBackOff using default values.
func NewExponentialBackOff() *ExponentialBackOff {
b := &ExponentialBackOff{
InitialInterval: DefaultInitialInterval,
RandomizationFactor: DefaultRandomizationFactor,
Multiplier: DefaultMultiplier,
MaxInterval: DefaultMaxInterval,
MaxElapsedTime: DefaultMaxElapsedTime,
Clock: SystemClock,
}
b.Reset()
return b
}
type systemClock struct{}
func (t systemClock) Now() time.Time {
return time.Now()
}
// SystemClock implements Clock interface that uses time.Now().
var SystemClock = systemClock{}
// Reset the interval back to the initial retry interval and restarts the timer.
func (b *ExponentialBackOff) Reset() {
b.currentInterval = b.InitialInterval
b.startTime = b.Clock.Now()
}
// NextBackOff calculates the next backoff interval using the formula:
// Randomized interval = RetryInterval +/- (RandomizationFactor * RetryInterval)
func (b *ExponentialBackOff) NextBackOff() time.Duration {
// Make sure we have not gone over the maximum elapsed time.
if b.MaxElapsedTime != 0 && b.GetElapsedTime() > b.MaxElapsedTime {
return Stop
}
defer b.incrementCurrentInterval()
return getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval)
}
// GetElapsedTime returns the elapsed time since an ExponentialBackOff instance
// is created and is reset when Reset() is called.
//
// The elapsed time is computed using time.Now().UnixNano(). It is
// safe to call even while the backoff policy is used by a running
// ticker.
func (b *ExponentialBackOff) GetElapsedTime() time.Duration {
return b.Clock.Now().Sub(b.startTime)
}
// Increments the current interval by multiplying it with the multiplier.
func (b *ExponentialBackOff) incrementCurrentInterval() {
// Check for overflow, if overflow is detected set the current interval to the max interval.
if float64(b.currentInterval) >= float64(b.MaxInterval)/b.Multiplier {
b.currentInterval = b.MaxInterval
} else {
b.currentInterval = time.Duration(float64(b.currentInterval) * b.Multiplier)
}
}
// Returns a random value from the following interval:
// [randomizationFactor * currentInterval, randomizationFactor * currentInterval].
func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration {
var delta = randomizationFactor * float64(currentInterval)
var minInterval = float64(currentInterval) - delta
var maxInterval = float64(currentInterval) + delta
// Get a random value from the range [minInterval, maxInterval].
// The formula used below has a +1 because if the minInterval is 1 and the maxInterval is 3 then
// we want a 33% chance for selecting either 1, 2 or 3.
return time.Duration(minInterval + (random * (maxInterval - minInterval + 1)))
}

3
vendor/github.com/cenkalti/backoff/v3/go.mod generated vendored Normal file
View File

@@ -0,0 +1,3 @@
module github.com/cenkalti/backoff/v3
go 1.12

82
vendor/github.com/cenkalti/backoff/v3/retry.go generated vendored Normal file
View File

@@ -0,0 +1,82 @@
package backoff
import "time"
// An Operation is executing by Retry() or RetryNotify().
// The operation will be retried using a backoff policy if it returns an error.
type Operation func() error
// Notify is a notify-on-error function. It receives an operation error and
// backoff delay if the operation failed (with an error).
//
// NOTE that if the backoff policy stated to stop retrying,
// the notify function isn't called.
type Notify func(error, time.Duration)
// Retry the operation o until it does not return error or BackOff stops.
// o is guaranteed to be run at least once.
//
// If o returns a *PermanentError, the operation is not retried, and the
// wrapped error is returned.
//
// Retry sleeps the goroutine for the duration returned by BackOff after a
// failed operation returns.
func Retry(o Operation, b BackOff) error { return RetryNotify(o, b, nil) }
// RetryNotify calls notify function with the error and wait duration
// for each failed attempt before sleep.
func RetryNotify(operation Operation, b BackOff, notify Notify) error {
var err error
var next time.Duration
var t *time.Timer
cb := ensureContext(b)
b.Reset()
for {
if err = operation(); err == nil {
return nil
}
if permanent, ok := err.(*PermanentError); ok {
return permanent.Err
}
if next = cb.NextBackOff(); next == Stop {
return err
}
if notify != nil {
notify(err, next)
}
if t == nil {
t = time.NewTimer(next)
defer t.Stop()
} else {
t.Reset(next)
}
select {
case <-cb.Context().Done():
return err
case <-t.C:
}
}
}
// PermanentError signals that the operation should not be retried.
type PermanentError struct {
Err error
}
func (e *PermanentError) Error() string {
return e.Err.Error()
}
// Permanent wraps the given err in a *PermanentError.
func Permanent(err error) *PermanentError {
return &PermanentError{
Err: err,
}
}

82
vendor/github.com/cenkalti/backoff/v3/ticker.go generated vendored Normal file
View File

@@ -0,0 +1,82 @@
package backoff
import (
"sync"
"time"
)
// Ticker holds a channel that delivers `ticks' of a clock at times reported by a BackOff.
//
// Ticks will continue to arrive when the previous operation is still running,
// so operations that take a while to fail could run in quick succession.
type Ticker struct {
C <-chan time.Time
c chan time.Time
b BackOffContext
stop chan struct{}
stopOnce sync.Once
}
// NewTicker returns a new Ticker containing a channel that will send
// the time at times specified by the BackOff argument. Ticker is
// guaranteed to tick at least once. The channel is closed when Stop
// method is called or BackOff stops. It is not safe to manipulate the
// provided backoff policy (notably calling NextBackOff or Reset)
// while the ticker is running.
func NewTicker(b BackOff) *Ticker {
c := make(chan time.Time)
t := &Ticker{
C: c,
c: c,
b: ensureContext(b),
stop: make(chan struct{}),
}
t.b.Reset()
go t.run()
return t
}
// Stop turns off a ticker. After Stop, no more ticks will be sent.
func (t *Ticker) Stop() {
t.stopOnce.Do(func() { close(t.stop) })
}
func (t *Ticker) run() {
c := t.c
defer close(c)
// Ticker is guaranteed to tick at least once.
afterC := t.send(time.Now())
for {
if afterC == nil {
return
}
select {
case tick := <-afterC:
afterC = t.send(tick)
case <-t.stop:
t.c = nil // Prevent future ticks from being sent to the channel.
return
case <-t.b.Context().Done():
return
}
}
}
func (t *Ticker) send(tick time.Time) <-chan time.Time {
select {
case t.c <- tick:
case <-t.stop:
return nil
}
next := t.b.NextBackOff()
if next == Stop {
t.Stop()
return nil
}
return time.After(next)
}

35
vendor/github.com/cenkalti/backoff/v3/tries.go generated vendored Normal file
View File

@@ -0,0 +1,35 @@
package backoff
import "time"
/*
WithMaxRetries creates a wrapper around another BackOff, which will
return Stop if NextBackOff() has been called too many times since
the last time Reset() was called
Note: Implementation is not thread-safe.
*/
func WithMaxRetries(b BackOff, max uint64) BackOff {
return &backOffTries{delegate: b, maxTries: max}
}
type backOffTries struct {
delegate BackOff
maxTries uint64
numTries uint64
}
func (b *backOffTries) NextBackOff() time.Duration {
if b.maxTries > 0 {
if b.maxTries <= b.numTries {
return Stop
}
b.numTries++
}
return b.delegate.NextBackOff()
}
func (b *backOffTries) Reset() {
b.numTries = 0
b.delegate.Reset()
}

View File

@@ -4,7 +4,6 @@
Aanand Prasad <aanand.prasad@gmail.com>
Aaron Davidson <aaron@databricks.com>
Aaron Feng <aaron.feng@gmail.com>
Aaron Hnatiw <aaron@griddio.com>
Aaron Huslage <huslage@gmail.com>
Aaron L. Xu <liker.xu@foxmail.com>
Aaron Lehmann <aaron.lehmann@docker.com>
@@ -18,7 +17,6 @@ Abhishek Chanda <abhishek.becs@gmail.com>
Abhishek Sharma <abhishek@asharma.me>
Abin Shahab <ashahab@altiscale.com>
Adam Avilla <aavilla@yp.com>
Adam Dobrawy <naczelnik@jawnosc.tk>
Adam Eijdenberg <adam.eijdenberg@gmail.com>
Adam Kunk <adam.kunk@tiaa-cref.org>
Adam Miller <admiller@redhat.com>
@@ -114,7 +112,6 @@ Anda Xu <anda.xu@docker.com>
Anders Janmyr <anders@janmyr.com>
Andre Dublin <81dublin@gmail.com>
Andre Granovsky <robotciti@live.com>
Andrea Denisse Gómez <crypto.andrea@protonmail.ch>
Andrea Luzzardi <aluzzardi@gmail.com>
Andrea Turli <andrea.turli@gmail.com>
Andreas Elvers <andreas@work.de>
@@ -179,10 +176,8 @@ Anusha Ragunathan <anusha.ragunathan@docker.com>
apocas <petermdias@gmail.com>
Arash Deshmeh <adeshmeh@ca.ibm.com>
ArikaChen <eaglesora@gmail.com>
Arko Dasgupta <arko.dasgupta@docker.com>
Arnaud Lefebvre <a.lefebvre@outlook.fr>
Arnaud Porterie <arnaud.porterie@docker.com>
Arnaud Rebillout <arnaud.rebillout@collabora.com>
Arthur Barr <arthur.barr@uk.ibm.com>
Arthur Gautier <baloo@gandi.net>
Artur Meyster <arthurfbi@yahoo.com>
@@ -284,7 +279,6 @@ Carl Loa Odin <carlodin@gmail.com>
Carl X. Su <bcbcarl@gmail.com>
Carlo Mion <mion00@gmail.com>
Carlos Alexandro Becker <caarlos0@gmail.com>
Carlos de Paula <me@carlosedp.com>
Carlos Sanchez <carlos@apache.org>
Carol Fager-Higgins <carol.fager-higgins@docker.com>
Cary <caryhartline@users.noreply.github.com>
@@ -334,7 +328,6 @@ Chris Gibson <chris@chrisg.io>
Chris Khoo <chris.khoo@gmail.com>
Chris McKinnel <chris.mckinnel@tangentlabs.co.uk>
Chris McKinnel <chrismckinnel@gmail.com>
Chris Price <chris.price@docker.com>
Chris Seto <chriskseto@gmail.com>
Chris Snow <chsnow123@gmail.com>
Chris St. Pierre <chris.a.st.pierre@gmail.com>
@@ -424,14 +417,12 @@ Daniel Norberg <dano@spotify.com>
Daniel Nordberg <dnordberg@gmail.com>
Daniel Robinson <gottagetmac@gmail.com>
Daniel S <dan.streby@gmail.com>
Daniel Sweet <danieljsweet@icloud.com>
Daniel Von Fange <daniel@leancoder.com>
Daniel Watkins <daniel@daniel-watkins.co.uk>
Daniel X Moore <yahivin@gmail.com>
Daniel YC Lin <dlin.tw@gmail.com>
Daniel Zhang <jmzwcn@gmail.com>
Danny Berger <dpb587@gmail.com>
Danny Milosavljevic <dannym@scratchpost.org>
Danny Yates <danny@codeaholics.org>
Danyal Khaliq <danyal.khaliq@tenpearls.com>
Darren Coxall <darren@darrencoxall.com>
@@ -525,8 +516,6 @@ Dmitry Smirnov <onlyjob@member.fsf.org>
Dmitry V. Krivenok <krivenok.dmitry@gmail.com>
Dmitry Vorobev <dimahabr@gmail.com>
Dolph Mathews <dolph.mathews@gmail.com>
Dominic Tubach <dominic.tubach@to.com>
Dominic Yin <yindongchao@inspur.com>
Dominik Dingel <dingel@linux.vnet.ibm.com>
Dominik Finkbeiner <finkes93@gmail.com>
Dominik Honnef <dominik@honnef.co>
@@ -595,7 +584,6 @@ Erik Weathers <erikdw@gmail.com>
Erno Hopearuoho <erno.hopearuoho@gmail.com>
Erwin van der Koogh <info@erronis.nl>
Ethan Bell <ebgamer29@gmail.com>
Ethan Mosbaugh <ethan@replicated.com>
Euan Kemp <euan.kemp@coreos.com>
Eugen Krizo <eugen.krizo@gmail.com>
Eugene Yakubovich <eugene.yakubovich@coreos.com>
@@ -632,7 +620,6 @@ Fareed Dudhia <fareeddudhia@googlemail.com>
Fathi Boudra <fathi.boudra@linaro.org>
Federico Gimenez <fgimenez@coit.es>
Felipe Oliveira <felipeweb.programador@gmail.com>
Felipe Ruhland <felipe.ruhland@gmail.com>
Felix Abecassis <fabecassis@nvidia.com>
Felix Geisendörfer <felix@debuggable.com>
Felix Hupfeld <felix@quobyte.com>
@@ -667,7 +654,6 @@ Frank Groeneveld <frank@ivaldi.nl>
Frank Herrmann <fgh@4gh.tv>
Frank Macreery <frank@macreery.com>
Frank Rosquin <frank.rosquin+github@gmail.com>
frankyang <yyb196@gmail.com>
Fred Lifton <fred.lifton@docker.com>
Frederick F. Kautz IV <fkautz@redhat.com>
Frederik Loeffert <frederik@zitrusmedia.de>
@@ -715,7 +701,6 @@ Gleb M Borisov <borisov.gleb@gmail.com>
Glyn Normington <gnormington@gopivotal.com>
GoBella <caili_welcome@163.com>
Goffert van Gool <goffert@phusion.nl>
Goldwyn Rodrigues <rgoldwyn@suse.com>
Gopikannan Venugopalsamy <gopikannan.venugopalsamy@gmail.com>
Gosuke Miyashita <gosukenator@gmail.com>
Gou Rao <gou@portworx.com>
@@ -739,7 +724,6 @@ Guruprasad <lgp171188@gmail.com>
Gustav Sinder <gustav.sinder@gmail.com>
gwx296173 <gaojing3@huawei.com>
Günter Zöchbauer <guenter@gzoechbauer.com>
Haichao Yang <yang.haichao@zte.com.cn>
haikuoliu <haikuo@amazon.com>
Hakan Özler <hakan.ozler@kodcu.com>
Hamish Hutchings <moredhel@aoeu.me>
@@ -748,7 +732,6 @@ Hans Rødtang <hansrodtang@gmail.com>
Hao Shu Wei <haosw@cn.ibm.com>
Hao Zhang <21521210@zju.edu.cn>
Harald Albers <github@albersweb.de>
Harald Niesche <harald@niesche.de>
Harley Laue <losinggeneration@gmail.com>
Harold Cooper <hrldcpr@gmail.com>
Harrison Turton <harrisonturton@gmail.com>
@@ -768,11 +751,9 @@ Hobofan <goisser94@gmail.com>
Hollie Teal <hollie@docker.com>
Hong Xu <hong@topbug.net>
Hongbin Lu <hongbin034@gmail.com>
Hongxu Jia <hongxu.jia@windriver.com>
hsinko <21551195@zju.edu.cn>
Hu Keping <hukeping@huawei.com>
Hu Tao <hutao@cn.fujitsu.com>
HuanHuan Ye <logindaveye@gmail.com>
Huanzhong Zhang <zhanghuanzhong90@gmail.com>
Huayi Zhang <irachex@gmail.com>
Hugo Duncan <hugo@hugoduncan.org>
@@ -916,7 +897,6 @@ Jie Luo <luo612@zju.edu.cn>
Jihyun Hwang <jhhwang@telcoware.com>
Jilles Oldenbeuving <ojilles@gmail.com>
Jim Alateras <jima@comware.com.au>
Jim Ehrismann <jim.ehrismann@docker.com>
Jim Galasyn <jim.galasyn@docker.com>
Jim Minter <jminter@redhat.com>
Jim Perrin <jperrin@centos.org>
@@ -954,7 +934,7 @@ John Feminella <jxf@jxf.me>
John Gardiner Myers <jgmyers@proofpoint.com>
John Gossman <johngos@microsoft.com>
John Harris <john@johnharris.io>
John Howard <github@lowenna.com>
John Howard (VM) <John.Howard@microsoft.com>
John Laswell <john.n.laswell@gmail.com>
John Maguire <jmaguire@duosecurity.com>
John Mulhausen <john@docker.com>
@@ -968,7 +948,6 @@ John Willis <john.willis@docker.com>
Jon Johnson <jonjohnson@google.com>
Jon Surrell <jon.surrell@gmail.com>
Jon Wedaman <jweede@gmail.com>
Jonas Dohse <jonas@dohse.ch>
Jonas Pfenniger <jonas@pfenniger.name>
Jonathan A. Schweder <jonathanschweder@gmail.com>
Jonathan A. Sternberg <jonathansternberg@gmail.com>
@@ -1022,7 +1001,6 @@ Julio Montes <imc.coder@gmail.com>
Jun-Ru Chang <jrjang@gmail.com>
Jussi Nummelin <jussi.nummelin@gmail.com>
Justas Brazauskas <brazauskasjustas@gmail.com>
Justen Martin <jmart@the-coder.com>
Justin Cormack <justin.cormack@docker.com>
Justin Force <justin.force@gmail.com>
Justin Menga <justin.menga@gmail.com>
@@ -1031,7 +1009,6 @@ Justin Simonelis <justin.p.simonelis@gmail.com>
Justin Terry <juterry@microsoft.com>
Justyn Temme <justyntemme@gmail.com>
Jyrki Puttonen <jyrkiput@gmail.com>
Jérémy Leherpeur <amenophis@leherpeur.net>
Jérôme Petazzoni <jerome.petazzoni@docker.com>
Jörg Thalheim <joerg@higgsboson.tk>
K. Heller <pestophagous@gmail.com>
@@ -1069,7 +1046,6 @@ Ken Reese <krrgithub@gmail.com>
Kenfe-Mickaël Laventure <mickael.laventure@gmail.com>
Kenjiro Nakayama <nakayamakenjiro@gmail.com>
Kent Johnson <kentoj@gmail.com>
Kenta Tada <Kenta.Tada@sony.com>
Kevin "qwazerty" Houdebert <kevin.houdebert@gmail.com>
Kevin Burke <kev@inburke.com>
Kevin Clark <kevin.clark@gmail.com>
@@ -1080,7 +1056,6 @@ Kevin Kern <kaiwentan@harmonycloud.cn>
Kevin Menard <kevin@nirvdrum.com>
Kevin Meredith <kevin.m.meredith@gmail.com>
Kevin P. Kucharczyk <kevinkucharczyk@gmail.com>
Kevin Parsons <kevpar@microsoft.com>
Kevin Richardson <kevin@kevinrichardson.co>
Kevin Shi <kshi@andrew.cmu.edu>
Kevin Wallace <kevin@pentabarf.net>
@@ -1171,7 +1146,6 @@ longliqiang88 <394564827@qq.com>
Lorenz Leutgeb <lorenz.leutgeb@gmail.com>
Lorenzo Fontana <fontanalorenz@gmail.com>
Lotus Fenn <fenn.lotus@gmail.com>
Louis Delossantos <ldelossa.ld@gmail.com>
Louis Opter <kalessin@kalessin.fr>
Luca Favatella <luca.favatella@erlang-solutions.com>
Luca Marturana <lucamarturana@gmail.com>
@@ -1180,18 +1154,15 @@ Luca-Bogdan Grigorescu <Luca-Bogdan Grigorescu>
Lucas Chan <lucas-github@lucaschan.com>
Lucas Chi <lucas@teacherspayteachers.com>
Lucas Molas <lmolas@fundacionsadosky.org.ar>
Lucas Silvestre <lukas.silvestre@gmail.com>
Luciano Mores <leslau@gmail.com>
Luis Martínez de Bartolomé Izquierdo <lmartinez@biicode.com>
Luiz Svoboda <luizek@gmail.com>
Lukas Heeren <lukas-heeren@hotmail.com>
Lukas Waslowski <cr7pt0gr4ph7@gmail.com>
lukaspustina <lukas.pustina@centerdevice.com>
Lukasz Zajaczkowski <Lukasz.Zajaczkowski@ts.fujitsu.com>
Luke Marsden <me@lukemarsden.net>
Lyn <energylyn@zju.edu.cn>
Lynda O'Leary <lyndaoleary29@gmail.com>
lzhfromutsc <lzhfromustc@gmail.com>
Lénaïc Huard <lhuard@amadeus.com>
Ma Müller <mueller-ma@users.noreply.github.com>
Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
@@ -1325,7 +1296,6 @@ Michael Stapelberg <michael+gh@stapelberg.de>
Michael Steinert <mike.steinert@gmail.com>
Michael Thies <michaelthies78@gmail.com>
Michael West <mwest@mdsol.com>
Michael Zhao <michael.zhao@arm.com>
Michal Fojtik <mfojtik@redhat.com>
Michal Gebauer <mishak@mishak.net>
Michal Jemala <michal.jemala@gmail.com>
@@ -1410,7 +1380,6 @@ Neyazul Haque <nuhaque@gmail.com>
Nghia Tran <nghia@google.com>
Niall O'Higgins <niallo@unworkable.org>
Nicholas E. Rabenau <nerab@gmx.at>
Nick Adcock <nick.adcock@docker.com>
Nick DeCoursin <n.decoursin@foodpanda.com>
Nick Irvine <nfirvine@nfirvine.com>
Nick Neisen <nwneisen@gmail.com>
@@ -1449,7 +1418,6 @@ Nuutti Kotivuori <naked@iki.fi>
nzwsch <hi@nzwsch.com>
O.S. Tezer <ostezer@gmail.com>
objectified <objectified@gmail.com>
Odin Ugedal <odin@ugedal.com>
Oguz Bilgic <fisyonet@gmail.com>
Oh Jinkyun <tintypemolly@gmail.com>
Ohad Schneider <ohadschn@users.noreply.github.com>
@@ -1460,7 +1428,6 @@ Oliver Reason <oli@overrateddev.co>
Olivier Gambier <dmp42@users.noreply.github.com>
Olle Jonsson <olle.jonsson@gmail.com>
Olli Janatuinen <olli.janatuinen@gmail.com>
Olly Pomeroy <oppomeroy@gmail.com>
Omri Shiv <Omri.Shiv@teradata.com>
Oriol Francès <oriolfa@gmail.com>
Oskar Niburski <oskarniburski@gmail.com>
@@ -1470,7 +1437,6 @@ Ovidio Mallo <ovidio.mallo@gmail.com>
Panagiotis Moustafellos <pmoust@elastic.co>
Paolo G. Giarrusso <p.giarrusso@gmail.com>
Pascal <pascalgn@users.noreply.github.com>
Pascal Bach <pascal.bach@siemens.com>
Pascal Borreli <pascal@borreli.com>
Pascal Hartig <phartig@rdrei.net>
Patrick Böänziger <patrick.baenziger@bsi-software.com>
@@ -1495,7 +1461,6 @@ Paul Nasrat <pnasrat@gmail.com>
Paul Weaver <pauweave@cisco.com>
Paulo Ribeiro <paigr.io@gmail.com>
Pavel Lobashov <ShockwaveNN@gmail.com>
Pavel Matěja <pavel@verotel.cz>
Pavel Pletenev <cpp.create@gmail.com>
Pavel Pospisil <pospispa@gmail.com>
Pavel Sutyrin <pavel.sutyrin@gmail.com>
@@ -1607,7 +1572,6 @@ Riku Voipio <riku.voipio@linaro.org>
Riley Guerin <rileytg.dev@gmail.com>
Ritesh H Shukla <sritesh@vmware.com>
Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
Rob Gulewich <rgulewich@netflix.com>
Rob Vesse <rvesse@dotnetrdf.org>
Robert Bachmann <rb@robertbachmann.at>
Robert Bittle <guywithnose@gmail.com>
@@ -1616,13 +1580,11 @@ Robert Schneider <mail@shakeme.info>
Robert Stern <lexandro2000@gmail.com>
Robert Terhaar <rterhaar@atlanticdynamic.com>
Robert Wallis <smilingrob@gmail.com>
Robert Wang <robert@arctic.tw>
Roberto G. Hashioka <roberto.hashioka@docker.com>
Roberto Muñoz Fernández <robertomf@gmail.com>
Robin Naundorf <r.naundorf@fh-muenster.de>
Robin Schneider <ypid@riseup.net>
Robin Speekenbrink <robin@kingsquare.nl>
Robin Thoni <robin@rthoni.com>
robpc <rpcann@gmail.com>
Rodolfo Carvalho <rhcarvalho@gmail.com>
Rodrigo Vaz <rodrigo.vaz@gmail.com>
@@ -1656,7 +1618,6 @@ Rozhnov Alexandr <nox73@ya.ru>
Rudolph Gottesheim <r.gottesheim@loot.at>
Rui Cao <ruicao@alauda.io>
Rui Lopes <rgl@ruilopes.com>
Ruilin Li <liruilin4@huawei.com>
Runshen Zhu <runshen.zhu@gmail.com>
Russ Magee <rmagee@gmail.com>
Ryan Abrams <rdabrams@gmail.com>
@@ -1695,7 +1656,6 @@ Sam J Sharpe <sam.sharpe@digital.cabinet-office.gov.uk>
Sam Neirinck <sam@samneirinck.com>
Sam Reis <sreis@atlassian.com>
Sam Rijs <srijs@airpost.net>
Sam Whited <sam@samwhited.com>
Sambuddha Basu <sambuddhabasu1@gmail.com>
Sami Wagiaalla <swagiaal@redhat.com>
Samuel Andaya <samuel@andaya.net>
@@ -1710,7 +1670,6 @@ sapphiredev <se.imas.kr@gmail.com>
Sargun Dhillon <sargun@netflix.com>
Sascha Andres <sascha.andres@outlook.com>
Sascha Grunert <sgrunert@suse.com>
SataQiu <qiushida@beyondcent.com>
Satnam Singh <satnam@raintown.org>
Satoshi Amemiya <satoshi_amemiya@voyagegroup.com>
Satoshi Tagomori <tagomoris@gmail.com>
@@ -1759,7 +1718,6 @@ Shijun Qin <qinshijun16@mails.ucas.ac.cn>
Shishir Mahajan <shishir.mahajan@redhat.com>
Shoubhik Bose <sbose78@gmail.com>
Shourya Sarcar <shourya.sarcar@gmail.com>
Shu-Wai Chow <shu-wai.chow@seattlechildrens.org>
shuai-z <zs.broccoli@gmail.com>
Shukui Yang <yangshukui@huawei.com>
Shuwei Hao <haosw@cn.ibm.com>
@@ -1770,7 +1728,6 @@ Silas Sewell <silas@sewell.org>
Silvan Jegen <s.jegen@gmail.com>
Simão Reis <smnrsti@gmail.com>
Simei He <hesimei@zju.edu.cn>
Simon Barendse <simon.barendse@gmail.com>
Simon Eskildsen <sirup@sirupsen.com>
Simon Ferquel <simon.ferquel@docker.com>
Simon Leinen <simon.leinen@gmail.com>
@@ -1779,7 +1736,6 @@ Simon Taranto <simon.taranto@gmail.com>
Simon Vikstrom <pullreq@devsn.se>
Sindhu S <sindhus@live.in>
Sjoerd Langkemper <sjoerd-github@linuxonly.nl>
skanehira <sho19921005@gmail.com>
Solganik Alexander <solganik@gmail.com>
Solomon Hykes <solomon@docker.com>
Song Gao <song@gao.io>
@@ -1791,18 +1747,16 @@ Sridatta Thatipamala <sthatipamala@gmail.com>
Sridhar Ratnakumar <sridharr@activestate.com>
Srini Brahmaroutu <srbrahma@us.ibm.com>
Srinivasan Srivatsan <srinivasan.srivatsan@hpe.com>
Staf Wagemakers <staf@wagemakers.be>
Stanislav Bondarenko <stanislav.bondarenko@gmail.com>
Steeve Morin <steeve.morin@gmail.com>
Stefan Berger <stefanb@linux.vnet.ibm.com>
Stefan J. Wernli <swernli@microsoft.com>
Stefan Praszalowicz <stefan@greplin.com>
Stefan S. <tronicum@user.github.com>
Stefan Scherer <stefan.scherer@docker.com>
Stefan Scherer <scherer_stefan@icloud.com>
Stefan Staudenmeyer <doerte@instana.com>
Stefan Weil <sw@weilnetz.de>
Stephan Spindler <shutefan@gmail.com>
Stephen Benjamin <stephen@redhat.com>
Stephen Crosby <stevecrozz@gmail.com>
Stephen Day <stephen.day@docker.com>
Stephen Drake <stephen@xenolith.net>
@@ -1819,12 +1773,10 @@ Steven Iveson <sjiveson@outlook.com>
Steven Merrill <steven.merrill@gmail.com>
Steven Richards <steven@axiomzen.co>
Steven Taylor <steven.taylor@me.com>
Stig Larsson <stig@larsson.dev>
Subhajit Ghosh <isubuz.g@gmail.com>
Sujith Haridasan <sujith.h@gmail.com>
Sun Gengze <690388648@qq.com>
Sun Jianbo <wonderflow.sun@gmail.com>
Sune Keller <sune.keller@gmail.com>
Sunny Gogoi <indiasuny000@gmail.com>
Suryakumar Sudar <surya.trunks@gmail.com>
Sven Dowideit <SvenDowideit@home.org.au>
@@ -1875,7 +1827,6 @@ Tianyi Wang <capkurmagati@gmail.com>
Tibor Vass <teabee89@gmail.com>
Tiffany Jernigan <tiffany.f.j@gmail.com>
Tiffany Low <tiffany@box.com>
Tim <elatllat@gmail.com>
Tim Bart <tim@fewagainstmany.com>
Tim Bosse <taim@bosboot.org>
Tim Dettrick <t.dettrick@uq.edu.au>
@@ -1961,7 +1912,6 @@ Victor Palma <palma.victor@gmail.com>
Victor Vieux <victor.vieux@docker.com>
Victoria Bialas <victoria.bialas@docker.com>
Vijaya Kumar K <vijayak@caviumnetworks.com>
Vikram bir Singh <vikrambir.singh@docker.com>
Viktor Stanchev <me@viktorstanchev.com>
Viktor Vojnovski <viktor.vojnovski@amadeus.com>
VinayRaghavanKS <raghavan.vinay@gmail.com>
@@ -2019,7 +1969,6 @@ Wenyu You <21551128@zju.edu.cn>
Wenzhi Liang <wenzhi.liang@gmail.com>
Wes Morgan <cap10morgan@gmail.com>
Wewang Xiaorenfine <wang.xiaoren@zte.com.cn>
Wiktor Kwapisiewicz <wiktor@metacode.biz>
Will Dietz <w@wdtz.org>
Will Rouesnel <w.rouesnel@gmail.com>
Will Weaver <monkey@buildingbananas.com>
@@ -2047,7 +1996,6 @@ xichengliudui <1693291525@qq.com>
xiekeyang <xiekeyang@huawei.com>
Ximo Guanter Gonzálbez <joaquin.guantergonzalbez@telefonica.com>
Xinbo Weng <xihuanbo_0521@zju.edu.cn>
Xinfeng Liu <xinfeng.liu@gmail.com>
Xinzi Zhou <imdreamrunner@gmail.com>
Xiuming Chen <cc@cxm.cc>
Xuecong Liao <satorulogic@gmail.com>
@@ -2062,7 +2010,6 @@ Yang Pengfei <yangpengfei4@huawei.com>
yangchenliang <yangchenliang@huawei.com>
Yanqiang Miao <miao.yanqiang@zte.com.cn>
Yao Zaiyong <yaozaiyong@hotmail.com>
Yash Murty <yashmurty@gmail.com>
Yassine Tijani <yasstij11@gmail.com>
Yasunori Mahata <nori@mahata.net>
Yazhong Liu <yorkiefixer@gmail.com>
@@ -2077,7 +2024,6 @@ Yongxin Li <yxli@alauda.io>
Yongzhi Pan <panyongzhi@gmail.com>
Yosef Fertel <yfertel@gmail.com>
You-Sheng Yang (楊有勝) <vicamo@gmail.com>
youcai <omegacoleman@gmail.com>
Youcef YEKHLEF <yyekhlef@gmail.com>
Yu Changchun <yuchangchun1@huawei.com>
Yu Chengxia <yuchengxia@huawei.com>
@@ -2114,7 +2060,6 @@ Zhoulin Xie <zhoulin.xie@daocloud.io>
Zhu Guihua <zhugh.fnst@cn.fujitsu.com>
Zhu Kunjia <zhu.kunjia@zte.com.cn>
Zhuoyun Wei <wzyboy@wzyboy.org>
Ziheng Liu <lzhfromustc@gmail.com>
Zilin Du <zilin.du@gmail.com>
zimbatm <zimbatm@zimbatm.com>
Ziming Dong <bnudzm@foxmail.com>
@@ -2123,7 +2068,7 @@ zmarouf <zeid.marouf@gmail.com>
Zoltan Tombol <zoltan.tombol@gmail.com>
Zou Yu <zouyu7@huawei.com>
zqh <zqhxuyuan@gmail.com>
Zuhayr Elahi <zuhayr.elahi@docker.com>
Zuhayr Elahi <elahi.zuhayr@gmail.com>
Zunayed Ali <zunayed@gmail.com>
Álex González <agonzalezro@gmail.com>
Álvaro Lázaro <alvaro.lazaro.g@gmail.com>

View File

@@ -3,7 +3,7 @@ package api // import "github.com/docker/docker/api"
// Common constants for daemon and client.
const (
// DefaultVersion of Current REST API
DefaultVersion = "1.41"
DefaultVersion = "1.40"
// NoBaseImageSpecifier is the symbol used by the FROM
// command to specify that no base image is to be used.

View File

@@ -19,10 +19,10 @@ produces:
consumes:
- "application/json"
- "text/plain"
basePath: "/v1.41"
basePath: "/v1.40"
info:
title: "Docker Engine API"
version: "1.41"
version: "1.40"
x-logo:
url: "https://docs.docker.com/images/logo-docker-main.png"
description: |
@@ -49,8 +49,8 @@ info:
the URL is not supported by the daemon, a HTTP `400 Bad Request` error message
is returned.
If you omit the version-prefix, the current version of the API (v1.41) is used.
For example, calling `/info` is the same as calling `/v1.41/info`. Using the
If you omit the version-prefix, the current version of the API (v1.40) is used.
For example, calling `/info` is the same as calling `/v1.40/info`. Using the
API without a version-prefix is deprecated and will be removed in a future release.
Engine releases in the near future should support this version of the API,
@@ -800,19 +800,6 @@ definitions:
description: "A list of kernel capabilities to drop from the container. Conflicts with option 'Capabilities'"
items:
type: "string"
CgroupnsMode:
type: "string"
enum:
- "private"
- "host"
description: |
cgroup namespace mode for the container. Possible values are:
- `"private"`: the container runs in its own private cgroup namespace
- `"host"`: use the host system's cgroup namespace
If not specified, the daemon default is used, which can either be `"private"`
or `"host"`, depending on daemon version, kernel support and configuration.
Dns:
type: "array"
description: "A list of DNS servers for the container to use."
@@ -2979,18 +2966,6 @@ definitions:
type: "object"
additionalProperties:
type: "string"
# This option is not used by Windows containers
Capabilities:
type: "array"
description: |
A list of kernel capabilities to be available for container (this overrides the default set).
items:
type: "string"
example:
- "CAP_NET_RAW"
- "CAP_SYS_ADMIN"
- "CAP_SYS_CHROOT"
- "CAP_SYSLOG"
NetworkAttachmentSpec:
description: |
Read-only spec type for non-swarm containers attached to swarm overlay
@@ -3205,12 +3180,6 @@ definitions:
type: "integer"
DesiredState:
$ref: "#/definitions/TaskState"
JobIteration:
description: |
If the Service this Task belongs to is a job-mode service, contains
the JobIteration of the Service this Task was created for. Absent if
the Task was created for a Replicated or Global Service.
$ref: "#/definitions/ObjectVersion"
example:
ID: "0kzzo1i0y4jz6027t0k7aezc7"
Version:
@@ -3303,22 +3272,6 @@ definitions:
format: "int64"
Global:
type: "object"
ReplicatedJob:
description: "The mode used for services with a finite number of tasks that run to a completed state."
type: "object"
properties:
MaxConcurrent:
description: "The maximum number of replicas to run simultaneously."
type: "integer"
format: "int64"
default: 1
TotalCompletions:
description: "The total number of replicas desired to reach the Completed state. If unset, will default to the value of MaxConcurrent"
type: "integer"
format: "int64"
GlobalJob:
description: "The mode used for services which run a task to the completed state on each valid node."
type: "object"
UpdateConfig:
description: "Specification for the update strategy of the service."
type: "object"
@@ -3498,58 +3451,6 @@ definitions:
format: "dateTime"
Message:
type: "string"
ServiceStatus:
description: |
The status of the service's tasks. Provided only when requested as
part of a ServiceList operation.
type: "object"
properties:
RunningTasks:
description: "The number of tasks for the service currently in the Running state"
type: "integer"
format: "uint64"
example: 7
DesiredTasks:
description: |
The number of tasks for the service desired to be running.
For replicated services, this is the replica count from the
service spec. For global services, this is computed by taking
count of all tasks for the service with a Desired State other
than Shutdown.
type: "integer"
format: "uint64"
example: 10
CompletedTasks:
description: |
The number of tasks for a job that are in the Completed state.
This field must be cross-referenced with the service type, as the
value of 0 may mean the service is not in a job mode, or it may
mean the job-mode service has no tasks yet Completed.
type: "integer"
format: "uint64"
JobStatus:
description: |
The status of the service when it is in one of ReplicatedJob or
GlobalJob modes. Absent on Replicated and Global mode services. The
JobIteration is an ObjectVersion, but unlike the Service's version,
does not need to be sent with an update request.
type: "object"
properties:
JobIteration:
description: |
JobIteration is a value increased each time a Job is executed,
successfully or otherwise. "Executed", in this case, means the
job as a whole has been started, not that an individual Task has
been launched. A job is "Executed" when its ServiceSpec is
updated. JobIteration can be used to disambiguate Tasks belonging
to different executions of a job. Though JobIteration will
increase with each subsequent execution, it may not necessarily
increase by 1, and so JobIteration should not be used to
$ref: "#/definitions/ObjectVersion"
LastExecution:
description: "The last time, as observed by the server, that this job was started"
type: "string"
format: "dateTime"
example:
ID: "9mnpnzenvg8p8tdbtq4wvbkcz"
Version:
@@ -3953,6 +3854,44 @@ definitions:
on Windows.
type: "string"
example: "/var/lib/docker"
SystemStatus:
description: |
Status information about this node (standalone Swarm API).
<p><br /></p>
> **Note**: The information returned in this field is only propagated
> by the Swarm standalone API, and is empty (`null`) when using
> built-in swarm mode.
type: "array"
items:
type: "array"
items:
type: "string"
example:
- ["Role", "primary"]
- ["State", "Healthy"]
- ["Strategy", "spread"]
- ["Filters", "health, port, containerslots, dependency, affinity, constraint, whitelist"]
- ["Nodes", "2"]
- [" swarm-agent-00", "192.168.99.102:2376"]
- [" └ ID", "5CT6:FBGO:RVGO:CZL4:PB2K:WCYN:2JSV:KSHH:GGFW:QOPG:6J5Q:IOZ2|192.168.99.102:2376"]
- [" └ Status", "Healthy"]
- [" └ Containers", "1 (1 Running, 0 Paused, 0 Stopped)"]
- [" └ Reserved CPUs", "0 / 1"]
- [" └ Reserved Memory", "0 B / 1.021 GiB"]
- [" └ Labels", "kernelversion=4.4.74-boot2docker, operatingsystem=Boot2Docker 17.06.0-ce (TCL 7.2); HEAD : 0672754 - Thu Jun 29 00:06:31 UTC 2017, ostype=linux, provider=virtualbox, storagedriver=aufs"]
- [" └ UpdatedAt", "2017-08-09T10:03:46Z"]
- [" └ ServerVersion", "17.06.0-ce"]
- [" swarm-manager", "192.168.99.101:2376"]
- [" └ ID", "TAMD:7LL3:SEF7:LW2W:4Q2X:WVFH:RTXX:JSYS:XY2P:JEHL:ZMJK:JGIW|192.168.99.101:2376"]
- [" └ Status", "Healthy"]
- [" └ Containers", "2 (2 Running, 0 Paused, 0 Stopped)"]
- [" └ Reserved CPUs", "0 / 1"]
- [" └ Reserved Memory", "0 B / 1.021 GiB"]
- [" └ Labels", "kernelversion=4.4.74-boot2docker, operatingsystem=Boot2Docker 17.06.0-ce (TCL 7.2); HEAD : 0672754 - Thu Jun 29 00:06:31 UTC 2017, ostype=linux, provider=virtualbox, storagedriver=aufs"]
- [" └ UpdatedAt", "2017-08-09T10:04:11Z"]
- [" └ ServerVersion", "17.06.0-ce"]
Plugins:
$ref: "#/definitions/PluginsInfo"
MemoryLimit:
@@ -4059,17 +3998,6 @@ definitions:
or "Windows Server 2016 Datacenter"
type: "string"
example: "Alpine Linux v3.5"
OSVersion:
description: |
Version of the host's operating system
<p><br /></p>
> **Note**: The information returned in this field, including its
> very existence, and the formatting of values, should not be considered
> stable, and may change without notice.
type: "string"
example: "16.04"
OSType:
description: |
Generic type of the operating system of the host, as returned by the
@@ -4186,7 +4114,7 @@ definitions:
<p><br /></p>
> **Deprecated**: This field is only propagated when using standalone Swarm
> **Note**: This field is only propagated when using standalone Swarm
> mode, and overlay networking using an external k/v store. Overlay
> networks with Swarm mode enabled use the built-in raft store, and
> this field will be empty.
@@ -4200,7 +4128,7 @@ definitions:
<p><br /></p>
> **Deprecated**: This field is only propagated when using standalone Swarm
> **Note**: This field is only propagated when using standalone Swarm
> mode, and overlay networking using an external k/v store. Overlay
> networks with Swarm mode enabled use the built-in raft store, and
> this field will be empty.
@@ -5096,6 +5024,9 @@ paths:
type: "string"
LogPath:
type: "string"
Node:
description: "TODO"
type: "object"
Name:
type: "string"
RestartCount:
@@ -9510,10 +9441,6 @@ paths:
- `label=<service label>`
- `mode=["replicated"|"global"]`
- `name=<service name>`
- name: "status"
in: "query"
type: "boolean"
description: "Include service status, with count of running and desired tasks"
tags: ["Service"]
/services/create:
post:

View File

@@ -205,7 +205,7 @@ const (
// BuilderV1 is the first generation builder in docker daemon
BuilderV1 BuilderVersion = "1"
// BuilderBuildKit is builder based on moby/buildkit project
BuilderBuildKit BuilderVersion = "2"
BuilderBuildKit = "2"
)
// ImageBuildResponse holds information
@@ -265,7 +265,7 @@ type ImagePullOptions struct {
// if the privilege request fails.
type RequestPrivilegeFunc func() (string, error)
// ImagePushOptions holds information to push images.
//ImagePushOptions holds information to push images.
type ImagePushOptions ImagePullOptions
// ImageRemoveOptions holds parameters to remove images.
@@ -363,10 +363,6 @@ type ServiceUpdateOptions struct {
// ServiceListOptions holds parameters to list services with.
type ServiceListOptions struct {
Filters filters.Args
// Status indicates whether the server should include the service task
// count of running and desired tasks.
Status bool
}
// ServiceInspectOptions holds parameters related to the "service inspect"

View File

@@ -1,7 +1,8 @@
package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// Code generated by `swagger generate operation`. DO NOT EDIT.
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------

View File

@@ -1,7 +1,8 @@
package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// Code generated by `swagger generate operation`. DO NOT EDIT.
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------

View File

@@ -1,7 +1,8 @@
package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// Code generated by `swagger generate operation`. DO NOT EDIT.
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------

View File

@@ -1,7 +1,8 @@
package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// Code generated by `swagger generate operation`. DO NOT EDIT.
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------

View File

@@ -1,7 +1,8 @@
package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// Code generated by `swagger generate operation`. DO NOT EDIT.
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------

View File

@@ -7,32 +7,9 @@ import (
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/strslice"
"github.com/docker/go-connections/nat"
units "github.com/docker/go-units"
"github.com/docker/go-units"
)
// CgroupnsMode represents the cgroup namespace mode of the container
type CgroupnsMode string
// IsPrivate indicates whether the container uses its own private cgroup namespace
func (c CgroupnsMode) IsPrivate() bool {
return c == "private"
}
// IsHost indicates whether the container shares the host's cgroup namespace
func (c CgroupnsMode) IsHost() bool {
return c == "host"
}
// IsEmpty indicates whether the container cgroup namespace mode is unset
func (c CgroupnsMode) IsEmpty() bool {
return c == ""
}
// Valid indicates whether the cgroup namespace mode is valid
func (c CgroupnsMode) Valid() bool {
return c.IsEmpty() || c.IsPrivate() || c.IsHost()
}
// Isolation represents the isolation technology of a container. The supported
// values are platform specific
type Isolation string
@@ -145,7 +122,7 @@ func (n NetworkMode) ConnectedContainer() string {
return ""
}
// UserDefined indicates user-created network
//UserDefined indicates user-created network
func (n NetworkMode) UserDefined() string {
if n.IsUserDefined() {
return string(n)
@@ -404,10 +381,9 @@ type HostConfig struct {
CapAdd strslice.StrSlice // List of kernel capabilities to add to the container
CapDrop strslice.StrSlice // List of kernel capabilities to remove from the container
Capabilities []string `json:"Capabilities"` // List of kernel capabilities to be available for container (this overrides the default set)
CgroupnsMode CgroupnsMode // Cgroup namespace mode to use for the container
DNS []string `json:"Dns"` // List of DNS server to lookup
DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for
DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for
DNS []string `json:"Dns"` // List of DNS server to lookup
DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for
DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for
ExtraHosts []string // List of extra hosts
GroupAdd []string // List of additional groups that the container process will run as
IpcMode IpcMode // IPC namespace to use for the container

View File

@@ -1,6 +0,0 @@
package types
// Error returns the error message
func (e ErrorResponse) Error() string {
return e.Message
}

View File

@@ -66,7 +66,7 @@ func ToJSON(a Args) (string, error) {
// then the encoded format will use an older legacy format where the values are a
// list of strings, instead of a set.
//
// Deprecated: do not use in any new code; use ToJSON instead
// Deprecated: Use ToJSON
func ToParamWithVersion(version string, a Args) (string, error) {
if a.Len() == 0 {
return "", nil
@@ -154,7 +154,7 @@ func (args Args) Len() int {
func (args Args) MatchKVList(key string, sources map[string]string) bool {
fieldValues := args.fields[key]
// do not filter if there is no filter set or cannot determine filter
//do not filter if there is no filter set or cannot determine filter
if len(fieldValues) == 0 {
return true
}
@@ -200,7 +200,7 @@ func (args Args) Match(field, source string) bool {
// ExactMatch returns true if the source matches exactly one of the values.
func (args Args) ExactMatch(key, source string) bool {
fieldValues, ok := args.fields[key]
// do not filter if there is no filter set or cannot determine filter
//do not filter if there is no filter set or cannot determine filter
if !ok || len(fieldValues) == 0 {
return true
}
@@ -213,7 +213,7 @@ func (args Args) ExactMatch(key, source string) bool {
// matches exactly the value.
func (args Args) UniqueExactMatch(key, source string) bool {
fieldValues := args.fields[key]
// do not filter if there is no filter set or cannot determine filter
//do not filter if there is no filter set or cannot determine filter
if len(fieldValues) == 0 {
return true
}

View File

@@ -1,7 +1,8 @@
package image // import "github.com/docker/docker/api/types/image"
// ----------------------------------------------------------------------------
// Code generated by `swagger generate operation`. DO NOT EDIT.
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------

View File

@@ -13,7 +13,7 @@ type Address struct {
// IPAM represents IP Address Management
type IPAM struct {
Driver string
Options map[string]string // Per network IPAM driver options
Options map[string]string //Per network IPAM driver options
Config []IPAMConfig
}

View File

@@ -4,7 +4,7 @@ import (
"encoding/json"
"net"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/image-spec/specs-go/v1"
)
// ServiceConfig stores daemon registry services configuration.

View File

@@ -67,11 +67,10 @@ type ContainerSpec struct {
// The format of extra hosts on swarmkit is specified in:
// http://man7.org/linux/man-pages/man5/hosts.5.html
// IP_address canonical_hostname [aliases...]
Hosts []string `json:",omitempty"`
DNSConfig *DNSConfig `json:",omitempty"`
Secrets []*SecretReference `json:",omitempty"`
Configs []*ConfigReference `json:",omitempty"`
Isolation container.Isolation `json:",omitempty"`
Sysctls map[string]string `json:",omitempty"`
Capabilities []string `json:",omitempty"`
Hosts []string `json:",omitempty"`
DNSConfig *DNSConfig `json:",omitempty"`
Secrets []*SecretReference `json:",omitempty"`
Configs []*ConfigReference `json:",omitempty"`
Isolation container.Isolation `json:",omitempty"`
Sysctls map[string]string `json:",omitempty"`
}

View File

@@ -1,5 +1,6 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// Code generated by protoc-gen-gogo.
// source: plugin.proto
// DO NOT EDIT!
/*
Package runtime is a generated protocol buffer package.
@@ -37,7 +38,6 @@ type PluginSpec struct {
Remote string `protobuf:"bytes,2,opt,name=remote,proto3" json:"remote,omitempty"`
Privileges []*PluginPrivilege `protobuf:"bytes,3,rep,name=privileges" json:"privileges,omitempty"`
Disabled bool `protobuf:"varint,4,opt,name=disabled,proto3" json:"disabled,omitempty"`
Env []string `protobuf:"bytes,5,rep,name=env" json:"env,omitempty"`
}
func (m *PluginSpec) Reset() { *m = PluginSpec{} }
@@ -73,13 +73,6 @@ func (m *PluginSpec) GetDisabled() bool {
return false
}
func (m *PluginSpec) GetEnv() []string {
if m != nil {
return m.Env
}
return nil
}
// PluginPrivilege describes a permission the user has to accept
// upon installing a plugin.
type PluginPrivilege struct {
@@ -167,21 +160,6 @@ func (m *PluginSpec) MarshalTo(dAtA []byte) (int, error) {
}
i++
}
if len(m.Env) > 0 {
for _, s := range m.Env {
dAtA[i] = 0x2a
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
return i, nil
}
@@ -230,6 +208,24 @@ func (m *PluginPrivilege) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func encodeFixed64Plugin(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
dAtA[offset+4] = uint8(v >> 32)
dAtA[offset+5] = uint8(v >> 40)
dAtA[offset+6] = uint8(v >> 48)
dAtA[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Plugin(dAtA []byte, offset int, v uint32) int {
dAtA[offset] = uint8(v)
dAtA[offset+1] = uint8(v >> 8)
dAtA[offset+2] = uint8(v >> 16)
dAtA[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintPlugin(dAtA []byte, offset int, v uint64) int {
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
@@ -259,12 +255,6 @@ func (m *PluginSpec) Size() (n int) {
if m.Disabled {
n += 2
}
if len(m.Env) > 0 {
for _, s := range m.Env {
l = len(s)
n += 1 + l + sovPlugin(uint64(l))
}
}
return n
}
@@ -439,35 +429,6 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
}
}
m.Disabled = bool(v != 0)
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPlugin
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPlugin
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Env = append(m.Env, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPlugin(dAtA[iNdEx:])
@@ -734,21 +695,18 @@ var (
func init() { proto.RegisterFile("plugin.proto", fileDescriptorPlugin) }
var fileDescriptorPlugin = []byte{
// 256 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x4d, 0x4b, 0xc3, 0x30,
0x18, 0xc7, 0x89, 0xdd, 0xc6, 0xfa, 0x4c, 0x70, 0x04, 0x91, 0xe2, 0xa1, 0x94, 0x9d, 0x7a, 0x6a,
0x45, 0x2f, 0x82, 0x37, 0x0f, 0x9e, 0x47, 0xbc, 0x09, 0x1e, 0xd2, 0xf6, 0xa1, 0x06, 0x9b, 0x17,
0x92, 0xb4, 0xe2, 0x37, 0xf1, 0x23, 0x79, 0xf4, 0x23, 0x48, 0x3f, 0x89, 0x98, 0x75, 0x32, 0x64,
0xa7, 0xff, 0x4b, 0xc2, 0x9f, 0x1f, 0x0f, 0x9c, 0x9a, 0xae, 0x6f, 0x85, 0x2a, 0x8c, 0xd5, 0x5e,
0x6f, 0x3e, 0x08, 0xc0, 0x36, 0x14, 0x8f, 0x06, 0x6b, 0x4a, 0x61, 0xa6, 0xb8, 0xc4, 0x84, 0x64,
0x24, 0x8f, 0x59, 0xf0, 0xf4, 0x02, 0x16, 0x16, 0xa5, 0xf6, 0x98, 0x9c, 0x84, 0x76, 0x4a, 0xf4,
0x0a, 0xc0, 0x58, 0x31, 0x88, 0x0e, 0x5b, 0x74, 0x49, 0x94, 0x45, 0xf9, 0xea, 0x7a, 0x5d, 0xec,
0xc6, 0xb6, 0xfb, 0x07, 0x76, 0xf0, 0x87, 0x5e, 0xc2, 0xb2, 0x11, 0x8e, 0x57, 0x1d, 0x36, 0xc9,
0x2c, 0x23, 0xf9, 0x92, 0xfd, 0x65, 0xba, 0x86, 0x08, 0xd5, 0x90, 0xcc, 0xb3, 0x28, 0x8f, 0xd9,
0xaf, 0xdd, 0x3c, 0xc3, 0xd9, 0xbf, 0xb1, 0xa3, 0x78, 0x19, 0xac, 0x1a, 0x74, 0xb5, 0x15, 0xc6,
0x0b, 0xad, 0x26, 0xc6, 0xc3, 0x8a, 0x9e, 0xc3, 0x7c, 0xe0, 0x5d, 0x8f, 0x81, 0x31, 0x66, 0xbb,
0x70, 0xff, 0xf0, 0x39, 0xa6, 0xe4, 0x6b, 0x4c, 0xc9, 0xf7, 0x98, 0x92, 0xa7, 0xdb, 0x56, 0xf8,
0x97, 0xbe, 0x2a, 0x6a, 0x2d, 0xcb, 0x46, 0xd7, 0xaf, 0x68, 0xf7, 0xc2, 0x8d, 0x28, 0xfd, 0xbb,
0x41, 0x57, 0xba, 0x37, 0x6e, 0x65, 0x69, 0x7b, 0xe5, 0x85, 0xc4, 0xbb, 0x49, 0xab, 0x45, 0x38,
0xe4, 0xcd, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x99, 0xa8, 0xd9, 0x9b, 0x58, 0x01, 0x00, 0x00,
// 196 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0xc8, 0x29, 0x4d,
0xcf, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x6a, 0x63, 0xe4, 0xe2, 0x0a, 0x00, 0x0b,
0x04, 0x17, 0xa4, 0x26, 0x0b, 0x09, 0x71, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30, 0x2a, 0x30,
0x6a, 0x70, 0x06, 0x81, 0xd9, 0x42, 0x62, 0x5c, 0x6c, 0x45, 0xa9, 0xb9, 0xf9, 0x25, 0xa9, 0x12,
0x4c, 0x60, 0x51, 0x28, 0x4f, 0xc8, 0x80, 0x8b, 0xab, 0xa0, 0x28, 0xb3, 0x2c, 0x33, 0x27, 0x35,
0x3d, 0xb5, 0x58, 0x82, 0x59, 0x81, 0x59, 0x83, 0xdb, 0x48, 0x40, 0x0f, 0x62, 0x58, 0x00, 0x4c,
0x22, 0x08, 0x49, 0x8d, 0x90, 0x14, 0x17, 0x47, 0x4a, 0x66, 0x71, 0x62, 0x52, 0x4e, 0x6a, 0x8a,
0x04, 0x8b, 0x02, 0xa3, 0x06, 0x47, 0x10, 0x9c, 0xaf, 0x14, 0xcb, 0xc5, 0x8f, 0xa6, 0x15, 0xab,
0x63, 0x14, 0xb8, 0xb8, 0x53, 0x52, 0x8b, 0x93, 0x8b, 0x32, 0x0b, 0x4a, 0x32, 0xf3, 0xf3, 0xa0,
0x2e, 0x42, 0x16, 0x12, 0x12, 0xe1, 0x62, 0x2d, 0x4b, 0xcc, 0x29, 0x4d, 0x05, 0xbb, 0x88, 0x33,
0x08, 0xc2, 0x71, 0xe2, 0x39, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4,
0x18, 0x93, 0xd8, 0xc0, 0x9e, 0x37, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xb8, 0x84, 0xad, 0x79,
0x0c, 0x01, 0x00, 0x00,
}

View File

@@ -9,7 +9,6 @@ message PluginSpec {
string remote = 2;
repeated PluginPrivilege privileges = 3;
bool disabled = 4;
repeated string env = 5;
}
// PluginPrivilege describes a permission the user has to accept

View File

@@ -10,17 +10,6 @@ type Service struct {
PreviousSpec *ServiceSpec `json:",omitempty"`
Endpoint Endpoint `json:",omitempty"`
UpdateStatus *UpdateStatus `json:",omitempty"`
// ServiceStatus is an optional, extra field indicating the number of
// desired and running tasks. It is provided primarily as a shortcut to
// calculating these values client-side, which otherwise would require
// listing all tasks for a service, an operation that could be
// computation and network expensive.
ServiceStatus *ServiceStatus `json:",omitempty"`
// JobStatus is the status of a Service which is in one of ReplicatedJob or
// GlobalJob modes. It is absent on Replicated and Global services.
JobStatus *JobStatus `json:",omitempty"`
}
// ServiceSpec represents the spec of a service.
@@ -43,10 +32,8 @@ type ServiceSpec struct {
// ServiceMode represents the mode of a service.
type ServiceMode struct {
Replicated *ReplicatedService `json:",omitempty"`
Global *GlobalService `json:",omitempty"`
ReplicatedJob *ReplicatedJob `json:",omitempty"`
GlobalJob *GlobalJob `json:",omitempty"`
Replicated *ReplicatedService `json:",omitempty"`
Global *GlobalService `json:",omitempty"`
}
// UpdateState is the state of a service update.
@@ -83,32 +70,6 @@ type ReplicatedService struct {
// GlobalService is a kind of ServiceMode.
type GlobalService struct{}
// ReplicatedJob is the a type of Service which executes a defined Tasks
// in parallel until the specified number of Tasks have succeeded.
type ReplicatedJob struct {
// MaxConcurrent indicates the maximum number of Tasks that should be
// executing simultaneously for this job at any given time. There may be
// fewer Tasks that MaxConcurrent executing simultaneously; for example, if
// there are fewer than MaxConcurrent tasks needed to reach
// TotalCompletions.
//
// If this field is empty, it will default to a max concurrency of 1.
MaxConcurrent *uint64 `json:",omitempty"`
// TotalCompletions is the total number of Tasks desired to run to
// completion.
//
// If this field is empty, the value of MaxConcurrent will be used.
TotalCompletions *uint64 `json:",omitempty"`
}
// GlobalJob is the type of a Service which executes a Task on every Node
// matching the Service's placement constraints. These tasks run to completion
// and then exit.
//
// This type is deliberately empty.
type GlobalJob struct{}
const (
// UpdateFailureActionPause PAUSE
UpdateFailureActionPause = "pause"
@@ -161,42 +122,3 @@ type UpdateConfig struct {
// started, or the new task is started before the old task is shut down.
Order string
}
// ServiceStatus represents the number of running tasks in a service and the
// number of tasks desired to be running.
type ServiceStatus struct {
// RunningTasks is the number of tasks for the service actually in the
// Running state
RunningTasks uint64
// DesiredTasks is the number of tasks desired to be running by the
// service. For replicated services, this is the replica count. For global
// services, this is computed by taking the number of tasks with desired
// state of not-Shutdown.
DesiredTasks uint64
// CompletedTasks is the number of tasks in the state Completed, if this
// service is in ReplicatedJob or GlobalJob mode. This field must be
// cross-referenced with the service type, because the default value of 0
// may mean that a service is not in a job mode, or it may mean that the
// job has yet to complete any tasks.
CompletedTasks uint64
}
// JobStatus is the status of a job-type service.
type JobStatus struct {
// JobIteration is a value increased each time a Job is executed,
// successfully or otherwise. "Executed", in this case, means the job as a
// whole has been started, not that an individual Task has been launched. A
// job is "Executed" when its ServiceSpec is updated. JobIteration can be
// used to disambiguate Tasks belonging to different executions of a job.
//
// Though JobIteration will increase with each subsequent execution, it may
// not necessarily increase by 1, and so JobIteration should not be used to
// keep track of the number of times a job has been executed.
JobIteration Version
// LastExecution is the time that the job was last executed, as observed by
// Swarm manager.
LastExecution time.Time `json:",omitempty"`
}

View File

@@ -56,12 +56,6 @@ type Task struct {
DesiredState TaskState `json:",omitempty"`
NetworksAttachments []NetworkAttachment `json:",omitempty"`
GenericResources []GenericResource `json:",omitempty"`
// JobIteration is the JobIteration of the Service that this Task was
// spawned from, if the Service is a ReplicatedJob or GlobalJob. This is
// used to determine which Tasks belong to which run of the job. This field
// is absent if the Service mode is Replicated or Global.
JobIteration *Version `json:",omitempty"`
}
// TaskSpec represents the spec of a task.

View File

@@ -39,7 +39,6 @@ type ImageInspect struct {
Author string
Config *container.Config
Architecture string
Variant string `json:",omitempty"`
Os string
OsVersion string `json:",omitempty"`
Size int64
@@ -154,7 +153,7 @@ type Info struct {
Images int
Driver string
DriverStatus [][2]string
SystemStatus [][2]string `json:",omitempty"` // SystemStatus is only propagated by the Swarm standalone API
SystemStatus [][2]string
Plugins PluginsInfo
MemoryLimit bool
SwapLimit bool
@@ -178,7 +177,6 @@ type Info struct {
NEventsListener int
KernelVersion string
OperatingSystem string
OSVersion string
OSType string
Architecture string
IndexServerAddress string
@@ -194,8 +192,8 @@ type Info struct {
Labels []string
ExperimentalBuild bool
ServerVersion string
ClusterStore string `json:",omitempty"` // Deprecated: host-discovery and overlay networks with external k/v stores are deprecated
ClusterAdvertise string `json:",omitempty"` // Deprecated: host-discovery and overlay networks with external k/v stores are deprecated
ClusterStore string
ClusterAdvertise string
Runtimes map[string]Runtime
DefaultRuntime string
Swarm swarm.Info
@@ -318,7 +316,7 @@ type ContainerState struct {
}
// ContainerNode stores information about the node that a container
// is running on. It's only used by the Docker Swarm standalone API
// is running on. It's only available in Docker Swarm
type ContainerNode struct {
ID string
IPAddress string `json:"IP"`
@@ -342,7 +340,7 @@ type ContainerJSONBase struct {
HostnamePath string
HostsPath string
LogPath string
Node *ContainerNode `json:",omitempty"` // Node is only propagated by Docker Swarm standalone API
Node *ContainerNode `json:",omitempty"`
Name string
RestartCount int
Driver string

View File

@@ -1,7 +1,8 @@
package volume // import "github.com/docker/docker/api/types/volume"
// ----------------------------------------------------------------------------
// Code generated by `swagger generate operation`. DO NOT EDIT.
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------

View File

@@ -1,7 +1,8 @@
package volume // import "github.com/docker/docker/api/types/volume"
// ----------------------------------------------------------------------------
// Code generated by `swagger generate operation`. DO NOT EDIT.
// DO NOT EDIT THIS FILE
// This file was generated by `swagger generate operation`
//
// See hack/generate-swagger-api.sh
// ----------------------------------------------------------------------------

View File

@@ -252,8 +252,7 @@ func (cli *Client) DaemonHost() string {
// HTTPClient returns a copy of the HTTP client bound to the server
func (cli *Client) HTTPClient() *http.Client {
c := *cli.client
return &c
return &*cli.client
}
// ParseHostURL parses a url string, validates the string is a host url, and

View File

@@ -1,4 +1,4 @@
// +build linux freebsd openbsd darwin solaris illumos
// +build linux freebsd openbsd darwin
package client // import "github.com/docker/docker/client"

View File

@@ -35,7 +35,6 @@ func (cli *Client) ContainerList(ctx context.Context, options types.ContainerLis
}
if options.Filters.Len() > 0 {
//nolint:staticcheck // ignore SA1019 for old code
filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters)
if err != nil {

View File

@@ -90,7 +90,6 @@ func buildEventsQueryParams(cliVersion string, options types.EventsOptions) (url
}
if options.Filters.Len() > 0 {
//nolint:staticcheck // ignore SA1019 for old code
filterJSON, err := filters.ToParamWithVersion(cliVersion, options.Filters)
if err != nil {
return nil, err

View File

@@ -24,7 +24,7 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu
}
apiPath := cli.getAPIPath(ctx, path, query)
req, err := http.NewRequest(http.MethodPost, apiPath, bodyEncoded)
req, err := http.NewRequest("POST", apiPath, bodyEncoded)
if err != nil {
return types.HijackedResponse{}, err
}
@@ -40,7 +40,7 @@ func (cli *Client) postHijacked(ctx context.Context, path string, query url.Valu
// DialHijack returns a hijacked connection with negotiated protocol proto.
func (cli *Client) DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error) {
req, err := http.NewRequest(http.MethodPost, url, nil)
req, err := http.NewRequest("POST", url, nil)
if err != nil {
return nil, err
}
@@ -87,8 +87,6 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto
// Server hijacks the connection, error 'connection closed' expected
resp, err := clientconn.Do(req)
//nolint:staticcheck // ignore SA1019 for connecting to old (pre go1.8) daemons
if err != httputil.ErrPersistEOF {
if err != nil {
return nil, err

View File

@@ -14,7 +14,7 @@ import (
// It returns the JSON content in the response body.
func (cli *Client) ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) {
if ref != "" {
// Check if the given image name can be resolved
//Check if the given image name can be resolved
if _, err := reference.ParseNormalizedNamed(ref); err != nil {
return nil, err
}

View File

@@ -24,7 +24,6 @@ func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions
}
}
if optionFilters.Len() > 0 {
//nolint:staticcheck // ignore SA1019 for old code
filterJSON, err := filters.ToParamWithVersion(cli.version, optionFilters)
if err != nil {
return images, err

View File

@@ -25,15 +25,16 @@ func (cli *Client) ImagePush(ctx context.Context, image string, options types.Im
return nil, errors.New("cannot push a digest reference")
}
tag := ""
name := reference.FamiliarName(ref)
query := url.Values{}
if !options.All {
ref = reference.TagNameOnly(ref)
if tagged, ok := ref.(reference.Tagged); ok {
query.Set("tag", tagged.Tag())
}
if nameTaggedRef, isNamedTagged := ref.(reference.NamedTagged); isNamedTagged {
tag = nameTaggedRef.Tag()
}
query := url.Values{}
query.Set("tag", tag)
resp, err := cli.tryImagePush(ctx, name, query, options.RegistryAuth)
if errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {
newAuthHeader, privilegeErr := options.PrivilegeFunc()

View File

@@ -13,7 +13,6 @@ import (
func (cli *Client) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
query := url.Values{}
if options.Filters.Len() > 0 {
//nolint:staticcheck // ignore SA1019 for old code
filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters)
if err != nil {
return nil, err

Some files were not shown because too many files have changed in this diff Show More