示例#1
0
    def get(self,
            oid: OID,
            context_name: Optional[SNMPContextName] = None) -> Optional[SNMPRawValue]:
        if oid.endswith(".*"):
            oid_prefix = oid[:-2]
            commandtype = "getnext"
        else:
            oid_prefix = oid
            commandtype = "get"

        protospec = self._snmp_proto_spec()
        ipaddress = self.config.ipaddress
        if self.config.is_ipv6_primary:
            ipaddress = "[" + ipaddress + "]"
        portspec = self._snmp_port_spec()
        command = (
            self._snmp_base_command(commandtype, context_name) +
            ["-On", "-OQ", "-Oe", "-Ot",
             "%s%s%s" % (protospec, ipaddress, portspec), oid_prefix])

        console.vverbose("Running '%s'\n" % subprocess.list2cmdline(command))

        snmp_process = subprocess.Popen(
            command,
            close_fds=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            encoding="utf-8",
        )
        exitstatus = snmp_process.wait()
        if snmp_process.stderr is None or snmp_process.stdout is None:
            raise TypeError()
        if exitstatus:
            console.verbose(tty.red + tty.bold + "ERROR: " + tty.normal + "SNMP error\n")
            console.verbose(snmp_process.stderr.read() + "\n")
            return None

        line = snmp_process.stdout.readline().strip()
        if not line:
            console.verbose("Error in response to snmpget.\n")
            return None

        parts = line.split("=", 1)
        if len(parts) != 2:
            return None
        item = parts[0]
        value = parts[1].strip()
        console.vverbose("SNMP answer: ==> [%s]\n" % value)
        if value.startswith('No more variables') or \
           value.startswith('End of MIB') or \
           value.startswith('No Such Object available') or \
           value.startswith('No Such Instance currently exists'):
            return None

        # In case of .*, check if prefix is the one we are looking for
        if commandtype == "getnext" and not item.startswith(oid_prefix + "."):
            return None

        return strip_snmp_value(value)
示例#2
0
    def walk(
        self,
        oid: OID,
        section_name: Optional[SectionName] = None,
        table_base_oid: Optional[OID] = None,
        context_name: Optional[SNMPContextName] = None,
    ) -> SNMPRowInfo:
        if oid.startswith("."):
            oid = oid[1:]

        if oid.endswith(".*"):
            oid_prefix = oid[:-2]
            dot_star = True
        else:
            oid_prefix = oid
            dot_star = False

        host_cache = snmp_cache.host_cache()
        try:
            lines = host_cache[self.config.hostname]
        except KeyError:
            path = cmk.utils.paths.snmpwalks_dir + "/" + self.config.hostname
            console.vverbose("  Loading %s from %s\n" % (oid, path))
            try:
                lines = StoredWalkSNMPBackend.read_walk_data(path)
            except IOError:
                raise MKSNMPError("No snmpwalk file %s" % path)
            host_cache[self.config.hostname] = lines

        begin = 0
        end = len(lines)
        hit = None
        while end - begin > 0:
            current = (begin + end) // 2
            parts = lines[current].split(None, 1)
            comp = parts[0]
            hit = StoredWalkSNMPBackend._compare_oids(oid_prefix, comp)
            if hit == 0:
                break
            if hit == 1:  # we are too low
                begin = current + 1
            else:
                end = current

        if hit != 0:
            return []  # not found

        rowinfo = StoredWalkSNMPBackend._collect_until(oid, oid_prefix, lines,
                                                       current, -1)
        rowinfo.reverse()
        rowinfo += StoredWalkSNMPBackend._collect_until(
            oid, oid_prefix, lines, current + 1, 1)

        if dot_star:
            return [rowinfo[0]]

        return rowinfo
示例#3
0
    def walk(self,
             oid: OID,
             check_plugin_name: Optional[CheckPluginNameStr] = None,
             table_base_oid: Optional[OID] = None,
             context_name: Optional[SNMPContextName] = None) -> SNMPRowInfo:
        if oid.startswith("."):
            oid = oid[1:]

        if oid.endswith(".*"):
            oid_prefix = oid[:-2]
            dot_star = True
        else:
            oid_prefix = oid
            dot_star = False

        if snmp_cache.host_cache_contains(self.config.hostname):
            lines = snmp_cache.host_cache_get(self.config.hostname)
        else:
            path = cmk.utils.paths.snmpwalks_dir + "/" + self.config.hostname
            console.vverbose("  Loading %s from %s\n" % (oid, path))
            try:
                lines = open(path).readlines()
            except IOError:
                raise MKSNMPError("No snmpwalk file %s" % path)
            snmp_cache.host_cache_set(self.config.hostname, lines)

        begin = 0
        end = len(lines)
        hit = None
        while end - begin > 0:
            current = (begin + end) // 2
            # skip over values including newlines to the next oid
            while not lines[current].startswith(".") and current < end:
                current += 1
            parts = lines[current].split(None, 1)
            comp = parts[0]
            hit = StoredWalkSNMPBackend._compare_oids(oid_prefix, comp)
            if hit == 0:
                break
            if hit == 1:  # we are too low
                begin = current + 1
            else:
                end = current

        if hit != 0:
            return []  # not found

        rowinfo = StoredWalkSNMPBackend._collect_until(oid, oid_prefix, lines,
                                                       current, -1)
        rowinfo.reverse()
        rowinfo += StoredWalkSNMPBackend._collect_until(
            oid, oid_prefix, lines, current + 1, 1)

        if dot_star:
            return [rowinfo[0]]

        return rowinfo
示例#4
0
 def get(self,
         oid: OID,
         context_name: Optional[SNMPContextName] = None) -> Optional[SNMPRawValue]:
     walk = self.walk(oid)
     # get_stored_snmpwalk returns all oids that start with oid but here
     # we need an exact match
     if len(walk) == 1 and oid == walk[0][0]:
         return walk[0][1]
     if oid.endswith(".*") and len(walk) > 0:
         return walk[0][1]
     return None