Hearth is the infrastructure home for the letemcook ecosystem. Ported from coherence-mcp/infra: - Terraform modules (VPC, EKS, IAM, NLB, S3, storage) - Kubernetes manifests (Forgejo, ingress, cert-manager, karpenter) - Deployment scripts (phased rollout) Status: Not deployed. EKS cluster needs to be provisioned. Next steps: 1. Bootstrap terraform backend 2. Deploy phase 1 (foundation) 3. Deploy phase 2 (core services including Forgejo) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
224 lines
6.5 KiB
Bash
Executable file
224 lines
6.5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
#
|
|
# Phase 5 Validation: E2EE Webmail
|
|
#
|
|
# Validates that RFC 0043 components are deployed and healthy:
|
|
# - Webmail frontend (loads, login works)
|
|
# - Key service (health endpoint, key generation)
|
|
# - E2EE functionality (encryption/decryption)
|
|
#
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
PASSED=0
|
|
FAILED=0
|
|
WARNINGS=0
|
|
|
|
# Configuration
|
|
DOMAIN="${DOMAIN:-coherence.dev}"
|
|
|
|
log_info() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_pass() {
|
|
echo -e "${GREEN}[PASS]${NC} $1"
|
|
((PASSED++))
|
|
}
|
|
|
|
log_fail() {
|
|
echo -e "${RED}[FAIL]${NC} $1"
|
|
((FAILED++))
|
|
}
|
|
|
|
log_warn() {
|
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
((WARNINGS++))
|
|
}
|
|
|
|
check_webmail_frontend() {
|
|
log_info "Checking webmail frontend..."
|
|
|
|
# Check if namespace exists
|
|
if ! kubectl get namespace webmail &> /dev/null; then
|
|
log_warn "webmail namespace does not exist (Phase 5 may be optional)"
|
|
return
|
|
fi
|
|
|
|
# Check pod health
|
|
local ready_pods
|
|
ready_pods=$(kubectl -n webmail get pods -l app=webmail -o json 2>/dev/null | jq '[.items[] | select(.status.phase == "Running") | select(.status.containerStatuses[]?.ready == true)] | length')
|
|
|
|
if [ "$ready_pods" -ge 1 ]; then
|
|
log_pass "Webmail frontend has $ready_pods ready pods"
|
|
else
|
|
log_fail "Webmail frontend has no ready pods"
|
|
return
|
|
fi
|
|
|
|
# Check service
|
|
local svc_exists
|
|
svc_exists=$(kubectl -n webmail get svc webmail -o name 2>/dev/null || echo "")
|
|
|
|
if [ -n "$svc_exists" ]; then
|
|
log_pass "Webmail service exists"
|
|
else
|
|
log_fail "Webmail service does not exist"
|
|
fi
|
|
|
|
# Check ingress
|
|
local ingress_exists
|
|
ingress_exists=$(kubectl get ingress -A -o json 2>/dev/null | jq '[.items[] | select(.spec.rules[]?.host | contains("mail"))] | length')
|
|
|
|
if [ "$ingress_exists" -ge 1 ]; then
|
|
log_pass "Webmail ingress configured"
|
|
else
|
|
log_warn "No webmail ingress found"
|
|
fi
|
|
}
|
|
|
|
check_key_service() {
|
|
log_info "Checking key service..."
|
|
|
|
# Check if namespace exists
|
|
if ! kubectl get namespace webmail &> /dev/null; then
|
|
log_warn "webmail namespace does not exist"
|
|
return
|
|
fi
|
|
|
|
# Check pod health
|
|
local ready_pods
|
|
ready_pods=$(kubectl -n webmail get pods -l app=key-service -o json 2>/dev/null | jq '[.items[] | select(.status.phase == "Running") | select(.status.containerStatuses[]?.ready == true)] | length')
|
|
|
|
if [ "$ready_pods" -ge 1 ]; then
|
|
log_pass "Key service has $ready_pods ready pods"
|
|
else
|
|
log_fail "Key service has no ready pods"
|
|
return
|
|
fi
|
|
|
|
# Check health endpoint
|
|
local ks_pod
|
|
ks_pod=$(kubectl -n webmail get pods -l app=key-service -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
|
|
|
|
if [ -n "$ks_pod" ]; then
|
|
local health_status
|
|
health_status=$(kubectl -n webmail exec "$ks_pod" -- wget -q -O - http://localhost:8080/health 2>/dev/null || echo "")
|
|
|
|
if echo "$health_status" | grep -q "ok\|healthy\|200"; then
|
|
log_pass "Key service health endpoint responding"
|
|
else
|
|
log_warn "Key service health check returned: $health_status"
|
|
fi
|
|
fi
|
|
|
|
# Check Vault integration
|
|
log_info "Checking Vault PKI integration..."
|
|
local vault_pki_exists
|
|
vault_pki_exists=$(kubectl -n vault exec vault-0 -- vault secrets list -format=json 2>/dev/null | jq 'has("pki_smime/")' || echo "false")
|
|
|
|
if [ "$vault_pki_exists" = "true" ]; then
|
|
log_pass "Vault S/MIME PKI is configured"
|
|
else
|
|
log_warn "Vault S/MIME PKI not found"
|
|
fi
|
|
}
|
|
|
|
check_e2ee_functionality() {
|
|
log_info "Checking E2EE functionality..."
|
|
|
|
log_info "Manual verification required:"
|
|
echo " 1. Navigate to https://mail.$DOMAIN"
|
|
echo " 2. Login via Keycloak SSO"
|
|
echo " 3. Verify key pair is generated on first login"
|
|
echo " 4. Compose an email to another user"
|
|
echo " 5. Verify email is encrypted in transit"
|
|
echo " 6. Verify recipient can decrypt and read email"
|
|
echo ""
|
|
|
|
log_warn "E2EE functionality requires manual testing"
|
|
}
|
|
|
|
check_stalwart_integration() {
|
|
log_info "Checking Stalwart integration..."
|
|
|
|
# Check if webmail can reach Stalwart
|
|
local webmail_pod
|
|
webmail_pod=$(kubectl -n webmail get pods -l app=webmail -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
|
|
|
|
if [ -n "$webmail_pod" ]; then
|
|
# Check IMAP connectivity
|
|
local imap_check
|
|
imap_check=$(kubectl -n webmail exec "$webmail_pod" -- nc -z stalwart.email.svc.cluster.local 993 2>/dev/null && echo "ok" || echo "fail")
|
|
|
|
if [ "$imap_check" = "ok" ]; then
|
|
log_pass "Webmail can reach Stalwart IMAP"
|
|
else
|
|
log_warn "Webmail cannot reach Stalwart IMAP"
|
|
fi
|
|
|
|
# Check SMTP connectivity
|
|
local smtp_check
|
|
smtp_check=$(kubectl -n webmail exec "$webmail_pod" -- nc -z stalwart.email.svc.cluster.local 587 2>/dev/null && echo "ok" || echo "fail")
|
|
|
|
if [ "$smtp_check" = "ok" ]; then
|
|
log_pass "Webmail can reach Stalwart SMTP"
|
|
else
|
|
log_warn "Webmail cannot reach Stalwart SMTP"
|
|
fi
|
|
else
|
|
log_warn "Cannot check Stalwart integration - no webmail pod"
|
|
fi
|
|
}
|
|
|
|
print_summary() {
|
|
echo ""
|
|
echo "========================================"
|
|
echo "Phase 5 Validation Summary"
|
|
echo "========================================"
|
|
echo -e " ${GREEN}Passed:${NC} $PASSED"
|
|
echo -e " ${RED}Failed:${NC} $FAILED"
|
|
echo -e " ${YELLOW}Warnings:${NC} $WARNINGS"
|
|
echo "========================================"
|
|
|
|
if [ "$FAILED" -gt 0 ]; then
|
|
echo ""
|
|
echo -e "${RED}Phase 5 validation FAILED${NC}"
|
|
echo "Please fix the issues above."
|
|
exit 1
|
|
elif [ "$WARNINGS" -gt 0 ]; then
|
|
echo ""
|
|
echo -e "${YELLOW}Phase 5 validation passed with warnings${NC}"
|
|
echo "Review warnings above. Perform manual E2EE testing."
|
|
exit 0
|
|
else
|
|
echo ""
|
|
echo -e "${GREEN}Phase 5 validation PASSED${NC}"
|
|
echo "Full infrastructure stack deployment complete!"
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
echo "========================================"
|
|
echo "Phase 5 Validation: E2EE Webmail"
|
|
echo "========================================"
|
|
echo ""
|
|
|
|
check_webmail_frontend
|
|
check_key_service
|
|
check_stalwart_integration
|
|
check_e2ee_functionality
|
|
|
|
print_summary
|
|
}
|
|
|
|
main "$@"
|