Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bin/dotsec
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ if [[ -z "${WORKSPACE_ROOT:-}" ]]; then
fi

DOTSEC_LIB="${DOTSEC_HOME}/lib"
for _m in ui core secrets dashboard proxy exegol engagement; do
for _m in ui core secrets dashboard proxy exegol engagement status; do
# shellcheck source=/dev/null
source "${DOTSEC_LIB}/${_m}.sh"
done
Expand Down Expand Up @@ -79,6 +79,7 @@ case "${1:-help}" in
printf '%b\n' "${GREEN}Rotated${RESET} ${CYAN}${_t}${RESET} ${DIM}(${_type})${RESET}"
;;
env) shift; cmd_env "$@";;
status) shift; cmd_status "$@";;
info) cmd_info;;
completions) shift; exec "${DOTSEC_HOME}/bin/dotsec-completions" "$@";;
help|--help|-h) usage;;
Expand Down
2 changes: 1 addition & 1 deletion bin/dotsec-completions
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Usage: source <(dotsec completions zsh)

_dotsec_completions() {
local commands="new load unload list spawn board dashboard proxy browser exegol tmux log secrets rotate archive stop restart completions info help"
local commands="new load unload list spawn board dashboard proxy browser exegol tmux log secrets rotate status archive stop restart completions info help"
local proxy_sub="up down status logs"
local board_sub="up start down stop reload status"
local exegol_sub="exec shell setup"
Expand Down
54 changes: 54 additions & 0 deletions lib/status.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
# ─── lib/status.sh ─── engagement status overview ──

__status_global() {
local exegol="${EXEGOL_CONTAINER:-exegol}"
local ex_state="stopped" db_state="down"
docker ps --filter "name=^${exegol}$" --format '{{.Names}}' 2>/dev/null | grep -q . && ex_state="running"
docker ps --filter "name=dotsec-homer" --format '{{.Names}}' 2>/dev/null | grep -q . \
&& db_state="up (127.0.0.1:${HOMER_PORT:-9997})"
printf '%b\n' "${BOLD}${CYAN}Global${RESET} ${DIM}Exegol:${RESET} ${ex_state} ${DIM}Dashboard:${RESET} ${db_state}"
return 0
}

__status_engagement() {
local target="$1" ws="$2"
local domain proxy tmuxs size loot last pport wport exegol
domain=$(__env_domain "${ws}/.env"); [[ -z "$domain" ]] && domain="?"
pport=$(grep -oP 'PROXY_PORT="?\K[0-9]+' "${ws}/.env" 2>/dev/null | head -1 || true); pport="${pport:-9999}"
wport=$(grep -oP 'WEB_PORT="?\K[0-9]+' "${ws}/.env" 2>/dev/null | head -1 || true); wport="${wport:-9998}"
proxy="down"
if docker ps --filter "name=mitmproxy-${target}" --format '{{.Names}}' 2>/dev/null | grep -q .; then
proxy="up 127.0.0.1:${pport} / ${wport}"
fi
tmuxs="—"
exegol="${EXEGOL_CONTAINER:-exegol}"
if docker ps --filter "name=^${exegol}$" --format '{{.Names}}' 2>/dev/null | grep -q .; then
docker exec "$exegol" tmux has-session -t "$target" 2>/dev/null && tmuxs="session present"
fi
size=$(du -sh "$ws" 2>/dev/null | cut -f1 || true); size="${size:-?}"
loot=$(find "${ws}/recon/loot" -type f 2>/dev/null | wc -l || true); loot="${loot:-0}"
last=$(find "$ws" -type f -printf '%TY-%Tm-%Td %TH:%TM\n' 2>/dev/null | sort -r | head -1 || true); last="${last:-?}"
printf '%b\n' "${GREEN}${target}${RESET} ${DIM}→ ${domain}${RESET}"
printf '%b\n' " ${DIM}Proxy${RESET} ${proxy}"
printf '%b\n' " ${DIM}Tmux${RESET} ${tmuxs}"
printf '%b\n' " ${DIM}Workspace${RESET} ${size} ${DIM}loot:${RESET} ${loot} ${DIM}last:${RESET} ${last}"
return 0
}

cmd_status() {
local only="${1:-}"
__require_docker
__status_global
echo ""
local found=0 d target
for d in "${WORKSPACE_ROOT:-/workspace}"/*/; do
[[ -d "$d" ]] || continue
target=$(basename "$d")
[[ -n "$only" && "$target" != "$only" ]] && continue
__status_engagement "$target" "${d%/}"
found=1
done
[[ $found -eq 0 ]] && printf '%b\n' " ${DIM}No engagements yet.${RESET} ${YELLOW}dotsec new <target>${RESET}"
return 0
}
1 change: 1 addition & 0 deletions lib/ui.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ ${BOLD}${MAGENTA}EXEGOL${RESET}
${GREEN}exegol${RESET} ${DIM}exec|shell|setup${RESET} Run commands inside Exegol

${BOLD}${CYAN}INFO${RESET}
${GREEN}status${RESET} ${DIM}[target]${RESET} Overview: engagements, proxy/tmux, stats
${GREEN}info${RESET} Show current engagement
${GREEN}help${RESET} This message

Expand Down
41 changes: 41 additions & 0 deletions tests/status.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bats
load test_helper

setup() {
WS="$(mktemp -d)"; CFG="$(mktemp -d)"
export WORKSPACE_ROOT="$WS" DOTSEC_CONFIG="$CFG"
export PATH="${DOTSEC_HOME}/tests/stubs:$PATH" # stub docker (ps → empty)
}
teardown() { rm -rf "$WS" "$CFG"; }

mk() { # mk <target> <domain>
mkdir -p "$WS/$1/recon/loot"
printf 'export TARGET="%s"\nexport DOMAIN="%s"\nexport PROXY_PORT="9999"\n' "$1" "$2" > "$WS/$1/.env"
}

@test "status with no engagements shows hint" {
run "$DOTSEC_BIN" status
[ "$status" -eq 0 ]
[[ "$output" == *"No engagements"* ]]
}

@test "status lists engagements with domain + stats + global header" {
mk acme acme.com
mk ghost ghost.com
run "$DOTSEC_BIN" status
[ "$status" -eq 0 ]
[[ "$output" == *"Global"* ]]
[[ "$output" == *"acme"* ]] && [[ "$output" == *"acme.com"* ]]
[[ "$output" == *"ghost"* ]] && [[ "$output" == *"ghost.com"* ]]
[[ "$output" == *"Workspace"* ]]
[[ "$output" == *"Proxy"* ]]
}

@test "status <target> shows only that engagement" {
mk acme acme.com
mk ghost ghost.com
run "$DOTSEC_BIN" status acme
[ "$status" -eq 0 ]
[[ "$output" == *"acme"* ]]
[[ "$output" != *"ghost"* ]]
}
Loading