ansiblepython-regex

Ansible regex_findall is not giving expected results with negative search


My ansible negative regex is returning everything

So I'm getting results of dns names from JSON, of which I'm trying to sort to create an automated ansible inventory. I have servers with naming schemes such as:

abc02vsomeserver01.subdomain1.domain.gov
abc02someserver01.subdomain1.domain.gov
xyz03votherserver11.subdomain2.domain.gov
wyz03otherserver11.subdomain2.domain.gov
qrsmainserver02.maindomain.domain.gov

I'm getting the "v" servers divided out by environment, then I want to create a catchall group that is not the "v" servers So! I'm attempting to do:

{{ jsonOutput | json_query('json.response.results[].dnsName') | regex_findall('(?![a-z]{3}[0-9]{2}v)^.*', multiline=true) }}

Which does seem to work when I plug it into https://pythex.org. But ansible is returning everything instead... What the heck am I doing wrong here?


Solution

  • It's because that json_query emits a list[str] which when fed directly into regex_findall doesn't become a newline delimited string, it becomes the same as str(["alpha", "beta"]) (e.g. ['alpha', 'beta']) and then the multiline regex fails to do what you are expecting

    There are, as with many things in life, a few ways to fix that. One is to just feed the results into |join("\n") and then you're likely back where you thought you were to begin with:

    - debug:
        msg: "{{ jsonOutput | json_query('json.response.results[].dnsName') | join('\n') | regex_findall('(?![a-z]{3}[0-9]{2}v)^.*', multiline=true) }}"
    

    The other is to acknowledge that it's a list[str] and use the | select("match", ...) filter to only allow though items that match:

        - debug:
            msg: >-
              {{ response | json_query('results[].dnsName')
              | select('match', '(?![a-z]{3}[0-9]{2}v)^.*')
              | list }}
          vars:
            response:
              results:
              - dnsName: abc02vsomeserver01.subdomain1.domain.gov
              - dnsName: abc02someserver01.subdomain1.domain.gov
              - dnsName: xyz03votherserver11.subdomain2.domain.gov
              - dnsName: wyz03otherserver11.subdomain2.domain.gov
              - dnsName: qrsmainserver02.maindomain.domain.gov
    

    similarly produces:

        "msg": [
            "abc02someserver01.subdomain1.domain.gov",
            "wyz03otherserver11.subdomain2.domain.gov",
            "qrsmainserver02.maindomain.domain.gov"
        ]
    

    I would guess it's personal preference which style works best in your playbook