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

How can I check a string contains all values in a list?

我试图通过将 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']
  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 or reject 过滤器根据测试过滤列表元素。

    在您的情况下,我们可以使用 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(', ') }}"
    

我可以在 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。两个答案都有帮助