# ═══════════════════════════════════════════════════════════════════════════════ # K3S Ansible Stack — Makefile # Всё запускается через Docker — Ansible устанавливать не нужно! # # Требования: docker, make # Начало работы: make setup → отредактируй .env и inventory → make install # ═══════════════════════════════════════════════════════════════════════════════ # ── Конфигурация ────────────────────────────────────────────────────────────── IMAGE_NAME := k3s-ansible # Уникальное имя на каждый вызов make, чтобы не конфликтовать при параллельных запусках # (вручную: make install ANSIBLE_CONTAINER_NAME=my-run-1) ANSIBLE_RUN_ID := $(shell date +%s | tr -d '\n')-$(shell awk 'BEGIN{srand(); print int(rand()*1000000)}' 2>/dev/null) CONTAINER_NAME := $(or $(ANSIBLE_CONTAINER_NAME),k3s-ansible-runner-$(ANSIBLE_RUN_ID)) DOCKER_TTY := $(shell if [ -t 1 ]; then echo -it; fi) # Загружаем .env если существует -include .env export # Цвета терминала CYAN := \033[0;36m GREEN := \033[0;32m YELLOW := \033[1;33m RED := \033[0;31m BOLD := \033[1m NC := \033[0m # ── Базовая команда запуска контейнера ──────────────────────────────────────── # Molecule запускается тоже из контейнера — монтируем Docker socket для DinD # Molecule: своё уникальное имя, чтобы k3s-ansible + molecule в параллели не бились DOCKER_RUN_MOLECULE := docker run --rm $(DOCKER_TTY) \ --name $(or $(MOLECULE_CONTAINER_NAME),k3s-ansible-molecule-$(ANSIBLE_RUN_ID)) \ -v $(PWD):/ansible \ -v /var/run/docker.sock:/var/run/docker.sock \ -e ANSIBLE_FORCE_COLOR=1 \ -e MOLECULE_NO_LOG=0 \ $(IMAGE_NAME) DOCKER_RUN := docker run --rm $(DOCKER_TTY) \ --name $(CONTAINER_NAME) \ --network host \ -v $(PWD):/ansible \ -v $(or $(SSH_KEY_PATH),$(HOME)/.ssh):/root/.ssh:ro \ -e VAULT_PASSWORD="$(VAULT_PASSWORD)" \ -e ANSIBLE_VERBOSITY="$(ANSIBLE_VERBOSITY)" \ -e ANSIBLE_TAGS="$(ANSIBLE_TAGS)" \ -e ANSIBLE_SKIP_TAGS="$(ANSIBLE_SKIP_TAGS)" \ -e EXTRA_VARS="$(EXTRA_VARS)" \ -e VERSION="$(VERSION)" \ -e ANSIBLE_FORCE_COLOR=1 \ $(IMAGE_NAME) .PHONY: help setup build rebuild \ dashboard \ bootstrap k8s-user mdadm k3s-certs chrony \ install install-full install-k3s install-cni install-kubevip \ addon-ingress-nginx addon-cert-manager addon-nfs-server addon-csi-nfs addon-nfs \ addon-istio addon-prometheus-stack addon-metrics-server \ addon-argocd addon-longhorn addon-kubernetes-dashboard \ addon-postgresql addon-mysql addon-redis addon-mongodb addon-kafka addon-kafka-ui addon-rabbitmq addon-gitlab addon-databasus \ addon-minio addon-velero addon-crowdsec \ addon-loki addon-promtail addon-tempo addon-pushgateway \ addon-harbor addon-gitea addon-owncloud addon-nextcloud \ addon-csi-s3 addon-csi-ceph addon-ceph-rock addon-csi-glusterfs addon-vaultwarden \ addon-smtp-relay addon-vault addon-external-secrets \ addon-jenkins addon-netbird addon-mediaserver addon-hysteria2-server addon-splitgw addon-ingress-proxypass addon-ingress-add-domains addon-yandex-dns-controller addon-technitium-dns addon-authelia \ add-node remove-node \ add-etcd-node remove-etcd-node \ etcd-backup etcd-restore etcd-list-snapshots \ upgrade uninstall health verify ping \ shell lint check \ molecule-k3s molecule-prometheus molecule-istio \ molecule-cluster \ molecule-addon-technitium-dns molecule-addon-authelia \ molecule-addon-ingress-proxypass molecule-addon-ingress-add-domains \ molecule-addon-yandex-dns-controller \ molecule-addon-gitlab molecule-addon-redis molecule-addon-mongodb molecule-addon-kafka molecule-addon-kafka-ui molecule-addon-rabbitmq \ molecule-addon-all molecule-all molecule-lint molecule-report \ vault-create vault-edit vault-view vault-encrypt-string \ vault-bootstrap-create vault-bootstrap-edit \ clean clean-all \ _check_env _check_image # ── DEFAULT ─────────────────────────────────────────────────────────────────── .DEFAULT_GOAL := help help: ## Показать эту справку @echo "" @printf "$(CYAN)$(BOLD)K3S Ansible Stack — управление через Docker$(NC)\n" @printf "$(CYAN)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$(NC)\n" @echo "" @printf "$(BOLD)Первый запуск:$(NC)\n" @echo " 1. make setup — создать .env из шаблона" @echo " 2. Отредактируй .env и inventory/hosts.ini" @echo " 3. make build — собрать Docker образ" @echo " 4. make vault-create — создать vault с K3S токеном" @echo " 5. make vault-bootstrap-create NODE=... — создать vault с паролями нод" @echo " 6. make bootstrap — создать пользователя + задеплоить SSH ключ" @echo " 7. make ping — проверить SSH" @echo " 8. make install — развернуть полный стек" @echo "" @printf "$(BOLD)Все команды:$(NC)\n" @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \ | grep -v '^_' \ | awk 'BEGIN {FS = ":.*?## "}; {printf " $(CYAN)%-26s$(NC) %s\n", $$1, $$2}' @echo "" @printf "$(BOLD)Переменные (передаются в командной строке):$(NC)\n" @printf " $(CYAN)VERSION$(NC)=v1.30.0+k3s1 версия K3S для upgrade\n" @printf " $(CYAN)NODE$(NC)=master04 нода для add-node/remove-node\n" @printf " $(CYAN)SNAPSHOT$(NC)=k3s-etcd-...db снимок для etcd-restore\n" @printf " $(CYAN)ETCD_COPY$(NC)=true скопировать backup локально\n" @printf " $(CYAN)ANSIBLE_VERBOSITY$(NC)=2 уровень debug вывода (0-4)\n" @printf " $(CYAN)ANSIBLE_TAGS$(NC)=k3s,kube_vip запустить только теги\n" @echo "" # ═══════════════════════════════════════════════════════════════════════════════ # НАСТРОЙКА # ═══════════════════════════════════════════════════════════════════════════════ setup: ## Первоначальная настройка: создать .env из шаблона @if [ -f .env ]; then \ printf "$(YELLOW)⚠ .env уже существует, пропускаю$(NC)\n"; \ else \ cp .env.example .env; \ printf "$(GREEN)✓ Создан .env$(NC)\n"; \ fi @echo "" @printf "$(BOLD)Следующие шаги:$(NC)\n" @echo " 1. nano .env — задай VAULT_PASSWORD" @echo " 2. nano inventory/hosts.ini — укажи IP серверов" @echo " 3. nano group_vars/all/main.yml — задай kube_vip_address и интерфейс" @echo " 4. make build — собери Docker образ" @echo " 5. make vault-create — создай vault" @echo " 6. make ping — проверь SSH" @echo " 7. make install — разверни стек" # ═══════════════════════════════════════════════════════════════════════════════ # DOCKER ОБРАЗ # ═══════════════════════════════════════════════════════════════════════════════ build: ## Собрать Docker образ ansible-runner @printf "$(CYAN)Сборка образа $(IMAGE_NAME)...$(NC)\n" docker build \ --build-arg HELM_VERSION=3.14.4 \ --build-arg KUBECTL_VERSION=v1.29.3 \ -t $(IMAGE_NAME):latest \ -f Dockerfile . @printf "$(GREEN)✓ Образ $(IMAGE_NAME):latest собран$(NC)\n" rebuild: ## Пересобрать образ без кэша @printf "$(CYAN)Пересборка без кэша...$(NC)\n" docker build --no-cache \ --build-arg HELM_VERSION=3.14.4 \ --build-arg KUBECTL_VERSION=v1.29.3 \ -t $(IMAGE_NAME):latest \ -f Dockerfile . @printf "$(GREEN)✓ Готово$(NC)\n" # ═══════════════════════════════════════════════════════════════════════════════ # ПРОВЕРКИ # ═══════════════════════════════════════════════════════════════════════════════ ping: _check_env _check_image ## Проверить SSH доступность всех нод @printf "$(CYAN)Проверка SSH...$(NC)\n" $(DOCKER_RUN) ping check: _check_env _check_image ## Dry-run: проверить плейбук без изменений @printf "$(CYAN)Dry-run...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/site.yml --check --diff lint: _check_image ## Проверить синтаксис всех плейбуков @printf "$(CYAN)Проверка синтаксиса...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/site.yml --syntax-check @printf "$(GREEN)✓ Синтаксис корректен$(NC)\n" # ═══════════════════════════════════════════════════════════════════════════════ # УСТАНОВКА # ═══════════════════════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════════════════════ # BOOTSTRAP — первичная настройка нод (создание пользователя + SSH ключ) # ═══════════════════════════════════════════════════════════════════════════════ bootstrap: _check_env _check_image ## Первый запуск: создать пользователя и задеплоить SSH ключ на все ноды @printf "$(CYAN)$(BOLD)Bootstrap нод (пользователь + SSH ключ)...$(NC)\n" @printf "$(YELLOW)Нужны: host_vars//vault.yml с bootstrap_user и bootstrap_password$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/bootstrap.yml \ $(if $(NODE),-e "node_to_bootstrap=$(NODE)",) vault-bootstrap-create: _check_image ## Создать vault с bootstrap credentials для ноды (NODE=master01) @if [ -z "$(NODE)" ]; then \ printf "$(RED)✗ Укажи ноду: make vault-bootstrap-create NODE=master01$(NC)\n"; \ exit 1; \ fi @if [ ! -f "host_vars/$(NODE)/vault.yml.example" ]; then \ printf "$(RED)✗ Не найден host_vars/$(NODE)/vault.yml.example$(NC)\n"; \ exit 1; \ fi @cp host_vars/$(NODE)/vault.yml.example host_vars/$(NODE)/vault.yml docker run --rm -it \ -v $(PWD):/ansible \ -e VAULT_PASSWORD="$(VAULT_PASSWORD)" \ $(IMAGE_NAME) \ ansible vault encrypt host_vars/$(NODE)/vault.yml @printf "$(GREEN)✓ Vault host_vars/$(NODE)/vault.yml создан$(NC)\n" vault-bootstrap-edit: _check_image ## Редактировать bootstrap vault ноды (NODE=master01) @if [ -z "$(NODE)" ]; then \ printf "$(RED)✗ Укажи ноду: make vault-bootstrap-edit NODE=master01$(NC)\n"; \ exit 1; \ fi docker run --rm -it \ -v $(PWD):/ansible \ -e VAULT_PASSWORD="$(VAULT_PASSWORD)" \ $(IMAGE_NAME) \ ansible vault edit host_vars/$(NODE)/vault.yml k8s-user: _check_env _check_image ## Создать k8s пользователя + разложить SSH ключи на все ноды (cluster + lab_hosts) @printf "$(CYAN)$(BOLD)Настройка k8s пользователя и SSH ключей...$(NC)\n" @printf "$(YELLOW)Нужны: host_vars//vault.yml с bootstrap_user и bootstrap_password для lab_hosts$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/k8s-user.yml \ $(if $(NODE),-e "node_to_limit=$(NODE)" --limit $(NODE),) mdadm: _check_env _check_image ## Найти RAID массив и смонтировать в /storage (mdadm_enabled: true) @printf "$(CYAN)Настройка mdadm RAID...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/mdadm.yml \ $(if $(NODE),--limit $(NODE),) chrony: _check_env _check_image ## Установить и настроить chrony (синхронизация времени + часовой пояс) @printf "$(CYAN)Настройка chrony (timezone: $(or $(TZ),из group_vars))...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/site.yml --tags chrony \ $(if $(TZ),-e chrony_timezone=$(TZ),) \ $(if $(NODE),--limit $(NODE),) k3s-certs: _check_env _check_image ## Установить systemd таймер автоматической ротации сертификатов K3S @printf "$(CYAN)Настройка автоматической ротации сертификатов K3S...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/k3s-certs.yml \ $(if $(NODE),--limit $(NODE),) install: _check_env _check_image ## Развернуть core кластер (K3S + kube-vip + сертификаты) @printf "$(CYAN)$(BOLD)Разворачиваю K3S core кластер...$(NC)\n" $(DOCKER_RUN) install install-full: _check_env _check_image ## Полный стек: core + аддоны по флагам из group_vars/all/addons.yml @printf "$(CYAN)$(BOLD)Полный стек: core + аддоны из addons.yml...$(NC)\n" $(DOCKER_RUN) install $(DOCKER_RUN) install-addons install-k3s: _check_env _check_image ## Установить только K3S кластер @printf "$(CYAN)Устанавливаю K3S...$(NC)\n" $(DOCKER_RUN) install-k3s install-cni: _check_env _check_image ## Установить CNI плагин (задай K3S_CNI=calico|cilium) @printf "$(CYAN)Устанавливаю CNI ($(or $(K3S_CNI),flannel))...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/site.yml --tags cni $(if $(K3S_CNI),-e k3s_cni=$(K3S_CNI),) install-kubevip: _check_env _check_image ## Установить только kube-vip @printf "$(CYAN)Устанавливаю kube-vip...$(NC)\n" $(DOCKER_RUN) install-kubevip install-addons: _check_env _check_image ## Установить аддоны по флагам из group_vars/all/addons.yml @printf "$(CYAN)Устанавливаю аддоны по addons.yml...$(NC)\n" $(DOCKER_RUN) install-addons install-etcd: _check_env _check_image ## Развернуть внешний etcd кластер (k3s_etcd_type: external) @printf "$(CYAN)Развёртываю внешний etcd кластер...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/site.yml --tags etcd $(ARGS) # ═══════════════════════════════════════════════════════════════════════════════ # АДДОНЫ — дополнительные компоненты кластера (addons//playbook.yml) # Кастомизация: make addon- ARGS="-e var=value" # Добавить новый аддон: создай addons//playbook.yml + addons//role/ # ═══════════════════════════════════════════════════════════════════════════════ # ── Сетевые и хранилище ─────────────────────────────────────────────────────── addon-nfs-server: _check_env _check_image ## Установить NFS сервер (запускается на группе nfs_server) @printf "$(CYAN)Устанавливаю NFS сервер...$(NC)\n" $(DOCKER_RUN) addon nfs-server $(ARGS) addon-csi-nfs: _check_env _check_image ## Установить CSI NFS Driver + StorageClass @printf "$(CYAN)Устанавливаю CSI NFS Driver...$(NC)\n" $(DOCKER_RUN) addon csi-nfs $(ARGS) addon-nfs: _check_env _check_image ## Установить NFS сервер + CSI Driver (комплект) @printf "$(CYAN)$(BOLD)Устанавливаю NFS сервер + CSI Driver...$(NC)\n" $(DOCKER_RUN) addon nfs-server $(ARGS) $(DOCKER_RUN) addon csi-nfs $(ARGS) addon-ingress-nginx: _check_env _check_image ## Установить ingress-nginx — Ingress controller @printf "$(CYAN)Устанавливаю ingress-nginx...$(NC)\n" $(DOCKER_RUN) addon ingress-nginx $(ARGS) # ── TLS и безопасность ──────────────────────────────────────────────────────── addon-cert-manager: _check_env _check_image ## Установить cert-manager — TLS сертификаты (Let's Encrypt / self-signed) @printf "$(CYAN)Устанавливаю cert-manager...$(NC)\n" $(DOCKER_RUN) addon cert-manager $(ARGS) # ── Мониторинг ──────────────────────────────────────────────────────────────── addon-prometheus-stack: _check_env _check_image ## Установить Prometheus + Grafana + Alertmanager @printf "$(CYAN)Устанавливаю kube-prometheus-stack...$(NC)\n" $(DOCKER_RUN) addon prometheus-stack $(ARGS) addon-metrics-server: _check_env _check_image ## Установить metrics-server (kubectl top nodes/pods, HPA) @printf "$(CYAN)Устанавливаю metrics-server...$(NC)\n" $(DOCKER_RUN) addon metrics-server $(ARGS) # ── Service Mesh ────────────────────────────────────────────────────────────── addon-istio: _check_env _check_image ## Установить Istio + Kiali (ARGS="-e kiali_enabled=true" для Kiali) @printf "$(CYAN)Устанавливаю Istio...$(NC)\n" $(DOCKER_RUN) addon istio $(ARGS) # ── GitOps и прочее ─────────────────────────────────────────────────────────── addon-argocd: _check_env _check_image ## Установить ArgoCD — GitOps CD (ARGS="-e argocd_ingress_enabled=true -e argocd_ingress_host=argocd.example.com") @printf "$(CYAN)Устанавливаю ArgoCD...$(NC)\n" $(DOCKER_RUN) addon argocd $(ARGS) addon-longhorn: _check_env _check_image ## Установить Longhorn — distributed block storage (ARGS="-e longhorn_default_replica_count=1" для single-node) @printf "$(CYAN)Устанавливаю Longhorn...$(NC)\n" $(DOCKER_RUN) addon longhorn $(ARGS) addon-kubernetes-dashboard: _check_env _check_image ## Установить Kubernetes Dashboard — веб UI кластера @printf "$(CYAN)Устанавливаю Kubernetes Dashboard...$(NC)\n" $(DOCKER_RUN) addon kubernetes-dashboard $(ARGS) # ── Базы данных ─────────────────────────────────────────────────────────────── addon-postgresql: _check_env _check_image ## Установить PostgreSQL (Bitnami; ARGS="-e postgresql_storage_size=20Gi") @printf "$(CYAN)Устанавливаю PostgreSQL...$(NC)\n" $(DOCKER_RUN) addon postgresql $(ARGS) addon-mysql: _check_env _check_image ## Установить MySQL (Bitnami; ARGS="-e mysql_storage_size=20Gi") @printf "$(CYAN)Устанавливаю MySQL...$(NC)\n" $(DOCKER_RUN) addon mysql $(ARGS) addon-redis: _check_env _check_image ## Установить Redis (Bitnami; ARGS="-e redis_architecture=replication") @printf "$(CYAN)Устанавливаю Redis...$(NC)\n" $(DOCKER_RUN) addon redis $(ARGS) addon-mongodb: _check_env _check_image ## Установить MongoDB (Bitnami; ARGS="-e mongodb_architecture=replicaset") @printf "$(CYAN)Устанавливаю MongoDB...$(NC)\n" $(DOCKER_RUN) addon mongodb $(ARGS) addon-kafka: _check_env _check_image ## Установить Kafka (Bitnami KRaft; ARGS="-e kafka_mode=cluster") @printf "$(CYAN)Устанавливаю Kafka...$(NC)\n" $(DOCKER_RUN) addon kafka $(ARGS) addon-kafka-ui: _check_env _check_image ## Установить Kafka UI с логином/паролем @printf "$(CYAN)Устанавливаю Kafka UI...$(NC)\n" $(DOCKER_RUN) addon kafka-ui $(ARGS) addon-rabbitmq: _check_env _check_image ## Установить RabbitMQ (Bitnami; ARGS="-e rabbitmq_mode=cluster") @printf "$(CYAN)Устанавливаю RabbitMQ...$(NC)\n" $(DOCKER_RUN) addon rabbitmq $(ARGS) addon-gitlab: _check_env _check_image ## Установить GitLab + Runner (ARGS="-e gitlab_ingress_host=gitlab.example.com") @printf "$(CYAN)Устанавливаю GitLab + Runner...$(NC)\n" $(DOCKER_RUN) addon gitlab $(ARGS) addon-databasus: _check_env _check_image ## Установить Databasus — управление резервными копиями БД (ARGS="-e databasus_ingress_host=backup.example.com") @printf "$(CYAN)Устанавливаю Databasus...$(NC)\n" $(DOCKER_RUN) addon databasus $(ARGS) # ── Объектное хранилище и backup ────────────────────────────────────────────── addon-minio: _check_env _check_image ## Установить MinIO — S3 объектное хранилище (ARGS="-e minio_storage_size=20Gi") @printf "$(CYAN)Устанавливаю MinIO...$(NC)\n" $(DOCKER_RUN) addon minio $(ARGS) addon-velero: _check_env _check_image ## Установить Velero — backup кластера + PVC через S3/MinIO @printf "$(CYAN)Устанавливаю Velero...$(NC)\n" $(DOCKER_RUN) addon velero $(ARGS) # ── Безопасность ────────────────────────────────────────────────────────────── addon-crowdsec: _check_env _check_image ## Установить CrowdSec — обнаружение вторжений (ARGS="-e crowdsec_nginx_bouncer_enabled=true") @printf "$(CYAN)Устанавливаю CrowdSec...$(NC)\n" $(DOCKER_RUN) addon crowdsec $(ARGS) # ── Приложения ──────────────────────────────────────────────────────────────── addon-harbor: _check_env _check_image ## Установить Harbor — container registry (ARGS="-e harbor_ingress_host=harbor.example.com") @printf "$(CYAN)Устанавливаю Harbor...$(NC)\n" $(DOCKER_RUN) addon harbor $(ARGS) addon-gitea: _check_env _check_image ## Установить Gitea — Git hosting (авто-обновление: gitea_version='') @printf "$(CYAN)Устанавливаю Gitea...$(NC)\n" $(DOCKER_RUN) addon gitea $(ARGS) addon-owncloud: _check_env _check_image ## Установить ownCloud OCIS — файловое хранилище (авто-обновление: owncloud_version='') @printf "$(CYAN)Устанавливаю ownCloud OCIS...$(NC)\n" $(DOCKER_RUN) addon owncloud $(ARGS) addon-nextcloud: _check_env _check_image ## Установить Nextcloud — файловое хранилище (авто-обновление: nextcloud_version='') @printf "$(CYAN)Устанавливаю Nextcloud...$(NC)\n" $(DOCKER_RUN) addon nextcloud $(ARGS) # ── Observability (logging / tracing / metrics) ─────────────────────────────── addon-loki: _check_env _check_image ## Установить Loki — агрегация логов (ARGS="-e loki_storage_type=s3" для MinIO) @printf "$(CYAN)Устанавливаю Loki...$(NC)\n" $(DOCKER_RUN) addon loki $(ARGS) addon-promtail: _check_env _check_image ## Установить Promtail — агент сбора логов → Loki @printf "$(CYAN)Устанавливаю Promtail...$(NC)\n" $(DOCKER_RUN) addon promtail $(ARGS) addon-tempo: _check_env _check_image ## Установить Tempo — distributed tracing (OTLP/Jaeger/Zipkin) @printf "$(CYAN)Устанавливаю Tempo...$(NC)\n" $(DOCKER_RUN) addon tempo $(ARGS) addon-pushgateway: _check_env _check_image ## Установить Prometheus Pushgateway — метрики batch-задач и скриптов @printf "$(CYAN)Устанавливаю Pushgateway...$(NC)\n" $(DOCKER_RUN) addon pushgateway $(ARGS) addon-csi-s3: _check_env _check_image ## Установить CSI S3 Driver — монтирование S3/MinIO бакетов как PVC (авто-MinIO при addon_minio: true) @printf "$(CYAN)Устанавливаю CSI S3 Driver...$(NC)\n" $(DOCKER_RUN) addon csi-s3 $(ARGS) addon-csi-ceph: _check_env _check_image ## Установить Kubernetes CSI Ceph (Rook-Ceph, PVC на Ceph) @printf "$(CYAN)Устанавливаю CSI Ceph...$(NC)\n" $(DOCKER_RUN) addon csi-ceph $(ARGS) addon-ceph-rock: _check_env _check_image ## Установить Ceph-Rook — distributed block (RWO) + filesystem (RWX) storage @printf "$(CYAN)Устанавливаю Rook-Ceph...$(NC)\n" $(DOCKER_RUN) addon ceph-rock $(ARGS) addon-csi-glusterfs: _check_env _check_image ## Установить CSI GlusterFS Driver (требует внешний GlusterFS + Heketi, ARGS="-e csi_glusterfs_heketi_url=...") @printf "$(CYAN)Устанавливаю CSI GlusterFS Driver...$(NC)\n" $(DOCKER_RUN) addon csi-glusterfs $(ARGS) addon-vaultwarden: _check_env _check_image ## Установить Vaultwarden — self-hosted Bitwarden (ARGS="-e vaultwarden_ingress_host=vault.example.com") @printf "$(CYAN)Устанавливаю Vaultwarden...$(NC)\n" $(DOCKER_RUN) addon vaultwarden $(ARGS) addon-smtp-relay: _check_env _check_image ## Установить SMTP Relay — Postfix → Yandex (уведомления из подов без внешней авторизации) @printf "$(CYAN)Устанавливаю SMTP Relay...$(NC)\n" $(DOCKER_RUN) addon smtp-relay $(ARGS) addon-vault: _check_env _check_image ## Установить HashiCorp Vault — менеджер секретов (ARGS="-e vault_mode=ha -e vault_auto_unseal_type=k8s") @printf "$(CYAN)Устанавливаю HashiCorp Vault...$(NC)\n" $(DOCKER_RUN) addon vault $(ARGS) addon-external-secrets: _check_env _check_image ## Установить External Secrets Operator → Vault/AWS/GCP (ARGS="-e external_secrets_vault_role_id=...") @printf "$(CYAN)Устанавливаю External Secrets Operator...$(NC)\n" $(DOCKER_RUN) addon external-secrets $(ARGS) addon-jenkins: _check_env _check_image ## Установить Jenkins CI/CD (ARGS="-e jenkins_ingress_host=jenkins.example.com") @printf "$(CYAN)Устанавливаю Jenkins...$(NC)\n" $(DOCKER_RUN) addon jenkins $(ARGS) addon-netbird: _check_env _check_image ## Установить NetBird VPN — management+signal+coturn+kube-vip (ARGS="-e netbird_domain=netbird.example.com -e netbird_subnet_router_enabled=true") @printf "$(CYAN)Устанавливаю NetBird VPN...$(NC)\n" $(DOCKER_RUN) addon netbird $(ARGS) addon-mediaserver: _check_env _check_image ## Установить MediaServer — Plex, Sonarr, Radarr, Lidarr, Bazarr, Prowlarr+Hysteria2, Overseerr, Transmission, Samba (ARGS="-e mediaserver_hysteria2_enabled=false" без прокси) @printf "$(CYAN)Устанавливаю MediaServer стек...$(NC)\n" $(DOCKER_RUN) addon mediaserver $(ARGS) addon-hysteria2-server: _check_env _check_image ## Установить Hysteria2 VPN сервер на удалённый VPS из группы [hysteria2_server] (ARGS="-k" для SSH пароля, ARGS="-k -K" для SSH+sudo) @printf "$(CYAN)Устанавливаю Hysteria2 сервер на удалённый VPS...$(NC)\n" $(DOCKER_RUN) addon hysteria2-server $(ARGS) addon-splitgw: _check_env _check_image ## Установить Split Gateway — sing-box+Hysteria2 TPROXY (группа [splitgw]; ARGS="-e splitgw_deploy_mode=k8s" для K8s DaemonSet) @printf "$(CYAN)Устанавливаю Split Gateway (sing-box + Hysteria2)...$(NC)\n" $(DOCKER_RUN) addon splitgw $(ARGS) addon-ingress-proxypass: _check_env _check_image ## Проксировать внешние сервисы через ingress-nginx (ARGS="-e ingress_proxypass_vip=192.168.1.x") @printf "$(CYAN)Устанавливаю External Services Ingress Proxy...$(NC)\n" $(DOCKER_RUN) addon ingress-proxypass $(ARGS) addon-ingress-add-domains: _check_env _check_image ## Добавить домены к существующим сервисам кластера (Ingress-only) @printf "$(CYAN)Устанавливаю ingress-add-domains...$(NC)\n" $(DOCKER_RUN) addon ingress-add-domains $(ARGS) addon-yandex-dns-controller: _check_env _check_image ## Yandex 360 DNS controller (safe mode, ARGS="-e yandex_dns_controller_dry_run=true") @printf "$(CYAN)Устанавливаю Yandex 360 DNS Controller...$(NC)\n" $(DOCKER_RUN) addon yandex-dns-controller $(ARGS) addon-technitium-dns: _check_env _check_image ## Technitium DNS HA — Primary+Secondary, kube-vip LB, zone sync @printf "$(CYAN)Устанавливаю Technitium DNS HA...$(NC)\n" $(DOCKER_RUN) addon technitium-dns $(ARGS) addon-authelia: _check_env _check_image ## Authelia SSO — Forward-auth + OIDC provider @printf "$(CYAN)Устанавливаю Authelia SSO...$(NC)\n" $(DOCKER_RUN) addon authelia $(ARGS) # Generic цель — любой аддон из addons//playbook.yml addon-%: _check_env _check_image @if [ ! -f "addons/$*/playbook.yml" ]; then \ printf "$(RED)✗ Аддон '$*' не найден. Ожидается: addons/$*/playbook.yml$(NC)\n"; \ printf "$(YELLOW) Доступные аддоны:$(NC) "; \ ls addons/ 2>/dev/null | tr '\n' ' '; echo ""; \ exit 1; \ fi @printf "$(CYAN)Устанавливаю аддон $*...$(NC)\n" $(DOCKER_RUN) addon $* $(ARGS) # ═══════════════════════════════════════════════════════════════════════════════ # МАСШТАБИРОВАНИЕ КЛАСТЕРА # ═══════════════════════════════════════════════════════════════════════════════ add-node: _check_env _check_image ## Добавить ноду: make add-node NODE=master04 @if [ -z "$(NODE)" ]; then \ printf "$(RED)✗ Укажи ноду: make add-node NODE=$(NC)\n"; \ exit 1; \ fi @printf "$(CYAN)Добавляю ноду $(NODE) в кластер...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/add-node.yml -e "node_to_add=$(NODE)" remove-node: _check_env _check_image ## Удалить ноду: make remove-node NODE=worker04 @if [ -z "$(NODE)" ]; then \ printf "$(RED)✗ Укажи ноду: make remove-node NODE=$(NC)\n"; \ exit 1; \ fi @printf "$(RED)$(BOLD)Удаление ноды $(NODE) из кластера...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/remove-node.yml -e "node_to_remove=$(NODE)" add-etcd-node: _check_env _check_image ## Добавить etcd ноду: make add-etcd-node NODE=etcd04 @if [ -z "$(NODE)" ]; then \ printf "$(RED)✗ Укажи ноду: make add-etcd-node NODE=$(NC)\n"; \ printf "$(YELLOW) Нода должна быть в [etcd_nodes] в inventory$(NC)\n"; \ exit 1; \ fi @printf "$(CYAN)Добавляю etcd ноду $(NODE)...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/add-etcd-node.yml -e "node_to_add=$(NODE)" $(ARGS) remove-etcd-node: _check_env _check_image ## Удалить etcd ноду: make remove-etcd-node NODE=etcd04 @if [ -z "$(NODE)" ]; then \ printf "$(RED)✗ Укажи ноду: make remove-etcd-node NODE=$(NC)\n"; \ exit 1; \ fi @printf "$(RED)$(BOLD)Удаление etcd ноды $(NODE) из кластера...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/remove-etcd-node.yml -e "node_to_remove=$(NODE)" $(ARGS) # ═══════════════════════════════════════════════════════════════════════════════ # РЕЗЕРВНОЕ КОПИРОВАНИЕ ETCD # ═══════════════════════════════════════════════════════════════════════════════ etcd-backup: _check_env _check_image ## Создать снимок etcd (make etcd-backup [SNAPSHOT=name] [ETCD_COPY=true]) @printf "$(CYAN)Создаю снимок etcd...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/etcd-backup.yml \ $(if $(SNAPSHOT),-e etcd_backup_name=$(SNAPSHOT),) \ $(if $(ETCD_COPY),-e etcd_backup_copy_to_local=$(ETCD_COPY),) etcd-restore: _check_env _check_image ## Восстановить etcd: make etcd-restore SNAPSHOT=k3s-etcd-20250101.db @if [ -z "$(SNAPSHOT)" ]; then \ printf "$(RED)✗ Укажи снимок: make etcd-restore SNAPSHOT=$(NC)\n"; \ printf "$(YELLOW) Список снимков: make etcd-list-snapshots$(NC)\n"; \ exit 1; \ fi @printf "$(RED)$(BOLD)ВНИМАНИЕ: восстановление etcd перезапишет данные кластера!$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/etcd-restore.yml \ -e "etcd_restore_snapshot=$(SNAPSHOT)" \ $(if $(FORCE),-e etcd_restore_force=true,) etcd-list-snapshots: _check_env _check_image ## Показать доступные снимки etcd @printf "$(CYAN)Список снимков etcd...$(NC)\n" $(DOCKER_RUN) ansible-playbook playbooks/etcd-restore.yml --tags list # ═══════════════════════════════════════════════════════════════════════════════ # ОБНОВЛЕНИЕ # ═══════════════════════════════════════════════════════════════════════════════ upgrade: _check_env _check_image ## Обновить K3S (make upgrade VERSION=v1.30.0+k3s1) @if [ -z "$(VERSION)" ]; then \ printf "$(RED)✗ Укажи версию: make upgrade VERSION=v1.30.0+k3s1$(NC)\n"; \ exit 1; \ fi @printf "$(CYAN)Обновляю K3S до $(VERSION)...$(NC)\n" $(DOCKER_RUN) upgrade # ═══════════════════════════════════════════════════════════════════════════════ # ДИАГНОСТИКА # ═══════════════════════════════════════════════════════════════════════════════ health: _check_env _check_image ## Диагностика кластера (сервисы, поды, диск, память) @printf "$(CYAN)Диагностика...$(NC)\n" $(DOCKER_RUN) health verify: _check_env _check_image ## Проверить весь стек (nodes/pods/svc/sc/ingress) @printf "$(CYAN)Проверка стека...$(NC)\n" $(DOCKER_RUN) verify # ═══════════════════════════════════════════════════════════════════════════════ # УДАЛЕНИЕ # ═══════════════════════════════════════════════════════════════════════════════ uninstall: _check_env _check_image ## ВНИМАНИЕ: удалить весь стек и данные @printf "$(RED)$(BOLD)ВНИМАНИЕ: Удаление всего стека — данные будут потеряны!$(NC)\n" @printf "$(YELLOW)Введи 'yes' для подтверждения: $(NC)"; \ read CONFIRM && [ "$$CONFIRM" = "yes" ] || (printf "Отменено.\n" && exit 1) $(DOCKER_RUN) uninstall # ═══════════════════════════════════════════════════════════════════════════════ # ANSIBLE VAULT # ═══════════════════════════════════════════════════════════════════════════════ vault-create: _check_image ## Создать зашифрованный vault (group_vars/all/vault.yml) @printf "$(CYAN)Создание vault...$(NC)\n" docker run --rm -it \ -v $(PWD):/ansible \ $(IMAGE_NAME) \ ansible vault create group_vars/all/vault.yml @printf "$(GREEN)✓ Vault создан$(NC)\n" vault-edit: _check_image ## Редактировать vault docker run --rm -it \ -v $(PWD):/ansible \ -e VAULT_PASSWORD="$(VAULT_PASSWORD)" \ $(IMAGE_NAME) \ ansible vault edit group_vars/all/vault.yml vault-view: _check_image ## Просмотреть vault (расшифрованный вывод) docker run --rm -it \ -v $(PWD):/ansible \ -e VAULT_PASSWORD="$(VAULT_PASSWORD)" \ $(IMAGE_NAME) \ ansible vault view group_vars/all/vault.yml vault-encrypt-string: _check_image ## Зашифровать строку: make vault-encrypt-string STR=... NAME=... @if [ -z "$(STR)" ]; then \ printf "$(RED)✗ Нужна строка: make vault-encrypt-string STR=мой-токен NAME=vault_k3s_token$(NC)\n"; \ exit 1; \ fi docker run --rm -it \ -v $(PWD):/ansible \ -e VAULT_PASSWORD="$(VAULT_PASSWORD)" \ $(IMAGE_NAME) \ ansible vault encrypt_string '$(STR)' --name '$(or $(NAME),encrypted_var)' # ═══════════════════════════════════════════════════════════════════════════════ # MOLECULE — ТЕСТИРОВАНИЕ РОЛЕЙ # Требования: pip install -r requirements-python.txt (molecule, molecule-plugins[docker]) # ═══════════════════════════════════════════════════════════════════════════════ molecule-k3s: _check_image ## Тест роли k3s — 3 контейнера (Ubuntu+Debian), ~8-12 мин @printf "$(CYAN)Тестирую роль k3s (3 ноды: master01, worker01, rpi01)...$(NC)\n" $(DOCKER_RUN_MOLECULE) molecule k3s @printf "$(GREEN)✓ k3s role: OK$(NC)\n" molecule-prometheus: _check_image ## Тест аддона prometheus-stack (legacy alias), ~2-3 мин @printf "$(CYAN)Тестирую аддон prometheus-stack...$(NC)\n" $(DOCKER_RUN_MOLECULE) molecule-addon prometheus-stack @printf "$(GREEN)✓ addon prometheus-stack: OK$(NC)\n" molecule-istio: _check_image ## Тест аддона istio (legacy alias), ~2-3 мин @printf "$(CYAN)Тестирую аддон istio...$(NC)\n" $(DOCKER_RUN_MOLECULE) molecule-addon istio @printf "$(GREEN)✓ addon istio: OK$(NC)\n" molecule-cluster: _check_image ## Тест topology кластера 3 master + 2 worker (embedded etcd HA), ~15-20 мин @printf "$(CYAN)$(BOLD)Тестирую кластер (3 master + 2 worker)...$(NC)\n" $(DOCKER_RUN_MOLECULE) molecule-cluster @printf "$(GREEN)✓ cluster topology: OK$(NC)\n" molecule-addon-technitium-dns: _check_image ## Тест аддона technitium-dns (Helm lint + template), ~2-3 мин @printf "$(CYAN)Тестирую аддон technitium-dns...$(NC)\n" $(DOCKER_RUN_MOLECULE) molecule-addon technitium-dns @printf "$(GREEN)✓ addon technitium-dns: OK$(NC)\n" molecule-addon-authelia: _check_image ## Тест аддона authelia (Helm lint + template + OIDC), ~2-3 мин @printf "$(CYAN)Тестирую аддон authelia...$(NC)\n" $(DOCKER_RUN_MOLECULE) molecule-addon authelia @printf "$(GREEN)✓ addon authelia: OK$(NC)\n" molecule-addon-ingress-proxypass: _check_image ## Тест аддона ingress-proxypass (Helm lint + template), ~2 мин @printf "$(CYAN)Тестирую аддон ingress-proxypass...$(NC)\n" $(DOCKER_RUN_MOLECULE) molecule-addon ingress-proxypass @printf "$(GREEN)✓ addon ingress-proxypass: OK$(NC)\n" molecule-addon-ingress-add-domains: _check_image ## Тест аддона ingress-add-domains (Helm lint + template), ~2 мин @printf "$(CYAN)Тестирую аддон ingress-add-domains...$(NC)\n" $(DOCKER_RUN_MOLECULE) molecule-addon ingress-add-domains @printf "$(GREEN)✓ addon ingress-add-domains: OK$(NC)\n" molecule-addon-yandex-dns-controller: _check_image ## Тест аддона yandex-dns-controller (Helm lint + template), ~2 мин @printf "$(CYAN)Тестирую аддон yandex-dns-controller...$(NC)\n" $(DOCKER_RUN_MOLECULE) molecule-addon yandex-dns-controller @printf "$(GREEN)✓ addon yandex-dns-controller: OK$(NC)\n" molecule-addon-argocd: _check_image ## Тест аддона argocd (Ingress шаблон), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon argocd molecule-addon-cert-manager: _check_image ## Тест аддона cert-manager (ClusterIssuer шаблоны), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon cert-manager molecule-addon-crowdsec: _check_image ## Тест аддона crowdsec (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon crowdsec molecule-addon-csi-ceph: _check_image ## Тест аддона csi-ceph (CephCluster шаблон), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon csi-ceph molecule-addon-ceph-rock: _check_image ## Тест аддона ceph-rock (CephCluster шаблон), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon ceph-rock molecule-addon-csi-glusterfs: _check_image ## Тест аддона csi-glusterfs (StorageClass шаблон), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon csi-glusterfs molecule-addon-csi-nfs: _check_image ## Тест аддона csi-nfs (StorageClass шаблон), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon csi-nfs molecule-addon-csi-s3: _check_image ## Тест аддона csi-s3 (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon csi-s3 molecule-addon-databasus: _check_image ## Тест аддона databasus (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon databasus molecule-addon-gitlab: _check_image ## Тест аддона gitlab (values шаблон), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon gitlab molecule-addon-redis: _check_image ## Тест аддона redis (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon redis molecule-addon-mongodb: _check_image ## Тест аддона mongodb (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon mongodb molecule-addon-kafka: _check_image ## Тест аддона kafka (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon kafka molecule-addon-kafka-ui: _check_image ## Тест аддона kafka-ui (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon kafka-ui molecule-addon-rabbitmq: _check_image ## Тест аддона rabbitmq (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon rabbitmq molecule-addon-external-secrets: _check_image ## Тест аддона external-secrets (ClusterSecretStore шаблон), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon external-secrets molecule-addon-gitea: _check_image ## Тест аддона gitea (Helm values шаблон), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon gitea molecule-addon-harbor: _check_image ## Тест аддона harbor (Helm values шаблон), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon harbor molecule-addon-hysteria2-server: _check_image ## Тест аддона hysteria2-server (config шаблон), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon hysteria2-server molecule-addon-ingress-nginx: _check_image ## Тест аддона ingress-nginx (Helm values шаблон), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon ingress-nginx molecule-addon-jenkins: _check_image ## Тест аддона jenkins (Helm values шаблон), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon jenkins molecule-addon-kubernetes-dashboard: _check_image ## Тест аддона kubernetes-dashboard (K8s шаблоны), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon kubernetes-dashboard molecule-addon-loki: _check_image ## Тест аддона loki (Helm values шаблон), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon loki molecule-addon-longhorn: _check_image ## Тест аддона longhorn (Ingress шаблон), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon longhorn molecule-addon-prometheus-stack: _check_image ## Тест аддона prometheus-stack (Helm values шаблон), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon prometheus-stack molecule-addon-mediaserver: _check_image ## Тест аддона mediaserver (PVC + values шаблоны), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon mediaserver molecule-addon-metrics-server: _check_image ## Тест аддона metrics-server (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon metrics-server molecule-addon-minio: _check_image ## Тест аддона minio (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon minio molecule-addon-mysql: _check_image ## Тест аддона mysql (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon mysql molecule-addon-netbird: _check_image ## Тест аддона netbird (management + signal values), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon netbird molecule-addon-nextcloud: _check_image ## Тест аддона nextcloud (Helm values шаблон), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon nextcloud molecule-addon-nfs-server: _check_image ## Тест аддона nfs-server (exports шаблон), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon nfs-server molecule-addon-owncloud: _check_image ## Тест аддона owncloud (Helm values шаблон), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon owncloud molecule-addon-postgresql: _check_image ## Тест аддона postgresql (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon postgresql molecule-addon-promtail: _check_image ## Тест аддона promtail (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon promtail molecule-addon-pushgateway: _check_image ## Тест аддона pushgateway (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon pushgateway molecule-addon-smtp-relay: _check_image ## Тест аддона smtp-relay (Helm values шаблон), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon smtp-relay molecule-addon-splitgw: _check_image ## Тест аддона splitgw (sing-box конфиг + iptables скрипт), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon splitgw molecule-addon-istio: _check_image ## Тест аддона istio (Helm values шаблон), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon istio molecule-addon-tempo: _check_image ## Тест аддона tempo (Helm values + datasource шаблоны), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon tempo molecule-addon-vault: _check_image ## Тест аддона vault (Helm values + init job шаблоны), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon vault molecule-addon-vaultwarden: _check_image ## Тест аддона vaultwarden (Helm values шаблон), ~2 мин $(DOCKER_RUN_MOLECULE) molecule-addon vaultwarden molecule-addon-velero: _check_image ## Тест аддона velero (defaults validation), ~1 мин $(DOCKER_RUN_MOLECULE) molecule-addon velero molecule-addon-all: _check_image ## Тест всех аддонов с Molecule (~60+ мин) @printf "$(CYAN)$(BOLD)Тестирую все аддоны...$(NC)\n" $(MAKE) molecule-addon-argocd $(MAKE) molecule-addon-authelia $(MAKE) molecule-addon-cert-manager $(MAKE) molecule-addon-crowdsec $(MAKE) molecule-addon-csi-ceph $(MAKE) molecule-addon-ceph-rock $(MAKE) molecule-addon-csi-glusterfs $(MAKE) molecule-addon-csi-nfs $(MAKE) molecule-addon-csi-s3 $(MAKE) molecule-addon-databasus $(MAKE) molecule-addon-gitlab $(MAKE) molecule-addon-redis $(MAKE) molecule-addon-mongodb $(MAKE) molecule-addon-kafka $(MAKE) molecule-addon-kafka-ui $(MAKE) molecule-addon-rabbitmq $(MAKE) molecule-addon-external-secrets $(MAKE) molecule-addon-gitea $(MAKE) molecule-addon-harbor $(MAKE) molecule-addon-hysteria2-server $(MAKE) molecule-addon-ingress-add-domains $(MAKE) molecule-addon-ingress-nginx $(MAKE) molecule-addon-ingress-proxypass $(MAKE) molecule-addon-jenkins $(MAKE) molecule-addon-kubernetes-dashboard $(MAKE) molecule-addon-loki $(MAKE) molecule-addon-longhorn $(MAKE) molecule-addon-prometheus-stack $(MAKE) molecule-addon-mediaserver $(MAKE) molecule-addon-metrics-server $(MAKE) molecule-addon-minio $(MAKE) molecule-addon-mysql $(MAKE) molecule-addon-netbird $(MAKE) molecule-addon-nextcloud $(MAKE) molecule-addon-nfs-server $(MAKE) molecule-addon-owncloud $(MAKE) molecule-addon-postgresql $(MAKE) molecule-addon-promtail $(MAKE) molecule-addon-pushgateway $(MAKE) molecule-addon-smtp-relay $(MAKE) molecule-addon-splitgw $(MAKE) molecule-addon-istio $(MAKE) molecule-addon-technitium-dns $(MAKE) molecule-addon-tempo $(MAKE) molecule-addon-vault $(MAKE) molecule-addon-vaultwarden $(MAKE) molecule-addon-velero $(MAKE) molecule-addon-yandex-dns-controller @printf "$(GREEN)$(BOLD)✓ Все аддоны OK$(NC)\n" molecule-all: _check_image ## Запустить ВСЕ Molecule тесты (роли + кластер + аддоны) + HTML отчёт @printf "$(CYAN)$(BOLD)Запуск всех Molecule тестов...$(NC)\n" @mkdir -p /tmp/molecule-junit $(MAKE) molecule-k3s $(MAKE) molecule-prometheus $(MAKE) molecule-istio $(MAKE) molecule-addon-all $(MAKE) molecule-report @printf "$(GREEN)$(BOLD)✓ Все тесты прошли. Отчёт: /tmp/molecule-report.html$(NC)\n" molecule-report: ## Сгенерировать HTML отчёт из JUnit XML (/tmp/molecule-junit/*.xml) @printf "$(CYAN)Генерирую HTML отчёт...$(NC)\n" python3 scripts/molecule-report.py \ --xml-dir /tmp/molecule-junit \ --output /tmp/molecule-report.html @printf "$(GREEN)✓ Отчёт: /tmp/molecule-report.html$(NC)\n" @printf "$(YELLOW) Открой: open /tmp/molecule-report.html$(NC)\n" molecule-lint: _check_image ## Линтинг (yamllint + ansible-lint) в контейнере, ~30 сек @printf "$(CYAN)Запуск линтинга...$(NC)\n" $(DOCKER_RUN_MOLECULE) molecule-lint @printf "$(GREEN)✓ Линтинг прошёл$(NC)\n" # ═══════════════════════════════════════════════════════════════════════════════ # ИНТЕРАКТИВНЫЙ SHELL # ═══════════════════════════════════════════════════════════════════════════════ shell: _check_image ## Запустить интерактивный bash внутри контейнера @printf "$(CYAN)Запуск shell (exit для выхода)...$(NC)\n" docker run --rm -it \ --name $(CONTAINER_NAME)-shell \ --network host \ -v $(PWD):/ansible \ -v $(or $(SSH_KEY_PATH),$(HOME)/.ssh):/root/.ssh:ro \ -e VAULT_PASSWORD="$(VAULT_PASSWORD)" \ -e ANSIBLE_FORCE_COLOR=1 \ $(IMAGE_NAME) shell dashboard: ## Запустить dashboard (FastAPI + worker + redis) через docker compose @printf "$(CYAN)Запускаю dashboard стек...$(NC)\n" docker compose -f dashboard/docker-compose.yml up --build # ═══════════════════════════════════════════════════════════════════════════════ # ОЧИСТКА # ═══════════════════════════════════════════════════════════════════════════════ clean: ## Удалить Docker образ @printf "$(YELLOW)Удаляю образ $(IMAGE_NAME)...$(NC)\n" docker rmi $(IMAGE_NAME):latest 2>/dev/null || printf "$(YELLOW)Образ не найден$(NC)\n" clean-all: clean ## Удалить образ + kubeconfig + кэш Docker rm -f kubeconfig docker system prune -f @printf "$(GREEN)✓ Очистка завершена$(NC)\n" # ═══════════════════════════════════════════════════════════════════════════════ # ВНУТРЕННИЕ # ═══════════════════════════════════════════════════════════════════════════════ _check_env: @if [ ! -f .env ]; then \ printf "$(RED)✗ Файл .env не найден! Запусти: make setup$(NC)\n"; \ exit 1; \ fi _check_image: @if ! docker image inspect $(IMAGE_NAME):latest > /dev/null 2>&1; then \ printf "$(YELLOW)⚠ Образ не найден, собираю...$(NC)\n"; \ $(MAKE) build; \ fi