Public Access
bd5f676e0a
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Has been cancelled
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Has been cancelled
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Has been cancelled
Platform: moko-platform CI / Gate 4: Governance (push) Has been cancelled
Platform: moko-platform CI / Gate 5: Template Integrity (push) Has been cancelled
Platform: moko-platform CI / CI Summary (push) Has been cancelled
Generic: Repo Health / Scripts governance (push) Has been cancelled
Generic: Repo Health / Repository health (push) Has been cancelled
Generic: Repo Health / Report Issues (push) Has been cancelled
Generic: Repo Health / Site Health (push) Has been cancelled
Generic: Repo Health / Access control (push) Has been cancelled
Platform: moko-platform CI / Gate 1: Code Quality (push) Has been cancelled
# Conflicts: # cli/manifest_licensing.php
539 lines
16 KiB
Bash
539 lines
16 KiB
Bash
#!/bin/bash
|
|
# SSH Manager CLI - Simple and powerful SSH server management
|
|
|
|
set -e
|
|
|
|
# Script directory - resolve symlinks if necessary
|
|
if [ -L "$0" ]; then
|
|
# Script is a symlink, resolve it
|
|
SCRIPT_PATH="$(readlink -f "$0" 2>/dev/null || readlink "$0")"
|
|
else
|
|
SCRIPT_PATH="$0"
|
|
fi
|
|
SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
|
|
# Source libraries
|
|
source "$SCRIPT_DIR/lib/colors.sh"
|
|
source "$SCRIPT_DIR/lib/config.sh"
|
|
source "$SCRIPT_DIR/lib/menu.sh"
|
|
|
|
# Source command modules
|
|
source "$SCRIPT_DIR/commands/server.sh"
|
|
source "$SCRIPT_DIR/commands/tools.sh"
|
|
|
|
# Version
|
|
VERSION="3.1.0"
|
|
|
|
# Show version
|
|
show_version() {
|
|
echo "SSH Manager CLI v$VERSION"
|
|
echo "Simple and powerful SSH server management"
|
|
}
|
|
|
|
# Show help
|
|
show_help() {
|
|
cat <<EOF
|
|
${BOLD}SSH Manager CLI${NC} - Simple and powerful SSH server management
|
|
|
|
${BOLD}USAGE:${NC}
|
|
ssh-manager # Interactive mode (menu)
|
|
ssh-manager -i # Interactive mode (menu)
|
|
ssh-manager <command> # Direct command mode
|
|
|
|
${BOLD}COMMANDS:${NC}
|
|
${CYAN}server${NC} Server management
|
|
add Add a new server
|
|
list List all servers
|
|
test Test server connection
|
|
remove Remove a server
|
|
edit Edit server configuration
|
|
show Show server details
|
|
|
|
${CYAN}sync${NC} File synchronization (rsync)
|
|
push Push files to server
|
|
pull Pull files from server
|
|
|
|
${CYAN}tunnel${NC} SSH tunnel management
|
|
create Create a new tunnel
|
|
list List active tunnels
|
|
close Close a tunnel
|
|
|
|
${CYAN}monitor${NC} System monitoring
|
|
cpu Monitor CPU usage
|
|
memory Monitor memory usage
|
|
disk Monitor disk usage
|
|
network Monitor network
|
|
|
|
${CYAN}session${NC} SSH session management
|
|
start Start interactive session
|
|
list List active sessions
|
|
close Close a session
|
|
|
|
${CYAN}exec${NC} Execute commands
|
|
run Run command on server
|
|
group Run on server group
|
|
|
|
${CYAN}config${NC} Configuration
|
|
edit Edit configuration
|
|
show Show configuration
|
|
init Initialize configuration
|
|
|
|
${CYAN}tools${NC} Tool activation/deactivation
|
|
list Show all tools and their status
|
|
configure Interactive configuration wizard
|
|
enable Enable a tool group
|
|
disable Disable a tool group
|
|
reset Reset to default (all tools enabled)
|
|
export Export Claude Code auto-approval config
|
|
|
|
${BOLD}OPTIONS:${NC}
|
|
-h, --help Show this help message
|
|
-v, --version Show version
|
|
-q, --quiet Quiet mode
|
|
-d, --debug Debug mode
|
|
|
|
${BOLD}EXAMPLES:${NC}
|
|
# Add a new server
|
|
ssh-manager server add
|
|
|
|
# List all servers
|
|
ssh-manager server list
|
|
|
|
# Test connection to prod1
|
|
ssh-manager server test prod1
|
|
|
|
# Sync files to server
|
|
ssh-manager sync push prod1 ./app /var/www/app
|
|
|
|
# Create SSH tunnel
|
|
ssh-manager tunnel create prod1 local 3307:localhost:3306
|
|
|
|
# Monitor server
|
|
ssh-manager monitor prod1 cpu
|
|
|
|
${BOLD}CONFIGURATION:${NC}
|
|
Config directory: ${SSH_MANAGER_HOME:-~/.ssh-manager}
|
|
Server config: ${SSH_MANAGER_ENV:-.env}
|
|
|
|
${BOLD}DOCUMENTATION:${NC}
|
|
https://github.com/bvisible/mcp-ssh-manager
|
|
|
|
EOF
|
|
}
|
|
|
|
# Execute command on server
|
|
cmd_exec() {
|
|
local server="$1"
|
|
shift
|
|
local command="$@"
|
|
|
|
if [ -z "$server" ] || [ -z "$command" ]; then
|
|
print_error "Usage: ssh-manager exec <server> <command>"
|
|
return 1
|
|
fi
|
|
|
|
local host=$(get_server_config "$server" "HOST")
|
|
local user=$(get_server_config "$server" "USER")
|
|
local port=$(get_server_config "$server" "PORT")
|
|
local keypath=$(get_server_config "$server" "KEYPATH")
|
|
|
|
port=${port:-22}
|
|
|
|
if [ -z "$host" ] || [ -z "$user" ]; then
|
|
print_error "Server '$server' not found"
|
|
return 1
|
|
fi
|
|
|
|
local ssh_opts="-p $port"
|
|
if [ -n "$keypath" ]; then
|
|
ssh_opts="$ssh_opts -i $keypath"
|
|
fi
|
|
|
|
print_info "Executing on $server: $command"
|
|
ssh $ssh_opts "$user@$host" "$command"
|
|
}
|
|
|
|
# Sync files using rsync
|
|
cmd_sync() {
|
|
local direction="$1"
|
|
local server="$2"
|
|
local source="$3"
|
|
local dest="$4"
|
|
|
|
if [ -z "$direction" ] || [ -z "$server" ] || [ -z "$source" ] || [ -z "$dest" ]; then
|
|
print_error "Usage: ssh-manager sync <push|pull> <server> <source> <destination>"
|
|
return 1
|
|
fi
|
|
|
|
# rsync is only required at this point — fail with a clear message
|
|
# rather than blocking the whole CLI at startup.
|
|
require_command rsync "ssh-manager sync" || return 1
|
|
|
|
local host=$(get_server_config "$server" "HOST")
|
|
local user=$(get_server_config "$server" "USER")
|
|
local port=$(get_server_config "$server" "PORT")
|
|
local keypath=$(get_server_config "$server" "KEYPATH")
|
|
|
|
port=${port:-22}
|
|
|
|
if [ -z "$host" ] || [ -z "$user" ]; then
|
|
print_error "Server '$server' not found"
|
|
return 1
|
|
fi
|
|
|
|
local ssh_opts="ssh -p $port"
|
|
if [ -n "$keypath" ]; then
|
|
ssh_opts="$ssh_opts -i $keypath"
|
|
fi
|
|
|
|
local rsync_opts="-avz --progress"
|
|
|
|
case "$direction" in
|
|
push)
|
|
print_info "Pushing $source to $server:$dest"
|
|
rsync $rsync_opts -e "$ssh_opts" "$source" "$user@$host:$dest"
|
|
;;
|
|
pull)
|
|
print_info "Pulling $server:$source to $dest"
|
|
rsync $rsync_opts -e "$ssh_opts" "$user@$host:$source" "$dest"
|
|
;;
|
|
*)
|
|
print_error "Invalid direction: $direction (use push or pull)"
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Quick SSH connection
|
|
cmd_ssh() {
|
|
local server="$1"
|
|
|
|
if [ -z "$server" ]; then
|
|
print_error "Usage: ssh-manager ssh <server>"
|
|
return 1
|
|
fi
|
|
|
|
local host=$(get_server_config "$server" "HOST")
|
|
local user=$(get_server_config "$server" "USER")
|
|
local port=$(get_server_config "$server" "PORT")
|
|
local keypath=$(get_server_config "$server" "KEYPATH")
|
|
|
|
port=${port:-22}
|
|
|
|
if [ -z "$host" ] || [ -z "$user" ]; then
|
|
print_error "Server '$server' not found"
|
|
return 1
|
|
fi
|
|
|
|
local ssh_opts="-p $port"
|
|
if [ -n "$keypath" ]; then
|
|
ssh_opts="$ssh_opts -i $keypath"
|
|
fi
|
|
|
|
print_info "Connecting to $server..."
|
|
ssh $ssh_opts "$user@$host"
|
|
}
|
|
|
|
# Simple tunnel creation
|
|
cmd_tunnel() {
|
|
local action="$1"
|
|
shift
|
|
|
|
case "$action" in
|
|
create)
|
|
local server="$1"
|
|
local type="$2"
|
|
local ports="$3"
|
|
|
|
if [ -z "$server" ] || [ -z "$type" ] || [ -z "$ports" ]; then
|
|
print_error "Usage: ssh-manager tunnel create <server> <local|remote|dynamic> <ports>"
|
|
print_info "Examples:"
|
|
print_info " Local: ssh-manager tunnel create prod1 local 3307:localhost:3306"
|
|
print_info " Remote: ssh-manager tunnel create prod1 remote 8080:localhost:8080"
|
|
print_info " Dynamic: ssh-manager tunnel create prod1 dynamic 1080"
|
|
return 1
|
|
fi
|
|
|
|
local host=$(get_server_config "$server" "HOST")
|
|
local user=$(get_server_config "$server" "USER")
|
|
local port=$(get_server_config "$server" "PORT")
|
|
local keypath=$(get_server_config "$server" "KEYPATH")
|
|
|
|
port=${port:-22}
|
|
|
|
if [ -z "$host" ] || [ -z "$user" ]; then
|
|
print_error "Server '$server' not found"
|
|
return 1
|
|
fi
|
|
|
|
local ssh_opts="-p $port -N -f"
|
|
if [ -n "$keypath" ]; then
|
|
ssh_opts="$ssh_opts -i $keypath"
|
|
fi
|
|
|
|
case "$type" in
|
|
local)
|
|
print_info "Creating local tunnel: $ports"
|
|
ssh $ssh_opts -L "$ports" "$user@$host"
|
|
;;
|
|
remote)
|
|
print_info "Creating remote tunnel: $ports"
|
|
ssh $ssh_opts -R "$ports" "$user@$host"
|
|
;;
|
|
dynamic)
|
|
print_info "Creating SOCKS proxy on port $ports"
|
|
ssh $ssh_opts -D "$ports" "$user@$host"
|
|
;;
|
|
*)
|
|
print_error "Invalid tunnel type: $type"
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
if [ $? -eq 0 ]; then
|
|
print_success "Tunnel created successfully"
|
|
else
|
|
print_error "Failed to create tunnel"
|
|
return 1
|
|
fi
|
|
;;
|
|
|
|
list)
|
|
print_header "Active SSH Tunnels"
|
|
ps aux | grep -E "ssh.*(-L|-R|-D)" | grep -v grep || print_info "No active tunnels"
|
|
;;
|
|
|
|
*)
|
|
print_error "Unknown tunnel command: $action"
|
|
echo "Available commands: create, list"
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Main command handler
|
|
main() {
|
|
# Check for help/version flags
|
|
case "$1" in
|
|
-h|--help|help)
|
|
show_help
|
|
exit 0
|
|
;;
|
|
-v|--version|version)
|
|
show_version
|
|
exit 0
|
|
;;
|
|
esac
|
|
|
|
# Initialize configuration
|
|
init_config
|
|
|
|
# Check dependencies
|
|
if ! check_dependencies; then
|
|
exit 1
|
|
fi
|
|
|
|
# Get command
|
|
local command="$1"
|
|
shift || true
|
|
|
|
# Handle commands
|
|
case "$command" in
|
|
server)
|
|
cmd_server "$@"
|
|
;;
|
|
exec)
|
|
cmd_exec "$@"
|
|
;;
|
|
sync)
|
|
cmd_sync "$@"
|
|
;;
|
|
ssh|connect)
|
|
cmd_ssh "$@"
|
|
;;
|
|
tunnel)
|
|
cmd_tunnel "$@"
|
|
;;
|
|
tools)
|
|
cmd_tools "$@"
|
|
;;
|
|
config)
|
|
case "$1" in
|
|
edit)
|
|
${EDITOR:-nano} "$SSH_MANAGER_CONFIG"
|
|
;;
|
|
show)
|
|
cat "$SSH_MANAGER_CONFIG"
|
|
;;
|
|
init)
|
|
init_config
|
|
;;
|
|
*)
|
|
print_error "Unknown config command: $1"
|
|
;;
|
|
esac
|
|
;;
|
|
""|-i|--interactive|menu)
|
|
# Interactive mode
|
|
interactive_mode
|
|
;;
|
|
*)
|
|
print_error "Unknown command: $command"
|
|
echo "Run 'ssh-manager --help' for usage information"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Interactive mode with menu
|
|
interactive_mode() {
|
|
# Initialize configuration
|
|
init_config
|
|
|
|
# Check dependencies
|
|
if ! check_dependencies; then
|
|
exit 1
|
|
fi
|
|
|
|
while true; do
|
|
show_main_menu
|
|
read choice
|
|
|
|
case "$choice" in
|
|
1)
|
|
# Server Management submenu
|
|
while true; do
|
|
show_server_menu
|
|
read server_choice
|
|
|
|
case "$server_choice" in
|
|
1)
|
|
wizard_add_server
|
|
;;
|
|
2)
|
|
cmd_server_list
|
|
echo
|
|
read -p "Press Enter to continue..."
|
|
;;
|
|
3)
|
|
if select_server_menu "Test Connection"; then
|
|
test_ssh_connection "$selected_server"
|
|
echo
|
|
read -p "Press Enter to continue..."
|
|
fi
|
|
;;
|
|
4)
|
|
if select_server_menu "Show Server Details"; then
|
|
cmd_server_show "$selected_server"
|
|
echo
|
|
read -p "Press Enter to continue..."
|
|
fi
|
|
;;
|
|
5)
|
|
wizard_edit_server
|
|
echo
|
|
read -p "Press Enter to continue..."
|
|
;;
|
|
6)
|
|
if select_server_menu "Remove Server"; then
|
|
echo
|
|
if prompt_yes_no "Remove server '$selected_server'?" "n"; then
|
|
remove_server_from_env "$selected_server"
|
|
fi
|
|
echo
|
|
read -p "Press Enter to continue..."
|
|
fi
|
|
;;
|
|
7)
|
|
cmd_server_edit_file
|
|
echo
|
|
read -p "Press Enter to continue..."
|
|
;;
|
|
0)
|
|
break
|
|
;;
|
|
esac
|
|
done
|
|
;;
|
|
2)
|
|
# Quick Connect
|
|
if select_server_menu "Quick Connect"; then
|
|
print_info "Connecting to $selected_server..."
|
|
cmd_ssh "$selected_server"
|
|
fi
|
|
;;
|
|
3)
|
|
# File Sync
|
|
show_sync_menu
|
|
;;
|
|
4)
|
|
# SSH Tunnels
|
|
wizard_create_tunnel
|
|
;;
|
|
5)
|
|
# System Monitoring
|
|
if select_server_menu "System Monitoring"; then
|
|
echo
|
|
print_subheader "Monitor Type"
|
|
echo " 1) Overview"
|
|
echo " 2) CPU"
|
|
echo " 3) Memory"
|
|
echo " 4) Disk"
|
|
echo " 5) Network"
|
|
echo
|
|
read -p "Choose [1-5]: " monitor_type
|
|
|
|
case "$monitor_type" in
|
|
1) cmd_exec "$selected_server" "uptime && free -h && df -h" ;;
|
|
2) cmd_exec "$selected_server" "top -bn1 | head -20" ;;
|
|
3) cmd_exec "$selected_server" "free -h && ps aux --sort=-%mem | head -10" ;;
|
|
4) cmd_exec "$selected_server" "df -h && du -sh /* 2>/dev/null | sort -h | tail -10" ;;
|
|
5) cmd_exec "$selected_server" "netstat -tulpn 2>/dev/null | grep LISTEN" ;;
|
|
esac
|
|
echo
|
|
read -p "Press Enter to continue..."
|
|
fi
|
|
;;
|
|
6)
|
|
# Execute Commands
|
|
if select_server_menu "Execute Command"; then
|
|
echo
|
|
local command
|
|
prompt_input "Command to execute" "uptime" "command"
|
|
echo
|
|
cmd_exec "$selected_server" "$command"
|
|
echo
|
|
read -p "Press Enter to continue..."
|
|
fi
|
|
;;
|
|
7)
|
|
# Configuration
|
|
clear
|
|
print_header "Configuration"
|
|
echo " 1) Edit CLI config"
|
|
echo " 2) Show CLI config"
|
|
echo " 3) Edit server config (.env)"
|
|
echo " 0) Back"
|
|
echo
|
|
read -p "Choose [0-3]: " config_choice
|
|
|
|
case "$config_choice" in
|
|
1) ${EDITOR:-nano} "$SSH_MANAGER_CONFIG" ;;
|
|
2) cat "$SSH_MANAGER_CONFIG"; read -p "Press Enter..." ;;
|
|
3) cmd_server_edit ;;
|
|
esac
|
|
;;
|
|
8)
|
|
# Help
|
|
show_help | less
|
|
;;
|
|
0|q|Q)
|
|
print_info "Goodbye!"
|
|
exit 0
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# Run main function
|
|
main "$@" |