Skip to content

Commit

Permalink
test(e2e): Add infra for ssh certificate injection test
Browse files Browse the repository at this point in the history
  • Loading branch information
moduli committed Aug 1, 2023
1 parent 91b74a0 commit 8e50d9a
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 38 deletions.
4 changes: 4 additions & 0 deletions enos/enos-modules.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ module "docker_openssh_server" {
source = "./modules/docker_openssh_server"
}

module "docker_openssh_server_ca_key" {
source = "./modules/docker_openssh_server_ca_key"
}

module "docker_network" {
source = "./modules/docker_network"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/with-contenv bash

cp /ca/ca-key.pub /etc/ssh/ca-key.pub
chown 1000:1000 /etc/ssh/ca-key.pub
chmod 644 /etc/ssh/ca-key.pub
echo TrustedUserCAKeys /etc/ssh/ca-key.pub >> /etc/ssh/sshd_config
echo PermitTTY yes >> /etc/ssh/sshd_config
sed -i 's/X11Forwarding no/X11Forwarding yes/' /etc/ssh/sshd_config
echo "X11UseLocalhost no" >> /etc/ssh/sshd_config

apk update
apk add xterm util-linux dbus ttf-freefont xauth firefox
108 changes: 108 additions & 0 deletions enos/modules/docker_openssh_server_ca_key/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "3.0.1"
}

tls = {
source = "hashicorp/tls"
version = "4.0.4"
}

enos = {
source = "app.terraform.io/hashicorp-qti/enos"
}
}
}

variable "image_name" {
description = "Name of Docker Image"
type = string
default = "docker.mirror.hashicorp.services/linuxserver/openssh-server:latest"
}
variable "network_name" {
description = "Name of Docker Network"
type = string
}
variable "container_name" {
description = "Name of Docker Container"
type = string
default = "openssh-server"
}
variable "target_user" {
description = "SSH username for target"
type = string
default = "ubuntu"
}
variable "private_key_file_path" {
description = "Local Path to key used to SSH onto created hosts"
type = string
}

data "tls_public_key" "host_key_openssh" {
private_key_openssh = file(var.private_key_file_path)
}

locals {
public_key = data.tls_public_key.host_key_openssh.public_key_openssh
}

resource "docker_image" "openssh_server" {
name = var.image_name
keep_locally = true
}

resource "docker_container" "openssh_server" {
image = docker_image.openssh_server.image_id
name = var.container_name
env = [
"PUID=1000",
"PGID=1000",
"TZ=US/Eastern",
"USER_NAME=${var.target_user}",
"PUBLIC_KEY=${local.public_key}",
]
networks_advanced {
name = var.network_name
}
ports {
internal = 2222
external = 2222
}
volumes {
host_path = format("%s/%s", abspath(path.module), "/custom-cont-init.d")
container_path = "/custom-cont-init.d"
}
volumes {
host_path = format("%s/%s", abspath(path.module), "/ca")
container_path = "/ca"
}
}

resource "enos_local_exec" "wait" {
depends_on = [
docker_container.openssh_server
]

inline = ["timeout 20s bash -c 'until ssh -t -t -i ${var.private_key_file_path} -p 2222 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes ${var.target_user}@localhost hostname; do sleep 2; done'"]
}

output "user" {
value = var.target_user
}

output "address" {
value = docker_container.openssh_server.network_data[0].ip_address
}

output "port" {
value = "2222"
}

output "ca_dir" {
value = format("%s/%s", abspath(path.module), "/ca")
}
6 changes: 6 additions & 0 deletions enos/modules/test_e2e_docker/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ variable "target_port" {
type = string
default = ""
}
variable "target_ca_dir" {
description = "Path to ca directory (containing public and private key)"
type = string
default = ""
}
variable "vault_addr" {
description = "External network address of Vault. Will be converted to a URL below"
type = string
Expand Down Expand Up @@ -202,6 +207,7 @@ resource "enos_local_exec" "run_e2e_test" {
E2E_SSH_USER = var.target_user,
E2E_SSH_PORT = var.target_port,
E2E_SSH_KEY_PATH = local.aws_ssh_private_key_path,
E2E_SSH_CA_DIR = var.target_ca_dir,
VAULT_ADDR = local.vault_addr,
VAULT_ADDR_INTERNAL = local.vault_addr_internal,
VAULT_TOKEN = var.vault_root_token,
Expand Down
79 changes: 42 additions & 37 deletions enos/modules/test_e2e_docker/test_runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,45 @@

set -eux -o pipefail

docker run \
--rm \
--name test-runner \
-e "TEST_PACKAGE=$TEST_PACKAGE" \
-e "TEST_TIMEOUT=$TEST_TIMEOUT" \
-e "E2E_TESTS=$E2E_TESTS" \
-e "BOUNDARY_ADDR=$BOUNDARY_ADDR" \
-e "E2E_PASSWORD_AUTH_METHOD_ID=$E2E_PASSWORD_AUTH_METHOD_ID" \
-e "E2E_PASSWORD_ADMIN_LOGIN_NAME=$E2E_PASSWORD_ADMIN_LOGIN_NAME" \
-e "E2E_PASSWORD_ADMIN_PASSWORD=$E2E_PASSWORD_ADMIN_PASSWORD" \
-e "E2E_TARGET_IP=$E2E_TARGET_IP" \
-e "E2E_SSH_USER=$E2E_SSH_USER" \
-e "E2E_SSH_PORT=$E2E_SSH_PORT" \
-e "E2E_SSH_KEY_PATH=/keys/target.pem" \
-e "VAULT_ADDR=$VAULT_ADDR_INTERNAL" \
-e "VAULT_TOKEN=$VAULT_TOKEN" \
-e "E2E_VAULT_ADDR=$E2E_VAULT_ADDR" \
-e "E2E_AWS_ACCESS_KEY_ID=$E2E_AWS_ACCESS_KEY_ID" \
-e "E2E_AWS_SECRET_ACCESS_KEY=$E2E_AWS_SECRET_ACCESS_KEY" \
-e "E2E_AWS_HOST_SET_FILTER=$E2E_AWS_HOST_SET_FILTER" \
-e "E2E_AWS_HOST_SET_IPS=$E2E_AWS_HOST_SET_IPS" \
-e "E2E_AWS_HOST_SET_FILTER2=$E2E_AWS_HOST_SET_FILTER2" \
-e "E2E_AWS_HOST_SET_IPS2=$E2E_AWS_HOST_SET_IPS2" \
-e "E2E_AWS_REGION=$E2E_AWS_REGION" \
-e "E2E_AWS_BUCKET_NAME=$E2E_AWS_BUCKET_NAME" \
-e "E2E_WORKER_TAG=$E2E_WORKER_TAG" \
--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 \
--mount type=bind,src=$(go env GOMODCACHE),dst=/go/pkg/mod \
-v "$MODULE_DIR/test.sh:/scripts/test.sh" \
-v "$E2E_SSH_KEY_PATH:/keys/target.pem" \
-v "$BOUNDARY_CLI_DIR:/boundary.zip" \
--network $TEST_NETWORK_NAME \
--cap-add=CAP_IPC_LOCK \
$TEST_RUNNER_IMAGE \
/bin/sh -c /scripts/test.sh
cmd_string="docker run"
cmd_string+=" --rm"
cmd_string+=" --name test-runner"
cmd_string+=" -e TEST_PACKAGE=$TEST_PACKAGE"
cmd_string+=" -e TEST_TIMEOUT=$TEST_TIMEOUT"
cmd_string+=" -e E2E_TESTS=$E2E_TESTS"
cmd_string+=" -e BOUNDARY_ADDR=$BOUNDARY_ADDR"
cmd_string+=" -e E2E_PASSWORD_AUTH_METHOD_ID=$E2E_PASSWORD_AUTH_METHOD_ID"
cmd_string+=" -e E2E_PASSWORD_ADMIN_LOGIN_NAME=$E2E_PASSWORD_ADMIN_LOGIN_NAME"
cmd_string+=" -e E2E_PASSWORD_ADMIN_PASSWORD=$E2E_PASSWORD_ADMIN_PASSWORD"
cmd_string+=" -e E2E_TARGET_IP=$E2E_TARGET_IP"
cmd_string+=" -e E2E_SSH_USER=$E2E_SSH_USER"
cmd_string+=" -e E2E_SSH_PORT=$E2E_SSH_PORT"
cmd_string+=" -e E2E_SSH_KEY_PATH=/keys/target.pem"
# If E2E_SSH_CA_DIR is set or is not empty
[[ ! -z "${E2E_SSH_CA_DIR+$E2E_SSH_CA_DIR}" ]] && cmd_string+=" -e E2E_SSH_CA_DIR=/ca"
cmd_string+=" -e VAULT_ADDR=$VAULT_ADDR_INTERNAL"
cmd_string+=" -e VAULT_TOKEN=$VAULT_TOKEN"
cmd_string+=" -e E2E_VAULT_ADDR=$E2E_VAULT_ADDR"
cmd_string+=" -e E2E_AWS_ACCESS_KEY_ID=$E2E_AWS_ACCESS_KEY_ID"
cmd_string+=" -e E2E_AWS_SECRET_ACCESS_KEY=$E2E_AWS_SECRET_ACCESS_KEY"
cmd_string+=" -e E2E_AWS_HOST_SET_FILTER=$E2E_AWS_HOST_SET_FILTER"
cmd_string+=" -e E2E_AWS_HOST_SET_IPS=$E2E_AWS_HOST_SET_IPS"
cmd_string+=" -e E2E_AWS_HOST_SET_FILTER2=$E2E_AWS_HOST_SET_FILTER2"
cmd_string+=" -e E2E_AWS_HOST_SET_IPS2=$E2E_AWS_HOST_SET_IPS2"
cmd_string+=" -e E2E_AWS_REGION=$E2E_AWS_REGION"
cmd_string+=" -e E2E_AWS_BUCKET_NAME=$E2E_AWS_BUCKET_NAME"
cmd_string+=" -e E2E_WORKER_TAG=$E2E_WORKER_TAG"
cmd_string+=" --mount type=bind,src=$BOUNDARY_DIR,dst=/src/boundary/"
cmd_string+=" --mount type=bind,src=$MODULE_DIR/../..,dst=/testlogs"
cmd_string+=" --mount type=bind,src=$(go env GOCACHE),dst=/root/.cache/go-build"
cmd_string+=" --mount type=bind,src=$(go env GOMODCACHE),dst=/go/pkg/mod"
[[ ! -z "${E2E_SSH_CA_DIR+$E2E_SSH_CA_DIR}" ]] && cmd_string+=" --mount type=bind,src=$E2E_SSH_CA_DIR,dst=/ca"
cmd_string+=" -v $MODULE_DIR/test.sh:/scripts/test.sh"
cmd_string+=" -v $E2E_SSH_KEY_PATH:/keys/target.pem"
cmd_string+=" -v $BOUNDARY_CLI_DIR:/boundary.zip"
cmd_string+=" --network $TEST_NETWORK_NAME"
cmd_string+=" --cap-add=CAP_IPC_LOCK"
cmd_string+=" $TEST_RUNNER_IMAGE"
cmd_string+=" /bin/sh -c /scripts/test.sh"

($cmd_string)
3 changes: 2 additions & 1 deletion testing/internal/e2e/tests/base_with_vault/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ type config struct {
TargetIp string `envconfig:"E2E_TARGET_IP" required:"true"` // e.g. 192.168.0.1
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
TargetPort string `envconfig:"E2E_SSH_PORT" required:"true"`
TargetPort string `envconfig:"E2E_SSH_PORT" required:"true"` // e.g. 22
TargetCaDir string `envconfig:"E2E_SSH_CA_DIR" required:"true"` // e.g. /Users/username/ca
// 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"`
Expand Down

0 comments on commit 8e50d9a

Please sign in to comment.