N. J
N. J

Reputation: 480

Ansible - How to get only certain parts of 'stdout_lines'?

I run ipa migrate-ds command using Ansible. When this command is finished I print out the result, which is similar to:

When group: is present in output:

...
        "stdout_lines": [
            "-----------",
            "migrate-ds:",
            "-----------",
            "Migrated:",
            "  user: usr1,usr2, usr3, usr4, usr5",
            "  group: usr1, usr2, usr3, usr4, usr5",
            "Failed user:",
            "  admin: This entry already exists",
            ...
           ]

When group: is not present in output:

  "stdout_lines": [
        "-----------",
        "migrate-ds:",
        "-----------",
        "Migrated:",
        "Failed user:",
        "  admin: This entry already exists",
         ...
        ]

I'm only interested in getting the groups under group: after Migrated, because I want to pass these to a script/template file.

It's important to note that sometimes group: is not even present in the stdout_lines, it all depends on the output of the command.

Upvotes: 0

Views: 499

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 68254

Usually, you get also stdout along with stdout_lines. Without the separators ----------- stdout would be a valid YAML

  stdout: |
    migrate-ds:
    Migrated:
      user: usr1,usr2, usr3, usr4, usr5
      group: usr1, usr2, usr3, usr4, usr5
    Failed user:
      admin: This entry already exists

Get rid of the separators and convert the string to YAML

  data: "{{ stdout|from_yaml }}"

If you can't remove the separators from the output of the command use the filter regex_replace

data: "{{ stdout|regex_replace('^-+', '', multiline=True)|from_yaml }}"

gives

  data:
    Failed user:
      admin: This entry already exists
    Migrated:
      group: usr1, usr2, usr3, usr4, usr5
      user: usr1,usr2, usr3, usr4, usr5
    migrate-ds: null

Upvotes: 1

larsks
larsks

Reputation: 312530

Vladimir's solution is probably better in this case, but if you're working with data that doesn't happen to be valid YAML you could also do something like this:

- hosts: localhost
  gather_facts: false
  vars:
    sample_results:
      - "stdout_lines": [
          "-----------",
          "migrate-ds:",
          "-----------",
          "Migrated:",
          "  user: usr1,usr2, usr3, usr4, usr5",
          "  group: usr1, usr2, usr3, usr4, usr5",
          "Failed user:",
          "  admin: This entry already exists"
         ]
      - "stdout_lines": [
            "-----------",
            "migrate-ds:",
            "-----------",
            "Migrated:",
            "Failed user:",
            "  admin: This entry already exists"
            ]
  tasks:
    - loop: "{{ sample_results }}"
      debug:
        msg: >-
          {{
            (
              item.stdout_lines | select('match', '  group:') | first | default("")
            ).split(': ')[1] | default("")
          }}

This uses the select filter to find the group: line, and makes use of the default filter to handle the situation in which there is no group: line in the output.

Running the above playbook produces:

TASK [debug] *******************************************************************
ok: [localhost] => (item={'stdout_lines': ['-----------', 'migrate-ds:', '-----------', 'Migrated:', '  user: usr1,usr2, usr3, usr4, usr5', '  group: usr1, usr2, usr3, usr4, usr5', 'Failed user:', '  admin: This entry already exists']}) => {
    "msg": "usr1, usr2, usr3, usr4, usr5"
}
ok: [localhost] => (item={'stdout_lines': ['-----------', 'migrate-ds:', '-----------', 'Migrated:', 'Failed user:', '  admin: This entry already exists']}) => {
    "msg": ""
}

Upvotes: 1

Related Questions