---
- name: Install balancer full
  hosts: vm02-balancer
  roles:
    - nginx
#    - zabbix-agent2
    - firewall
#    - chrony

  vars:
###### NGINX Configuration ######
    nginx_worker_connections: 16384
    nginx_use_epoll: true
    nginx_multi_accept: "on"
    nginx_selinux: false
    pki_dir: /etc/nginx/certs
    nginx_webroot: /var/www
    local_http_port: 8080
    nginx_letsencrypt_managed: true
    letsencrypt_acme_install: true
    letsencrypt_acme_certs_dir: /etc/letsencrypt/live
    nginx_conf_snippets:
      - nginx-compression.conf
      - nginx-proxy-params.conf
      - nginx-server-ssl.conf
    #     - nginx-websockets.conf
    #     - nginx-browser-cache.conf
    #     - letsencrypt-proxy.conf
    #     - nginx-cors.conf

    nginx_streams:
      - stream: DNS_udp
        listen_port: 53
        protocol: udp
        transparent: true
        responses: 1
        backends:
          - 10.203.2.11:53
          - 10.203.2.12:53
      - stream: DNS_tcp
        listen_port: 53
        protocol: tcp
        transparent: true
        responses: 1
        backends:
          - 10.203.2.11:53
          - 10.203.2.12:53
      - stream: NTP
        listen_port: 123
        protocol: udp
        responses: 1
        backends:
          - 10.203.2.11:123
          - 10.203.2.12:123

    nginx_virthosts:
      - virthost_name: gigacoms.ru
        listen: "80"
        server_name: gigacoms.ru
        server_aliases: "www.gigacoms.ru"
  #      index: index.php
        # error_page: /path_to_error_page.html
        ssl_enabled: true
        ssl_only: true
        ssl_letsencrypt_certs: "{{ nginx_letsencrypt_managed }}"
  #      root: "{{ nginx_webroot }}"
        server_tokens: "off"
        proxy_standard_setup: true
        proxy_additional_options:
          - proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache:30m max_size=250m;
        locations:
          - location: /
            target: "http://10.203.2.251:80"

###### Zabbix agent configuration ######
    agent_major_version: "7.0"
    agent_variant: "2"
    agent_package_state: present # present or latest
    agent_param_server: ::/0
    agent_param_listenport: 10050
    # agent_2_plugin_list: ['named'] # set in inventory vars
    agent_param_tlsconnect: unencrypted
    agent_param_tlsaccept:
      - unencrypted
    agent_apply_firewalld_rule: auto # force or auto

###### Firewalld configuration ######
    firewall:
#      - previous: replaced          # flush previous rules

      - zone: internal
        state: enabled
        permanent: true
        service:
          - ssh
          - zabbix-agent
          - ntp
          - dns
          - http
          - https
        port:
          - '10050/tcp'
        source:
          - 10.200.0.0/16
          - 10.202.0.0/16
          - 10.203.0.0/16
          - 91.218.87.192/26

      - zone: internal
        state: disabled
        permanent: true
        service:
          - cockpit
          - dhcpv6-client
          - mdns
          - samba-client

      - zone: public
        state: enabled
        permanent: true
        service:
          - ntp
          - dns
          - http
          - https

      - zone: public
        state: disabled
        permanent: true
        service:
          - ssh
          - cockpit
          - dhcpv6-client
          - mdns
          - samba-client

      - set_default_zone: internal
        state: enabled
        permanent: true

      - interface: ens192
        zone: internal
        state: enabled
        permanent: true

      - interface: ens224
        zone: public
        state: enabled
        permanent: true

###### chrony-client ######
    chrony_disable_ntpd: true
    chrony_enable: true
    chrony_log_enable: true
    chrony_log: measurements statistics tracking
    chrony_logdir: /var/log/chrony/
    chrony_ntp_servers:
      - 10.203.2.11
      - 10.203.2.12
    chrony_rtcsync: true
    chrony_timezone: Europe/Moscow

  handlers:
    - name: Reload firewalld
      ansible.builtin.service:
        name: firewalld
        state: reloaded

    - name: Restart nginx-transparent-route
      ansible.builtin.systemd:
        name: nginx-transparent-route
        state: restarted
        daemon_reload: true

  post_tasks:
    - name: Включить ip_nonlocal_bind для transparent proxy
      ansible.posix.sysctl:
        name: net.ipv4.ip_nonlocal_bind
        value: "1"
        sysctl_file: /etc/sysctl.d/50-nginx-transparent.conf
        reload: true

    - name: Добавить таблицу 200 в rt_tables для local route
      ansible.builtin.lineinfile:
        path: /etc/iproute2/rt_tables
        line: "200\tnginx-transparent"
        regexp: "^200\\s"
        owner: root
        group: root
        mode: "0644"
        create: true

    - name: Установить systemd unit nginx-transparent-route
      ansible.builtin.copy:
        dest: /etc/systemd/system/nginx-transparent-route.service
        owner: root
        group: root
        mode: "0644"
        content: |
          [Unit]
          Description=Local route for nginx transparent proxy return path
          After=network-online.target
          Wants=network-online.target

          [Service]
          Type=oneshot
          RemainAfterExit=yes
          ExecStart=/usr/sbin/ip rule add fwmark 100 table 200 priority 200
          ExecStart=/usr/sbin/ip route add local 0.0.0.0/0 dev lo table 200
          ExecStop=/usr/sbin/ip rule del fwmark 100 table 200 priority 200
          ExecStop=/usr/sbin/ip route flush table 200

          [Install]
          WantedBy=multi-user.target
      notify: Restart nginx-transparent-route

    - name: Включить и запустить nginx-transparent-route
      ansible.builtin.systemd:
        name: nginx-transparent-route
        enabled: true
        state: started
        daemon_reload: true

    - name: Маркировать входящие DNS-ответы от бэкендов (PREROUTING)
      ansible.builtin.command:
        cmd: >
          firewall-cmd --permanent --direct --add-rule
          ipv4 mangle PREROUTING 0
          -s 10.203.2.0/24 -p {{ item }} --sport 53
          -j MARK --set-mark 100
      loop:
        - udp
        - tcp
      register: fwd_result
      changed_when: "'ALREADY_ENABLED' not in fwd_result.stderr"
      notify: Reload firewalld
