kopia lustrzana https://github.com/Yakifo/amqtt
updating broker and client config documentation. updating description on how to create a custom plugin.
rodzic
a8e1692631
commit
92141d9a54
|
@ -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.
|
||||
|
|
|
@ -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/#']
|
||||
|
|
|
@ -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:
|
||||
|
||||
```
|
||||
|
|
Ładowanie…
Reference in New Issue