Как сложить переменные разных хостов в Ansible

#ansible

Вопрос:

У меня ситуация, похожая на следующую:

 all:
  hosts:
    host1:
      num: 3

    host2:
      num: 4

    host3:
      num: 2
 

Я хочу создать шаблон файла для хостов, который должен num шаг за шагом агрегировать значение на каждом из хостов, начиная с 1.

Так, например , для хоста 1 содержимое новой переменной/файла from должно быть 1 , для хоста 2 оно должно быть 4 (1 3), а для хоста 3 8 (4 4). Но порядок выполнения на самом деле не имеет значения — это также может быть: хост3 1 , хост1 3 (1 2), хост2 6 (3 3). Таким образом, переменная num в основном указывает, сколько элементов будет обрабатывать хост, и цель моего вопроса состоит в том, чтобы предоставить каждому из хостов выделенный диапазон номеров, который был бы [from,from num-1] .

РЕДАКТИРОВАТЬ: Я еще раз подумал об этом, и это также можно было бы просчитать заранее. В основном я хочу перейти от [3,4,2] к [0,3,7](или [1,4,8]). К сожалению, я не могу найти фильтр Jinja2, который делает это.

Комментарии:

1. Может быть, вы можете использовать делегирование фактов для этого docs.ansible.com/ansible/latest/user_guide/…

2. видеть set_stats

3. Я не знаю, как получить список хостов, заказанных путем выполнения заказа на основе инвентаризации . Боюсь, это невозможно. Если это так, то ваша проблема не может быть решена. Конечно, вы можете создать список или словарь с увеличенными значениями. Но вы никогда не будете уверены в порядке хозяев.

4. @VladimirBotka на самом деле речь не идет о порядке выполнения, это может быть просто любой заказ, с которым согласны хосты. Таким образом, это также может быть предварительно рассчитано на компьютере контроллера. В основном я просто хочу уменьшить/сопоставить массив [a,b,c] с [1, a 1, a b 1].

5. В этом случае вы также можете «сократить» вопрос.

Ответ №1:

Вопрос: «уменьшите/сопоставьте массив [a,b,c] с [1, a 1, a b 1]«

Ответ: карта не применяет фильтры аддитивно. Боюсь, что необходима итерация. Например, учитывая список

 l: [10, 20, 30]
 

создайте элементы и объедините новый список

     - set_fact:
        l2: "{{ l2|d([])   [l[0:(item)]|sum   1] }}"
      loop: "{{ range(0, l|length) }}"
 

дает

   l2:
  - 1
  - 11
  - 31
 

Конечно, вы можете написать фильтр, если хотите сократить список за один шаг.

Комментарии:

1. Большое вам спасибо! Как новичок в Ansible/Jinja2, мне, вероятно, потребовалось бы несколько часов, чтобы придумать это решение… Я не «сводил» свой вопрос только к этому, потому что я также хотел включить аспект использования результата на моих отдельных хостах, с которым я также борюсь. Может быть, вы могли бы указать мне направление, в котором мне нужно идти сюда? Может быть, я могу начать с объекта, похожего на карту [{1.1.1.1: 10}, {2.2.2.2: 20}, {3.3.3.3: 30}] и просто преобразуйте это в [{1.1.1.1: 1}, {2.2.2.2: 11}, {3.3.3.3: 31}] как мы поступили со списком. Затем я подумал, что смогу получить доступ к значению для каждого хоста.