Список серверов имен из resolv.conf с именем хоста в одной строке на хост

Мне нужно получить 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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
60
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Поскольку ваш 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

Поместите хотя бы один пробел после ключевого слова, чтобы избежать совпадения серверов имен в потенциальном комментарии \s*nameserver\s+(.*). Тем не менее, это регулярное выражение будет соответствовать потенциальному серверу имен в комментариях.

Vladimir Botka 07.11.2022 18:15

После попытки запустить yml: строка нарушения выглядит так: {{ ( ^ здесь

masterzst 07.11.2022 18:17
Ответ принят как подходящий

Декларация ниже дает список серверов имен

nameservers: "{{ lookup('file', '/etc/resolv.conf').splitlines()|
                 select('match', '^nameserver.*$')|
                 map('split', ' ')|
                 map('last')|list }}"

Вы можете присоединиться к имени хоста и элементам в списке

msg: "{{ inventory_hostname }};{{ nameservers|join(';') }}"

Notes

  1. 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(';') }}

  1. 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 }}"

фатальный: [10.0.3.103]: НЕУДАЧА! => {"msg": "Произошло необработанное исключение при шаблонировании '{{ lookup('file', '/etc/resolv.conf').splitlines()| select('match', '^nameserver.*$' )| map('split', ' ')| map('last')|list }}'. Ошибка была <class 'jinja2.exceptions.TemplateRuntimeError'>, исходное сообщение: нет фильтра с именем 'split'"}

masterzst 07.11.2022 18:37

Вместо этого используйте regex_replace. Я добавил пример.

Vladimir Botka 07.11.2022 18:53

У меня проблема с выводом. похоже, я вижу локальный файл resolv.conf, а не файлы на хостах.

masterzst 08.11.2022 10:19

Конечно. поиск работает только на локальном хосте. Ваша проблема hosts: localhost. Откройте новый вопрос, если вы хотите работать на удаленных хостах. Это совсем другая проблема.

Vladimir Botka 08.11.2022 10:44

Я не очень понимаю, мне нужно проверить этот файл на многих хостах, которые у меня есть в инвентаре.

masterzst 08.11.2022 10:45

Какую часть, в частности, вы не понимаете?

Vladimir Botka 08.11.2022 10:47

Я не понимаю, почему в результате я получаю DNS-адреса, которые у меня есть в моем локальном resolv.conf, а не те, что из инвентаря.

masterzst 08.11.2022 10:50

Давайте продолжим обсуждение в чате.

masterzst 08.11.2022 10:53

Другие вопросы по теме