diff --git a/.memory/project.md b/.memory/project.md index 3372cf2..1d5489e 100644 --- a/.memory/project.md +++ b/.memory/project.md @@ -8,6 +8,7 @@ - Sample config is stored in `sample-config/` and mirrors current script behavior. - Documentation language: English. - Current task focus: keep README and memory aligned with the working script and sample configuration. +- Sample host files currently use numbered names: `01_prod.yaml`, `02_staging.yaml`, `03_dev.yaml`. - Known follow-up improvements: - Group naming should avoid duplicating the file name and the YAML value. - Each group should have default values. diff --git a/README.md b/README.md index a3620f8..84f11d1 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ A Bash SSH target picker built around `fzf` and YAML configuration. ## What it does - Lists SSH targets from grouped YAML files +- Uses the `group` value from each YAML file as the displayed group name +- Allows the YAML file name to differ from the group name - Supports global defaults for user, port, and jump hosts - Supports per-host overrides - Can also browse entries from `~/.ssh/known_hosts` @@ -49,10 +51,10 @@ ssh: ``` -### `hosts/dev.yaml` +### `hosts/01_prod.yaml` ```yaml -group: dev +group: prod servers: - name: api-1 aliases: @@ -71,10 +73,10 @@ servers: port: 22 ``` -### `hosts/prod.yaml` +### `hosts/03_dev.yaml` ```yaml -group: prod +group: dev servers: - name: web-1 aliases: @@ -84,6 +86,10 @@ servers: jump_host: office ``` +The file name does not need to match the `group` value. The script reads the `group` from the YAML content and uses the file path internally to load the selected host. + +The sample configuration now uses numbered file names such as `01_prod.yaml`, `02_staging.yaml`, and `03_dev.yaml`. + Each host entry can define: - `name` @@ -104,6 +110,8 @@ A complete sample configuration is available in `sample-config/`. - If a host does not define a user or port, global defaults are used. - `default_options` is present in the config but not consumed by the current script. - The sample config includes `ssh_options` in one file, but the current script does not consume it yet. +- Sample host examples are stored as `sample-config/hosts/01_prod.yaml`, `02_staging.yaml`, and `03_dev.yaml`. +- The `group` key is required for each host config file; the file name is only an internal storage detail. - When `-k` is used, entries from `known_hosts` are shown with the selected user or `root` by default. - `known_hosts` entries use port `22`. - The script uses strict Bash mode (`set -euo pipefail`). diff --git a/mtm-ssh-menu b/mtm-ssh-menu index bf44cc0..ad3b348 100755 --- a/mtm-ssh-menu +++ b/mtm-ssh-menu @@ -94,12 +94,13 @@ load_config() { 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_NAME=$(yq -r '.group // empty' <<<"$FILE_CONTENT") + if [ "$GROUP_NAME" = "" ]; then + printf 'Error: missing group name in config file: %s\n' "$file" >&2 + exit 1 + fi GROUP_SERVERS=$(yq -r '.servers // []' <<<"$FILE_CONTENT") 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") @@ -115,10 +116,9 @@ load_config() { if [ "$SERVERS" != "" ]; then SERVERS+="\n" fi - SERVERS+="${GROUP_NAME} | ${INDEX} | ${SSH_SERVER_HOST} | ${SSH_SERVER_NAME} ${ALIASES} | ${SSH_SERVER_USER} | ${SSH_SERVER_PORT}" + SERVERS+="${GROUP_NAME} | ${file} | ${INDEX} | ${SSH_SERVER_HOST} | ${SSH_SERVER_NAME} ${ALIASES} | ${SSH_SERVER_USER} | ${SSH_SERVER_PORT}" INDEX=$((INDEX+1)) done - done shopt -u nullglob } @@ -130,21 +130,22 @@ load_known_hosts() { if [ "$SERVERS" != "" ]; then SERVERS+="\n" fi - SERVERS+="${GROUP_NAME} | ${host} | ${host} | ${host} | ${USE_KNOWN_HOSTS_USER} | 22" + SERVERS+="${GROUP_NAME} | known_hosts | ${host} | ${host} | ${USE_KNOWN_HOSTS_USER} | 22" done } popup_menu() { local SERVER - SERVER=$(echo -e "${SERVERS}" | column -t -s "|" -o "|" | fzf -e --layout=reverse --with-nth=1,3,4,5,6 --delimiter="|") - local GROUP_NAME HOST_INDEX + SERVER=$(echo -e "${SERVERS}" | column -t -s "|" -o "|" | fzf -e --layout=reverse --with-nth=1,4,5,6,7 --delimiter="|") + local GROUP_NAME GROUP_SOURCE 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" + GROUP_SOURCE=$(echo "$SERVER" | awk -F '|' '{print $2}' | xargs) + HOST_INDEX=$(echo "$SERVER" | awk -F '|' '{print $3}' | xargs) + ssh_connect "$GROUP_SOURCE" "$HOST_INDEX" } ssh_connect() { if [[ "$HOST_INDEX" != *"."* ]]; then 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]") + SERVER=$(yq -r '.servers['"$2"']' "$1") 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") diff --git a/sample-config/hosts/prod.yaml b/sample-config/hosts/01_prod.yaml similarity index 100% rename from sample-config/hosts/prod.yaml rename to sample-config/hosts/01_prod.yaml diff --git a/sample-config/hosts/staging.yaml b/sample-config/hosts/02_staging.yaml similarity index 100% rename from sample-config/hosts/staging.yaml rename to sample-config/hosts/02_staging.yaml diff --git a/sample-config/hosts/dev.yaml b/sample-config/hosts/03_dev.yaml similarity index 100% rename from sample-config/hosts/dev.yaml rename to sample-config/hosts/03_dev.yaml