如何在Ansible设置命令中放置多个过滤器参数

时间:2018-06-26 08:27:34

标签: linux bash ansible

我想使用ansible setup模块在​​for循环中检索主机规范。

规格:

declare -a specs=("ansible_all_ipv4_addresses" "ansible_processor" "ansible_processor_cores" "ansible_uptime_seconds")

For循环:

for i in "${specs[@]}"
do
    ansible rhelmachines -m setup -a 'filter='$i'
done

如何仅在一个连接中串联多个过滤器?

谢谢!

4 个答案:

答案 0 :(得分:0)

specs=( "ansible_all_ipv4_addresses"
        "ansible_processor"
        "ansible_processor_cores"
        "ansible_uptime_seconds" )
args=( )
for spec in "${specs[@]}"; do args+=( -a "$spec" ); done
ansible rhelmachines -m setup "${args[@]}"

...将导致您的最终命令等效于:

ansible rhelmachines -m setup \
  -a ansible_all_ipv4_addresses \
  -a ansible_processor \
  -a ansible_processor_cores \
  -a ansible_uptime_seconds

答案 1 :(得分:0)

我发现在不使用bash脚本的情况下使用Ansible的一种解决方案是展开 local_action 命令和单个任务中的循环。然后,Playbook会在多个主机上进行迭代。

---
- hosts: rhelmachines
  gather_facts: True
  tasks:
  - name: Gather Facts
    setup:
        gather_subset=all
    register: facts

  - debug:
      msg: "{{ facts.ansible_facts.ansible_all_ipv4_addresses }}"

  - name: copy content from facts to output file
    local_action:
     module: lineinfile
     line: "{{ item }}"
     path: /tmp/assessments/facts.txt
    loop:
      - "{{ facts.ansible_facts.ansible_all_ipv4_addresses }}"
      - "{{ facts.ansible_facts.ansible_all_ipv6_addresses }}"

答案 2 :(得分:0)

有一些sed黑客将ansible的输出转换为JSON,您可以使用jq仅提取所需的片段:

ansible -m setup localhost | sed -e 's/^[[:alpha:]].*[|].* [>][>] {$/{/' | jq -n '
[inputs |
 .ansible_facts as $facts |
 $facts.ansible_hostname as $hostname |
 {($hostname): {
    "ipv4_addresses":  $facts.ansible_all_ipv4_addresses,
    "processor": $facts.ansible_processor[0],
    "cores": $facts.ansible_processor_cores,
    "uptime": $facts.ansible_uptime_seconds}}] | add'

...生成以下形式的输出:

{
  "my-current-hostname": {
    "ipv4_addresses": [
      "192.168.119.129"
    ],
    "processor": "Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz",
    "cores": 1,
    "uptime": null
  }
}

(以ansible 1.4.5运行,不会产生正常运行时间。)

答案 3 :(得分:0)

我接受了@Luigi Sambolino的回答,并使它变得更好。他的回答在清单中的多个主机上都失败了。他建议使用lineinfile,它在这种情况下有一个缺点-与其他机器相同的每个事实都被省略了。另一个缺点是结果没有排序在一起,而是混合在一起。

我需要掌握一些有关系统的基本信息,例如IP,OS版本等。这是我的剧本:

- hosts: all
  gather_facts: true
  ignore_unreachable: true
  tasks:
  - name: get the facts
    setup:
      gather_subset=all
    register: facts
  - name: remove file
    local_action:
      module: file
      path: results
      state: absent
  - name: save results in file
    local_action:
      module: shell
      cmd: echo "{{ item }}" >> results
    with_together:
      - "{{ facts.ansible_facts.ansible_default_ipv4.address }}"
      - "{{ facts.ansible_facts.ansible_architecture }}"
      - "{{ facts.ansible_facts.ansible_distribution }}"
      - "{{ facts.ansible_facts.ansible_distribution_version }}"
      - "{{ facts.ansible_facts.ansible_hostname }}"
      - "{{ facts.ansible_facts.ansible_kernel }}"

现在结果如下:

...
['10.200.1.21', 'x86_64', 'Ubuntu', '18.04', 'bacula', '4.15.18-7-pve']
['10.200.2.53', 'x86_64', 'Ubuntu', '18.04', 'webserver', '4.15.18-27-pve']
...

sed可以删除方括号,例如,我们有一个漂亮的CSV文件,可用于任何电子表格。