【问题标题】:How to save the return values of different hosts with separate variables如何用不同的变量保存不同主机的返回值
【发布时间】:2021-12-28 11:03:48
【问题描述】:

这是我的剧本:

---

- hosts: server 
  gather_facts: false
  tasks:
  - name: 
    shell: ping -c 1 -W 1 <ip_addr>
    register: shell_result_var
  - name:
    set_fact:
      time_fact: "{{ ((shell_result_var['stdout_lines'][1] | split('='))[3] | split(' '))[0] }}"

执行ansible-playbook playbook.yml -vvv

TASK [set_fact] **************************************************************************************************************************************************************
task path: /home/playbook.yml:9
ok: [*.*.*.*] => {"ansible_facts": {"time_fact": "56.9"}, "changed": false}
ok: [*.*.*.*] => {"ansible_facts": {"time_fact": "32.1"}, "changed": false}
META: ran handlers
META: ran handlers

我想将这两个字符串(“56.9”和“32.1”)保存在不同的变量中,并将它们转换为数字来计算它们

【问题讨论】:

    标签: ansible ansible-2.x ansible-template


    【解决方案1】:

    我想将这两个字符串(“56.9”和“32.1”)保存在不同的变量中,并将它们转换为数字来计算它们

    ping 命令的输出是一个浮点数,所以我把它当成这样。我添加了一个示例,您可以使用它进行计算。

    - hosts:
        - test-multi-01
      gather_facts: false
      tasks:
        - name:
          shell: 'ping -c 1 -W 1 <ip> |  grep -Po "time=.*"'
          register: shell_result_var
    
        - set_fact:
            ping_number: "{{ shell_result_var.stdout | regex_replace(' ms','') | regex_replace('time=','') | float }}"
    
        - debug:
            msg: "{{ ping_number | float + 0.1 }}"
    

    生产:

    ok: [test-multi-01] => {
        "msg": "0.33499999999999996"
    }
    

    【讨论】:

    • 谢谢。如果我想动态计算不同主机返回的结果应该怎么做。比如在ok: [*.*.*.*] =&gt; {"ansible_facts": {"time_fact": "56.9"}, "changed": false}ok: [*.*.*.*] =&gt; {"ansible_facts": {"time_fact": "32.1"}, "changed": false}中加上time(56.9+32.1)的值
    【解决方案2】:

    根据您的问题和不同的 cmets,我不确定您要计算什么。因此,这是一个非常基本的示例,用于获取所有主机的总和和平均值。

    您可以查看jinja2 filteransible filters 的文档,了解有关我在剧本中使用的表达式的更多信息。

    请注意,jinja2 输出字符串,因此传递给set_fact 的值将转换回字符串。因此,在剧本的不同点使用大量 float 过滤器并不是过度预防,而是绝对必要的。

    我使用了以下“假”清单ìnv.yml,两台主机都解析到我的本地计算机。

    ---
    all:
        vars:
            ansible_connection: local
        hosts:
            test1:
            test2:
    

    还有test.yml 剧本:

    ---
    - hosts: all
      gather_facts: false
    
      tasks:
        - name: Run ping command
          shell: ping -c 1 -W 1 192.168.0.2
          register: ping_cmd
          changed_when: false
        
        - name: set ping time for each host
          set_fact:
            ping_time: "{{ ((ping_cmd.stdout_lines[1] | split('='))[3] | split(' '))[0] }}"
            
        - name: set total ping time once for all hosts
          set_fact:
            total_ping_time: "{{ play_hosts | map('extract', hostvars)
              | map(attribute='ping_time') | map('float') | sum }}"
          run_once: true
    
        - name: set mean ping time once for all hosts
          set_fact:
            mean_ping_time: "{{ ((total_ping_time | float) / (play_hosts | length)) }}"
          run_once: true
    
        - name: show the result
          debug:
            msg: "For this host, ping_time is {{ ping_time }}s
            for a total of {{ total_ping_time | float | round(3) }}s
            and an average of {{ mean_ping_time | float | round(3) }}s"
    

    这给出了:

    $ ansible-playbook -i inv.yml test.yml 
    
    PLAY [all] ********************************************************************************************************************************************************************************************************
    
    TASK [Run ping command] *******************************************************************************************************************************************************************************************
    ok: [test1]
    ok: [test2]
    
    TASK [set ping time for each host] ********************************************************************************************************************************************************************************
    ok: [test1]
    ok: [test2]
    
    TASK [set total ping time once for all hosts] *********************************************************************************************************************************************************************
    ok: [test1]
    
    TASK [set mean ping time once for all hosts] **********************************************************************************************************************************************************************
    ok: [test1]
    
    TASK [show the result] ********************************************************************************************************************************************************************************************
    ok: [test1] => {
        "msg": "For this host, ping_time is 0.137s for a total of 0.214s and an average of 0.107s"
    }
    ok: [test2] => {
        "msg": "For this host, ping_time is 0.077s for a total of 0.214s and an average of 0.107s"
    }
    
    PLAY RECAP ********************************************************************************************************************************************************************************************************
    test1                      : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    test2                      : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    

    【讨论】:

    • 是的。当我读到他对我的回答的评论时,这就是他真正想要的。
    • 你太客气了,这就是我想要的。我从你的回答中学到了很多
    【解决方案3】:

    您可以使用特殊变量hostvars 访问每个主机的变量。例如,使用run_once,您可以在 ansible 供应商上运行一次您想要的“计算操作”。

    - hosts: server
      name: https://stackoverflow.com/q/70506128/13953427
      become: no
      gather_facts: false
      
      tasks:
        - name: Test reachability to 1.1.1.1
          ansible.builtin.shell: ping -c 1 -W 1 1.1.1.1 | grep --only-matching "time=.*"
          register: ping_result
    
        - name: extract time from ping output
          ansible.builtin.set_fact:
            ping_number: "{{ ping_result.stdout | regex_replace(' ms','') | regex_replace('time=','') | float }}"
    
        - name: debug ping time of each host
          ansible.builtin.debug:
            var: ping_number
    
        - name: set total ping time once for all hosts
          ansible.builtin.set_fact:
            total: "{{ total | default(0.0) | float + hostvars[item].ping_number | float  }}"
          loop: "{{ ansible_play_hosts }}"
          run_once: true
    
        - name: set average ping time once for all hosts
          ansible.builtin.set_fact:
            average_ping_time: "{{ total|float / ansible_play_hosts|length }}"
          run_once: true
    
        - name: debug total ping time
          ansible.builtin.debug:
            var: total
          run_once: true
    
        - name: debug average ping time
          ansible.builtin.debug:
            var: average_ping_time
          run_once: true
    
    PLAY [https://stackoverflow.com/q/70506128/13953427] ***************************************************************************************************
    
    TASK [Test reachability to 1.1.1.1] ********************************************************************************************************************
    Tuesday 28 December 2021  13:28:11 +0000 (0:00:00.028)       0:00:00.028 ****** 
    changed: [host1]
    changed: [host2]
    
    TASK [gather time as float] ****************************************************************************************************************************
    Tuesday 28 December 2021  13:28:12 +0000 (0:00:00.705)       0:00:00.733 ****** 
    ok: [host1]
    ok: [host2]
    
    TASK [print individual time] ***************************************************************************************************************************
    Tuesday 28 December 2021  13:28:12 +0000 (0:00:00.083)       0:00:00.817 ****** 
    ok: [host1] => 
      ping_number: '1.71'
    ok: [host2] => 
      ping_number: '3.89'
    
    TASK [gather] ******************************************************************************************************************************************
    Tuesday 28 December 2021  13:28:12 +0000 (0:00:00.100)       0:00:00.917 ****** 
    ok: [host1 -> localhost] => (item=host1)
    ok: [host1 -> localhost] => (item=host2)
    
    TASK [do something] ************************************************************************************************************************************
    Tuesday 28 December 2021  13:28:12 +0000 (0:00:00.042)       0:00:00.960 ****** 
    ok: [host1 -> localhost]
    
    TASK [do something] ************************************************************************************************************************************
    Tuesday 28 December 2021  13:28:12 +0000 (0:00:00.022)       0:00:00.983 ****** 
    ok: [host1 -> localhost] => 
      total: '5.6'
    
    TASK [do something] ************************************************************************************************************************************
    Tuesday 28 December 2021  13:28:12 +0000 (0:00:00.022)       0:00:01.005 ****** 
    ok: [host1 -> localhost] => 
      average_ping_time: '2.8'
    
    PLAY RECAP *********************************************************************************************************************************************
    host1               : ok=7    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    host2               : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
    

    【讨论】:

    • debugset_fact 委派给localhost 是一种挑战:这些任务始终在控制器上运行,而与远程目标没有任何连接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多