diff --git a/tests/topotests/lib/snmptest.py b/tests/topotests/lib/snmptest.py index e7cd657b2027..293f755faa54 100644 --- a/tests/topotests/lib/snmptest.py +++ b/tests/topotests/lib/snmptest.py @@ -18,6 +18,7 @@ """ from lib.topolog import logger +import re class SnmpTester(object): @@ -72,15 +73,38 @@ def _get_snmp_oid(snmp_output): # third token onwards is the value of the object return tokens[0].split(".", 1)[1] - @staticmethod - def _get_snmp_oid(snmp_output): - tokens = snmp_output.strip().split() - - # if len(tokens) > 5: - # return None - - # third token is the value of the object - return tokens[0].split(".", 1)[1] + def _parse_notification_trap(self, snmp_out): + # we use the "=" as separator thus we will have + # element of list formated "value oid" + # value for index i is corresponding to index i-1 + results = snmp_out.strip().split("=") + + # remove the notification part date, notification OID + del results[0:2] + + index = 0 + oid_list = [] + next_oid='' + while index < len(results): + result = results[index].strip().split() + if index < len(results) -1: + raw_oid = result[-1] + # remove initial "." of oid + next_oid = raw_oid.split(".", 1)[1] + # remove oid from result to have only value + del result[-1] + if index > 0: + value = ' '.join(result) + logger.info("OID=>{} VALUE =>{}".format(oid,value)) + # ignore remote port oid 1.3.6.1.3.5.1.1.2.1.9 since + # it's value is variable + local_port = re.search("1.3.6.1.3.5.1.1.2.1.9", oid) + if not local_port: + oid_list.append((oid, value)) + + oid = next_oid + index += 1 + return oid_list def _parse_multiline(self, snmp_output): results = snmp_output.strip().split("\n") @@ -93,6 +117,15 @@ def _parse_multiline(self, snmp_output): return out_dict, out_list + def _parse_multiline_trap(self, results): + out_list = [] + results = [elem for index, elem in enumerate(results) if index % 2 != 0] + + for response in results: + oid_list = self._parse_notification_trap(response) + out_list += oid_list + return out_list + def get(self, oid): cmd = "snmpget {0} {1}".format(self._snmp_config(), oid) @@ -116,6 +149,11 @@ def walk(self, oid): result = self.router.cmd(cmd) return self._parse_multiline(result) + def trap(self, outputfile): + whitecleanfile = re.sub('\t',' ',outputfile) + results = whitecleanfile.strip().split("\n") + return self._parse_multiline_trap(results) + def test_oid(self, oid, value): print("oid: {}".format(self.get_next(oid))) return self.get_next(oid) == value diff --git a/tests/topotests/lib/topogen.py b/tests/topotests/lib/topogen.py index 4d935b9538c5..99c5be7dd3f0 100644 --- a/tests/topotests/lib/topogen.py +++ b/tests/topotests/lib/topogen.py @@ -744,6 +744,7 @@ class TopoRouter(TopoGear): RD_SNMP = 18 RD_PIM6 = 19 RD_MGMTD = 20 + RD_TRAP = 21 RD = { RD_FRR: "frr", RD_ZEBRA: "zebra", @@ -766,6 +767,7 @@ class TopoRouter(TopoGear): RD_PATH: "pathd", RD_SNMP: "snmpd", RD_MGMTD: "mgmtd", + RD_TRAP: "snmptrapd", } def __init__(self, tgen, cls, name, **params): @@ -842,7 +844,7 @@ def load_config(self, daemon, source=None, param=None): TopoRouter.RD_RIPNG, TopoRouter.RD_OSPF, TopoRouter.RD_OSPF6, TopoRouter.RD_ISIS, TopoRouter.RD_BGP, TopoRouter.RD_LDP, TopoRouter.RD_PIM, TopoRouter.RD_PIM6, TopoRouter.RD_PBR, - TopoRouter.RD_SNMP, TopoRouter.RD_MGMTD. + TopoRouter.RD_SNMP, TopoRouter.RD_MGMTD, TopoRouter.RD_TRAP. Possible `source` values are `None` for an empty config file, a path name which is used directly, or a file name with no path components which is first looked for diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index c220bcfed1b8..88a9f62e102d 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -1420,6 +1420,7 @@ def __init__(self, name, *posargs, **params): "pathd": 0, "snmpd": 0, "mgmtd": 0, + "snmptrapd": 0, } self.daemons_options = {"zebra": ""} self.reportCores = True @@ -1883,6 +1884,15 @@ def start_daemon(daemon, extra_opts=None): daemon_opts ) + "{}.pid -x /etc/frr/agentx".format(runbase) # check_daemon_files.append(runbase + ".pid") + elif daemon == "snmptrapd": + binary = "/usr/sbin/snmptrapd" + cmdenv = "" + cmdopt = ( + "{} ".format(daemon_opts) + + "-C -c /etc/{}/snmptrapd.conf".format(self.routertype) + + " -p {}.pid".format(runbase) + + " -LF 6-7 {}/{}/snmptrapd.log".format(self.logdir, self.name) + ) else: binary = os.path.join(self.daemondir, daemon) check_daemon_files.extend([runbase + ".pid", runbase + ".vty"]) @@ -1922,6 +1932,7 @@ def start_daemon(daemon, extra_opts=None): tail_log_files.append( "{}/{}/{}.log".format(self.logdir, self.name, daemon) ) + if extra_opts: cmdopt += " " + extra_opts @@ -1970,7 +1981,7 @@ def start_daemon(daemon, extra_opts=None): "%s: %s %s started with perf", self, self.routertype, daemon ) else: - if daemon != "snmpd": + if daemon != "snmpd" and daemon != "snmptrapd": cmdopt += " -d " cmdopt += rediropt @@ -2213,6 +2224,8 @@ def checkRouterRunning(self): for daemon in self.daemons: if daemon == "snmpd": continue + if daemon == "snmptrapd": + continue if (self.daemons[daemon] == 1) and not (daemon in daemonsRunning): sys.stderr.write("%s: Daemon %s not running\n" % (self.name, daemon)) if daemon == "staticd":