From a two-agent audit (docs accuracy + greenfield deploy path): - init_db docs were describing upstream behavior: this repo's psql-app auto-creates the schema on first run and drops config/do_not_init_db to skip later (psql-app/scripts/run:74). README/DOCS/backup-restore now describe the marker semantics; the restore flow creates the marker BEFORE first start instead of 'not creating init_db' - DOCS.md contained heavy retired-lab drift: banner declares it a legacy walkthrough with illustrative values; fixed its self-contradictions -- external port 1790, folder OBMP-Reference, datasource 'PostgreSQL', OpenConfig gNMI paths (matching telegraf.conf), EXABGP_PEERS, TRAFFIC_GEN_PORT - deploy.sh --help now shows the current scope names (old ones remain accepted aliases) - navigation: new docs/README.md index with operator and network-engineer tracks (links the previously orphaned backup-restore, security-hardening, ROADMAP, DB_SCHEMA); README gains a Start-here router - intra-docs prose paths no longer carry the docs/ prefix (they resolve from within docs/); RR-CLIENTS -> RR-CLIENT matches the blueprint; ROADMAP A6 marked done - scripts/deploy-lib.sh added: shared log/ask/confirm/get_env/set_env helpers for the deploy tooling consolidation (wiring lands next) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
91 lines
3.4 KiB
Bash
91 lines
3.4 KiB
Bash
#!/usr/bin/env bash
|
|
#
|
|
# deploy-lib.sh - shared helpers for deploy.sh and setup.sh.
|
|
#
|
|
# Both scripts source this file so output styling and .env handling stay
|
|
# identical and are defined exactly once. Safe to source multiple times.
|
|
#
|
|
# Provides:
|
|
# log / ok / warn / die / hr - consistent colored output
|
|
# banner "title" - boxed section banner
|
|
# step N M "title" - numbered decision/stage header
|
|
# ask VAR "prompt" "default" - editable-default prompt (honors ARG_YES)
|
|
# confirm "prompt" - y/N confirm (honors ARG_YES)
|
|
# get_env KEY / set_env KEY VAL - .env read/write without sourcing it
|
|
# is_ipv4 ADDR - dotted-quad shape check
|
|
#
|
|
# Conventions: callers may set ARG_YES=1 for unattended runs and TAG to
|
|
# change the log prefix (defaults to "deploy").
|
|
|
|
TAG="${TAG:-deploy}"
|
|
ARG_YES="${ARG_YES:-0}"
|
|
|
|
log() { printf '\033[1;36m[%s]\033[0m %s\n' "$TAG" "$*"; }
|
|
ok() { printf '\033[1;32m[%s] \xe2\x9c\x94\033[0m %s\n' "$TAG" "$*"; }
|
|
warn() { printf '\033[1;33m[%s][warn]\033[0m %s\n' "$TAG" "$*" >&2; }
|
|
die() { printf '\033[1;31m[%s][err]\033[0m %s\n' "$TAG" "$*" >&2; exit 1; }
|
|
hr() { printf '\033[2m%s\033[0m\n' "----------------------------------------------------------------"; }
|
|
|
|
# Boxed banner, e.g.:
|
|
# +--------------------------------------------------------------+
|
|
# | OpenBMP stack deploy |
|
|
# +--------------------------------------------------------------+
|
|
banner() {
|
|
local title="$1" width=62
|
|
printf '\033[1;36m+%s+\n' "$(printf -- '-%.0s' $(seq 1 $width))"
|
|
printf '| %-*s|\n' "$((width - 2))" "$title"
|
|
printf '+%s+\033[0m\n' "$(printf -- '-%.0s' $(seq 1 $width))"
|
|
}
|
|
|
|
# Numbered header for decisions and stages: step 2 5 "Deployment type"
|
|
step() {
|
|
local n="$1" total="$2" title="$3"
|
|
printf '\n\033[1;36m[%s] Step %s/%s\033[0m \033[1m%s\033[0m\n' "$TAG" "$n" "$total" "$title"
|
|
}
|
|
|
|
# Prompt with an editable default. Honors ARG_YES (accepts default silently).
|
|
ask() {
|
|
local __var="$1" __prompt="$2" __default="${3:-}" __reply=""
|
|
if [ "$ARG_YES" -eq 1 ]; then
|
|
printf -v "$__var" '%s' "$__default"; return
|
|
fi
|
|
if [ -n "$__default" ]; then
|
|
read -r -p "$__prompt [$__default]: " __reply
|
|
__reply="${__reply:-$__default}"
|
|
else
|
|
read -r -p "$__prompt: " __reply
|
|
fi
|
|
printf -v "$__var" '%s' "$__reply"
|
|
}
|
|
|
|
confirm() {
|
|
local __prompt="$1" __reply=""
|
|
[ "$ARG_YES" -eq 1 ] && return 0
|
|
read -r -p "$__prompt [y/N]: " __reply
|
|
[ "$__reply" = "y" ] || [ "$__reply" = "Y" ]
|
|
}
|
|
|
|
# Read a single KEY=value from .env without sourcing it -- .env contains keys
|
|
# with hyphens (PROX-CML_*) that a shell `source` would choke on.
|
|
get_env() { grep -E "^$1=" .env | head -1 | cut -d= -f2- || true; }
|
|
|
|
# Set KEY=value in .env: replace the line if present, else append.
|
|
set_env() {
|
|
local key="$1" val="$2"
|
|
if grep -qE "^${key}=" .env; then
|
|
# `|` delimiter -- values are hex/IPs, no `|`.
|
|
sed -i "s|^${key}=.*|${key}=${val}|" .env
|
|
else
|
|
printf '%s=%s\n' "$key" "$val" >> .env
|
|
fi
|
|
}
|
|
|
|
# Dotted-quad shape check (rejects placeholders like <WINDOWS_LAN_IP>).
|
|
is_ipv4() {
|
|
local ip="$1" o
|
|
[[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] || return 1
|
|
IFS=. read -r -a o <<<"$ip"
|
|
for x in "${o[@]}"; do [ "$x" -le 255 ] || return 1; done
|
|
return 0
|
|
}
|