Skip to content

Commit

Permalink
Utilize pynetsnmp's improved API.
Browse files Browse the repository at this point in the history
Replaced net-snmp specific code and implicit configuration with explicit,
declarative, configurations.

ZEN-35109
  • Loading branch information
jpeacock-zenoss committed Oct 28, 2024
1 parent c0d17dc commit 700387d
Show file tree
Hide file tree
Showing 13 changed files with 336 additions and 256 deletions.
4 changes: 2 additions & 2 deletions Products/DataCollector/SnmpClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ def __init__(
options=None,
device=None,
datacollector=None,
plugins=[],
plugins=None,
):
super(SnmpClient, self).__init__(device, datacollector)
global defaultTries, defaultTimeout
self.hostname = hostname
self.device = device
self.options = options
self.datacollector = datacollector
self.plugins = plugins
self.plugins = plugins if plugins else []

self._getdata = {}
self._tabledata = {}
Expand Down
75 changes: 39 additions & 36 deletions Products/DataCollector/zendisc.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

from optparse import SUPPRESS_HELP

import six

from twisted.internet import defer
from twisted.names.error import DNSNameError

Expand Down Expand Up @@ -82,7 +84,7 @@ class ZenDisc(ZenModeler):
"""

initialServices = PBDaemon.initialServices + ["DiscoverService"]
name = "zendisc"
mname = name = "zendisc"
scanned = 0

def __init__(self, single=True):
Expand Down Expand Up @@ -142,7 +144,8 @@ def discoverIps(self, nets):
full_ip_list = net.fullIpList()
if self.options.removeInterfaceIps:
full_ip_list = yield self.config().callRemote(
"removeInterfaces", net)
"removeInterfaces", net
)

results = yield self.pingMany(full_ip_list)
goodips, badips = _partitionPingResults(results)
Expand All @@ -168,7 +171,7 @@ def discoverRanges(self):
back.
"""
iprange = self.options.range
if isinstance(iprange, basestring):
if isinstance(iprange, six.string_types):
iprange = [iprange]
# in case someone uses 10.0.0.0-5,192.168.0.1-5 instead of
# --range 10.0.0.0-5 --range 192.168.0.1-5
Expand All @@ -183,8 +186,8 @@ def discoverRanges(self):
self.log.debug(
"Found %d good IPs and %d bad IPs", len(goodips), len(badips)
)
devices = yield self.discoverDevices(goodips)
self.log.info("Discovered %d active IPs", len(goodips))
devices = yield self.discoverDevices(goodips)
defer.returnValue(devices)

@defer.inlineCallbacks
Expand Down Expand Up @@ -227,16 +230,16 @@ def sendDiscoveredEvent(self, ip, dev=None, sev=2):
if dev:
devname = dev.id
msg = "Discovered device name '%s' for ip '%s'" % (devname, ip)
evt = dict(
device=devname,
ipAddress=ip,
eventKey=ip,
component=comp,
eventClass=Status_Snmp,
summary=msg,
severity=sev,
agent="Discover",
)
evt = {
"device": devname,
"ipAddress": ip,
"eventKey": ip,
"component": comp,
"eventClass": Status_Snmp,
"summary": msg,
"severity": sev,
"agent": "Discover",
}
self.sendEvent(evt)

@defer.inlineCallbacks
Expand Down Expand Up @@ -414,16 +417,16 @@ def discoverDevice(
defer.returnValue(None)

try:
kw = dict(
deviceName=ip,
discoverProto=None,
devicePath=devicepath,
performanceMonitor=self.options.monitor,
locationPath=self.options.location,
groupPaths=self.options.groups,
systemPaths=self.options.systems,
productionState=prodState,
)
kw = {
"deviceName": ip,
"discoverProto": None,
"devicePath": devicepath,
"performanceMonitor": self.options.monitor,
"locationPath": self.options.location,
"groupPaths": self.options.groups,
"systemPaths": self.options.systems,
"productionState": prodState,
}

# If zProperties are set via a job, get them and pass them in
if self.options.job:
Expand Down Expand Up @@ -548,18 +551,18 @@ def discoverDevice(
self.log.exception(e)
if self.options.snmpMissing:
self.sendEvent(
dict(
device=ip,
component=ip,
ipAddress=ip,
eventKey=ip,
eventClass=Status_Snmp,
summary=str(e),
severity=Info,
agent="Discover",
)
{
"device": ip,
"component": ip,
"ipAddress": ip,
"eventKey": ip,
"eventClass": Status_Snmp,
"summary": str(e),
"severity": Info,
"agent": "Discover",
}
)
except Exception as e:
except Exception:
self.log.exception("Failed device discovery for '%s'", ip)
finally:
self.log.info("Finished scanning device with address %s", ip)
Expand All @@ -576,7 +579,7 @@ def collectNet(self):
"""
network = self.options.net
# net option from the config file is a string
if isinstance(network, basestring):
if isinstance(network, six.string_types):
network = [network]
# in case someone uses 10.0.0.0,192.168.0.1 instead of
# --net 10.0.0.0 --net 192.168.0.1
Expand Down
43 changes: 27 additions & 16 deletions Products/DataCollector/zenmodeler.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def __init__(self, single=False):
self.log.debug('option "now" specified, starting immediately.')
else:
# self.startDelay = randint(10, 60) * 60
self.startDelay = randint(10, 60) * 1
self.startDelay = randint(10, 60) * 1 # noqa: S311
self.immediate = 0
self.log.info(
'option "now" not specified, waiting %s seconds to start.',
Expand Down Expand Up @@ -335,7 +335,7 @@ def collectDevice(self, device):
if USE_WMI:
self.wmiCollect(device, ip, timeout)
else:
self.log.info(
self.log.debug(
"skipping WMI-based collection, PySamba zenpack not installed"
)
self.log.info(
Expand All @@ -361,17 +361,17 @@ def wmiCollect(self, device, ip, timeout):
"""
if self.options.nowmi:
return

client = None
try:
plugins = self.selectPlugins(device, "wmi")
if not plugins:
self.log.info("No WMI plugins found for %s", device.id)
return
if self.checkCollection(device):
self.log.info("WMI collector method for device %s", device.id)
self.log.info(
"plugins: %s", ", ".join(map(lambda p: p.name(), plugins))
"WMI collector method for device %s", device.id)
self.log.info(
"plugins: %s", ", ".join(p.name() for p in plugins)
)
client = WMIClient(device, self, plugins)
if not client or not plugins:
Expand Down Expand Up @@ -401,9 +401,11 @@ def pythonCollect(self, device, ip, timeout):
if self.checkCollection(device):
self.log.info("Python collection device %s", device.id)
self.log.info(
"plugins: %s", ", ".join(map(lambda p: p.name(), plugins))
"plugins: %s", ", ".join(p.name() for p in plugins)
)
client = PythonClient(device, self, plugins)
else:
self.log.info("no Python collection for device %s", device.id)
if not client or not plugins:
self.log.warn("Python client creation failed")
return
Expand Down Expand Up @@ -439,6 +441,7 @@ def cmdCollect(self, device, ip, timeout):

# don't even create a client if we shouldn't collect/model yet
if not self.checkCollection(device):
self.log.info("no cmd collection for device %s", device.id)
return

if protocol == "ssh":
Expand All @@ -454,7 +457,7 @@ def cmdCollect(self, device, ip, timeout):
)
clientType = "ssh"
self.log.info(
"Using SSH collection method for device %s", hostname
"using SSH collection method for device %s", hostname
)

elif protocol == "telnet":
Expand All @@ -471,7 +474,7 @@ def cmdCollect(self, device, ip, timeout):
)
clientType = "telnet"
self.log.info(
"Using telnet collection method for device %s", hostname
"using telnet collection method for device %s", hostname
)

else:
Expand All @@ -496,10 +499,10 @@ def cmdCollect(self, device, ip, timeout):
return

if not client:
self.log.warn("Shell command collector creation failed")
self.log.warn("shell command collector creation failed")
else:
self.log.info(
"plugins: %s", ", ".join(map(lambda p: p.name(), plugins))
"plugins: %s", ", ".join(p.name() for p in plugins)
)
except Exception:
self.log.exception("Error opening command collector")
Expand All @@ -524,23 +527,28 @@ def snmpCollect(self, device, ip, timeout):
return

if not ip:
self.log.info("No manage IP for %s", hostname)
self.log.info("no manage IP for %s", hostname)
return

plugins = []
plugins = self.selectPlugins(device, "snmp")
if not plugins:
self.log.info("No SNMP plugins found for %s", hostname)
self.log.info("no SNMP plugins found for %s", hostname)
return

if self.checkCollection(device):
self.log.info("SNMP collection device %s", hostname)
self.log.info(
"plugins: %s", ", ".join(map(lambda p: p.name(), plugins))
"plugins: %s", ", ".join(p.name() for p in plugins)
)
client = SnmpClient(
device.id, ip, self.options, device, self, plugins
)
self.log.info(
"SNMP config summary: %s", client.connInfo.summary()
)
else:
self.log.info("no SNMP collection for device %s", hostname)
if not client or not plugins:
self.log.warn("SNMP collector creation failed")
return
Expand Down Expand Up @@ -629,11 +637,13 @@ def portscanCollect(self, device, ip, timeout):
"Portscan collector method for device %s", hostname
)
self.log.info(
"plugins: %s", ", ".join(map(lambda p: p.name(), plugins))
"plugins: %s", ", ".join(p.name() for p in plugins)
)
client = PortscanClient(
device.id, ip, self.options, device, self, plugins
)
else:
self.log.info("no portscan collection for device %s", hostname)
if not client or not plugins:
self.log.warn("Portscan collector creation failed")
return
Expand Down Expand Up @@ -984,8 +994,9 @@ def checkStop(self, unused=None):
if not self.options.cycle:
self.stop()
self.finished = []
# frequency of heartbeat rate could be 2 times per minute in case we have
# cron job modeling faster than 1 minute it'll be trigger a second time
# frequency of heartbeat rate could be 2 times per minute in
# case we have cron job modeling faster than 1 minute it'll be
# trigger a second time.
if runTime < 60 and self.startat is not None:
yield wait(60)
self.started = False
Expand Down
2 changes: 1 addition & 1 deletion Products/ZenCollector/services/ConfigCache.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ def _keys(self, servicename):
@rtype: Iterator[str]
"""
query = DeviceQuery(monitor=self.instance, service=servicename)
self.log.info("[ConfigCache] using query %s", query)
self.log.debug("[ConfigCache] using query %s", query)
return self._stores.device.search(query)

def _filter(self, keys, predicate):
Expand Down
4 changes: 3 additions & 1 deletion Products/ZenHub/HubService.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ def __init__(self, dmd, instance):
:param instance: The name of the collection monitor.
:type instance: str
"""
self.log = logging.getLogger("zen.hub")
self.log = logging.getLogger(
"zen.hub.{}".format(type(self).__name__.lower())
)
self.fqdn = socket.getfqdn()
self.dmd = dmd
self.zem = dmd.ZenEventManager
Expand Down
Loading

0 comments on commit 700387d

Please sign in to comment.