Restore from Gitea ZIP snapshot (12.08.2026) after full instance reinstall
Git history was lost when the previous Gitea instance was wiped and reinstalled due to an unresolved corruption bug — this commit is the last known-good file content, exported before the reinstall. Prior commit history is not recoverable through this path.
This commit is contained in:
@@ -0,0 +1,319 @@
|
||||
---
|
||||
- name: "Полное сканирование (включая Unknown)"
|
||||
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 КЛЮЧЕЙ (ПРОВЕРЬТЕ ИХ В SEMAPHORE!) ---
|
||||
key_windows: 7
|
||||
key_linux: 7
|
||||
key_mikrotik: 7
|
||||
key_printers: 7
|
||||
key_other: 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:
|
||||
# ----------------------------------------------------------------
|
||||
# ШАГ 0: Проверка наличия утилиты nmap (защита от Errno 2)
|
||||
# ----------------------------------------------------------------
|
||||
- name: Проверка установки nmap
|
||||
command: which nmap
|
||||
register: nmap_check
|
||||
ignore_errors: yes
|
||||
changed_when: false
|
||||
|
||||
- name: Остановка, если nmap не установлен
|
||||
fail:
|
||||
msg: >
|
||||
Утилита nmap не найдена! Если вы используете Docker-версию Semaphore (Alpine),
|
||||
зайдите в контейнер и выполните: apk add nmap.
|
||||
Если это Ubuntu/Debian: apt-get install nmap.
|
||||
when: nmap_check.rc != 0
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# ШАГ 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: Сканирование портов
|
||||
# ----------------------------------------------------------------
|
||||
- name: TCP Port Scan & Name Discovery
|
||||
shell: |
|
||||
nmap -sT -p 22,445,5985,5986,8291,9100 \
|
||||
--script smb-os-discovery \
|
||||
-Pn -n -T4 {{ item }}
|
||||
loop: "{{ active_ips }}"
|
||||
register: scan_results
|
||||
changed_when: false
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# ШАГ 3: Классификация (ИСПРАВЛЕНО)
|
||||
# ----------------------------------------------------------------
|
||||
- name: Обработка результатов
|
||||
set_fact:
|
||||
classified_hosts: []
|
||||
|
||||
- name: Классификация хостов
|
||||
set_fact:
|
||||
classified_hosts: "{{ classified_hosts + [host_info] }}"
|
||||
loop: "{{ scan_results.results }}"
|
||||
vars:
|
||||
out: "{{ item.stdout }}"
|
||||
ip: "{{ item.item }}"
|
||||
smb_found: "{{ out | regex_search('Computer name: ([\\w-]+)', '\\1') | default([]) }}"
|
||||
smb_name: "{{ smb_found[0] if smb_found else '' }}"
|
||||
type: >-
|
||||
{%- if out | regex_search('5985/tcp\\s+open') or out | regex_search('5986/tcp\\s+open') -%}
|
||||
windows
|
||||
{%- elif out | regex_search('8291/tcp\\s+open') -%}
|
||||
mikrotik
|
||||
{%- elif out | regex_search('9100/tcp\\s+open') -%}
|
||||
printer
|
||||
{%- elif out | regex_search('22/tcp\\s+open') -%}
|
||||
linux
|
||||
{%- else -%}
|
||||
other
|
||||
{%- endif %}
|
||||
final_name: >-
|
||||
{%- if type == 'windows' and smb_name != '' -%}
|
||||
{{ smb_name | lower }}
|
||||
{%- else -%}
|
||||
{{ type }}_{{ ip | replace('.', '_') }}
|
||||
{%- endif %}
|
||||
host_info:
|
||||
ip: "{{ ip }}"
|
||||
type: "{{ type }}"
|
||||
name: "{{ final_name }}"
|
||||
when: item.stdout is defined and item.stdout != ""
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# ШАГ 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 }}"
|
||||
list_oth: "{{ classified_hosts | selectattr('type', 'equalto', 'other') | list }}"
|
||||
|
||||
- name: СТАТИСТИКА
|
||||
debug:
|
||||
msg:
|
||||
- "Windows (WinRM): {{ list_win | length }}"
|
||||
- "MikroTik: {{ list_tik | length }}"
|
||||
- "Linux: {{ list_lin | length }}"
|
||||
- "Printers: {{ list_prn | length }}"
|
||||
- "Unknown: {{ list_oth | length }}"
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# ШАГ 5: Отправка Windows
|
||||
# ----------------------------------------------------------------
|
||||
- block:
|
||||
- set_fact:
|
||||
content_win: |
|
||||
[windows]
|
||||
{% for h in list_win %}
|
||||
{{ h.name }} ansible_host={{ h.ip }}
|
||||
{% endfor %}
|
||||
[windows:vars]
|
||||
ansible_connection=winrm
|
||||
ansible_port=5985
|
||||
ansible_winrm_server_cert_validation=ignore
|
||||
ansible_winrm_transport=ntlm
|
||||
|
||||
- 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
|
||||
|
||||
- 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:
|
||||
- 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
|
||||
|
||||
- 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
|
||||
|
||||
- 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: Отправка Linux
|
||||
# ----------------------------------------------------------------
|
||||
- block:
|
||||
- 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
|
||||
|
||||
- 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
|
||||
|
||||
- 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
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# ШАГ 8: Отправка Printers
|
||||
# ----------------------------------------------------------------
|
||||
- block:
|
||||
- set_fact:
|
||||
content_prn: |
|
||||
[printers]
|
||||
{% for h in list_prn %}
|
||||
{{ h.name }} ansible_host={{ h.ip }}
|
||||
{% endfor %}
|
||||
[printers:vars]
|
||||
ansible_connection=local
|
||||
|
||||
- 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
|
||||
|
||||
- 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
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# ШАГ 9: Отправка UNKNOWN (Other)
|
||||
# ----------------------------------------------------------------
|
||||
- block:
|
||||
- set_fact:
|
||||
content_oth: |
|
||||
[unknown_devices]
|
||||
{% for h in list_oth %}
|
||||
{{ h.name }} ansible_host={{ h.ip }}
|
||||
{% endfor %}
|
||||
[unknown_devices:vars]
|
||||
ansible_connection=local
|
||||
|
||||
- copy:
|
||||
content: |
|
||||
{
|
||||
"name": "Auto Unknown {{ 1000 | random }}",
|
||||
"project_id": {{ semaphore_project_id }},
|
||||
"type": "static",
|
||||
"ssh_key_id": {{ key_other }},
|
||||
"become_key_id": null,
|
||||
"repository_id": null,
|
||||
"inventory": {{ content_oth | to_json }}
|
||||
}
|
||||
dest: /tmp/p_oth.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_oth.json
|
||||
ignore_errors: yes
|
||||
when: list_oth | length > 0
|
||||
|
||||
- name: Очистка
|
||||
shell: rm -f /tmp/p_*.json
|
||||
Reference in New Issue
Block a user