Мне нужно получить DNS-сервер(ы) из моей сети, я пытался использовать:
- 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
Но это не совсем дает нужный мне результат.
Можно ли будет написать плейбук так, чтобы результат выглядел так, как показано ниже?
имя хоста;dns1;dns2;dnsN
Поскольку ваш regex_findall
уже создает вам список со всеми DNS-серверами, вам просто нужно добавить имя хоста в этот список и присоединиться ко всему списку с помощью точки с запятой.
- name: check nameservers list in resolv.conf
debug:
msg: >-
{{
(
[ ansible_hostname ] +
lookup('file', '/etc/resolv.conf', errors='ignore')
| regex_findall('\s*nameserver\s*(.*)')
) | join(';')
}}
В результате получится что-то вроде (b176263884e6
— фактическое имя хоста контейнера):
TASK [check nameservers list in resolv.conf] *****************************
ok: [localhost] =>
msg: b176263884e6;1.1.1.1;4.4.4.4;8.8.8.8
Обратите внимание, что вам даже не нужна задача stat
, так как вы можете игнорировать ошибки поиска с помощью errors='ignore'.
Это даст вам только имя хоста вместе с предупреждением:
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
После попытки запустить yml: строка нарушения выглядит так: {{ ( ^ здесь
Декларация ниже дает список серверов имен
nameservers: "{{ lookup('file', '/etc/resolv.conf').splitlines()|
select('match', '^nameserver.*$')|
map('split', ' ')|
map('last')|list }}"
Вы можете присоединиться к имени хоста и элементам в списке
msg: "{{ inventory_hostname }};{{ nameservers|join(';') }}"
Notes
- 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(';') }}
nameserver.*
in the commentsnameservers: "{{ 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 }}"
фатальный: [10.0.3.103]: НЕУДАЧА! => {"msg": "Произошло необработанное исключение при шаблонировании '{{ lookup('file', '/etc/resolv.conf').splitlines()| select('match', '^nameserver.*$' )| map('split', ' ')| map('last')|list }}'. Ошибка была <class 'jinja2.exceptions.TemplateRuntimeError'>, исходное сообщение: нет фильтра с именем 'split'"}
Вместо этого используйте regex_replace. Я добавил пример.
У меня проблема с выводом. похоже, я вижу локальный файл resolv.conf, а не файлы на хостах.
Конечно. поиск работает только на локальном хосте. Ваша проблема hosts: localhost
. Откройте новый вопрос, если вы хотите работать на удаленных хостах. Это совсем другая проблема.
Я не очень понимаю, мне нужно проверить этот файл на многих хостах, которые у меня есть в инвентаре.
Какую часть, в частности, вы не понимаете?
Я не понимаю, почему в результате я получаю DNS-адреса, которые у меня есть в моем локальном resolv.conf, а не те, что из инвентаря.
Давайте продолжим обсуждение в чате.
Поместите хотя бы один пробел после ключевого слова, чтобы избежать совпадения серверов имен в потенциальном комментарии
\s*nameserver\s+(.*)
. Тем не менее, это регулярное выражение будет соответствовать потенциальному серверу имен в комментариях.