| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """Ping every collected switch's management IP in parallel.
- Zabbix host -> switch latency is the only latency that can be measured without
- touching device config, so this is what drives the node latency colouring.
- Writes /tmp/latency.tsv -> <ip>\\t<avg_ms or empty>
- """
- import json
- import re
- import subprocess
- import concurrent.futures as cf
- import urllib.request
- import l2cfg
- TOK = 'd3abb125eb301a021ef80a2847a803a7cd2d0b1d3c8337a14d09db9d571369b5'
- API = 'http://192.168.87.20:8080/api_jsonrpc.php'
- OUT = '/tmp/latency.tsv'
- def call(m, p):
- d = json.dumps({"jsonrpc": "2.0", "method": m, "params": p, "id": 1}).encode()
- q = urllib.request.Request(API, data=d, headers={'Content-Type': 'application/json', 'Authorization': 'Bearer ' + TOK})
- return json.loads(urllib.request.urlopen(q, timeout=60).read().decode())
- def ping(ip):
- try:
- r = subprocess.run(['ping', '-c', '3', '-W', '1', '-q', ip],
- capture_output=True, text=True, timeout=10)
- m = re.search(r'=\s*[\d.]+/([\d.]+)/', r.stdout)
- if m:
- return ip, float(m.group(1))
- m = re.search(r'time=([\d.]+)\s*ms', r.stdout)
- if m:
- return ip, float(m.group(1))
- except Exception:
- pass
- return ip, None
- def main():
- hs = l2cfg.hosts(call)
- ips = sorted({i['ip'] for h in hs for i in (h.get('interfaces') or [])
- if i.get('ip') and i.get('type') == '2'})
- if not ips:
- ips = sorted({i['ip'] for h in hs for i in (h.get('interfaces') or []) if i.get('ip')})
- res = {}
- with cf.ThreadPoolExecutor(max_workers=40) as ex:
- for ip, v in ex.map(ping, ips):
- res[ip] = v
- with open(OUT, 'w', encoding='utf-8') as f:
- for ip in ips:
- v = res.get(ip)
- f.write('%s\t%s\n' % (ip, '' if v is None else '%.3f' % v))
- ok = sum(1 for v in res.values() if v is not None)
- print('latency: %d/%d reachable' % (ok, len(ips)))
- if __name__ == '__main__':
- main()
|