Обновить playbooks/inventory_generator.yml
This commit is contained in:
@@ -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
|
|
||||||
Reference in New Issue
Block a user