test(e2e): Add a test for a single-hop worker (#3690)

* refact(e2e): Add env for workers

* test(e2e): Add test for single-hop worker

* fixup! refact(e2e): Add env for workers

* fixup! test(e2e): Add test for single-hop worker

* fixup! test(e2e): Add test for single-hop worker

* fixup! test(e2e): Add test for single-hop worker

* fixup! test(e2e): Add test for single-hop worker
This commit is contained in:
Michael Li authored and GitHub committed 2023-09-11 14:25:32 -04:00
1 parent 5f66f2fa8e
commit ff34cb629e
20 files changed
+573 -89

No files matched your search

+2 -1
View File
@@ -81,6 +81,7 @@ jobs:
- filter: 'e2e_docker_base builder:crt'
- filter: 'e2e_docker_base_with_vault builder:crt'
- filter: 'e2e_docker_base_with_postgres builder:crt'
- filter: 'e2e_docker_base_with_worker builder:crt'
runs-on: ${{ fromJSON(vars.RUNNER_LARGE) }}
env:
GITHUB_TOKEN: ${{ secrets.SERVICE_USER_GITHUB_TOKEN }}
@@ -184,7 +185,7 @@ jobs:
run: |
wget https://releases.hashicorp.com/vault/1.12.2/vault_1.12.2_linux_amd64.zip -O /tmp/test-deps/vault.zip
- name: Install Vault CLI
if: matrix.filter == 'e2e_aws_base_with_vault builder:crt' || matrix.filter == 'e2e_database' || matrix.filter == 'e2e_ui builder:crt' || matrix.filter == 'e2e_docker_base_with_vault builder:crt'
if: contains(matrix.filter, 'vault') || contains(matrix.filter, 'e2e_docker') || matrix.filter == 'e2e_database' || matrix.filter == 'e2e_ui builder:crt'
run: |
unzip /tmp/test-deps/vault.zip -d /usr/local/bin
- name: GH fix for localhost resolution
+6 -2
View File
@@ -179,6 +179,10 @@ scenario "e2e_aws" {
}
}
locals {
egress_tag = "egress"
}
step "create_isolated_worker" {
module = module.worker
depends_on = [step.create_boundary_cluster]
@@ -194,7 +198,7 @@ scenario "e2e_aws" {
cluster_tag = step.create_boundary_cluster.cluster_tag
controller_addresses = step.create_boundary_cluster.public_controller_addresses
controller_sg_id = step.create_boundary_cluster.controller_aux_sg_id
worker_type_tags = ["worker_e2e_test"]
worker_type_tags = [local.egress_tag]
config_file_path = "templates/worker.hcl"
}
}
@@ -247,7 +251,7 @@ scenario "e2e_aws" {
aws_host_set_filter2 = step.create_tag2_inputs.tag_string
aws_host_set_ips2 = step.create_targets_with_tag2.target_ips
target_address = step.create_isolated_target.target_ips[0]
worker_tags = step.create_isolated_worker.worker_tags
worker_tag_egress = local.egress_tag
}
}
@@ -0,0 +1,187 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: BUSL-1.1
# For this scenario to work, add the following line to /etc/hosts
# 127.0.0.1 localhost boundary
# 127.0.0.1 localhost worker
scenario "e2e_docker_base_with_worker" {
terraform_cli = terraform_cli.default
terraform = terraform.default
providers = [
provider.enos.default
]
matrix {
builder = ["local", "crt"]
}
locals {
aws_ssh_private_key_path = abspath(var.aws_ssh_private_key_path)
local_boundary_dir = abspath(var.local_boundary_dir)
local_boundary_src_dir = abspath(var.local_boundary_src_dir)
boundary_docker_image_file = abspath(var.boundary_docker_image_file)
license_path = abspath(var.boundary_license_path != null ? var.boundary_license_path : joinpath(path.root, "./support/boundary.hclic"))
network_cluster = "e2e_cluster"
network_host = "e2e_host"
network_database = "e2e_db"
build_path = {
"local" = "/tmp",
"crt" = var.crt_bundle_path == null ? null : abspath(var.crt_bundle_path)
}
tags = merge({
"Project Name" : var.project_name
"Project" : "Enos",
"Environment" : "ci"
}, var.tags)
}
step "build_boundary_docker_image" {
module = matrix.builder == "crt" ? module.build_boundary_docker_crt : module.build_boundary_docker_local
variables {
path = matrix.builder == "crt" ? local.boundary_docker_image_file : ""
cli_build_path = local.build_path[matrix.builder]
}
}
step "create_docker_network_database" {
module = module.docker_network
variables {
network_name = local.network_database
}
}
step "create_docker_network_cluster" {
module = module.docker_network
variables {
network_name = local.network_cluster
}
}
step "create_docker_network_host" {
module = module.docker_network
variables {
network_name = local.network_host
}
}
step "create_boundary_database" {
depends_on = [
step.create_docker_network_cluster
]
variables {
image_name = "${var.docker_mirror}/library/postgres:latest"
network_name = [local.network_database]
}
module = module.docker_postgres
}
step "read_license" {
skip_step = var.boundary_edition == "oss"
module = module.read_license
variables {
file_name = local.license_path
}
}
step "create_boundary" {
module = module.docker_boundary
depends_on = [
step.create_docker_network_cluster,
step.create_docker_network_database,
step.create_boundary_database,
step.build_boundary_docker_image
]
variables {
image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
network_name = [local.network_cluster, local.network_database]
database_network = local.network_database
postgres_address = step.create_boundary_database.address
boundary_license = var.boundary_edition != "oss" ? step.read_license.license : ""
}
}
step "create_vault" {
module = module.docker_vault
depends_on = [
step.create_docker_network_cluster
]
variables {
image_name = "${var.docker_mirror}/hashicorp/vault:${var.vault_version}"
network_name = [local.network_cluster]
}
}
step "create_host" {
module = module.docker_openssh_server
depends_on = [
step.create_docker_network_host
]
variables {
image_name = "${var.docker_mirror}/linuxserver/openssh-server:latest"
network_name = [local.network_host]
private_key_file_path = local.aws_ssh_private_key_path
}
}
locals {
egress_tag = "egress"
}
step "create_worker" {
module = module.docker_worker
depends_on = [
step.create_docker_network_cluster,
step.create_docker_network_host,
step.build_boundary_docker_image,
step.create_boundary
]
variables {
image_name = matrix.builder == "crt" ? var.boundary_docker_image_name : step.build_boundary_docker_image.image_name
boundary_license = var.boundary_edition != "oss" ? step.read_license.license : ""
config_file = "worker-config.hcl"
container_name = "worker"
initial_upstream = step.create_boundary.upstream_address
network_name = [local.network_cluster, local.network_host]
tags = [local.egress_tag]
port = "9402"
}
}
step "run_e2e_test" {
module = module.test_e2e_docker
depends_on = [
step.create_boundary,
step.create_vault,
step.create_host,
step.create_worker,
]
variables {
test_package = "github.com/hashicorp/boundary/testing/internal/e2e/tests/base_with_worker"
docker_mirror = var.docker_mirror
network_name = step.create_docker_network_cluster.network_name
go_version = var.go_version
debug_no_run = var.e2e_debug_no_run
alb_boundary_api_addr = step.create_boundary.address
auth_method_id = step.create_boundary.auth_method_id
auth_login_name = step.create_boundary.login_name
auth_password = step.create_boundary.password
local_boundary_dir = step.build_boundary_docker_image.cli_zip_path
local_boundary_src_dir = local.local_boundary_src_dir
aws_ssh_private_key_path = local.aws_ssh_private_key_path
target_address = step.create_host.address
target_port = step.create_host.port
target_user = "ubuntu"
vault_addr = step.create_vault.address
vault_addr_internal = step.create_vault.address_internal
vault_root_token = step.create_vault.token
vault_port = step.create_vault.port
worker_tag_egress = local.egress_tag
worker_tag_collocated = step.create_boundary.worker_tag
}
}
}
@@ -11,6 +11,16 @@ controller {
}
}
worker {
name = "boundary-collocated-worker"
description = "A worker that runs alongside the controller in the same process"
address = "boundary:9202"
tags {
type = ["${worker_type_tag}"]
}
}
listener "tcp" {
address = "boundary:9200"
purpose = "api"
@@ -12,9 +12,13 @@ controller {
}
worker {
name = "boundary-colocated-worker"
name = "boundary-collocated-worker"
description = "A worker that runs alongside the controller in the same process"
address = "boundary:9202"
tags {
type = ["${worker_type_tag}"]
}
}
listener "tcp" {
+10
View File
@@ -49,6 +49,11 @@ variable "config_file" {
type = string
default = "boundary-config.hcl"
}
variable "worker_tag" {
description = "Tag to set on worker for use in worker filters"
type = string
default = "collocated"
}
resource "docker_image" "boundary" {
name = var.image_name
@@ -109,6 +114,7 @@ resource "docker_container" "boundary" {
upload {
content = templatefile("${abspath(path.module)}/${var.config_file}", {
worker_type_tag = var.worker_tag
})
file = "/boundary/boundary-config.hcl"
}
@@ -163,3 +169,7 @@ output "login_name" {
output "password" {
value = local.password
}
output "worker_tag" {
value = var.worker_tag
}
@@ -16,6 +16,7 @@ listener "tcp" {
worker {
name = "${worker_name}"
public_addr = "${worker_name}:${port}"
initial_upstreams = ["${initial_upstream}"]
tags {
@@ -16,6 +16,7 @@ listener "tcp" {
worker {
name = "${worker_name}"
public_addr = "${worker_name}:${port}"
initial_upstreams = ["${initial_upstream}"]
tags {
@@ -16,6 +16,7 @@ listener "tcp" {
worker {
name = "${worker_name}"
public_addr = "${worker_name}:${port}"
initial_upstreams = ["${initial_upstream}"]
tags {
@@ -16,6 +16,7 @@ listener "tcp" {
worker {
name = "${worker_name}"
public_addr = "${worker_name}:${port}"
initial_upstreams = ["${initial_upstream}"]
tags {
+31 -26
View File
@@ -127,9 +127,13 @@ variable "aws_bucket_name" {
type = string
default = ""
}
variable "worker_tags" {
type = list(string)
default = [""]
variable "worker_tag_ingress" {
type = string
default = ""
}
variable "worker_tag_egress" {
type = string
default = ""
}
variable "test_timeout" {
type = string
@@ -151,29 +155,30 @@ locals {
resource "enos_local_exec" "run_e2e_test" {
environment = {
E2E_TESTS = "true",
BOUNDARY_ADDR = var.alb_boundary_api_addr,
BOUNDARY_LICENSE = var.boundary_license,
E2E_PASSWORD_AUTH_METHOD_ID = var.auth_method_id,
E2E_PASSWORD_ADMIN_LOGIN_NAME = var.auth_login_name,
E2E_PASSWORD_ADMIN_PASSWORD = var.auth_password,
E2E_TARGET_ADDRESS = var.target_address,
E2E_TARGET_PORT = var.target_port,
E2E_SSH_USER = var.target_user,
E2E_SSH_KEY_PATH = local.aws_ssh_private_key_path,
E2E_SSH_CA_KEY = "",
VAULT_ADDR = local.vault_addr,
VAULT_TOKEN = var.vault_root_token,
E2E_VAULT_ADDR = local.vault_addr_internal,
E2E_AWS_ACCESS_KEY_ID = var.aws_access_key_id,
E2E_AWS_SECRET_ACCESS_KEY = var.aws_secret_access_key,
E2E_AWS_HOST_SET_FILTER = var.aws_host_set_filter1,
E2E_AWS_HOST_SET_IPS = local.aws_host_set_ips1,
E2E_AWS_HOST_SET_FILTER2 = var.aws_host_set_filter2,
E2E_AWS_HOST_SET_IPS2 = local.aws_host_set_ips2,
E2E_AWS_REGION = var.aws_region,
E2E_AWS_BUCKET_NAME = var.aws_bucket_name,
E2E_WORKER_TAG = jsonencode(var.worker_tags),
E2E_TESTS = "true"
BOUNDARY_ADDR = var.alb_boundary_api_addr
BOUNDARY_LICENSE = var.boundary_license
E2E_PASSWORD_AUTH_METHOD_ID = var.auth_method_id
E2E_PASSWORD_ADMIN_LOGIN_NAME = var.auth_login_name
E2E_PASSWORD_ADMIN_PASSWORD = var.auth_password
E2E_TARGET_ADDRESS = var.target_address
E2E_TARGET_PORT = var.target_port
E2E_SSH_USER = var.target_user
E2E_SSH_KEY_PATH = local.aws_ssh_private_key_path
E2E_SSH_CA_KEY = ""
VAULT_ADDR = local.vault_addr
VAULT_TOKEN = var.vault_root_token
E2E_VAULT_ADDR = local.vault_addr_internal
E2E_AWS_ACCESS_KEY_ID = var.aws_access_key_id
E2E_AWS_SECRET_ACCESS_KEY = var.aws_secret_access_key
E2E_AWS_HOST_SET_FILTER = var.aws_host_set_filter1
E2E_AWS_HOST_SET_IPS = local.aws_host_set_ips1
E2E_AWS_HOST_SET_FILTER2 = var.aws_host_set_filter2
E2E_AWS_HOST_SET_IPS2 = local.aws_host_set_ips2
E2E_AWS_REGION = var.aws_region
E2E_AWS_BUCKET_NAME = var.aws_bucket_name
E2E_WORKER_TAG_INGRESS = var.worker_tag_ingress
E2E_WORKER_TAG_EGRESS = var.worker_tag_egress
}
inline = var.debug_no_run ? [""] : [
+42 -32
View File
@@ -160,9 +160,17 @@ variable "aws_bucket_name" {
type = string
default = ""
}
variable "worker_tags" {
type = list(string)
default = [""]
variable "worker_tag_ingress" {
type = string
default = ""
}
variable "worker_tag_egress" {
type = string
default = ""
}
variable "worker_tag_collocated" {
type = string
default = ""
}
variable "postgres_user" {
type = string
@@ -206,38 +214,40 @@ resource "docker_image" "go" {
resource "enos_local_exec" "run_e2e_test" {
depends_on = [docker_image.go]
environment = {
TEST_PACKAGE = var.test_package,
TEST_TIMEOUT = var.test_timeout,
TEST_RUNNER_IMAGE = docker_image.go.image_id,
TEST_NETWORK_NAME = var.network_name,
E2E_TESTS = "true",
BOUNDARY_ADDR = var.alb_boundary_api_addr,
E2E_PASSWORD_AUTH_METHOD_ID = var.auth_method_id,
E2E_PASSWORD_ADMIN_LOGIN_NAME = var.auth_login_name,
E2E_PASSWORD_ADMIN_PASSWORD = var.auth_password,
E2E_TARGET_ADDRESS = var.target_address,
E2E_TARGET_PORT = var.target_port,
E2E_SSH_USER = var.target_user,
E2E_SSH_KEY_PATH = local.aws_ssh_private_key_path,
E2E_SSH_CA_KEY = var.target_ca_key,
VAULT_ADDR = local.vault_addr,
VAULT_ADDR_INTERNAL = local.vault_addr_internal,
VAULT_TOKEN = var.vault_root_token,
E2E_VAULT_ADDR = local.vault_addr_internal,
E2E_AWS_ACCESS_KEY_ID = var.aws_access_key_id,
E2E_AWS_SECRET_ACCESS_KEY = var.aws_secret_access_key,
E2E_AWS_HOST_SET_FILTER = var.aws_host_set_filter1,
E2E_AWS_HOST_SET_IPS = local.aws_host_set_ips1,
E2E_AWS_HOST_SET_FILTER2 = var.aws_host_set_filter2,
E2E_AWS_HOST_SET_IPS2 = local.aws_host_set_ips2,
E2E_AWS_REGION = var.aws_region,
E2E_AWS_BUCKET_NAME = var.aws_bucket_name,
E2E_WORKER_TAG = jsonencode(var.worker_tags),
TEST_PACKAGE = var.test_package
TEST_TIMEOUT = var.test_timeout
TEST_RUNNER_IMAGE = docker_image.go.image_id
TEST_NETWORK_NAME = var.network_name
E2E_TESTS = "true"
BOUNDARY_ADDR = var.alb_boundary_api_addr
E2E_PASSWORD_AUTH_METHOD_ID = var.auth_method_id
E2E_PASSWORD_ADMIN_LOGIN_NAME = var.auth_login_name
E2E_PASSWORD_ADMIN_PASSWORD = var.auth_password
E2E_TARGET_ADDRESS = var.target_address
E2E_TARGET_PORT = var.target_port
E2E_SSH_USER = var.target_user
E2E_SSH_KEY_PATH = local.aws_ssh_private_key_path
E2E_SSH_CA_KEY = var.target_ca_key
VAULT_ADDR = local.vault_addr
VAULT_ADDR_INTERNAL = local.vault_addr_internal
VAULT_TOKEN = var.vault_root_token
E2E_VAULT_ADDR = local.vault_addr_internal
E2E_AWS_ACCESS_KEY_ID = var.aws_access_key_id
E2E_AWS_SECRET_ACCESS_KEY = var.aws_secret_access_key
E2E_AWS_HOST_SET_FILTER = var.aws_host_set_filter1
E2E_AWS_HOST_SET_IPS = local.aws_host_set_ips1
E2E_AWS_HOST_SET_FILTER2 = var.aws_host_set_filter2
E2E_AWS_HOST_SET_IPS2 = local.aws_host_set_ips2
E2E_AWS_REGION = var.aws_region
E2E_AWS_BUCKET_NAME = var.aws_bucket_name
E2E_POSTGRES_USER = var.postgres_user
E2E_POSTGRES_PASSWORD = var.postgres_password
E2E_POSTGRES_DB_NAME = var.postgres_database_name
BOUNDARY_DIR = abspath(var.local_boundary_src_dir),
BOUNDARY_CLI_DIR = abspath(var.local_boundary_dir),
E2E_WORKER_TAG_INGRESS = var.worker_tag_ingress
E2E_WORKER_TAG_EGRESS = var.worker_tag_egress
E2E_WORKER_TAG_COLLOCATED = var.worker_tag_collocated
BOUNDARY_DIR = abspath(var.local_boundary_src_dir)
BOUNDARY_CLI_DIR = abspath(var.local_boundary_dir)
MODULE_DIR = abspath(path.module)
}
+4 -2
View File
@@ -18,8 +18,8 @@ docker run \
-e "E2E_PASSWORD_ADMIN_LOGIN_NAME=$E2E_PASSWORD_ADMIN_LOGIN_NAME" \
-e "E2E_PASSWORD_ADMIN_PASSWORD=$E2E_PASSWORD_ADMIN_PASSWORD" \
-e "E2E_TARGET_ADDRESS=$E2E_TARGET_ADDRESS" \
-e "E2E_SSH_USER=$E2E_SSH_USER" \
-e "E2E_TARGET_PORT=$E2E_TARGET_PORT" \
-e "E2E_SSH_USER=$E2E_SSH_USER" \
-e "E2E_SSH_CA_KEY=$E2E_SSH_CA_KEY" \
-e "E2E_SSH_KEY_PATH=/keys/target.pem" \
-e "VAULT_ADDR=$VAULT_ADDR_INTERNAL" \
@@ -36,7 +36,9 @@ docker run \
-e "E2E_POSTGRES_USER=$E2E_POSTGRES_USER" \
-e "E2E_POSTGRES_PASSWORD=$E2E_POSTGRES_PASSWORD" \
-e "E2E_POSTGRES_DB_NAME=$E2E_POSTGRES_DB_NAME" \
-e "E2E_WORKER_TAG=$E2E_WORKER_TAG" \
-e "E2E_WORKER_TAG_INGRESS=$E2E_WORKER_TAG_INGRESS" \
-e "E2E_WORKER_TAG_EGRESS=$E2E_WORKER_TAG_EGRESS" \
-e "E2E_WORKER_TAG_COLLOCATED=$E2E_WORKER_TAG_COLLOCATED" \
--mount type=bind,src=$BOUNDARY_DIR,dst=/src/boundary/ \
--mount type=bind,src=$MODULE_DIR/../..,dst=/testlogs \
--mount type=bind,src=$(go env GOCACHE),dst=/root/.cache/go-build \
+16 -17
View File
@@ -128,23 +128,22 @@ locals {
resource "enos_local_exec" "run_e2e_ui_test" {
environment = {
BOUNDARY_ADDR = var.alb_boundary_api_addr,
E2E_PASSWORD_AUTH_METHOD_ID = var.auth_method_id,
E2E_PASSWORD_ADMIN_LOGIN_NAME = var.auth_login_name,
E2E_PASSWORD_ADMIN_PASSWORD = var.auth_password,
E2E_TARGET_ADDRESS = var.target_address,
E2E_TARGET_PORT = var.target_port,
E2E_SSH_USER = var.target_user,
E2E_SSH_KEY_PATH = local.aws_ssh_private_key_path,
VAULT_ADDR = local.vault_addr,
VAULT_TOKEN = var.vault_root_token,
E2E_VAULT_ADDR = local.vault_addr_internal,
E2E_AWS_ACCESS_KEY_ID = var.aws_access_key_id,
E2E_AWS_SECRET_ACCESS_KEY = var.aws_secret_access_key,
E2E_AWS_HOST_SET_FILTER = var.aws_host_set_filter1,
E2E_AWS_HOST_SET_IPS = local.aws_host_set_ips1,
E2E_AWS_HOST_SET_FILTER2 = var.aws_host_set_filter2,
E2E_AWS_HOST_SET_IPS2 = local.aws_host_set_ips2
BOUNDARY_ADDR = var.alb_boundary_api_addr
E2E_PASSWORD_AUTH_METHOD_ID = var.auth_method_id
E2E_PASSWORD_ADMIN_LOGIN_NAME = var.auth_login_name
E2E_PASSWORD_ADMIN_PASSWORD = var.auth_password
E2E_TARGET_ADDRESS = var.target_address
E2E_TARGET_PORT = var.target_port
E2E_SSH_USER = var.target_user
E2E_SSH_KEY_PATH = local.aws_ssh_private_key_path
VAULT_ADDR = local.vault_addr
VAULT_TOKEN = var.vault_root_token
E2E_VAULT_ADDR = local.vault_addr_internal
E2E_AWS_ACCESS_KEY_ID = var.aws_access_key_id
E2E_AWS_SECRET_ACCESS_KEY = var.aws_secret_access_key
E2E_AWS_HOST_SET_FILTER = var.aws_host_set_filter1
E2E_AWS_HOST_SET_IPS = local.aws_host_set_ips1
E2E_AWS_HOST_SET_FILTER2 = var.aws_host_set_filter2
}
inline = var.debug_no_run ? [""] : ["set -o pipefail; PATH=\"${var.local_boundary_dir}:$PATH\" yarn --cwd ${var.local_boundary_ui_src_dir}/ui/admin run e2e 2>&1 | tee ${path.module}/../../test-e2e-ui.log"]
+3
View File
@@ -83,6 +83,9 @@ func CreateNewTargetCli(t testing.TB, ctx context.Context, projectId string, def
if opts.WithIngressWorkerFilter != "" {
args = append(args, "-ingress-worker-filter", opts.WithIngressWorkerFilter)
}
if opts.WithEgressWorkerFilter != "" {
args = append(args, "-egress-worker-filter", opts.WithEgressWorkerFilter)
}
output := e2e.RunCommand(ctx, "boundary",
e2e.WithArgs("targets", "create"),
+1 -1
View File
@@ -18,7 +18,7 @@ type config struct {
TargetSshUser string `envconfig:"E2E_SSH_USER" required:"true"` // e.g. "ubuntu"
TargetPort string `envconfig:"E2E_TARGET_PORT" required:"true"` // e.g. "22"
TargetAddress string `envconfig:"E2E_TARGET_ADDRESS" required:"true"` // e.g. "192.168.0.1"
WorkerTags string `envconfig:"E2E_WORKER_TAG" required:"true"` // e.g. "[\"tag1\", \"tag2\"]"
WorkerTagEgress string `envconfig:"E2E_WORKER_TAG_EGRESS" required:"true"` // e.g. "egress"
}
func loadTestConfig() (*config, error) {
@@ -5,7 +5,6 @@ package aws_test
import (
"context"
"encoding/json"
"fmt"
"testing"
@@ -67,17 +66,12 @@ func TestCliWorker(t *testing.T) {
t.Logf("Successfully detected connection failure")
// Set correct worker filter, expect connection success
var workerTags []string
err = json.Unmarshal([]byte(c.WorkerTags), &workerTags)
require.NoError(t, err)
require.NotEmpty(t, workerTags)
t.Logf("Setting correct worker filter...")
output = e2e.RunCommand(ctx, "boundary",
e2e.WithArgs(
"targets", "update", "tcp",
"-id", newTargetId,
"-egress-worker-filter", fmt.Sprintf(`"%s" in "/tags/type"`, workerTags[0]),
"-egress-worker-filter", fmt.Sprintf(`"%s" in "/tags/type"`, c.WorkerTagEgress),
"-format", "json",
),
)
@@ -0,0 +1,29 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package base_with_worker_test
import "github.com/kelseyhightower/envconfig"
type config struct {
TargetAddress string `envconfig:"E2E_TARGET_ADDRESS" required:"true"` // e.g. 192.168.0.1
TargetPort string `envconfig:"E2E_TARGET_PORT" required:"true"` // e.g. 22
TargetSshUser string `envconfig:"E2E_SSH_USER" required:"true"` // e.g. ubuntu
TargetSshKeyPath string `envconfig:"E2E_SSH_KEY_PATH" required:"true"` // e.g. /Users/username/key.pem
WorkerTagIngress string `envconfig:"E2E_WORKER_TAG_INGRESS" required:"true"` // e.g. "ingress"
WorkerTagEgress string `envconfig:"E2E_WORKER_TAG_EGRESS" required:"true"` // e.g. "egress"
WorkerTagCollocated string `envconfig:"E2E_WORKER_TAG_COLLOCATED" required:"true"` // e.g. "collocated"
// VaultAddr is the address that the Boundary server uses to interact with the running Vault instance
VaultAddr string `envconfig:"E2E_VAULT_ADDR" required:"true"` // e.g. "http://127.0.0.1:8200"
VaultSecretPath string `envconfig:"E2E_VAULT_SECRET_PATH" default:"e2e_secrets"`
}
func loadTestConfig() (*config, error) {
var c config
err := envconfig.Process("", &c)
if err != nil {
return nil, err
}
return &c, nil
}
@@ -0,0 +1,196 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package base_with_worker_test
import (
"context"
"encoding/json"
"fmt"
"strings"
"testing"
"github.com/hashicorp/boundary/api/credentiallibraries"
"github.com/hashicorp/boundary/internal/target"
"github.com/hashicorp/boundary/testing/internal/e2e"
"github.com/hashicorp/boundary/testing/internal/e2e/boundary"
"github.com/hashicorp/boundary/testing/internal/e2e/vault"
"github.com/stretchr/testify/require"
)
// TestCliTcpTargetWorkerConnectTarget uses the boundary cli to do the
// following...
// - create a target with an egress worker filter and confirm that you can
// connect to it
// - update the target to use a worker filter that can't reach the host and
// confirm that you cannot connect to it
// - attempt to create a target with an ingress worker filter and confirm that
// the operation fails
// Note: This test is specific to the community version
func TestCliTcpTargetWorkerConnectTarget(t *testing.T) {
e2e.MaybeSkipTest(t)
c, err := loadTestConfig()
require.NoError(t, err)
ctx := context.Background()
boundary.AuthenticateAdminCli(t, ctx)
newOrgId := boundary.CreateNewOrgCli(t, ctx)
t.Cleanup(func() {
ctx := context.Background()
boundary.AuthenticateAdminCli(t, ctx)
output := e2e.RunCommand(ctx, "boundary", e2e.WithArgs("scopes", "delete", "-id", newOrgId))
require.NoError(t, output.Err, string(output.Stderr))
})
newProjectId := boundary.CreateNewProjectCli(t, ctx, newOrgId)
newTargetId := boundary.CreateNewTargetCli(
t,
ctx,
newProjectId,
c.TargetPort,
target.WithAddress("openssh-server"),
target.WithEgressWorkerFilter(fmt.Sprintf(`"%s" in "/tags/type"`, c.WorkerTagEgress)),
)
// Configure vault
boundaryPolicyName, kvPolicyFilePath := vault.Setup(t)
t.Cleanup(func() {
output := e2e.RunCommand(ctx, "vault",
e2e.WithArgs("policy", "delete", boundaryPolicyName),
)
require.NoError(t, output.Err, string(output.Stderr))
})
output := e2e.RunCommand(ctx, "vault",
e2e.WithArgs("secrets", "enable", fmt.Sprintf("-path=%s", c.VaultSecretPath), "kv-v2"),
)
require.NoError(t, output.Err, string(output.Stderr))
t.Cleanup(func() {
output := e2e.RunCommand(ctx, "vault",
e2e.WithArgs("secrets", "disable", c.VaultSecretPath),
)
require.NoError(t, output.Err, string(output.Stderr))
})
// Create credential in vault
privateKeySecretName := vault.CreateKvPrivateKeyCredential(t, c.VaultSecretPath, c.TargetSshUser, c.TargetSshKeyPath, kvPolicyFilePath)
kvPolicyName := vault.WritePolicy(t, ctx, kvPolicyFilePath)
t.Cleanup(func() {
output := e2e.RunCommand(ctx, "vault",
e2e.WithArgs("policy", "delete", kvPolicyName),
)
require.NoError(t, output.Err, string(output.Stderr))
})
t.Log("Created Vault Credential")
// Create vault token for boundary
output = e2e.RunCommand(ctx, "vault",
e2e.WithArgs(
"token", "create",
"-no-default-policy=true",
fmt.Sprintf("-policy=%s", boundaryPolicyName),
fmt.Sprintf("-policy=%s", kvPolicyName),
"-orphan=true",
"-period=20m",
"-renewable=true",
"-format=json",
),
)
require.NoError(t, output.Err, string(output.Stderr))
var tokenCreateResult vault.CreateTokenResponse
err = json.Unmarshal(output.Stdout, &tokenCreateResult)
require.NoError(t, err)
credStoreToken := tokenCreateResult.Auth.Client_Token
t.Log("Created Vault Cred Store Token")
// Create a credential store
newCredentialStoreId := boundary.CreateNewCredentialStoreVaultCli(t, ctx, newProjectId, c.VaultAddr, credStoreToken)
// Create a credential library
output = e2e.RunCommand(ctx, "boundary",
e2e.WithArgs(
"credential-libraries", "create", "vault",
"-credential-store-id", newCredentialStoreId,
"-vault-path", fmt.Sprintf("%s/data/%s", c.VaultSecretPath, privateKeySecretName),
"-name", "e2e Automated Test Vault Credential Library",
"-credential-type", "ssh_private_key",
"-format", "json",
),
)
require.NoError(t, output.Err, string(output.Stderr))
var newCredentialLibraryResult credentiallibraries.CredentialLibraryCreateResult
err = json.Unmarshal(output.Stdout, &newCredentialLibraryResult)
require.NoError(t, err)
newCredentialLibraryId := newCredentialLibraryResult.Item.Id
t.Logf("Created Credential Library: %s", newCredentialLibraryId)
// Add brokered credentials to target
boundary.AddBrokeredCredentialSourceToTargetCli(t, ctx, newTargetId, newCredentialLibraryId)
// Connect to target and print host's IP address using retrieved credentials
output = e2e.RunCommand(ctx, "boundary",
e2e.WithArgs(
"connect", "ssh",
"-target-id", newTargetId,
"-remote-command", "hostname -i",
"--",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "StrictHostKeyChecking=no",
"-o", "IdentitiesOnly=yes", // forces the use of the provided key
),
)
// Note: If this test fails due to: "Unable to connect to worker at
// worker:9402", modify your /etc/hosts file to contain...
// `127.0.0.1 localhost worker``
require.NoError(t, output.Err, string(output.Stderr))
require.Equal(t, c.TargetAddress, strings.TrimSpace(string(output.Stdout)))
t.Log("Successfully connected to target")
// Update the egress filter to one that can't access the target
output = e2e.RunCommand(ctx, "boundary",
e2e.WithArgs(
"targets", "update", "tcp",
"-id", newTargetId,
"-egress-worker-filter", fmt.Sprintf(`"%s" in "/tags/type"`, c.WorkerTagCollocated),
),
)
require.NoError(t, output.Err, string(output.Stderr))
output = e2e.RunCommand(ctx, "boundary",
e2e.WithArgs(
"connect", "ssh",
"-target-id", newTargetId,
"-remote-command", "hostname -i",
"--",
"-o", "UserKnownHostsFile=/dev/null",
"-o", "StrictHostKeyChecking=no",
"-o", "IdentitiesOnly=yes", // forces the use of the provided key
),
)
require.Error(t, output.Err)
require.Equal(t, output.ExitCode, 255)
t.Log("Successfully failed to connect to target with wrong worker filter")
// Try creating targets with an ingress worker filter. This should result in
// an error
output = e2e.RunCommand(ctx, "boundary",
e2e.WithArgs(
"targets", "create", "tcp",
"-name", "Target with Ingress Filter",
"-scope-id", newProjectId,
"-default-port", c.TargetPort,
"-ingress-worker-filter", `"tag" in "/tags/type"`,
),
)
require.Error(t, output.Err, "Unexpectedly created a target with an ingress worker filter")
output = e2e.RunCommand(ctx, "boundary",
e2e.WithArgs(
"targets", "create", "tcp",
"-name", "Target with Ingress Filter",
"-scope-id", newProjectId,
"-default-port", c.TargetPort,
"-ingress-worker-filter", `"tag" in "/tags/type"`,
"-egress-worker-filter", fmt.Sprintf(`"%s" in "/tags/type"`, c.WorkerTagEgress),
),
)
require.Error(t, output.Err, "Unexpectedly created a target with an ingress worker filter")
}
@@ -0,0 +1,26 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: BUSL-1.1
path "auth/token/lookup-self" {
capabilities = ["read"]
}
path "auth/token/renew-self" {
capabilities = ["update"]
}
path "auth/token/revoke-self" {
capabilities = ["update"]
}
path "sys/leases/renew" {
capabilities = ["update"]
}
path "sys/leases/revoke" {
capabilities = ["update"]
}
path "sys/capabilities-self" {
capabilities = ["update"]
}