Ansible:如何将字典(不确定数量的 key:value 对)转换为字符串?

Ansible: How to convert a dictionary (indeterminate number of key:value pairs) to a string?

在 Ansible 剧本中,我如何过滤具有不确定数量的 key:value 对的字典以将其转换为字符串,然后我可以将其用作 Ansible shell 的命令字符串例如模块?

下面的示例手册说明了数据、问题和预期结果。

---

- name: Convert a dictionary into a string containing the key value pairs to run as a shell command

  hosts:
    - all

  vars:
    devices:
      - parameter_key: foo_device
        parameter_a: value1
        parameter_b: value2
        parameter_c: value3
      - parameter_key: bar_device
        parameter_a: value4
        parameter_b: value5
        parameter_d: value6
        parameter_e: value7

      # or like this
      - foo_device:
          parameter_a: value1
          parameter_b: value2
          parameter_c: value3
      
      - bar_device:
          parameter_a: value4
          parameter_b: value5
          parameter_d: value6
          parameter_e: value7
      
  tasks:

    - set_fact:
        # I have no idea what to do here
      loop: devices

# desired result is a string, or array or strings I can then feed to the ansible shell module for execution on the host

      command_str1: "{{ foo_cmd foo_device --parameter_a value1 --parameter_b value2 --parameter_c value3 }}"

      command_str2: "{{ foo_cmd bar_device --parameter_a value4 --parameter_b value5 --parameter_d value6 --parameter_e value7 }}"

# and so on if there was more devices

请查看循环内的 dict2item 过滤器。因此,您可以遍历一个字典并使用 item.key 获取字典的键,然后使用 dict[item.key] 获取值。 set_fact 中的所有内容,您将拥有自己的字符串。

我想,没有比这更简单的方法了。

- hosts: localhost
  vars:
    devices:
      - parameter_key: foo_device
        parameter_a: value1
        parameter_b: value2
        parameter_c: value3
      - parameter_key: bar_device
        parameter_a: value4
        parameter_b: value5
        parameter_d: value6
        parameter_e: value7
  tasks:
    - include_tasks: "task.yml"
      loop: "{{ devices }}"
      loop_control:
        loop_var: device

包含的 task.yml 包含:

---
- set_fact:
    cmd: "my_command"

- set_fact:
    cmd: "{{ cmd }} {{ item.value }}"
  when: "item.key == 'parameter_key'"
  loop: "{{ device | default({}) | dict2items }}"

- set_fact:
    cmd: "{{ cmd }} --{{ item.key }} {{ item.value }}"
  when: "item.key != 'parameter_key'"
  loop: "{{ device | default({}) | dict2items }}"

- debug:
    msg: "{{ cmd }}"

输出将是:

ok: [localhost] => 
  msg: my_command foo_device --parameter_a value1 --parameter_b value2 --parameter_c value3


ok: [localhost] => 
  msg: my_command bar_device --parameter_a value4 --parameter_b value5 --parameter_d value6 --parameter_e value7

这应该有效:

  tasks:
    - debug:
        msg: "command is: {{ item.key }} with value of --parameter_b {{ item.value.parameter_b }}"
      loop: "{{ devices[2] | dict2items }}"

给予

    "msg": "command is: foo_device with value of --parameter_b value2"

请注意,变量中的值是以列表形式放置的。如果转换成实际的字典会更方便。