diff --git a/bin/fc b/bin/fc new file mode 100755 index 0000000..9044814 --- /dev/null +++ b/bin/fc @@ -0,0 +1,12 @@ +#!/bin/bash +set -euo pipefail +if [[ $# -eq 0 ]]; then + echo "Использование: fc <файл>" + exit 1 +fi +if [[ -f "$1" ]]; then + wl-copy < "$1" + echo "'$1' +++" +else + echo "'$1'+++" +fi diff --git a/bin/gg b/bin/gg new file mode 100755 index 0000000..ee1d680 --- /dev/null +++ b/bin/gg @@ -0,0 +1,7 @@ +#!/bin/bash +set -euo pipefail +if [[ -z "${1:-}" ]]; then + echo "Тема СВО не раскрыта: gg \"сообщение\"" + exit 1 +fi +git add . && git commit -m "$1" && git push diff --git a/bin/op b/bin/op new file mode 100755 index 0000000..43749a9 --- /dev/null +++ b/bin/op @@ -0,0 +1,9 @@ +#!/bin/bash +set -euo pipefail +if [[ $# -eq 0 ]]; then + echo "Использование: op <файл...>" + exit 1 +fi +for f in "$@"; do + printf "file://%s\r\n" "$(realpath "$f")" +done | wl-copy -t text/uri-list diff --git a/bin/zarya b/bin/zarya index 28a1d64..8ea1d52 100755 --- a/bin/zarya +++ b/bin/zarya @@ -7,7 +7,11 @@ SUBCMD="${1:-help}" shift || true case "${SUBCMD}" in + git-credential) exec "${ZARYA_DIR}/cmd/git-credential.sh" "$@" ;; + exec) exec "${ZARYA_DIR}/cmd/exec.sh" "$@" ;; p|pod|pods) exec "${ZARYA_DIR}/cmd/pods.sh" "$@" ;; + node|nodes) exec "${ZARYA_DIR}/cmd/nodes.sh" "$@" ;; + flux) exec "${ZARYA_DIR}/cmd/flux.sh" "$@" ;; e|err|errors) exec "${ZARYA_DIR}/cmd/errors.sh" "$@" ;; l|log|logs) exec "${ZARYA_DIR}/cmd/logs.sh" "$@" ;; n|net) exec "${ZARYA_DIR}/cmd/net.sh" "$@" ;; @@ -24,14 +28,18 @@ case "${SUBCMD}" in gc) exec "${ZARYA_DIR}/layers/gc.sh" "$@" ;; help|--help|-h) cat <] [-s ] [-A] Просмотр подов + z nodes [-w] Статус нод, роли, зона и регион z errors Мгновенный триаж сломанных сервисов - z logs [-f] [-t ] Логи любого сервиса без ввода неймспейса + z logs [-f] [-t ] Логи сервиса без ввода неймспейса z net Сетевой радар доступности узлов (1 сек) - z disks Срез пулов astra/terra и ZVOL томов K8s -Управление и сессия: + z disks Срез пулов astra/terra и томов K8s +GitOps и оркестрация: + z flux [status|sync|logs] Управление GitOps-конвергенцией + z exec <команда...> Вызов бинарников внутри RAM-изоляции +Сессия и доступы: z login [TTL] Открытие смены (YubiKey + RAM) z logout Мгновенная очистка RAM z unseal Распечатывание OpenBao Vault @@ -40,8 +48,8 @@ Zarya C2 Operator Interface (z) z run Плейбуки Ansible (01, 02) z a [-auto-approve] OpenTofu apply в RAM-изоляции Телеметрия и LLM: - z snap Снятие полного .md аудита в snapshots/ - z pack [code|state|atlas] Сборка контекста Repomix + z snap Снятие аудита в state/snapshots/ + z pack [all|atlas|code|state] Сборка контекстов Repomix для LLM EOF ;; *) diff --git a/cmd/exec.sh b/cmd/exec.sh new file mode 100755 index 0000000..5a43d1e --- /dev/null +++ b/cmd/exec.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -euo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" + +if [[ $# -eq 0 ]]; then + log_err "Использование: z exec <команда> [аргументы...]" + exit 1 +fi + +run_isolated "$@" \ No newline at end of file diff --git a/cmd/flux.sh b/cmd/flux.sh new file mode 100755 index 0000000..69c6ace --- /dev/null +++ b/cmd/flux.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -uo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" + +subcmd="${1:-status}" +shift || true + +case "${subcmd}" in + sync|reconcile|s) + log_info "Принудительная конвергенция FluxCD..." + flux reconcile source git atlas-repo -n flux-system 2>/dev/null || true + flux reconcile kustomization infra-sync -n flux-system 2>/dev/null || true + flux reconcile kustomization apps-sync -n flux-system 2>/dev/null || true + log_ok "Синхронизация завершена." + ;; + logs|log|l) + log_info "Стриминг логов kustomize-controller..." + exec kubectl -n flux-system logs -l app.kubernetes.io/name=kustomize-controller --tail=50 -f + ;; + status|st) + echo -e "${BLUE}=== СТАТУС РЕПОЗИТОРИЕВ И KUSTOMIZATION (FLUX) ===${NC}" + kubectl -n flux-system get gitrepositories,kustomizations,helmreleases 2>/dev/null || log_err "Flux недоступен" + ;; + *) + kubectl -n flux-system get kustomizations 2>/dev/null || log_err "Flux недоступен" + ;; +esac \ No newline at end of file diff --git a/cmd/git-credential.sh b/cmd/git-credential.sh new file mode 100644 index 0000000..5a5bb0a --- /dev/null +++ b/cmd/git-credential.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -euo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" + +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 \ No newline at end of file diff --git a/cmd/nodes.sh b/cmd/nodes.sh new file mode 100755 index 0000000..26bfa25 --- /dev/null +++ b/cmd/nodes.sh @@ -0,0 +1,46 @@ +#!/bin/bash +set -u +watch_mode=false + +while [[ $# -gt 0 ]]; do + case "$1" in + -w|--watch) watch_mode=true; shift ;; + *) shift ;; + esac +done + +render_nodes() { + local raw + raw=$(kubectl get nodes -L topology.kubernetes.io/zone,topology.kubernetes.io/region 2>/dev/null || true) + + echo "$raw" | awk ' + BEGIN { + ERR = "\033[38;2;255;46;76m" + RUN = "\033[38;2;166;227;161m" + HEAD = "\033[38;2;147;154;183m" + RST = "\033[0m" + } + NR==1 { print HEAD $0 RST; next } + { + if ($2 ~ /Ready/ && $2 !~ /NotReady/) { + print RUN $0 RST + } + else { + print ERR $0 RST + } + }' +} + +if [[ "$watch_mode" == true ]]; then + trap 'tput cnorm 2>/dev/null || true; echo ""; exit 0' INT TERM + tput civis 2>/dev/null || true + clear + while true; do + tput cup 0 0 2>/dev/null || true + render_nodes + tput ed 2>/dev/null || true + sleep 1 + done +else + render_nodes +fi \ No newline at end of file diff --git a/cmd/pack.sh b/cmd/pack.sh index 3e9bda5..2b5d972 100755 --- a/cmd/pack.sh +++ b/cmd/pack.sh @@ -1,28 +1,50 @@ #!/bin/bash set -euo pipefail ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -mode="${1:-state}" +source "${ZARYA_DIR}/lib/common.sh" + +mode="${1:-all}" + +pack_atlas() { + log_info "==> [1/3] Упаковка чистой архитектуры Atlas (atlas-code.xml)..." + (cd "${ATLAS_DIR}" && repomix --config "${ATLAS_DIR}/repomix.config.json") + log_ok "Файл ${ATLAS_DIR}/atlas-code.xml готов." +} + +pack_zarya() { + log_info "==> [2/3] Упаковка станции оператора Zarya (zarya-code.xml)..." + (cd "${ZARYA_DIR}" && repomix --config "${ZARYA_DIR}/repomix.config.json") + log_ok "Файл ${ZARYA_DIR}/zarya-code.xml готов." +} + +pack_state() { + log_info "==> [3/3] Снятие живого аудита и упаковка телеметрии (zarya-state.xml)..." + "${ZARYA_DIR}/state/collect_state.sh" all + (cd "${ZARYA_DIR}" && repomix --config "${ZARYA_DIR}/repomix.state.json") + log_ok "Файл ${ZARYA_DIR}/zarya-state.xml готов." +} case "${mode}" in - state) - echo "==> Снятие свежего аудита..." - "${ZARYA_DIR}/state/collect_state.sh" all >/dev/null 2>&1 || true - echo "==> Упаковка среза состояния Repomix (zarya-state.xml)..." - repomix --config "${ZARYA_DIR}/repomix.state.json" - echo "✔ Файл zarya-state.xml готов для отправки в LLM." - ;; - code) - echo "==> Упаковка кодовой базы zarya (zarya-code.xml)..." - repomix --config "${ZARYA_DIR}/repomix.config.json" - echo "✔ Файл zarya-code.xml готов." + all) + pack_atlas + echo "" + pack_zarya + echo "" + pack_state + echo "" + log_ok "Все три контекста Repomix собраны без ошибок." ;; atlas) - echo "==> Упаковка чистой инфраструктуры atlas (atlas-code.xml)..." - cd "${ATLAS_DIR}" && repomix - echo "✔ Файл atlas/repomix-output.xml готов." + pack_atlas + ;; + code) + pack_zarya + ;; + state) + pack_state ;; *) - echo "Использование: z pack [state|code|atlas]" + log_err "Использование: z pack [all|atlas|code|state]" exit 1 ;; -esac +esac \ No newline at end of file diff --git a/lib/net.sh b/lib/net.sh index ecdba07..ed48c42 100644 --- a/lib/net.sh +++ b/lib/net.sh @@ -1,5 +1,4 @@ #!/bin/bash -# Network routing and terminal prerequisites ensure_prerequisites() { local target_ip="${VAULT_ADDR#*//}" target_ip="${target_ip%%:*}" @@ -7,19 +6,20 @@ ensure_prerequisites() { log_info "Восстанавливаем маршрут к ${NET_PREFIX} через VyOS (${VYOS_ROUTER_IP})..." sudo ip route replace "${NET_PREFIX}" via "${VYOS_ROUTER_IP}" 2>/dev/null || true fi - # Регистрация Git Credential Helper (доменный и прямой IP Tier-0) - local target_helper="!${REPO_ROOT}/deploy.sh git-credential" + + local target_helper="!${ZARYA_DIR}/bin/zarya git-credential" local current_helper current_helper=$(git config --global --get credential."https://${GIT_HOST}".helper 2>/dev/null || true) if [[ "${current_helper}" != "${target_helper}" ]]; then git config --global credential."https://${GIT_HOST}".helper "${target_helper}" fi + local direct_helper direct_helper=$(git config --global --get credential."http://10.0.10.13:3000".helper 2>/dev/null || true) if [[ "${direct_helper}" != "${target_helper}" ]]; then git config --global credential."http://10.0.10.13:3000".helper "${target_helper}" fi - # Нативная привязка IdentityFile для всех C2-хостов и LXC-контейнеров + local ssh_hosts="proxmox pve0 vyos vyos_router 10.0.* dns0 vault0 git0 storage0 registry0" if [[ -f "${HOME}/.ssh/config" ]] && ! grep -q "IdentityFile ${RAM_KEY}" "${HOME}/.ssh/config"; then printf "\nHost %s\n IdentityFile %s\n IdentitiesOnly yes\n" "${ssh_hosts}" "${RAM_KEY}" >> "${HOME}/.ssh/config" diff --git a/lib/session.sh b/lib/session.sh index 1dafd45..9c7ae29 100644 --- a/lib/session.sh +++ b/lib/session.sh @@ -1,20 +1,14 @@ #!/bin/bash -# Session state in RAM tmpfs and YubiKey integration - load_secrets_to_ram() { local hours="${1:-$DEFAULT_SESSION_TTL}" local now now=$(date +%s) - ensure_prerequisites - - # Валидация сессии по наличию непустых кэша секретов и SSH-ключа if [[ -f "${RAM_CACHE}" ]] && [[ -f "${RAM_KEY}" ]] && [[ -s "${RAM_KEY}" ]]; then local created age cached_ttl created=$(stat -c %Y "${RAM_CACHE}" 2>/dev/null || echo 0) age=$(( now - created )) cached_ttl=$(grep '^# TTL_SECONDS=' "${RAM_CACHE}" 2>/dev/null | cut -d= -f2 || echo 3600) - if [[ "${cached_ttl}" -ne 0 ]] && (( age >= cached_ttl )); then log_warn "Время сессии истекло ($(( age / 60 )) мин >= $(( cached_ttl / 60 )) мин). Инвалидация кэша..." rm -f "${RAM_CACHE}" "${RAM_KEY}" @@ -22,30 +16,24 @@ load_secrets_to_ram() { return 0 fi fi - local ttl_seconds if [[ "${hours}" -eq 0 ]]; then ttl_seconds=0 else ttl_seconds=$(( hours * 3600 )) fi - - log_info "🔐 Вход в защищенный контур C2..." + log_info "🔐 Вход в защищенный контур Zarya..." read -s -p "Master Password: " KP_PASS echo "" - local yk_args=() if ykman info >/dev/null 2>&1; then yk_args=("-y" "2") log_info "YubiKey обнаружен. Приготовьтесь к аппаратному подтверждению (1 касание)..." fi - - # Атомарный 1-Touch экспорт всей базы KDBX в RAM (ровно 1 касание YubiKey на всю сессию) local tmp_dump="/dev/shm/.kdbx_dump_${now}_$$.xml" rm -f "${tmp_dump}" touch "${tmp_dump}" chmod 600 "${tmp_dump}" - if ! echo "${KP_PASS}" | keepassxc-cli export "${yk_args[@]}" "${KDBX_PATH}" -f xml > "${tmp_dump}" 2>/dev/null; then log_err "Ошибка расшифровки базы KDBX (неверный пароль или таймаут касания YubiKey)" rm -f "${tmp_dump}" @@ -53,8 +41,7 @@ load_secrets_to_ram() { return 1 fi unset KP_PASS - - python3 "${REPO_ROOT}/scripts/lib/kdbx_parser.py" "${tmp_dump}" "${RAM_CACHE}" "${RAM_KEY}" "${ttl_seconds}" "${PVE_ENDPOINT}" "${VAULT_ADDR}" + python3 "${ZARYA_DIR}/lib/kdbx_parser.py" "${tmp_dump}" "${RAM_CACHE}" "${RAM_KEY}" "${ttl_seconds}" "${PVE_ENDPOINT}" "${VAULT_ADDR}" rm -f "${tmp_dump}" log_ok "База расшифрована за 1 касание. Ключ и секреты в RAM (TTL: ${hours}ч)" } diff --git a/state/collect_state.sh b/state/collect_state.sh new file mode 100644 index 0000000..e06250e --- /dev/null +++ b/state/collect_state.sh @@ -0,0 +1,68 @@ +#!/bin/bash +set -uo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +STATE_DIR="${ZARYA_DIR}/state" +SNAPSHOTS_DIR="${STATE_DIR}/snapshots" +TARGET="${1:-all}" + +MODULES=( + "00_workstation.sh" + "01_pve.sh" + "02_vps.sh" + "03_vyos.sh" + "04_tier0.sh" + "05_k8s.sh" +) + +mkdir -p "${SNAPSHOTS_DIR}" + +generate_header() { + local mod_name="$1" + local timestamp branch short_hash commit_msg + timestamp=$(date -u +"%Y-%m-%d %H:%M:%S UTC") + branch=$(git -C "${ATLAS_DIR:-$HOME/Projects/atlas}" branch --show-current 2>/dev/null || echo "unknown") + short_hash=$(git -C "${ATLAS_DIR:-$HOME/Projects/atlas}" rev-parse --short HEAD 2>/dev/null || echo "none") + commit_msg=$(git -C "${ATLAS_DIR:-$HOME/Projects/atlas}" log -1 --format='%s' 2>/dev/null || echo "none") + cat < Сбор модуля: ${mod_name}..." + generate_header "${mod_name}" > "${tmp_file}" + if [[ -x "${script}" ]]; then + "${script}" >> "${tmp_file}" 2>&1 + else + bash "${script}" >> "${tmp_file}" 2>&1 + fi + mv "${tmp_file}" "${out_file}" +} + +if [[ "${TARGET}" == "all" ]]; then + echo "==> Сбор полного аудита Sovereign C2 в ${SNAPSHOTS_DIR}..." + for mod in "${MODULES[@]}"; do + run_single_module "${mod}" + done + echo "✔ Все модули телеметрии успешно сохранены." +else + case "${TARGET}" in + 00_workstation|workstation|host) run_single_module "00_workstation.sh" ;; + 01_pve|pve) run_single_module "01_pve.sh" ;; + 02_vps|vps) run_single_module "02_vps.sh" ;; + 03_vyos|vyos|net) run_single_module "03_vyos.sh" ;; + 04_tier0|tier0) run_single_module "04_tier0.sh" ;; + 05_k8s|k8s|talos) run_single_module "05_k8s.sh" ;; + *) + echo "Неизвестный модуль: ${TARGET}" + exit 1 + ;; + esac +fi \ No newline at end of file diff --git a/test b/test deleted file mode 100644 index e69de29..0000000 diff --git a/zarya-code.xml b/zarya-code.xml new file mode 100644 index 0000000..66c4745 --- /dev/null +++ b/zarya-code.xml @@ -0,0 +1,1181 @@ +This file is a merged representation of a subset of the codebase, containing specifically included files and files not matching ignore patterns, combined into a single document by Repomix. +The content has been processed where empty lines have been removed. + + +This section contains a summary of this file. + + +This file contains a packed representation of a subset of the repository's contents that is considered the most important context. +It is designed to be easily consumable by AI systems for analysis, code review, +or other automated processes. + + + +The content is organized as follows: +1. This summary section +2. Repository information +3. Directory structure +4. Repository files (if enabled) +5. Multiple file entries, each consisting of: + - File path as an attribute + - Full contents of the file + + + +- This file should be treated as read-only. Any changes should be made to the + original repository files, not this packed version. +- When processing this file, use the file path to distinguish + between different files in the repository. +- Be aware that this file may contain sensitive information. Handle it with + the same level of security as you would the original repository. + + + +- Some files may have been excluded based on .gitignore rules and Repomix's configuration +- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files +- Only files matching these patterns are included: bin/**, cmd/**, lib/**, layers/**, state/*.sh, config.env +- Files matching these patterns are excluded: state/snapshots/**, *.xml +- Files matching patterns in .gitignore are excluded +- Files matching default ignore patterns are excluded +- Empty lines have been removed from all files +- Files are sorted by Git change count (files with more changes are at the bottom) + + + + + +bin/ + zarya +cmd/ + a.sh + disks.sh + errors.sh + logs.sh + net.sh + pack.sh + pods.sh + run.sh + session.sh + snap.sh + unseal.sh + up.sh +layers/ + 00_host.sh + 01_net.sh + 02_tier0.sh + 03_talos.sh + 04_apps.sh + gc.sh + reset.sh +lib/ + common.sh + kdbx_parser.py + log.sh + net.sh + session.sh + vault.sh +state/ + 00_workstation.sh + 01_pve.sh + 02_vps.sh + 03_vyos.sh + 04_tier0.sh + 05_k8s.sh +config.env + + + +This section contains the contents of the repository's files. + + +#!/bin/bash +set -euo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" + +SUBCMD="${1:-help}" +shift || true + +case "${SUBCMD}" in + p|pod|pods) exec "${ZARYA_DIR}/cmd/pods.sh" "$@" ;; + e|err|errors) exec "${ZARYA_DIR}/cmd/errors.sh" "$@" ;; + l|log|logs) exec "${ZARYA_DIR}/cmd/logs.sh" "$@" ;; + n|net) exec "${ZARYA_DIR}/cmd/net.sh" "$@" ;; + d|df|disks) exec "${ZARYA_DIR}/cmd/disks.sh" "$@" ;; + unseal) exec "${ZARYA_DIR}/cmd/unseal.sh" "$@" ;; + login|start) exec "${ZARYA_DIR}/cmd/session.sh" "start" "$@" ;; + logout|clean) exec "${ZARYA_DIR}/cmd/session.sh" "clean" "$@" ;; + up) exec "${ZARYA_DIR}/cmd/up.sh" "$@" ;; + run) exec "${ZARYA_DIR}/cmd/run.sh" "$@" ;; + a|apply) exec "${ZARYA_DIR}/cmd/a.sh" "$@" ;; + snap) exec "${ZARYA_DIR}/cmd/snap.sh" "$@" ;; + pack) exec "${ZARYA_DIR}/cmd/pack.sh" "$@" ;; + reset|nuke) exec "${ZARYA_DIR}/layers/reset.sh" "$@" ;; + gc) exec "${ZARYA_DIR}/layers/gc.sh" "$@" ;; + help|--help|-h) + cat <] [-s ] [-A] Просмотр подов + z errors Мгновенный триаж сломанных сервисов + z logs [-f] [-t ] Логи любого сервиса без ввода неймспейса + z net Сетевой радар доступности узлов (1 сек) + z disks Срез пулов astra/terra и ZVOL томов K8s +Управление и сессия: + z login [TTL] Открытие смены (YubiKey + RAM) + z logout Мгновенная очистка RAM + z unseal Распечатывание OpenBao Vault +Деплой и IaC: + z up [layer] Макро-слои (host, net, tier0, talos, apps, all) + z run Плейбуки Ansible (01, 02) + z a [-auto-approve] OpenTofu apply в RAM-изоляции +Телеметрия и LLM: + z snap Снятие полного .md аудита в snapshots/ + z pack [code|state|atlas] Сборка контекста Repomix +EOF + ;; + *) + log_err "Неизвестная команда: ${SUBCMD}. Введите 'z help'." + exit 1 + ;; +esac + + + +#!/bin/bash +set -euo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" +unseal_vault +run_isolated bash -c "cd '${REPO_ROOT}/tofu' && tofu apply $*" + + + +#!/bin/bash +set -uo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" +echo -e "${BLUE}=== ФИЗИЧЕСКИЕ ПУЛЫ ХОСТА PROXMOX (ZFS) ===${NC}" +ssh -n -o BatchMode=yes -o ConnectTimeout=2 proxmox "zpool list -o name,size,alloc,free,cap,health" 2>/dev/null || log_err "PVE недоступен" +echo "" +echo -e "${BLUE}=== ПОЛЬЗОВАТЕЛЬСКИЕ ДАТАСЕТЫ TIER-0 (/astra/data) ===${NC}" +ssh -n -o BatchMode=yes -o ConnectTimeout=2 proxmox "zfs list -o name,used,avail,refer,mountpoint -r astra/data" 2>/dev/null || true +echo "" +echo -e "${BLUE}=== ТОМА ДИСКОВ KUBERNETES (ZVOL) ===${NC}" +kubectl get pvc -A -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name,STATUS:.status.phase,VOLUME:.spec.volumeName,SIZE:.status.capacity.storage 2>/dev/null || log_err "K8s API недоступен" + + + +#!/bin/bash +set -uo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" +has_errors=false +echo -e "${YELLOW}=== ТРИАЖ АВАРИЙ И СБОЕВ (K8s / Host / VyOS) ===${NC}" +bad_pods=$(kubectl get pods -A --field-selector=status.phase!=Running,status.phase!=Succeeded --no-headers 2>/dev/null | grep -v 'Completed' || true) +if [[ -n "${bad_pods}" ]]; then + has_errors=true + echo -e "${RED}[K8S] Проблемные поды:${NC}" + echo "${bad_pods}" | awk '{printf " %-16s %-36s %s\n", $1, $2, $3}' +fi +pve_failed=$(ssh -n -o BatchMode=yes -o ConnectTimeout=1 proxmox "systemctl --failed --no-legend --plain" 2>/dev/null || echo "UNREACHABLE") +if [[ "${pve_failed}" == "UNREACHABLE" ]]; then + has_errors=true + echo -e "${RED}[PVE] Гипервизор недоступен по SSH${NC}" +elif [[ -n "${pve_failed}" ]]; then + has_errors=true + echo -e "${RED}[PVE] Упавшие systemd-сервисы:${NC}" + echo "${pve_failed}" | awk '{print " " $1}' +fi +vyos_failed=$(ssh -n -o BatchMode=yes -o ConnectTimeout=1 vyos_router "systemctl --failed --no-legend --plain" 2>/dev/null || echo "UNREACHABLE") +if [[ "${vyos_failed}" == "UNREACHABLE" ]]; then + has_errors=true + echo -e "${RED}[VyOS] Роутер недоступен по SSH${NC}" +elif [[ -n "${vyos_failed}" ]]; then + has_errors=true + echo -e "${RED}[VyOS] Упавшие systemd-сервисы:${NC}" + echo "${vyos_failed}" | awk '{print " " $1}' +fi +if [[ "$has_errors" == false ]]; then + echo -e "${GREEN}✔ Все системы в норме. Сбоев не обнаружено.${NC}" +fi + + + +#!/bin/bash +set -uo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" +query="${1:-}" +if [[ -z "${query}" ]]; then + log_err "Использование: z logs <сервис> [-f] [-t <строки>]" + exit 1 +fi +shift +follow_arg="" +tail_val="50" +while [[ $# -gt 0 ]]; do + case "$1" in + -f|--follow) follow_arg="-f"; shift ;; + -t|--tail) tail_val="$2"; shift 2 ;; + *) shift ;; + esac +done +pod_info=$(kubectl get pods -A --no-headers 2>/dev/null | awk -v q="${query}" 'tolower($1) ~ tolower(q) || tolower($2) ~ tolower(q) {print $1, $2; exit}') +if [[ -z "${pod_info}" ]]; then + log_err "Под с именем '${query}' не найден ни в одном namespace." + exit 1 +fi +ns=$(echo "${pod_info}" | awk '{print $1}') +pod=$(echo "${pod_info}" | awk '{print $2}') +log_info "Логи ${ns}/${pod} (tail: ${tail_val}):" +exec kubectl logs -n "${ns}" "${pod}" --tail="${tail_val}" ${follow_arg} + + + +#!/bin/bash +set -uo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" +echo -e "${BLUE}=== СЕТЕВОЙ РАДАР ИНФРАСТРУКТУРЫ (Таймаут 1 сек) ===${NC}" +printf "%-22s %-20s %-12s %s\n" "УЗЕЛ" "АДРЕС" "СТАТУС" "ЗАДЕРЖКА" +echo "------------------------------------------------------------------" +check_target() { + local name="$1" + local host="$2" + local port="$3" + local start end dur + start=$(date +%s%N) + if nc -z -w 1 "${host}" "${port}" 2>/dev/null; then + end=$(date +%s%N) + dur=$(( (end - start) / 1000000 )) + printf "%-22s %-20s \033[32m%-12s\033[0m %d ms\n" "${name}" "${host}:${port}" "UP" "${dur}" + else + printf "%-22s %-20s \033[31m%-12s\033[0m -\n" "${name}" "${host}:${port}" "DOWN" + fi +} +check_target "Proxmox Host (PVE)" "192.168.1.177" 8006 +check_target "Edge Router (VyOS)" "192.168.1.2" 22 +check_target "Technitium DNS" "10.0.10.11" 53 +check_target "OpenBao Vault" "10.0.10.12" 8200 +check_target "Forgejo GitOps" "10.0.10.13" 3000 +check_target "NFS Storage (NAS)" "10.0.10.14" 2049 +check_target "Traefik L2 VIP" "10.0.30.200" 443 +check_target "Perimeter VPS" "153.76.194.24" 443 + + + +#!/bin/bash +set -euo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +mode="${1:-state}" +case "${mode}" in + state) + echo "==> Снятие свежего аудита..." + "${ZARYA_DIR}/state/collect_state.sh" all >/dev/null 2>&1 || true + echo "==> Упаковка среза состояния Repomix (zarya-state.xml)..." + repomix --config "${ZARYA_DIR}/repomix.state.json" + echo "✔ Файл zarya-state.xml готов для отправки в LLM." + ;; + code) + echo "==> Упаковка кодовой базы zarya (zarya-code.xml)..." + repomix --config "${ZARYA_DIR}/repomix.config.json" + echo "✔ Файл zarya-code.xml готов." + ;; + atlas) + echo "==> Упаковка чистой инфраструктуры atlas (atlas-code.xml)..." + cd "${ATLAS_DIR}" && repomix + echo "✔ Файл atlas/repomix-output.xml готов." + ;; + *) + echo "Использование: z pack [state|code|atlas]" + exit 1 + ;; +esac + + + +#!/bin/bash +set -u +watch_mode=false +ns_filter="" +query="" +all_namespaces=false +while [[ $# -gt 0 ]]; do + case "$1" in + -w|--watch) watch_mode=true; shift ;; + -n|--namespace) ns_filter="$2"; shift 2 ;; + -s|--service) query="$2"; shift 2 ;; + -A|--all) all_namespaces=true; shift ;; + all) all_namespaces=true; shift ;; + *) query="$1"; shift ;; + esac +done +render_pods() { + local raw + if [[ "$all_namespaces" == true ]]; then + raw=$(kubectl get pods -A -o wide 2>/dev/null || true) + elif [[ -n "$ns_filter" ]]; then + raw=$(kubectl get pods -n "$ns_filter" -o wide 2>/dev/null || true) + elif [[ -n "$query" ]]; then + raw=$(kubectl get pods -A -o wide 2>/dev/null | awk -v q="$query" 'NR==1 || tolower($1) ~ tolower(q) || tolower($2) ~ tolower(q)' || true) + else + raw=$(kubectl get pods -A -o wide 2>/dev/null | awk 'NR==1 || ($1 !~ /^(kube-system|flux-system|cert-manager|external-secrets)$/ && $4 != "Completed")' || true) + fi + echo "$raw" | awk ' + BEGIN { + ERR = "\033[38;2;255;46;76m" + RUN = "\033[38;2;180;190;254m" + WARN = "\033[38;2;250;179;135m" + HEAD = "\033[38;2;147;154;183m" + RST = "\033[0m" + } + NR==1 { print HEAD $0 RST; next } + { + if ($0 ~ /CrashLoopBackOff|Error|OOMKilled|ImagePullBackOff/) { print ERR $0 RST } + else if ($0 ~ /ContainerCreating|Pending|Terminating|Init:/ || ($0 ~ /Running/ && $2 ~ /^0\//)) { print WARN $0 RST } + else if ($0 ~ /Running/) { print RUN $0 RST } + else { print $0 } + }' +} +if [[ "$watch_mode" == true ]]; then + trap 'tput cnorm 2>/dev/null || true; echo ""; exit 0' INT TERM + tput civis 2>/dev/null || true + clear + while true; do + tput cup 0 0 2>/dev/null || true + render_pods + tput ed 2>/dev/null || true + sleep 1 + done +else + render_pods +fi + + + +#!/bin/bash +set -euo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" +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}" +} +if [[ $# -eq 0 ]] || [[ "${1:-}" == "list" ]]; then + echo -e "${BLUE}=== Каталог плейбуков (${REPO_ROOT}/ansible/playbooks/) ===${NC}" + for pb in $(ls -1 "${REPO_ROOT}/ansible/playbooks"/[0-9][0-9]_*.yml 2>/dev/null | sort); do + echo " $(basename "${pb}")" + done + exit 0 +fi +for id in "$@"; do + pb_path=$(resolve_playbook "${id}") + log_info "==> Исполнение: $(basename "${pb_path}")..." + run_isolated ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${pb_path}" +done +log_ok "Плейбуки выполнены." + + + +#!/bin/bash +set -euo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" +action="${1:-start}" +shift || true +case "${action}" in + start|login) + hours="${1:-1}" + ensure_prerequisites + load_secrets_to_ram "${hours}" + unseal_vault + log_ok "Сессия Zarya активна (TTL: ${hours} ч)." + ;; + clean|logout) + rm -f "${RAM_CACHE}" /dev/shm/.atlas_core + log_ok "RAM-кэш и ключи уничтожены." + ;; +esac + + + +#!/bin/bash +set -uo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +target="${1:-all}" +"${ZARYA_DIR}/state/collect_state.sh" "${target}" + + + +#!/bin/bash +set -euo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" +ensure_prerequisites +unseal_vault + + + +#!/bin/bash +set -euo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ZARYA_DIR}/lib/common.sh" +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 "Инфраструктура Atlas развернута." + ;; + *) + log_err "Неизвестный слой: ${target}. Доступны: host, net, tier0, talos, apps, all" + exit 1 + ;; +esac + + + +#!/bin/bash +set -euo pipefail +source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" +ensure_prerequisites +load_secrets_to_ram +log_info "[Layer 0: PVE Host] Подготовка хоста, шаблонов и базовых директорий ZFS..." +ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/01_pve_host_day0.yml" +log_info "[Layer 0: PVE Host] Инициализация compute-скелетов ВМ и LXC через OpenTofu..." +cd "${REPO_ROOT}/tofu" && tofu apply \ + -target=proxmox_virtual_environment_vm.vyos_router \ + -target=proxmox_virtual_environment_container.dns0 \ + -target=proxmox_virtual_environment_container.vault0 \ + -target=proxmox_virtual_environment_container.git0 \ + -target=proxmox_virtual_environment_container.storage0 \ + -target=proxmox_virtual_environment_container.registry0 \ + -target=proxmox_virtual_environment_vm.talos_master_1 \ + -target=proxmox_virtual_environment_vm.talos_worker_1 \ + -target=proxmox_virtual_environment_vm.talos_worker_2 \ + -auto-approve +log_info "[Layer 0: PVE Host] Применение постоянных ZFS-маунтов (mp) на созданные LXC..." +ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/01_pve_host_day0.yml" +log_ok "Layer 0 готов: хост настроен, ВМ и LXC созданы, ZFS смонтирован." + + + +#!/bin/bash +set -euo pipefail +source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" +ensure_prerequisites +load_secrets_to_ram +log_info "[Layer 1: VyOS & Perimeter] Накатка конфигурации сети..." +ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/02_vyos_network_day0.yml" +log_ok "Layer 1 готов." + + + +#!/bin/bash +set -euo pipefail +source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" +ensure_prerequisites +load_secrets_to_ram +log_info "[Layer 2: Tier-0 Air-Gap] Развертывание базовой инфраструктуры (Registry, DNS, Vault)..." +for pb in 03_zot_registry.yml 04_technitium_dns.yml 05_openbao_vault.yml; do + ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/${pb}" +done +log_info "[Layer 2: Tier-0 Air-Gap] Распечатывание OpenBao Vault..." +unseal_vault +log_info "[Layer 2: Tier-0 Air-Gap] Наполнение Vault секретами через OpenTofu..." +cd "${REPO_ROOT}/tofu" && tofu apply -auto-approve +log_info "[Layer 2: Tier-0 Air-Gap] Развертывание зависимых сервисов (Forgejo, NAS Storage)..." +for pb in 06_forgejo_git.yml 07_nas_storage.yml; do + ansible-playbook -i "${REPO_ROOT}/ansible/inventory.yml" "${REPO_ROOT}/ansible/playbooks/${pb}" +done +log_info "[Layer 2: Tier-0 Air-Gap] Автоматическая первичная синхронизация Git в Forgejo (SEC-03 RAM auth)..." +CURRENT_BRANCH=$(git -C "${REPO_ROOT}" branch --show-current 2>/dev/null || echo "master") +git -C "${REPO_ROOT}" push -u http://10.0.10.13:3000/atlas/atlas.git "${CURRENT_BRANCH}" 2>/dev/null || \ + git -C "${REPO_ROOT}" push http://10.0.10.13:3000/atlas/atlas.git "${CURRENT_BRANCH}" 2>/dev/null || true +log_ok "Layer 2 готов. Базовые сервисы, секреты и GitOps-репозиторий развернуты." + + + +#!/bin/bash +set -euo pipefail +source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" +ensure_prerequisites +load_secrets_to_ram +unseal_vault +log_info "[Layer 3: Talos & Kubernetes] Проверка конфигураций машинных манифестов..." +if [[ ! -f "${REPO_ROOT}/talos/clusterconfig/controlplane.yaml" ]]; then + log_info "Генерация машинных конфигураций Talos..." + cd "${REPO_ROOT}" && talos/generate_config.sh +fi +log_info "[Layer 3: Talos & Kubernetes] Бутстрап кластера..." +cd "${REPO_ROOT}/talos" && ./bootstrap.sh +sync_k8s_vault_token +log_ok "Layer 3 готов." + + + +#!/bin/bash +set -euo pipefail +source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" +ensure_prerequisites +log_info "[Layer 4: Apps] Применение манифестов FluxCD..." +kubectl apply -f "${REPO_ROOT}/kubernetes/bootstrap/sync.yaml" +log_ok "Layer 4 готов." + + + +#!/bin/bash +set -uo pipefail +source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" +ensure_prerequisites +log_info "🧹 Запуск генеральной очистки кластера (dep gc)..." +# 1. Удаление зомби-нод в статусе NotReady +NOT_READY_NODES=$(kubectl get nodes --no-headers 2>/dev/null | grep 'NotReady' | awk '{print $1}' || true) +if [[ -n "${NOT_READY_NODES}" ]]; then + for node in ${NOT_READY_NODES}; do + log_warn "Удаляем мертвую ноду: ${node}" + kubectl delete node "${node}" --timeout=5s 2>/dev/null || true + done +fi +# 2. Мгновенная зачистка зависших в Terminating +kubectl get pods -A --no-headers 2>/dev/null | awk '/Terminating/ {print $1, $2}' | while read -r ns pod; do + log_warn "Принудительно удаляем: ${ns}/${pod}" + kubectl -n "${ns}" delete pod "${pod}" --force --grace-period=0 2>/dev/null || true +done +# 3. Сброс бэкоффа для упавших подов (CrashLoopBackOff, Error, OOMKilled, CreateContainerConfigError) +kubectl get pods -A --no-headers 2>/dev/null | grep -E 'CrashLoopBackOff|Error|OOMKilled|CreateContainerConfigError|ImagePullBackOff' | awk '{print $1, $2}' | while read -r ns pod; do + log_info "Сбрасываем упавший под: ${ns}/${pod}" + kubectl -n "${ns}" delete pod "${pod}" --force --grace-period=0 2>/dev/null || true +done +# 4. Очистка завершенных одноразовых Job +COMPLETED_JOBS=$(kubectl get jobs -A --field-selector status.successful=1 --no-headers 2>/dev/null | awk '{print $1, $2}' || true) +if [[ -n "${COMPLETED_JOBS}" ]]; then + echo "${COMPLETED_JOBS}" | while read -r ns job; do + kubectl -n "${ns}" delete job "${job}" >/dev/null 2>&1 || true + done +fi +log_ok "Кластер очищен. Все сервисы пересоздаются против живых БД и NFS." + + + +#!/bin/bash +set -euo pipefail +source "$(dirname "${BASH_SOURCE[0]}")/../lib/common.sh" +RESET_WIPE_HISTORY="${RESET_WIPE_HISTORY:-false}" +log_warn "ВНИМАНИЕ! Инициирована процедура полного уничтожения инфраструктуры Proxmox VE." +log_info "Очистка текущей RAM-сессии. Требуется физическая повторная аутентификация..." +rm -f "${RAM_CACHE}" /dev/shm/.atlas_core +read -s -p "Master Password для подтверждения сноса: " KP_PASS +echo "" +yk_args=() +if ykman info >/dev/null 2>&1; then + yk_args=("-y" "2") + log_info "Приготовьтесь к аппаратному подтверждению (касание YubiKey)..." +fi +tmp_verify="/dev/shm/.verify_$$" +if ! echo "${KP_PASS}" | timeout 15 keepassxc-cli export "${yk_args[@]}" "${KDBX_PATH}" -f xml > "${tmp_verify}" 2>/dev/null; then + log_err "Аппаратная проверка провалена или таймаут касания. Доступ заблокирован." + rm -f "${tmp_verify}" + unset KP_PASS + if [[ "${RESET_WIPE_HISTORY}" == "true" ]]; then + history -c 2>/dev/null || true + fi + exit 1 +fi +rm -f "${tmp_verify}" +unset KP_PASS +log_ok "Аппаратная проверка YubiKey и пароля подтверждена." +read -r -p "Введите 'CONFIRM-DESTRUCTION' для безвозвратного уничтожения: " confirm +if [[ "${confirm}" != "CONFIRM-DESTRUCTION" ]]; then + log_warn "Отмена операции." + exit 0 +fi +log_info "Снятие защиты и уничтожение виртуальных машин и контейнеров на Proxmox..." +ssh proxmox bash << 'SSHEOF' +for id in 100 201 202 203; do + qm stop $id --skiplock 1 2>/dev/null || true + qm destroy $id --purge 1 --destroy-unreferenced-disks 1 2>/dev/null || true +done +for id in 101 102 103 104 105; do + pct set $id -protection 0 2>/dev/null || true + pct stop $id --skiplock 1 2>/dev/null || true + pct destroy $id --purge 1 --force 1 2>/dev/null || true +done +SSHEOF +log_info "Очистка локального стейта OpenTofu..." +rm -f "${REPO_ROOT}/tofu/terraform.tfstate"* "${REPO_ROOT}/tofu/.terraform.tfstate.lock.info" +rm -f "${RAM_CACHE}" /dev/shm/.atlas_core +if [[ "${RESET_WIPE_HISTORY}" == "true" ]]; then + history -c 2>/dev/null || true +fi +log_ok "Сервер зачищен до голого железа." + + + +#!/bin/bash +set -euo pipefail +ZARYA_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +export ATLAS_DIR="${ATLAS_DIR:-$HOME/Projects/atlas}" +export REPO_ROOT="${ATLAS_DIR}" +source "${ZARYA_DIR}/config.env" 2>/dev/null || true +source "${ZARYA_DIR}/lib/log.sh" +source "${ZARYA_DIR}/lib/net.sh" +source "${ZARYA_DIR}/lib/vault.sh" +source "${ZARYA_DIR}/lib/session.sh" + + + +import sys +import xml.etree.ElementTree as ET +import os +dump_file = sys.argv[1] +cache_file = sys.argv[2] +key_file = sys.argv[3] +ttl_sec = sys.argv[4] +pve_endpoint = sys.argv[5] +vault_addr = sys.argv[6] +tree = ET.parse(dump_file) +root = tree.getroot() +for h in root.findall(".//History"): + h.clear() +for g in root.findall(".//Group"): + name = g.find("./Name") + if name is not None and name.text == "Recycle Bin": + g.clear() +entries = {} +for entry in root.findall(".//Entry"): + title = "" + username = "" + password = "" + notes = "" + for string in entry.findall("./String"): + key_elem = string.find("./Key") + val_elem = string.find("./Value") + if key_elem is not None and val_elem is not None and key_elem.text: + k = key_elem.text + v = val_elem.text or "" + if k == "Title": title = v.strip() + elif k == "UserName": username = v.strip() + elif k == "Password": password = v.strip() + elif k == "Notes": notes = v.strip() + if title and title not in entries: + entries[title] = { + "username": username, + "password": password, + "notes": notes + } +ssh_loaded = False +for title in ("Atlas Core Key", "AtlasCoreKey", "Atlas Core"): + entry_data = entries.get(title, {}) + for field in ("password", "notes"): + val = entry_data.get(field, "") + if "-----BEGIN" in val or "PRIVATE KEY" in val: + with open(key_file, "w") as kf: + kf.write(val.strip() + "\n") + os.chmod(key_file, 0o600) + ssh_loaded = True + break + if ssh_loaded: + break +if not ssh_loaded: + sys.stderr.write("Внимание: приватный SSH-ключ не найден в полях Password/Notes записи Atlas Core Key.\n") +with open(cache_file, "w") as f: + f.write(f"# TTL_SECONDS={ttl_sec}\n") + f.write(f"export PROXMOX_VE_API_TOKEN={repr(entries.get('ProxmoxAPI', {}).get('password', ''))}\n") + f.write(f"export TF_VAR_proxmox_api_token={repr(entries.get('ProxmoxAPI', {}).get('password', ''))}\n") + f.write(f"export TF_VAR_state_passphrase={repr(entries.get('TofuState', {}).get('password', ''))}\n") + f.write(f"export PROXMOX_VE_ENDPOINT={repr(pve_endpoint)}\n") + f.write(f"export VAULT_ADDR={repr(vault_addr)}\n") + f.write(f"export VAULT_TOKEN={repr(entries.get('OpenBaoToken', {}).get('password', ''))}\n") + f.write(f"export VAULT_UNSEAL_KEY={repr(entries.get('OpenBaoUnseal', {}).get('password', ''))}\n") + f.write(f"export TECHNITIUM_PASSWORD={repr(entries.get('Technitium', {}).get('password', 'admin'))}\n") + f.write(f"export TF_VAR_vaultwarden_admin_token={repr(entries.get('VaultwardenAdmin', {}).get('password', ''))}\n") + f.write(f"export TF_VAR_forgejo_runner_token={repr(entries.get('ForgejoRunnerToken', {}).get('password', ''))}\n") + f.write(f"export TF_VAR_forgejo_oidc_client_id={repr(entries.get('ForgejoOIDC', {}).get('username', 'forgejo'))}\n") + f.write(f"export TF_VAR_forgejo_oidc_secret={repr(entries.get('ForgejoOIDC', {}).get('password', ''))}\n") + f.write(f"export ATLAS_PUSH_TOKEN={repr(entries.get('AtlasPushToken', {}).get('password', ''))}\n") + f.write(f"export VYOS_WG_PRIVATE_KEY={repr(entries.get('VyosWG', {}).get('password', ''))}\n") +os.chmod(cache_file, 0o600) + + + +#!/bin/bash +# Log formatting and color definitions +RED='\033[0;31m' +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +NC='\033[0m' +log_info() { echo -e "${BLUE}==>${NC} $*"; } +log_ok() { echo -e "${GREEN}✔${NC} $*"; } +log_warn() { echo -e "${YELLOW}⚠${NC} $*"; } +log_err() { echo -e "${RED}✖${NC} $*"; } + + + +#!/bin/bash +# Network routing and terminal prerequisites +ensure_prerequisites() { + local target_ip="${VAULT_ADDR#*//}" + target_ip="${target_ip%%:*}" + if ! ip route get "${target_ip}" 2>/dev/null | grep -q "${VYOS_ROUTER_IP}"; then + log_info "Восстанавливаем маршрут к ${NET_PREFIX} через VyOS (${VYOS_ROUTER_IP})..." + sudo ip route replace "${NET_PREFIX}" via "${VYOS_ROUTER_IP}" 2>/dev/null || true + fi + # Регистрация Git Credential Helper (доменный и прямой IP Tier-0) + local target_helper="!${REPO_ROOT}/deploy.sh git-credential" + local current_helper + current_helper=$(git config --global --get credential."https://${GIT_HOST}".helper 2>/dev/null || true) + if [[ "${current_helper}" != "${target_helper}" ]]; then + git config --global credential."https://${GIT_HOST}".helper "${target_helper}" + fi + local direct_helper + direct_helper=$(git config --global --get credential."http://10.0.10.13:3000".helper 2>/dev/null || true) + if [[ "${direct_helper}" != "${target_helper}" ]]; then + git config --global credential."http://10.0.10.13:3000".helper "${target_helper}" + fi + # Нативная привязка IdentityFile для всех C2-хостов и LXC-контейнеров + local ssh_hosts="proxmox pve0 vyos vyos_router 10.0.* dns0 vault0 git0 storage0 registry0" + if [[ -f "${HOME}/.ssh/config" ]] && ! grep -q "IdentityFile ${RAM_KEY}" "${HOME}/.ssh/config"; then + printf "\nHost %s\n IdentityFile %s\n IdentitiesOnly yes\n" "${ssh_hosts}" "${RAM_KEY}" >> "${HOME}/.ssh/config" + fi +} + + + +#!/bin/bash +# Session state in RAM tmpfs and YubiKey integration +load_secrets_to_ram() { + local hours="${1:-$DEFAULT_SESSION_TTL}" + local now + now=$(date +%s) + ensure_prerequisites + # Валидация сессии по наличию непустых кэша секретов и SSH-ключа + if [[ -f "${RAM_CACHE}" ]] && [[ -f "${RAM_KEY}" ]] && [[ -s "${RAM_KEY}" ]]; then + local created age cached_ttl + created=$(stat -c %Y "${RAM_CACHE}" 2>/dev/null || echo 0) + age=$(( now - created )) + cached_ttl=$(grep '^# TTL_SECONDS=' "${RAM_CACHE}" 2>/dev/null | cut -d= -f2 || echo 3600) + if [[ "${cached_ttl}" -ne 0 ]] && (( age >= cached_ttl )); then + log_warn "Время сессии истекло ($(( age / 60 )) мин >= $(( cached_ttl / 60 )) мин). Инвалидация кэша..." + rm -f "${RAM_CACHE}" "${RAM_KEY}" + else + return 0 + fi + fi + local ttl_seconds + if [[ "${hours}" -eq 0 ]]; then + ttl_seconds=0 + else + ttl_seconds=$(( hours * 3600 )) + fi + log_info "🔐 Вход в защищенный контур C2..." + read -s -p "Master Password: " KP_PASS + echo "" + local yk_args=() + if ykman info >/dev/null 2>&1; then + yk_args=("-y" "2") + log_info "YubiKey обнаружен. Приготовьтесь к аппаратному подтверждению (1 касание)..." + fi + # Атомарный 1-Touch экспорт всей базы KDBX в RAM (ровно 1 касание YubiKey на всю сессию) + local tmp_dump="/dev/shm/.kdbx_dump_${now}_$$.xml" + rm -f "${tmp_dump}" + touch "${tmp_dump}" + chmod 600 "${tmp_dump}" + if ! echo "${KP_PASS}" | keepassxc-cli export "${yk_args[@]}" "${KDBX_PATH}" -f xml > "${tmp_dump}" 2>/dev/null; then + log_err "Ошибка расшифровки базы KDBX (неверный пароль или таймаут касания YubiKey)" + rm -f "${tmp_dump}" + unset KP_PASS + return 1 + fi + unset KP_PASS + python3 "${REPO_ROOT}/scripts/lib/kdbx_parser.py" "${tmp_dump}" "${RAM_CACHE}" "${RAM_KEY}" "${ttl_seconds}" "${PVE_ENDPOINT}" "${VAULT_ADDR}" + rm -f "${tmp_dump}" + log_ok "База расшифрована за 1 касание. Ключ и секреты в RAM (TTL: ${hours}ч)" +} +run_isolated() { + ensure_prerequisites + load_secrets_to_ram + ( + set -a + source "${RAM_CACHE}" + set +a + "$@" + ) +} + + + +#!/bin/bash +# OpenBao Vault operations and Kubernetes Secret synchronization +sync_k8s_vault_token() { + if kubectl --request-timeout=2s cluster-info >/dev/null 2>&1; then + log_info "Синхронизация токена OpenBao в Kubernetes..." + local bao_tok + bao_tok=$(grep '^export VAULT_TOKEN=' "${RAM_CACHE}" 2>/dev/null | cut -d= -f2- | tr -d '"'"'") + if [[ -n "${bao_tok}" ]]; then + kubectl create namespace external-secrets --dry-run=client -o yaml | kubectl apply -f - >/dev/null 2>&1 || true + kubectl -n external-secrets create secret generic openbao-token \ + --from-literal=token="${bao_tok}" \ + --dry-run=client -o yaml | kubectl apply -f - >/dev/null 2>&1 + kubectl -n external-secrets rollout restart deployment external-secrets >/dev/null 2>&1 || true + log_ok "Токен OpenBao в Kubernetes актуализирован." + fi + fi +} +unseal_vault() { + local unseal_key target_vault_addr seal_status resp + unseal_key=$(grep '^export VAULT_UNSEAL_KEY=' "${RAM_CACHE}" 2>/dev/null | cut -d= -f2- | tr -d '"'"'") + target_vault_addr=$(grep '^export VAULT_ADDR=' "${RAM_CACHE}" 2>/dev/null | cut -d= -f2- | tr -d '"'"'") + target_vault_addr="${target_vault_addr:-$VAULT_ADDR}" + seal_status=$(curl -s --connect-timeout 2 "${target_vault_addr}/v1/sys/seal-status" 2>/dev/null || echo "") + if [[ -z "${seal_status}" ]]; then + log_warn "OpenBao (${target_vault_addr}) недоступен. Пропуск ансила." + return 0 + fi + if echo "${seal_status}" | grep -q '"sealed":true'; then + log_info "OpenBao запечатан. Ансил..." + resp=$(printf '{"key":"%s"}' "${unseal_key}" | curl -s -X POST -H "Content-Type: application/json" --data-binary @- "${target_vault_addr}/v1/sys/unseal") + if echo "${resp}" | grep -q '"sealed":false'; then + log_ok "OpenBao успешно распечатан." + sync_k8s_vault_token + else + log_err "Ошибка ансила OpenBao: ${resp}" + return 1 + fi + else + log_ok "OpenBao распечатан." + sync_k8s_vault_token + fi +} + + + +#!/bin/bash +set -uo pipefail +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +echo "## 0. Рабочая станция администратора (Operator Environment)" +echo "### Инфраструктурные SSH-хосты (~/.ssh/config):" +echo '```text' +if [[ -f ~/.ssh/config ]]; then + awk '/^Host (router|proxmox|vyos|10\.|fin21|ded|incserv)/, /^$/' ~/.ssh/config +else + echo "Файл ~/.ssh/config не найден" +fi +echo '```' +echo "### Рабочие алиасы и функции оператора (Active Workflow Aliases):" +echo '```bash' +if [[ -f ~/.bashrc ]] && grep -q '# >>> ATLAS C2 WORKFLOW >>>' ~/.bashrc; then + sed -n '/# >>> ATLAS C2 WORKFLOW >>>/,/# <<< ATLAS C2 WORKFLOW <<>>' +else + echo "# Маркер # >>> ATLAS C2 WORKFLOW >>> не найден в ~/.bashrc" +fi +echo '```' +echo "### Статус RAM-кэша секретов (/dev/shm/.atlas_secrets_cache):" +echo '```text' +if [[ -f /dev/shm/.atlas_secrets_cache ]]; then + stat -c "Размер: %s байт | Права: %a | Создан: %y" /dev/shm/.atlas_secrets_cache +else + echo "Кэш секретов в RAM отсутствует" +fi +echo '```' +echo "### Проверка Git Credential Helper (git.svo88.space):" +echo '```text' +printf "protocol=https\nhost=git.svo88.space\n" | git credential fill 2>&1 | awk -F= '/^username/ {print "Username:", $2} /^password/ {print "Password: [PRESENT in RAM]"}' || echo "Credential helper не вернул учетных данных" +echo '```' +echo "### Ядро, память, ZRAM и параметры Coredump:" +echo '```text' +echo -n "Kernel: "; uname -r +echo -n "Swapon: "; swapon --show 2>&1 || echo "swapon недоступен" +zramctl 2>&1 || echo "zramctl недоступен" +echo "Coredump config:" +cat /etc/systemd/coredump.conf.d/*.conf 2>/dev/null || grep -E "Storage|ProcessSizeMax" /etc/systemd/coredump.conf 2>/dev/null || echo "Дефолтная конфигурация coredump" +echo '```' +echo "### Токены безопасности и ключи в ssh-agent:" +echo '```text' +echo "Active SSH Agent keys:" +ssh-add -l 2>&1 || true +echo "YubiKey / FIDO2 Status:" +ykman info 2>/dev/null || echo "Токен YubiKey не обнаружен" +echo '```' +echo "### Зеркала пакетов Pacman (Mirrorlist):" +echo '```text' +grep -E "^Server|^\[" /etc/pacman.conf /etc/pacman.d/* 2>/dev/null | head -n 15 || echo "Нет данных о зеркалах" +echo '```' +echo "### Маршрутизация на хосте (Routing to C2):" +echo '```text' +ip route show | grep -E "10.0.|192.168." || echo "Маршруты к ЦОД не обнаружены" +echo '```' +echo "### Версии локальных инструментов:" +echo '```text' +echo -n "OpenTofu: "; tofu version 2>/dev/null | head -n1 || echo "not installed" +echo -n "Kubectl: "; kubectl version --client -o yaml 2>/dev/null | grep gitVersion | head -n1 || echo "not installed" +echo -n "Talosctl: "; talosctl version --client --short 2>/dev/null || echo "not installed" +echo '```' +echo "### Состояние локального Git-репозитория (SSOT Source):" +echo '```text' +git -C "${REPO_ROOT}" status -sb +echo "Последний коммит: $(git -C "${REPO_ROOT}" log -1 --format='%h - %s (%cr)')" +echo "Remote URL: $(git -C "${REPO_ROOT}" remote -v 2>/dev/null | head -n1 | awk '{print $1, $2}' || echo 'no remote')" +echo '```' +echo "---" + + + +#!/bin/bash +set -uo pipefail +SSH_CMD="ssh -n -o BatchMode=yes -o ConnectTimeout=3 proxmox" +echo "## 1. Гипервизор Proxmox VE (192.168.1.177)" +echo "### Память хоста, Uptime и Температура CPU:" +echo '```text' +timeout 4s ${SSH_CMD} "uptime; echo ''; free -h; echo ''; sensors 2>/dev/null | grep -E 'Tctl|Package|temp1' || cat /sys/class/thermal/thermal_zone*/temp 2>/dev/null | awk '{print \"CPU Temp: \" \$1/1000 \"°C\"}'" 2>&1 || echo "PVE недоступен" +echo '```' +echo "### Здоровье физических дисков (SMART):" +echo '```text' +timeout 5s ${SSH_CMD} "for d in sda sdb sdc sdd sde sdf; do echo -n \"/dev/\$d: \"; smartctl -H /dev/\$d 2>/dev/null | grep -E 'result|PASSED|FAILED' || echo 'N/A'; done" 2>&1 || echo "SMART недоступен" +echo '```' +echo "### Статус шифрования ZFS (Encryption & Keys):" +echo '```text' +timeout 4s ${SSH_CMD} "zfs get encryption,keystatus,keyformat,keylocation astra terra 2>/dev/null" 2>&1 || echo "Ошибка сбора шифрования ZFS" +echo '```' +echo "### Здоровье и емкость ZFS-пулов:" +echo '```text' +timeout 4s ${SSH_CMD} "zpool list -o name,size,alloc,free,frag,cap,health; echo ''; zfs list -o name,used,avail,refer,mountpoint -r astra terra" 2>&1 || echo "Ошибка сбора ZFS" +echo '```' +echo "### Физическая емкость каталогов на /terra:" +echo '```text' +timeout 5s ${SSH_CMD} "du -sh /terra/* 2>/dev/null" 2>&1 || echo "Ошибка чтения /terra" +echo '```' +echo "### Блочные устройства хоста и тома ZVOL (lsblk):" +echo '```text' +timeout 4s ${SSH_CMD} "lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINTS" 2>&1 || echo "Ошибка сбора lsblk" +echo '```' +echo "### Виртуальные диски K8s и ВМ (ZVOLs на astra):" +echo '```text' +timeout 4s ${SSH_CMD} "zfs list -t volume -o name,volsize,used,referenced" 2>&1 || echo "Ошибка чтения ZVOL" +echo '```' +echo "### Модули ядра (nfsd, zfs):" +echo '```text' +timeout 4s ${SSH_CMD} "lsmod | grep -E '^(nfsd|zfs) '" 2>&1 || echo "Модули не загружены" +echo '```' +echo "### Теги сетевых карт ВМ 100 (VyOS) в Proxmox:" +echo '```text' +timeout 4s ${SSH_CMD} "qm config 100 2>/dev/null | grep -E '^net[0-9]'" 2>&1 || echo "Ошибка чтения qm config 100" +echo '```' +echo "### Точки монтирования LXC-контейнеров (/etc/pve/lxc/*.conf):" +echo '```text' +timeout 4s ${SSH_CMD} "grep -H -E '^mp[0-9]:' /etc/pve/lxc/*.conf 2>/dev/null" 2>&1 || echo "Ошибка чтения lxc conf" +echo '```' +echo "### Флаги автостарта ВМ и Контейнеров (onboot):" +echo '```text' +timeout 4s ${SSH_CMD} "grep -H -E '^onboot:' /etc/pve/qemu-server/*.conf /etc/pve/lxc/*.conf 2>/dev/null" 2>&1 || echo "Ошибка чтения onboot" +echo '```' +echo "### Виртуальные машины (QEMU) и Контейнеры (LXC):" +echo '```text' +timeout 4s ${SSH_CMD} "qm list; echo ''; pct list" 2>&1 || echo "Ошибка получения списка ВМ/LXC" +echo '```' +echo "---" + + + +#!/bin/bash +set -uo pipefail +SSH_CMD="ssh -n -o BatchMode=yes -o ConnectTimeout=4 fin21" +echo "## 2. Периметр: Белый VPS (Host: fin21, IP: 153.76.194.24)" +echo "### WireGuard wg0 на VPS:" +echo '```text' +timeout 4s ${SSH_CMD} "sudo wg show wg0" 2>&1 || echo "VPS или WireGuard недоступен" +echo '```' +echo "### Статус системных сервисов (Edge Stack):" +echo '```text' +timeout 4s ${SSH_CMD} "sudo systemctl is-active wg-quick@wg0 haproxy xray nginx | paste -d' ' -s - | awk '{print \"WireGuard:\", \$1, \"| HAProxy:\", \$2, \"| Xray:\", \$3, \"| Nginx:\", \$4}'" 2>&1 || echo "Ошибка проверки systemd" +echo '```' +echo "### Прослушиваемые сокеты (Ports 80, 443, 4443, 8443, 51820):" +echo '```text' +timeout 4s ${SSH_CMD} "sudo ss -tulpn | grep -E '80|443|4443|8443|51820'" 2>&1 || echo "Ошибка ss" +echo '```' +echo "### Тест аварийной заглушки Nginx (127.0.0.1:8443):" +echo '```text' +timeout 3s ${SSH_CMD} "curl -k -s https://127.0.0.1:8443" 2>&1 || echo "Nginx fallback не отвечает" +echo '```' +echo "### Конфигурация SSH-демона (sshd runtime):" +echo '```text' +timeout 4s ${SSH_CMD} "sudo sshd -T | grep -E 'passwordauthentication|permitrootlogin'" 2>&1 || echo "Ошибка проверки sshd" +echo '```' +echo "---" + + + +#!/bin/bash +set -uo pipefail +SSH_CMD="ssh -n -o BatchMode=yes -o ConnectTimeout=3 vyos" +echo "## 3. Маршрутизатор VyOS (192.168.1.2)" +echo "### Сетевые интерфейсы и L2-транк (VLANs 10, 20, 30):" +echo '```text' +timeout 4s ${SSH_CMD} "/opt/vyatta/bin/vyatta-op-cmd-wrapper show interfaces" 2>&1 || echo "Ошибка получения интерфейсов" +echo '```' +echo "### ARP-таблица K8s-интерфейса eth1 (проверка связности с нодами):" +echo '```text' +timeout 4s ${SSH_CMD} "ip neigh show dev eth1 2>/dev/null" 2>&1 || echo "Ошибка чтения ARP" +echo '```' +echo "### DHCP-сервер и выданные лизы (Options 3, 6):" +echo '```text' +timeout 4s ${SSH_CMD} "/opt/vyatta/bin/vyatta-op-cmd-wrapper show dhcp server leases" 2>&1 || echo "Ошибка получения DHCP лизов" +echo '```' +echo "### Перехват DNS через DNAT (Rule 53 -> 127.0.0.42:53):" +echo '```text' +timeout 4s ${SSH_CMD} "/opt/vyatta/bin/vyatta-op-cmd-wrapper show nat destination rules" 2>&1 || echo "Ошибка получения NAT правил" +echo '```' +echo "### Контейнеры маршрутизатора (Sing-Box & Zapret2):" +echo '```text' +timeout 4s ${SSH_CMD} "/opt/vyatta/bin/vyatta-op-cmd-wrapper show container" 2>&1 || echo "Ошибка получения контейнеров" +echo '```' +echo "### Наличие /dev/net/tun внутри контейнера sing-box:" +echo '```text' +timeout 4s ${SSH_CMD} "sudo podman exec sing-box ls -l /dev/net/tun 2>/dev/null" 2>&1 || echo "Контейнер sing-box не запущен или tun отсутствует" +echo '```' +echo "### Задержка VLESS-канала через Clash API (Main-1-out -> fin21):" +echo '```text' +timeout 4s ${SSH_CMD} "curl -s http://127.0.0.1:9090/proxies/Main-1-out 2>/dev/null" 2>&1 || echo "Clash API недоступен" +echo '```' +echo "### Статус таймера автосинхронизации Git (singbox-sync):" +echo '```text' +timeout 4s ${SSH_CMD} "sudo systemctl status singbox-sync.timer --no-pager; echo ''; sudo journalctl -u singbox-sync.service -n 5 --no-pager" 2>&1 || echo "Ошибка проверки таймера" +echo '```' +echo "### Статус WireGuard туннеля wg0 и пинг до VPS:" +echo '```text' +timeout 4s ${SSH_CMD} "sudo wg show wg0; echo ''; /opt/vyatta/bin/vyatta-op-cmd-wrapper ping 10.8.0.1 count 2" 2>&1 || echo "VyOS или туннель недоступен" +echo '```' +echo "### Таблица маршрутизации (show ip route):" +echo '```text' +timeout 4s ${SSH_CMD} "/opt/vyatta/bin/vyatta-op-cmd-wrapper show ip route" 2>&1 || echo "Ошибка получения маршрутов" +echo '```' +echo "---" + + + +#!/bin/bash +set -uo pipefail +SSH_VYOS="ssh -n -o BatchMode=yes -o ConnectTimeout=3 vyos" +SSH_STORAGE="ssh -n -o BatchMode=yes -o ConnectTimeout=3 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -J vyos root@10.0.10.14" +echo "## 4. Сервисы Tier-0 (Air-Gap фундамент)" +echo "### Technitium DNS (10.0.10.11:53):" +echo "* **Внутренний домен (*.svo88.space -> 10.0.30.200):** $(timeout 3s ${SSH_VYOS} "dig @10.0.10.11 vw.svo88.space +short" 2>&1 | tr '\n' ' ')" +echo "* **Внешний резолв (google.com):** $(timeout 3s ${SSH_VYOS} "dig @10.0.10.11 google.com +short" 2>&1 | head -n1)" +echo "### OpenBao Vault (10.0.10.12:8200):" +echo '```json' +timeout 3s ${SSH_VYOS} "curl -s http://10.0.10.12:8200/v1/sys/seal-status" 2>&1 || echo '{"error": "Vault недоступен"}' +echo '```' +echo "### Zot OCI Registry (10.0.10.15:5000):" +echo '```json' +timeout 3s ${SSH_VYOS} "curl -s http://10.0.10.15:5000/v2/_catalog" 2>&1 || echo '{"error": "Zot недоступен"}' +echo '```' +echo "### Forgejo GitOps Server (10.0.10.13:3000):" +echo '```json' +timeout 3s ${SSH_VYOS} "curl -s http://10.0.10.13:3000/api/v1/version" 2>&1 || echo '{"error": "Forgejo недоступен"}' +echo '```' +echo "### Ядерный NFS nfsd (storage0 - 10.0.10.14):" +echo '```text' +timeout 4s ${SSH_STORAGE} "echo '== Активные экспорты ядра (exportfs):'; exportfs -v; echo ''; echo '== Емкость смонтированных ZFS-датасетов:'; df -h /media /torrents /backups /models; echo ''; echo '== Права точки монтирования OpenCloud:'; ls -ld /backups/opencloud-users" 2>&1 || echo "NFS (storage0) недоступен" +echo '```' +echo "---" + + + +#!/bin/bash +set -uo pipefail +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +TALOSCONFIG="${REPO_ROOT}/talos/clusterconfig/talosconfig" +KUBECONFIG_PATH="${HOME}/.kube/config" +echo "## 5. Kubernetes Платформа & Нагрузки" +echo "### Участники кластера Talos (OS-level):" +echo '```text' +timeout 5s talosctl --talosconfig="${TALOSCONFIG}" -n 10.0.20.10 -e 10.0.20.10 get members 2>&1 || echo "Talos API недоступен" +echo '```' +echo "### Ноды кластера K8s:" +echo '```text' +timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get nodes -o wide 2>&1 || echo "K8s API недоступен" +echo '```' +echo "### Топологические лейблы нод (Proxmox-CSI topology):" +echo '```text' +timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get nodes -L topology.kubernetes.io/zone,topology.kubernetes.io/region 2>&1 || echo "Не удалось получить лейблы нод" +echo '```' +echo "### Статус ExternalSecrets (Синхронизация из Vault):" +echo '```text' +timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get clustersecretstores,externalsecrets -A 2>&1 || echo "Не удалось получить ExternalSecrets" +echo '```' +echo "### Сетевой ingress, сертификаты TLS и L2 Fast-Path VIP:" +echo '```text' +timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get certificates,ingresses -A 2>&1 || echo "Не удалось получить Ingress/TLS" +echo '' +timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" -n kube-system get ciliuml2announcementpolicies,ciliumloadbalancerippools 2>&1 || echo "Не удалось получить Cilium L2" +echo '' +timeout 3s curl -k -s -o /dev/null -w "Traefik VIP (10.0.30.200:443) HTTP Status: %{http_code}\n" https://10.0.30.200 2>&1 || echo "Traefik VIP недоступен" +echo '```' +echo "### Диски и тома (PVC / PV):" +echo '```text' +timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get pvc,pv -A 2>&1 || echo "Не удалось получить PVC" +echo '```' +echo "### Статус DaemonSet Proxmox-CSI Node:" +echo '```text' +timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" -n kube-system get daemonset proxmox-csi-plugin-node 2>&1 || echo "Не удалось получить DaemonSet CSI" +echo '```' +echo "### Статус пространства мониторинга (VictoriaMetrics & Grafana):" +echo '```text' +timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" -n monitoring get statefulsets,pods,pvc 2>&1 || echo "Не удалось получить мониторинг" +echo '```' +echo "### Логи ошибок Proxmox CSI Plugin (последние строки):" +echo '```text' +timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" -n kube-system logs -l app.kubernetes.io/name=proxmox-csi-plugin --tail=15 --prefix=true 2>&1 || echo "Нет логов CSI" +echo '```' +echo "### Синхронизация GitOps (FluxCD):" +echo '```text' +timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get gitrepositories,kustomizations,helmreleases -A 2>&1 || echo "Flux не установлен или недоступен" +echo '```' +echo "### Проблемные поды (Non-Running):" +echo '```text' +timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get pods -A --field-selector=status.phase!=Running 2>&1 || echo "Все поды в статусе Running" +echo '```' +echo "### Последние события-предупреждения (Warning Events):" +echo '```text' +timeout 5s kubectl --kubeconfig="${KUBECONFIG_PATH}" get events -A --field-selector type=Warning --sort-by='.lastTimestamp' 2>&1 | tail -n 15 || echo "Нет предупреждений" +echo '```' +echo "### Реальный объем данных OpenCloud (/var/lib/opencloud-users):" +echo '```text' +timeout 10s kubectl --kubeconfig="${KUBECONFIG_PATH}" -n storage exec statefulset/opencloud -c opencloud -- du -sh /var/lib/opencloud-users 2>&1 || echo "Не удалось получить размер данных OpenCloud" +echo '```' + + + +#!/bin/bash +# Atlas C2 Configuration SSOT + +KDBX_PATH="${HOME}/Projects/atlas-secrets.kdbx" +RAM_CACHE="/dev/shm/.atlas_secrets_cache" +RAM_KEY="/dev/shm/.atlas_core" + +VAULT_ADDR="http://10.0.10.12:8200" +VYOS_ROUTER_IP="192.168.1.2" +NET_PREFIX="10.0.0.0/16" +GIT_HOST="git.svo88.space" +PVE_ENDPOINT="https://192.168.1.177:8006/" + +DEFAULT_SESSION_TTL=1 + + + diff --git a/zarya-state.xml b/zarya-state.xml new file mode 100644 index 0000000..6ca7bc4 --- /dev/null +++ b/zarya-state.xml @@ -0,0 +1,51 @@ +This file is a merged representation of a subset of the codebase, containing specifically included files, combined into a single document by Repomix. +The content has been processed where empty lines have been removed. + + +This section contains a summary of this file. + + +This file contains a packed representation of a subset of the repository's contents that is considered the most important context. +It is designed to be easily consumable by AI systems for analysis, code review, +or other automated processes. + + + +The content is organized as follows: +1. This summary section +2. Repository information +3. Directory structure +4. Repository files (if enabled) +5. Multiple file entries, each consisting of: + - File path as an attribute + - Full contents of the file + + + +- This file should be treated as read-only. Any changes should be made to the + original repository files, not this packed version. +- When processing this file, use the file path to distinguish + between different files in the repository. +- Be aware that this file may contain sensitive information. Handle it with + the same level of security as you would the original repository. + + + +- Some files may have been excluded based on .gitignore rules and Repomix's configuration +- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files +- Only files matching these patterns are included: state/snapshots/** +- Files matching default ignore patterns are excluded +- Empty lines have been removed from all files +- Files are sorted by Git change count (files with more changes are at the bottom) + + + + + + + + + +This section contains the contents of the repository's files. + +