zarya/bin/dep

222 lines
8.9 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

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.

#!/bin/bash
set -euo pipefail
ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "${ZARYA_DIR}/lib/common.sh"
COMMAND="${1:-help}"
parse_run_targets() {
local raw_input="$*"
local normalized
normalized=$(echo "${raw_input}" | tr ',' ' ')
local targets=()
for item in ${normalized}; do
if [[ "${item}" =~ ^([0-9]+)-([0-9]+)$ ]]; then
local start="${BASH_REMATCH[1]}"
local end="${BASH_REMATCH[2]}"
for ((i=10#$start; i<=10#$end; i++)); do
targets+=($(printf "%02d" "${i}"))
done
elif [[ "${item}" =~ ^[0-9]+$ ]]; then
targets+=($(printf "%02d" "$((10#$item))"))
else
log_err "Некорректный идентификатор плейбука: '${item}'"
exit 1
fi
done
printf "%s\n" "${targets[@]}" | sort -u -n
}
resolve_playbook() {
local id="$1"
local found
found=$(find "${REPO_ROOT}/ansible/playbooks" -maxdepth 1 -name "${id}_*.yml" | head -n1)
if [[ -z "${found}" ]]; then
log_err "Плейбук с префиксом [${id}] не найден в ansible/playbooks/"
exit 1
fi
echo "${found}"
}
print_playbooks_catalog() {
echo -e "${BLUE}=== Каталог доступных плейбуков (ansible/playbooks/) ===${NC}"
printf "%-4s %-28s %-12s %s\n" "ID" "PLAYBOOK" "HOSTS" "DESCRIPTION"
echo "----------------------------------------------------------------------------------"
for pb in $(ls -1 "${REPO_ROOT}/ansible/playbooks"/[0-9][0-9]_*.yml 2>/dev/null | sort); do
local file_name
file_name=$(basename "${pb}")
local id="${file_name:0:2}"
local hosts
hosts=$(awk '/hosts:/ {print $2; exit}' "${pb}" | tr -d '"'"'")
local desc
desc=$(awk '/- name:/ {print substr($0, index($0,$3)); exit}' "${pb}")
printf "%-4s %-28s %-12s %s\n" "${id}" "${file_name%.yml}" "${hosts}" "${desc}"
done
}
case "${COMMAND}" in
git-credential)
if [[ -f "${RAM_CACHE}" ]]; then
token=$(grep '^export ATLAS_PUSH_TOKEN=' "${RAM_CACHE}" 2>/dev/null | cut -d= -f2- | tr -d '"'\'' ' || true)
if [[ -n "${token}" ]]; then
echo "username=atlas"
echo "password=${token}"
fi
fi
exit 0
;;
start|login)
shift || true
hours="${1:-1}"
if ! [[ "${hours}" =~ ^[0-9]+$ ]] || (( hours < 0 || hours > 24 )); then
log_err "Недопустимый TTL сессии: '${hours}'. Допустимо: 0 (бессрочно) или 1-24 (часы)."
exit 1
fi
ensure_prerequisites
load_secrets_to_ram "${hours}"
unseal_vault
if [[ "${hours}" -eq 0 ]]; then
log_ok "Рабочая сессия Sovereign C2 открыта (Бессрочно)."
else
log_ok "Рабочая сессия Sovereign C2 открыта (TTL: ${hours} ч)."
fi
;;
clean|logout)
rm -f "${RAM_CACHE}" /dev/shm/.atlas_core
log_ok "Секреты и SSH-ключи безопасно удалены из RAM."
;;
unseal)
ensure_prerequisites
unseal_vault
;;
up)
shift || true
target="${1:-all}"
case "${target}" in
host) run_isolated "${ZARYA_DIR}/layers/00_host.sh" ;;
net) run_isolated "${ZARYA_DIR}/layers/01_net.sh" ;;
tier0) run_isolated "${ZARYA_DIR}/layers/02_tier0.sh" ;;
talos) run_isolated "${ZARYA_DIR}/layers/03_talos.sh" ;;
apps) "${ZARYA_DIR}/layers/04_apps.sh" ;;
all)
run_isolated "${ZARYA_DIR}/layers/00_host.sh"
run_isolated "${ZARYA_DIR}/layers/01_net.sh"
run_isolated "${ZARYA_DIR}/layers/02_tier0.sh"
run_isolated "${ZARYA_DIR}/layers/03_talos.sh"
"${ZARYA_DIR}/layers/04_apps.sh"
log_ok "Вся инфраструктура полностью развернута."
;;
*)
log_err "Неизвестный слой: ${target}. Доступны: host, net, tier0, talos, apps, all"
exit 1
;;
esac
;;
run)
shift || true
if [[ $# -eq 0 ]] || [[ "${1:-}" == "list" ]]; then
print_playbooks_catalog
exit 0
fi
targets=$(parse_run_targets "$*")
log_info "Очередь выполнения плейбуков: $(echo ${targets} | tr '\n' ' ')"
for id in ${targets}; do
pb_path=$(resolve_playbook "${id}")
log_info "==> [RUN ${id}] Исполнение: $(basename "${pb_path}")..."
run_isolated ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${pb_path}"
done
log_ok "Все выбранные плейбуки успешно выполнены."
;;
exec)
shift || true
if [[ $# -eq 0 ]]; then
log_err "Использование: dep exec <команда> [аргументы...]"
exit 1
fi
run_isolated "$@"
;;
a|apply)
unseal_vault
shift || true
run_isolated bash -c "cd '${REPO_ROOT}/tofu' && tofu apply $*"
;;
plan)
shift || true
run_isolated bash -c "cd '${REPO_ROOT}/tofu' && tofu plan $*"
;;
tf)
shift || true
run_isolated bash -c "cd '${REPO_ROOT}/tofu' && tofu $*"
;;
pods)
shift || true
kpods "$@"
;;
sync)
log_info "Принудительная конвергенция FluxCD..."
flux reconcile source git atlas-repo
flux reconcile kustomization infra-sync
flux reconcile kustomization apps-sync
log_ok "Синхронизация завершена."
;;
gc)
"${ZARYA_DIR}/layers/gc.sh"
;;
state)
shift || true
target="${1:-all}"
if [[ "${target}" == "--snapshot" ]]; then
shift || true
"${ZARYA_DIR}/state/collect_state.sh" "$@"
else
case "${target}" in
host|pve) bash "${ZARYA_DIR}/state/01_pve.sh" ;;
net|vyos) bash "${ZARYA_DIR}/state/03_vyos.sh" ;;
vps|edge) bash "${ZARYA_DIR}/state/02_vps.sh" ;;
tier0) bash "${ZARYA_DIR}/state/04_tier0.sh" ;;
k8s|talos) bash "${ZARYA_DIR}/state/05_k8s.sh" ;;
workstation) bash "${ZARYA_DIR}/state/00_workstation.sh" ;;
all)
for mod in 00_workstation 01_pve 02_vps 03_vyos 04_tier0 05_k8s; do
bash "${ZARYA_DIR}/state/${mod}.sh"
done
;;
*)
log_err "Неизвестный таргет: ${target}. Доступны: host, net, vps, tier0, k8s, workstation, all"
exit 1
;;
esac
fi
;;
reset|nuke)
"${ZARYA_DIR}/layers/reset.sh"
;;
help|--help|-h)
cat <<EOF
Sovereign C2 Orchestrator (dep)
Управление сессией:
dep start [0-24] Открытие смены (TTL в часах, по дефолту 1ч, 0 = бессрочно)
dep clean Закрытие смены (уничтожение RAM-кэша и ключа SSH)
dep unseal Ручной ансил OpenBao + синк токена в K8s
Исполнение и деплой:
dep up [layer] Сквозной макро-деплой: host, net, tier0, talos, apps, all
dep run <selector> Точечный запуск плейбуков: 06 | 01-03 | 01,03,06
dep run list Каталог всех плейбуков с описанием
dep exec <команда...> Вызов любого бинарника строго внутри RAM-изоляции run_isolated
Инфраструктура (IaC):
dep a [-auto-approve] OpenTofu apply с авто-ансилом Vault
dep plan OpenTofu plan
dep tf <args...> Прямой вызов OpenTofu в изолированном контексте
Кластер и состояние:
dep pods [args...] Просмотр подов через kpods (включая kpods -w)
dep sync Принудительный синк FluxCD
dep gc Сборка мусора и сброс бэкоффа подов
dep state [target] Живой вывод статуса в терминал (host, net, vps, tier0, k8s, all)
dep reset Полное уничтожение инфраструктуры (MFA через YubiKey)
EOF
;;
*)
log_err "Неизвестная команда: ${COMMAND}. Используйте 'dep help' для справки."
exit 1
;;
esac