280 lines
10 KiB
YAML
280 lines
10 KiB
YAML
---
|
||
- name: "Сканирование сети (Jinja2 Logic Fix)"
|
||
hosts: localhost
|
||
connection: local
|
||
gather_facts: no
|
||
vars:
|
||
# --- SEMAPHORE API ---
|
||
semaphore_url: "http://192.168.0.198:9999"
|
||
semaphore_project_id: 1
|
||
semaphore_api_token: "9ojexqiwt1xkemig7j1bd1pe-frh7hkre4reryk2occ="
|
||
|
||
# --- ID КЛЮЧЕЙ ---
|
||
key_windows: 7
|
||
key_linux: 8
|
||
key_mikrotik: 9
|
||
key_printers: 7
|
||
|
||
# --- СЕТИ ---
|
||
subnets:
|
||
- "192.168.0.0/24"
|
||
- "192.168.0.0/23"
|
||
- "192.168.2.0/24"
|
||
- "192.168.3.0/24"
|
||
- "172.19.8.0/24"
|
||
- "172.19.9.0/24"
|
||
- "172.19.10.0/24"
|
||
- "172.19.24.0/24"
|
||
- "172.19.26.0/24"
|
||
- "172.19.40.0/24"
|
||
- "172.19.42.0/24"
|
||
- "172.19.56.0/24"
|
||
- "172.19.58.0/24"
|
||
- "172.19.90.0/24"
|
||
|
||
tasks:
|
||
# ----------------------------------------------------------------
|
||
# ШАГ 1: Поиск живых хостов
|
||
# ----------------------------------------------------------------
|
||
- name: Ping Sweep
|
||
command: "nmap -sn -n --min-rate 1000 -T4 -oG - {{ subnets | join(' ') }}"
|
||
register: ping_scan
|
||
changed_when: false
|
||
|
||
- name: Формирование списка активных IP
|
||
set_fact:
|
||
active_ips: "{{ ping_scan.stdout | regex_findall('Host: ([0-9.]+)') | unique | list }}"
|
||
|
||
- name: Проверка наличия хостов
|
||
fail:
|
||
msg: "Сеть пуста, активных хостов не найдено."
|
||
when: active_ips | length == 0
|
||
|
||
# ----------------------------------------------------------------
|
||
# ШАГ 2: Сканирование портов (TCP Connect)
|
||
# ----------------------------------------------------------------
|
||
- name: TCP Port Scan & Name Discovery
|
||
shell: |
|
||
nmap -sT -p 22,445,8291,9100 \
|
||
--script smb-os-discovery \
|
||
-Pn -n -T4 {{ item }}
|
||
loop: "{{ active_ips }}"
|
||
register: scan_results
|
||
changed_when: false
|
||
|
||
# ----------------------------------------------------------------
|
||
# ШАГ 3: Классификация (Jinja2 Block - Исправленная логика)
|
||
# Мы обрабатываем весь список результатов сразу, а не в цикле задач.
|
||
# ----------------------------------------------------------------
|
||
- name: Обработка результатов сканирования
|
||
set_fact:
|
||
classified_hosts: >-
|
||
[
|
||
{% for res in scan_results.results %}
|
||
{% set out = res.stdout %}
|
||
{% set ip = res.item %}
|
||
|
||
{# Поиск имени #}
|
||
{% set smb_found = out | regex_search('Computer name: ([\\w-]+)', '\\1') %}
|
||
{% set smb_name = smb_found[0] if smb_found else '' %}
|
||
|
||
{# Определение типа (Ищем 'порт/tcp' и 'open' с любыми пробелами) #}
|
||
{% set type = 'other' %}
|
||
{% if out | regex_search('445/tcp\s+open') %}
|
||
{% set type = 'windows' %}
|
||
{% elif out | regex_search('8291/tcp\s+open') %}
|
||
{% set type = 'mikrotik' %}
|
||
{% elif out | regex_search('9100/tcp\s+open') %}
|
||
{% set type = 'printer' %}
|
||
{% elif out | regex_search('22/tcp\s+open') %}
|
||
{% set type = 'linux' %}
|
||
{% endif %}
|
||
|
||
{# Формирование имени #}
|
||
{% if type == 'windows' and smb_name != '' %}
|
||
{% set final_name = smb_name | lower %}
|
||
{% else %}
|
||
{% set final_name = type + '_' + ip | replace('.', '_') %}
|
||
{% endif %}
|
||
|
||
{
|
||
"ip": "{{ ip }}",
|
||
"type": "{{ type }}",
|
||
"name": "{{ final_name }}"
|
||
},
|
||
{% endfor %}
|
||
]
|
||
|
||
# ----------------------------------------------------------------
|
||
# ШАГ 4: Разбиение на группы
|
||
# ----------------------------------------------------------------
|
||
- name: Формирование списков
|
||
set_fact:
|
||
list_win: "{{ classified_hosts | selectattr('type', 'equalto', 'windows') | list }}"
|
||
list_lin: "{{ classified_hosts | selectattr('type', 'equalto', 'linux') | list }}"
|
||
list_tik: "{{ classified_hosts | selectattr('type', 'equalto', 'mikrotik') | list }}"
|
||
list_prn: "{{ classified_hosts | selectattr('type', 'equalto', 'printer') | list }}"
|
||
|
||
- name: СТАТИСТИКА (Результат)
|
||
debug:
|
||
msg:
|
||
- "Windows: {{ list_win | length }}"
|
||
- "MikroTik: {{ list_tik | length }}"
|
||
- "Linux: {{ list_lin | length }}"
|
||
- "Printers: {{ list_prn | length }}"
|
||
- "Other: {{ classified_hosts | length - (list_win|length + list_lin|length + list_tik|length + list_prn|length) }}"
|
||
|
||
# ----------------------------------------------------------------
|
||
# ШАГ 5: Отправка Windows
|
||
# ----------------------------------------------------------------
|
||
- block:
|
||
- name: Генерация инвентаря Windows
|
||
set_fact:
|
||
content_win: |
|
||
[windows]
|
||
{% for h in list_win %}
|
||
{{ h.name }} ansible_host={{ h.ip }}
|
||
{% endfor %}
|
||
[windows:vars]
|
||
ansible_connection=ssh
|
||
ansible_shell_type=powershell
|
||
ansible_port=22
|
||
|
||
- name: Сохранение JSON (Windows)
|
||
copy:
|
||
content: |
|
||
{
|
||
"name": "Auto Windows {{ 1000 | random }}",
|
||
"project_id": {{ semaphore_project_id }},
|
||
"type": "static",
|
||
"ssh_key_id": {{ key_windows }},
|
||
"become_key_id": null,
|
||
"repository_id": null,
|
||
"inventory": {{ content_win | to_json }}
|
||
}
|
||
dest: /tmp/p_win.json
|
||
|
||
- name: Отправка API (Windows)
|
||
command: >
|
||
curl -X POST "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
|
||
-H "Authorization: Bearer {{ semaphore_api_token }}"
|
||
-H "Content-Type: application/json"
|
||
-d @/tmp/p_win.json
|
||
ignore_errors: yes
|
||
when: list_win | length > 0
|
||
|
||
# ----------------------------------------------------------------
|
||
# ШАГ 6: Отправка MikroTik
|
||
# ----------------------------------------------------------------
|
||
- block:
|
||
- name: Генерация инвентаря MikroTik
|
||
set_fact:
|
||
content_tik: |
|
||
[routers]
|
||
{% for h in list_tik %}
|
||
{{ h.name }} ansible_host={{ h.ip }}
|
||
{% endfor %}
|
||
[routers:vars]
|
||
ansible_connection=network_cli
|
||
ansible_network_os=routeros
|
||
|
||
- name: Сохранение JSON (MikroTik)
|
||
copy:
|
||
content: |
|
||
{
|
||
"name": "Auto MikroTik {{ 1000 | random }}",
|
||
"project_id": {{ semaphore_project_id }},
|
||
"type": "static",
|
||
"ssh_key_id": {{ key_mikrotik }},
|
||
"become_key_id": null,
|
||
"repository_id": null,
|
||
"inventory": {{ content_tik | to_json }}
|
||
}
|
||
dest: /tmp/p_tik.json
|
||
|
||
- name: Отправка API (MikroTik)
|
||
command: >
|
||
curl -X POST "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
|
||
-H "Authorization: Bearer {{ semaphore_api_token }}"
|
||
-H "Content-Type: application/json"
|
||
-d @/tmp/p_tik.json
|
||
ignore_errors: yes
|
||
when: list_tik | length > 0
|
||
|
||
# ----------------------------------------------------------------
|
||
# ШАГ 7: Отправка Принтеров
|
||
# ----------------------------------------------------------------
|
||
- block:
|
||
- name: Генерация инвентаря Принтеров
|
||
set_fact:
|
||
content_prn: |
|
||
[printers]
|
||
{% for h in list_prn %}
|
||
{{ h.name }} ansible_host={{ h.ip }}
|
||
{% endfor %}
|
||
[printers:vars]
|
||
ansible_connection=local
|
||
|
||
- name: Сохранение JSON (Принтеры)
|
||
copy:
|
||
content: |
|
||
{
|
||
"name": "Auto Printers {{ 1000 | random }}",
|
||
"project_id": {{ semaphore_project_id }},
|
||
"type": "static",
|
||
"ssh_key_id": {{ key_printers }},
|
||
"become_key_id": null,
|
||
"repository_id": null,
|
||
"inventory": {{ content_prn | to_json }}
|
||
}
|
||
dest: /tmp/p_prn.json
|
||
|
||
- name: Отправка API (Принтеры)
|
||
command: >
|
||
curl -X POST "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
|
||
-H "Authorization: Bearer {{ semaphore_api_token }}"
|
||
-H "Content-Type: application/json"
|
||
-d @/tmp/p_prn.json
|
||
ignore_errors: yes
|
||
when: list_prn | length > 0
|
||
|
||
# ----------------------------------------------------------------
|
||
# ШАГ 8: Отправка Linux
|
||
# ----------------------------------------------------------------
|
||
- block:
|
||
- name: Генерация инвентаря Linux
|
||
set_fact:
|
||
content_lin: |
|
||
[linux]
|
||
{% for h in list_lin %}
|
||
{{ h.name }} ansible_host={{ h.ip }}
|
||
{% endfor %}
|
||
[linux:vars]
|
||
ansible_connection=ssh
|
||
ansible_user=root
|
||
|
||
- name: Сохранение JSON (Linux)
|
||
copy:
|
||
content: |
|
||
{
|
||
"name": "Auto Linux {{ 1000 | random }}",
|
||
"project_id": {{ semaphore_project_id }},
|
||
"type": "static",
|
||
"ssh_key_id": {{ key_linux }},
|
||
"become_key_id": null,
|
||
"repository_id": null,
|
||
"inventory": {{ content_lin | to_json }}
|
||
}
|
||
dest: /tmp/p_lin.json
|
||
|
||
- name: Отправка API (Linux)
|
||
command: >
|
||
curl -X POST "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
|
||
-H "Authorization: Bearer {{ semaphore_api_token }}"
|
||
-H "Content-Type: application/json"
|
||
-d @/tmp/p_lin.json
|
||
ignore_errors: yes
|
||
when: list_lin | length > 0
|
||
|
||
- name: Очистка
|
||
shell: rm -f /tmp/p_*.json |