puresnmp.plugins.mpm module
This module provides a plugin architecture for SNMP message-processing models (mpm).
Each mpm plugin can be distributed as separate package by providing
modules inside the namespace-package “puresnmp.mpm”. Note that in order
to be a valid namespace-package, such a package must not have a
__init__.py
file!
Example folder-structure for a mpm plugin:
my-security-plugin/
+- setup.py (or pyproject.toml)
+- puresnmp/
+- mpm/
+- mymodule.py
+- myothermodule.py
Note that there is no __init__.py
file!
In order for modules to be detected as plugin, they must follow the following rules:
Have a function
create
returning an instance of a class implementing the message-processing model. The function must take a network-transport handler and a “local configuration directory” as arguments. A reference implementation can be found inpuresnmp.mpm.v3.V3MPM
.Contain a int-variable
IDENTIFIER
. This variable should map to the message-processing model identifiers as defined in the SNMPv3 standard. See https://www.iana.org/assignments/snmp-number-spaces/snmp-number-spaces.xhtml and RFC 3411
- class puresnmp.plugins.mpm.AbstractEncodingResult(data: bytes, security_model: SecurityModel[Any, Any] | None = None)
Bases:
NamedTuple
Generic type for the output of the conversion from messages to bytes by the message processing modules.
- security_model: SecurityModel[Any, Any] | None
The security model that was applied by the message-processing module
- puresnmp.plugins.mpm.DISCOVERED_PLUGINS: Dict[int, TMPMPlugin] = {}
Global registry of detected plugins
- class puresnmp.plugins.mpm.MessageProcessingModel(transport_handler: Callable[[bytes], Awaitable[bytes]], lcd: Dict[str, Any])
Bases:
Generic
[TEncodeResult
,TSecurityModel
]Each Message Processing Model defines the format of a particular version of an SNMP message and coordinates the preparation and extraction of each such version-specific message format.
See https://tools.ietf.org/html/rfc3411#section-6.2
- decode(whole_msg: bytes, credentials: Credentials) PDU
Convert bytes (as received raw from the network) into an SNMP PDU
- Parameters:
whole_msg – The message as received from the network
credentials – Credentials which will be used if required by the model.
- Returns:
A plain SNMP PDU
- async encode(request_id: int, credentials: Credentials, engine_id: bytes, context_name: bytes, pdu: PDU) TEncodeResult
Convert an SNMP PDU into raw bytes for the network.
- Parameters:
request_id – A unique ID for the request.
credentials – Credentials which are used by the model if needed (encryption, authentication, …).
engine_id – The engine-id for use in SNMPv3.
puresnmp.util
contains helper methods to create those according to the RFC.context_name – An identifier for the SNMPv3 context
pdu – The plain SNMP PDU to process
- Returns:
Raw bytes that can be sent to the network
- class puresnmp.plugins.mpm.TMPMPlugin(*args, **kwargs)
Bases:
Protocol
Protocol for the plugin factory function.
- puresnmp.plugins.mpm.create(identifier: int, transport_handler: Callable[[bytes], Awaitable[bytes]], lcd: Dict[str, Any]) MessageProcessingModel[Any, Any]
Creates a new instance of a message-processing-model
- Parameters:
identifier – The IANA ID for the message-processing model
transport_handler – A callable that is responsible to send data to the network. It will be called with bytes to be sent, and should return bytes. It should by itself already be aware of where to send them (the only input it gets is the payload). This is used in situations where the message-processing model needs to communicate with the device outside of normal data-exchange message, like the initial discovery message in the SNMPv3 protocol.
lcd – A “local configuration directory” which is dynamically updated with “discovery” data if required.
- Returns:
A new Message Processing Model instance
>>> async def packet_handler(data: bytes) -> bytes: ... loop = get_event_loop() ... _, protocol = await loop.create_datagram_endpoint( ... lambda: SNMPClientProtocol(packet, loop), ... remote_addr=("192.0.2.1", 161), ... ) ... response = await protocol.get_data(timeout) ... return response >>> create(3, packet_handler, {}) <puresnmp_plugins.mpm.v3.V3MPM object ...>
- puresnmp.plugins.mpm.is_valid_mpm_plugin(mod: ModuleType) bool
Return True if the module in mod is usable as MPM plugin