workspaces-pipelines/gitops_router.sh
2025-05-23 12:36:55 +00:00

189 lines
5.8 KiB
Bash
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
set -euo pipefail
PERSON="${1:?Missing PERSON argument}"
HOST="alps:3222"
PROTOCOL="http"
REPO=("babbarc/workspaces" "babbarc/workspaces-pipelines" "babbarc/workspaces-sec-alps-infilytics")
BRANCH="master"
LOG_FILE="/tmp/.gitops-router-${PERSON}.log"
# ─────────────────────────────────────────────
# ANSI color codes
readonly C_RESET='\033[0m'
readonly C_INFO='\033[1;34m' # bold blue
readonly C_WARN='\033[1;33m' # bold yellow
readonly C_ERROR='\033[1;31m' # bold red
# ─────────────────────────────────────────────
# log <level> <message...> with emojis
log() {
local lvl="${1^^}"
shift
local icon color
case "$lvl" in
INFO) icon="" color="$C_INFO" ;;
WARN) icon="⚠️" color="$C_WARN" ;;
ERROR) icon="❌" color="$C_ERROR" ;;
*) icon="🔹" color="$C_RESET" ;;
esac
local ts
ts="$(date '+%Y-%m-%d %H:%M:%S')"
printf '%b%s [%s] [%s] %s%b\n' \
"$color" "$icon" "$ts" "$lvl" "$*" "$C_RESET" |
tee -a "$LOG_FILE"
}
# ─────────────────────────────────────────────
# Build the raw URL for fetching files
geturl() {
local repo="$1" type="$2" file="$3"
printf '%s://%s/%s/%s/branch/%s/%s\n' \
"$PROTOCOL" "$HOST" "${REPO[$repo]}" "$type" "$BRANCH" "$file"
}
# ─────────────────────────────────────────────
# Run a local script
run() {
local script="$1"
"$HOME/.local/bin/$script"
}
# ─────────────────────────────────────────────
# Download & install an artifact
# update <repo> <file> <target-dir> <mode> [<type>]
update() {
local repo="$1" file="$2" dir="$3" mode="$4" type="${5:-raw}"
local url out
out="$HOME/$dir/$(basename "$file")"
url="$(geturl "$repo" "$type" "$file")"
[[ -f "$out" ]] && chmod 700 "$out"
if curl -fsSL "$url" -o "$out"; then
log INFO "Downloaded $url$out"
chmod "$mode" "$out"
else
log ERROR "Failed to download $url"
return 1
fi
}
# ─────────────────────────────────────────────
# Clean up dangling podman images
clean_images() {
local dangling
dangling="$(podman images -f dangling=true -q)"
if [[ -z "$dangling" ]]; then
log INFO "No dangling images to remove."
else
log WARN "Removing dangling images..."
echo "$dangling" | xargs podman rmi
log INFO "Dangling images removed."
fi
}
# ─────────────────────────────────────────────
# Remove host podman containers
remove_containers() {
local tokens=("$@")
local flags=() patterns=() containers=()
local valid='^[A-Za-z0-9._-]+$'
# allow unmatched globs to disappear
shopt -s nullglob
# separate flags (-f, etc.) from name patterns
for tok in "${tokens[@]}"; do
if [[ "$tok" == -* ]]; then
flags+=("$tok")
else
patterns+=("$tok")
fi
done
# validate & expand each pattern
for pat in "${patterns[@]}"; do
if [[ ! "$pat" =~ $valid ]]; then
log ERROR "Invalid container name: '$pat'"
shopt -u nullglob
return 1
fi
containers+=("$pat")
done
shopt -u nullglob
if ((${#containers[@]} == 0)); then
log WARN "No containers matched: ${patterns[*]}"
return 0
fi
# pass flags *then* containers to podman rm
podman rm "${flags[@]}" "${containers[@]}"
}
# ─────────────────────────────────────────────
# validate_command <workspace> <cmd> [<tok1> <tok2> …]
source "$HOME"/.local/bin/validate_command_access.sh
# ─────────────────────────────────────────────
# Entry & command parsing
if [[ -z "${SSH_ORIGINAL_COMMAND:-}" ]]; then
log ERROR "No SSH_ORIGINAL_COMMAND provided."
exit 1
fi
log INFO "SSH_ORIGINAL_COMMAND: $SSH_ORIGINAL_COMMAND"
read -ra parts <<<"$SSH_ORIGINAL_COMMAND"
cmd="${parts[0]}"
args=("${parts[@]:1}")
validate_command "$PERSON" "$cmd" "${args[@]}"
# ─────────────────────────────────────────────
# Dispatch
case "$cmd" in
build)
case "${args[0]}" in
base) podman build --target base -t workspaces-base . ;;
workspace) podman build --target workspace -t workspaces . ;;
all) podman build -t workspaces . ;;
*) log ERROR "build: invalid arg '${args[0]}'" ;;
esac
;;
update)
case "${args[0]}" in
containerfile) update 0 Containerfile . 500 ;;
access) update 2 access.yml . 400 ;;
authorized_keys) update 2 authorized_keys .ssh 400 ;;
secret_key) update 2 keys/"${args[1]}"/id_ed25519 secrets/"${args[1]}" 400 ;;
podman_access)
update 2 podman_access.keys . 400
scp podman_access.keys mypodmanuser@alps:~/.ssh/authorized_keys
;;
ssh_router) update 1 ssh_router.sh .local/bin 500 ;;
gitops_router) update 1 gitops_router.sh .local/bin 500 ;;
validate_command) update 1 validate_command_access.sh .local/bin 500 ;;
home_tar)
podman cp "$PERSON":/app/private/workspaces/home.tar.gz "$HOME"/
chmod 600 "$HOME"/home.tar.gz
;;
gitconfig) update 0 gitconfig.template . 500 ;;
start.sh) update 0 start.sh . 500 ;;
*) log ERROR "update: invalid arg '${args[0]}'" ;;
esac
;;
clean) clean_images ;;
status) podman images ;;
remove) remove_containers "${args[@]}" ;;
rmi) podman rmi "${args[@]}" ;;
*)
log ERROR "Unknown command: '$cmd'"
exit 127
;;
esac