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,36 @@
|
||||
---
|
||||
- name: Auto Configure DNS on Active Adapters
|
||||
hosts: windows
|
||||
gather_facts: no
|
||||
vars:
|
||||
dns_servers:
|
||||
- 192.168.1.250
|
||||
- 192.168.1.254
|
||||
- 77.88.8.8
|
||||
|
||||
tasks:
|
||||
# 1. Ищем имена активных адаптеров
|
||||
- name: Find active physical network adapters
|
||||
ansible.windows.win_shell: |
|
||||
Get-NetAdapter |
|
||||
Where-Object { $_.Status -eq 'Up' -and $_.HardwareInterface -eq $true } |
|
||||
Select-Object -ExpandProperty Name
|
||||
register: net_adapters
|
||||
changed_when: false
|
||||
|
||||
# 2. Показываем, какие адаптеры нашли (для логов)
|
||||
- name: Debug - Found Adapters
|
||||
debug:
|
||||
msg: "Найдены активные адаптеры: {{ net_adapters.stdout_lines }}"
|
||||
|
||||
# 3. Применяем DNS ко всем найденным адаптерам
|
||||
- name: Set DNS Servers
|
||||
ansible.windows.win_dns_client:
|
||||
adapter_names: "{{ item }}"
|
||||
ipv4_addresses: "{{ dns_servers }}"
|
||||
# Цикл пройдется по каждому найденному адаптеру (например, и Ethernet, и Wi-Fi)
|
||||
loop: "{{ net_adapters.stdout_lines }}"
|
||||
|
||||
# 4. Очищаем кэш
|
||||
- name: Flush DNS Cache
|
||||
ansible.windows.win_shell: ipconfig /flushdns
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
- name: Change SSH Port
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
new_ssh_port: 22233
|
||||
old_ssh_port: 22
|
||||
|
||||
tasks:
|
||||
# 1. Настройка SELinux (для CentOS/RHEL/Fedora)
|
||||
- name: Check if SELinux is enabled
|
||||
command: getenforce
|
||||
register: selinux_status
|
||||
changed_when: false
|
||||
ignore_errors: true
|
||||
|
||||
- name: Allow SSH on new port via SELinux
|
||||
community.general.seport:
|
||||
ports: "{{ new_ssh_port }}"
|
||||
proto: tcp
|
||||
setype: ssh_port_t
|
||||
state: present
|
||||
when:
|
||||
- selinux_status.stdout is defined
|
||||
- selinux_status.stdout == "Enforcing"
|
||||
ignore_errors: true
|
||||
# Игнорируем ошибки, если semanage не установлен,
|
||||
# но лучше установить policycoreutils-python-utils заранее.
|
||||
|
||||
# 2. Настройка Firewall (UFW для Ubuntu/Debian)
|
||||
- name: Open new SSH port in UFW
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
port: "{{ new_ssh_port }}"
|
||||
proto: tcp
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
# 3. Настройка Firewall (Firewalld для CentOS/RHEL)
|
||||
- name: Open new SSH port in Firewalld
|
||||
ansible.posix.firewalld:
|
||||
port: "{{ new_ssh_port }}/tcp"
|
||||
permanent: yes
|
||||
state: enabled
|
||||
immediate: yes
|
||||
when: ansible_os_family == "RedHat"
|
||||
|
||||
# 4. Изменение конфигурации SSHD
|
||||
- name: Update SSH port in sshd_config
|
||||
lineinfile:
|
||||
path: /etc/ssh/sshd_config
|
||||
regexp: '^#?Port\s+'
|
||||
line: "Port {{ new_ssh_port }}"
|
||||
state: present
|
||||
validate: '/usr/sbin/sshd -t -f %s'
|
||||
notify: Restart SSH
|
||||
|
||||
handlers:
|
||||
- name: Restart SSH
|
||||
service:
|
||||
name: "{{ item }}"
|
||||
state: restarted
|
||||
loop:
|
||||
- ssh
|
||||
- sshd
|
||||
ignore_errors: true
|
||||
# Используем loop, так как в Ubuntu служба называется 'ssh', а в CentOS 'sshd'
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
- name: Change SSH Port on Windows
|
||||
hosts: windows
|
||||
gather_facts: no
|
||||
|
||||
# ДОБАВИТЬ ЭТОТ БЛОК:
|
||||
collections:
|
||||
- ansible.windows
|
||||
- community.windows
|
||||
|
||||
vars:
|
||||
new_ssh_port: 22233
|
||||
sshd_config_path: 'C:\ProgramData\ssh\sshd_config'
|
||||
|
||||
tasks:
|
||||
- name: Allow new SSH port in Windows Firewall
|
||||
# Теперь можно писать короче, так как коллекции подключили выше
|
||||
win_firewall_rule:
|
||||
name: "OpenSSH-Server-Custom-Port"
|
||||
localport: "{{ new_ssh_port }}"
|
||||
action: allow
|
||||
direction: in
|
||||
protocol: tcp
|
||||
profiles: domain,private,public
|
||||
state: present
|
||||
enabled: yes
|
||||
|
||||
- name: Update Port in sshd_config
|
||||
win_lineinfile:
|
||||
path: "{{ sshd_config_path }}"
|
||||
regexp: '^#?Port\s+\d+'
|
||||
line: "Port {{ new_ssh_port }}"
|
||||
state: present
|
||||
notify: Restart Windows SSH
|
||||
|
||||
handlers:
|
||||
- name: Restart Windows SSH
|
||||
win_service:
|
||||
name: sshd
|
||||
state: restarted
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
- name: Check Ansible Config
|
||||
hosts: localhost
|
||||
gather_facts: no
|
||||
tasks:
|
||||
- name: Show current config file
|
||||
debug:
|
||||
msg: "Конфиг берется из: {{ lookup('env', 'ANSIBLE_CONFIG') | default('Не задан через ENV, ищем стандартный', true) }}"
|
||||
|
||||
- name: Run ansible --version to see config path
|
||||
command: ansible --version
|
||||
register: version_out
|
||||
|
||||
- name: Show version output
|
||||
debug:
|
||||
var: version_out.stdout_lines
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
- name: Configure Windows PC
|
||||
hosts: windows
|
||||
gather_facts: yes
|
||||
tasks:
|
||||
- name: Проверка связи (Ping)
|
||||
ansible.windows.win_ping:
|
||||
|
||||
- name: Узнать имя компьютера
|
||||
ansible.windows.win_shell: hostname
|
||||
register: host_out
|
||||
|
||||
- name: Показать имя
|
||||
debug:
|
||||
var: host_out.stdout_lines
|
||||
|
||||
# Пример: Создать папку на диске C
|
||||
- name: Create directory
|
||||
ansible.windows.win_file:
|
||||
path: C:\Temp\FromSemaphore
|
||||
state: directory
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
- name: Install Software from SMB
|
||||
hosts: windows
|
||||
gather_facts: no
|
||||
|
||||
# Не забываем про коллекции, если они нужны
|
||||
collections:
|
||||
- community.windows
|
||||
- ansible.windows
|
||||
|
||||
vars:
|
||||
drive_letter: "Z"
|
||||
# smb_user, smb_pass, smb_path приходят из Semaphore Environment
|
||||
|
||||
tasks:
|
||||
# 1. СНАЧАЛА УДАЛЯЕМ ДИСК (Принудительная зачистка)
|
||||
# Это гарантирует, что старые зависшие сессии не помешают
|
||||
- name: Force unmount Z drive
|
||||
community.windows.win_mapped_drive:
|
||||
letter: "{{ drive_letter }}"
|
||||
state: absent
|
||||
ignore_errors: yes # Не падать, если диска и так нет
|
||||
|
||||
# 2. ТЕПЕРЬ МОНТИРУЕМ НАЧИСТО
|
||||
- name: Mount Network Drive
|
||||
community.windows.win_mapped_drive:
|
||||
letter: "{{ drive_letter }}"
|
||||
path: "{{ smb_path }}"
|
||||
username: "{{ smb_user }}"
|
||||
password: "{{ smb_pass }}"
|
||||
state: present
|
||||
|
||||
# 3. Проверяем файлы (для отладки)
|
||||
- name: Check file existence
|
||||
win_stat:
|
||||
path: "{{ drive_letter }}:\\Stirling-PDF.msi"
|
||||
register: file_info
|
||||
|
||||
# 4. Установка
|
||||
#- name: Install Stirling-PDF (MSI)
|
||||
# ansible.windows.win_package:
|
||||
# path: "{{ drive_letter }}:\\Stirling-PDF.msi"
|
||||
# state: present
|
||||
# arguments: /quiet /norestart
|
||||
# when: file_info.stat.exists
|
||||
|
||||
# Пример 2: Установка EXE (mango)
|
||||
- name: Install mango (EXE)
|
||||
ansible.windows.win_package:
|
||||
path: "{{ drive_letter }}:\\mango.exe"
|
||||
state: present
|
||||
# Для EXE ключи тихой установки зависят от установщика (/S, /VERYSILENT и т.д.)
|
||||
arguments: /--silent
|
||||
product_id: mango # Помогает Ansible понять, установлен ли софт
|
||||
|
||||
# 5. Уборка
|
||||
- name: Unmount Network Drive
|
||||
community.windows.win_mapped_drive:
|
||||
letter: "{{ drive_letter }}"
|
||||
state: absent
|
||||
@@ -0,0 +1,142 @@
|
||||
---
|
||||
- name: Сбор инвентаря и создание (Метод через файл)
|
||||
hosts: localhost
|
||||
connection: local
|
||||
gather_facts: no
|
||||
vars:
|
||||
# --- НАСТРОЙКИ ---
|
||||
semaphore_url: "http://192.168.0.198:9999"
|
||||
semaphore_project_id: 1
|
||||
semaphore_key_id: 7
|
||||
semaphore_api_token: "9ojexqiwt1xkemig7j1bd1pe-frh7hkre4reryk2occ="
|
||||
inventory_name: "Auto Scanned Network"
|
||||
|
||||
# --- СЕТИ ---
|
||||
subnets:
|
||||
- "192.168.0.0/23"
|
||||
- "192.168.1.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"
|
||||
# добавьте остальные ваши подсети сюда...
|
||||
scan_ports: [5985, 22, 445]
|
||||
|
||||
tasks:
|
||||
# 1. Сканирование (Ваш код)
|
||||
- name: Сканирование сети
|
||||
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 не найдены!"
|
||||
when: active_ips | length == 0
|
||||
|
||||
# 2. Имена (Ваш код)
|
||||
- name: Определение имен
|
||||
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 }}
|
||||
|
||||
# 4. Текст инвентаря
|
||||
- name: Генерация текста
|
||||
set_fact:
|
||||
inventory_content: |
|
||||
[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
|
||||
|
||||
# ==========================================================
|
||||
# ИЗМЕНЕННАЯ ЧАСТЬ: СОЗДАНИЕ ЧЕРЕЗ ФАЙЛ
|
||||
# ==========================================================
|
||||
|
||||
- name: Сохранение JSON-пейлоада в файл (для надежности)
|
||||
copy:
|
||||
content: |
|
||||
{
|
||||
"name": "{{ inventory_name }} {{ 1000 | random }}",
|
||||
"project_id": {{ semaphore_project_id | int }},
|
||||
"type": "static",
|
||||
"ssh_key_id": {{ semaphore_key_id | int }},
|
||||
"become_key_id": null,
|
||||
"repository_id": null,
|
||||
"inventory": {{ inventory_content | to_json }}
|
||||
}
|
||||
dest: /tmp/semaphore_payload.json
|
||||
|
||||
- name: Отправка через 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"
|
||||
-H "Accept: application/json"
|
||||
-d @/tmp/semaphore_payload.json
|
||||
register: curl_result
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Показать полный ответ CURL
|
||||
debug:
|
||||
var: curl_result.stderr_lines
|
||||
|
||||
- name: Показать ответ сервера (body)
|
||||
debug:
|
||||
var: curl_result.stdout_lines
|
||||
|
||||
- name: Удалить временный файл
|
||||
file:
|
||||
path: /tmp/semaphore_payload.json
|
||||
state: absent
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
# -------------------------------------------------------------------------
|
||||
# ПЛЕЙ 1: Подключение к Docker-хосту и извлечение данных
|
||||
# -------------------------------------------------------------------------
|
||||
- name: Extract inventory from Docker container
|
||||
hosts: docker_servers # Группа в Semaphore, где лежит ваш Docker-сервер
|
||||
become: true # Обычно нужно sudo для команд docker
|
||||
vars:
|
||||
container_name: "my_app_container" # Имя вашего контейнера
|
||||
file_path_in_container: "/app/hosts.txt" # Путь к файлу внутри контейнера
|
||||
|
||||
tasks:
|
||||
- name: Check if container is running
|
||||
shell: "docker ps -q -f name={{ container_name }}"
|
||||
register: container_check
|
||||
|
||||
- name: Fail if container is not running
|
||||
fail:
|
||||
msg: "Контейнер {{ container_name }} не запущен!"
|
||||
when: container_check.stdout == ""
|
||||
|
||||
- name: Read file content from container
|
||||
# Используем docker exec для чтения файла
|
||||
command: "docker exec {{ container_name }} cat {{ file_path_in_container }}"
|
||||
register: file_content
|
||||
changed_when: false
|
||||
|
||||
- name: Parse output and add to in-memory inventory
|
||||
# add_host работает локально в памяти Ansible во время выполнения
|
||||
add_host:
|
||||
name: "{{ item }}"
|
||||
groups: extracted_hosts # Создаем новую временную группу
|
||||
# Можно добавить переменные, например, способ подключения:
|
||||
# ansible_ssh_user: root
|
||||
# Разделяем вывод cat по строкам и убираем пустые
|
||||
loop: "{{ file_content.stdout_lines | select('match', '^.+$') | list }}"
|
||||
|
||||
- name: Debug info
|
||||
debug:
|
||||
msg: "Добавлен хост: {{ item }}"
|
||||
loop: "{{ file_content.stdout_lines | select('match', '^.+$') | list }}"
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# ПЛЕЙ 2: Работа с новыми хостами
|
||||
# -------------------------------------------------------------------------
|
||||
- name: Configure the extracted hosts
|
||||
hosts: extracted_hosts # Обращаемся к группе, созданной в предыдущем шаге
|
||||
gather_facts: false # Отключаем, если нет SSH доступа или нужно ускорить
|
||||
|
||||
tasks:
|
||||
- name: Ping new hosts
|
||||
ping:
|
||||
|
||||
- name: Echo Hello
|
||||
debug:
|
||||
msg: "Я подключился к хосту {{ inventory_hostname }}, полученному из контейнера!"
|
||||
@@ -0,0 +1,6 @@
|
||||
- name: Test Connection to Servers
|
||||
hosts: all
|
||||
become: no
|
||||
tasks:
|
||||
- name: Ping my Servers
|
||||
ping:
|
||||
@@ -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
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Check Windows DNS settings
|
||||
hosts: all
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Check DNS servers
|
||||
ansible.windows.win_shell: |
|
||||
Get-DnsClientServerAddress -AddressFamily IPv4 |
|
||||
Select-Object InterfaceAlias, ServerAddresses
|
||||
register: dns_result
|
||||
|
||||
- name: Display DNS settings
|
||||
debug:
|
||||
msg: "{{ dns_result.stdout }}"
|
||||
Reference in New Issue
Block a user