Jinja_dude
Jinja_dude

Reputation: 529

Ansible replacing the last bit of an ip using a playbook

I wrote a playbook with the purpose of changing the last bit of the default gateway ip of all the hosts in my inventory.ini

So far I am able to change the last bit through this command :

cat /etc/network/interfaces | grep -i default | awk -F'.' -vOFS='.' '{$NF=6}1;' > /etc/network/interfaces

But the problem is that I still cannot figure out how to replace only the last line of the interfaces file without overwriting the whole content of the file.

Here's how my playbook look like :

---
- name: test connectivity
  hosts: all
  tasks:
    - name: ping
      ping:
    - name: change default gateway address
      command: cat /etc/network/interfaces | grep -i default | awk -F'.' -vOFS='.' '{$NF=6}1;' > /etc/network/interfaces 
    - name: restart networking service
      command: systemctl restart networking
    - name: check ip configuration
      command: netstat -rn
...

All hint and tips are more than welcome.

Upvotes: 3

Views: 660

Answers (3)

Jinja_dude
Jinja_dude

Reputation: 529

Well after many tries and after taking the advice of using ansible modules in account I came out with this gem of a playbook that helped me reach my goal :

---
- name: test connectivity
  hosts: all
  tasks:
    - name: ping
      ping:
    - name: change default gateway address
      replace:
        path: /etc/network/interfaces
        regexp: '(up route add default gw [\d]*\.[\d]*.[\d]*)\.[\d]*$'
        replace: '\1.6'
        backup: yes
      when: (ansible_facts['distribution'] == "Debian")
    - name: restart networking serviice
      service:
        name: networking
        state: restarted
      when: (ansible_facts['distribution'] == "Debian")
    - name: change default gateway address on Redhat
      replace:
        path: /etc/sysconfig/network-scripts/ifcfg-eth0
        regexp: '(GATEWAY=[\d]*\.[\d]*.[\d]*)\.[\d]*$'
        replace: '\1.6'
        backup: yes
      when: (ansible_facts['distribution'] == "RedHat")
    - name: restart networking service for Redhat
      service:
        name: network
        state: restarted
      when: (ansible_facts['distribution'] == "RedHat")
...

It is working just as expected and of course it can be enhanced for other context. Thank you all for your advices and help

Upvotes: 1

Vladimir Botka
Vladimir Botka

Reputation: 68034

Q: "Ansible replacing the last line of file"

A: Given a file

shell> cat test.txt
l1
l2
l3

the playbook

- hosts: localhost
  vars:
    replace_line: last line replacement
  tasks:
    - command: cat test.txt
      register: result
    - copy:
        dest: test.txt
        content: |
          {% for line in result.stdout_lines[:-1] %}
          {{ line }}
          {% endfor %}
          {{ replace_line }}

gives

shell> cat test.txt
l1
l2
last line replacement

The playbook is idempotent.

Upvotes: 2

RavinderSingh13
RavinderSingh13

Reputation: 133518

Have your playbook of Ansible in this way. This is completely based on your shown samples. I couldn't test it since I don't have Ansible with me, though command should work.

---
- name: test connectivity
  hosts: all
  tasks:
    - name: ping
      ping:
    - name: change default gateway address
      command: tac /etc/network/interfaces | awk -F'.' -v IGNORECASE="1" -v OFS="." '/default/{if(FNR==1){$NF=6};print}' | tac  > temp && mv temp /etc/network/interfaces 
    - name: restart networking service
      command: systemctl restart networking
    - name: check ip configuration
      command: netstat -rn
# ...

Fixes done in OP's attempt:

  • I have also taken care of your overwriting issue, where you are overwriting your same Input_file without inplace option OR without using a temp output file. Because if try to update an Input_file while awk program is reading it, it gets empty because we are not using inplace option to perform same(which creates temp file in backend and saves output into it and then renames that file to Input_file).

  • Removed grep command since awk can take care of by itself, so attached the logic of grep into awk code itself.

Upvotes: 3

Related Questions