Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: bump avsc and i18n example files #126

Merged
merged 7 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/erlang.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest

container:
image: ghcr.io/emqx/emqx-builder/5.3-2:1.15.7-26.2.1-2-ubuntu22.04
image: ghcr.io/emqx/emqx-builder/5.3-5:1.15.7-26.2.1-2-ubuntu22.04

steps:
- uses: actions/checkout@v2
Expand Down
11 changes: 11 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## The Official Releases using OTP 26 since EMQX v5.5.0
## See also
## https://github.com/emqx/emqx/releases/tag/v5.5.0
# erlang 26.2.1-2
# elixir 1.15.7-otp-26

## Keep using OTP 25.3.2 for docker image
## see also
## https://github.com/emqx/emqx/blob/v5.6.0/build#L400-L401
erlang 25.3.2-2
elixir 1.15.7-otp-25
23 changes: 13 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
export BUILD_WITHOUT_QUIC ?= true
export BUILD_WITHOUT_ROCKSDB ?= true

## shallow clone for speed
export REBAR_GIT_CLONE_OPTIONS += --depth=1

BUILD_WITHOUT_QUIC ?= true
export BUILD_WITHOUT_QUIC
BUILD_WITHOUT_ROCKSDB ?= true
export BUILD_WITHOUT_ROCKSDB
## Feature Used in rebar plugin emqx_plugrel
## The Feature have not enabled by default on OTP25
export ERL_FLAGS ?= -enable-feature maybe_expr

REBAR ?= $(or $(shell which rebar3 2>/dev/null),$(CURDIR)/rebar3)
REBAR_VERSION ?= 3.19.0-emqx-1
REBAR = $(CURDIR)/rebar3
SCRIPTS = $(CURDIR)/scripts

.PHONY: all
all: compile

.PHONY: get-rebar3
get-rebar3:
@$(CURDIR)/get-rebar3 $(REBAR_VERSION)
.PHONY: ensure-rebar3
ensure-rebar3:
@$(SCRIPTS)/ensure-rebar3.sh

$(REBAR):
$(MAKE) get-rebar3
$(MAKE) ensure-rebar3

.PHONY: compile
compile: $(REBAR)
Expand Down
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ This is a [rebar3 template](https://rebar3.org/docs/tutorials/templates/#custom-

This plugin template is for EMQX >= 5.0.

We introduced a AVRO config schema mechanism for plugins in EMQX 5.7.0 to facilitate configuration updates for plugins at runtime via RESTAPI.
Please see [priv/config_schmea.avsc.example](./priv/config_schmea.avsc.example) and [priv/config_i18n.json.example](./priv/config_schmea.avsc.example) as examples.

For EMQX >= 4.3, please see branch emqx-v4

For older EMQX versions, plugin development is no longer maintained.
Expand All @@ -13,7 +16,8 @@ A plugin template for Elixir (experimental) can be found at https://github.com/e
## Prerequisites

+ A working build environment (eg `build_essential`) including `make`
+ Erlang OTP 25 or newer recommended
+ ASDF tool-chains recommended to manage EMQX released Erlang/OTP.
+ **MUST** use OTP 25 For docker image deployment. See also [./.tool-versions](./.tool-versions) and [EMQX Release v5.5.0](https://github.com/emqx/emqx/releases/tag/v5.5.0).
+ rebar3

## Usage
Expand All @@ -27,9 +31,14 @@ $ rebar3 new emqx-plugin my_emqx_plugin
$ make -C my_emqx_plugin rel
```

**NOTE**
If the `REBAR_CACHE_DIR` environment variable has been set, the directory for templates should be `$REBAR_CACHE_DIR/.config/rebar3/templates`.
[Here](https://github.com/erlang/rebar3/issues/2762) is a relevant issue.
> [!NOTE]
> In order to use the AVRO config schema feature, please make sure the plugin template tag version >= 5.7.0
> Rename files in the `./priv` directory to ensure that EMQX can load them correctly after the plugin is installed.
> See also [EMQX Documents - Plugins](https://www.emqx.io/docs/en/latest/extensions/plugins.html) for more detail.

> [!NOTE]
> If the `REBAR_CACHE_DIR` environment variable has been set, the directory for templates should be `$REBAR_CACHE_DIR/.config/rebar3/templates`.
> [Here](https://github.com/erlang/rebar3/issues/2762) is a relevant issue.

This will create a tarball containing your custom plugin. You can use EMQX's Dashboard or it's command line tools to deploy it into your running EMQX cluster.

Expand Down
1 change: 1 addition & 0 deletions README_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ An EMQX plugin release is a tar file including including a subdirectory of this

1. A JSON format metadata file describing the plugin
2. Versioned directories for all applications needed for this plugin (source and binaries).
3. Confirm the OTP version used by EMQX that the plugin will be installed on (See also [./.tool-versions](./.tool-versions)).

In a shell from this plugin's working directory execute `make rel` to have the package created like:

Expand Down
17 changes: 13 additions & 4 deletions emqx-plugin.template
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,29 @@
{description, "Another amazing EMQX plugin."},
{version, "1.0.0", "The release version of this plugin."},
{app_vsn, "0.1.0", "The erlang application vsn value."},
{emqx_vsn, "v5.4.1", "EMQX version to use as a dependency."},
{emqx_vsn, "v5.6.1", "EMQX version to use as a dependency."},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
{emqx_vsn, "v5.6.1", "EMQX version to use as a dependency."},
{emqx_vsn, "v5.6.1", "EMQX version to use as a dependency for compile and test."},

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be updated when v5.7.0 released

{license, "Apache-2.0", "Short identifier for license you want to distribute this plugin under."},
{author_website, "http://example.com", "A website with details about the author."},
{repo, "https://github.com/emqx/emqx-plugin-template", "Where to find the source code for this plugin."}
]}.
{dir, "{{name}}/src"}.
{dir, "{{name}}/priv"}.
{dir, "{{name}}/scripts"}.
{file, ".tool-versions", "{{name}}/.tool-versions"}.
{file, "LICENSE", "{{name}}/LICENSE"}.
{file, "Makefile", "{{name}}/Makefile"}.
{file, "erlang_ls.config", "{{name}}/erlang_ls.config"}.
{file, "get-rebar3", "{{name}}/get-rebar3"}.
{file, "priv/config.hocon", "{{name}}/priv/config.hocon"}.

{file, "priv/config.hocon.example", "{{name}}/priv/config.hocon.example"}.
{file, "priv/config_schema.avsc.enterprise.example", "{{name}}/priv/config_schema.avsc.enterprise.example"}.
{file, "priv/config_schema.avsc.example", "{{name}}/priv/config_schema.avsc.example"}.
{file, "priv/config_i18n.json.example", "{{name}}/priv/config_i18n.json.example"}.

{file, "scripts/ensure-rebar3.sh", "{{name}}/scripts/ensure-rebar3.sh"}.
{file, "scripts/get-otp-vsn.sh", "{{name}}/scripts/get-otp-vsn.sh"}.
{file, "gitignore_template", "{{name}}/.gitignore"}.
{chmod, "{{name}}/get-rebar3", 8#755}.
{chmod, "{{name}}/scripts/ensure-rebar3.sh", 8#755}.
{chmod, "{{name}}/scripts/get-otp-vsn.sh", 8#755}.
{template, "README_template.md", "{{name}}/README.md"}.
{template, "rebar_template.config", "{{name}}/rebar.config"}.
{template, "src/emqx_plugin_template.app.src", "{{name}}/src/{{name}}.app.src"}.
Expand Down
4 changes: 0 additions & 4 deletions priv/config.hocon

This file was deleted.

20 changes: 20 additions & 0 deletions priv/config.hocon.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## This is a demo config in HOCON format
## The same format used by EMQX since 5.0

hostname = "localhost"
port = 3306

connectionOptions = [
{
optionName = "autoReconnect"
optionType = "string"
optionValue = "true"
}
]

auth {
username = "admin"
password {
string = "Public123"
}
}
74 changes: 74 additions & 0 deletions priv/config_i18n.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"$hostname_label": {
"zh": "主机名",
"en": "Hostname"
},
"$hostname_desc": {
"zh": "主机名是一个标识符,用于识别网络上的设备。主机名通常是一个域名,例如:www.example.com。",
"en": "The hostname is an identifier used to identify devices on a network. The hostname is usually a domain name, such as www.example.com."
},
"$hostname_validate": {
"zh": "主机名必须是一个有效的域名。",
"en": "The hostname must be a valid domain name."
},
"$port_label": {
"zh": "端口",
"en": "Port"
},
"$port_desc": {
"zh": "端口是一个数字,用于标识网络上的服务。常见的端口有:80(HTTP)、443(HTTPS)、21(FTP)。",
"en": "The port is a number used to identify services on a network. Common ports include: 80 (HTTP), 443 (HTTPS), 21 (FTP)."
},
"$port_range_validate": {
"zh": "端口必须在 1 到 65535 之间。",
"en": "The port must be between 1 and 65535."
},
"$connection_options_label": {
"en": "Connection Options",
"zh": "连接选项"
},
"$connection_options_desc": {
"en": "A list of additional options for the database connection.",
"zh": "数据库连接的附加选项列表。"
},
"$username_label": {
"en": "Username",
"zh": "用户名"
},
"$username_desc": {
"zh": "连接数据库的用户名",
"en": "The username used to connect to the database."
},
"$password_label": {
"en": "Password",
"zh": "密码"
},
"$password_desc": {
"en": "The password used to connect to the database.",
"zh": "连接数据库的密码。"
},
"$password_length_validate": {
"en": "The password must be at least 8 characters long.",
"zh": "密码长度必须至少为 8 个字符。"
},
"$password_validate": {
"en": "The password must contain at least one uppercase letter, one lowercase letter, one number, and one special character.",
"zh": "密码必须包含至少一个大写字母、一个小写字母、一个数字和一个特殊字符。"
},
"$option_name_label": {
"en": "Option Name",
"zh": "选项名称"
},
"$option_name_desc": {
"en": "The name of the connection option.",
"zh": "连接选项的名称。"
},
"$option_value_label": {
"en": "Option Value",
"zh": "选项值"
},
"$option_value_desc": {
"en": "The value of the connection option.",
"zh": "连接选项的值。"
}
}
141 changes: 141 additions & 0 deletions priv/config_schema.avsc.enterprise.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
{
"type": "record",
"name": "ExtendedConfig",
"fields": [
{
"name": "hostname",
"type": "string",
"default": "localhost",
"$ui": {
"component": "input",
"flex": 12,
"required": true,
"label": "$hostname_label",
"description": "$hostname_desc",
"rules": [
{
"type": "pattern",
"pattern": "^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])(\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]))*$",
"message": "$hostname_validate"
}
]
}
},
{
"name": "port",
"type": "int",
"default": 3306,
"$ui": {
"component": "input-number",
"flex": 12,
"required": true,
"label": "$port_label",
"description": "$port_desc",
"rules": [
{
"type": "range",
"min": 1,
"max": 65535,
"message": "$port_range_validate"
}
]
}
},
{
"name": "connectionOptions",
"type": {
"type": "array",
"items": {
"type": "record",
"name": "ConnectionOption",
"fields": [
{
"name": "optionName",
"type": "string"
},
{
"name": "optionValue",
"type": "string"
},
{
"name": "optionType",
"type": "string"
}
]
}
},
"default": [
{
"optionName": "autoReconnect",
"optionValue": "true",
"optionType": "boolean"
}
],
"$ui": {
"component": "maps-editor",
"flex": 24,
"items": {
"optionName": {
"label": "$option_name_label",
"description": "$option_name_desc",
"type": "string"
},
"optionValue": {
"label": "$option_value_label",
"description": "$option_value_desc",
"type": "string"
}
},
"label": "$connection_options_label",
"description": "$connection_options_desc"
}
},
{
"name": "auth",
"type": {
"type": "record",
"name": "authConfigs",
"fields": [
{
"name": "username",
"type": "string",
"$ui": {
"component": "input",
"flex": 12,
"required": true,
"label": "$username_label",
"description": "$username_desc"
}
},
{
"name": "password",
"type": [
"null",
"string"
],
"default": null,
"$ui": {
"component": "input-password",
"flex": 12,
"label": "$password_label",
"description": "$password_desc",
"rules": [
{
"type": "length",
"minLength": 8,
"maxLength": 128,
"message": "$password_length_validate"
},
{
"type": "pattern",
"pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]*$",
"message": "$password_validate"
}
]
}
}
]
}
}
]
}
Loading
Loading