not yet working correctly
This commit is contained in:
parent
9f034b6a22
commit
b3fdc82913
@ -1,5 +1,6 @@
|
|||||||
import ntp.packet
|
import ntp.packet
|
||||||
import threading
|
import threading
|
||||||
|
from contextlib import AbstractContextManager
|
||||||
import time
|
import time
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
@ -8,6 +9,101 @@ import pwd
|
|||||||
import grp
|
import grp
|
||||||
import logging
|
import logging
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
|
import pyagentx3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BASE_OID_ENTERPRISE = '1.3.6.1.4.1'
|
||||||
|
BASE_OID_HOTTIS = BASE_OID_ENTERPRISE + '.9676'
|
||||||
|
BASE_OID_HOTTIS_NTPSEC = BASE_OID_HOTTIS + '.123'
|
||||||
|
|
||||||
|
def int_scale1k(x):
|
||||||
|
return int (x * 1000)
|
||||||
|
|
||||||
|
def int_scale1M(x):
|
||||||
|
return int (x * 1000000)
|
||||||
|
|
||||||
|
def pass_value(x):
|
||||||
|
return x
|
||||||
|
|
||||||
|
LOCAL_SERVER_KEYS = [
|
||||||
|
['leap', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['stratum', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['precision', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['rootdelay', pyagentx3.TYPE_INTEGER, int_scale1k],
|
||||||
|
['rootdisp', pyagentx3.TYPE_INTEGER, int_scale1k],
|
||||||
|
['rootdist', pyagentx3.TYPE_INTEGER, int_scale1k],
|
||||||
|
['refid', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['reftime', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['tc', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['peer', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['offset', pyagentx3.TYPE_INTEGER, int_scale1M],
|
||||||
|
['frequency', pyagentx3.TYPE_INTEGER, int_scale1k],
|
||||||
|
['sys_jitter', pyagentx3.TYPE_INTEGER, int_scale1M],
|
||||||
|
['clk_jitter', pyagentx3.TYPE_INTEGER, int_scale1M],
|
||||||
|
['clock', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['processor', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['system', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['release', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['version', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['clk_wander', pyagentx3.TYPE_INTEGER, int_scale1M],
|
||||||
|
['daemon_version', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['tai', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['leapsec', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['expire', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['mintc', pyagentx3.TYPE_INTEGER, pass_value]
|
||||||
|
]
|
||||||
|
|
||||||
|
PEER_KEYS = [
|
||||||
|
['srcadr', pyagentx3.TYPE_IPADDRESS, pass_value],
|
||||||
|
['srcport', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['dstadr', pyagentx3.TYPE_IPADDRESS, pass_value],
|
||||||
|
['dstport', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['leap', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['hmode', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['stratum', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['ppoll', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['hpoll', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['precision', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['rootdelay', pyagentx3.TYPE_INTEGER, int_scale1k],
|
||||||
|
['rootdisp', pyagentx3.TYPE_INTEGER, int_scale1k],
|
||||||
|
['refid', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['reftime', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['rec', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['xmt', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['reach', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['unreach', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['delay-s', pyagentx3.TYPE_INTEGER, int_scale1k],
|
||||||
|
['delay', pyagentx3.TYPE_INTEGER, int_scale1k],
|
||||||
|
['offset', pyagentx3.TYPE_INTEGER, int_scale1M],
|
||||||
|
['jitter', pyagentx3.TYPE_INTEGER, int_scale1M],
|
||||||
|
['dispersion', pyagentx3.TYPE_INTEGER, int_scale1k],
|
||||||
|
['keyid', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['filtdelay', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['filtoffset', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['pmode', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['filtdisp', pyagentx3.TYPE_OCTETSTRING, pass_value],
|
||||||
|
['flash', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['headway', pyagentx3.TYPE_INTEGER, pass_value],
|
||||||
|
['ntscookies', pyagentx3.TYPE_INTEGER, pass_value]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class DataStore(AbstractContextManager):
|
||||||
|
def __init__(self):
|
||||||
|
self.lock = threading.Lock()
|
||||||
|
self.data = {}
|
||||||
|
|
||||||
|
def update_data(self, data):
|
||||||
|
self.data.clear()
|
||||||
|
self.data.update(data)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.lock.acquire()
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
|
self.lock.release()
|
||||||
|
|
||||||
|
|
||||||
class NtpDataCollector(threading.Thread):
|
class NtpDataCollector(threading.Thread):
|
||||||
@ -19,6 +115,8 @@ class NtpDataCollector(threading.Thread):
|
|||||||
self.session = ntp.packet.ControlSession()
|
self.session = ntp.packet.ControlSession()
|
||||||
self.session.openhost(self.ntpserver)
|
self.session.openhost(self.ntpserver)
|
||||||
|
|
||||||
|
self.data_store = DataStore()
|
||||||
|
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
@ -28,19 +126,82 @@ class NtpDataCollector(threading.Thread):
|
|||||||
ntpserver_vars = self.session.readvar(0)
|
ntpserver_vars = self.session.readvar(0)
|
||||||
logger.debug(f"{ntpserver_vars=}")
|
logger.debug(f"{ntpserver_vars=}")
|
||||||
|
|
||||||
|
tmp_data_store = {}
|
||||||
|
tmp_data_store['local'] = dict(ntpserver_vars)
|
||||||
|
|
||||||
peers = self.session.readstat()
|
peers = self.session.readstat()
|
||||||
|
tmp_data_store['peers'] = {}
|
||||||
for peer in peers:
|
for peer in peers:
|
||||||
peer_vars = self.session.readvar(peer.associd)
|
peer_vars = self.session.readvar(peer.associd)
|
||||||
|
tmp_data_store['peers'][peer.associd] = dict(peer_vars)
|
||||||
logger.debug(f"{peer.associd=}, {peer_vars=}")
|
logger.debug(f"{peer.associd=}, {peer_vars=}")
|
||||||
|
|
||||||
|
with self.data_store as ds:
|
||||||
|
ds.update_data(tmp_data_store)
|
||||||
|
|
||||||
time.sleep(self.period)
|
time.sleep(self.period)
|
||||||
logger.info('NtpDataCollector terminating')
|
logger.info('NtpDataCollector terminating')
|
||||||
|
|
||||||
|
def get_data_store(self):
|
||||||
|
return self.data_store
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.stop_event.set()
|
self.stop_event.set()
|
||||||
self.join()
|
self.join()
|
||||||
|
|
||||||
|
class TestUpdater(pyagentx3.Updater):
|
||||||
|
def update(self):
|
||||||
|
self.set_INTEGER('1', 123)
|
||||||
|
|
||||||
|
class NtpsecDataUpdater(pyagentx3.Updater):
|
||||||
|
def update(self):
|
||||||
|
logger.warn('XXX')
|
||||||
|
with self.data_store as ds:
|
||||||
|
for index, data_spec in enumerate(LOCAL_SERVER_KEYS):
|
||||||
|
logger.debug(f"local: {index=}, {data_spec}")
|
||||||
|
CURRENT_NAME_OID_BASE = '0.' + str(index) + '.0'
|
||||||
|
CURRENT_VALUE_OID_BASE = '0.' + str(index) + '.1'
|
||||||
|
self._data[CURRENT_NAME_OID_BASE] = {
|
||||||
|
'name': CURRENT_NAME_OID_BASE,
|
||||||
|
'type': pyagentx3.TYPE_OCTETSTRING,
|
||||||
|
'value': data_spec[0]
|
||||||
|
}
|
||||||
|
self._data[CURRENT_VALUE_OID_BASE] = {
|
||||||
|
'name': CURRENT_VALUE_OID_BASE,
|
||||||
|
'type': data_spec[1],
|
||||||
|
'value': data_spec[2](ds.data['local'][data_spec[0]])
|
||||||
|
}
|
||||||
|
for associd, peer in ds.data['peers'].items():
|
||||||
|
logger.debug(f"peer: {associd=}, {peer=}")
|
||||||
|
for index, data_spec in enumerate(PEER_KEYS):
|
||||||
|
logger.debug(f"peer: {associd=}, {index=}, {data_spec}")
|
||||||
|
CURRENT_NAME_OID_BASE = str(associd) + '.' + str(index) + '.0'
|
||||||
|
CURRENT_VALUE_OID_BASE = str(associd) + '.' + str(index) + '.1'
|
||||||
|
self._data[CURRENT_NAME_OID_BASE] = {
|
||||||
|
'name': CURRENT_NAME_OID_BASE,
|
||||||
|
'type': pyagentx3.TYPE_OCTETSTRING,
|
||||||
|
'value': data_spec[0]
|
||||||
|
}
|
||||||
|
self._data[CURRENT_VALUE_OID_BASE] = {
|
||||||
|
'name': CURRENT_VALUE_OID_BASE,
|
||||||
|
'type': data_spec[1],
|
||||||
|
'value': data_spec[2](ds.data['local'][data_spec[0]])
|
||||||
|
}
|
||||||
|
logger.warn(f"YYY: {self._data=}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class NtpsecAgent(pyagentx3.Agent):
|
||||||
|
def __init__(self, agent_id='NtpsecAgent', socket_path=None, data_store=None):
|
||||||
|
logger.debug('Agent created')
|
||||||
|
self.data_store = data_store
|
||||||
|
super().__init__(agent_id, socket_path)
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
logger.debug('Agent setup')
|
||||||
|
self.register(BASE_OID_HOTTIS_NTPSEC, NtpsecDataUpdater, freq=1, data_store=self.data_store)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def daemonize(pid_filename):
|
def daemonize(pid_filename):
|
||||||
@ -153,9 +314,14 @@ if __name__ == '__main__':
|
|||||||
try:
|
try:
|
||||||
ndc = NtpDataCollector(ntpserver=ntpserver, period=period)
|
ndc = NtpDataCollector(ntpserver=ntpserver, period=period)
|
||||||
ndc.start()
|
ndc.start()
|
||||||
|
|
||||||
|
nsax = NtpsecAgent(data_store=ndc.get_data_store())
|
||||||
|
nsax.start()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Unhandled exception: {e}")
|
logger.error(f"Unhandled exception: {e}")
|
||||||
|
nsax.stop()
|
||||||
ndc.stop()
|
ndc.stop()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
nsax.stop()
|
||||||
ndc.stop()
|
ndc.stop()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user