mirror of
https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin.git
synced 2026-07-21 19:48:59 +02:00
✨ tests: end-to-end suite scaffold + stream-mode scenario
Add tests/e2e/ structure with shared bash helpers and the first scenario (stream-mode): spin up real Traefik + Crowdsec via docker compose, mount the repo as a local plugin, add a ban via cscli, verify the bouncer blocks the matching X-Forwarded-For, then delete the decision and verify pass-through. Adds .github/workflows/e2e.yml with one matrix job per scenario (stream-mode for now), and Makefile targets `e2e` and `e2e_<scenario>` for local runs. Refs #328
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3.5.0
|
||||
container_name: e2e-stream-traefik
|
||||
command:
|
||||
- "--log.level=INFO"
|
||||
- "--accesslog"
|
||||
- "--api.insecure=true"
|
||||
- "--providers.file.filename=/etc/traefik/dynamic.yml"
|
||||
- "--providers.file.watch=false"
|
||||
- "--entrypoints.web.address=:80"
|
||||
- "--entryPoints.web.forwardedHeaders.insecure=true"
|
||||
- "--experimental.localplugins.bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin"
|
||||
volumes:
|
||||
- ./traefik-dynamic.yml:/etc/traefik/dynamic.yml:ro
|
||||
- ../../../..:/plugins-local/src/github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin
|
||||
ports:
|
||||
- "8000:80"
|
||||
depends_on:
|
||||
crowdsec:
|
||||
condition: service_healthy
|
||||
|
||||
whoami:
|
||||
image: traefik/whoami
|
||||
container_name: e2e-stream-whoami
|
||||
|
||||
crowdsec:
|
||||
image: crowdsecurity/crowdsec:v1.6.8
|
||||
container_name: crowdsec
|
||||
environment:
|
||||
DISABLE_ONLINE_API: "true"
|
||||
BOUNCER_KEY_TRAEFIK: 40796d93c2958f9e58345514e67740e5
|
||||
CUSTOM_HOSTNAME: crowdsec
|
||||
healthcheck:
|
||||
test: ["CMD", "cscli", "lapi", "status"]
|
||||
interval: 2s
|
||||
timeout: 3s
|
||||
retries: 30
|
||||
start_period: 5s
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
HERE="$(cd "$(dirname "$0")" && pwd)"
|
||||
# shellcheck source=../../lib/common.sh
|
||||
source "$HERE/../../lib/common.sh"
|
||||
|
||||
SCENARIO=stream-mode
|
||||
PROJECT="e2e-${SCENARIO}"
|
||||
COMPOSE_FILE="$HERE/docker-compose.yml"
|
||||
LOG_FILE="/tmp/e2e-${SCENARIO}.log"
|
||||
|
||||
cleanup() {
|
||||
local rc=$?
|
||||
if (( rc != 0 )); then
|
||||
dump_diagnostics "$PROJECT" "$COMPOSE_FILE" > "$LOG_FILE" 2>&1 || true
|
||||
echo "Scenario failed. Logs written to $LOG_FILE"
|
||||
fi
|
||||
docker compose -p "$PROJECT" -f "$COMPOSE_FILE" down -v --remove-orphans >/dev/null 2>&1 || true
|
||||
exit $rc
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "[$SCENARIO] starting stack..."
|
||||
docker compose -p "$PROJECT" -f "$COMPOSE_FILE" up -d --wait
|
||||
|
||||
echo "[$SCENARIO] waiting for crowdsec readiness..."
|
||||
wait_crowdsec_ready
|
||||
|
||||
echo "[$SCENARIO] waiting for traefik readiness..."
|
||||
wait_for_status http://localhost:8000/foo 200 30
|
||||
|
||||
echo "[$SCENARIO] no decision yet -> request allowed"
|
||||
assert_status http://localhost:8000/foo 200 -H "X-Forwarded-For: 1.2.3.4"
|
||||
|
||||
echo "[$SCENARIO] adding ban decision for 1.2.3.4"
|
||||
docker exec crowdsec cscli decisions add --ip 1.2.3.4 --type ban --duration 5m
|
||||
|
||||
echo "[$SCENARIO] waiting one stream tick + buffer..."
|
||||
sleep 6
|
||||
|
||||
echo "[$SCENARIO] banned IP must be blocked (HTTP 403)"
|
||||
assert_status http://localhost:8000/foo 403 -H "X-Forwarded-For: 1.2.3.4"
|
||||
|
||||
echo "[$SCENARIO] non-banned IP must still pass (HTTP 200)"
|
||||
assert_status http://localhost:8000/foo 200 -H "X-Forwarded-For: 5.6.7.8"
|
||||
|
||||
echo "[$SCENARIO] deleting ban decision"
|
||||
docker exec crowdsec cscli decisions delete --ip 1.2.3.4
|
||||
|
||||
echo "[$SCENARIO] waiting one stream tick + buffer..."
|
||||
sleep 6
|
||||
|
||||
echo "[$SCENARIO] previously banned IP must pass again"
|
||||
assert_status http://localhost:8000/foo 200 -H "X-Forwarded-For: 1.2.3.4"
|
||||
|
||||
echo "[$SCENARIO] OK"
|
||||
@@ -0,0 +1,22 @@
|
||||
http:
|
||||
routers:
|
||||
whoami:
|
||||
rule: "PathPrefix(`/foo`)"
|
||||
entryPoints: [web]
|
||||
service: whoami
|
||||
middlewares: [bouncer]
|
||||
services:
|
||||
whoami:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://whoami:80"
|
||||
middlewares:
|
||||
bouncer:
|
||||
plugin:
|
||||
bouncer:
|
||||
enabled: true
|
||||
crowdsecMode: stream
|
||||
updateIntervalSeconds: 3
|
||||
crowdsecLapiKey: "40796d93c2958f9e58345514e67740e5"
|
||||
forwardedHeadersTrustedIPs:
|
||||
- "172.16.0.0/12"
|
||||
Reference in New Issue
Block a user