prole/etc/prole_cfg.sh

203 lines
5.7 KiB
Bash

#!/usr/bin/env bash
# Standard include for Prole etc scripts.
# - Loads environment from env.sh (if available)
# - Loads values from PROLE_CONF/prole.cfg (INI-style)
# - Does not override already-set env vars
if [[ "${_PROLE_CFG_LOADED:-}" == "1" ]]; then
return 0 2>/dev/null || true
fi
_PROLE_CFG_LOADED=1
_prole_cfg_script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
_prole_cfg_home_guess=$(cd "$_prole_cfg_script_dir/.." && pwd)
# 1. Try to load env.sh to establish base PROLE_HOME/PROLE_CONF
if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then
# shellcheck disable=SC1090
source "$PROLE_HOME/env.sh"
elif [[ -f "$HOME/.prole/env.sh" ]]; then
# shellcheck disable=SC1090
source "$HOME/.prole/env.sh"
elif [[ -f "$_prole_cfg_home_guess/env.sh" ]]; then
# shellcheck disable=SC1090
source "$_prole_cfg_home_guess/env.sh"
fi
_prole_trim() {
local s="$1"
s="${s#"${s%%[![:space:]]*}"}"
s="${s%"${s##*[![:space:]]}"}"
printf '%s' "$s"
}
_PROLE_CFG_SET_VARS="|"
_prole_cfg_set_default() {
local key="$1" value="$2" token="|$key|"
# Only set if currently empty OR if we were the ones who set it from config previously
if [[ -z "${!key:-}" || "$_PROLE_CFG_SET_VARS" == *"$token"* ]]; then
printf -v "$key" '%s' "$value"
export "$key"
if [[ "$_PROLE_CFG_SET_VARS" != *"$token"* ]]; then
_PROLE_CFG_SET_VARS="${_PROLE_CFG_SET_VARS}${key}|"
fi
fi
}
_prole_read_cfg() {
local cfg="$1" line key value
while IFS= read -r line || [[ -n "$line" ]]; do
line="$(_prole_trim "$line")"
[[ -z "$line" ]] && continue
case "$line" in
\#*|\;*|\[*\])
continue
;;
esac
if [[ "$line" == *"="* ]]; then
key="$(_prole_trim "${line%%=*}")"
value="$(_prole_trim "${line#*=}")"
[[ -z "$key" ]] && continue
# Replace dots with underscores for shell compatibility
key="${key//./_}"
_prole_cfg_set_default "$key" "$value"
fi
done <"$cfg"
}
_prole_cfg_extract_key() {
local cfg="$1" key="$2"
local value
value=$(awk -F= -v k="$key" '
/^[[:space:]]*;/ {next}
/^[[:space:]]*#/ {next}
/^[[:space:]]*\\[/ {next}
$1 ~ "^[[:space:]]*" k "[[:space:]]*$" {
v=$2
sub(/^[[:space:]]+/, "", v)
sub(/[[:space:]]+$/, "", v)
val=v
}
END { print val }
' "$cfg" 2>/dev/null || true)
printf '%s' "$value"
}
prole_normalize_mode() {
local s
s=$(printf '%s' "${1:-}" | tr 'A-Z' 'a-z')
case "$s" in
dev|k3d|k3d-*) echo "k3d"; return 0 ;;
service|k3s|k3s-*) echo "k3s"; return 0 ;;
prod|production|k8s|k8s-*) echo "k8s"; return 0 ;;
prole-dev-cluster|k3d-prole-dev-cluster) echo "k3d"; return 0 ;;
prole-service-cluster) echo "k3s"; return 0 ;;
prole-prod-cluster) echo "k8s"; return 0 ;;
esac
echo "$s"
}
prole_set_mode() {
local raw="$1"
if [[ -z "$raw" ]]; then
echo "ERROR: --mode requires a value (k3d, k3s, k8s)" >&2
exit 2
fi
local norm
norm=$(prole_normalize_mode "$raw")
case "$norm" in
k3d|k3s|k8s)
PROLE_MODE="$norm"
export PROLE_MODE
;;
*)
echo "ERROR: Unsupported mode '$raw' (use k3d, k3s, or k8s)" >&2
exit 2
;;
esac
}
prole_render_manifest() {
local src="$1"
if [[ "${PROLE_MODE:-}" != "k3d" ]]; then
cat "$src"
return 0
fi
local renderer=""
if [[ -n "${PROLE_SERVICE:-}" && -f "$PROLE_SERVICE/render_manifest.py" ]]; then
renderer="$PROLE_SERVICE/render_manifest.py"
elif [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/etc/render_manifest.py" ]]; then
renderer="$PROLE_HOME/etc/render_manifest.py"
fi
if [[ -n "$renderer" ]]; then
python3 "$renderer" "$src"
return $?
fi
cat "$src"
}
_prole_cfg_file=""
if [[ -n "${PROLE_CONF:-}" && -f "$PROLE_CONF/prole.cfg" ]]; then
_prole_cfg_file="$PROLE_CONF/prole.cfg"
elif [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/conf/prole.cfg" ]]; then
_prole_cfg_file="$PROLE_HOME/conf/prole.cfg"
elif [[ -f "$_prole_cfg_home_guess/conf/prole.cfg" ]]; then
_prole_cfg_file="$_prole_cfg_home_guess/conf/prole.cfg"
fi
if [[ -n "$_prole_cfg_file" ]]; then
if [[ -z "${PROLE_CONF:-}" ]]; then
PROLE_CONF=$(cd "$(dirname "$_prole_cfg_file")" && pwd)
export PROLE_CONF
fi
_prole_read_cfg "$_prole_cfg_file"
# Prefer namespace from config unless explicitly overridden by env.
if [[ "${PROLE_NAMESPACE_PREFER_ENV:-0}" != "1" ]]; then
_cfg_ns=$(_prole_cfg_extract_key "$_prole_cfg_file" "NAMESPACE")
if [[ -n "$_cfg_ns" ]]; then
export NAMESPACE="$_cfg_ns"
fi
unset _cfg_ns
fi
fi
if [[ -z "${PROLE_HOME:-}" && -d "$_prole_cfg_home_guess" ]]; then
PROLE_HOME="$_prole_cfg_home_guess"
export PROLE_HOME
fi
# Final check for critical variables
if [[ -z "${PROLE_SERVICE:-}" && -n "${PROLE_HOME:-}" ]]; then
export PROLE_SERVICE="$PROLE_HOME/etc"
fi
# Ensure NAMESPACE is set, defaulting to 'default' if not in config/env
if [[ -z "${NAMESPACE:-}" ]]; then
# Try to detect from current context if not set anywhere
NAMESPACE=$(kubectl config view --minify --output 'jsonpath={..namespace}' 2>/dev/null)
fi
export NAMESPACE=${NAMESPACE:-default}
if [[ -z "${PROLE_MODE:-}" ]]; then
if [[ -n "${DEPLOYMENT_MODE:-}" ]]; then
_prole_mode_guess=$(prole_normalize_mode "$DEPLOYMENT_MODE")
case "$_prole_mode_guess" in
k3d|k3s|k8s) PROLE_MODE="$_prole_mode_guess"; export PROLE_MODE ;;
esac
unset _prole_mode_guess
elif [[ -n "${CLUSTER_ENV:-}" ]]; then
_prole_mode_guess=$(prole_normalize_mode "$CLUSTER_ENV")
case "$_prole_mode_guess" in
k3d|k3s|k8s) PROLE_MODE="$_prole_mode_guess"; export PROLE_MODE ;;
esac
unset _prole_mode_guess
fi
fi
unset _prole_cfg_script_dir
unset _prole_cfg_home_guess
unset _prole_cfg_file
unset _PROLE_CFG_SET_VARS