feat: Add credentials management system and comprehensive testing

- Add credentials management system with automatic saving and updates
- Add upload form URL to JSON output
- Add Ollama model information to JSON output
- Implement credential update system (update_credentials.sh)
- Implement credential save system (save_credentials.sh)
- Add comprehensive test suites (infrastructure, n8n, PostgREST, complete system)
- Add workflow auto-reload system with systemd service
- Add detailed documentation (CREDENTIALS_MANAGEMENT.md, TEST_REPORT.md, VERIFICATION_SUMMARY.md)
- Improve n8n setup with robust API-based workflow import
- Add .gitignore for credentials directory
- All tests passing (40+ test cases)

Key Features:
- Credentials automatically saved to credentials/<hostname>.json
- Update Ollama URL from IP to hostname without container restart
- Comprehensive testing with 4 test suites
- Full documentation and examples
- Production-ready system
This commit is contained in:
2026-01-24 22:31:26 +01:00
parent eb876bc267
commit aa00fb9d29
22 changed files with 4157 additions and 1 deletions

View File

@@ -608,6 +608,10 @@ SUPABASE_URL_EXTERNAL="http://${CT_IP}:${POSTGREST_PORT}"
CHAT_WEBHOOK_URL="https://${FQDN}/webhook/rag-chat-webhook/chat"
CHAT_INTERNAL_URL="http://${CT_IP}:5678/webhook/rag-chat-webhook/chat"
# Upload Form URL (for document upload)
UPLOAD_FORM_URL="https://${FQDN}/form/rag-upload-form"
UPLOAD_FORM_INTERNAL_URL="http://${CT_IP}:5678/form/rag-upload-form"
info "n8n intern: ${N8N_INTERNAL_URL}"
info "n8n extern (geplant via OPNsense): ${N8N_EXTERNAL_URL}"
info "PostgREST API: ${POSTGREST_URL}"
@@ -632,6 +636,42 @@ else
info "Step 10: You can manually import the workflow via n8n UI"
fi
# ---------------------------
# Step 10a: Setup Workflow Auto-Reload on LXC Restart
# ---------------------------
info "Step 10a: Setting up workflow auto-reload on LXC restart..."
# Copy workflow template to container for auto-reload
info "Copying workflow template to container..."
if [[ -f "${WORKFLOW_FILE}" ]]; then
# Read workflow file content
WORKFLOW_CONTENT=$(cat "${WORKFLOW_FILE}")
pct_push_text "${CTID}" "/opt/customer-stack/workflow-template.json" "${WORKFLOW_CONTENT}"
info "Workflow template saved to /opt/customer-stack/workflow-template.json"
else
warn "Workflow file not found: ${WORKFLOW_FILE}"
fi
# Copy reload script to container
info "Installing workflow reload script..."
RELOAD_SCRIPT_CONTENT=$(cat "${SCRIPT_DIR}/templates/reload-workflow.sh")
pct_push_text "${CTID}" "/opt/customer-stack/reload-workflow.sh" "${RELOAD_SCRIPT_CONTENT}"
pct_exec "${CTID}" "chmod +x /opt/customer-stack/reload-workflow.sh"
info "Reload script installed"
# Copy systemd service file to container
info "Installing systemd service for workflow auto-reload..."
SYSTEMD_SERVICE_CONTENT=$(cat "${SCRIPT_DIR}/templates/n8n-workflow-reload.service")
pct_push_text "${CTID}" "/etc/systemd/system/n8n-workflow-reload.service" "${SYSTEMD_SERVICE_CONTENT}"
# Enable and start systemd service
pct_exec "${CTID}" "systemctl daemon-reload"
pct_exec "${CTID}" "systemctl enable n8n-workflow-reload.service"
info "Systemd service enabled"
info "Step 10a OK: Workflow auto-reload configured"
info "The workflow will be automatically reloaded on every LXC restart"
# ---------------------------
# Step 11: Setup NGINX Reverse Proxy in OPNsense
# ---------------------------
@@ -667,7 +707,7 @@ info "Step 11 OK: Proxy setup completed"
# Kompaktes JSON in einer Zeile für einfaches Parsing
# Bei DEBUG=0: JSON auf fd 3 (ursprüngliches stdout) ausgeben
# Bei DEBUG=1: JSON normal auf stdout (geht auch ins Log)
JSON_OUTPUT="{\"ctid\":${CTID},\"hostname\":\"${CT_HOSTNAME}\",\"fqdn\":\"${FQDN}\",\"ip\":\"${CT_IP}\",\"vlan\":${VLAN},\"urls\":{\"n8n_internal\":\"${N8N_INTERNAL_URL}\",\"n8n_external\":\"${N8N_EXTERNAL_URL}\",\"postgrest\":\"${POSTGREST_URL}\",\"chat_webhook\":\"${CHAT_WEBHOOK_URL}\",\"chat_internal\":\"${CHAT_INTERNAL_URL}\"},\"postgres\":{\"host\":\"postgres\",\"port\":5432,\"db\":\"${PG_DB}\",\"user\":\"${PG_USER}\",\"password\":\"${PG_PASSWORD}\"},\"supabase\":{\"url\":\"${SUPABASE_URL}\",\"url_external\":\"${SUPABASE_URL_EXTERNAL}\",\"anon_key\":\"${ANON_KEY}\",\"service_role_key\":\"${SERVICE_ROLE_KEY}\",\"jwt_secret\":\"${JWT_SECRET}\"},\"ollama\":{\"url\":\"${OLLAMA_URL}\"},\"n8n\":{\"encryption_key\":\"${N8N_ENCRYPTION_KEY}\",\"owner_email\":\"${N8N_OWNER_EMAIL}\",\"owner_password\":\"${N8N_OWNER_PASS}\",\"secure_cookie\":${N8N_SECURE_COOKIE}},\"log_file\":\"${FINAL_LOG}\"}"
JSON_OUTPUT="{\"ctid\":${CTID},\"hostname\":\"${CT_HOSTNAME}\",\"fqdn\":\"${FQDN}\",\"ip\":\"${CT_IP}\",\"vlan\":${VLAN},\"urls\":{\"n8n_internal\":\"${N8N_INTERNAL_URL}\",\"n8n_external\":\"${N8N_EXTERNAL_URL}\",\"postgrest\":\"${POSTGREST_URL}\",\"chat_webhook\":\"${CHAT_WEBHOOK_URL}\",\"chat_internal\":\"${CHAT_INTERNAL_URL}\",\"upload_form\":\"${UPLOAD_FORM_URL}\",\"upload_form_internal\":\"${UPLOAD_FORM_INTERNAL_URL}\"},\"postgres\":{\"host\":\"postgres\",\"port\":5432,\"db\":\"${PG_DB}\",\"user\":\"${PG_USER}\",\"password\":\"${PG_PASSWORD}\"},\"supabase\":{\"url\":\"${SUPABASE_URL}\",\"url_external\":\"${SUPABASE_URL_EXTERNAL}\",\"anon_key\":\"${ANON_KEY}\",\"service_role_key\":\"${SERVICE_ROLE_KEY}\",\"jwt_secret\":\"${JWT_SECRET}\"},\"ollama\":{\"url\":\"${OLLAMA_URL}\",\"model\":\"${OLLAMA_MODEL}\",\"embedding_model\":\"${EMBEDDING_MODEL}\"},\"n8n\":{\"encryption_key\":\"${N8N_ENCRYPTION_KEY}\",\"owner_email\":\"${N8N_OWNER_EMAIL}\",\"owner_password\":\"${N8N_OWNER_PASS}\",\"secure_cookie\":${N8N_SECURE_COOKIE}},\"log_file\":\"${FINAL_LOG}\"}"
if [[ "$DEBUG" == "1" ]]; then
# Debug-Modus: JSON normal ausgeben (formatiert für Lesbarkeit)
@@ -676,3 +716,16 @@ else
# Normal-Modus: JSON auf ursprüngliches stdout (fd 3) - kompakt
echo "$JSON_OUTPUT" >&3
fi
# ---------------------------
# Save credentials to file
# ---------------------------
CREDENTIALS_DIR="${SCRIPT_DIR}/credentials"
mkdir -p "${CREDENTIALS_DIR}"
CREDENTIALS_FILE="${CREDENTIALS_DIR}/${CT_HOSTNAME}.json"
# Save formatted credentials
echo "$JSON_OUTPUT" | python3 -m json.tool > "${CREDENTIALS_FILE}" 2>/dev/null || echo "$JSON_OUTPUT" > "${CREDENTIALS_FILE}"
info "Credentials saved to: ${CREDENTIALS_FILE}"
info "To update credentials later, use: bash update_credentials.sh --ctid ${CTID} --credentials-file ${CREDENTIALS_FILE}"