ansible parse text string from stdout

2020-06-08 13:27发布

My problem is with ansible and parsing stdout. I need to capture the stdout from an ansible play and parse this output for a specific substring within stdout and save into a var. My specific use case is below

- shell: "vault.sh --keystore EAP_HOME/vault/vault.keystore |
          --keystore-password vault22 --alias vault --vault-block |
          vb --attribute password --sec-attr 0penS3sam3 --enc-dir |
          EAP_HOME/vault/ --iteration 120 --salt 1234abcd" 
  register: results
  become: true

This generates an output with the following line, the goal is to capture the masked key that jboss vault generates and save that in an ansible var so I can use it to configure the standalone.xml template:

vault-option name="KEYSTORE_PASSWORD" value="MASK-5dOaAVafCSd"/>

I need a way parse this string with possibly regex and save the "MASK-5dOaAVafCSd" substring into an ansible var using set_facts module or any other ansible module.

Currently my code looks like this

#example stdout
results: vault-option name=\"KEYSTORE_PASSWORD\" value=\"MASK-5dOaAVafCSd\"/>
- name: JBOSS_VAULT:define keystore password masked value variable
    set_fact:
    masked_value: |
       "{{ results.stdout | 
        regex_replace('^.+(MASK-.+?)\\.+','\\\1') }}"

This code is defining masked_value as the results.stdout, not the expected capture group.

2条回答
SAY GOODBYE
2楼-- · 2020-06-08 13:50

The above solution worked for me, however I had to do some extra logic to filter shell command output to get to the line which contains following

<vault-option name="KEYSTORE_PASSWORD" value="MASK-6qcNdkIprlA"/>

because vault command output has many lines in it. Once this line is captured, the solution given by Konstantin works just fine. Below is the whole thing that needs to done in one place.

 - name: Creating jboss vault
   shell: |
    {{ baseDir }}/bin/vault.sh -e {{ vaultDir }} -k {{ keystoreURL }} -p {{ keystorePassword }} \
    -s {{ keystoreSalt }} -i {{ iterationCount }} -v {{ keystoreAlias }} -b {{ vaultBlock }} \
    -a {{ attributeName }} -x {{ attributeValue }}
   register: vaultResult
 - set_fact:
    jbossKeystorePassword: "{{ item | regex_search('value=\"([^\"]+)','\\1') | first }}"
   when: item | trim | match('.*KEYSTORE_PASSWORD.*')
   with_items:
     - "{{ vaultResult.stdout_lines }}"
 - debug:
     var: jbossKeystorePassword

Be sure to replace all variables with your values in above vault.sh command.

查看更多
啃猪蹄的小仙女
3楼-- · 2020-06-08 14:11

You are very close. I advice you to use regex101.com to test regular expressions.

Here is my solution:

---
- hosts: localhost
  gather_facts: no
  tasks:
    - shell: echo 'vault-option name="KEYSTORE_PASSWORD" value="MASK-5dOaAVafCSd"'
      register: results
    - set_fact:
        myvalue: "{{ results.stdout | regex_search(regexp,'\\1') }}"
      vars:
        regexp: 'value=\"([^"]+)'
    - debug:
        var: myvalue

result:

ok: [localhost] => {
    "myvalue": [
        "MASK-5dOaAVafCSd"
    ]
}

Update:

regex_search returns a list of found matches, so to get only first one use:

{{ results.stdout | regex_search(regexp,'\\1') | first }}
查看更多
登录 后发表回答