test(e2e): Add test for controller-led worker registration (#3882)
* test(e2e): Add test for controller led worker registration * chore(e2e): Rename log files to ensure uniqueness This updates the log files to be based on the scenario name instead of just the test package in case some scenarios run the same test package
This commit is contained in:
1 parent
c93edfb612
commit
f0a4bce17c
8 files changed
+376
-1
No files matched your search
@@ -82,6 +82,7 @@ jobs:
|
||||
- filter: 'e2e_docker_base_with_vault builder:crt'
|
||||
- filter: 'e2e_docker_base_with_postgres builder:crt'
|
||||
- filter: 'e2e_docker_base_with_worker builder:crt'
|
||||
- filter: 'e2e_docker_worker_registration_controller_led builder:crt'
|
||||
runs-on: ${{ fromJSON(vars.RUNNER_LARGE) }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.SERVICE_USER_GITHUB_TOKEN }}
|
||||
@@ -248,11 +249,17 @@ jobs:
|
||||
mkdir -p ./enos/terraform-plugin-cache
|
||||
export ENOS_VAR_enos_user=$GITHUB_ACTOR && \
|
||||
enos scenario launch --timeout 60m0s --chdir ./enos ${{ matrix.filter }}
|
||||
- name: Rename e2e tests output
|
||||
run : |
|
||||
pushd enos
|
||||
scenario="${{ matrix.filter }}"
|
||||
for f in *.log; do mv -- "$f" "${f%.log}_${scenario%% *}.log"; done
|
||||
popd
|
||||
- name: Upload e2e tests output
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
with:
|
||||
name: test-e2e-output
|
||||
path: enos/test*.log
|
||||
path: enos/*.log
|
||||
retention-days: 5
|
||||
- name: Get logs from postgres container
|
||||
# Retrieve logs from the postgres container on a failed
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
# 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_worker_registration_controller_led" {
|
||||
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]
|
||||
edition = var.boundary_edition
|
||||
}
|
||||
}
|
||||
|
||||
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 : ""
|
||||
config_file = "boundary-config.hcl"
|
||||
get_auth_token = true
|
||||
get_worker_token = true
|
||||
}
|
||||
}
|
||||
|
||||
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-controller-led.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"
|
||||
token = step.create_boundary.worker_token
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env sh
|
||||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
boundary authenticate password \
|
||||
-login-name $LOGIN_NAME \
|
||||
-password env://BPASS \
|
||||
-format json
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env sh
|
||||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
boundary workers create controller-led \
|
||||
-token env://BOUNDARY_TOKEN \
|
||||
-format json
|
||||
@@ -54,6 +54,16 @@ variable "worker_tag" {
|
||||
type = string
|
||||
default = "collocated"
|
||||
}
|
||||
variable "get_auth_token" {
|
||||
description = "Flag to retrieve a boundary auth token"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
variable "get_worker_token" {
|
||||
description = "Flag to retrieve a boundary worker token"
|
||||
type = bool
|
||||
default = false
|
||||
}
|
||||
|
||||
resource "docker_image" "boundary" {
|
||||
name = var.image_name
|
||||
@@ -150,6 +160,47 @@ resource "enos_local_exec" "check_health" {
|
||||
inline = ["timeout 10s bash -c 'until curl -i http://0.0.0.0:9203/health; do sleep 2; done'"]
|
||||
}
|
||||
|
||||
resource "enos_local_exec" "get_auth_token" {
|
||||
count = var.get_auth_token ? 1 : 0
|
||||
depends_on = [enos_local_exec.check_health]
|
||||
environment = {
|
||||
TEST_BOUNDARY_IMAGE = var.image_name
|
||||
BOUNDARY_ADDR = local.address
|
||||
TEST_NETWORK_NAME = var.network_name[0]
|
||||
E2E_PASSWORD_ADMIN_LOGIN_NAME = local.login_name
|
||||
E2E_PASSWORD_ADMIN_PASSWORD = local.password
|
||||
MODULE_DIR = abspath(path.module)
|
||||
SCRIPT = "${abspath(path.module)}/get_auth_token.sh"
|
||||
}
|
||||
inline = ["bash ./${path.module}/script_runner.sh"]
|
||||
}
|
||||
|
||||
locals {
|
||||
auth_info = var.get_auth_token ? jsondecode(enos_local_exec.get_auth_token[0].stdout) : null
|
||||
auth_token = var.get_auth_token ? local.auth_info["item"]["attributes"]["token"] : ""
|
||||
}
|
||||
|
||||
resource "enos_local_exec" "get_worker_token" {
|
||||
count = var.get_worker_token ? 1 : 0
|
||||
depends_on = [enos_local_exec.check_health]
|
||||
environment = {
|
||||
TEST_BOUNDARY_IMAGE = var.image_name,
|
||||
BOUNDARY_ADDR = local.address
|
||||
TEST_NETWORK_NAME = var.network_name[0]
|
||||
E2E_PASSWORD_ADMIN_LOGIN_NAME = local.login_name
|
||||
E2E_PASSWORD_ADMIN_PASSWORD = local.password
|
||||
MODULE_DIR = abspath(path.module)
|
||||
SCRIPT = "${abspath(path.module)}/get_worker_token.sh"
|
||||
BOUNDARY_TOKEN = local.auth_token
|
||||
}
|
||||
inline = ["bash ./${path.module}/script_runner.sh"]
|
||||
}
|
||||
|
||||
locals {
|
||||
worker_info = var.get_worker_token ? jsondecode(enos_local_exec.get_worker_token[0].stdout) : null
|
||||
worker_token = var.get_worker_token ? local.worker_info["item"]["controller_generated_activation_token"] : ""
|
||||
}
|
||||
|
||||
output "address" {
|
||||
value = local.address
|
||||
}
|
||||
@@ -173,3 +224,13 @@ output "password" {
|
||||
output "worker_tag" {
|
||||
value = var.worker_tag
|
||||
}
|
||||
|
||||
output "auth_token" {
|
||||
value = local.auth_token
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
output "worker_token" {
|
||||
value = local.worker_token
|
||||
sensitive = true
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
# This script initializes a postgres database to work with Boundary by spinning up a temporary
|
||||
# Boundary docker container pointed to the specified database and invoking `boundary database init`.
|
||||
#
|
||||
# This script must only output the JSON that comes from `boundary database init` as the output is
|
||||
# consumed by other scripts.
|
||||
|
||||
TEST_CONTAINER_NAME=boundary-script-runner
|
||||
SOURCE=$(realpath $(dirname ${BASH_SOURCE[0]})) # get directory of this script
|
||||
|
||||
docker run \
|
||||
--rm \
|
||||
--name $TEST_CONTAINER_NAME \
|
||||
-e "BOUNDARY_ADDR=$BOUNDARY_ADDR" \
|
||||
-e "LOGIN_NAME=$E2E_PASSWORD_ADMIN_LOGIN_NAME" \
|
||||
-e "BPASS=$E2E_PASSWORD_ADMIN_PASSWORD" \
|
||||
-e "BOUNDARY_TOKEN=$BOUNDARY_TOKEN" \
|
||||
-e "SKIP_CHOWN=true" \
|
||||
--cap-add IPC_LOCK \
|
||||
--network $TEST_NETWORK_NAME \
|
||||
-v "$SCRIPT:/script.sh" \
|
||||
$TEST_BOUNDARY_IMAGE \
|
||||
/bin/sh -c /script.sh
|
||||
@@ -55,6 +55,11 @@ variable "config_file" {
|
||||
type = string
|
||||
default = "worker-config.hcl"
|
||||
}
|
||||
variable "token" {
|
||||
description = "Controller generated activation token to initialize worker"
|
||||
type = string
|
||||
default = ""
|
||||
}
|
||||
|
||||
resource "docker_image" "boundary" {
|
||||
name = var.image_name
|
||||
@@ -102,6 +107,7 @@ resource "docker_container" "worker" {
|
||||
recording_storage_path = local.recording_storage_path
|
||||
port = var.port
|
||||
port_ops = local.port_ops
|
||||
token = var.token
|
||||
})
|
||||
file = "/boundary/worker-config.hcl"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# Copyright (c) HashiCorp, Inc.
|
||||
# SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
disable_mlock = true
|
||||
|
||||
telemetry {
|
||||
prometheus_retention_time = "24h"
|
||||
disable_hostname = true
|
||||
}
|
||||
|
||||
listener "tcp" {
|
||||
address = "0.0.0.0:${port}"
|
||||
purpose = "proxy"
|
||||
tls_disable = true
|
||||
}
|
||||
|
||||
listener "tcp" {
|
||||
address = "0.0.0.0:${port_ops}"
|
||||
purpose = "ops"
|
||||
tls_disable = true
|
||||
}
|
||||
|
||||
worker {
|
||||
public_addr = "${worker_name}:${port}"
|
||||
initial_upstreams = ["${initial_upstream}"]
|
||||
controller_generated_activation_token = "${token}"
|
||||
|
||||
tags {
|
||||
type = ${type_tags},
|
||||
}
|
||||
|
||||
auth_storage_path = "/tmp/boundary/worker"
|
||||
}
|
||||
|
||||
events {
|
||||
audit_enabled = true
|
||||
sysevents_enabled = true
|
||||
observations_enable = true
|
||||
|
||||
sink "stderr" {
|
||||
name = "all-events"
|
||||
description = "All events sent to stderr"
|
||||
event_types = ["*"]
|
||||
format = "cloudevents-json"
|
||||
}
|
||||
|
||||
sink {
|
||||
name = "Log File"
|
||||
event_types = ["*"]
|
||||
format = "cloudevents-json"
|
||||
|
||||
file {
|
||||
path = "/boundary/logs"
|
||||
file_name = "events.log"
|
||||
}
|
||||
|
||||
audit_config {
|
||||
audit_filter_overrides {
|
||||
secret = "redact"
|
||||
sensitive = "redact"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user