91 lines
3.4 KiB
Python
91 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
import subprocess
|
|
import sys
|
|
import json
|
|
import re
|
|
|
|
# Имя вашего контейнера
|
|
CONTAINER = "amnezia-awg2"
|
|
|
|
def get_awg_output():
|
|
# Получаем вывод без -it (для скриптов tty не нужен)
|
|
cmd = f"docker exec {CONTAINER} awg show"
|
|
res = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
|
return res.stdout
|
|
|
|
def parse_awg():
|
|
output = get_awg_output()
|
|
peers = {}
|
|
current_peer = None
|
|
|
|
# Регулярные выражения для парсинга
|
|
for line in output.split('\n'):
|
|
line = line.strip()
|
|
if line.startswith('peer:'):
|
|
current_peer = line.split()[1]
|
|
peers[current_peer] = {'peer': current_peer}
|
|
elif current_peer and ':' in line:
|
|
key, val = line.split(':', 1)
|
|
peers[current_peer][key.strip()] = val.strip()
|
|
|
|
return peers
|
|
|
|
def do_discovery():
|
|
peers = parse_awg()
|
|
discovery_data = []
|
|
for p_id, p_data in peers.items():
|
|
# Используем Allowed IPs (например, 10.8.1.3) в качестве уникального имени макроса
|
|
ip = p_data.get('allowed ips', '').split('/')[0]
|
|
if ip:
|
|
discovery_data.append({
|
|
"{#AWG_PEER_IP}": ip,
|
|
"{#AWG_PEER_KEY}": p_id[:8] # первые 8 символов ключа для удобства
|
|
})
|
|
print(json.dumps({"data": discovery_data}))
|
|
|
|
def do_metrics():
|
|
peers = parse_awg()
|
|
# Если используется zabbix_sender, формируем строки для отправки
|
|
# Для пассивных проверок выводим конкретную метрику
|
|
if len(sys.argv) < 4:
|
|
return
|
|
|
|
target_ip = sys.argv[2]
|
|
metric = sys.argv[3]
|
|
|
|
for p_id, p_data in peers.items():
|
|
ip = p_data.get('allowed ips', '').split('/')[0]
|
|
if ip == target_ip:
|
|
val = p_data.get(metric, '0')
|
|
|
|
# Конвертируем трафик в байты, если запрашивают transfer
|
|
if metric == 'transfer':
|
|
# Пример: "683.97 MiB received, 10.20 GiB sent"
|
|
rx = re.search(r'([\d\.]+)\s+(\w+)\s+received', val)
|
|
tx = re.search(r'([\d\.]+)\s+(\w+)\s+sent', val)
|
|
|
|
def to_bytes(num, unit):
|
|
mult = {'B': 1, 'KiB': 1024, 'MiB': 1024**2, 'GiB': 1024**3, 'TiB': 1024**4}
|
|
return int(float(num) * mult.get(unit, 1))
|
|
|
|
if rx and tx:
|
|
if 'rx' in sys.argv[0] or 'received' in metric_type_sub(): # См. логику ниже
|
|
pass
|
|
# Упростим отдачу для UserParameter: отдельный вызов под каждую метрику
|
|
|
|
# Для простоты отдаем сырую строку, Zabbix сам умеет парсить Handshake
|
|
if metric == 'latest handshake':
|
|
# Если handshakes нет вообще
|
|
if 'disabled' in val or not val: print(-1)
|
|
else: print(val)
|
|
return
|
|
|
|
print(val)
|
|
return
|
|
print(0)
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) > i and sys.argv[1] == "discovery":
|
|
do_discovery()
|
|
|