Add Consul Lambda integration tests (#13770)
This commit is contained in:
parent
2875cbe856
commit
00f9dc2a70
|
@ -876,8 +876,13 @@ jobs:
|
||||||
environment:
|
environment:
|
||||||
ENVOY_VERSION: << parameters.envoy-version >>
|
ENVOY_VERSION: << parameters.envoy-version >>
|
||||||
XDS_TARGET: << parameters.xds-target >>
|
XDS_TARGET: << parameters.xds-target >>
|
||||||
|
AWS_LAMBDA_REGION: us-west-2
|
||||||
steps: &ENVOY_INTEGRATION_TEST_STEPS
|
steps: &ENVOY_INTEGRATION_TEST_STEPS
|
||||||
- checkout
|
- checkout
|
||||||
|
- assume-role:
|
||||||
|
access-key: AWS_ACCESS_KEY_ID_LAMBDA
|
||||||
|
secret-key: AWS_SECRET_ACCESS_KEY_LAMBDA
|
||||||
|
role-arn: ROLE_ARN_LAMBDA
|
||||||
# Get go binary from workspace
|
# Get go binary from workspace
|
||||||
- attach_workspace:
|
- attach_workspace:
|
||||||
at: .
|
at: .
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
snapshot_envoy_admin localhost:19000 s1 primary || true
|
||||||
|
snapshot_envoy_admin localhost:20000 terminating-gateway primary || true
|
|
@ -0,0 +1,12 @@
|
||||||
|
config_entries {
|
||||||
|
bootstrap {
|
||||||
|
kind = "terminating-gateway"
|
||||||
|
name = "terminating-gateway"
|
||||||
|
|
||||||
|
services = [
|
||||||
|
{
|
||||||
|
name = "l2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"Node": "lambdas",
|
||||||
|
"SkipNodeUpdate": true,
|
||||||
|
"NodeMeta": {
|
||||||
|
"external-node": "true",
|
||||||
|
"external-probe": "true"
|
||||||
|
},
|
||||||
|
"Service": {
|
||||||
|
"ID": "l1",
|
||||||
|
"Service": "l1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"Node": "lambdas",
|
||||||
|
"SkipNodeUpdate": true,
|
||||||
|
"NodeMeta": {
|
||||||
|
"external-node": "true",
|
||||||
|
"external-probe": "true"
|
||||||
|
},
|
||||||
|
"Service": {
|
||||||
|
"ID": "l2",
|
||||||
|
"Service": "l2"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
connect {
|
||||||
|
enable_serverless_plugin = true
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"Kind": "service-defaults",
|
||||||
|
"Name": "l1",
|
||||||
|
"Protocol": "http",
|
||||||
|
"Meta": {
|
||||||
|
"serverless.consul.hashicorp.com/v1alpha1/lambda/enabled": "true",
|
||||||
|
"serverless.consul.hashicorp.com/v1alpha1/lambda/region": "${AWS_LAMBDA_REGION}",
|
||||||
|
"serverless.consul.hashicorp.com/v1alpha1/lambda/arn": "${AWS_LAMBDA_ARN}",
|
||||||
|
"serverless.consul.hashicorp.com/v1alpha1/lambda/payload-passthrough": "true"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"Kind": "service-defaults",
|
||||||
|
"Name": "l2",
|
||||||
|
"Protocol": "http",
|
||||||
|
"Meta": {
|
||||||
|
"serverless.consul.hashicorp.com/v1alpha1/lambda/enabled": "true",
|
||||||
|
"serverless.consul.hashicorp.com/v1alpha1/lambda/region": "${AWS_LAMBDA_REGION}",
|
||||||
|
"serverless.consul.hashicorp.com/v1alpha1/lambda/arn": "${AWS_LAMBDA_ARN}",
|
||||||
|
"serverless.consul.hashicorp.com/v1alpha1/lambda/payload-passthrough": "false"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
services {
|
||||||
|
name = "terminating-gateway"
|
||||||
|
kind = "terminating-gateway"
|
||||||
|
port = 8443
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
services {
|
||||||
|
name = "s1"
|
||||||
|
port = 8080
|
||||||
|
connect {
|
||||||
|
sidecar_service {
|
||||||
|
proxy {
|
||||||
|
upstreams = [
|
||||||
|
{
|
||||||
|
destination_name = "l1"
|
||||||
|
local_bind_port = 1234
|
||||||
|
},
|
||||||
|
{
|
||||||
|
destination_name = "l2"
|
||||||
|
local_bind_port = 5678
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -eEuo pipefail
|
||||||
|
|
||||||
|
# Copy lambda config files into the register dir
|
||||||
|
find ${CASE_DIR} -maxdepth 1 -name '*_l*.json' -type f -exec cp -f {} workdir/${CLUSTER}/register \;
|
||||||
|
|
||||||
|
# wait for tgw config entry
|
||||||
|
wait_for_config_entry terminating-gateway terminating-gateway
|
||||||
|
|
||||||
|
register_services primary
|
||||||
|
register_lambdas primary
|
||||||
|
|
||||||
|
# wait for Lambda config entries
|
||||||
|
wait_for_config_entry service-defaults l1
|
||||||
|
wait_for_config_entry service-defaults l2
|
||||||
|
|
||||||
|
gen_envoy_bootstrap s1 19000 primary
|
||||||
|
gen_envoy_bootstrap terminating-gateway 20000 primary true
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Ensure that the environment variables required to configure and invoke the Lambda function are present, otherwise skip.
|
||||||
|
# Note that `set | grep ...` is used here because we cannot check the vars directly. If they are unbound the test will
|
||||||
|
# fail instead of being skipped.
|
||||||
|
export SKIP_CASE=""
|
||||||
|
[ -n "$(set | grep '^AWS_LAMBDA_REGION=')" ] || export SKIP_CASE="AWS_LAMBDA_REGION is not present in the environment"
|
||||||
|
[ -n "$(set | grep '^AWS_LAMBDA_ARN=')" ] || export SKIP_CASE="AWS_LAMBDA_ARN is not present in the environment"
|
||||||
|
[ -n "$(set | grep '^AWS_SESSION_TOKEN=')" ] || export SKIP_CASE="AWS_SESSION_TOKEN is not present in the environment"
|
||||||
|
[ -n "$(set | grep '^AWS_SECRET_ACCESS_KEY=')" ] || export SKIP_CASE="AWS_SECRET_ACCESS_KEY is not present in the environment"
|
||||||
|
[ -n "$(set | grep '^AWS_ACCESS_KEY_ID=')" ] || export SKIP_CASE="AWS_ACCESS_KEY_ID is not present in the environment"
|
||||||
|
|
||||||
|
[ -n "$SKIP_CASE" ] && return 0
|
||||||
|
|
||||||
|
export REQUIRED_SERVICES="s1 s1-sidecar-proxy terminating-gateway-primary"
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
load helpers
|
||||||
|
|
||||||
|
@test "s1 has lambda cluster for l1" {
|
||||||
|
assert_lambda_envoy_dynamic_cluster_exists localhost:19000 l1
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "s1 has lambda http filter for l1" {
|
||||||
|
assert_lambda_envoy_dynamic_http_filter_exists localhost:19000 l1 $AWS_LAMBDA_ARN
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "terminating gateway has lambda cluster for l2" {
|
||||||
|
assert_lambda_envoy_dynamic_cluster_exists localhost:20000 l2
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "terminating gateway has lambda http filter for l2" {
|
||||||
|
assert_lambda_envoy_dynamic_http_filter_exists localhost:20000 l2 $AWS_LAMBDA_ARN
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "s1 can call l1 through its sidecar-proxy" {
|
||||||
|
run retry_default curl -s -f -H "Content-type: application/json" -d '"hello"' 'localhost:1234'
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
# l1 is configured with payload_passthrough = true so the response needs to be unwrapped
|
||||||
|
[ $(echo "$output" | jq -r '.statusCode') -eq 200 ]
|
||||||
|
[ $(echo "$output" | jq -r '.body') == "hello" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "s1 can call l2 through the terminating gateway" {
|
||||||
|
run retry_default curl -s -f -H "Content-type: application/json" -d '"hello"' 'localhost:5678'
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[ "$output" == '"hello"' ]
|
||||||
|
|
||||||
|
# Omitting the Content-type in the request will cause envoy to base64 encode the request.
|
||||||
|
run curl -s -f -d '{"message":"hello"}' 'localhost:5678'
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
[ "$output" == '{"message":"hello"}' ]
|
||||||
|
}
|
|
@ -966,3 +966,55 @@ function create_peering {
|
||||||
# echo "$output" >&3
|
# echo "$output" >&3
|
||||||
[ "$status" == 0 ]
|
[ "$status" == 0 ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_lambda_envoy_http_filter {
|
||||||
|
local HOSTPORT=$1
|
||||||
|
local NAME_PREFIX=$2
|
||||||
|
run retry_default curl -s -f $HOSTPORT/config_dump
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
# get the full http filter object so the individual fields can be validated.
|
||||||
|
echo "$output" | jq --raw-output ".configs[2].dynamic_listeners[] | .active_state.listener.filter_chains[].filters[] | select(.name == \"envoy.filters.network.http_connection_manager\") | .typed_config.http_filters[] | select(.name == \"envoy.filters.http.aws_lambda\") | .typed_config"
|
||||||
|
}
|
||||||
|
|
||||||
|
function register_lambdas {
|
||||||
|
local DC=${1:-primary}
|
||||||
|
# register lambdas to the catalog
|
||||||
|
for f in $(find workdir/${DC}/register -type f -name 'lambda_*.json'); do
|
||||||
|
retry_default curl -sL -XPUT -d @${f} "http://localhost:8500/v1/catalog/register" >/dev/null && \
|
||||||
|
echo "Registered Lambda: $(jq -r .Service.Service $f)"
|
||||||
|
done
|
||||||
|
# write service-defaults config entries for lambdas
|
||||||
|
for f in $(find workdir/${DC}/register -type f -name 'service_defaults_*.json'); do
|
||||||
|
varsub ${f} AWS_LAMBDA_REGION AWS_LAMBDA_ARN
|
||||||
|
retry_default curl -sL -XPUT -d @${f} "http://localhost:8500/v1/config" >/dev/null && \
|
||||||
|
echo "Wrote config: $(jq -r '.Kind + " / " + .Name' $f)"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function assert_lambda_envoy_dynamic_cluster_exists {
|
||||||
|
local HOSTPORT=$1
|
||||||
|
local NAME_PREFIX=$2
|
||||||
|
|
||||||
|
local BODY=$(get_envoy_dynamic_cluster_once $HOSTPORT $NAME_PREFIX)
|
||||||
|
[ -n "$BODY" ]
|
||||||
|
|
||||||
|
[ "$(echo $BODY | jq -r '.cluster.transport_socket.typed_config.sni')" == '*.amazonaws.com' ]
|
||||||
|
}
|
||||||
|
|
||||||
|
function assert_lambda_envoy_dynamic_http_filter_exists {
|
||||||
|
local HOSTPORT=$1
|
||||||
|
local NAME_PREFIX=$2
|
||||||
|
local ARN=$3
|
||||||
|
|
||||||
|
local FILTER=$(get_lambda_envoy_http_filter $HOSTPORT $NAME_PREFIX)
|
||||||
|
[ -n "$FILTER" ]
|
||||||
|
|
||||||
|
[ "$(echo $FILTER | jq -r '.arn')" == "$ARN" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
function varsub {
|
||||||
|
local file=$1 ; shift
|
||||||
|
for v in "$@"; do
|
||||||
|
sed -i "s/\${$v}/${!v}/g" $file
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
|
@ -43,6 +43,20 @@ function network_snippet {
|
||||||
echo "--net container:envoy_consul-${DC}_1"
|
echo "--net container:envoy_consul-${DC}_1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function aws_snippet {
|
||||||
|
local snippet=""
|
||||||
|
|
||||||
|
# The Lambda integration cases assume that a Lambda function exists in $AWS_REGION with an ARN of $AWS_LAMBDA_ARN.
|
||||||
|
# The AWS credentials must have permission to invoke the Lambda function.
|
||||||
|
[ -n "$(set | grep '^AWS_ACCESS_KEY_ID=')" ] && snippet="${snippet} -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID"
|
||||||
|
[ -n "$(set | grep '^AWS_SECRET_ACCESS_KEY=')" ] && snippet="${snippet} -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY"
|
||||||
|
[ -n "$(set | grep '^AWS_SESSION_TOKEN=')" ] && snippet="${snippet} -e AWS_SESSION_TOKEN=$AWS_SESSION_TOKEN"
|
||||||
|
[ -n "$(set | grep '^AWS_LAMBDA_REGION=')" ] && snippet="${snippet} -e AWS_LAMBDA_REGION=$AWS_LAMBDA_REGION"
|
||||||
|
[ -n "$(set | grep '^AWS_LAMBDA_ARN=')" ] && snippet="${snippet} -e AWS_LAMBDA_ARN=$AWS_LAMBDA_ARN"
|
||||||
|
|
||||||
|
echo "$snippet"
|
||||||
|
}
|
||||||
|
|
||||||
function init_workdir {
|
function init_workdir {
|
||||||
local CLUSTER="$1"
|
local CLUSTER="$1"
|
||||||
|
|
||||||
|
@ -333,6 +347,7 @@ function verify {
|
||||||
$WORKDIR_SNIPPET \
|
$WORKDIR_SNIPPET \
|
||||||
--pid=host \
|
--pid=host \
|
||||||
$(network_snippet $CLUSTER) \
|
$(network_snippet $CLUSTER) \
|
||||||
|
$(aws_snippet) \
|
||||||
bats-verify \
|
bats-verify \
|
||||||
--pretty /workdir/${CLUSTER}/bats ; then
|
--pretty /workdir/${CLUSTER}/bats ; then
|
||||||
echogreen "✓ PASS"
|
echogreen "✓ PASS"
|
||||||
|
@ -679,6 +694,7 @@ function common_run_container_sidecar_proxy {
|
||||||
docker run -d --name $(container_name_prev) \
|
docker run -d --name $(container_name_prev) \
|
||||||
$WORKDIR_SNIPPET \
|
$WORKDIR_SNIPPET \
|
||||||
$(network_snippet $CLUSTER) \
|
$(network_snippet $CLUSTER) \
|
||||||
|
$(aws_snippet) \
|
||||||
"${HASHICORP_DOCKER_PROXY}/envoyproxy/envoy:v${ENVOY_VERSION}" \
|
"${HASHICORP_DOCKER_PROXY}/envoyproxy/envoy:v${ENVOY_VERSION}" \
|
||||||
envoy \
|
envoy \
|
||||||
-c /workdir/${CLUSTER}/envoy/${service}-bootstrap.json \
|
-c /workdir/${CLUSTER}/envoy/${service}-bootstrap.json \
|
||||||
|
@ -765,6 +781,7 @@ function common_run_container_gateway {
|
||||||
docker run -d --name $(container_name_prev) \
|
docker run -d --name $(container_name_prev) \
|
||||||
$WORKDIR_SNIPPET \
|
$WORKDIR_SNIPPET \
|
||||||
$(network_snippet $DC) \
|
$(network_snippet $DC) \
|
||||||
|
$(aws_snippet) \
|
||||||
"${HASHICORP_DOCKER_PROXY}/envoyproxy/envoy:v${ENVOY_VERSION}" \
|
"${HASHICORP_DOCKER_PROXY}/envoyproxy/envoy:v${ENVOY_VERSION}" \
|
||||||
envoy \
|
envoy \
|
||||||
-c /workdir/${DC}/envoy/${name}-bootstrap.json \
|
-c /workdir/${DC}/envoy/${name}-bootstrap.json \
|
||||||
|
|
Loading…
Reference in New Issue