SNR
SNR

Reputation: 510

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

I am trying to validate rabbitmq cluster status by taking the cluster_status command output to a variable and then look if output contains all hosts of the group. And exit if any host missing.

How can I check a string (command_output) contains all values in the list (group_hosts)?

My code:

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

Output:

    "stdout": "Cluster status of node [email protected] ...\n[{nodes,[{disc,['[email protected]','[email protected]']}]},\n {running_nodes,['[email protected]','[email protected]']},\n {cluster_name,<<\"[email protected]\">>},\n {partitions,[]},\n {alarms,[{'[email protected]',[]},{'[email protected]',[]}]}]",
    "stdout_lines": [
        "Cluster status of node [email protected] ...",
        "[{nodes,[{disc,['[email protected]','[email protected]']}]},",
        " {running_nodes,['[email protected]','[email protected]']},",
        " {cluster_name,<<\"[email protected]\">>},",
        " {partitions,[]},",
        " {alarms,[{'[email protected]',[]},{'[email protected]',[]}]}]"
    ]

list variable variable:

group_hosts=[ip-127.0.0.1,ip-127.0.0.2]

How can I get the following line to a variable from stdout?

running_nodes,['[email protected]','[email protected]']

Upvotes: 1

Views: 957

Answers (2)

SNR
SNR

Reputation: 510

I am able to achieve this with the help of --formatter json flag to rabbitmq command.

  - 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"

Thanks to @Zeitounator and @Vladimir Botka. Both answers helped

Upvotes: 0

Zeitounator
Zeitounator

Reputation: 44615

  1. You can check if a string is contained in an other with the in test

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

    One liner demos:

    $ 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. You can filter list elements based on a test using the select or reject filters.

    In your case we can use reject to filter out all elements from the initial list which are actually found in the given command result string. If all elements are found, the resulting list should be empty.

    - 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(', ') }}"
    

Upvotes: 2

Related Questions