Revision 856d1a756c3b2b6f183ed3d69de4aef753b1f396 authored by Michi Mutsuzaki on 16 November 2022, 01:03:54 UTC, committed by Michi Mutsuzaki on 16 November 2022, 05:13:46 UTC
Signed-off-by: Michi Mutsuzaki <michi@isovalent.com>
1 parent e3bbd8b
envoy-smoke-test.sh
#!/bin/bash
dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
source "${dir}/helpers.bash"
# dir might have been overwritten by helpers.bash
dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
TEST_NAME=$(get_filename_without_extension $0)
LOGS_DIR="${dir}/cilium-files/${TEST_NAME}/logs"
redirect_debug_logs ${LOGS_DIR}
set -ex
function cleanup {
monitor_stop
echo "Tip: Add '--debug-verbose=flow' into cilium options in /etc/sysconfig/cilium to get Envoy debug logging."
# These are commented to allow for easier debugging, but are left as comments to remind how to clean up:
# cilium service delete --all 2> /dev/null || true
# cilium policy delete --all 2> /dev/null || true
# docker rm -f server1 server2 client 2> /dev/null || true
}
function finish_test {
# Gathering files takes a long time and is not needed for live debugging.
# gather_files ${TEST_NAME} ${TEST_SUITE}
cleanup
}
trap finish_test EXIT
SERVER_LABEL="id.server"
CLIENT_LABEL="id.client"
SVC_IP="f00d::1:1"
SVC_IP4="2.2.2.2"
cleanup
logs_clear
function no_service_init {
cilium service delete --all
SERVER_IP=$SERVER1_IP;
SERVER_IP4=$SERVER1_IP4;
}
function service_init {
log "beginning service init"
cilium service update --frontend "$SVC_IP4:80" --id 2233 \
--backends "$SERVER1_IP4:80" \
--backends "$SERVER2_IP4:80"
cilium service update --frontend "[$SVC_IP]:80" --id 2234 \
--backends "[$SERVER1_IP]:80" \
--backends "[$SERVER2_IP]:80"
SERVER_IP=$SVC_IP
SERVER_IP4=$SVC_IP4
log "finished service init"
}
function proxy_init {
log "beginning proxy_init"
create_cilium_docker_network
if [ -z `docker ps -q -f name=^/server1$` ] ; then
docker run -dt --net=cilium --name server1 -l $SERVER_LABEL -v "$dir/testsite":/usr/local/apache2/htdocs/ httpd
fi
if [ -z `docker ps -q -f name=^/server2$` ] ; then
docker run -dt --net=cilium --name server2 -l $SERVER_LABEL -v "$dir/testsite":/usr/local/apache2/htdocs/ httpd
fi
if [ -z `docker ps -q -f name=^/client$` ] ; then
# use an unused loopback address on a reserved non-listening port with large retry timeout to make this pause "forever"
docker run -dt --net=cilium --name client -l id.client curlimages/curl -s --retry-connrefused --retry-delay 1000000 --retry 5 127.242.139.58:967
fi
SERVER1_IP=$(docker inspect --format '{{ .NetworkSettings.Networks.cilium.GlobalIPv6Address }}' server1)
SERVER2_IP=$(docker inspect --format '{{ .NetworkSettings.Networks.cilium.GlobalIPv6Address }}' server2)
SERVER1_IP4=$(docker inspect --format '{{ .NetworkSettings.Networks.cilium.IPAddress }}' server1)
SERVER2_IP4=$(docker inspect --format '{{ .NetworkSettings.Networks.cilium.IPAddress }}' server2)
SERVER_IP=$SERVER1_IP;
SERVER_IP4=$SERVER1_IP4;
wait_for_docker_ipv6_addr server1
wait_for_docker_ipv6_addr server2
wait_for_docker_ipv6_addr client
log "waiting for endpoints to get identities"
while [ `cilium endpoint list -o jsonpath='{range [*]}{.status.identity.id}{" "}{.status.identity.labels}{"\n"}' | grep '^[1-9][0-9]* .*id.\(server\|client\)' | cut -d ' ' -f1 | sort | uniq | wc -l` -ne 2 ] ; do
log "waiting..."
sleep 1
done
monitor_start
log "finished proxy_init"
}
# Dummy policy to keep the containers in policy enforcement mode all the time
function policy_base {
cilium policy delete --all
cat <<EOF | policy_import_and_wait -
[{
"labels": [{"key": "policy", "value": "enforced"}],
"endpointSelector": {"matchLabels":{}},
"ingress": [{}],
"egress": [{}]
},{
"labels": [{"key": "policy", "value": "test"}],
"endpointSelector": {"matchLabels":{}},
"ingress": [{}],
"egress": [{}]
}]
EOF
}
function policy_single_egress {
cilium policy delete policy=test
cat <<EOF | policy_import_and_wait -
[{
"labels": [{"key": "policy", "value": "test"}],
"endpointSelector": {"matchLabels":{"id.server":""}},
"ingress": [{
"fromEndpoints": [
{"matchLabels":{"reserved:host":""}},
{"matchLabels":{"id.client":""}}
]
}]
},{
"labels": [{"key": "policy", "value": "test"}],
"endpointSelector": {"matchLabels":{"id.client":""}},
"egress": [{
"toPorts": [{
"ports": [{"port": "80", "protocol": "tcp"}],
"rules": {
"HTTP": [{
"method": "GET",
"path": "/public"
}]
}
}]
}]
}]
EOF
}
function policy_many_egress {
cilium policy delete policy=test
cat <<EOF | policy_import_and_wait -
[{
"labels": [{"key": "policy", "value": "test"}],
"endpointSelector": {"matchLabels":{"id.server":""}},
"ingress": [{
"fromEndpoints": [
{"matchLabels":{"reserved:host":""}},
{"matchLabels":{"id.client":""}}
]
}]
},{
"labels": [{"key": "policy", "value": "test"}],
"endpointSelector": {"matchLabels":{"id.client":""}},
"egress": [{
"toEndpoints": [{"matchLabels":{"id.server":""}}],
"toPorts": [{
"ports": [{"port": "80", "protocol": "tcp"}],
"rules": {
"HTTP": [{
"method": "GET",
"path": "/public"
}]
}
}]
}, {
"toEndpoints": [{"matchLabels":{"id.client":""}}],
"toPorts": [{
"ports": [{"port": "80", "protocol": "tcp"}],
"rules": {
"HTTP": [{
"method": "GET",
"path": "/self"
}]
}
}]
}, {
"toEndpoints": [{"matchLabels":{"id.server":""}}],
"toPorts": [{
"ports": [{"port": "8000", "protocol": "tcp"},
{"port": "8080", "protocol": "tcp"}],
"rules": {
"HTTP": [{
"method": "PUT",
"path": "/publix"
}]
}
}]
}]
}]
EOF
}
function policy_single_ingress {
cilium policy delete policy=test
cat <<EOF | policy_import_and_wait -
[{
"labels": [{"key": "policy", "value": "test"}],
"endpointSelector": {"matchLabels":{"id.server":""}},
"ingress": [{
"fromEndpoints": [
{"matchLabels":{"reserved:host":""}},
{"matchLabels":{"id.client":""}}
],
"toPorts": [{
"ports": [{"port": "80", "protocol": "tcp"}],
"rules": {
"HTTP": [{
"method": "GET",
"path": "/public"
}]
}
}]
}]
},{
"labels": [{"key": "policy", "value": "test"}],
"endpointSelector": {"matchLabels":{"id.client":""}},
"egress": [{
"toPorts": [{
"ports": [{"port": "80", "protocol": "tcp"}]
}]
}]
}]
EOF
}
function policy_many_ingress {
cilium policy delete policy=test
cat <<EOF | policy_import_and_wait -
[{
"labels": [{"key": "policy", "value": "test"}],
"endpointSelector": {"matchLabels":{"id.server":""}},
"ingress": [{
"fromEndpoints": [
{"matchLabels":{"reserved:host":""}},
{"matchLabels":{"id.client":""}}
],
"toPorts": [{
"ports": [{"port": "80", "protocol": "tcp"},
{"port": "8080", "protocol": "tcp"}],
"rules": {
"HTTP": [{
"method": "GET",
"path": "/public"
}]
}
}]
}]
},{
"labels": [{"key": "policy", "value": "test"}],
"endpointSelector": {"matchLabels":{"id.client":""}},
"egress": [{
"toPorts": [{
"ports": [{"port": "80", "protocol": "tcp"}]
}]
}]
}]
EOF
}
function policy_egress_and_ingress {
cilium policy delete policy=test
cat <<EOF | policy_import_and_wait -
[{
"labels": [{"key": "policy", "value": "test"}],
"endpointSelector": {"matchLabels":{"id.server":""}},
"ingress": [{
"fromEndpoints": [
{"matchLabels":{"id.client":""}}
]
}]
},{
"labels": [{"key": "policy", "value": "test"}],
"endpointSelector": {"matchLabels":{"id.client":""}},
"egress": [{
"toPorts": [{
"ports": [{"port": "80", "protocol": "tcp"}],
"rules": {
"HTTP": [{
"method": "GET",
"path": "/public"
}]
}
}]
}]
},{
"labels": [{"key": "policy", "value": "test"}],
"endpointSelector": {"matchLabels":{"id.server":""}},
"ingress": [{
"toPorts": [{
"ports": [{"port": "8000", "protocol": "tcp"},
{"port": "80", "protocol": "tcp"},
{"port": "8080", "protocol": "tcp"}],
"rules": {
"HTTP": [{
"method": "GET",
"path": "/public"
}]
}
}]
}]
}]
EOF
}
function proxy_test {
log "beginning proxy test"
monitor_clear
# Cilium launches Envoy with path normalization enabled by default, so '//public' will be seen as '/public'
log "trying to reach server IPv4 at http://$SERVER_IP4:80//public from client (expected: 200)"
RETURN=$(docker exec -i client curl -s --output /dev/stderr -w '%{http_code}' --connect-timeout 10 -XGET http://$SERVER_IP4:80//public)
if [[ "${RETURN//$'\n'}" != "200" ]]; then
abort "GET /public, unexpected return ${RETURN//$'\n'} != 200"
fi
log "trying to reach server IPv6 at http://[$SERVER_IP]:80/public from client (expected: 200)"
RETURN=$(docker exec -i client curl -s --output /dev/stderr -w '%{http_code}' --connect-timeout 10 -XGET http://[$SERVER_IP]:80/public)
if [[ "${RETURN//$'\n'}" != "200" ]]; then
abort "GET /public, unexpected return ${RETURN//$'\n'} != 200"
fi
log "trying to reach server IPv4 at http://$SERVER_IP4:80/private from client (expected: 403)"
RETURN=$(docker exec -i client curl -s --output /dev/stderr -w '%{http_code}' --connect-timeout 10 -XGET http://$SERVER_IP4:80/private)
if [[ "${RETURN//$'\n'}" != "403" ]]; then
abort "GET /private, unexpected return ${RETURN//$'\n'} != 403"
fi
log "trying to reach server IPv6 at http://[$SERVER_IP]:80/private from client (expected: 403)"
RETURN=$(docker exec -i client curl -s --output /dev/stderr -w '%{http_code}' --connect-timeout 10 -XGET http://[$SERVER_IP]:80/private)
if [[ "${RETURN//$'\n'}" != "403" ]]; then
abort "GET /private, unexpected return ${RETURN//$'\n'} != 403"
fi
log "finished proxy test"
}
proxy_init
log "+----------------------------------------------------------------------+"
log "Testing without Policy"
log "+----------------------------------------------------------------------+"
# Cilium launches Envoy with path normalization enabled by default, so '//public' will be seen as '/public'
log "trying to reach server IPv4 at http://$SERVER_IP4:80//public from client (expected: 200)"
RETURN=$(docker exec -i client curl -s --output /dev/stderr -w '%{http_code}' --connect-timeout 10 -XGET http://$SERVER_IP4:80//public)
if [[ "${RETURN//$'\n'}" != "200" ]]; then
abort "GET /public, unexpected return ${RETURN//$'\n'} != 200"
fi
policy_base
for state in "false" "true"; do
cilium config ConntrackLocal=$state
for service in "none" "lb"; do
case $service in
"none")
no_service_init;;
"lb")
service_init;;
esac
for policy in "egress" "ingress" "egress_and_ingress" "many_egress" "many_ingress"; do
log "+----------------------------------------------------------------------+"
log "Testing with Policy=$policy, Service=$service, Conntrack=$state"
log "+----------------------------------------------------------------------+"
case $policy in
"many_egress")
policy_many_egress;;
"egress")
policy_single_egress;;
"many_ingress")
policy_many_ingress;;
"ingress")
policy_single_ingress;;
"egress_and_ingress")
policy_egress_and_ingress;;
esac
proxy_test
done
done
done
log "deleting all services from Cilium"
cilium service delete --all
log "deleting all policies from Cilium"
cilium policy delete --all 2> /dev/null || true
log "removing containers"
docker rm -f server1 server2 client 2> /dev/null || true
test_succeeded "${TEST_NAME}"
Computing file changes ...