Обновить playbooks/inventory_generator.yml

This commit is contained in:
2025-12-05 12:25:10 +00:00
parent 9c11b2dc00
commit b84bada015

View File

@@ -1,13 +1,11 @@
--- ---
- name: Генерация инвентаря Windows PC по DNS - name: Максимально быстрая генерация инвентаря
hosts: localhost hosts: localhost
connection: local connection: local
gather_facts: yes gather_facts: yes
vars: vars:
domain: "zag.lan" domain: "zag.lan"
dns_servers: dns_server: "192.168.1.250"
- "192.168.1.250"
- "192.168.1.254"
inventory_file: "/tmp/windows_inventory.yml" inventory_file: "/tmp/windows_inventory.yml"
subnets: subnets:
- "192.168.0.0/24" - "192.168.0.0/24"
@@ -24,105 +22,69 @@
- "172.19.58.0/23" - "172.19.58.0/23"
tasks: tasks:
- name: Генерация списка всех IP - name: Быстрый поиск активных хостов (nmap)
command: "nmap -sn -T5 {{ subnets | join(' ') }} --min-parallelism 100"
register: nmap_result
changed_when: false
- name: Извлечение активных IP
set_fact:
active_ips: "{{ nmap_result.stdout | regex_findall('Nmap scan report for ([0-9.]+)') }}"
- name: DNS резолв только для активных хостов
shell: | shell: |
python3 << 'EOF' python3 << 'EOF'
import ipaddress import subprocess
subnets = {{ subnets | to_json }} import concurrent.futures
for subnet in subnets:
network = ipaddress.ip_network(subnet) DNS = "{{ dns_server }}"
for ip in network.hosts(): IPS = {{ active_ips | to_json }}
print(ip)
def resolve(ip):
try:
r = subprocess.run(['nslookup', ip, DNS], capture_output=True, text=True, timeout=2)
for line in r.stdout.split('\n'):
if 'name =' in line:
host = line.split('=')[-1].strip().rstrip('.')
if host.lower().startswith('pc'):
return f"{ip}|{host}"
except: pass
return None
with concurrent.futures.ThreadPoolExecutor(max_workers=50) as ex:
for r in filter(None, ex.map(resolve, IPS)):
print(r)
EOF EOF
register: all_ips register: dns_result
changed_when: false changed_when: false
when: active_ips | length > 0
- name: Парсинг IP адресов - name: Формирование списка PC
set_fact: set_fact:
ip_list: "{{ all_ips.stdout_lines }}" pc_hosts: "{{ pc_hosts | default([]) + [{'ip': item.split('|')[0], 'hostname': item.split('|')[1]}] }}"
loop: "{{ dns_result.stdout_lines }}"
- name: Информация о сканировании
debug:
msg: "Будет проверено {{ ip_list | length }} IP адресов"
- name: DNS резолв для всех IP
shell: |
result=$(nslookup {{ item }} {{ dns_servers[0] }} 2>/dev/null | grep 'name =' | awk '{print $NF}' | sed 's/\.$//')
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: "{{ ip_list }}"
register: dns_results
changed_when: false
# Выполнение параллельно для ускорения
async: 30
poll: 0
- name: Ожидание завершения DNS запросов
async_status:
jid: "{{ item.ansible_job_id }}"
register: dns_jobs
until: dns_jobs.finished
retries: 60
delay: 1
loop: "{{ dns_results.results }}"
- name: Фильтрация PC хостов
set_fact:
pc_hosts: "{{ pc_hosts | default([]) + [{'hostname': item.stdout | trim, 'ip': item.item}] }}"
loop: "{{ dns_jobs.results }}"
when: when:
- item.stdout is defined - dns_result.stdout_lines is defined
- item.stdout != "NO_DNS" - dns_result.stdout_lines | length > 0
- item.stdout | trim | lower is match('^pc\\d+.*')
- name: Создание инвентаря YAML - name: Создание инвентаря
copy: copy:
content: | content: |
# ==========================================
# Инвентарь Windows PC
# Сгенерирован: {{ ansible_date_time.iso8601 }}
# DNS серверы: {{ dns_servers | join(', ') }}
# Подсети: {{ subnets | join(', ') }}
# Всего IP проверено: {{ ip_list | length }}
# PC хостов найдено: {{ pc_hosts | default([]) | length }}
# ==========================================
all: all:
children: children:
windows_pcs: windows_pcs:
hosts: hosts:
{% for host in pc_hosts | default([]) | sort(attribute='hostname') %} {% for h in pc_hosts | default([]) | sort(attribute='hostname') %}
{{ host.hostname | regex_replace('\\.' + domain + '$', '') | regex_replace('\\..*$', '') }}: {{ h.hostname.split('.')[0] }}:
ansible_host: {{ host.ip }} ansible_host: {{ h.ip }}
{% endfor %} {% endfor %}
vars: vars:
ansible_connection: winrm ansible_connection: winrm
ansible_winrm_transport: ntlm ansible_winrm_transport: ntlm
ansible_winrm_server_cert_validation: ignore ansible_winrm_server_cert_validation: ignore
ansible_port: 5985 ansible_port: 5985
ansible_winrm_scheme: http
dest: "{{ inventory_file }}" dest: "{{ inventory_file }}"
- name: Итоговая статистика - name: Результат
debug: debug:
msg: msg: "Найдено {{ pc_hosts | default([]) | length }} PC хостов → {{ inventory_file }}"
- "=========================================="
- "Просканировано подсетей: {{ subnets | length }}"
- "Проверено IP адресов: {{ ip_list | length }}"
- "Найдено PC хостов: {{ pc_hosts | default([]) | length }}"
- "Файл инвентаря: {{ inventory_file }}"
- "=========================================="
- name: Список найденных PC
debug:
msg: "{{ item.hostname }} ({{ item.ip }})"
loop: "{{ pc_hosts | default([]) | sort(attribute='hostname') }}"
when: pc_hosts is defined