test(07): create integration tests for all labs

Integration Tests (4 files, 600+ lines):
- 01-cross-lab-test.sh: Cross-lab functionality verification
- 02-security-compliance-test.sh: INF-01/02/03/04 across all labs
- 03-architecture-validation-test.sh: Multi-tier architecture validation
- 99-final-integration-test.sh: End-to-end integration validation

Tests verify:
- All labs exist with complete structure
- All INF requirements met across all labs
- Multi-tier architecture properly implemented
- Data flows correctly between tiers
- Security compliance globally enforced

Integration validates:
- Lab 01 (IAM) → AWS IAM
- Lab 02 (Network) → VPC/Subnets
- Lab 03 (Compute) → EC2
- Lab 04 (Storage) → S3/EBS
- Lab 05 (Database) → RDS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Luca Sacchi Ricciardi
2026-04-03 17:46:17 +02:00
parent f669e85266
commit a0de73ae15
4 changed files with 839 additions and 0 deletions

View File

@@ -0,0 +1,201 @@
#!/bin/bash
# Integration Test 02: Security Compliance
# Verifica INF-01, INF-02, INF-03, INF-04 su TUTTI i lab
set -euo pipefail
# Colori
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
pass_count=0
fail_count=0
skip_count=0
inc_pass() { ((pass_count++)) || true; }
inc_fail() { ((fail_count++)) || true; }
inc_skip() { ((skip_count++)) || true; }
echo "=========================================="
echo "Integration Test 02: Security Compliance"
echo "=========================================="
echo ""
# Array di tutti i lab con docker-compose
labs_with_compose=("lab-03-compute" "lab-04-storage" "lab-05-database")
echo "=== INF-01: Nessun container gira come root ==="
echo ""
for lab in "${labs_with_compose[@]}"; do
compose_file="labs/$lab/docker-compose.yml"
if [ ! -f "$compose_file" ]; then
continue
fi
echo -n "[TEST] $lab - non-root containers... "
# Verifica che non ci sia 'user: root' o simili
if grep -q "user: root" "$compose_file"; then
echo -e "${RED}FAIL${NC} (user: root trovato)"
inc_fail
# PostgreSQL official image non gira come root
elif grep -q "image: postgres" "$compose_file"; then
echo -e "${GREEN}PASS${NC} (PostgreSQL non gira come root)"
inc_pass
# Alpine images default to root, ma i nostri Dockerfile creano utenti
elif grep -q "adduser\|addgroup" "$compose_file" 2>/dev/null || \
[ -f "labs/$lab/Dockerfile" ] && grep -q "adduser\|addgroup" "labs/$lab/Dockerfile"; then
echo -e "${GREEN}PASS${NC} (utente non-root configurato)"
inc_pass
else
echo -e "${YELLOW}WARN${NC} (impossibile verificare automaticamente)"
inc_skip
fi
done
echo ""
echo "=== INF-02: Reti private non espongono porte sull'host ==="
echo ""
labs_with_private=("lab-02-network" "lab-05-database")
for lab in "${labs_with_private[@]}"; do
compose_file="labs/$lab/docker-compose.yml"
if [ ! -f "$compose_file" ]; then
continue
fi
echo -n "[TEST] $lab - private network ports... "
# Cerca database o servizi in rete privata
if grep -A 20 "db:" "$compose_file" | grep -q "ports:"; then
# Se ci sono porte, verifica che siano 127.0.0.1
if grep -A 20 "db:" "$compose_file" | grep -A 5 "ports:" | grep -q "127.0.0.1"; then
echo -e "${YELLOW}WARN${NC} (porta su 127.0.0.1 - RDS non expone porte)"
inc_skip
else
echo -e "${RED}FAIL${NC} (porta esposta su host)"
inc_fail
fi
else
echo -e "${GREEN}PASS${NC} (nessuna porta esposta)"
inc_pass
fi
done
echo ""
echo "=== INF-03: Tutti i container hanno limiti risorse ==="
echo ""
for lab in "${labs_with_compose[@]}"; do
compose_file="labs/$lab/docker-compose.yml"
if [ ! -f "$compose_file" ]; then
continue
fi
echo -n "[TEST] $lab - resource limits... "
# Verifica deploy.resources per ogni servizio
services=$(grep "^ [a-z]*:" "$compose_file" | grep -v "^ #" | sed 's/://g' | grep -v "^networks\|^volumes")
all_limited=true
for service in $services; do
if grep -A 30 "^ $service:" "$compose_file" | grep -q "deploy:"; then
if grep -A 30 "^ $service:" "$compose_file" | grep -A 10 "deploy:" | grep -q "cpus:" && \
grep -A 30 "^ $service:" "$compose_file" | grep -A 10 "deploy:" | grep -q "memory:"; then
: # service has limits
else
all_limited=false
break
fi
else
all_limited=false
break
fi
done
if $all_limited; then
echo -e "${GREEN}PASS${NC}"
inc_pass
else
echo -e "${RED}FAIL${NC} (alcuni servizi senza limiti)"
inc_fail
fi
done
echo ""
echo "=== INF-04: Dati persistenti in volumi nominativi ==="
echo ""
labs_with_volumes=("lab-04-storage" "lab-05-database")
for lab in "${labs_with_volumes[@]}"; do
compose_file="labs/$lab/docker-compose.yml"
if [ ! -f "$compose_file" ]; then
continue
fi
echo -n "[TEST] $lab - named volumes... "
# Verifica sezioni volumes definita
if grep -q "^volumes:" "$compose_file"; then
# Verifica che i volumi usino driver local
if grep -A 10 "^volumes:" "$compose_file" | grep -q "driver: local"; then
echo -e "${GREEN}PASS${NC}"
inc_pass
else
echo -e "${YELLOW}WARN${NC} (volumi definiti ma driver non verificato)"
inc_skip
fi
else
echo -e "${RED}FAIL${NC} (nessun volume definito)"
inc_fail
fi
done
echo ""
echo "=== Verifica Container in Esecuzione ==="
echo ""
running_containers=$(docker ps --format '{{{{Names}}}}' | grep -E "lab0[1-5]" | wc -l)
echo -n "[TEST] Container in esecuzione... "
if [ $running_containers -gt 0 ]; then
echo -e "${GREEN}PASS${NC} ($running_containers container)"
inc_pass
# Verifica non-root per container in esecuzione
echo ""
echo "[TEST] Verifica non-root per container in esecuzione..."
for container in $(docker ps --format '{{{{Names}}}}' | grep -E "lab0[1-5]"); do
container_user=$(docker exec $container whoami 2>/dev/null || echo "unknown")
echo -n " $container: utente=$container_user... "
if [ "$container_user" != "root" ]; then
echo -e "${GREEN}OK${NC}"
inc_pass
else
echo -e "${RED}FAIL${NC}"
inc_fail
fi
done
else
echo -e "${YELLOW}SKIP${NC} (nessun container in esecuzione)"
inc_skip
fi
echo ""
echo "=========================================="
echo "Risultato: $pass_count PASS, $fail_count FAIL, $skip_count SKIP"
echo "=========================================="
if [ $fail_count -gt 0 ]; then
echo ""
echo -e "${RED}✗ SECURITY COMPLIANCE FAIL${NC}"
echo "Risolvere le violazioni INF prima di procedere"
exit 1
fi
exit 0