Files
semaphore/playbooks/inventory_generator.yml

150 lines
5.4 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
- 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