【问题标题】:How can I check a string contains all values in a list?如何检查字符串是否包含列表中的所有值?
【发布时间】:2021-04-02 09:16:41
【问题描述】:

我正在尝试通过将cluster_status 命令输出到一个变量来验证rabbitmq 集群状态,然后查看输出是否包含该组的所有主机。如果缺少任何主机,则退出。

如何检查字符串 (command_output) 是否包含列表 (group_hosts) 中的所有值?

我的代码:

- name: check cluster status
  command: rabbitmqctl cluster_status
  register: cluster_status
  changed_when: false

输出:

    "stdout": "Cluster status of node rabbit@ip-127.0.0.1 ...\n[{nodes,[{disc,['rabbit@ip-127.0.0.1','rabbit@ip-127.0.0.2']}]},\n {running_nodes,['rabbit@ip-127.0.0.2','rabbit@ip-127.0.0.1']},\n {cluster_name,<<\"rabbit@ip-127.0.0.2.ec2.internal\">>},\n {partitions,[]},\n {alarms,[{'rabbit@ip-127.0.0.2',[]},{'rabbit@ip-127.0.0.1',[]}]}]",
    "stdout_lines": [
        "Cluster status of node rabbit@ip-127.0.0.1 ...",
        "[{nodes,[{disc,['rabbit@ip-127.0.0.1','rabbit@ip-127.0.0.2']}]},",
        " {running_nodes,['rabbit@ip-127.0.0.2','rabbit@ip-127.0.0.1']},",
        " {cluster_name,<<\"rabbit@ip-127.0.0.2.ec2.internal\">>},",
        " {partitions,[]},",
        " {alarms,[{'rabbit@ip-127.0.0.2',[]},{'rabbit@ip-127.0.0.1',[]}]}]"
    ]

列出变量变量:

group_hosts=[ip-127.0.0.1,ip-127.0.0.2]

如何从 stdout 获取以下行到变量?

running_nodes,['rabbit@ip-127.0.0.2','rabbit@ip-127.0.0.1']

【问题讨论】:

  • 向兔子询问 JSON " --formatter json"。

标签: ansible jinja2 ansible-2.x ansible-template


【解决方案1】:
  1. 您可以使用in test检查一个字符串是否包含在另一个字符串中

    "{{ 'a_string' in 'an other string containing a_string somewhere' }}"
    

    一个班轮演示:

    $ ansible localhost -m debug -a "msg={{ 'a_string' in 'an other string containing a_string somewhere' }}"
    localhost | SUCCESS => {
        "msg": true
    }
    
    $ ansible localhost -m debug -a "msg={{ 'a_string' in 'it won''t be find in here' }}"
    localhost | SUCCESS => {
        "msg": false
    }
    
    
  2. 您可以使用select 或reject 过滤器根据测试过滤列表元素。

    在您的情况下,我们可以使用拒绝从初始列表中过滤掉在给定命令结果字符串中实际找到的所有元素。如果找到所有元素,则结果列表应为空。

    - name: demo task which fails if all servers are not found
      vars:
        unfound: "{{ group_hosts | reject('in', cluster_status.stdout) | list }}"
      assert:
        that: unfound | length == 0
        success_msg: all servers where found
        fail_msg: "one ore more servers are missing: {{ unfound | join(', ') }}"
    

【讨论】:

  • 第二种方法出错。 error was a &lt;class 'jinja2.exceptions.TemplateRuntimeError'&gt;, original message: no test named 'in'"}。如何创建“测试”。
  • @SNR 可能是时候在您的安装中升级 ansible/jinja2 了。
【解决方案2】:

我可以借助 rabbitmq 命令的--formatter json 标志来实现这一点。

  - name: Get cluster status
    shell: rabbitmqctl cluster_status --formatter json
    register: cluster_status
    failed_when: cluster_status.rc > 0

  - name: demo task which fails if all servers are not found
    vars:
      group_hosts: "{{ groups['rmq_servers'] | map('extract', hostvars, 'ansible_hostname') | list }}"
      running_nodes: "{{ cluster_status.stdout| from_json| json_query('running_nodes')  }}"
    assert:
      that: group_hosts|length == running_nodes|length
      success_msg: All Nodes joined cluster
      fail_msg: "All Nodes are not part of cluster: {{ group_hosts|length - running_nodes|length }} missing"

感谢@Zeitounator 和@Vladimir Botka。两个答案都有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-10
    • 2019-07-21
    • 2013-01-01
    • 1970-01-01
    • 2017-05-16
    • 2021-03-12
    • 2022-12-13
    • 1970-01-01
    相关资源
    最近更新 更多