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"
请注意,变量中的值是以列表形式放置的。如果转换成实际的字典会更方便。
在 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"
请注意,变量中的值是以列表形式放置的。如果转换成实际的字典会更方便。