feat: add ssh menu script with sample YAML config
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
config/
|
||||||
Executable
+162
@@ -0,0 +1,162 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
CONFIG_DIR="$SCRIPT_DIR/config"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
Usage: sshm [--config-dir DIR]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help Show this help message
|
||||||
|
--config-dir DIR Use a custom config directory
|
||||||
|
|
||||||
|
The config directory must contain:
|
||||||
|
- global.yaml
|
||||||
|
- hosts/*.yaml
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args() {
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--config-dir)
|
||||||
|
if [[ $# -lt 2 ]]; then
|
||||||
|
printf 'Error: --config-dir requires a value.\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
CONFIG_DIR="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--help|-h)
|
||||||
|
usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf 'Error: unknown argument: %s\n' "$1" >&2
|
||||||
|
usage >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
parse_args "$@"
|
||||||
|
|
||||||
|
dependency_check() {
|
||||||
|
if ! command -v yq >/dev/null 2>&1; then
|
||||||
|
printf 'Error: yq is required but not installed.\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! command -v jq >/dev/null 2>&1; then
|
||||||
|
printf 'Error: jq is required but not installed.\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! command -v ssh >/dev/null 2>&1; then
|
||||||
|
printf 'Error: ssh is required but not installed.\n' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
#if command -v fzf >/dev/null 2>&1; then
|
||||||
|
# printf 'Error: fzf is required but not installed.\n' >&2
|
||||||
|
# exit 1
|
||||||
|
#fi
|
||||||
|
}
|
||||||
|
dependency_check
|
||||||
|
|
||||||
|
GLOBAL_CONFIG="$CONFIG_DIR/global.yaml"
|
||||||
|
HOSTS_DIR="$CONFIG_DIR/hosts"
|
||||||
|
DEFAULT_SSH_USER="root"
|
||||||
|
DEFAULT_SSH_PORT="22"
|
||||||
|
DEFAULT_SSH_OPTIONS=""
|
||||||
|
SSH_JUMP_HOSTS={}
|
||||||
|
SERVERS=""
|
||||||
|
|
||||||
|
load_config() {
|
||||||
|
local GLOBAL_CONFIG_CONTENT
|
||||||
|
GLOBAL_CONFIG_CONTENT="$(<"$GLOBAL_CONFIG")"
|
||||||
|
DEFAULT_SSH_USER=$(yq -r '.ssh.default_user // "'$DEFAULT_SSH_USER'"' <<<"$GLOBAL_CONFIG_CONTENT")
|
||||||
|
DEFAULT_SSH_PORT=$(yq -r '.ssh.default_port // "'$DEFAULT_SSH_PORT'"' <<<"$GLOBAL_CONFIG_CONTENT")
|
||||||
|
DEFAULT_SSH_OPTIONS=$(yq -r '.ssh.default_options // "'"$DEFAULT_SSH_OPTIONS"'"' <<<"$GLOBAL_CONFIG_CONTENT")
|
||||||
|
SSH_JUMP_HOSTS=$(yq -r '.ssh.jump_hosts // {}' <<<"$GLOBAL_CONFIG_CONTENT")
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
for file in "$HOSTS_DIR"/*.yaml; do
|
||||||
|
local FILE_CONTENT GROUP_NAME GROUP_SERVERS INDEX
|
||||||
|
FILE_CONTENT="$(<"$file")"
|
||||||
|
GROUP_NAME=$(basename "$file")
|
||||||
|
GROUP_NAME=${GROUP_NAME%.*}
|
||||||
|
GROUP_NAME=$(yq -r '.group // "'"$GROUP_NAME"'"' <<<"$FILE_CONTENT")
|
||||||
|
GROUP_SERVERS=$(yq -r '.servers // []' <<<"$FILE_CONTENT")
|
||||||
|
#echo "$GROUP_NAME"
|
||||||
|
INDEX=0
|
||||||
|
|
||||||
|
for ((i=0; i<$(jq -r '. | length' <<<"$GROUP_SERVERS"); i++)); do
|
||||||
|
local SSH_SERVER_NAME SSH_SERVER_ALIASES ALIASES SSH_SERVER_HOST SSH_SERVER_PORT SSH_SERVER_USER
|
||||||
|
SSH_SERVER_NAME=$(jq -r '.'"[$i]"'.name // ""' <<<"$GROUP_SERVERS")
|
||||||
|
SSH_SERVER_ALIASES=$(jq -r '.'"[$i]"'.aliases // ""' <<<"$GROUP_SERVERS")
|
||||||
|
SSH_SERVER_HOST=$(jq -r '.'"[$i]"'.host // ""' <<<"$GROUP_SERVERS")
|
||||||
|
SSH_SERVER_PORT=$(jq -r '.'"[$i]"'.port // "'"$DEFAULT_SSH_PORT"'"' <<<"$GROUP_SERVERS")
|
||||||
|
SSH_SERVER_USER=$(jq -r '.'"[$i]"'.port // "'"$DEFAULT_SSH_USER"'"' <<<"$GROUP_SERVERS")
|
||||||
|
#SSH_JUMP_HOST=$(jq -r '.'"[$i]"'.jump_host // ""' <<<"$GROUP_SERVERS")
|
||||||
|
#if [ "$SSH_JUMP_HOST" != "" ]; then
|
||||||
|
# SSH_JUMP_HOST=$(jq -r '.yverdon // ""' <<<"$SSH_JUMP_HOSTS")
|
||||||
|
#fi
|
||||||
|
#SSH_OPTIONS=$(jq -r '.'"[$i]"'.options // ""' <<<"$GROUP_SERVERS")
|
||||||
|
|
||||||
|
if [ "$SSH_SERVER_ALIASES" != "" ]; then
|
||||||
|
ALIASES="("$(echo "$SSH_SERVER_ALIASES" | jq -r 'join(", ")')")"
|
||||||
|
#echo "$SSH_SERVER_NAME $ALIASES"
|
||||||
|
#else
|
||||||
|
# echo "$SSH_SERVER_NAME"
|
||||||
|
fi
|
||||||
|
#if [ "$SSH_JUMP_HOST" == "" ]; then
|
||||||
|
# echo "$SSH_SERVER_USER@$SSH_SERVER_HOST:$SSH_SERVER_PORT"
|
||||||
|
#else
|
||||||
|
# echo "$SSH_SERVER_USER@$SSH_SERVER_HOST:$SSH_SERVER_PORT via $SSH_JUMP_HOST"
|
||||||
|
#fi
|
||||||
|
#echo "$SSH_OPTIONS"
|
||||||
|
#echo '{ "name": "'"$SSH_SERVER_NAME"'" }' | jq
|
||||||
|
if [ "$SERVERS" != "" ]; then
|
||||||
|
SERVERS+="\n"
|
||||||
|
fi
|
||||||
|
SERVERS+="${GROUP_NAME} | ${INDEX} | ${SSH_SERVER_HOST} | ${SSH_SERVER_NAME} ${ALIASES} | ${SSH_SERVER_USER} | ${SSH_SERVER_PORT}"
|
||||||
|
INDEX=$((INDEX+1))
|
||||||
|
done
|
||||||
|
|
||||||
|
done
|
||||||
|
shopt -u nullglob
|
||||||
|
|
||||||
|
}
|
||||||
|
popup_menu() {
|
||||||
|
local SERVER
|
||||||
|
SERVER=$(echo -e "${SERVERS}" | column -t -s "|" -o "|" | fzf -e --tac --with-nth=1,3,4,5,6 --delimiter="|")
|
||||||
|
local GROUP_NAME HOST_INDEX
|
||||||
|
GROUP_NAME=$(echo "$SERVER" | awk -F '|' '{print $1}' | xargs)
|
||||||
|
HOST_INDEX=$(echo "$SERVER" | awk -F '|' '{print $2}' | xargs)
|
||||||
|
ssh_connect "$GROUP_NAME" "$HOST_INDEX"
|
||||||
|
}
|
||||||
|
ssh_connect() {
|
||||||
|
local SERVER SSH_SERVER_USER SSH_SERVER_HOST SSH_SERVER_PORT SSH_SERVER_OPTIONS SSH_JUMP_HOST
|
||||||
|
SERVER=$(cat "$HOSTS_DIR/$1.yaml" | yq -r '.servers'"[$2]")
|
||||||
|
SSH_SERVER_USER=$(jq -r '.user // "'"$DEFAULT_SSH_USER"'"' <<<"$SERVER")
|
||||||
|
SSH_SERVER_HOST=$(jq -r '.host // ""' <<<"$SERVER")
|
||||||
|
SSH_SERVER_PORT=$(jq -r '.port // "'"$DEFAULT_SSH_PORT"'"' <<<"$SERVER")
|
||||||
|
|
||||||
|
SSH_SERVER_OPTIONS="-p $SSH_SERVER_PORT"
|
||||||
|
SSH_JUMP_HOST=$(jq -r '.jump_host // ""' <<<"$SERVER")
|
||||||
|
if [ "$SSH_JUMP_HOST" != "" ]; then
|
||||||
|
SSH_JUMP_HOST=$(jq -r '.'"$SSH_JUMP_HOST"' // ""' <<<"${SSH_JUMP_HOSTS}")
|
||||||
|
SSH_JUMP_HOST="-t $SSH_JUMP_HOST ssh -p $SSH_SERVER_PORT"
|
||||||
|
SSH_SERVER_OPTIONS=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "ssh ${SSH_SERVER_OPTIONS} ${SSH_JUMP_HOST} ${SSH_SERVER_USER}@${SSH_SERVER_HOST}"
|
||||||
|
ssh ${SSH_SERVER_OPTIONS} ${SSH_JUMP_HOST} "${SSH_SERVER_USER}"@"${SSH_SERVER_HOST}"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
load_config
|
||||||
|
popup_menu
|
||||||
|
}
|
||||||
|
|
||||||
|
main
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
ssh:
|
||||||
|
default_user: root
|
||||||
|
default_port: 22
|
||||||
|
default_options: ""
|
||||||
|
jump_hosts:
|
||||||
|
office: "user@192.168.10.11"
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
group: dev
|
||||||
|
servers:
|
||||||
|
- name: api-1
|
||||||
|
aliases:
|
||||||
|
- api
|
||||||
|
- backend
|
||||||
|
host: 192.168.10.11
|
||||||
|
user: dev
|
||||||
|
port: 2222
|
||||||
|
|
||||||
|
- name: web-1
|
||||||
|
aliases:
|
||||||
|
- frontend
|
||||||
|
- ui
|
||||||
|
host: 192.168.10.12
|
||||||
|
user: dev
|
||||||
|
port: 22
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
group: prod
|
||||||
|
servers:
|
||||||
|
- name: web-1
|
||||||
|
aliases:
|
||||||
|
- frontend
|
||||||
|
- web
|
||||||
|
host: web-1.prod.internal
|
||||||
|
jump_host: office
|
||||||
|
|
||||||
|
- name: db-1
|
||||||
|
aliases:
|
||||||
|
- database
|
||||||
|
- sql
|
||||||
|
host: 10.0.0.20
|
||||||
|
jump_host: office
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
group: staging
|
||||||
|
servers:
|
||||||
|
- name: app-1
|
||||||
|
aliases:
|
||||||
|
- app
|
||||||
|
- application
|
||||||
|
host: staging-app.example.com
|
||||||
|
user: ubuntu
|
||||||
|
port: 22
|
||||||
|
ssh_options: ""
|
||||||
|
|
||||||
|
- name: worker-1
|
||||||
|
aliases:
|
||||||
|
- worker
|
||||||
|
host: 10.20.0.15
|
||||||
|
user: ubuntu
|
||||||
|
port: 22
|
||||||
Reference in New Issue
Block a user