Add Consul Lambda integration tests (#13770)
This commit is contained in:
parent
2875cbe856
commit
00f9dc2a70
|
@ -876,8 +876,13 @@ jobs:
|
|||
environment:
|
||||
ENVOY_VERSION: << parameters.envoy-version >>
|
||||
XDS_TARGET: << parameters.xds-target >>
|
||||
AWS_LAMBDA_REGION: us-west-2
|
||||
steps: &ENVOY_INTEGRATION_TEST_STEPS
|
||||
- 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
|
||||
- attach_workspace:
|
||||
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
|
||||
[ "$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"
|
||||
}
|
||||
|
||||
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 {
|
||||
local CLUSTER="$1"
|
||||
|
||||
|
@ -333,6 +347,7 @@ function verify {
|
|||
$WORKDIR_SNIPPET \
|
||||
--pid=host \
|
||||
$(network_snippet $CLUSTER) \
|
||||
$(aws_snippet) \
|
||||
bats-verify \
|
||||
--pretty /workdir/${CLUSTER}/bats ; then
|
||||
echogreen "✓ PASS"
|
||||
|
@ -679,6 +694,7 @@ function common_run_container_sidecar_proxy {
|
|||
docker run -d --name $(container_name_prev) \
|
||||
$WORKDIR_SNIPPET \
|
||||
$(network_snippet $CLUSTER) \
|
||||
$(aws_snippet) \
|
||||
"${HASHICORP_DOCKER_PROXY}/envoyproxy/envoy:v${ENVOY_VERSION}" \
|
||||
envoy \
|
||||
-c /workdir/${CLUSTER}/envoy/${service}-bootstrap.json \
|
||||
|
@ -765,6 +781,7 @@ function common_run_container_gateway {
|
|||
docker run -d --name $(container_name_prev) \
|
||||
$WORKDIR_SNIPPET \
|
||||
$(network_snippet $DC) \
|
||||
$(aws_snippet) \
|
||||
"${HASHICORP_DOCKER_PROXY}/envoyproxy/envoy:v${ENVOY_VERSION}" \
|
||||
envoy \
|
||||
-c /workdir/${DC}/envoy/${name}-bootstrap.json \
|
||||
|
|
Loading…
Reference in New Issue