Files
semaphore/playbooks/inventory.yml

172 lines
7.0 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
- name: Сбор инвентаря и создание его в Semaphore UI
hosts: localhost
connection: local
gather_facts: no
vars:
# --- НАСТРОЙКИ SEMAPHORE ---
semaphore_url: "http://192.168.0.198:9999" # Укажите ваш URL (или http://localhost:3000)
semaphore_project_id: 1
# ID ключа, который будет использоваться для подключения к новым хостам
semaphore_key_id: 7
# Токен API (лучше хранить в Secret, но для теста можно тут)
semaphore_api_token: "9ojexqiwt1xkemig7j1bd1pe-frh7hkre4reryk2occ="
inventory_name: "Auto Scanned Network"
# --- НАСТРОЙКИ СЕТИ ---
subnets:
- "192.168.0.0/24"
- "192.168.1.0/24"
- "192.168.2.0/24"
- "192.168.3.0/24"
- "172.19.8.0/23"
- "172.19.9.0/23"
- "172.19.10.0/23"
- "172.19.24.0/23"
- "172.19.26.0/23"
- "172.19.40.0/23"
- "172.19.42.0/23"
- "172.19.56.0/23"
- "172.19.58.0/23"
- "172.19.90.0/23"
# - "192.168.1.0/24" # Добавьте нужные подсети
scan_ports: [5985, 22, 445]
tasks:
# ---------------------------------------------------------
# ШАГ 1: Сканирование (Nmap)
# ---------------------------------------------------------
- name: Сканирование сети (поиск живых IP)
command: >
nmap -p {{ scan_ports | join(',') }}
-Pn -n --open --min-rate 1000 -T4 -oG -
{{ subnets | join(' ') }}
register: nmap_result
changed_when: false
ignore_errors: yes # Чтобы не падало, если ничего не нашлось
- name: Извлечение IP адресов
set_fact:
active_ips: "{{ nmap_result.stdout | regex_findall('Host: ([0-9.]+).*Ports:.*(?:' + scan_ports | join('|') + ')/open') | unique | list }}"
- name: Проверка, найдены ли IP
fail:
msg: "Не найдено ни одного активного IP. Проверьте настройки сети или Nmap."
when: active_ips | length == 0
# ---------------------------------------------------------
# ШАГ 2: Определение имен
# ---------------------------------------------------------
- name: Определение имен хостов (SMB Discovery + DNS)
shell: |
IP="{{ item }}"
SMB_NAME=$(nmap -p 445 --script smb-os-discovery $IP -Pn -n | grep "Computer name:" | awk -F': ' '{print $2}')
if [ ! -z "$SMB_NAME" ]; then
echo "$SMB_NAME" | tr '[:upper:]' '[:lower:]'
else
DNS_NAME=$(nslookup -timeout=1 $IP 192.168.1.250 2>/dev/null | grep 'name =' | awk '{print $NF}' | sed 's/\.$//' | head -n 1)
if [ ! -z "$DNS_NAME" ]; then
echo "$DNS_NAME" | tr '[:upper:]' '[:lower:]'
else
echo "UNKNOWN"
fi
fi
loop: "{{ active_ips }}"
register: host_names
changed_when: false
no_log: true
# ---------------------------------------------------------
# ШАГ 3: Сортировка и генерация текста
# ---------------------------------------------------------
- name: Сортировка хостов
set_fact:
pc_list: >-
{{ host_names.results | selectattr('stdout', 'search', 'pc')
| map(attribute='item') | list
| zip(host_names.results | selectattr('stdout', 'search', 'pc') | map(attribute='stdout') | list)
| list }}
other_list: >-
{{ host_names.results | rejectattr('stdout', 'search', 'pc')
| map(attribute='item') | list
| zip(host_names.results | rejectattr('stdout', 'search', 'pc') | map(attribute='stdout') | list)
| list }}
- name: Генерация текста инвентаря
set_fact:
inventory_content: |
# === Найденные PC ===
[windows_pcs]
{% for ip, name in pc_list %}
{{ name }} ansible_host={{ ip }}
{% endfor %}
# === Остальные устройства ===
[windows_other]
{% for ip, name in other_list %}
{% if name == "UNKNOWN" %}
unknown_{{ ip | replace('.', '_') }} ansible_host={{ ip }}
{% else %}
{{ name }} ansible_host={{ ip }}
{% endif %}
{% endfor %}
[windows:children]
windows_pcs
windows_other
[windows:vars]
ansible_connection=ssh
ansible_port=22
ansible_shell_type=powershell
ansible_user=o.grechko
# ---------------------------------------------------------
# ШАГ 4: Отладка (проверка данных перед отправкой)
# ---------------------------------------------------------
- name: Debug Payload (Проверка данных)
debug:
msg:
- "URL: {{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
- "SSH Key ID: {{ semaphore_key_id }}"
- "Количество символов в инвентаре: {{ inventory_content | length }}"
# ---------------------------------------------------------
# ШАГ 5: Отправка в API (ИСПРАВЛЕНО ssh_key_id)
# ---------------------------------------------------------
- name: Создание инвентаря в Semaphore через API
uri:
url: "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
method: POST
headers:
Authorization: "Bearer {{ semaphore_api_token }}"
Content-Type: "application/json"
Accept: "application/json"
body_format: json
body:
name: "{{ inventory_name }}"
project_id: "{{ semaphore_project_id | int }}"
type: "static"
ssh_key_id: "{{ semaphore_key_id | int }}"
become_key_id: null
inventory: "{{ inventory_content }}"
status_code: [201, 200]
register: api_response
- name: DEBUG - Попробовать через CURL (чтобы увидеть текст ошибки)
command: >
curl -v -X POST "{{ semaphore_url }}/api/project/{{ semaphore_project_id }}/inventory"
-H "Authorization: Bearer {{ semaphore_api_token }}"
-H "Content-Type: application/json"
-d '{"name": "{{ inventory_name }}", "project_id": {{ semaphore_project_id }}, "type": "static", "ssh_key_id": {{ semaphore_key_id }}, "become_key_id": null, "inventory": "localhost ansible_connection=local"}'
register: curl_output
ignore_errors: yes
- name: Вывод ошибки CURL
debug:
var: curl_output.stderr_lines
- name: Успех
debug:
msg: "Инвентарь создан! ID: {{ api_response.json.id | default('OK') }}"