[Git][NTPsec/ntpsec][master] 3 commits: Comment cleanup
Ian Bruene
gitlab at mg.gitlab.com
Wed Dec 27 18:46:32 UTC 2017
Ian Bruene pushed to branch master at NTPsec / ntpsec
Commits:
7ba3a555 by Ian Bruene at 2017-12-27T08:48:01-06:00
Comment cleanup
- - - - -
fde7efee by Ian Bruene at 2017-12-27T08:48:01-06:00
Moved some functions around
- - - - -
64003e7d by Ian Bruene at 2017-12-27T12:45:06-06:00
Attempted ntpsnmpd notifications, currently non-functional
- - - - -
1 changed file:
- ntpclients/ntpsnmpd.py
Changes:
=====================================
ntpclients/ntpsnmpd.py
=====================================
--- a/ntpclients/ntpsnmpd.py
+++ b/ntpclients/ntpsnmpd.py
@@ -12,10 +12,10 @@ import select
import subprocess
try:
- import ntp.agentx
- ax = ntp.agentx
import ntp.packet
import ntp.util
+ import ntp.agentx
+ ax = ntp.agentx
except ImportError as e:
sys.stderr.write(
"ntpsnmpd: can't find Python NTP library.\n")
@@ -34,10 +34,12 @@ timeout = 5 # default timeout, what shuold this be?
ntpRootOID = (1, 3, 6, 1, 2, 1, 197) # mib-2 . 197, aka: NTPv4-MIB
+snmpTrapOID = (1, 3, 6, 1, 6, 3, 1, 1, 4, 1)
+
DEFHOST = "localhost" # For now only know how to talk to the local ntp
-class DataSource: # This may be broken up in future to be less NTP-specific
+class DataSource: # This will be broken up in future to be less NTP-specific
def __init__(self):
node = ax.mibnode
# This is defined as a dict tree because simpler, and avoids
@@ -249,12 +251,13 @@ class DataSource: # This may be broken up in future to be less NTP-specific
# Cache so we don't hammer ntpd, default 1 second timeout
# timeout default pulled from a hat
self.cache = ntp.util.Cache(1)
+ self.lastHeartbeat = 0
# The undo system is only for the last operation
self.inSetP = False # Are we currently in the set procedure?
self.setVarbinds = [] # Varbind of the current set operation
self.setHandlers = [] # Handlers for commit/undo/cleanup of set
self.setUndoData = [] # Previous values for undoing
- self.heartbeatInterval = 0
+ self.heartbeatInterval = 10 # should save to disk
self.sentNotifications = 0
# Notify bits, these should be saved to disk
# Also they currently have no effect
@@ -265,7 +268,7 @@ class DataSource: # This may be broken up in future to be less NTP-specific
self.notifyRMAssociation = False # 5
self.notifyConfigChange = False # 6
self.notifyLeapSecondAnnounced = False # 7
- self.notifyHeartbeat = False # 8
+ self.notifyHeartbeat = True # 8
def getOID_core(self, nextP, searchoid, returnGenerator=False):
gen = ax.walkMIBTree(self.oidTree, ntpRootOID)
@@ -390,8 +393,10 @@ class DataSource: # This may be broken up in future to be less NTP-specific
mode = 3 # No reference configured
elif source == ntp.control.CTL_SST_TS_LOCAL:
mode = 4 # Distributing local clock (low accuracy)
- elif source in (ntp.control.CTL_SST_TS_ATOM, ntp.control.CTL_SST_TS_LF,
- ntp.control.CTL_SST_TS_HF, ntp.control.CTL_SST_TS_UHF):
+ elif source in (ntp.control.CTL_SST_TS_ATOM,
+ ntp.control.CTL_SST_TS_LF,
+ ntp.control.CTL_SST_TS_HF,
+ ntp.control.CTL_SST_TS_UHF):
# I am not sure if I should be including the radios in this
mode = 5 # Synced to local refclock
elif source == ntp.control.CTL_SST_TS_NTP:
@@ -420,7 +425,9 @@ class DataSource: # This may be broken up in future to be less NTP-specific
def cbr_statusActiveRefSourceName(self, oid):
# utf8
- data = self.session.readvar(0, ["peeradr"])
+ data = self.safeReadvar(0, ["peeradr"])
+ if data is None:
+ return ax.Varbind(ax.VALUE_NULL, oid)
data = ntp.util.canonicalize_dns(data["peeradr"])
return ax.Varbind(ax.VALUE_OCTET_STR, oid, data)
@@ -625,7 +632,7 @@ class DataSource: # This may be broken up in future to be less NTP-specific
pdata = self.misc_getPeerData()
if pdata is None:
return ax.Varbind(ax.VALUE_NULL, oid)
- peername = pdata[associd]["srcadr"][1] # TODO: DNS
+ peername = pdata[associd]["srcadr"][1]
peername = ntp.util.canonicalize_dns(peername)
return ax.Varbind(ax.VALUE_OCTET_STR, oid, peername)
return self.dynamicCallbackSkeleton(handler)
@@ -768,6 +775,31 @@ class DataSource: # This may be broken up in future to be less NTP-specific
return self.dynamicCallbackSkeleton(handler)
# =====================================
+ # Notification handlers
+ # =====================================
+
+ def checkNotifications(self, control):
+ if self.notifyHeartbeat is True:
+ if self.heartbeatInterval == 0: # interval == 0 means send once
+ self.notifyHeartbeat = False
+ vl = [ax.Varbind(ax.VALUE_OID, snmpTrapOID,
+ ax.OID((1, 3, 6, 1, 2, 1, 197, 0, 8))),
+ ax.Varbind(ax.VALUE_GAUGE32,
+ (1, 2, 6, 1, 2, 1, 197, 0, 1, 4, 1),
+ self.heartbeatInterval)]
+ control.sendNotify(vl, "public")
+ else:
+ current = ntp.util.monoclock()
+ if (current - self.lastHeartbeat) > self.heartbeatInterval:
+ self.lastHeartbeat = current
+ vl = [ax.Varbind(ax.VALUE_OID, snmpTrapOID,
+ ax.OID((1, 3, 6, 1, 2, 1, 197, 0, 8))),
+ ax.Varbind(ax.VALUE_GAUGE32,
+ (1, 2, 6, 1, 2, 1, 197, 0, 1, 4, 1),
+ self.heartbeatInterval)]
+ control.sendNotify(vl, "public")
+
+ # =====================================
# Misc data helpers (not part of the MIB proper)
# =====================================
@@ -824,21 +856,6 @@ class DataSource: # This may be broken up in future to be less NTP-specific
return peerdata
-def dolog(text, level):
- if debug >= level:
- logfp.write(text)
-
-
-def connect():
- sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- try:
- sock.connect("/var/agentx/master")
- except socket.error as msg:
- dolog(repr(msg) + "\n", 2)
- sys.exit(1)
- return sock
-
-
class PacketControl:
def __init__(self, sock, dbase, spinGap=0.001, timeout=5):
# take a pre-made socket instead of making our own so that
@@ -868,7 +885,7 @@ class PacketControl:
while True:
self._doloop()
if self.loopCallback is not None:
- self.loopCallback()
+ self.loopCallback(self)
time.sleep(self.spinGap)
else:
self._doloop()
@@ -968,6 +985,11 @@ class PacketControl:
packet.packetID)
self.packetLog[index] = packet
+ def sendNotify(self, varbinds, context=None):
+ # DUMMY: transactionID, packetID
+ pkt = ax.NotifyPDU(True, self.sessionID, 300, 1, varbinds, context)
+ self.sendPacket(pkt, True)
+
def sendErrorResponse(self, errorHeader, errorType, errorIndex):
err = ax.ResponsePDU(errorHeader["flags"]["bigEndian"],
errorHeader["session_id"],
@@ -1140,11 +1162,27 @@ class PacketControl:
self.database.inSetP = False
+def dolog(text, level):
+ if debug >= level:
+ logfp.write(text)
+
+
+def connect():
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ try:
+ sock.connect("/var/agentx/master")
+ except socket.error as msg:
+ dolog(repr(msg) + "\n", 2)
+ sys.exit(1)
+ return sock
+
+
def mainloop():
dolog("initing loop\n", 1)
sock = connect()
dbase = DataSource()
control = PacketControl(sock, dbase)
+ control.loopCallback = dbase.checkNotifications
control.initNewSession()
control.mainloop(True)
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/b4665e1084ac7e80995a5e0b726dcd7f28d4bc9a...64003e7dec63acdc456697b7c42e070d971dfb5a
---
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/b4665e1084ac7e80995a5e0b726dcd7f28d4bc9a...64003e7dec63acdc456697b7c42e070d971dfb5a
You're receiving this email because of your account on gitlab.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20171227/75a0034a/attachment.html>
More information about the vc
mailing list