package devopsmodules

import (
	"rubric/utils"
)

var AnsibleModule = Module{
	Key:         "ansible",
	Aliases:     []string{"an", "ansible"},
	Title:       "Ansible — управление конфигурацией",
	Description: "Инвентарь, playbook, роли, модули, vault, динамический инвентарь",
	Run:         showAnsible,
}

func showAnsible() {
	utils.Header("DevOps — Ansible")

	utils.Section("Основы и установка")
	utils.Code(`Ansible — agentless: работает через SSH, не требует агентов на хостах.
Push-модель: управляющая машина отправляет команды.

# Установка:
pip install ansible          # рекомендуется через pip
dnf install ansible          # RHEL/Fedora
apt install ansible          # Debian/Ubuntu

ansible --version
ansible-galaxy collection install community.general`)

	utils.Section("Инвентарь (Inventory)")
	utils.Code(`# /etc/ansible/hosts или ./inventory.ini:
# Статический инвентарь:

[webservers]
web1.example.com
web2.example.com ansible_port=2222

[databases]
db1.example.com ansible_user=dbadmin

[production:children]
webservers
databases

[all:vars]
ansible_python_interpreter=/usr/bin/python3

# YAML-формат (inventory.yml):
all:
  children:
    webservers:
      hosts:
        web1.example.com:
          http_port: 80
        web2.example.com:
    databases:
      hosts:
        db1.example.com:
          ansible_user: dbadmin`)

	utils.Println(utils.ColorBold + "Ad-hoc команды:" + utils.ColorReset)
	utils.Command("ansible all -i inventory.ini -m ping", "проверить доступность хостов")
	utils.Command("ansible webservers -m command -a 'uptime'", "выполнить команду")
	utils.Command("ansible all -m shell -a 'df -h'", "через shell")
	utils.Command("ansible webservers -m apt -a 'name=nginx state=present' -b", "установить пакет")
	utils.Command("ansible all -m gather_facts --tree /tmp/facts", "собрать факты")
	utils.Command("ansible all -m setup -a 'filter=ansible_os_family'", "конкретный факт")

	utils.Section("Playbook")
	utils.Code(`# site.yml — основной playbook:
---
- name: Настройка веб-серверов
  hosts: webservers
  become: yes                    # sudo
  vars:
    nginx_port: 80
    app_user: www-data

  pre_tasks:
    - name: Обновить кэш пакетов
      apt:
        update_cache: yes
        cache_valid_time: 3600

  tasks:
    - name: Установить nginx
      package:
        name: nginx
        state: present

    - name: Скопировать конфигурацию
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        owner: root
        mode: '0644'
      notify: Перезапустить nginx

    - name: Создать директорию приложения
      file:
        path: /var/www/myapp
        state: directory
        owner: "{{ app_user }}"
        mode: '0755'

    - name: Убедиться что nginx запущен
      service:
        name: nginx
        state: started
        enabled: yes

  handlers:
    - name: Перезапустить nginx
      service:
        name: nginx
        state: restarted

- name: Настройка баз данных
  hosts: databases
  become: yes
  roles:
    - role: postgresql
      vars:
        pg_version: 16`)

	utils.Println(utils.ColorBold + "Запуск playbook:" + utils.ColorReset)
	utils.Command("ansible-playbook site.yml -i inventory.ini", "запустить")
	utils.Command("ansible-playbook site.yml --check", "dry-run (без изменений)")
	utils.Command("ansible-playbook site.yml --diff", "показать изменения файлов")
	utils.Command("ansible-playbook site.yml --tags nginx", "только помеченные теги")
	utils.Command("ansible-playbook site.yml --skip-tags debug", "пропустить теги")
	utils.Command("ansible-playbook site.yml --limit web1.example.com", "только один хост")
	utils.Command("ansible-playbook site.yml -e 'nginx_port=8080'", "переопределить переменную")
	utils.Command("ansible-playbook site.yml -v", "verbose (-vvv для debug)")

	utils.Section("Модули (основные)")
	utils.Code(`# Файлы и шаблоны:
copy:    — скопировать файл с управляющей машины
template: — шаблон Jinja2
file:    — создать файл/директорию/ссылку
fetch:   — скачать файл с хоста
lineinfile: — управление строками в файле
blockinfile: — управление блоками

# Пакеты и сервисы:
package: / apt: / dnf: / yum:  — пакеты
service: / systemd:             — сервисы

# Команды:
command: — выполнить команду (без shell)
shell:   — выполнить через sh
raw:     — без Python (для минимальных систем)
script:  — выполнить локальный скрипт

# Пользователи:
user:    — управление пользователями
group:   — управление группами
authorized_key: — SSH-ключи

# Сеть:
uri:     — HTTP-запросы
get_url: — скачать файл по URL
wait_for: — ждать порт/файл/условие`)

	utils.Section("Переменные и шаблоны Jinja2")
	utils.Code(`# Приоритет переменных (от низкого к высокому):
# defaults → inventory → group_vars → host_vars → play vars → task vars → extra-vars

# group_vars/webservers.yml:
nginx_version: "1.25"
nginx_worker_processes: auto

# host_vars/web1.example.com.yml:
nginx_port: 8080

# Шаблон templates/nginx.conf.j2:
worker_processes {{ nginx_worker_processes }};

events { worker_connections 1024; }

http {
    server {
        listen {{ nginx_port }};
        server_name {{ inventory_hostname }};

        {% if ssl_enabled %}
        listen 443 ssl;
        ssl_certificate {{ ssl_cert_path }};
        {% endif %}

        {% for location in nginx_locations %}
        location {{ location.path }} {
            proxy_pass {{ location.backend }};
        }
        {% endfor %}
    }
}

# Фильтры Jinja2:
{{ variable | default('fallback') }}
{{ list | join(', ') }}
{{ string | upper }}
{{ path | basename }}
{{ number | int }}`)

	utils.Section("Роли (Roles)")
	utils.Code(`# Структура роли:
roles/
└── nginx/
    ├── defaults/main.yml    # переменные по умолчанию
    ├── vars/main.yml        # жёсткие переменные
    ├── tasks/main.yml       # задачи
    ├── handlers/main.yml    # обработчики
    ├── templates/           # шаблоны Jinja2
    ├── files/               # статические файлы
    ├── meta/main.yml        # зависимости
    └── README.md

# Создать структуру:
ansible-galaxy role init roles/nginx

# Использование роли в playbook:
- hosts: webservers
  roles:
    - nginx
    - role: postgresql
      vars:
        pg_version: 16

# Установить роль из Galaxy:
ansible-galaxy install geerlingguy.nginx
# requirements.yml:
roles:
  - name: geerlingguy.nginx
    version: "3.2.0"
ansible-galaxy install -r requirements.yml`)

	utils.Section("Ansible Vault — шифрование секретов")
	utils.Code(`# Зашифровать файл:
ansible-vault encrypt vars/secrets.yml
ansible-vault encrypt_string 'mypassword' --name db_password

# Редактировать зашифрованный файл:
ansible-vault edit vars/secrets.yml

# Просмотр:
ansible-vault view vars/secrets.yml

# Расшифровать:
ansible-vault decrypt vars/secrets.yml

# Изменить пароль:
ansible-vault rekey vars/secrets.yml

# Использование в playbook:
ansible-playbook site.yml --ask-vault-pass
ansible-playbook site.yml --vault-password-file ~/.vault_pass

# .vault_pass (файл с паролем, не коммитить!):
echo 'myVaultPassword' > ~/.vault_pass
chmod 600 ~/.vault_pass`)

	utils.Footer()
}
