fix: validate commands, improve remove container logic, standardize logs in gitops router
This commit is contained in:
parent
6e11d19510
commit
9629c3253e
137
gitops_router.sh
137
gitops_router.sh
@ -64,10 +64,10 @@ update() {
|
||||
[[ -f "$out" ]] && chmod 700 "$out"
|
||||
|
||||
if curl -fsSL "$url" -o "$out"; then
|
||||
log info "Downloaded $url → $out"
|
||||
log INFO "Downloaded $url → $out"
|
||||
chmod "$mode" "$out"
|
||||
else
|
||||
log error "Failed to download $url"
|
||||
log ERROR "Failed to download $url"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@ -78,36 +78,145 @@ clean_images() {
|
||||
local dangling
|
||||
dangling="$(podman images -f dangling=true -q)"
|
||||
if [[ -z "$dangling" ]]; then
|
||||
log info "No dangling images to remove."
|
||||
log INFO "No dangling images to remove."
|
||||
else
|
||||
log warn "Removing dangling images..."
|
||||
log WARN "Removing dangling images..."
|
||||
echo "$dangling" | xargs podman rmi
|
||||
log info "Dangling images removed."
|
||||
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 <cmd> [<tok1> <tok2> …]
|
||||
validate_command() {
|
||||
local cmd="$1"
|
||||
shift
|
||||
local tokens=("$@")
|
||||
local yaml="$HOME/access.yml"
|
||||
|
||||
# 1) Is command allowed at all?
|
||||
if [[ "$(yq e ".\"$PERSON\".commands | has(\"$cmd\")" "$yaml")" != "true" ]]; then
|
||||
log ERROR "Unauthorized command: '$cmd'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2) Load allowed args for this cmd (may be empty array)
|
||||
mapfile -t allowed < <(yq e ".\"$PERSON\".commands.${cmd}[]" "$yaml")
|
||||
|
||||
if [[ "${#allowed[@]}" -eq 0 ]]; then
|
||||
log ERROR "No allowed arguments for command '$cmd' in $yaml"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 3) Extract just the non-flag tokens
|
||||
local args=()
|
||||
for tok in "${tokens[@]}"; do
|
||||
[[ "$tok" == -* ]] && continue
|
||||
args+=("$tok")
|
||||
done
|
||||
|
||||
if [[ "$cmd" == "remove" ]]; then
|
||||
# ─ remove: must have at least one arg
|
||||
if ((${#args[@]} == 0)); then
|
||||
log ERROR "Command '$cmd' requires at least one argument: ${allowed[*]}"
|
||||
exit 1
|
||||
fi
|
||||
# Validate each against allowed[]
|
||||
for a in "${args[@]}"; do
|
||||
local ok=false
|
||||
for want in "${allowed[@]}"; do
|
||||
[[ "$a" == "$want" ]] && ok=true && break
|
||||
done
|
||||
if ! $ok; then
|
||||
log ERROR "Invalid argument '$a' for '$cmd'; allowed: ${allowed[*]}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
else
|
||||
# ─ all other cmds: must have exactly one arg
|
||||
if ((${#args[@]} != 1)); then
|
||||
log ERROR "Command '$cmd' requires exactly one argument: ${allowed[*]}"
|
||||
exit 1
|
||||
fi
|
||||
# And that single arg must be allowed
|
||||
local a="${args[0]}"
|
||||
local ok=false
|
||||
for want in "${allowed[@]}"; do
|
||||
[[ "$a" == "$want" ]] && ok=true && break
|
||||
done
|
||||
if ! $ok; then
|
||||
log ERROR "Invalid argument '$a' for '$cmd'; allowed: ${allowed[*]}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# Entry & command parsing
|
||||
if [[ -z "${SSH_ORIGINAL_COMMAND:-}" ]]; then
|
||||
log error "No SSH_ORIGINAL_COMMAND provided."
|
||||
log ERROR "No SSH_ORIGINAL_COMMAND provided."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log info "SSH_ORIGINAL_COMMAND: $SSH_ORIGINAL_COMMAND"
|
||||
read -r cmd arg <<<"$SSH_ORIGINAL_COMMAND"
|
||||
log INFO "SSH_ORIGINAL_COMMAND: $SSH_ORIGINAL_COMMAND"
|
||||
read -ra parts <<<"$SSH_ORIGINAL_COMMAND"
|
||||
cmd="${parts[0]}"
|
||||
args=("${parts[@]:1}")
|
||||
|
||||
validate_command "$cmd" "${args[@]}"
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# Dispatch
|
||||
case "$cmd" in
|
||||
build)
|
||||
case "$arg" in
|
||||
case "${args[0]}" in
|
||||
base) run build-base.sh ;;
|
||||
workspace) run build-workspace.sh ;;
|
||||
*) log error "build: invalid arg '$arg'" ;;
|
||||
*) log ERROR "build: invalid arg '${args[0]}'" ;;
|
||||
esac
|
||||
;;
|
||||
update)
|
||||
case "$arg" in
|
||||
case "${args[0]}" in
|
||||
base) update build-base.sh .local/bin 500 ;;
|
||||
workspace) update build-workspace.sh .local/bin 500 ;;
|
||||
access) update access.yml . 400 ;;
|
||||
@ -115,14 +224,14 @@ update)
|
||||
gitops_router) update gitops_router.sh .local/bin 500 ;;
|
||||
home_tar) update home.tar.gz . 500 media ;;
|
||||
gitconfig) update gitconfig.template . 500 ;;
|
||||
*) log error "update: invalid arg '$arg'" ;;
|
||||
*) log ERROR "update: invalid arg '${args[0]}'" ;;
|
||||
esac
|
||||
;;
|
||||
clean) clean_images ;;
|
||||
status) podman images ;;
|
||||
remove) podman rm "$arg" ;;
|
||||
remove) remove_containers "${args[@]}" ;;
|
||||
*)
|
||||
log error "Unknown command: '$cmd'"
|
||||
log ERROR "Unknown command: '$cmd'"
|
||||
exit 127
|
||||
;;
|
||||
esac
|
||||
|
Loading…
x
Reference in New Issue
Block a user