ansible советы по использованию (Помощь)

Обсуждение настройки и работы сервисов, резервирования, сетевых настроек и вопросов безопасности ОС.

Модератор: SLEDopit

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: ansible советы по использованию

Сообщение Bizdelnick »

bars писал:
29.10.2021 16:32
Более точно нужно указывать что менять.
Не более точно, а
When modifying a line the regexp should typically match both the initial state of the line as well as its state after replacement by line to ensure idempotence.
bars писал:
29.10.2021 16:32
А как указать что бы поменялись все совпадения в файле?
https://docs.ansible.com/ansible-core/devel/collections/ansible/builtin/replace_module.html
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: ansible советы по использованию

Сообщение SLEDopit »

bars писал:
29.10.2021 16:21
regexp: '^Port 11111'
Стоит ещё помнить, что такие открытые регексы могут попортить нервов. Потому что оно матчится не только с Port 11111, но и с Port 111111 и с Port 1111122. В данном конкретном случае скорее всего проблем не будет. Потому что портов всего 64 тысячи. Но вероятность что что-то пойдет не так всё же есть.

Ну и в целом, я бы использовал replace в случае крайней необходимости. template или даже просто copy всё же куда надежнее.

Например, в случае с sshd есть прекрасная директория /etc/ssh/sshd_config.d, куда можно положить файл с нужными значениями, а не править /etc/ssh/sshd_config. Его лучше оставить на откуп мантейнерам дистрибутива и не трогать. И во время обновления вопросов будет меньше. Вот выдержка из man sshd_config:

Код: Выделить всё

     /etc/ssh/sshd_config.d/*.conf files are included at the start of the configuration file, 
     so options set there will override those in /etc/ssh/sshd_config.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: ansible советы по использованию

Сообщение Bizdelnick »

SLEDopit писал(а):
29.10.2021 18:29
bars писал:
29.10.2021 16:21
regexp: '^Port 11111'
Стоит ещё помнить, что такие открытые регексы могут попортить нервов. Потому что оно матчится не только с Port 11111, но и с Port 111111 и с Port 1111122. В данном конкретном случае скорее всего проблем не будет. Потому что портов всего 64 тысячи. Но вероятность что что-то пойдет не так всё же есть.
В данном конкретном случае надо вообще ^Port\b.
Добавлено (18:34):
SLEDopit писал(а):
29.10.2021 18:29
Ну и в целом, я бы использовал replace в случае крайней необходимости. template или даже просто copy всё же куда надежнее.
Вот тут полностью согласен. Правда, добавляется проблемка, что помимо Ansible и YAML надо учить ещё и Jinja.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

Продолжаю дальше экспериментировать.

Код: Выделить всё

- hosts: "BSD"
  tasks:
  - name: Syn files
    synchronize:
     src: '/mnt/test'
     dest: '/mnt/
Ошибка

Код: Выделить всё

TASK [Syn files] ******************************************************************************************************************************************************************************
fatal: [ans_prod1]: FAILED! => {"changed": false, "cmd": "/usr/local/bin/rsync --delay-updates -F --compress --archive --rsh='/usr/bin/ssh -S none -o Port=1111 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' --out-format='<<CHANGED>>%i %n%L' /mnt/test ans_prod1:/mnt/", "msg": "ssh: Could not resolve hostname ans_prod1: Name does not resolve\r\nrsync: connection unexpectedly closed (0 bytes received so far) [sender]\nrsync error: unexplained error (code 255) at io.c(228) [sender=3.2.3]\n", "rc": 255}
Я так понял что rsync не знает сетевые данные об ans_prod1, в нес в системный файл /etc/hosts ip ans_prod1 и после ансибл запустился нормально, директория /mnt/test синхронизировалась.
Хоть в конфиге ансибле host данные сетевые серверов прописаны.

Код: Выделить всё

[nodes]
ans_prod1 ansible_ssh_port=1111
ans_prod1 ansible_ssh_host=1.3.9.4
Добавлено (19:09):
SLEDopit писал(а):
29.10.2021 18:29
Например, в случае с sshd есть прекрасная директория /etc/ssh/sshd_config.d, куда можно положить файл с нужными значениями, а не править /etc/ssh/sshd_config. Его лучше оставить на откуп мантейнерам дистрибутива и не трогать. И во время обновления вопросов будет меньше. Вот выдержка из man sshd_config:
Подобное сработает если ssh запущен на стандартных настройках.
+ все равно нужно инклудить новую диру с файлами конфига.
Тоже нюанс, если параметр активирован в основном конфиге ssh, то этот же параметр про дублируется с новыми параметрами на сервере из конфига shd_config.d
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

Подскажите по такой задачи.
Есть группа на сервере ftp, в нее входят несколько пользователей.
Хочу добавить правило в крон пользователей которые в группе ftp.

Код: Выделить всё

- hosts: ans_prod
  tasks:
    - name: Who is in group ftp.
      shell: getent group ftp | cut -d: -f4 |  tr ',' '\n'
      register: users_name
    - name: add users to cron
      cron:
        name: "ftp backup"
        minute: "0"
        hour: "*/4"
        job: "sh /home/users_name.stdout_lines/back.sh"
Почему-то переменная users_name не добавляет содержимой самой переменной, а просто прописывается как есть (sh /home/users_name.stdout_lines/back.sh).
Содержимое команды.

Код: Выделить всё

getent group ftp | cut -d: -f4 |  tr ',' '\n'
igor
sir
Все это тестово делается, эксперименты провожу с ansible.
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: ansible советы по использованию

Сообщение Bizdelnick »

Ну так синтаксис ведь {{ users_name.stdout_lines }}
Да и loop здесь нужен, к тому же.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

Сейчас чуть исправил.
Переменная определяется.

Код: Выделить всё

        job: backup /home/{{ item }}
      with_items:
      - "{{ users_name.stdout_lines }}"
Но в этом случае добавляется только одна запись в кронтаб.
И запись добавляется только под тем пользователем, который конектится по ssh.

Код: Выделить всё

TASK [add users to cron] **********************************************************************************************************************************************************************
changed: [ans_prod] => (item=igor)
changed: [ans_prod] => (item=sir)
На сервере ans_prod.

Код: Выделить всё

# crontab -l
#Ansible: ftp backup
0 */3 * * * backup /home/sir
Добавлено (20:08):
С лупом чуть по другому но все равно не так как хотелось.

Код: Выделить всё

         job: backup /home/{{ item }}
      loop:
      - "{{ users_name.stdout_lines }}"

Код: Выделить всё

TASK [add users to cron] **********************************************************************************************************************************************************************
changed: [ans_prod] => (item=['igor', 'sir'])

Код: Выделить всё

# crontab -l
#Ansible: ftp backup
0 */3 * * * backup /home/['igor', 'sir']
Хочется либо что бы у рута появилась несколько записей крона.
0 */3 * * * backup /home/sir
0 */3 * * * backup /home/igor
Либо чтобы в в самом пользовательстком кронтабе от того пользователя который в группе состоит прописывалась запись.
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: ansible советы по использованию

Сообщение Bizdelnick »

Так попробуйте:

Код: Выделить всё

loop: "{{ users_name.stdout_lines }}"
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

Bizdelnick писал:
02.11.2021 20:21
Так попробуйте:

Код: Выделить всё

loop: "{{ users_name.stdout_lines }}"
Делал уже.

Код: Выделить всё

        job: backup /home/{{ item }}
      loop: "{{ users_name.stdout_lines }}"

Код: Выделить всё

TASK [add users to cron] **********************************************************************************************************************************************************************
changed: [ans_prod] => (item=igor)
changed: [ans_prod] => (item=sir)
Создается только одна запись в кроне и под рутом.

Код: Выделить всё

# crontab -l
#Ansible: ftp backup
0 */3 * * * backup /home/sir
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: ansible советы по использованию

Сообщение Bizdelnick »

bars писал:
03.11.2021 09:45
Создается только одна запись в кроне и под рутом
Так Вы ж user не задали.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

Bizdelnick писал:
03.11.2021 13:07
Так Вы ж user не задали.
Не понял, что значит не задал пользователя?
Добавлено (16:29):
Bizdelnick писал:
03.11.2021 13:07
Так Вы ж user не задали.
Понял.

Код: Выделить всё

      cron:
        user: '{{ item }}'
...
...
      loop: '{{ users_name.stdout_lines }}'
Добавлено (16:35):
С этим разобрался, а вот допустим если под рутом нужно создать несколько заданий крона?
Допустим проверять определенную директорию.

Код: Выделить всё

        name: "ftp backup"
        minute: "0"
        hour: "*/3"
        job: backup /home/'{{ item }}'
      loop: '{{ dir_name.stdout_lines }}'
Добавлено (16:38):
И с этим разобрался.
Так можно добавить несколько записей сразу в рутовый крон.
То есть под каким пользаком ансибл соединяется с серверами.

Код: Выделить всё

      cron:
#        user: '{{ item }}'
        name: "ftp backup {{ item }}" 
        minute: "0"
        hour: "*/3"
        job: backup /home/{{ item }} 
      loop: '{{ users_name.stdout_lines }}'

Код: Выделить всё

# crontab -l
#Ansible: ftp backup igor
0 */3 * * * backup /home/igor
#Ansible: ftp backup sir
0 */3 * * * backup /home/sir
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

Подскажите пожалуйста, почему команда не отрабатывает верно?

Код: Выделить всё

    - name: del ports
      shell: "rm -rf /mnt/tes_por/{*,.*}"
Как бы при выполнение ошибок нет.

Код: Выделить всё

TASK [del ports] *****************************************************************************************************************************************************
changed: [ans_prod]
В консоли такая команда отрабатывает нормально rm -rf /mnt/tes_por/{*,.*}
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

Отвечу на свой вопрос.
Сделал так.

Код: Выделить всё

    - name: del ports
      shell: "rm -rf /mnt/tes_por/{{ item }}"
      ignore_errors: yes
      loop:
      - '*'
      - '.*'
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: ansible советы по использованию

Сообщение SLEDopit »

bars писал:
04.11.2021 17:55
В консоли такая команда отрабатывает нормально rm -rf /mnt/tes_por/{*,.*}
Если правильно помню, то по умолчанию ansible пытается всё это запускать в sh, который не умеет в shell expansion, wildcards и прочие редиректы. Оболочку можно переназначить через executable. Примерно так:

Код: Выделить всё

    - name: del ports
      shell: 
        cmd: "rm -rf /mnt/tes_por/{*,.*}"
        executable: /bin/bash
(не тестировал)

зы. Согласно ansible-way лучше обходиться без shell. В данном случае можно удалить / создать директорию через модуль file. Примерно так:

Код: Выделить всё

- name: Recreate dir
  file:
    state: "{{ item }}"
    path: "/mnt/tes_por/"
    owner: 1000
    group: 1000
    mode: '0755'
  with_items:
    - absent
    - directory
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

SLEDopit писал(а):
04.11.2021 19:25
executable: /bin/bash
Спасибо за подсказку.
Работает.

Код: Выделить всё

        shell: rm -rf /mnt/tes_por/{*,.*}
        ignore_errors: yes
        args:
          executable: /bin/csh
Насчет создания директории так правильнее будет я думаю.

Код: Выделить всё

     - name: Recreate dir
       file:
         path: '/mnt/tes_por/{{ item }}'
         state: directory
         owner: root
         group: wheel
         mode: '0777'
       with_items:
       - absent
       - directory
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

Еще хотел уточнить, конфликта выполнения sheel команд не будет?
Если указать к примеру две подряд опции выполнения команд?

Код: Выделить всё

- hosts: ans_prod
  tasks:
    - name: who is in group ftp.
      shell:
        cmd: "getent group ftp | cut -d: -f4 |  tr ',' '\n' > /tmp/tee1"
        cmd: "ls /usr/ > /tmp/tee.txt"
        executable: /bin/csh

Код: Выделить всё

# ansible-playbook shel
[WARNING]: While constructing a mapping from /usr/local/etc/ansible/shel, line 5,
column 9, found a duplicate dict key (cmd). Using last defined value only.

PLAY [ans_prod] *********************************************************************

TASK [Gathering Facts] **************************************************************
ok: [ans_prod]

TASK [who is in group ftp.] *********************************************************
changed: [ans_prod]
Отрабатывает только последняя команда (cmd: "ls /usr/ > /tmp/tee.txt").
То-есть как я понял, несколько подряд команд нельзя запускать.
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: ansible советы по использованию

Сообщение Bizdelnick »

bars писал:
05.11.2021 12:05
Отрабатывает только последняя команда (cmd: "ls /usr/ > /tmp/tee.txt").
То-есть как я понял, несколько подряд команд нельзя запускать.
Можно отдельными тасками. Но, как правило, они вообще не нужны.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: ansible советы по использованию

Сообщение SLEDopit »

bars писал:
04.11.2021 19:52
Насчет создания директории так правильнее будет я думаю.

Код: Выделить всё

     - name: Recreate dir
       file:
         path: '/mnt/tes_por/{{ item }}'
         state: directory
         owner: root
         group: wheel
         mode: '0777'
       with_items:
       - absent
       - directory
Нет. С этим кодом у вас создадутся две директории /mnt/tes_por/absent и /mnt/tes_por/directory. Вам нужно {{ item }} именно в state указывать, чтобы по нему цикл шёл.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

Bizdelnick писал:
05.11.2021 13:19
Можно отдельными тасками. Но, как правило, они вообще не нужны.
Не понял.
Поясните пожалуйста.
Добавлено (13:33):
SLEDopit писал(а):
05.11.2021 13:25
чтобы по нему цикл шёл.
Так же не понял, что вы имеете ввиду?
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: ansible советы по использованию

Сообщение Bizdelnick »

bars писал:
05.11.2021 13:32
Bizdelnick писал:
05.11.2021 13:19
Можно отдельными тасками. Но, как правило, они вообще не нужны.
Не понял.
Поясните пожалуйста.
Что именно пояснить? Как создать две таски, или почему шелл обычно не нужен?
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

Bizdelnick писал:
05.11.2021 13:38
почему шелл обычно не нужен?
Это.
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 20752
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: ansible советы по использованию

Сообщение Bizdelnick »

В ansible есть модули на все случаи жизни. Их использовать надёжнее, чем шелл, потому что шелловские команды могут создать проблемы с переносимостью. Между двумя установками одной и той же системы, если в одной не хватает какой-то команды, между двумя разными версиями одной и той же системы, или, тем более, если решите что-то с фряхи на линукс перевести.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: ansible советы по использованию

Сообщение SLEDopit »

bars писал:
05.11.2021 13:32
Так же не понял, что вы имеете ввиду?
Чтобы очистить полностью всё содержимое директории, нужно её сначала удалить, а потом создать обратно. В цикле, который я привёл, именно это и происходит. {{ item }} подставляется в state и ansible понимает, что с одной и той же директорией нужно делать разные вещи. В вашем переделанном варианте {{ item }} подставляется в имя директории, а state остается тем же самым. Таким образом ansible вместо удаления / создания одной и той же директории создаёт 2 разные директории внутри вашей целевой. Что немного отличается от поставленной цели.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

Продолжаю изучения ansible.
Есть чистый сервер, на нем питон не установлен, вообще ничего не установлен, только добавлен ssh запущен.
так вот пытаюсь через raw установить питона.

Код: Выделить всё

- hosts: ans_test
  pre_tasks:
    - name: 'Install python.'
      raw: pkg install python38
Вот что получаю, говорит что нет питона и задача не выполнима.
Как я понял с помощью raw модуля, можно устанавливать питона на удаленные сервера.

Код: Выделить всё

ansible-playbook shel

PLAY [ans_test] *******************************************************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************************************
fatal: [ans_test]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"ansible.legacy.setup": {"failed": true, "module_stderr": "Shared connection to 3.4.7.9 closed.\r\n", "module_stdout": "/bin/sh: /usr/local/bin/python: not found\r\n", "msg": "The module failed to execute correctly, you probably need to set the interpreter.\nSee stdout/stderr for the exact error", "rc": 127}}, "msg": "The following modules failed to execute: ansible.legacy.setup\n"}

PLAY RECAP ************************************************************************************************************************************************************
ans_test                   : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0  
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Аватара пользователя
bars
Сообщения: 917
ОС: BSD/LINUX
Контактная информация:

Re: ansible советы по использованию

Сообщение bars »

Разобрался.
Странно параметр gather_facts: False указан глобально у меня.

Код: Выделить всё

egrep gather_facts: ansible.cfg 
gather_facts: false
Пришлось указать индивидуально в playbook задачи.

При установки менеджер паркетов требовал поддверждения что установит зависимости по порту.
Добавил ключ -y к установке и спустя какоето время ( пока обновится репа) питон установил, после задача создать симлинк и можно пользоваться.

Код: Выделить всё

- hosts: ans_test
  gather_facts: False
  pre_tasks:
    - name: 'Install python.'
      raw: pkg install -y python38

    - name: "Symlink created."
      raw: 'ln -s /usr/local/bin/python3.8 /usr/local/bin/python'
      register: set_symlink
      failed_when: set_symlink.rc != 0 and set_symlink.rc != 1
Добавлено (11:27):
Думаю лучше добавить проверку наличия питона.

Код: Выделить всё

    - name: 'Install python.'
      raw: test -e /usr/local/bin/python || (pkg install -y python38)

    - name: "Symlink created."
      raw: test -e /usr/local/bin/python || (ln -s /usr/local/bin/python3.8 /usr/local/bin/python)
Настройка BSD систем
Знание сила, незнание Рабочая сила!
Спасибо сказали:
Ответить