Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement multi provider support #59

Merged
merged 7 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Run the test suite:

```shell
make test
make test-e2e
```

Run linters:
Expand Down
2 changes: 0 additions & 2 deletions common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ type Config struct {
LogServer string `json:"log_server"`
Daemon bool `json:"daemon"`
Delay time.Duration `json:"delay"`
Provider string `json:"provider"`
}

func LoadConfig() (*Config, error) {
Expand All @@ -46,6 +45,5 @@ func LoadConfig() (*Config, error) {
LogServer: os.Getenv(LogServerEnv),
Daemon: cast.ToBool(os.Getenv(DaemonEnv)),
Delay: cast.ToDuration(os.Getenv(DelayEnv)),
Provider: os.Getenv(ProviderEnv),
}, nil
}
8 changes: 1 addition & 7 deletions common/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,12 @@ func TestConfig(t *testing.T) {
JSONLogEnv: "true",
LogServerEnv: "",
DaemonEnv: "true",
ProviderEnv: "vault",
},
wantConfig: &Config{
LogLevel: "debug",
JSONLog: true,
LogServer: "",
Daemon: true,
Provider: "vault",
},
},
}
Expand All @@ -52,16 +50,12 @@ func TestConfig(t *testing.T) {
for envKey, envVal := range ttp.env {
os.Setenv(envKey, envVal)
}
defer os.Clearenv()

config, err := LoadConfig()
assert.Nil(t, err, "Unexpected error")

assert.Equal(t, ttp.wantConfig, config, "Unexpected config")

// unset envs for the next test
for envKey := range ttp.env {
os.Unsetenv(envKey)
}
})
}
}
34 changes: 22 additions & 12 deletions e2e/file-provider.bats
ramizpolic marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,40 @@ setup() {
bats_load_library bats-support
bats_load_library bats-assert

setup_pod

run go build
assert_success
}

setup_pod() {
TMPFILE=$(mktemp)
printf "secret-value" > "$TMPFILE"
setup_file_provider() {
add_secret_file

export SECRET_INIT_PROVIDER="file"
export FILE_MOUNT_PATH="/"
export Secret="file:$TMPFILE"

export FILE_SECRET="file:$TMPFILE_SECRET"
}

add_secret_file() {
TMPFILE_SECRET=$(mktemp)
printf "secret-value" > "$TMPFILE_SECRET"
}

teardown() {
rm -f "$TMPFILE"
rm -f "$TMPFILE_SECRET"
rm -f secret-init
}

@test "secret successfully loaded" {
run_output=$(./secret-init env | grep Secret)
assert_output_contains() {
local expected=$1
local output=$2

echo "$output" | grep -qF "$expected" || fail "Expected line not found: $expected"
}

@test "secret successfully loaded from file" {
setup_file_provider

run_output=$(./secret-init env | grep FILE_SECRET)
assert_success
expected_output="Secret=secret-value"

assert_equal "$run_output" "$expected_output"
assert_output_contains "FILE_SECRET=secret-value" "$run_output"
}
174 changes: 174 additions & 0 deletions e2e/multi-provider.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
vault_container_name="vault"

setup() {
bats_load_library bats-support
bats_load_library bats-assert

run go build
assert_success
}

setup_file_provider() {
add_secret_file

export FILE_MOUNT_PATH="/"

export FILE_SECRET="file:$TMPFILE_SECRET"
}

add_secret_file() {
TMPFILE_SECRET=$(mktemp)
printf "secret-value" > "$TMPFILE_SECRET"
}

setup_vault_provider() {
TMPFILE_TOKEN=$(mktemp)
printf "227e1cce-6bf7-30bb-2d2a-acc854318caf" > "$TMPFILE_TOKEN"

export VAULT_ADDR="http://127.0.0.1:8200"
export VAULT_TOKEN_FILE="$TMPFILE_TOKEN"

export MYSQL_PASSWORD=vault:secret/data/test/mysql#MYSQL_PASSWORD
export AWS_SECRET_ACCESS_KEY=vault:secret/data/test/aws#AWS_SECRET_ACCESS_KEY
export AWS_ACCESS_KEY_ID=vault:secret/data/test/aws#AWS_ACCESS_KEY_ID

start_vault
}

start_vault() {
docker compose up -d

# wait for Vault to be ready
max_attempts=${MAX_ATTEMPTS:-10}

for ((attempts = 0; attempts < max_attempts; attempts++)); do
if docker compose exec -T "$vault_container_name" vault status > /dev/null 2>&1; then
break
fi
sleep 1
done
}

set_vault_token() {
local token=$1
export VAULT_TOKEN="$token"
}

set_daemon_mode() {
export SECRET_INIT_DAEMON="true"
}

add_secrets_to_vault() {
docker exec "$vault_container_name" vault kv put secret/test/mysql MYSQL_PASSWORD=3xtr3ms3cr3t
docker exec "$vault_container_name" vault kv put secret/test/aws AWS_ACCESS_KEY_ID=secretId AWS_SECRET_ACCESS_KEY=s3cr3t
}

remove_secrets_from_vault() {
docker exec "$vault_container_name" vault kv delete secret/test/mysql
docker exec "$vault_container_name" vault kv delete secret/test/aws
}

teardown() {
stop_vault

rm -f "$TMPFILE_SECRET"
rm -f "$TMPFILE_TOKEN"
rm -f secret-init
}

stop_vault() {
remove_secrets_from_vault
docker compose down
}

assert_output_contains() {
local expected=$1
local output=$2

echo "$output" | grep -qF "$expected" || fail "Expected line not found: $expected"
}

check_process_status() {
local process_name="$1"

if pgrep -f "$process_name" > /dev/null; then
echo "Process is running"
else
echo "Process is not running"
fi
}

@test "secrets successfully loaded" {
setup_file_provider

setup_vault_provider
set_vault_token 227e1cce-6bf7-30bb-2d2a-acc854318caf
add_secrets_to_vault

run_output=$(./secret-init env | grep 'MYSQL_PASSWORD\|AWS_SECRET_ACCESS_KEY\|AWS_ACCESS_KEY_ID\|FILE_SECRET')
assert_success

assert_output_contains "MYSQL_PASSWORD=3xtr3ms3cr3t" "$run_output"
assert_output_contains "AWS_SECRET_ACCESS_KEY=s3cr3t" "$run_output"
assert_output_contains "AWS_ACCESS_KEY_ID=secretId" "$run_output"
assert_output_contains "FILE_SECRET=secret-value" "$run_output"
}

@test "secrets successfully loaded using vault:login as token" {
setup_file_provider

setup_vault_provider
set_vault_token "vault:login"
add_secrets_to_vault

run_output=$(./secret-init env | grep 'MYSQL_PASSWORD\|AWS_SECRET_ACCESS_KEY\|AWS_ACCESS_KEY_ID\|FILE_SECRET')
assert_success

assert_output_contains "MYSQL_PASSWORD=3xtr3ms3cr3t" "$run_output"
assert_output_contains "AWS_SECRET_ACCESS_KEY=s3cr3t" "$run_output"
assert_output_contains "AWS_ACCESS_KEY_ID=secretId" "$run_output"
assert_output_contains "FILE_SECRET=secret-value" "$run_output"
}

@test "secrets successfully loaded from vault using vault:login as token and daemon mode enabled" {
setup_file_provider

setup_vault_provider
set_vault_token "vault:login"
set_daemon_mode
add_secrets_to_vault

run_output=$(./secret-init env | grep 'MYSQL_PASSWORD\|AWS_SECRET_ACCESS_KEY\|AWS_ACCESS_KEY_ID\|FILE_SECRET')
assert_success

assert_output_contains "MYSQL_PASSWORD=3xtr3ms3cr3t" "$run_output"
assert_output_contains "AWS_SECRET_ACCESS_KEY=s3cr3t" "$run_output"
assert_output_contains "AWS_ACCESS_KEY_ID=secretId" "$run_output"
assert_output_contains "FILE_SECRET=secret-value" "$run_output"

# Check if the process is still running in the background
check_process_status "secret-init env"
assert_success
}

@test "secrets successfully loaded using VAULT_FROM_PATH" {
# unset env vars to ensure secret-init will utilize VAULT_FROM_PATH
unset MYSQL_PASSWORD
unset AWS_SECRET_ACCESS_KEY
unset AWS_ACCESS_KEY_ID

setup_file_provider

setup_vault_provider
set_vault_token 227e1cce-6bf7-30bb-2d2a-acc854318caf
add_secrets_to_vault
export VAULT_FROM_PATH="secret/data/test/mysql,secret/data/test/aws"

run_output=$(./secret-init env | grep 'MYSQL_PASSWORD\|AWS_SECRET_ACCESS_KEY\|AWS_ACCESS_KEY_ID\|FILE_SECRET')
assert_success

assert_output_contains "MYSQL_PASSWORD=3xtr3ms3cr3t" "$run_output"
assert_output_contains "AWS_SECRET_ACCESS_KEY=s3cr3t" "$run_output"
assert_output_contains "AWS_ACCESS_KEY_ID=secretId" "$run_output"
assert_output_contains "FILE_SECRET=secret-value" "$run_output"
}
47 changes: 24 additions & 23 deletions e2e/vault-provider.bats
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,24 @@ setup() {
bats_load_library bats-support
bats_load_library bats-assert

start_vault

setup_pod

run go build
assert_success
}

setup_vault_provider() {
TMPFILE_TOKEN=$(mktemp)
printf "227e1cce-6bf7-30bb-2d2a-acc854318caf" > "$TMPFILE_TOKEN"

export VAULT_ADDR="http://127.0.0.1:8200"
export VAULT_TOKEN_FILE="$TMPFILE_TOKEN"

export MYSQL_PASSWORD=vault:secret/data/test/mysql#MYSQL_PASSWORD
export AWS_SECRET_ACCESS_KEY=vault:secret/data/test/aws#AWS_SECRET_ACCESS_KEY
export AWS_ACCESS_KEY_ID=vault:secret/data/test/aws#AWS_ACCESS_KEY_ID

start_vault
}

start_vault() {
docker compose up -d

Expand All @@ -26,19 +36,6 @@ start_vault() {
done
}

setup_pod() {
TMPFILE=$(mktemp)
printf "227e1cce-6bf7-30bb-2d2a-acc854318caf" > "$TMPFILE"

export SECRET_INIT_PROVIDER="vault"
export VAULT_ADDR="http://127.0.0.1:8200"
export VAULT_TOKEN_FILE="$TMPFILE"

export MYSQL_PASSWORD=vault:secret/data/test/mysql#MYSQL_PASSWORD
export AWS_SECRET_ACCESS_KEY=vault:secret/data/test/aws#AWS_SECRET_ACCESS_KEY
export AWS_ACCESS_KEY_ID=vault:secret/data/test/aws#AWS_ACCESS_KEY_ID
}

set_vault_token() {
local token=$1
export VAULT_TOKEN="$token"
Expand All @@ -53,10 +50,15 @@ add_secrets_to_vault() {
docker exec "$vault_container_name" vault kv put secret/test/aws AWS_ACCESS_KEY_ID=secretId AWS_SECRET_ACCESS_KEY=s3cr3t
}

remove_secrets_from_vault() {
docker exec "$vault_container_name" vault kv delete secret/test/mysql
docker exec "$vault_container_name" vault kv delete secret/test/aws
}

teardown() {
stop_vault

rm -f "$TMPFILE"
rm -f "$TMPFILE_TOKEN"
rm -f secret-init
}

Expand All @@ -65,11 +67,6 @@ stop_vault() {
docker compose down
}

remove_secrets_from_vault() {
docker exec "$vault_container_name" vault kv delete secret/test/mysql
docker exec "$vault_container_name" vault kv delete secret/test/aws
}

assert_output_contains() {
local expected=$1
local output=$2
Expand All @@ -89,6 +86,7 @@ check_process_status() {


@test "secrets successfully loaded from vault" {
setup_vault_provider
set_vault_token 227e1cce-6bf7-30bb-2d2a-acc854318caf
add_secrets_to_vault

Expand All @@ -101,6 +99,7 @@ check_process_status() {
}

@test "secrets successfully loaded from vault using vault:login as token" {
setup_vault_provider
set_vault_token "vault:login"
add_secrets_to_vault

Expand All @@ -113,6 +112,7 @@ check_process_status() {
}

@test "secrets successfully loaded from vault using vault:login as token and daemon mode enabled" {
setup_vault_provider
set_vault_token "vault:login"
set_daemon_mode
add_secrets_to_vault
Expand All @@ -135,6 +135,7 @@ check_process_status() {
unset AWS_SECRET_ACCESS_KEY
unset AWS_ACCESS_KEY_ID

setup_vault_provider
set_vault_token 227e1cce-6bf7-30bb-2d2a-acc854318caf
add_secrets_to_vault
export VAULT_FROM_PATH="secret/data/test/mysql,secret/data/test/aws"
Expand Down
Loading
Loading