updating broker and client config documentation. updating description on how to create a custom plugin.

pull/240/head
Andrew Mirsky 2025-06-28 23:02:02 -04:00
rodzic a8e1692631
commit 92141d9a54
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: A98E67635CDF2C39
3 zmienionych plików z 135 dodań i 102 usunięć

Wyświetl plik

@ -1,37 +1,73 @@
from dataclasses import dataclass
# Custom Plugins
With the aMQTT Broker plugins framework, one can add additional functionality to the broker without
having to subclass or rewrite any of the core broker logic. To define a custom list of plugins to be loaded,
add this section to your `pyproject.toml`"
With the aMQTT plugins framework, one can add additional functionality to the client or broker without
having to rewrite any of the core logic.
```toml
[project.entry-points."mypackage.mymodule.plugins"]
plugin_alias = "module.submodule.file:ClassName"
```
and specify the namespace when instantiating the broker:
To create a custom plugin, subclass from `BasePlugin` (client or broker) or `BaseAuthPlugin` (broker only)
or `BaseTopicPlugin` (broker only). Each custom plugin may define settings specific to itself by creating
a nested (or inner) `dataclass` named `Config` which declares each option and a default value (if applicable). A
plugin's configuration dataclass will be type-checked and made available from within the `self.context` instance variable.
```python
from amqtt.broker import Broker
from dataclasses import dataclass, field
from amqtt.plugins.base import BasePlugin
from amqtt.contexts import BaseContext
broker = Broker(plugin_namespace='mypackage.mymodule.plugins')
class OneClassName(BasePlugin[BaseContext]):
"""This is a plugin with no functionality"""
class TwoClassName(BasePlugin[BaseContext]):
"""This is a plugin with configuration options."""
def __init__(self, context: BaseContext):
super().__init__(context)
my_option_one: str = self.context.config.option1
@dataclass
class Config:
option1: int
option3: str = field(default="my_default_value")
```
Each plugin has access to the full configuration file through the provided `BaseContext` and can define
its own variables to configure its behavior.
This plugin class then should be added to the configuration file of the broker or client (or to the `config`
dictionary passed to the `Broker` or `MQTTClient`).
```yaml
...
...
plugins:
- module.submodule.file.OneClassName:
- module.submodule.file.TwoClassName:
option1: 123
```
??? warning "Deprecated: activating plugins using `EntryPoints`"
With the aMQTT plugins framework, one can add additional functionality to the client or broker without
having to rewrite any of the core logic. To define a custom list of plugins to be loaded, add this section
to your `pyproject.toml`"
```toml
[project.entry-points."mypackage.mymodule.plugins"]
plugin_alias = "module.submodule.file:ClassName"
```
Each plugin has access to the full configuration file through the provided `BaseContext` and can define its own
variables to configure its behavior.
::: amqtt.plugins.base.BasePlugin
## Events
Plugins that are defined in the`project.entry-points` are notified of events if the subclass
implements one or more of these methods:
All plugins are notified of events if the `BasePlugin` subclass implements one or more of these methods:
### Client and Broker
- `async def on_mqtt_packet_sent(self, packet: MQTTPacket[MQTTVariableHeader, MQTTPayload[MQTTVariableHeader], MQTTFixedHeader], session: Session | None = None) -> None`
- `async def on_mqtt_packet_received(self, packet: MQTTPacket[MQTTVariableHeader, MQTTPayload[MQTTVariableHeader], MQTTFixedHeader], session: Session | None = None) -> None`
- `async def on_mqtt_packet_sent(self, *, packet: MQTTPacket[MQTTVariableHeader, MQTTPayload[MQTTVariableHeader], MQTTFixedHeader], session: Session | None = None) -> None`
- `async def on_mqtt_packet_received(self, *, packet: MQTTPacket[MQTTVariableHeader, MQTTPayload[MQTTVariableHeader], MQTTFixedHeader], session: Session | None = None) -> None`
### Client Only
@ -55,32 +91,22 @@ none
## Authentication Plugins
Of the plugins listed in `project.entry-points`, one or more can be used to validate client sessions
by specifying their alias in `auth` > `plugins` section of the config:
```yaml
auth:
plugins:
- plugin_alias_name
```
These plugins should subclass from `BaseAuthPlugin` and implement the `authenticate` method.
In addition to receiving any of the event callbacks, a plugin which subclasses from `BaseAuthPlugin`
is used by the aMQTT `Broker` to determine if a connection from a client is allowed by
implementing the `authenticate` method and returning `True` if the session is allowed or `False` otherwise.
::: amqtt.plugins.base.BaseAuthPlugin
## Topic Filter Plugins
Of the plugins listed in `project.entry-points`, one or more can be used to determine topic access
by specifying their alias in `topic-check` > `plugins` section of the config:
```yaml
topic-check:
enable: True
plugins:
- plugin_alias_name
```
These plugins should subclass from `BaseTopicPlugin` and implement the `topic_filtering` method.
In addition to receiving any of the event callbacks, a plugin which is subclassed from `BaseTopicPlugin`
is used by the aMQTT `Broker` to determine if a connected client can send (PUBLISH) or receive (SUBSCRIBE)
messages to a particular topic by implementing the `topic_filtering` method and returning `True` if allowed or
`False` otherwise.
::: amqtt.plugins.base.BaseTopicPlugin
!!! note
A custom plugin class can subclass from both `BaseAuthPlugin` and `BaseTopicPlugin` as long it defines
both the `authenticate` and `topic_filtering` method.

Wyświetl plik

@ -3,7 +3,7 @@
This configuration structure is valid as a python dictionary passed to the `amqtt.broker.Broker` class's `__init__` method or
as a yaml formatted file passed to the `amqtt` script.
### `listeners` *(list[mapping])*
### `listeners` *(list[dict[str, Any]])*
Defines the network listeners used by the service. Items defined in the `default` listener will be
applied to all other listeners, unless they are overridden by the configuration for the specific
@ -20,77 +20,77 @@ listener.
- `certfile` *(string)*: Path to a single file in PEM format containing the certificate as well as any number of CA certificates needed to establish the certificate's authenticity.
- `keyfile` *(string): A file containing the private key. Otherwise the private key will be taken from `certfile` as well.
### `sys_interval` *(int)*
System status report interval in seconds (`broker_sys` plugin)
### `timeout-disconnect-delay` *(int)*
Client disconnect timeout without a keep-alive
### `auth` *(mapping)*
### `plugins` *(mapping)*
Configuration for authentication behaviour:
- `plugins` *(list[string])*: defines the list of plugins which are activated as authentication plugins.
!!! note "Entry points"
Plugins used here must first be defined in the `amqtt.broker.plugins` [entry point](https://packaging.python.org/en/latest/guides/creating-and-discovering-plugins/#using-package-metadata).
A list of strings representing the modules and class name of `BasePlugin`, `BaseAuthPlugin` and `BaseTopicPlugins`. Each
entry may have one or more configuration settings. For more information, see the [configuration of the included plugins](../packaged_plugins.md)
!!! danger "Legacy behavior"
if `plugins` is omitted from the `auth` section, all plugins listed in the `amqtt.broker.plugins` entrypoint will be enabled
for authentication, *including allowing anonymous login.*
`plugins: []` will deny connections from all clients.
- `allow-anonymous` *(bool)*: `True` will allow anonymous connections.
*Used by the internal `amqtt.plugins.authentication.AnonymousAuthPlugin` plugin*
??? warning "Deprecated: `sys_interval` "
**`sys_interval`** *(int)*
!!! danger "Username only connections"
`False` does not disable the `auth_anonymous` plugin; connections will still be allowed as long as a username is provided.
If security is required, do not include `auth_anonymous` in the `plugins` list.
System status report interval in seconds, used by the `amqtt.plugins.sys.broker.BrokerSysPlugin`.
- `password-file` *(string)*: Path to file which includes `username:password` pair, one per line. The password should be encoded using sha-512 with `mkpasswd -m sha-512` or:
```python
import sys
from getpass import getpass
from passlib.hash import sha512_crypt
passwd = input() if not sys.stdin.isatty() else getpass()
print(sha512_crypt.hash(passwd))
```
*Used by the internal `amqtt.plugins.authentication.FileAuthPlugin` plugin.*
### `topic-check` *(mapping)*
??? warning "Deprecated: `auth` configuration settings"
Configuration for access control policies for publishing and subscribing to topics:
**`auth`**
Configuration for authentication behaviour:
- `plugins` *(list[string])*: defines the list of plugins which are activated as authentication plugins.
!!! note
Plugins used here must first be defined in the `amqtt.broker.plugins` [entry point](https://packaging.python.org/en/latest/guides/creating-and-discovering-plugins/#using-package-metadata).
- `enabled` *(bool)*: Enable access control policies (`true`). `false` will allow clients to publish and subscribe to any topic.
- `plugins` *(list[string])*: defines the list of plugins which are activated as access control plugins. Note the plugins must be defined in the `amqtt.broker.plugins` [entry point](https://pythonhosted.org/setuptools/setuptools.html#dynamic-discovery-of-services-and-plugins).
!!! warning
If `plugins` is omitted from the `auth` section, all plugins listed in the `amqtt.broker.plugins` entrypoint will be enabled
for authentication, including _allowing anonymous login._
`plugins: []` will deny connections from all clients.
- `allow-anonymous` *(bool)*: `True` will allow anonymous connections, used by `amqtt.plugins.authentication.AnonymousAuthPlugin`.
!!! danger
`False` does not disable the `auth_anonymous` plugin; connections will still be allowed as long as a username is provided. If security is required, do not include `auth_anonymous` in the `plugins` list.
- `acl` *(list)*: plugin to determine subscription access; if `publish-acl` is not specified, determine both publish and subscription access.
The list should be a key-value pair, where:
`<username>:[<topic1>, <topic2>, ...]` *(string, list[string])*: username of the client followed by a list of allowed topics (wildcards are supported: `#`, `+`).
- `password-file` *(string)*. Path to sha-512 encoded password file, used by `amqtt.plugins.authentication.FileAuthPlugin`.
*used by the `amqtt.plugins.topic_acl.TopicAclPlugin`*
- `publish-acl` *(list)*: plugin to determine publish access. This parameter defines the list of access control rules; each item is a key-value pair, where:
`<username>:[<topic1>, <topic2>, ...]` *(string, list[string])*: username of the client followed by a list of allowed topics (wildcards are supported: `#`, `+`).
!!! info "Reserved usernames"
- The username `admin` is allowed access to all topic.
- The username `anonymous` will control allowed topics if using the `auth_anonymous` plugin.
??? warning "Deprecated: `topic-check` configuration settings"
*used by the `amqtt.plugins.topic_acl.TopicAclPlugin`*
**`topic-check`**
Configuration for access control policies for publishing and subscribing to topics:
- `enabled` *(bool)*: Enable access control policies (`true`). `false` will allow clients to publish and subscribe to any topic.
- `plugins` *(list[string])*: defines the list of plugins which are activated as access control plugins. Note the plugins must be defined in the `amqtt.broker.plugins` [entry point](https://pythonhosted.org/setuptools/setuptools.html#dynamic-discovery-of-services-and-plugins).
- `acl` *(list)*: plugin to determine subscription access; if `publish-acl` is not specified, determine both publish and subscription access.
The list should be a key-value pair, where:
`<username>:[<topic1>, <topic2>, ...]` *(string, list[string])*: username of the client followed by a list of allowed topics (wildcards are supported: `#`, `+`).
*used by the `amqtt.plugins.topic_acl.TopicAclPlugin`*
- `publish-acl` *(list)*: plugin to determine publish access. This parameter defines the list of access control rules; each item is a key-value pair, where:
`<username>:[<topic1>, <topic2>, ...]` *(string, list[string])*: username of the client followed by a list of allowed topics (wildcards are supported: `#`, `+`).
_Reserved usernames (used by the `amqtt.plugins.topic_acl.TopicAclPlugin`)_
- The username `admin` is allowed access to all topic.
- The username `anonymous` will control allowed topics if using the `auth_anonymous` plugin.
@ -130,14 +130,13 @@ listeners:
certfile: /some/certfile
keyfile: /some/key
timeout-disconnect-delay: 2
auth:
plugins: ['auth_anonymous', 'auth_file']
allow-anonymous: true
password-file: /some/password-file
topic-check:
enabled: true
plugins: ['topic_acl']
acl:
plugins:
- amqtt.plugins.authentication.AnonymousAuthPlugin:
allow-anonymous: true
- amqtt.plugin.authentication.FileAuthPlugin:
password-file: /some/password-file
- amqtt.plugins.topic_checking.TopicAccessControlListPlugin:
acl:
username1: ['repositories/+/master', 'calendar/#', 'data/memes']
username2: [ 'calendar/2025/#', 'data/memes']
anonymous: ['calendar/2025/#']

Wyświetl plik

@ -68,8 +68,8 @@ TLS certificates used to verify the broker's authenticity.
- `cafile` *(string)*: Path to a file of concatenated CA certificates in PEM format. See [Certificates](https://docs.python.org/3/library/ssl.html#ssl-certificates) for more info.
- `capath` *(string)*: Path to a directory containing several CA certificates in PEM format, following an [OpenSSL specific layout](https://docs.openssl.org/master/man3/SSL_CTX_load_verify_locations/).
- `cadata` *(string)*: Either an ASCII string of one or more PEM-encoded certificates or a bytes-like object of DER-encoded certificates.
-
-
### `certfile` *(string)*
Path to a single file in PEM format containing the certificate as well as any number of CA certificates needed to establish the server certificate's authenticity.
@ -78,6 +78,11 @@ Path to a single file in PEM format containing the certificate as well as any nu
Bypass ssl host certificate verification, allowing self-signed certificates
### `plugins` *(mapping)*
A list of strings representing the modules and class name of any `BasePlugin`s. Each entry may have one or more
configuration settings. For more information, see the [configuration of the included plugins](../packaged_plugins.md)
## Default Configuration
@ -110,4 +115,7 @@ will:
broker:
uri: mqtt://localhost:1883
cafile: /path/to/ca/file
plugins:
- amqtt.plugins.logging_amqtt.PacketLoggerPlugin:
```