From cec1fd41b4df86cdf0375641b1239ac8fb736816 Mon Sep 17 00:00:00 2001 From: aturenkov Date: Fri, 5 Dec 2025 12:07:34 +0000 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20playbooks/inventory=5Fgenerator.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- playbooks/inventory_generator.yml | 150 ++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 playbooks/inventory_generator.yml diff --git a/playbooks/inventory_generator.yml b/playbooks/inventory_generator.yml new file mode 100644 index 0000000..cf0732f --- /dev/null +++ b/playbooks/inventory_generator.yml @@ -0,0 +1,150 @@ +--- +- name: Сбор инвентаря Windows машин (nmap) + hosts: localhost + connection: local + gather_facts: yes + vars: + domain: "zag.lan" + dns_servers: + - "192.168.1.250" + - "192.168.1.254" + inventory_file: "/tmp/windows_inventory.ini" + subnets: + - "192.168.0.0/24" + - "192.168.1.0/24" + - "192.168.2.0/24" + - "192.168.3.0/24" + - "172.19.8.0/23" + - "172.19.10.0/23" + - "172.19.24.0/23" + - "172.19.26.0/23" + - "172.19.40.0/23" + - "172.19.42.0/23" + - "172.19.56.0/23" + - "172.19.58.0/23" + winrm_ports: + - 5985 + - 5986 + + tasks: + - name: Проверка установки nmap + command: which nmap + register: nmap_check + failed_when: false + changed_when: false + + - name: Ошибка если nmap не установлен + fail: + msg: "nmap не установлен!" + when: nmap_check.rc != 0 + + - name: Сканирование подсетей + command: "nmap -p {{ winrm_ports | join(',') }} --open -T4 -oG - {{ subnets | join(' ') }}" + register: nmap_result + changed_when: false + + - name: Извлечение IP с WinRM + set_fact: + active_ips: "{{ nmap_result.stdout | regex_findall('Host: ([0-9.]+).*Ports:.*(?:5985|5986)/open') | unique | list }}" + + - name: Найдено IP + debug: + msg: "Найдено {{ active_ips | length }} IP с WinRM" + + # ИЗМЕНЕНО: Попытка резолва через оба DNS сервера + - name: DNS резолв через корпоративные DNS + shell: | + # Пробуем первый DNS + result=$(nslookup {{ item }} {{ dns_servers[0] }} 2>/dev/null | grep 'name =' | awk '{print $NF}' | sed 's/\.$//') + + # Если не получилось, пробуем второй DNS + if [ -z "$result" ]; then + result=$(nslookup {{ item }} {{ dns_servers[1] }} 2>/dev/null | grep 'name =' | awk '{print $NF}' | sed 's/\.$//') + fi + + # Если оба не сработали + if [ -z "$result" ]; then + echo "NO_DNS" + else + echo "$result" + fi + loop: "{{ active_ips }}" + register: dns_lookup + changed_when: false + when: active_ips | length > 0 + + - name: Формирование PC хостов + set_fact: + pc_hosts: "{{ pc_hosts | default([]) + [{'hostname': item.stdout | trim, 'ip': item.item}] }}" + loop: "{{ dns_lookup.results | default([]) }}" + when: + - active_ips | length > 0 + - item.stdout is defined + - item.stdout != "NO_DNS" + - item.stdout | trim is match('^pc\\d+.*' + domain + '$') + + - name: Фильтрация PC (pc01-pc500 / pc001-pc500) + set_fact: + filtered_hosts: "{{ pc_hosts | default([]) | selectattr('hostname', 'match', '^pc(\\d{2,3})\\.' + domain + '$') | list }}" + + - name: Неопознанные хосты + set_fact: + unknown_ips: "{{ active_ips | difference(filtered_hosts | default([]) | map(attribute='ip') | list) }}" + + - name: Создание инвентаря + copy: + content: | + # ========================================== + # Инвентарь Windows PC + # Дата: {{ ansible_date_time.iso8601 }} + # DNS серверы: {{ dns_servers | join(', ') }} + # Подсети: {{ subnets | join(', ') }} + # Найдено IP с WinRM: {{ active_ips | length }} + # PC хостов в домене: {{ filtered_hosts | default([]) | length }} + # Неопознанных: {{ unknown_ips | default([]) | length }} + # ========================================== + + [windows_pcs] + {% for host in filtered_hosts | default([]) | sort(attribute='hostname') %} + {{ host.hostname | regex_replace('\\.' + domain + '$', '') }} ansible_host={{ host.hostname }} + {% endfor %} + + {% if unknown_ips | length > 0 %} + # Хосты с WinRM, но без DNS имён или не PC* + [windows_unknown] + {% for ip in unknown_ips %} + unknown_{{ ip | replace('.', '_') }} ansible_host={{ ip }} + {% endfor %} + + [windows:children] + windows_pcs + windows_unknown + {% else %} + [windows:children] + windows_pcs + {% endif %} + + [windows:vars] + ansible_connection=winrm + ansible_winrm_transport=ntlm + ansible_winrm_server_cert_validation=ignore + ansible_port=5985 + dest: "{{ inventory_file }}" + + - name: Итоговая статистика + debug: + msg: + - "==========================================" + - "Просканировано подсетей: {{ subnets | length }}" + - "Найдено IP с WinRM: {{ active_ips | length }}" + - "PC хостов (pc01-pc500): {{ filtered_hosts | default([]) | length }}" + - "Неопознанных хостов: {{ unknown_ips | default([]) | length }}" + - "Файл: {{ inventory_file }}" + - "==========================================" + + - name: Список найденных PC + debug: + msg: "{{ filtered_hosts | default([]) | map(attribute='hostname') | list }}" + when: + - filtered_hosts is defined + - filtered_hosts | length > 0 \ No newline at end of file