-1

Note: i m seeking solution for Ansible. Here is the issue description:

I have a file filedet.yml as below, however realtime this yaml may contain many more IP and file details.

---
10.9.9.111:
  /tmp/test.jar:
    hash: e6df90d38fa86f0e289f73d79cd2cfd2a29954eb

  /tmp/best.jar:
    hash: e6df90d38fa86f0e289f73d79cd2cfd2a29954eb

10.8.8.44:
  /tmp/conf/extra/httpd-ssl.conf:
    hash: 1746f03d57491b27158b0d3a48fca8b5fa85c0c2

  /tmp/conf/httpd.conf:
    hash: 1746f03d57491b27158b0d3a48fca8b5fa85c0c2

I wish to extract a particular IP and the file details so that it can be removed from the yaml using state: absent attribute . Thus, the desired regex should return the below:

10.9.9.111:
  /tmp/test.jar:
    hash: e6df90d38fa86f0e289f73d79cd2cfd2a29954e

  /tmp/best.jar:
    hash: e6df90d38fa86f0e289f73d79cd2cfd2a29954eb

I decided to have the start pattern as '10.9.9.111' and search until there are no spaces or newlines which means until it gets to the next IP.

I prepared the below regex and it shows correct, desired FULL Text match on http://regex101.com. See snapshot.

Regex query below:

[^#](^10.9.9.111:)(.|\n)*^(?!( |\n))

enter image description here

The same regex works fine with grep -Pzo and returns the desired string. However, the regex fails to work with ansible's lineinfile module as it does not yeild any results.

i want this regex or any other solution to work with Ansible so i can remove the given IP and it's file details from the yaml

Ansible:

   - name: "Remove entry from file."
     lineinfile:
       path: "/app/filedet.yaml"
       regexp: "[^#](^10.9.9.111:)(.|\n)*^(?!( |\n))"
       state: absent

Can you please suggest what is the issue here ?

Ashar
  • 2,942
  • 10
  • 58
  • 122
  • In POSIX *REs, circumflex in the middle of a regular expression matches a regular circumflex; it loses its meaning as a special character. And IIRC a POSIX grep can't perform a multiline match – oguz ismail Jan 28 '20 at 07:10
  • `grep` only examines one line at a time; there is no way really to specify matches which should straddle newlines with this tool. – tripleee Jan 28 '20 at 07:26
  • 1
    Does this answer your question? [How to find patterns across multiple lines using grep?](https://stackoverflow.com/questions/2686147/how-to-find-patterns-across-multiple-lines-using-grep) – tripleee Jan 28 '20 at 07:27
  • I m not seeking a solution for grep but seeking a regex that will work with Ansible – Ashar Jan 28 '20 at 07:39
  • `grep -Pzo` works for me. But how can i get it to work with Ansible's lineinfile ? – Ashar Jan 28 '20 at 07:45
  • Shall i repost specific to Ansible? – Ashar Jan 28 '20 at 09:03
  • @Ashar, you might want to remove the irrelevant info about grep and POSIX. It's all about Python regex. And, in the end, it's not about regex at all, I think. – Vladimir Botka Jan 28 '20 at 09:42

1 Answers1

0

Q: "I wish to extract an IP and the file details."

A: Use include_vars. For example

    - include_vars:
        file: filedet.yml
        name: my_dict
    - debug:
        msg: "{{ my_dict['10.9.9.111'] }}"

give

    "msg": {
        "/tmp/best.jar": {
            "hash": "e6df90d38fa86f0e289f73d79cd2cfd2a29954eb"
        }, 
        "/tmp/test.jar": {
            "hash": "e6df90d38fa86f0e289f73d79cd2cfd2a29954eb"
        }
    }

Q: "Remove an entry from the file."

A: Use template. For example

$ cat filedet.yml.j2
{% for item in my_dict_keys %}
{{ item }}:
  {{ my_dict[item]|to_nice_yaml|indent(2) }}
{% endfor %}

The task below

    - set_fact:
        my_dict_keys:
          - "10.8.8.44"
    - template:
        src: filedet.yml.j2
        dest: filedet.yml

gives

$ cat filedet.yml
10.8.8.44:
  /tmp/conf/extra/httpd-ssl.conf:
      hash: 1746f03d57491b27158b0d3a48fca8b5fa85c0c2
  /tmp/conf/httpd.conf:
      hash: 1746f03d57491b27158b0d3a48fca8b5fa85c0c2

Notes:

  • It's a bad idea to use lineinfile for this purpose

  • Data in the question is not valid YAML. The key is repeating

10.9.9.111:
  /tmp/test.jar:
    hash: e6df90d38fa86f0e289f73d79cd2cfd2a29954eb
  /tmp/test.jar:
    hash: e6df90d38fa86f0e289f73d79cd2cfd2a29954eb
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
  • can you get the template to include all ip and file details except the one i wish to remove inthis case 10.9.9.111 – Ashar Jan 28 '20 at 09:42
  • No. I can't. The template is fine as it is. Instead, you can test what you want first and update your question with all the relevant details. – Vladimir Botka Jan 28 '20 at 09:47
  • Vladimir i updated the question with all the details. Can you have a look ? – Ashar Jan 28 '20 at 09:54
  • New post with refined description here: https://stackoverflow.com/questions/59948370/remove-contents-of-a-include-vars-file-using-ansible – Ashar Jan 28 '20 at 12:06