Skip to main content
Glama
config.sh10.8 kB
#!/bin/bash # Configuration management library for ssh-manager CLI # Configuration paths export SSH_MANAGER_HOME="${SSH_MANAGER_HOME:-$HOME/.ssh-manager}" export SSH_MANAGER_CONFIG="$SSH_MANAGER_HOME/config.json" # Resolve .env path - handle both direct and symlinked execution if [ -z "$SSH_MANAGER_ENV" ]; then if [ -n "$SCRIPT_DIR" ]; then # Called from main ssh-manager script SSH_MANAGER_ENV="$(dirname "$SCRIPT_DIR")/.env" else # Called directly - need to resolve path ourselves if [ -L "$0" ]; then REAL_PATH="$(readlink -f "$0" 2>/dev/null || readlink "$0")" else REAL_PATH="$0" fi REAL_DIR="$(cd "$(dirname "$REAL_PATH")" && pwd)" SSH_MANAGER_ENV="$(dirname "$(dirname "$REAL_DIR")")/.env" fi export SSH_MANAGER_ENV fi export SSH_MANAGER_ALIASES="$SSH_MANAGER_HOME/aliases.json" # Ensure config directory exists init_config() { if [ ! -d "$SSH_MANAGER_HOME" ]; then mkdir -p "$SSH_MANAGER_HOME" print_info "Created config directory: $SSH_MANAGER_HOME" fi # Create default config if not exists if [ ! -f "$SSH_MANAGER_CONFIG" ]; then cat > "$SSH_MANAGER_CONFIG" <<EOF { "default_editor": "${EDITOR:-nano}", "default_shell": "${SHELL:-/bin/bash}", "history_file": "$SSH_MANAGER_HOME/history", "log_level": "info", "color_output": true } EOF print_info "Created default config: $SSH_MANAGER_CONFIG" fi } # Load configuration value get_config() { local key="$1" local default="$2" if [ -f "$SSH_MANAGER_CONFIG" ] && command -v jq >/dev/null 2>&1; then local value=$(jq -r ".$key // null" "$SSH_MANAGER_CONFIG" 2>/dev/null) if [ "$value" != "null" ]; then echo "$value" else echo "$default" fi else echo "$default" fi } # Set configuration value set_config() { local key="$1" local value="$2" if command -v jq >/dev/null 2>&1; then local temp=$(mktemp) jq ".$key = \"$value\"" "$SSH_MANAGER_CONFIG" > "$temp" && mv "$temp" "$SSH_MANAGER_CONFIG" print_success "Updated config: $key = $value" else print_error "jq is required for config management" return 1 fi } # Load servers from .env file load_servers() { local servers=() if [ ! -f "$SSH_MANAGER_ENV" ]; then return 1 fi # Parse .env file for server definitions while IFS= read -r line; do if [[ "$line" =~ ^SSH_SERVER_(.+)_HOST= ]]; then local server_name="${BASH_REMATCH[1]}" # Convert to lowercase server_name=$(echo "$server_name" | tr '[:upper:]' '[:lower:]') servers+=("$server_name") fi done < "$SSH_MANAGER_ENV" # Remove duplicates printf '%s\n' "${servers[@]}" | sort -u } # Get server configuration get_server_config() { local server="$1" local field="$2" local server_upper="$(echo "$server" | tr '[:lower:]' '[:upper:]')" if [ ! -f "$SSH_MANAGER_ENV" ]; then return 1 fi local field_upper="$(echo "$field" | tr '[:lower:]' '[:upper:]')" local key="SSH_SERVER_${server_upper}_${field_upper}" # Read value using IFS to preserve all special characters including quotes local value="" while IFS="=" read -r k v; do if [[ "$k" == "$key" ]]; then value="$v" break fi done < <(grep "^${key}=" "$SSH_MANAGER_ENV" 2>/dev/null) # Return error if no value found if [ -z "$value" ]; then return 1 fi # Only remove surrounding quotes if they exist, preserve quotes within the value if [[ "$value" =~ ^\"(.*)\"$ ]]; then printf '%s' "${BASH_REMATCH[1]}" else printf '%s' "$value" fi } # Add server to .env add_server_to_env() { local name="$1" local host="$2" local user="$3" local auth_type="$4" local auth_value="$5" local port="${6:-22}" local description="${7:-}" local name_upper="$(echo "$name" | tr '[:lower:]' '[:upper:]')" # Check if server already exists if grep -q "^SSH_SERVER_${name_upper}_HOST=" "$SSH_MANAGER_ENV" 2>/dev/null; then print_error "Server '$name' already exists" return 1 fi # Backup .env file cp "$SSH_MANAGER_ENV" "$SSH_MANAGER_ENV.bak" # Add server configuration { echo "" echo "# Server: $name" echo "SSH_SERVER_${name_upper}_HOST=$host" echo "SSH_SERVER_${name_upper}_USER=$user" echo "SSH_SERVER_${name_upper}_PORT=$port" if [ "$auth_type" = "password" ]; then echo "SSH_SERVER_${name_upper}_PASSWORD=$auth_value" else echo "SSH_SERVER_${name_upper}_KEYPATH=$auth_value" fi if [ -n "$description" ]; then echo "SSH_SERVER_${name_upper}_DESCRIPTION=\"$description\"" fi } >> "$SSH_MANAGER_ENV" print_success "Server '$name' added successfully" } # Update server in .env update_server_in_env() { local name="$1" local host="$2" local user="$3" local auth_type="$4" local auth_value="$5" local port="${6:-22}" local description="${7:-}" local default_dir="${8:-}" local name_upper="$(echo "$name" | tr '[:lower:]' '[:upper:]')" # Check if server exists if ! grep -q "^SSH_SERVER_${name_upper}_HOST=" "$SSH_MANAGER_ENV" 2>/dev/null; then print_error "Server '$name' not found" return 1 fi # Backup .env file cp "$SSH_MANAGER_ENV" "$SSH_MANAGER_ENV.bak" # Remove old server configuration (all lines including comments and old auth methods) local temp=$(mktemp) # Remove server config lines and the comment line before them sed "/^# Server: $name$/d; /^SSH_SERVER_${name_upper}_/d" "$SSH_MANAGER_ENV" > "$temp" # Find position to insert (after other servers or at end) # Add updated server configuration { cat "$temp" echo "" echo "# Server: $name" echo "SSH_SERVER_${name_upper}_HOST=$host" echo "SSH_SERVER_${name_upper}_USER=$user" echo "SSH_SERVER_${name_upper}_PORT=$port" if [ "$auth_type" = "password" ]; then echo "SSH_SERVER_${name_upper}_PASSWORD=$auth_value" else echo "SSH_SERVER_${name_upper}_KEYPATH=$auth_value" fi if [ -n "$description" ]; then echo "SSH_SERVER_${name_upper}_DESCRIPTION=\"$description\"" fi if [ -n "$default_dir" ]; then echo "SSH_SERVER_${name_upper}_DEFAULT_DIR=$default_dir" fi } > "$SSH_MANAGER_ENV" rm -f "$temp" print_success "Server '$name' updated successfully" } # Remove server from .env remove_server_from_env() { local name="$1" local name_upper="$(echo "$name" | tr '[:lower:]' '[:upper:]')" if ! grep -q "^SSH_SERVER_${name_upper}_HOST=" "$SSH_MANAGER_ENV" 2>/dev/null; then print_error "Server '$name' not found" return 1 fi # Backup .env file cp "$SSH_MANAGER_ENV" "$SSH_MANAGER_ENV.bak" # Remove all lines for this server local temp=$(mktemp) grep -v "^SSH_SERVER_${name_upper}_" "$SSH_MANAGER_ENV" > "$temp" mv "$temp" "$SSH_MANAGER_ENV" print_success "Server '$name' removed successfully" } # Test SSH connection test_ssh_connection() { local server="$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") local password=$(get_server_config "$server" "PASSWORD") port=${port:-22} if [ -z "$host" ] || [ -z "$user" ]; then print_error "Server '$server' not found or incomplete configuration" return 1 fi print_info "Testing connection to $server ($user@$host:$port)..." local ssh_opts="-o ConnectTimeout=10 -o StrictHostKeyChecking=no" local ssh_output=$(mktemp) local ssh_status if [ -n "$keypath" ]; then ssh_opts="$ssh_opts -i $keypath" fi if [ -n "$password" ]; then # Use sshpass if available if command -v sshpass >/dev/null 2>&1; then sshpass -p "$password" ssh $ssh_opts -p "$port" "$user@$host" "echo 'Connection successful'" > "$ssh_output" 2>&1 ssh_status=$? else print_warning "sshpass not installed, cannot test password authentication" rm -f "$ssh_output" return 1 fi else ssh $ssh_opts -p "$port" "$user@$host" "echo 'Connection successful'" > "$ssh_output" 2>&1 ssh_status=$? fi if [ $ssh_status -eq 0 ]; then print_success "Connection successful" rm -f "$ssh_output" return 0 else print_error "Connection failed" # Show error details if SSH_MANAGER_DEBUG is set if [ -n "$SSH_MANAGER_DEBUG" ]; then print_warning "Debug output:" cat "$ssh_output" | sed 's/^/ /' else print_info "Set SSH_MANAGER_DEBUG=1 to see detailed error output" fi rm -f "$ssh_output" return 1 fi } # Validate server name validate_server_name() { local name="$1" # Check if name is empty if [ -z "$name" ]; then print_error "Server name cannot be empty" return 1 fi # Check for invalid characters if ! [[ "$name" =~ ^[a-zA-Z0-9_-]+$ ]]; then print_error "Server name can only contain letters, numbers, underscore and hyphen" return 1 fi # Check if name starts with a letter if ! [[ "$name" =~ ^[a-zA-Z] ]]; then print_error "Server name must start with a letter" return 1 fi return 0 } # Check dependencies check_dependencies() { local missing=() # Check for required commands for cmd in ssh rsync; do if ! command -v "$cmd" >/dev/null 2>&1; then missing+=("$cmd") fi done # Check for optional but recommended commands local optional=() for cmd in jq sshpass; do if ! command -v "$cmd" >/dev/null 2>&1; then optional+=("$cmd") fi done if [ ${#missing[@]} -gt 0 ]; then print_error "Missing required dependencies: ${missing[*]}" print_info "Please install them and try again" return 1 fi if [ ${#optional[@]} -gt 0 ]; then print_warning "Missing optional dependencies: ${optional[*]}" print_info "Some features may not work without them" fi return 0 }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bvisible/mcp-ssh-manager'

If you have feedback or need assistance with the MCP directory API, please join our Discord server