From fc94c9d6ed66271a443e28027364abaa9ab65dc3 Mon Sep 17 00:00:00 2001 From: ogrechko Date: Wed, 10 Dec 2025 11:08:38 +0000 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20playbooks/scan=5Finventory.yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- playbooks/scan_inventory.yml | 205 +++++++++++++++++++---------------- 1 file changed, 110 insertions(+), 95 deletions(-) diff --git a/playbooks/scan_inventory.yml b/playbooks/scan_inventory.yml index 6ea790b..fadcff7 100644 --- a/playbooks/scan_inventory.yml +++ b/playbooks/scan_inventory.yml @@ -3,13 +3,13 @@ hosts: localhost connection: local gather_facts: no - become: yes # Нужно для сканирования UDP (SNMP) + become: yes # Нужно для сканирования UDP (SNMP) и Nmap -O 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 @@ -32,7 +32,7 @@ - "172.19.56.0/24" - "172.19.58.0/24" - "172.19.90.0/24" - + # SNMP Community (пароль для чтения) snmp_community: "public" @@ -40,16 +40,20 @@ # ---------------------------------------------------------------- # ШАГ 1: Поиск живых хостов (Ping) # ---------------------------------------------------------------- - - name: Ping Sweep + - name: Ping Sweep (быстрый поиск) command: "nmap -sn -n --min-rate 1000 -T4 -oG - {{ subnets | join(' ') }}" register: ping_scan changed_when: false - - name: Список IP + - name: Формирование списка активных IP set_fact: active_ips: "{{ ping_scan.stdout | regex_findall('Host: ([0-9.]+)') | unique | list }}" - - - fail: msg="Сеть пуста" when: active_ips|length == 0 + + # ИСПРАВЛЕННАЯ СТРОКА (Теперь это правильный многострочный блок) + - name: Проверка наличия хостов + fail: + msg: "Сеть пуста, активных хостов не найдено." + when: active_ips | length == 0 # ---------------------------------------------------------------- # ШАГ 2: Опрос через SNMP + Проверка портов @@ -67,24 +71,25 @@ # ---------------------------------------------------------------- # ШАГ 3: Классификация на основе ответа SNMP # ---------------------------------------------------------------- - - name: Анализ устройств + - name: Анализ устройств и классификация set_fact: classified_hosts: "{{ classified_hosts | default([]) + [ host_data ] }}" vars: out: "{{ item.stdout }}" ip: "{{ item.item }}" - + # Пытаемся вытащить строку sysDescr snmp_desc: "{{ out | regex_search('sysDescr\\.0: ([^\\n]+)', '\\1') | first | default('') }}" - - # Определяем тип + + # Определяем тип (Логика распознавания) detected_type: >- {% if 'Windows' in snmp_desc or '445/tcp open' in out %}windows {% elif 'RouterOS' in snmp_desc or 'MikroTik' in snmp_desc or '8291/tcp open' in out %}mikrotik {% elif 'Linux' in snmp_desc or 'Ubuntu' in snmp_desc or '22/tcp open' in out %}linux {% elif 'JetDirect' in snmp_desc or 'LaserJet' in snmp_desc or 'Samsung' in snmp_desc or 'Kyocera' in snmp_desc or '9100/tcp open' in out %}printer {% else %}other{% endif %} - + + # Собираем данные об одном хосте host_data: ip: "{{ ip }}" type: "{{ detected_type }}" @@ -96,7 +101,8 @@ # ---------------------------------------------------------------- # ШАГ 4: Разбиение на группы # ---------------------------------------------------------------- - - set_fact: + - 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 }}" @@ -106,106 +112,115 @@ # ШАГ 5: Отправка в Semaphore (Windows) # ---------------------------------------------------------------- - block: - - set_fact: - content_win: | - [windows] - {% for h in list_win %} - {{ h.name }} ansible_host={{ h.ip }} # SNMP: {{ h.desc }} - {% endfor %} - [windows:vars] - ansible_connection=ssh - ansible_shell_type=powershell - ansible_port=22 + - name: Генерация текста инвентаря Windows + set_fact: + content_win: | + [windows] + {% for h in list_win %} + {{ h.name }} ansible_host={{ h.ip }} # SNMP: {{ h.desc }} + {% endfor %} + [windows:vars] + ansible_connection=ssh + ansible_shell_type=powershell + ansible_port=22 - - copy: - content: | - { - "name": "SNMP 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: Сохранение JSON для Windows + copy: + content: | + { + "name": "SNMP 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 - - 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 + - name: Отправка Windows 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_win.json + ignore_errors: yes when: list_win | length > 0 # ---------------------------------------------------------------- # ШАГ 6: Отправка в Semaphore (MikroTik) # ---------------------------------------------------------------- - block: - - set_fact: - content_tik: | - [routers] - {% for h in list_tik %} - {{ h.name }} ansible_host={{ h.ip }} # {{ h.desc }} - {% endfor %} - [routers:vars] - ansible_connection=network_cli - ansible_network_os=routeros + - name: Генерация текста инвентаря MikroTik + set_fact: + content_tik: | + [routers] + {% for h in list_tik %} + {{ h.name }} ansible_host={{ h.ip }} # {{ h.desc }} + {% endfor %} + [routers:vars] + ansible_connection=network_cli + ansible_network_os=routeros - - copy: - content: | - { - "name": "SNMP 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: Сохранение JSON для MikroTik + copy: + content: | + { + "name": "SNMP 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 - - 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 + - name: Отправка MikroTik 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_tik.json + ignore_errors: yes when: list_tik | length > 0 # ---------------------------------------------------------------- # ШАГ 7: Отправка в Semaphore (Принтеры) # ---------------------------------------------------------------- - block: - - set_fact: - content_prn: | - [printers] - {% for h in list_prn %} - {{ h.name }} ansible_host={{ h.ip }} # {{ h.desc }} - {% endfor %} - [printers:vars] - ansible_connection=local + - name: Генерация текста инвентаря Принтеров + set_fact: + content_prn: | + [printers] + {% for h in list_prn %} + {{ h.name }} ansible_host={{ h.ip }} # {{ h.desc }} + {% endfor %} + [printers:vars] + ansible_connection=local - - copy: - content: | - { - "name": "SNMP 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: Сохранение JSON для Принтеров + copy: + content: | + { + "name": "SNMP 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 - - 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 + - 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 - - name: Очистка + - name: Очистка временных файлов shell: rm -f /tmp/p_*.json \ No newline at end of file