l2cfg.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. # -*- coding: utf-8 -*-
  2. """Shared helper for the L2 collectors: read the module config, resolve the
  3. selected templates to template ids, and list the hosts that should be collected.
  4. """
  5. import os
  6. import json
  7. import time
  8. try:
  9. import l2db
  10. except Exception: # pragma: no cover - only used on an installed host
  11. l2db = None
  12. DEFAULT_PATHS = [
  13. os.environ.get('L2_CONFIG') or '',
  14. '/opt/zabbix/zabbix-server/web-modules/WecomCenter/assets/l2topology/config.json',
  15. '/usr/share/zabbix/modules/WecomCenter/assets/l2topology/config.json',
  16. os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.json'),
  17. ]
  18. _CACHE = None
  19. _CACHE_AT = 0
  20. def _from_db():
  21. """Read the module config from Zabbix's own DB (primary source)."""
  22. if l2db is None:
  23. return None
  24. try:
  25. raw = l2db.scalar('SELECT HEX(config) FROM l2_topology_config WHERE id=1')
  26. if raw:
  27. return json.loads(bytes.fromhex(raw).decode('utf-8'))
  28. except Exception:
  29. pass
  30. return None
  31. def _from_mirror():
  32. """Fallback for a fresh install before the first DB save."""
  33. for p in DEFAULT_PATHS:
  34. if p and os.path.isfile(p):
  35. try:
  36. with open(p, encoding='utf-8') as f:
  37. return json.load(f)
  38. except Exception:
  39. pass
  40. return None
  41. def config():
  42. """Return the L2 configuration, DB first and JSON mirror as fallback."""
  43. global _CACHE, _CACHE_AT
  44. now = time.time()
  45. if _CACHE is not None and now - _CACHE_AT < 30:
  46. return _CACHE
  47. data = _from_db()
  48. if data is None:
  49. data = _from_mirror()
  50. if data is None:
  51. data = {}
  52. _CACHE = data
  53. _CACHE_AT = now
  54. return data
  55. def template_ids(call):
  56. """Resolve configured template names -> [templateid]. Empty list => no filter."""
  57. cfg = config()
  58. names = [str(n).strip() for n in (cfg.get('templates') or []) if str(n).strip()]
  59. if not names:
  60. return []
  61. try:
  62. tpls = call('template.get', {'output': ['templateid', 'name']})['result']
  63. except Exception:
  64. return []
  65. want = {n.lower() for n in names}
  66. return [t['templateid'] for t in tpls if t.get('name', '').strip().lower() in want]
  67. def hosts(call, output=None, interfaces='extend'):
  68. """host.get restricted to the configured templates (when resolvable)."""
  69. p = {'output': output or ['hostid', 'name'], 'selectInterfaces': interfaces}
  70. tids = template_ids(call)
  71. if tids:
  72. p['templateids'] = tids
  73. return call('host.get', p)['result']