选择Ansible任务中每个项目有条件的with_items?

问题描述 投票:2回答:1

我有一个需要根据群集位置选择的代理列表。例如,我的群集名称是“ abc”和“ def”。群集上的所有节点均以群集名称开头(例如,abc1023.net表示abc等)

我想基于当前inventory_hostname选择点的代理并将其提供在参数中。我尝试使用with_items的地图,并根据以下代码在地图内“创建” when条件:

- name: run pip on proxy
  pip:
    name: <package_name>
    extra_args: "--proxy item.proxy"
  when: "item.when"
  with_items:
    - {proxy: 'http:abc_proxy:port', when: "'abc' in {{inventory_hostname|lower}}"}
    - {proxy: 'http:def_proxy:port', when: "'def' in {{inventory_hostname|lower}}"}

我面临的问题是,这种情况总是被认为是真实的。我尝试将when: "'abc' in {{inventory_hostname|lower}}"替换为when: false,但实际上可行。也就是说,将其设为显式false实际上会返回false,但当我检查字符串引号中的条件时不会返回false。我认为,如果地图中包含任何值,则仅会被视为真实。

如何在when映射中明确检查此条件?删除引号无济于事,因为它会引发语法错误:

We could be wrong, but this one looks like it might be an issue
with missing quotes.  Always quote template expression brackets when
they start a value. For instance:

    with_items:
      - {{ foo }}

Should be written as:

    with_items:
      - "{{ foo }}"

exception type: <class 'yaml.parser.ParserError'> 

尝试其他解决方案

  1. 在任务中添加了变量
- name: run pip on proxy
  vars:
    abc_status: "{{ true if 'abc' in {{inventory_hostname|lower}} else false }}"
    def_status: "{{ true if 'def' in {{inventory_hostname|lower}} else false }}"
  pip:
    name: <package_name>
    extra_args: "--proxy item.proxy"
  when: "item.when"
  with_items:
    - {proxy: 'http:abc_proxy:port', when: abc_status}
    - {proxy: 'http:def_proxy:port', when: def_status}

2。将任务添加到set_fact

- set_fact:
    abc_status: true
  when: inventory_hostname|lower is match('abc.*')

- set_fact:
    def_status: true
  when: inventory_hostname|lower is match('def.*')
  1. 测试了错误的案例我通过以下方式在abc群集上测试了错误的情况:
- name: run pip on proxy
  vars:
    abc_status: "{{ true if 'abc' in {{inventory_hostname|lower}} else false }}"
    def_status: "{{ true if 'def' in {{inventory_hostname|lower}} else false }}"
  pip:
    name: <package_name>
    extra_args: "--proxy item.proxy"
  when: "item.when"
  with_items:
    - {proxy: 'http:def_proxy:port', when: def_status}

这应该总是失败,因为代理服务器以及when条件在def群集上检查而在abc群集上运行时。但是我得到以下Ansible输出:

TASK [<project> : run pip on proxy] ************************************************
changed: [abc1023.net] => (item={u'when': u'def_status', u'proxy': u'http:def_proxy:port'})

这也是我从其他尝试过的解决方案中获得的输出。

问题

即使尝试了不同的解决方案,when: "item.when"始终返回true(即使应返回false)。我怎样才能解决这个问题?有没有更好的解决方案来实现我的用例?为了完整起见,我使用的是Ansible 2.4.1.0。

ansible yaml ansible-2.x
1个回答
1
投票

TL; DR;

这里,您正在尝试评估string "item.when"true的布尔值,这是因为非空字符串将导致true语句。删除when条件周围的双打引号,您应该可以参加。


您从Ansible得到的警告是关于when的,只有此语句,它始终是原始的Jinja2表达式。

这在Ansible中使用when子句很容易做到,其中包含不带双花括号的原始Jinja2表达式(请参阅group_by – Create Ansible groups based on facts)。

来源:https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html#the-when-statement,重点,我的。] >>

鉴于您的实际剧本,可能的解决方案可能是:

- name: run pip on proxy
  pip:
    name: <package_name>
    extra_args: "--proxy item.proxy"
  when: item.proxy_ref in inventory_hostname|lower
  with_items:
    - proxy: 'http:abc_proxy:port'
      proxy_ref: 'abc'
    - proxy: 'http:def_proxy:port'
      proxy_ref: 'def'

另一个可能是:

- name: run pip on proxy
  pip:
    name: <package_name>
    extra_args: "--proxy item.proxy"
  when: item.when
  with_items:
    - proxy: 'http:abc_proxy:port'
      when: "{{ 'abc' in inventory_hostname|lower }}"
    - proxy: 'http:def_proxy:port'
      when: "{{ 'def' in inventory_hostname|lower }}"

因此,简而言之,在这里,您试图评估string

"item.when"是一个布尔值,即true,这是因为非空字符串将导致true声明。删除when条件周围的双打引号,您应该可以参加。

PS:在可能的情况下,尽量不要将JSON语法与YAML语法混合使用

© www.soinside.com 2019 - 2024. All rights reserved.