Обновить playbooks/inventory.yml
This commit is contained in:
@@ -1,78 +1,132 @@
|
|||||||
---
|
---
|
||||||
# -------------------------------------------------------------------------
|
- name: Сбор инвентаря и создание его в Semaphore UI
|
||||||
# ПЛЕЙ 1: Подключение к Docker-серверу, чтение файла и создание инвентаря
|
hosts: localhost
|
||||||
# -------------------------------------------------------------------------
|
connection: local
|
||||||
- name: Extract IPs from Docker and create Inventory
|
gather_facts: no
|
||||||
hosts: docker_servers # Группа в Semaphore, где лежит ваш Docker-сервер
|
|
||||||
become: true # Нужно для выполнения команд docker
|
|
||||||
vars:
|
vars:
|
||||||
# НАСТРОЙКИ
|
# --- НАСТРОЙКИ SEMAPHORE ---
|
||||||
container_name: "semaphore-semaphore-1" # Имя контейнера
|
semaphore_url: "http://192.168.0.198:9999" # Адрес вашего Semaphore
|
||||||
file_path_in_container: "/app/hosts.txt" # Путь к файлу внутри контейнера
|
semaphore_project_id: 1 # ID проекта
|
||||||
inventory_save_path: "/tmp/extracted_inventory.ini" # Куда сохранить результат на сервере
|
semaphore_key_id: 5 # ID ключа (Store Key) для подключения к хостам
|
||||||
|
semaphore_api_token: "9ojexqiwt1xkemig7j1bd1pe-frh7hkre4reryk2occ=" # Вставьте токен или передайте через Extra Vars
|
||||||
|
inventory_name: "Auto Scanned Network" # Как назвать инвентарь в Semaphore
|
||||||
|
|
||||||
|
# --- НАСТРОЙКИ СЕТИ (из вашего примера) ---
|
||||||
|
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"
|
||||||
|
# ... добавьте остальные подсети ...
|
||||||
|
scan_ports: [5985, 22, 445]
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
# 1. Проверяем, жив ли контейнер
|
# 1. Сканирование (Ваш код)
|
||||||
- name: Check if container is running
|
- name: Сканирование сети (поиск живых IP)
|
||||||
shell: "docker ps -q -f name={{ container_name }}"
|
command: >
|
||||||
register: container_check
|
nmap -p {{ scan_ports | join(',') }}
|
||||||
|
-Pn -n --open --min-rate 1000 -T4 -oG -
|
||||||
- name: Fail if container is not running
|
{{ subnets | join(' ') }}
|
||||||
fail:
|
register: nmap_result
|
||||||
msg: "Контейнер {{ container_name }} не найден или остановлен!"
|
|
||||||
when: container_check.stdout == ""
|
|
||||||
|
|
||||||
# 2. Читаем файл (формат: просто список IP, каждый с новой строки)
|
|
||||||
- name: Read file content from container
|
|
||||||
command: "docker exec {{ container_name }} cat {{ file_path_in_container }}"
|
|
||||||
register: file_content
|
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
# 3. Добавляем хосты в оперативную память (для текущего запуска Ansible)
|
- name: Извлечение IP адресов
|
||||||
- name: Add hosts to memory (dynamic inventory)
|
set_fact:
|
||||||
add_host:
|
active_ips: "{{ nmap_result.stdout | regex_findall('Host: ([0-9.]+).*Ports:.*(?:' + scan_ports | join('|') + ')/open') | unique | list }}"
|
||||||
name: "{{ item }}"
|
|
||||||
groups: extracted_dockers_hosts
|
|
||||||
ansible_user: "Administrator" # Можно задать пользователя по умолчанию для новых хостов
|
|
||||||
ansible_connection: "winrm" # Или ssh, в зависимости от того, что за хосты в списке
|
|
||||||
# Фильтр select проверяет, что строка не пустая
|
|
||||||
loop: "{{ file_content.stdout_lines | select('match', '^.+$') | list }}"
|
|
||||||
|
|
||||||
# 4. (Опционально) Сохраняем физический файл инвентаря, как в вашем старом скрипте
|
# 2. Определение имен (Ваш код)
|
||||||
- name: Save inventory to file (INI format)
|
- name: Определение имен хостов (SMB Discovery + DNS)
|
||||||
copy:
|
shell: |
|
||||||
content: |
|
IP="{{ item }}"
|
||||||
# === Инвентарь, полученный из Docker: {{ container_name }} ===
|
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
|
||||||
|
|
||||||
[extracted_hosts]
|
# 3. Сортировка (Ваш код)
|
||||||
{% for ip in file_content.stdout_lines | select('match', '^.+$') %}
|
- name: Сортировка хостов
|
||||||
host_{{ ip | replace('.', '_') }} ansible_host={{ ip }}
|
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 }}
|
||||||
|
|
||||||
|
# 4. Формирование текста инвентаря в переменную
|
||||||
|
- name: Генерация текста инвентаря
|
||||||
|
set_fact:
|
||||||
|
inventory_content: |
|
||||||
|
# === Найденные PC ===
|
||||||
|
[windows_pcs]
|
||||||
|
{% for ip, name in pc_list %}
|
||||||
|
{{ name }} ansible_host={{ ip }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
[extracted_hosts:vars]
|
# === Остальные устройства ===
|
||||||
# Пример переменных (настройте под ваши задачи)
|
[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=winrm
|
ansible_connection=winrm
|
||||||
ansible_port=5985
|
|
||||||
ansible_winrm_transport=ntlm
|
ansible_winrm_transport=ntlm
|
||||||
ansible_winrm_server_cert_validation=ignore
|
ansible_winrm_server_cert_validation=ignore
|
||||||
dest: "{{ inventory_save_path }}"
|
ansible_port=5985
|
||||||
delegate_to: localhost # Сохранить файл на сервере Semaphore (или уберите, чтобы сохранить на Docker-сервере)
|
ansible_user=Administrator
|
||||||
|
|
||||||
- name: Show extracted IPs
|
# 5. ОТПРАВКА В SEMAPHORE API
|
||||||
|
- 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"
|
||||||
|
key_id: "{{ semaphore_key_id | int }}"
|
||||||
|
inventory: "{{ inventory_content }}"
|
||||||
|
status_code: [201, 204, 200]
|
||||||
|
register: api_response
|
||||||
|
|
||||||
|
- name: Результат API
|
||||||
debug:
|
debug:
|
||||||
msg: "Найден IP: {{ item }}"
|
msg: "Инвентарь успешно создан! ID: {{ api_response.json.id | default('неизвестен') }}"
|
||||||
loop: "{{ file_content.stdout_lines | select('match', '^.+$') | list }}"
|
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
|
||||||
# ПЛЕЙ 2: (Пример) Проверка связи с новыми хостами
|
|
||||||
# -------------------------------------------------------------------------
|
|
||||||
- name: Verify connection to new hosts
|
|
||||||
hosts: extracted_dockers_hosts
|
|
||||||
gather_facts: false # Отключаем сбор фактов для скорости (или если нет доступа)
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ping host
|
|
||||||
# Используем win_ping для Windows или ping для Linux
|
|
||||||
# win_ping:
|
|
||||||
debug:
|
|
||||||
msg: "Успешное подключение к {{ inventory_hostname }} (IP: {{ ansible_host | default(inventory_hostname) }})"
|
|
||||||
Reference in New Issue
Block a user