Ansible 将变量注册到预先存在的列表中

Ansible 将变量注册到预先存在的列表中,ansible,ansible-playbook,ansible-2.x,Ansible,Ansible Playbook,Ansible 2.x,我有一个列表和一个with_items循环,我在其中浏览列表。我的问题是,当我浏览列表时,如何将结果注册/附加到现有列表中?我使用的是Ansible版本2.0.1.0 我的列表: channels: channel1: item1: 'value' item2: 'value' channel2: item1: 'value' item2: 'value' - name: Do a shell command for each channel she

我有一个列表和一个with_items循环,我在其中浏览列表。我的问题是,当我浏览列表时,如何将结果注册/附加到现有列表中?我使用的是Ansible版本2.0.1.0

我的列表:

channels:
  channel1:
    item1: 'value'
    item2: 'value'
  channel2:
    item1: 'value'
    item2: 'value'
- name: Do a shell command for each channel
  shell: some command that returns a number with the help {{ item }}
  with_items: "{{ channels }}"
  register: channels.item3.result #?? not sure how to do this
channels:
  channel1:
    item1: 'value'
    item2: 'value'
    item3: 'result from shell command'
  channel2:
    item1: 'value'
    item2: 'value'
    item3: 'result from shell command'
循环:

channels:
  channel1:
    item1: 'value'
    item2: 'value'
  channel2:
    item1: 'value'
    item2: 'value'
- name: Do a shell command for each channel
  shell: some command that returns a number with the help {{ item }}
  with_items: "{{ channels }}"
  register: channels.item3.result #?? not sure how to do this
channels:
  channel1:
    item1: 'value'
    item2: 'value'
    item3: 'result from shell command'
  channel2:
    item1: 'value'
    item2: 'value'
    item3: 'result from shell command'
执行调试var=channels时的输出应该是什么:

channels:
  channel1:
    item1: 'value'
    item2: 'value'
  channel2:
    item1: 'value'
    item2: 'value'
- name: Do a shell command for each channel
  shell: some command that returns a number with the help {{ item }}
  with_items: "{{ channels }}"
  register: channels.item3.result #?? not sure how to do this
channels:
  channel1:
    item1: 'value'
    item2: 'value'
    item3: 'result from shell command'
  channel2:
    item1: 'value'
    item2: 'value'
    item3: 'result from shell command'

有很多方法可以更新字典,但它们都会被阻止,因为Ansible(我相信)不会在不同的任务之间对变量进行更改,除了“set_fact”的情况,而且,唉,你不能在字典中设置_fact

您需要创建一个Jinja2过滤器,将项目设置到字典的深处。然后在任务上使用“register”捕获输出,然后使用修改后的字典在“channels”上设置事实。例如:

- set_fact: channels: "{{ channels|deep_set(item+'.item3', result) }}" -设定事实: 通道:{{channels | deep_set(item+'.item3',result)}” 在deep_set filter的定义中,类似这样的功能应该可以工作:

@environmentfilter do_deep_set(environment, value, attr, val): parent = value parts = [int(x) if x.isdigit(x) else x for x in attr.split('.')] for part in parts: parent=environment.getitem(parent, part) parent[part[-1]] = val return value @环境过滤器 do_deep_set(环境、值、属性、值): 父项=值 parts=[int(x)if x.isdigit(x)else x for x in attr.split('.')] 对于部分中的部分: 父项=环境.getitem(父项,零件) 父项[部分[-1]]=val 返回值
我使用environment.getitem只是为了防止部件的任何部分是属性而不是索引/键。设置总是设置元素。

有很多方法可以在适当的位置更新字典,但它们都会受到阻碍,因为Ansible(我相信)不会在任务之间对变量进行更改,除了“设置事实”的情况,而且,唉,你不能将事实设置到字典中

您需要创建一个Jinja2过滤器,将项目设置到字典的深处。然后在任务上使用“register”捕获输出,然后使用修改后的字典在“channels”上设置事实。例如:

- set_fact: channels: "{{ channels|deep_set(item+'.item3', result) }}" -设定事实: 通道:{{channels | deep_set(item+'.item3',result)}” 在deep_set filter的定义中,类似这样的功能应该可以工作:

@environmentfilter do_deep_set(environment, value, attr, val): parent = value parts = [int(x) if x.isdigit(x) else x for x in attr.split('.')] for part in parts: parent=environment.getitem(parent, part) parent[part[-1]] = val return value @环境过滤器 do_deep_set(环境、值、属性、值): 父项=值 parts=[int(x)if x.isdigit(x)else x for x in attr.split('.')] 对于部分中的部分: 父项=环境.getitem(父项,零件) 父项[部分[-1]]=val 返回值 我使用environment.getitem只是为了防止部件的任何部分是属性而不是索引/键。设置总是设置元素