I need to get the DNS server(s) from my network, I tried using:
- hosts: localhost
gather_facts: no
tasks:
- name: check resolv.conf exists
stat:
path: /etc/resolv.conf
register: resolv_conf
- name: check nameservers list in resolv.conf
debug:
msg: "{{ contents }}"
vars:
contents: "{{ lookup('file', '/etc/resolv.conf') | regex_findall('\\s*nameserver\\s*(.*)') }}"
when: resolv_conf.stat.exists == True
But this does not quite gives the result I need.
Will it be possible to write a playbook in such a way that the result looks like the below?
hostname;dns1;dns2;dnsN
CodePudding user response:
The declaration below gives the list of nameservers
nameservers: "{{ lookup('file', '/etc/resolv.conf').splitlines()|
select('match', '^nameserver.*$')|
map('split', ' ')|
map('last')|list }}"
You can join the hostname and the items on the list
msg: "{{ inventory_hostname }};{{ nameservers|join(';') }}"
Notes
- Example of a complete playbook for testing
- hosts: localhost
vars:
nameservers: "{{ lookup('file', '/etc/resolv.conf').splitlines()|
select('match', '^nameserver.*$')|
map('split', ' ')|
map('last')|list }}"
tasks:
- debug:
var: nameservers
- debug:
msg: |
{{ inventory_hostname }};{{ nameservers|join(';') }}
- The simplified declaration below works fine if there is no
nameserver.*
in the comments
nameservers: "{{ lookup('file', '/etc/resolv.conf')|
regex_findall('\\s*nameserver\\s*(.*)') }}"
Unfortunately, the Linux default file /etc/resolv.conf contains the comment:
| # run "systemd-resolve --status" to see details about the actual nameservers.
This regex will match nameservers.
nameservers:
- s.
You can solve this problem by putting at least one space behind the keyword nameserver
.
regex_findall('\\s*nameserver\\s (.*)') }}"
However, this won't help if there is the keyword nameserver
in the comment.
Q: "No filter named 'split'"
A: There is no filter split in Ansible less than 2.11. Use regex_replace instead
nameservers: "{{ lookup('file', '/etc/resolv.conf').splitlines()|
select('match', '^nameserver.*$')|
map('regex_replace', '^(.*) (.*)$', '\\2')|list }}"
CodePudding user response:
Since your regex_findall
already creates you a list with all DNS servers, you just need to add the hostname to that list and join
the whole list with a semicolon.
- name: check nameservers list in resolv.conf
debug:
msg: >-
{{
(
[ ansible_hostname ]
lookup('file', '/etc/resolv.conf', errors='ignore')
| regex_findall('\s*nameserver\s*(.*)')
) | join(';')
}}
Which will result in something like (b176263884e6
being the actual hostname of a container):
TASK [check nameservers list in resolv.conf] *****************************
ok: [localhost] =>
msg: b176263884e6;1.1.1.1;4.4.4.4;8.8.8.8
Note that you don't even need the stat
task, as you can ignore errors of the lookup with errors='ignore'
.
This will, then, give you only the hostname, along with a warning:
TASK [check nameservers list in resolv.conf] *****************************
[WARNING]: Unable to find '/etc/resolv.conf' in expected paths
(use -vvvvv to see paths)
ok: [localhost] =>
msg: b176263884e6