[Git][NTPsec/ntpsec][master] 3 commits: Added mode change notification.

Ian Bruene gitlab at mg.gitlab.com
Fri Jan 5 19:47:55 UTC 2018


Ian Bruene pushed to branch master at NTPsec / ntpsec


Commits:
8674d1df by Ian Bruene at 2018-01-05T11:25:06-06:00
Added mode change notification.

- - - - -
66b6dae5 by Ian Bruene at 2018-01-05T13:44:11-06:00
Added associd add/remove notifications.

- - - - -
28dde842 by Ian Bruene at 2018-01-05T13:47:30-06:00
Removed obsolete documention of FHS violation.

- - - - -


3 changed files:

- INSTALL
- ntpclients/ntpsnmpd.py
- packaging/packaging.txt


Changes:

=====================================
INSTALL
=====================================
--- a/INSTALL
+++ b/INSTALL
@@ -58,7 +58,6 @@ Python 2.x, x >= 6, or Python 3.x, x >= 3::
      export PYTHONPATH=/usr/local/lib/python2.6/site-packages
    (I put it in my .bashrc)
 
-
 argparse::
    Required for ntpviz when using Python version 2.6
    Install with pip: pip install argparse


=====================================
ntpclients/ntpsnmpd.py
=====================================
--- a/ntpclients/ntpsnmpd.py
+++ b/ntpclients/ntpsnmpd.py
@@ -376,36 +376,8 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
 
     # Blank: ntpEntStatus
 
-    def cbr_statusCurrentMode(self, oid):  # DUMMY, partially implemented
-        # Range of integers
-        try:
-            # Don't care about the data, this is a ploy to the the rstatus
-            self.session.readvar(0, ["stratum"])
-        except ntp.packet.ControlException as e:
-            if e.message == ntp.packet.SERR_SOCKET:
-                # Can't connect, ntpd probably not running
-                return ax.Varbind(ax.VALUE_INTEGER, oid, 1)
-            else:
-                raise e
-        rstatus = self.session.rstatus  # a ploy to get the system status
-        source = ntp.control.CTL_SYS_SOURCE(rstatus)
-        if source == ntp.control.CTL_SST_TS_UNSPEC:
-            mode = 2  # Not yet synced
-        elif False:
-            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):
-            # 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:
-            # Should this include "other"? That covers things like chrony...
-            mode = 6  # Sync to remote NTP
-        else:
-            mode = 99  # Unknown
+    def cbr_statusCurrentMode(self, oid):
+        mode = self.misc_getMode()
         return ax.Varbind(ax.VALUE_INTEGER, oid, mode)
 
     def cbr_statusStratum(self, oid):
@@ -781,11 +753,15 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
         if self.notifySyspeerChange is True:
             self.doNotifySyspeerChange(control)
 
-        if self.notifyAddAssociation is True:
-            self.doNotifyAddAssociation(control)
-
-        if self.notifyRMAssociation is True:
-            self.doNotifyRMAssociation(control)
+        # Both and and remove have to look at the same data, don't want them
+        # stepping on each other. Therefore the functions are combined.
+        if (self.notifyAddAssociation is True) and \
+           (self.notifyRMAssociation is True):
+            self.doNotifyChangeAssociation(control, "both")
+        elif self.notifyAddAssociation is True:
+            self.doNotifyChangeAssociation(control, "add")
+        elif self.notifyRMAssociation is True:
+            self.doNotifyChangeAssociation(control, "rm")
 
         if self.notifyConfigChange is True:
             self.doNotifyConfigChange(control)
@@ -795,9 +771,21 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
 
         if self.notifyHeartbeat is True:
             self.doNotifyHeartbeat(control)
+        # Test code
 
     def doNotifyModeChange(self, control):
-        pass  # DUMMY
+        oldMode = self.oldValues.get("mode")
+        newMode = self.misc_getMode()  # connection failure handled by method
+        if oldMode is None:
+            self.oldValues["mode"] = newMode
+            return
+        elif oldMode != newMode:
+            self.oldValues["mode"] = newMode
+            vl = [ax.Varbind(ax.VALUE_OID, snmpTrapOID,
+                             ax.OID(ntpRootOID + (0, 1))),
+                  ax.Varbind(ax.VALUE_INTEGER, ntpRootOID + (1, 2, 1),
+                             newMode)]
+            control.sendNotify(vl)
 
     def doNotifyStratumChange(self, control):
         oldStratum = self.oldValues.get("stratum")
@@ -808,6 +796,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
             self.oldValues["stratum"] = newStratum
             return
         elif oldStratum != newStratum:
+            self.oldValues["stratum"] = newStratum
             datetime = self.safeReadvar(0, ["reftime"])["reftime"]
             if datetime is None:
                 datetime = ""
@@ -832,6 +821,7 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
             self.oldValues["syspeer"] = newSyspeer
             return
         elif oldSyspeer != newSyspeer:
+            self.oldValues["syspeer"] = newSyspeer
             datetime = self.safeReadvar(0, ["reftime"])["reftime"]
             if datetime is None:
                 datetime = ""
@@ -848,11 +838,43 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
                              "SysPeer changed")]  # Uh... what goes here?
             control.sendNotify(vl)
 
-    def doNotifyAddAssociation(self, control):
-        pass  # DUMMY
-
-    def doNotifyRMAssociation(self, control):
-        pass  # DUMMY
+    def doNotifyChangeAssociation(self, control, which):
+        changes = self.misc_getAssocListChanges()
+        if changes is None:
+            return
+        datetime = self.safeReadvar(0, ["reftime"])["reftime"]
+        if datetime is None:
+            datetime = ""
+        else:
+            datetime = ntp.util.deformatNTPTime(datetime)
+        adds, rms = changes
+        print("Notify Change assoc:", changes)
+        if which in ("add", "both"):
+            print("adding", adds)
+            for name in adds:
+                vl = [ax.Varbind(ax.VALUE_OID, snmpTrapOID,
+                                 ax.OID(ntpRootOID + (0, 4))),  # Add
+                      ax.Varbind(ax.VALUE_OCTET_STR, ntpRootOID + (1, 2, 9),
+                                 datetime),
+                      ax.Varbind(ax.VALUE_OCTET_STR,
+                                 ntpRootOID + (1, 3, 1, 1, 2),
+                                 name),
+                      ax.Varbind(ax.VALUE_OCTET_STR, ntpRootOID + (1, 5, 1),
+                                 "Association added")]  # Uh... what goes here?
+                control.sendNotify(vl)
+        if which in ("rm", "both"):
+            print("removing", rms)
+            for name in rms:
+                vl = [ax.Varbind(ax.VALUE_OID, snmpTrapOID,
+                                 ax.OID(ntpRootOID + (0, 5))),  # Remove
+                      ax.Varbind(ax.VALUE_OCTET_STR, ntpRootOID + (1, 2, 9),
+                                 datetime),
+                      ax.Varbind(ax.VALUE_OCTET_STR,
+                                 ntpRootOID + (1, 3, 1, 1, 2),
+                                 name),
+                      ax.Varbind(ax.VALUE_OCTET_STR, ntpRootOID + (1, 5, 1),
+                                 "Association removed")]  # Uh... what goes here?
+                control.sendNotify(vl)
 
     def doNotifyConfigChange(self, control):
         pass  # DUMMY
@@ -879,6 +901,70 @@ class DataSource:  # This will be broken up in future to be less NTP-specific
     # Misc data helpers (not part of the MIB proper)
     # =====================================
 
+    def misc_getAssocListChanges(self):
+        # We need to keep the names, because those won't be available
+        # after they have been removed.
+        oldAssoc = self.oldValues.get("assoc")
+        newAssoc = {}
+        # Yes, these are cached, for a very short time
+        pdata = self.misc_getPeerData()
+        if pdata is None:
+            return
+        ids = self.misc_getPeerIDs()
+        if ids is None:
+            return
+        for associd in ids:
+            addr = pdata[associd]["srcadr"][1]
+            name = ntp.util.canonicalize_dns(addr)
+            newAssoc[associd] = name
+        if oldAssoc is None:
+            self.oldValues["assoc"] = newAssoc
+            return
+        elif oldAssoc != newAssoc:
+            oldIDs = oldAssoc.keys()
+            newIDs = newAssoc.keys()
+            adds = []
+            rms = []
+            for associd in oldIDs + newIDs:
+                if associd not in newIDs:  # removed
+                    rms.append(oldAssoc[associd])
+                if associd not in oldIDs:  # added
+                    adds.append(newAssoc[associd])
+            return (adds, rms)
+        return
+
+    def misc_getMode(self):
+        # DUMMY: not fully implemented
+        try:
+            # Don't care about the data, this is a ploy to the the rstatus
+            self.session.readvar(0, ["stratum"])
+        except ntp.packet.ControlException as e:
+            if e.message == ntp.packet.SERR_SOCKET:
+                # Can't connect, ntpd probably not running
+                return ax.Varbind(ax.VALUE_INTEGER, oid, 1)
+            else:
+                raise e
+        rstatus = self.session.rstatus  # a ploy to get the system status
+        source = ntp.control.CTL_SYS_SOURCE(rstatus)
+        if source == ntp.control.CTL_SST_TS_UNSPEC:
+            mode = 2  # Not yet synced
+        elif False:
+            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):
+            # 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:
+            # Should this include "other"? That covers things like chrony...
+            mode = 6  # Sync to remote NTP
+        else:
+            mode = 99  # Unknown
+        return mode
+
     def misc_getSyspeerID(self):
         peers = self.misc_getPeerData()
         syspeer = 0


=====================================
packaging/packaging.txt
=====================================
--- a/packaging/packaging.txt
+++ b/packaging/packaging.txt
@@ -14,26 +14,6 @@ or ntp.d in place. Your installable package should do this.
 The reason this is so is that NTPsec does not yet have an authorized
 pool group of its own. This may change in the future.
 
-== FHS noncompliance under Linux ==
-
-The function get_python_lib() in the Python distutils library is the
-only reliable way to know where in fact the ntp Python library can
-installed; under Linux, it normally returns something under /usr/lib.
-This corresponds to a system installation.
-
-Thus, if you install from the source distribution with prefix set to a
-value other than /usr - in particular, if it's the default value
-/usr/local corresponding to a user installation - the ntp Python
-library may get dropped in /usr/lib anyway, violating the Linux File
-Hierarchy Standard.
-
-We say 'may' because if the Python library directory corresponding
-to the prefixed library path already exists it will be used.
-
-Your installable package should arrange library installation to comply
-with the FHS.  If you are using --prefix=/usr (or, more generally, the
-default sys.prefix) this should not require special action.
-
 == Platforms without Python ==
 
 Many tools (actually, almost everything except the core daemon itself)



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/29fa4f249f6e9d22dbad0dea6c730607aa5e1fa5...28dde8422e1a949e50663ae965d58c2fdbc782b9

---
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/29fa4f249f6e9d22dbad0dea6c730607aa5e1fa5...28dde8422e1a949e50663ae965d58c2fdbc782b9
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/20180105/df20ef99/attachment.html>


More information about the vc mailing list