dotfiles/zsh/homelab.zsh
ilia 78f7874055
All checks were successful
CI / skip-ci-check (pull_request) Successful in 19s
CI / secret-scan (pull_request) Successful in 17s
Sync live zsh + Cursor pack for family Macs
Bring .zshrc up to the current machine config (portable paths), ship
homelab/ansible shell helpers, shared Cursor rules/skills, and an
install.sh so Irina can clone and run ./install.sh --ira.
2026-07-26 16:00:43 -04:00

146 lines
4.8 KiB
Bash

# Homelab + ansible shell helpers (sourced from ~/.zshrc when present).
# Requires a checkout at $ANSIBLE_DIR for SSH/secret pickers; Gmail make
# targets for Irina live in personal-scripts (or ansible — see README).
# Ansible repo shortcuts
alias mk='make -C "$ANSIBLE_DIR"'
alias mps='make -C "$PERSONAL_SCRIPTS_DIR"'
alias hping='mk ping'
alias hlist='[[ -f "$ANSIBLE_DIR/docs/guides/host-list.md" ]] && less "$ANSIBLE_DIR/docs/guides/host-list.md"'
_homelab-ansible-inventory() {
local bin="$ANSIBLE_DIR/.venv/bin/ansible-inventory"
if [[ -x "$bin" ]]; then
"$bin" -i "$ANSIBLE_DIR/inventories/production" --list "$@"
else
command ansible-inventory -i "$ANSIBLE_DIR/inventories/production" --list "$@"
fi
}
_homelab-hosts-tsv() {
local repo="${ANSIBLE_DIR:-$HOME/Documents/code/ansible}"
local script="${repo}/scripts/homelab-hosts.sh"
if [[ -x "$script" ]]; then
"$script" && return 0
fi
if [[ -f "$repo/inventories/production/hosts" ]]; then
echo "hsp: run chmod +x $script (or fix ANSIBLE_DIR=$repo)" >&2
fi
command -v jq >/dev/null 2>&1 || return 1
_homelab-ansible-inventory 2>/dev/null | jq -r '
._meta.hostvars | to_entries[]
| select(.value.ansible_host != null)
| "\(.key)\t\(.value.ansible_user // "root")@\(.value.ansible_host)\t\(.value.url // "-")"
'
}
homelab-hosts() {
_homelab-hosts-tsv | sort | column -t -s $'\t'
}
homelab-ssh() {
local host="${1:?Usage: homelab-ssh HOST (run homelab-hosts to list)}"
local row ip user
row=$(_homelab-hosts-tsv | awk -F'\t' -v h="$host" '$1 == h {print; exit}')
if [[ -z "$row" ]]; then
echo "Unknown host: $host (try: homelab-hosts)" >&2
return 1
fi
user=${row#*$'\t'}
user=${user%%@*}
ip=${row#*@}
ip=${ip%%$'\t'*}
ssh "${user}@${ip}"
}
unalias hs 2>/dev/null
hs() { homelab-ssh "$@"; }
alias hh="homelab-hosts"
alias gohermes='homelab-ssh hermes'
alias goedge='homelab-ssh edge'
alias gomon='homelab-ssh monitoring'
alias goobs='homelab-ssh observability'
alias goauth='homelab-ssh identity'
alias gopve10='homelab-ssh pve10'
alias gopve='ssh pve'
alias goimmich='homelab-ssh immich'
alias gogitea='homelab-ssh giteaVM'
hsp() {
local repo="${ANSIBLE_DIR:-$HOME/Documents/code/ansible}"
local script="${repo}/scripts/homelab-hosts.sh"
local lines pick
[[ -x "$script" ]] || chmod +x "$script" 2>/dev/null || true
lines=$(_homelab-hosts-tsv | sort)
if [[ -z "$lines" ]]; then
echo "hsp: no hosts (ANSIBLE_DIR=${ANSIBLE_DIR:-unset}, repo=$repo)" >&2
echo " Fix: export ANSIBLE_DIR=\$HOME/Documents/code/ansible && clone ansible" >&2
return 1
fi
if ! command -v fzf >/dev/null 2>&1; then
echo "hsp: install fzf, or use: hs HOST / hh" >&2
return 1
fi
pick=$(printf '%s\n' "$lines" | fzf --header='Homelab SSH — pick a host' --height=40% --reverse | awk '{print $1}')
[[ -n "$pick" ]] && homelab-ssh "$pick"
}
# Homelab secrets picker (Ansible vault + Vaultwarden) — Ilia day-to-day;
# Irina usually only needs Vaultwarden UI for "Gmail App Password (Ira)".
hvk() {
local repo="${ANSIBLE_DIR:-$HOME/Documents/code/ansible}"
local script="${repo}/scripts/homelab-secret-pick.sh"
[[ -f "$script" ]] || { echo "hvk: missing $script (clone ansible)" >&2; return 1; }
chmod +x "$script" "${repo}/scripts/hbw.sh" 2>/dev/null || true
if [[ -z "${BW_SESSION:-}" ]] && command -v bw >/dev/null 2>&1; then
local st
st="$(bw status 2>/dev/null | "${repo}/.venv/bin/python3" -c 'import json,sys; print(json.load(sys.stdin).get("status",""))' 2>/dev/null || true)"
if [[ "$st" == "locked" ]]; then
echo "hvk: run hbw first to include Vaultwarden passwords" >&2
elif [[ "$st" == "unlocked" ]]; then
export BW_SESSION="$(bw unlock --raw 2>/dev/null)" || true
fi
fi
command bash "$script" "$@"
}
alias hsec='hvk'
alias hvka='hvk -a'
homelab-help() {
local doc="${ANSIBLE_DIR:-$HOME/Documents/code/ansible}/docs/guides/homelab-shell-shortcuts.md"
if [[ -f "$doc" ]]; then
less -F "$doc"
else
cat <<'EOF'
Homelab shortcuts — SSH: hsp | hs HOST | hh | gohermes goimmich goedge …
Secrets: hbw (unlock) → hvk (copy) | hvk -e (export)
Ansible: mk | hping | hlist | cdc
Personal scripts (Gmail etc.): mps | cd $PERSONAL_SCRIPTS_DIR
Help: hhlp
EOF
fi
}
alias hhlp='homelab-help'
alias hhelp='homelab-help'
unalias hbw 2>/dev/null
hbw() {
local dir="${ANSIBLE_DIR:-$HOME/Documents/code/ansible}"
local script="${dir}/scripts/hbw.sh"
if [[ ! -x "$script" ]]; then
chmod +x "${dir}/scripts/bw-unlock.sh" "${dir}/scripts/hbw.sh" 2>/dev/null || true
fi
if [[ ! -f "$script" ]]; then
echo "hbw: not found: $script (clone ansible)" >&2
return 1
fi
local session
session="$(command bash "$script" 2>/dev/tty)" || return $?
if [[ -n "$session" ]]; then
eval "$session"
echo "Vaultwarden ready — pick a password with: hvk (or export: hvk -e)" >&2
fi
}