472 lines
14 KiB
Bash
Executable File
472 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
|
# 🦉 Crumbpages Doktor v2.0-RC3 - Der Wald-Sanitäter für dein Repo
|
|
# Mit .env Support und spezialisierten Shells
|
|
|
|
# Farben für schöne Ausgabe
|
|
GREEN='\033[0;32m'
|
|
BLUE='\033[0;34m'
|
|
RED='\033[0;31m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Infrastruktur: Environment
|
|
# -----------------------------------------------------------------------------
|
|
ENV_FILE=".env"
|
|
|
|
function check_env() {
|
|
if [ ! -f "$ENV_FILE" ]; then
|
|
echo -e "${YELLOW}Keine .env Datei gefunden. Erstelle Template...${NC}"
|
|
cat > "$ENV_FILE" << EOF
|
|
# Crumbpages Doktor Configuration
|
|
# API Setup
|
|
CRUMB_API_URL="https://api.crumbforest.de"
|
|
CRUMB_API_TOKEN="changeme"
|
|
|
|
# Remote / SSH
|
|
CRUMB_SSH_USER="admin"
|
|
CRUMB_SCP_TARGET="backup.crumbforest.de:/var/backups"
|
|
|
|
# Vektor DB (Qdrant)
|
|
CRUMB_QDRANT_URL="http://localhost:6333"
|
|
CRUMB_QDRANT_KEY=""
|
|
|
|
EOF
|
|
echo -e "${GREEN}.env Template erstellt. Bitte anpassen!${NC}"
|
|
sleep 2
|
|
fi
|
|
|
|
# Load Env
|
|
source "$ENV_FILE"
|
|
}
|
|
|
|
# Starte Env Check
|
|
check_env
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Modul: Git Doktor (Interactive Shell)
|
|
# -----------------------------------------------------------------------------
|
|
function git_doktor() {
|
|
echo -e "${BLUE}--- 🌲 Git Workstation ---${NC}"
|
|
export GIT_RC="/tmp/git_doktor.rc"
|
|
|
|
cat > "$GIT_RC" << 'EOF'
|
|
if [ -f /etc/bashrc ]; then source /etc/bashrc; fi
|
|
if [ -f ~/.bashrc ]; then source ~/.bashrc; fi
|
|
|
|
export PS1="\[\033[0;34m\](🌲 Git) \u@\h:\w$ \[\033[0m\]"
|
|
|
|
function check_health() {
|
|
echo "Prüfe Repo Gesundheit..."
|
|
if [ ! -d ".git" ]; then echo "❌ Kein Git Repo!"; return; fi
|
|
git remote update > /dev/null 2>&1
|
|
LOCAL=$(git rev-parse @)
|
|
REMOTE=$(git rev-parse @{u} 2>/dev/null)
|
|
|
|
if [ "$LOCAL" = "$REMOTE" ]; then
|
|
echo "✅ Synchron."
|
|
else
|
|
echo "⚠️ Nicht synchron / Push needed."
|
|
fi
|
|
git status --short
|
|
}
|
|
|
|
alias gst="git status"
|
|
alias gd="git diff"
|
|
alias gl="git log --oneline --graph --decorate --all -n 10"
|
|
|
|
echo ""
|
|
echo "Willkommen in der Git Shell."
|
|
echo "Befehle: check_health, gst, gd, gl"
|
|
echo ""
|
|
check_health
|
|
EOF
|
|
|
|
bash --rcfile "$GIT_RC"
|
|
rm -f "$GIT_RC"
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Modul: Web Tools (API / Curl)
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
# Modul: Web Tools (API / Curl)
|
|
# -----------------------------------------------------------------------------
|
|
# -----------------------------------------------------------------------------
|
|
# Modul: Web Tools (API / Curl)
|
|
# -----------------------------------------------------------------------------
|
|
function web_doktor() {
|
|
echo -e "${BLUE}--- 🕸️ Web Tools (API) ---${NC}"
|
|
export WEB_RC="/tmp/web_doktor.rc"
|
|
|
|
cat > "$WEB_RC" << EOF
|
|
if [ -f /etc/bashrc ]; then source /etc/bashrc; fi
|
|
if [ -f ~/.bashrc ]; then source ~/.bashrc; fi
|
|
|
|
export PS1="\[\033[0;36m\](🕸️ Web) \u@\h:\w$ \[\033[0m\]"
|
|
export API_URL="$CRUMB_API_URL"
|
|
export TOKEN="$CRUMB_API_TOKEN"
|
|
|
|
function api_help() {
|
|
echo "Configured API: \$API_URL"
|
|
if [ -n "\$TOKEN" ] && [ "\$TOKEN" != "changeme" ]; then
|
|
echo "Token: Set (\${TOKEN:0:5}...)"
|
|
else
|
|
echo "Token: None (Public Mode)"
|
|
fi
|
|
echo ""
|
|
echo "Endpoints:"
|
|
echo " GET /api/hello?lang=admin"
|
|
echo " POST /api/diary/index"
|
|
echo " POST /api/diary/search"
|
|
echo " POST /api/diary/search"
|
|
echo " GET /api/diary/{child_id}/status"
|
|
echo " GET /health"
|
|
echo " GET /__routes"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " api_search <query> -> Search Diary (JSON)"
|
|
echo " api_get <path> -> Generic GET (e.g. 'health')"
|
|
echo " api_post <path> <body> -> Generic POST (body as JSON string)"
|
|
echo " open_url <url> -> Open in Browser"
|
|
echo ""
|
|
echo "💡 Tipp: Nutze 'jq' für schönes JSON: api_search 'vpn' | jq"
|
|
}
|
|
|
|
# Helper to build common curl args
|
|
function _build_curl_args() {
|
|
CURL_ARGS=(-s)
|
|
if [ -n "\$TOKEN" ] && [ "\$TOKEN" != "changeme" ]; then
|
|
CURL_ARGS+=(-H "Authorization: Bearer \$TOKEN")
|
|
fi
|
|
}
|
|
|
|
function api_get() {
|
|
if [ -z "\$1" ]; then echo "Usage: api_get <endpoint>"; return; fi
|
|
ENDPOINT="\${1#/}"
|
|
|
|
_build_curl_args
|
|
curl "\${CURL_ARGS[@]}" "\$API_URL/\$ENDPOINT"
|
|
}
|
|
|
|
function api_post() {
|
|
if [ -z "\$1" ]; then echo "Usage: api_post <endpoint> <json_body>"; return; fi
|
|
ENDPOINT="\${1#/}"
|
|
# Use array for body to avoid quoting hell, or just pass strictly
|
|
BODY="\${2:-{}}"
|
|
|
|
echo "POST \$API_URL/\$ENDPOINT ..." >&2
|
|
|
|
_build_curl_args
|
|
CURL_ARGS+=(-X POST -H "Content-Type: application/json")
|
|
CURL_ARGS+=(-d "\$BODY")
|
|
|
|
curl "\${CURL_ARGS[@]}" "\$API_URL/\$ENDPOINT"
|
|
}
|
|
|
|
function api_search() {
|
|
if [ -z "\$1" ]; then echo "Usage: api_search <query> [limit]"; return; fi
|
|
QUERY="\$1"
|
|
LIMIT="\${2:-5}"
|
|
|
|
if command -v python3 &>/dev/null; then
|
|
ENCODED_QUERY=\$(python3 -c "import urllib.parse; print(urllib.parse.quote('''\$QUERY'''))")
|
|
else
|
|
ENCODED_QUERY="\$QUERY"
|
|
fi
|
|
|
|
echo "Suche nach '\$QUERY' (Limit: \$LIMIT)..." >&2
|
|
|
|
_build_curl_args
|
|
curl "\${CURL_ARGS[@]}" "\$API_URL/api/documents/search?q=\$ENCODED_QUERY&limit=\$LIMIT"
|
|
}
|
|
|
|
function open_url() {
|
|
if [ -z "\$1" ]; then echo "Usage: open_url <url>"; return; fi
|
|
if [[ "\$OSTYPE" == "darwin"* ]]; then
|
|
open "\$1"
|
|
elif [[ "\$OSTYPE" == "linux-gnu"* ]]; then
|
|
xdg-open "\$1" 2>/dev/null || echo "Kein Browser gefunden."
|
|
else
|
|
echo "OS nicht unterstützt für Browser-Start."
|
|
fi
|
|
}
|
|
|
|
alias wget_clean="wget --hsts-file=/tmp/.wget-hsts"
|
|
|
|
echo ""
|
|
api_help
|
|
EOF
|
|
|
|
bash --rcfile "$WEB_RC"
|
|
rm -f "$WEB_RC"
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Modul: Remote Tools (SSH / SCP)
|
|
# -----------------------------------------------------------------------------
|
|
function remote_doktor() {
|
|
echo -e "${BLUE}--- 🔐 Remote Tools (SSH) ---${NC}"
|
|
export REMOTE_RC="/tmp/remote_doktor.rc"
|
|
|
|
cat > "$REMOTE_RC" << EOF
|
|
if [ -f /etc/bashrc ]; then source /etc/bashrc; fi
|
|
if [ -f ~/.bashrc ]; then source ~/.bashrc; fi
|
|
|
|
export PS1="\[\033[0;31m\](🔐 Remote) \u@\h:\w$ \[\033[0m\]"
|
|
export SSH_USER="$CRUMB_SSH_USER"
|
|
export SCP_TARGET="$CRUMB_SCP_TARGET"
|
|
|
|
# Paranoid Mode: Clear keys when this shell exits
|
|
trap 'echo "🧹 Cleaning up keys..."; ssh-add -D 2>/dev/null' EXIT
|
|
|
|
# Watchdog Control Paths
|
|
WATCHDOG_PID="$HOME/.ssh-agent-watchdog.pid"
|
|
WATCHDOG_PAUSE="$HOME/.ssh-agent-watchdog.pause"
|
|
|
|
function remote_help() {
|
|
echo "User: \$SSH_USER | Target: \$SCP_TARGET"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " crumbupload <file> -> SCP file to target"
|
|
echo " my_keys -> List local public keys"
|
|
echo " ssh_config -> Edit SSH config"
|
|
echo " watchdog status -> Check Agent Watchdog"
|
|
echo " watchdog off -> Pause Watchdog (for large transfers)"
|
|
echo " watchdog on -> Resume Watchdog"
|
|
}
|
|
|
|
function watchdog() {
|
|
CMD="\$1"
|
|
case "\$CMD" in
|
|
status)
|
|
if [ -f "\$WATCHDOG_PID" ] && kill -0 \$(cat "\$WATCHDOG_PID") 2>/dev/null; then
|
|
if [ -f "\$WATCHDOG_PAUSE" ]; then
|
|
echo "⚠️ Watchdog läuft (PID \$(cat \$WATCHDOG_PID)), ist aber PAUSIERT (Deep Work)."
|
|
else
|
|
echo "✅ Watchdog läuft und ist scharf (PID \$(cat \$WATCHDOG_PID))."
|
|
fi
|
|
else
|
|
echo "❌ Watchdog läuft nicht."
|
|
fi
|
|
;;
|
|
off|pause)
|
|
touch "\$WATCHDOG_PAUSE"
|
|
echo "⏸️ Watchdog pausiert. Bildschirmsperre tötet den Agent jetzt NICHT."
|
|
;;
|
|
on|resume)
|
|
rm -f "\$WATCHDOG_PAUSE"
|
|
echo "▶️ Watchdog wieder aktiv. Zero Trust re-enabled."
|
|
;;
|
|
*)
|
|
echo "Usage: watchdog {status|off|on}"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function crumbupload() {
|
|
if [ -z "\$1" ]; then echo "Usage: crumbupload <file>"; return; fi
|
|
scp "\$1" "\$SSH_USER@\$SCP_TARGET"
|
|
}
|
|
|
|
alias my_keys="ls -l ~/.ssh/*.pub"
|
|
alias ssh_config="nano ~/.ssh/config"
|
|
|
|
echo ""
|
|
echo "⚠️ Paranoid Mode: Closing this shell clears ssh-agent keys!"
|
|
remote_help
|
|
EOF
|
|
|
|
bash --rcfile "$REMOTE_RC"
|
|
rm -f "$REMOTE_RC"
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Modul: DNS Doktor (Legacy Logic)
|
|
# -----------------------------------------------------------------------------
|
|
function dns_doktor() {
|
|
echo -e "${BLUE}--- 🌐 DNS Doktor: Namensauflösung ---${NC}"
|
|
echo "Welche Domain soll ich untersuchen?"
|
|
read -p "Domain [crumbforest.de]: " DOMAIN
|
|
DOMAIN=${DOMAIN:-crumbforest.de}
|
|
|
|
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M")
|
|
REPORT_FILE="dns_report_${DOMAIN}_${TIMESTAMP}.txt"
|
|
|
|
check_record() {
|
|
local type=$1
|
|
local server=$2
|
|
local desc=$3
|
|
echo -n "Prüfe $type ($desc)... "
|
|
if [ -n "$server" ]; then RESULT=$(dig $server +short -t $type $DOMAIN 2>&1); else RESULT=$(dig +short -t $type $DOMAIN 2>&1); fi
|
|
if [ -n "$RESULT" ]; then echo -e "${GREEN}OK${NC}"; echo "$type Records:" >> $REPORT_FILE; echo "$RESULT" >> $REPORT_FILE; echo "---" >> $REPORT_FILE; else echo -e "${YELLOW}LEER${NC}"; echo "$type Records: LEER" >> $REPORT_FILE; echo "---" >> $REPORT_FILE; fi
|
|
}
|
|
|
|
echo "Erstelle Bericht in: $REPORT_FILE"
|
|
echo "DNS Report für $DOMAIN ($TIMESTAMP)" > $REPORT_FILE
|
|
|
|
check_record "A" "" "Lokal"
|
|
check_record "A" "@8.8.8.8" "Google"
|
|
check_record "MX" "" "MX"
|
|
check_record "SOA" "" "SOA"
|
|
check_record "TXT" "" "SPF"
|
|
|
|
echo -e "\n${BLUE}🔍 Starte Trace...${NC}"
|
|
dig +trace +short $DOMAIN >> $REPORT_FILE 2>&1
|
|
echo -e "${GREEN}✅ Fertig.${NC} Bericht: $REPORT_FILE"
|
|
read -p "Enter..."
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Modul: System Doktor
|
|
# -----------------------------------------------------------------------------
|
|
function system_doktor() {
|
|
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|
echo -e "${BLUE}--- 🐧 Linux Doktor ---${NC}"
|
|
hostnamectl 2>/dev/null || hostname; uname -r; free -h; df -h /
|
|
else
|
|
echo -e "${BLUE}--- 🍏 Mac Doktor ---${NC}"
|
|
hostname; sw_vers; vm_stat | head -n 5; df -h /
|
|
fi
|
|
echo ""
|
|
read -p "Enter..."
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Modul: Werkzeugkasten (General)
|
|
# -----------------------------------------------------------------------------
|
|
function tools_doktor() {
|
|
export TOOL_RC="/tmp/general_doktor.rc"
|
|
cat > "$TOOL_RC" << 'EOF'
|
|
if [ -f /etc/bashrc ]; then source /etc/bashrc; fi
|
|
if [ -f ~/.bashrc ]; then source ~/.bashrc; fi
|
|
|
|
GREEN='\033[0;32m'
|
|
RED='\033[0;31m'
|
|
NC='\033[0m'
|
|
|
|
export PS1="\[\033[0;33m\](🛠️ Tools) \u@\h:\w$ \[\033[0m\]"
|
|
|
|
function doktor_help() {
|
|
echo "Verfügbare Werkzeuge im Wald:"
|
|
echo "-----------------------------"
|
|
TOOLS="htop ncdu tree mc nano vim curl git ip"
|
|
|
|
for tool in $TOOLS; do
|
|
if command -v $tool &> /dev/null; then
|
|
echo -e "${GREEN}✅ $tool${NC}"
|
|
else
|
|
echo -e "${RED}❌ $tool (Nicht installiert)${NC}"
|
|
fi
|
|
done
|
|
}
|
|
|
|
alias logs="tail -f /var/log/syslog 2>/dev/null || tail -f /var/log/system.log"
|
|
alias tf="tail -f"
|
|
|
|
echo ""
|
|
echo "Willkommen im Allgemeinen Werkzeugkasten!"
|
|
doktor_help
|
|
echo ""
|
|
EOF
|
|
bash --rcfile "$TOOL_RC"
|
|
rm -f "$TOOL_RC"
|
|
}
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Modul: Qdrant Doktor (Vektor DB)
|
|
# -----------------------------------------------------------------------------
|
|
function qdrant_doktor() {
|
|
echo -e "${BLUE}--- 🧠 Vektor Doktor (Qdrant) ---${NC}"
|
|
export QDRANT_RC="/tmp/qdrant_doktor.rc"
|
|
|
|
cat > "$QDRANT_RC" << EOF
|
|
if [ -f /etc/bashrc ]; then source /etc/bashrc; fi
|
|
if [ -f ~/.bashrc ]; then source ~/.bashrc; fi
|
|
|
|
export PS1="\[\033[1;35m\](🧠 Vektor) \u@\h:\w$ \[\033[0m\]"
|
|
export QDRANT_URL="$CRUMB_QDRANT_URL"
|
|
export QDRANT_KEY="$CRUMB_QDRANT_KEY"
|
|
|
|
function q_help() {
|
|
echo "Target: \$QDRANT_URL"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " q_health -> Check Health (/healthz)"
|
|
echo " q_list -> List Collections"
|
|
echo " q_info -> Cluster Info"
|
|
echo " q_search <col> <q> -> Search (Raw JSON)"
|
|
}
|
|
|
|
function _q_curl() {
|
|
local endpoint="\$1"
|
|
local method="\${2:-GET}"
|
|
local body="\$3"
|
|
|
|
ARGS=(-s)
|
|
if [ -n "\$QDRANT_KEY" ]; then ARGS+=(-H "api-key: \$QDRANT_KEY"); fi
|
|
ARGS+=(-H "Content-Type: application/json")
|
|
|
|
if [ "$method" == "POST" ]; then
|
|
curl "\${ARGS[@]}" -X POST -d "\$body" "\$QDRANT_URL/\$endpoint"
|
|
else
|
|
curl "\${ARGS[@]}" "\$QDRANT_URL/\$endpoint"
|
|
fi
|
|
}
|
|
|
|
function q_health() {
|
|
resp=\$(_q_curl "healthz")
|
|
echo "Status: \$resp"
|
|
}
|
|
|
|
function q_list() {
|
|
_q_curl "collections" | jq .result.collections[] 2>/dev/null || _q_curl "collections"
|
|
}
|
|
|
|
function q_info() {
|
|
_q_curl "" | jq 2>/dev/null || _q_curl ""
|
|
}
|
|
|
|
alias ql="q_list"
|
|
|
|
echo ""
|
|
q_help
|
|
EOF
|
|
|
|
bash --rcfile "$QDRANT_RC"
|
|
rm -f "$QDRANT_RC"
|
|
}
|
|
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Hauptmenü
|
|
# -----------------------------------------------------------------------------
|
|
while true; do
|
|
clear
|
|
echo -e "${BLUE}🦉 Crumbpages Doktor v2${NC}"
|
|
echo "---------------------------"
|
|
echo "1) 🌲 Git Workstation (Shell)"
|
|
echo "2) 🌐 DNS Doktor (Diagnose)"
|
|
echo "3) 🖥️ System Doktor (Diagnose)"
|
|
echo "4) 🕸️ Web Tools (API / Curl)"
|
|
echo "5) 🔐 Remote Tools (SSH / SCP)"
|
|
echo "6) 🛠️ General Tools (Shell)"
|
|
echo "7) 🧠 Qdrant Doktor (Vektor DB)"
|
|
echo "8) 👋 Beenden"
|
|
echo ""
|
|
read -p "Auswahl [1-8]: " CHOICE
|
|
|
|
case $CHOICE in
|
|
1) git_doktor ;;
|
|
2) dns_doktor ;;
|
|
3) system_doktor ;;
|
|
4) web_doktor ;;
|
|
5) remote_doktor ;;
|
|
6) tools_doktor ;;
|
|
7) qdrant_doktor ;;
|
|
8) echo "Ahoi!"; exit 0 ;;
|
|
*) echo "Bitte 1-8 wählen."; sleep 1 ;;
|
|
esac
|
|
done
|