# -*- coding: utf-8 -*- """Shared helper for the L2 collectors: read the module config, resolve the selected templates to template ids, and list the hosts that should be collected. """ import os import json import time try: import l2db except Exception: # pragma: no cover - only used on an installed host l2db = None DEFAULT_PATHS = [ os.environ.get('L2_CONFIG') or '', '/opt/zabbix/zabbix-server/web-modules/WecomCenter/assets/l2topology/config.json', '/usr/share/zabbix/modules/WecomCenter/assets/l2topology/config.json', os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.json'), ] _CACHE = None _CACHE_AT = 0 def _from_db(): """Read the module config from Zabbix's own DB (primary source).""" if l2db is None: return None try: raw = l2db.scalar('SELECT HEX(config) FROM l2_topology_config WHERE id=1') if raw: return json.loads(bytes.fromhex(raw).decode('utf-8')) except Exception: pass return None def _from_mirror(): """Fallback for a fresh install before the first DB save.""" for p in DEFAULT_PATHS: if p and os.path.isfile(p): try: with open(p, encoding='utf-8') as f: return json.load(f) except Exception: pass return None def config(): """Return the L2 configuration, DB first and JSON mirror as fallback.""" global _CACHE, _CACHE_AT now = time.time() if _CACHE is not None and now - _CACHE_AT < 30: return _CACHE data = _from_db() if data is None: data = _from_mirror() if data is None: data = {} _CACHE = data _CACHE_AT = now return data def template_ids(call): """Resolve configured template names -> [templateid]. Empty list => no filter.""" cfg = config() names = [str(n).strip() for n in (cfg.get('templates') or []) if str(n).strip()] if not names: return [] try: tpls = call('template.get', {'output': ['templateid', 'name']})['result'] except Exception: return [] want = {n.lower() for n in names} return [t['templateid'] for t in tpls if t.get('name', '').strip().lower() in want] def hosts(call, output=None, interfaces='extend'): """host.get restricted to the configured templates (when resolvable).""" p = {'output': output or ['hostid', 'name'], 'selectInterfaces': interfaces} tids = template_ids(call) if tids: p['templateids'] = tids return call('host.get', p)['result']