Reputation: 21
I'm trying to edit the netcfg.yaml and update the nameserver address:
currently it has this:
version: 2
renderer: networkd
ethernets:
enp0s3:
dhcp4: no
addresses: [192.168.1.222/24]
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8,8.8.4.4]
I was able to edit all the lines with lineinfile, except the last line in the above: addresses: [8.8.8.8.,8.8.4.4]
I tried this:
regexp: ' addresses: [[0-9]{1}[.][0-9]{1}[.][0-9]{1}[.][0-9]{1}]'
Ansible playbook doesn't show any error, but it's not identifying it to modify the values.
Upvotes: 1
Views: 229
Reputation: 68189
It's very risky to update IPs in such files by regex. There are two attributes addresses in this simple example. It would be more practical to read the YAML dictionary, update it and write it back.
Declare what you want to update. For example, update addresses of the nameservers in each interface from ethernets
ethernets_update:
nameservers:
addresses: [127.0.0.53, 8.8.8.8, 8.8.4.4]
Given the (fixed) file for testing
shell> cat /tmp/netcfg.yaml
network:
version: 2
renderer: networkd
ethernets:
enp0s3:
dhcp4: no
addresses: [192.168.1.222/24]
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8,8.8.4.4]
Declare the variable
netcfg: "{{ netcfg_yaml.content|b64decode|from_yaml }}"
and read the file
- slurp:
src: /tmp/netcfg.yaml
register: netcfg_yaml
gives
netcfg:
network:
ethernets:
enp0s3:
addresses: [192.168.1.222/24]
dhcp4: false
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
renderer: networkd
version: 2
Update the dictionary
ethernets: "{{ dict(netcfg.network.ethernets.keys()|
zip(netcfg.network.ethernets.values()|
product([ethernets_update])|map('combine'))) }}"
netcfg_update: "{{ [netcfg, {'network': {'ethernets': ethernets}}]|
combine(recursive=true) }}"
gives
netcfg_update:
network:
ethernets:
enp0s3:
addresses: [192.168.1.222/24]
dhcp4: false
gateway4: 192.168.1.1
nameservers:
addresses: [127.0.0.53, 8.8.8.8, 8.8.4.4]
renderer: networkd
version: 2
Write the file
- copy:
dest: /tmp/netcfg.yaml
content: |
{{ netcfg_update|to_yaml }}
gives
shell> cat /tmp/netcfg.yaml
network:
ethernets:
enp0s3:
addresses: [192.168.1.222/24]
dhcp4: false
gateway4: 192.168.1.1
nameservers:
addresses: [127.0.0.53, 8.8.8.8, 8.8.4.4]
renderer: networkd
version: 2
Example of a complete playbook for testing
- hosts: localhost
vars:
ethernets_update:
nameservers:
addresses: [127.0.0.53, 8.8.8.8, 8.8.4.4]
netcfg: "{{ netcfg_yaml.content|b64decode|from_yaml }}"
ethernets: "{{ dict(netcfg.network.ethernets|dict2items|map(attribute='key')|
zip(netcfg.network.ethernets|dict2items|map(attribute='value')|
product([ethernets_update])|map('combine'))) }}"
netcfg_update: "{{ [netcfg, {'network': {'ethernets': ethernets}}]|
combine(recursive=true) }}"
tasks:
- slurp:
src: /tmp/netcfg.yaml
register: netcfg_yaml
- debug:
var: netcfg
- debug:
var: ethernets
- debug:
var: netcfg_update|to_yaml
- copy:
dest: /tmp/netcfg.yaml
content: |
{{ netcfg_update|to_yaml }}
Upvotes: 0
Reputation: 163577
You could write the pattern escaping the first \[
and optionally repeat matching ,
followed by the digits and dots.
If you want to match 1 or more digits, you can use \d+
\baddresses: \[\d\.\d\.\d\.\d(?:,\d\.\d\.\d\.\d)*]
Explanation
\baddresses: \[
Match the word addresses
followed by : [
\d\.\d\.\d\.\d
Match 4 times a digit with a dot in between(?:,\d\.\d\.\d\.\d)*
Optionally repeat matching a ,
and the previous pattern]
Match literallySee a regex demo.
Upvotes: 0
Reputation: 3475
Your pattern is missed comma ,
between address, you could try this pattern:
addresses: \[(\d\.\d\.\d\.\d\,?)*\]
See demo here.
Upvotes: 0