function cmd::group::show() { local name="" while [[ $# -gt 0 ]]; do case "$1" in --name) util::require_flag "--name" "${2:-}" || return 1; name="$2"; shift 2 ;; --help) cmd::group::help; return ;; *) log::error "Unknown flag: $1"; return 1 ;; esac done [[ -z "$name" ]] && log::error "Missing required flag: --name" && return 1 group::require_exists "$name" || return 1 local group_file group_file="$(group::path "$name")" log::section "Group: ${name}" local desc desc=$(json::get "$group_file" "desc") printf "\n %-20s %s\n" "Description:" "${desc:-—}" # Load peers local peers_list=() mapfile -t peers_list < <(json::get "$group_file" "peers") # Filter empty entries local filtered=() for p in "${peers_list[@]:-}"; do [[ -n "$p" ]] && filtered+=("$p") done peers_list=("${filtered[@]:-}") local peer_count=${#peers_list[@]} [[ -z "${peers_list[0]}" ]] && peer_count=0 printf " %-20s %s\n" "Peers:" "$peer_count" printf " %s\n" "$(printf '─%.0s' {1..50})" if [[ "$peer_count" -gt 0 ]]; then printf "\n %-28s %-15s %-12s %s\n" "NAME" "IP" "RULE" "STATUS" printf " %s\n" "$(printf '─%.0s' {1..65})" for peer_name in "${peers_list[@]}"; do [[ -z "$peer_name" ]] && continue local ip rule status_str status_color ip=$(peers::get_ip "$peer_name") rule=$(peers::get_meta "$peer_name" "rule") rule="${rule:-—}" if peers::is_blocked "$peer_name"; then status_color="\033[1;31m" status_str="blocked" else status_color="\033[1;32m" status_str="active" fi printf " %-28s %-15s %-12s %b\n" \ "$peer_name" "${ip:-—}" "$rule" \ "${status_color}${status_str}\033[0m" done else printf " —\n" fi printf "\n" }