Exemple #1
0
def _logError(path, line, severity, msg, tag):
    global _lastError
    if path != ffi.NULL and msg != ffi.NULL:
        _lastError = "{0}:{1}: {2}".format(ffi.string(path), line,
                                           ffi.string(msg))
    else:
        _lastError = None
Exemple #2
0
    def typeName(self, type_name):
        """Override the node's type to type_name, found using _getType.
        The new type must resolve to the same basictype.

        :param type_name: string name of the type.
        """
        current_override = self._override_type

        declared_type = _smi.smiGetNodeType(self.node)
        declared_basetype = self.type

        new_type = _getType(type_name)
        if not new_type:
            raise SMIException(
                "no type named {0} in any loaded module".format(type_name))

        # Easiest way to find the new basetype is to set the override
        # and ask.
        self._override_type = new_type
        new_basetype = self.type

        if declared_basetype != new_basetype:
            self._override_type = current_override
            raise SMIException("override type {1} not compatible with "
                               "basetype of {0}".format(
                                   ffi.string(declared_type.name),
                                   ffi.string(new_type.name)))
Exemple #3
0
    def objects(self):
        """Get objects for a notification.

        :return: The list of objects (as :class:`Column`,
            :class:`Node` or :class:`Scalar` instances) of the notification.
        """
        child = self.node
        lindex = []
        element = _smi.smiGetFirstElement(child)
        while element != ffi.NULL:
            nelement = _smi.smiGetElementNode(element)
            if nelement == ffi.NULL:
                raise SMIException("cannot get object "
                                   "associated with {0}".format(
                                       ffi.string(self.node.name)))
            if nelement.nodekind == _smi.SMI_NODEKIND_COLUMN:
                lindex.append(Column(nelement))
            elif nelement.nodekind == _smi.SMI_NODEKIND_NODE:
                lindex.append(Node(nelement))
            elif nelement.nodekind == _smi.SMI_NODEKIND_SCALAR:
                lindex.append(Scalar(nelement))
            else:
                raise SMIException("object {0} for {1} is "
                                   "not a node".format(
                                       ffi.string(nelement.name),
                                       ffi.string(self.node.name)))
            element = _smi.smiGetNextElement(element)
        return lindex
Exemple #4
0
    def objects(self):
        """Get objects for a notification.

        :return: The list of objects (as :class:`Column`,
            :class:`Node` or :class:`Scalar` instances) of the notification.
        """
        child = self.node
        lindex = []
        element = _smi.smiGetFirstElement(child)
        while element != ffi.NULL:
            nelement = _smi.smiGetElementNode(element)
            if nelement == ffi.NULL:
                raise SMIException("cannot get object "
                                   "associated with {0}".format(
                                       ffi.string(self.node.name)))
            if nelement.nodekind == _smi.SMI_NODEKIND_COLUMN:
                lindex.append(Column(nelement))
            elif nelement.nodekind == _smi.SMI_NODEKIND_NODE:
                lindex.append(Node(nelement))
            elif nelement.nodekind == _smi.SMI_NODEKIND_SCALAR:
                lindex.append(Scalar(nelement))
            else:
                raise SMIException("object {0} for {1} is "
                                   "not a node".format(
                                       ffi.string(nelement.name),
                                       ffi.string(self.node.name)))
            element = _smi.smiGetNextElement(element)
        return lindex
Exemple #5
0
def _logError(path, line, severity, msg, tag):
    global _lastError
    if path != ffi.NULL and msg != ffi.NULL:
        _lastError = "{0}:{1}: {2}".format(ffi.string(path), line,
                                           ffi.string(msg))
    else:
        _lastError = None
Exemple #6
0
    def typeName(self, type_name):
        """Override the node's type to type_name, found using _getType.
        The new type must resolve to the same basictype.

        :param type_name: string name of the type.
        """
        current_override = self._override_type

        declared_type = _smi.smiGetNodeType(self.node)
        declared_basetype = self.type

        new_type = _getType(type_name)
        if not new_type:
            raise SMIException("no type named {0} in any loaded module".format(
                type_name))

        # Easiest way to find the new basetype is to set the override
        # and ask.
        self._override_type = new_type
        new_basetype = self.type

        if declared_basetype != new_basetype:
            self._override_type = current_override
            raise SMIException("override type {1} not compatible with "
                               "basetype of {0}".format(
                                   ffi.string(declared_type.name),
                                   ffi.string(new_type.name)))
Exemple #7
0
    def fmt(self):
        """Get node format. The node format is a string to use to display
        a user-friendly version of the node. This is can be used for
        both octet strings or integers (to make them appear as decimal
        numbers).

        :return: The node format as a string or None if there is no
            format available.

        """
        if self._override_type:
            t = self._override_type
        else:
            t = _smi.smiGetNodeType(self.node)
        tt = _smi.smiGetParentType(t)
        f = (
            t != ffi.NULL
            and t.format != ffi.NULL
            and ffi.string(t.format)
            or tt != ffi.NULL
            and tt.format != ffi.NULL
            and ffi.string(tt.format)
        ) or None
        if f is None:
            return None
        return f.decode("ascii")
Exemple #8
0
 def __repr__(self):
     r = _smi.smiRenderNode(self.node, _smi.SMI_RENDER_ALL)
     if r == ffi.NULL:
         return "<uninitialized {0} object at {1}>".format(self.__class__.__name__, hex(id(self)))
     r = ffi.gc(r, _smi.free)
     module = _smi.smiGetNodeModule(self.node)
     if module == ffi.NULL:
         raise SMIException("unable to get module for {0}".format(self.node.name))
     return "<{0} {1} from '{2}'>".format(self.__class__.__name__, ffi.string(r), ffi.string(module.name))
Exemple #9
0
 def __repr__(self):
     r = _smi.smiRenderNode(self.node, _smi.SMI_RENDER_ALL)
     if r == ffi.NULL:
         return "<uninitialized {0} object at {1}>".format(
             self.__class__.__name__, hex(id(self)))
     r = ffi.gc(r, _smi.free)
     module = _smi.smiGetNodeModule(self.node)
     if module == ffi.NULL:
         raise SMIException("unable to get module for {0}".format(
             self.node.name))
     return "<{0} {1} from '{2}'>".format(self.__class__.__name__,
                                          ffi.string(r),
                                          ffi.string(module.name))
Exemple #10
0
    def type(self):
        """Get the basic type associated with this node.

        :return: The class from :mod:`basictypes` module which can
            represent the node. When retrieving a valid value for
            this node, the returned class can be instanciated to get
            an appropriate representation.
        """
        from snimpy import basictypes

        if self._override_type:
            t = self._override_type
        else:
            t = _smi.smiGetNodeType(self.node)
        target = {
            _smi.SMI_BASETYPE_INTEGER32: basictypes.Integer,
            _smi.SMI_BASETYPE_INTEGER64: basictypes.Integer,
            _smi.SMI_BASETYPE_UNSIGNED32: {b"TimeTicks": basictypes.Timeticks, None: basictypes.Unsigned32},
            _smi.SMI_BASETYPE_UNSIGNED64: basictypes.Unsigned64,
            _smi.SMI_BASETYPE_OCTETSTRING: {b"IpAddress": basictypes.IpAddress, None: basictypes.OctetString},
            _smi.SMI_BASETYPE_OBJECTIDENTIFIER: basictypes.Oid,
            _smi.SMI_BASETYPE_ENUM: {b"TruthValue": basictypes.Boolean, None: basictypes.Enum},
            _smi.SMI_BASETYPE_BITS: basictypes.Bits,
        }.get(t.basetype, None)
        if isinstance(target, dict):
            tt = _smi.smiGetParentType(t)
            target = target.get(
                (t.name != ffi.NULL and ffi.string(t.name)) or (tt.name != ffi.NULL and ffi.string(tt.name)) or None,
                target.get(None, None),
            )

        if target is None:
            raise SMIException("unable to retrieve type of node")
        return target
Exemple #11
0
def loadedMibNames():
    """Generates the list of loaded MIB names.

    :yield: The names of all currently loaded MIBs.
    """
    for module in _loadedModules():
        yield ffi.string(module.name).decode('utf-8')
Exemple #12
0
def loadedMibNames():
    """Generates the list of loaded MIB names.

    :yield: The names of all currently loaded MIBs.
    """
    for module in _loadedModules():
        yield ffi.string(module.name).decode('utf-8')
Exemple #13
0
    def type(self):
        """Get the basic type associated with this node.

        :return: The class from :mod:`basictypes` module which can
            represent the node. When retrieving a valid value for
            this node, the returned class can be instanciated to get
            an appropriate representation.
        """
        from snimpy import basictypes
        if self._override_type:
            t = self._override_type
        else:
            t = _smi.smiGetNodeType(self.node)
        if t == ffi.NULL:
            raise SMIException("unable to retrieve type of node")
        target = {
            _smi.SMI_BASETYPE_INTEGER32: basictypes.Integer,
            _smi.SMI_BASETYPE_INTEGER64: basictypes.Integer,
            _smi.SMI_BASETYPE_UNSIGNED32: {
                b"TimeTicks": basictypes.Timeticks,
                None: basictypes.Unsigned32
            },
            _smi.SMI_BASETYPE_UNSIGNED64: basictypes.Unsigned64,
            _smi.SMI_BASETYPE_OCTETSTRING: {
                b"IpAddress": basictypes.IpAddress,
                None: basictypes.OctetString
            },
            _smi.SMI_BASETYPE_OBJECTIDENTIFIER: basictypes.Oid,
            _smi.SMI_BASETYPE_ENUM: {
                b"TruthValue": basictypes.Boolean,
                None: basictypes.Enum
            },
            _smi.SMI_BASETYPE_BITS: basictypes.Bits
        }.get(t.basetype, None)
        if isinstance(target, dict):
            tt = _smi.smiGetParentType(t)
            target = target.get(
                (t.name != ffi.NULL and ffi.string(t.name))
                or (tt.name != ffi.NULL and ffi.string(tt.name)) or None,
                target.get(None, None))

        if target is None:
            raise SMIException("unable to retrieve type of node")
        return target
Exemple #14
0
    def fmt(self):
        """Get node format. The node format is a string to use to display
        a user-friendly version of the node. This is can be used for
        both octet strings or integers (to make them appear as decimal
        numbers).

        :return: The node format as a string or None if there is no
            format available.

        """
        if self._override_type:
            t = self._override_type
        else:
            t = _smi.smiGetNodeType(self.node)
        tt = _smi.smiGetParentType(t)
        f = (t != ffi.NULL and t.format != ffi.NULL and ffi.string(t.format)
             or tt != ffi.NULL and tt.format != ffi.NULL
             and ffi.string(tt.format)) or None
        if f is None:
            return None
        return f.decode("ascii")
Exemple #15
0
    def index(self):
        """Get indexes for a table. The indexes are used to locate a precise
        row in a table. They are a subset of the table columns.

        :return: The list of indexes (as :class:`Column` instances) of
            the table.
        """
        child = self._row
        lindex = []
        element = _smi.smiGetFirstElement(child)
        while element != ffi.NULL:
            nelement = _smi.smiGetElementNode(element)
            if nelement == ffi.NULL:
                raise SMIException("cannot get index " "associated with {0}".format(ffi.string(self.node.name)))
            if nelement.nodekind != _smi.SMI_NODEKIND_COLUMN:
                raise SMIException(
                    "index {0} for {1} is " "not a column".format(ffi.string(nelement.name), ffi.string(self.node.name))
                )
            lindex.append(Column(nelement))
            element = _smi.smiGetNextElement(element)
        return lindex
Exemple #16
0
    def _row(self):
        """Get the table row.

        :return: row object (as an opaque object)
        """
        child = _smi.smiGetFirstChildNode(self.node)
        if child != ffi.NULL and child.indexkind == _smi.SMI_INDEX_AUGMENT:
            child = _smi.smiGetRelatedNode(child)
            if child == ffi.NULL:
                raise SMIException("AUGMENT index for {0} but "
                                   "unable to retrieve it".format(
                                       ffi.string(self.node.name)))
        if child == ffi.NULL:
            raise SMIException("{0} does not have a row".format(
                ffi.string(self.node.name)))
        if child.nodekind != _smi.SMI_NODEKIND_ROW:
            raise SMIException("child {0} of {1} is not a row".format(
                ffi.string(child.name),
                ffi.string(self.node.name)))
        if child.indexkind != _smi.SMI_INDEX_INDEX:
            raise SMIException("child {0} of {1} has an unhandled "
                               "kind of index".format(
                                   ffi.string(child.name),
                                   ffi.string(self.node.name)))
        return child
Exemple #17
0
    def _row(self):
        """Get the table row.

        :return: row object (as an opaque object)
        """
        child = _smi.smiGetFirstChildNode(self.node)
        if child != ffi.NULL and child.indexkind == _smi.SMI_INDEX_AUGMENT:
            child = _smi.smiGetRelatedNode(child)
            if child == ffi.NULL:
                raise SMIException("AUGMENT index for {0} but "
                                   "unable to retrieve it".format(
                                       ffi.string(self.node.name)))
        if child == ffi.NULL:
            raise SMIException("{0} does not have a row".format(
                ffi.string(self.node.name)))
        if child.nodekind != _smi.SMI_NODEKIND_ROW:
            raise SMIException("child {0} of {1} is not a row".format(
                ffi.string(child.name),
                ffi.string(self.node.name)))
        if child.indexkind != _smi.SMI_INDEX_INDEX:
            raise SMIException("child {0} of {1} has an unhandled "
                               "kind of index".format(
                                   ffi.string(child.name),
                                   ffi.string(self.node.name)))
        return child
Exemple #18
0
    def columns(self):
        """Get table columns. The columns are the different kind of objects
        that can be retrieved in a table.

        :return: list of table columns (:class:`Column` instances)

        """
        child = _smi.smiGetFirstChildNode(self.node)
        if child == ffi.NULL:
            return []
        if child.nodekind != _smi.SMI_NODEKIND_ROW:
            raise SMIException("child {0} of {1} is not a row".format(
                ffi.string(child.name), ffi.string(self.node.name)))
        columns = []
        child = _smi.smiGetFirstChildNode(child)
        while child != ffi.NULL:
            if child.nodekind != _smi.SMI_NODEKIND_COLUMN:
                raise SMIException("child {0} of {1} is not a column".format(
                    ffi.string(child.name), ffi.string(self.node.name)))
            columns.append(Column(child))
            child = _smi.smiGetNextChildNode(child)
        return columns
Exemple #19
0
    def columns(self):
        """Get table columns. The columns are the different kind of objects
        that can be retrieved in a table.

        :return: list of table columns (:class:`Column` instances)

        """
        child = _smi.smiGetFirstChildNode(self.node)
        if child == ffi.NULL:
            return []
        if child.nodekind != _smi.SMI_NODEKIND_ROW:
            raise SMIException("child {0} of {1} is not a row".format(
                ffi.string(child.name),
                ffi.string(self.node.name)))
        columns = []
        child = _smi.smiGetFirstChildNode(child)
        while child != ffi.NULL:
            if child.nodekind != _smi.SMI_NODEKIND_COLUMN:
                raise SMIException("child {0} of {1} is not a column".format(
                    ffi.string(child.name),
                    ffi.string(self.node.name)))
            columns.append(Column(child))
            child = _smi.smiGetNextChildNode(child)
        return columns
Exemple #20
0
    def index(self):
        """Get indexes for a table. The indexes are used to locate a precise
        row in a table. They are a subset of the table columns.

        :return: The list of indexes (as :class:`Column` instances) of
            the table.
        """
        child = self._row
        lindex = []
        element = _smi.smiGetFirstElement(child)
        while element != ffi.NULL:
            nelement = _smi.smiGetElementNode(element)
            if nelement == ffi.NULL:
                raise SMIException("cannot get index "
                                   "associated with {0}".format(
                                       ffi.string(self.node.name)))
            if nelement.nodekind != _smi.SMI_NODEKIND_COLUMN:
                raise SMIException("index {0} for {1} is "
                                   "not a column".format(
                                       ffi.string(nelement.name),
                                       ffi.string(self.node.name)))
            lindex.append(Column(nelement))
            element = _smi.smiGetNextElement(element)
        return lindex
Exemple #21
0
    def enum(self):
        """Get possible enum values. When the node can only take a discrete
        number of values, those values are defined in the MIB and can
        be retrieved through this property.

        :return: The dictionary of possible values keyed by the integer value.
        """
        t = _smi.smiGetNodeType(self.node)
        if t == ffi.NULL or t.basetype not in (_smi.SMI_BASETYPE_ENUM, _smi.SMI_BASETYPE_BITS):
            return None

        result = {}
        element = _smi.smiGetFirstNamedNumber(t)
        while element != ffi.NULL:
            result[self._convert(element.value)] = ffi.string(element.name).decode("ascii")
            element = _smi.smiGetNextNamedNumber(element)
        return result
Exemple #22
0
    def enum(self):
        """Get possible enum values. When the node can only take a discrete
        number of values, those values are defined in the MIB and can
        be retrieved through this property.

        :return: The dictionary of possible values keyed by the integer value.
        """
        t = _smi.smiGetNodeType(self.node)
        if t == ffi.NULL or t.basetype not in (_smi.SMI_BASETYPE_ENUM,
                                               _smi.SMI_BASETYPE_BITS):
            return None

        result = {}
        element = _smi.smiGetFirstNamedNumber(t)
        while element != ffi.NULL:
            result[self._convert(element.value)] = ffi.string(
                element.name).decode("ascii")
            element = _smi.smiGetNextNamedNumber(element)
        return result
Exemple #23
0
def load(mib):
    """Load a MIB into the library.

    :param mib: The MIB to load, either a filename or a MIB name.
    :return: The MIB name that has been loaded.
    :except SMIException: The requested MIB cannot be loaded.
    """
    if not isinstance(mib, bytes):
        mib = mib.encode("ascii")
    modulename = _smi.smiLoadModule(mib)
    if modulename == ffi.NULL:
        raise SMIException("unable to find {0} (check the path)".format(mib))
    modulename = ffi.string(modulename)
    if not _get_module(modulename.decode("ascii")):
        details = "check with smilint -s -l1"
        if _lastError is not None:
            details = "{0}: {1}".format(_lastError, details)
        raise SMIException("{0} contains major SMI error ({1})".format(mib, details))
    return modulename
Exemple #24
0
def load(mib):
    """Load a MIB into the library.

    :param mib: The MIB to load, either a filename or a MIB name.
    :return: The MIB name that has been loaded.
    :except SMIException: The requested MIB cannot be loaded.
    """
    if not isinstance(mib, bytes):
        mib = mib.encode("ascii")
    modulename = _smi.smiLoadModule(mib)
    if modulename == ffi.NULL:
        raise SMIException("unable to find {0} (check the path)".format(mib))
    modulename = ffi.string(modulename)
    if not _get_module(modulename.decode("ascii")):
        details = "check with smilint -s -l1"
        if _lastError is not None:
            details = "{0}: {1}".format(_lastError, details)
        raise SMIException("{0} contains major SMI error ({1})".format(
            mib, details))
    return modulename
Exemple #25
0
    def typeName(self):
        """Retrieves the name of the the node's current declared type
        (not basic type).

        :return: A string representing the current declared type,
            suitable for assignment to type.setter.
        """
        if self._override_type:
            t = self._override_type
        else:
            t = _smi.smiGetNodeType(self.node)

        # This occurs when the type is "implied".
        if t.name == ffi.NULL:
            t = _smi.smiGetParentType(t)

        if t is None or t == ffi.NULL:
            raise SMIException("unable to retrieve the declared type " "of the node '{}'".format(self.node.name))

        return ffi.string(t.name)
Exemple #26
0
    def typeName(self):
        """Retrieves the name of the the node's current declared type
        (not basic type).

        :return: A string representing the current declared type,
            suitable for assignment to type.setter.
        """
        if self._override_type:
            t = self._override_type
        else:
            t = _smi.smiGetNodeType(self.node)

        # This occurs when the type is "implied".
        if t.name == ffi.NULL:
            t = _smi.smiGetParentType(t)

        if t is None or t == ffi.NULL:
            raise SMIException("unable to retrieve the declared type "
                               "of the node '{0}'".format(self.node.name))

        return ffi.string(t.name)
Exemple #27
0
def path(path=None):
    """Set or get a search path to libsmi.

    When no path is provided, return the current path,
    unmodified. Otherwise, set the path to the specified value.

    :param path: The string to be used to change the search path or
                 `None`

    """
    if path is None:
        # Get the path
        path = _smi.smiGetPath()
        if path == ffi.NULL:
            raise SMIException("unable to get current libsmi path")
        path = ffi.gc(path, _smi.free)
        result = ffi.string(path)
        return result.decode("utf8")

    # Set the path
    if not isinstance(path, bytes):
        path = path.encode("utf8")
    if _smi.smiSetPath(path) < 0:
        raise SMIException("unable to set the path {0}".format(path))
Exemple #28
0
def path(path=None):
    """Set or get a search path to libsmi.

    When no path is provided, return the current path,
    unmodified. Otherwise, set the path to the specified value.

    :param path: The string to be used to change the search path or
                 `None`

    """
    if path is None:
        # Get the path
        path = _smi.smiGetPath()
        if path == ffi.NULL:
            raise SMIException("unable to get current libsmi path")
        path = ffi.gc(path, _smi.free)
        result = ffi.string(path)
        return result.decode("utf8")

    # Set the path
    if not isinstance(path, bytes):
        path = path.encode("utf8")
    if _smi.smiSetPath(path) < 0:
        raise SMIException("unable to set the path {0}".format(path))
Exemple #29
0
    def table(self):
        """Get table associated with this column.

        :return: The :class:`Table` instance associated to this
            column.
        """
        parent = _smi.smiGetParentNode(self.node)
        if parent == ffi.NULL:
            raise SMIException("unable to get parent of {0}".format(ffi.string(self.node.name)))
        if parent.nodekind != _smi.SMI_NODEKIND_ROW:
            raise SMIException(
                "parent {0} of {1} is not a row".format(ffi.string(parent.name), ffi.string(self.node.name))
            )
        parent = _smi.smiGetParentNode(parent)
        if parent == ffi.NULL:
            raise SMIException("unable to get parent of {0}".format(ffi.string(self.node.name)))
        if parent.nodekind != _smi.SMI_NODEKIND_TABLE:
            raise SMIException(
                "parent {0} of {1} is not a table".format(ffi.string(parent.name), ffi.string(self.node.name))
            )
        t = Table(parent)
        return t
Exemple #30
0
    def table(self):
        """Get table associated with this column.

        :return: The :class:`Table` instance associated to this
            column.
        """
        parent = _smi.smiGetParentNode(self.node)
        if parent == ffi.NULL:
            raise SMIException("unable to get parent of {0}".format(
                ffi.string(self.node.name)))
        if parent.nodekind != _smi.SMI_NODEKIND_ROW:
            raise SMIException("parent {0} of {1} is not a row".format(
                ffi.string(parent.name), ffi.string(self.node.name)))
        parent = _smi.smiGetParentNode(parent)
        if parent == ffi.NULL:
            raise SMIException("unable to get parent of {0}".format(
                ffi.string(self.node.name)))
        if parent.nodekind != _smi.SMI_NODEKIND_TABLE:
            raise SMIException("parent {0} of {1} is not a table".format(
                ffi.string(parent.name), ffi.string(self.node.name)))
        t = Table(parent)
        return t
Exemple #31
0
 def __str__(self):
     return ffi.string(self.node.name).decode("ascii")
Exemple #32
0
 def __str__(self):
     return ffi.string(self.node.name).decode("ascii")