Значение регистра Ansible sum

#ansible #jinja2

#ansible #jinja2

Вопрос:

Как получить сумму двух хостов с помощью фильтрации Jinja2 ansible host1 и host 2

 ---
- name: Count Check
  hosts: MYGROUP
  gather_facts: true
  user: sv_admin
  tasks:
    - name: count check
      shell: cat /etc/hosts | wc -l
      register: command_result
    - debug:
        var: command_result.stdout
    - set_fact:
        total_result: "{{ command_result.stdout | map('int') | sum(start=0) }}"
    - debug:
        msg: "Total count: {{ total_result }}" 
  

Вывод сборника воспроизведения

 TASK [debug] *****************************************************************
ok: [Host-01] => {
  "msg": "Total count:      134"
}
ok: [Host-02] => {
  "msg": "Total count:      133"
}
  

Ответ №1:

Используйте извлечение и суммирование. Например, приведенный ниже сборник пьес

 shell> cat playbook.yml
- hosts: test_01:test_03
  gather_facts: false
  tasks:
    - shell: cat /etc/hosts | wc -l
      register: command_result
    - debug:
        var: command_result.stdout
    - set_fact:
        total_result: "{{ ansible_play_hosts_all|
                          map('extract', hostvars, ['command_result', 'stdout'])|
                          map('int')|
                          sum }}"
      run_once: true
    - debug:
        var: total_result
  

выдает (сокращенное)

 shell> ansible-playbook playbook.yml 

PLAY [test_01:test_03] ****

TASK [shell] ****
changed: [test_01]
changed: [test_03]

TASK [debug] ****
ok: [test_01] => {
    "command_result.stdout": "      62"
}
ok: [test_03] => {
    "command_result.stdout": "      31"
}

TASK [set_fact] ****
ok: [test_01]

TASK [debug] ****
ok: [test_03] => {
    "total_result": "93"
}
ok: [test_01] => {
    "total_result": "93"
}
  

Ответ №2:

Для этого вы можете использовать пользовательскую статистику:https://docs.ansible.com/ansible/latest/modules/set_stats_module.html

Итак, для вашего случая это будет выглядеть так

 ---
- name: Count Check
  hosts: MYGROUP
  gather_facts: true
  user: sv_admin
  tasks:
    - name: count check
      shell: cat /etc/hosts | wc -l
      register: command_result
    - debug:
        var: command_result.stdout
    - set_fact:
        host_result: "{{ command_result.stdout }}"
    - debug:
        msg: "Count for this host: {{ host_result }}"
    - set_stats:
        data: "{{ { 'total_count': host_result | int } }}"
  

Затем, если вы запустите его с ANSIBLE_SHOW_CUSTOM_STATS=yes , он покажет вам результат в конце:

 $ ANSIBLE_SHOW_CUSTOM_STATS=yes ansible-playbook -i inventory pb.yml
... (usual output)

CUSTOM STATS: *************************************************************

    RUN: { "total_count": 267}

  

set_stats Задача по умолчанию объединяет результаты со всех хостов, что и является тем, что вы ищете. Однако вам нужно убедиться, что значения являются целыми числами, потому что, если они являются строками, они просто объединят их, и в итоге вы получите что-то вроде RUN: { "total_count": "134133"} . Вот почему я поставил data: бит так, как у меня есть — если вы попытаетесь создать словарь в обычном yaml, например

   data:
    total_count: "{{ host_result | int }}"
  

вы увидите, что значение по-прежнему является строкой (из-за того, как работает yaml / jinja), и оно не будет работать должным образом.