Merge branch 'main-v4.4' into kjell/mongodb_upgrade_in_4.4
This commit is contained in:
commit
99d46bd1ce
|
@ -1,3 +1,6 @@
|
||||||
|
## Default
|
||||||
|
* @emqx/emqx-review-board
|
||||||
|
|
||||||
## MQTT & Core
|
## MQTT & Core
|
||||||
/src/ @qzhuyan
|
/src/ @qzhuyan
|
||||||
/include/ @qzhuyan
|
/include/ @qzhuyan
|
||||||
|
@ -5,13 +8,13 @@
|
||||||
/test/ @qzhuyan
|
/test/ @qzhuyan
|
||||||
|
|
||||||
## CI
|
## CI
|
||||||
/.github/ @id
|
/.github/ @emqx/emqx-review-board @id
|
||||||
/.ci/ @id
|
/.ci/ @emqx/emqx-review-board @id
|
||||||
/scripts/ @id
|
/scripts/ @emqx/emqx-review-board @id
|
||||||
/build @id
|
/build @emqx/emqx-review-board @id
|
||||||
/deploy/ @id
|
/deploy/ @emqx/emqx-review-board @id
|
||||||
|
|
||||||
## Authenticatio & ACL
|
## Authentication & ACL
|
||||||
/apps/emqx_auth_*/ @savonarola
|
/apps/emqx_auth_*/ @savonarola
|
||||||
/apps/emqx_psk_file/ @savonarola
|
/apps/emqx_psk_file/ @savonarola
|
||||||
/apps/emqx_retainer/ @savonarola
|
/apps/emqx_retainer/ @savonarola
|
||||||
|
@ -31,13 +34,6 @@
|
||||||
/apps/emqx_prometheus/ @zhongwencool
|
/apps/emqx_prometheus/ @zhongwencool
|
||||||
/apps/emqx_recon/ @zhongwencool
|
/apps/emqx_recon/ @zhongwencool
|
||||||
|
|
||||||
|
|
||||||
## Data integration
|
## Data integration
|
||||||
/apps/emqx_rule_engine/ @thalesmg
|
/apps/emqx_rule_engine/ @thalesmg
|
||||||
/apps/emqx_web_hook/ @thalesmg
|
/apps/emqx_web_hook/ @thalesmg
|
||||||
|
|
||||||
## External Plugins
|
|
||||||
/lib-extra/ @zmstone
|
|
||||||
|
|
||||||
## Default
|
|
||||||
* @zmstone
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ jobs:
|
||||||
os:
|
os:
|
||||||
- ubuntu20.04
|
- ubuntu20.04
|
||||||
|
|
||||||
container: ghcr.io/emqx/emqx-builder/4.4-23:${{ matrix.erl_otp }}-${{ matrix.os }}
|
container: ghcr.io/emqx/emqx-builder/4.4-24:${{ matrix.erl_otp }}-${{ matrix.os }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
|
@ -157,6 +157,7 @@ jobs:
|
||||||
- amd64
|
- amd64
|
||||||
- arm64
|
- arm64
|
||||||
os:
|
os:
|
||||||
|
- ubuntu22.04
|
||||||
- ubuntu20.04
|
- ubuntu20.04
|
||||||
- ubuntu18.04
|
- ubuntu18.04
|
||||||
- ubuntu16.04
|
- ubuntu16.04
|
||||||
|
@ -195,7 +196,7 @@ jobs:
|
||||||
--profile "${PROFILE}" \
|
--profile "${PROFILE}" \
|
||||||
--pkgtype "${PACKAGE}" \
|
--pkgtype "${PACKAGE}" \
|
||||||
--arch "${ARCH}" \
|
--arch "${ARCH}" \
|
||||||
--builder "ghcr.io/emqx/emqx-builder/4.4-23:${OTP}-${SYSTEM}"
|
--builder "ghcr.io/emqx/emqx-builder/4.4-24:${OTP}-${SYSTEM}"
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ matrix.profile }}
|
name: ${{ matrix.profile }}
|
||||||
|
@ -271,7 +272,7 @@ jobs:
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
build-args: |
|
build-args: |
|
||||||
BUILD_FROM=ghcr.io/emqx/emqx-builder/4.4-23:${{ matrix.otp }}-alpine3.15.1
|
BUILD_FROM=ghcr.io/emqx/emqx-builder/4.4-24:${{ matrix.otp }}-alpine3.15.1
|
||||||
RUN_FROM=alpine:3.15.1
|
RUN_FROM=alpine:3.15.1
|
||||||
EMQX_NAME=${{ matrix.profile }}
|
EMQX_NAME=${{ matrix.profile }}
|
||||||
file: source/deploy/docker/Dockerfile
|
file: source/deploy/docker/Dockerfile
|
||||||
|
@ -287,7 +288,7 @@ jobs:
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
build-args: |
|
build-args: |
|
||||||
BUILD_FROM=ghcr.io/emqx/emqx-builder/4.4-23:${{ matrix.otp }}-alpine3.15.1
|
BUILD_FROM=ghcr.io/emqx/emqx-builder/4.4-24:${{ matrix.otp }}-alpine3.15.1
|
||||||
RUN_FROM=alpine:3.15.1
|
RUN_FROM=alpine:3.15.1
|
||||||
EMQX_NAME=${{ matrix.profile }}
|
EMQX_NAME=${{ matrix.profile }}
|
||||||
file: source/deploy/docker/Dockerfile.enterprise
|
file: source/deploy/docker/Dockerfile.enterprise
|
||||||
|
|
|
@ -19,6 +19,7 @@ jobs:
|
||||||
otp:
|
otp:
|
||||||
- 24.3.4.2-1
|
- 24.3.4.2-1
|
||||||
os:
|
os:
|
||||||
|
- ubuntu22.04
|
||||||
- ubuntu20.04
|
- ubuntu20.04
|
||||||
- el7
|
- el7
|
||||||
runs-on:
|
runs-on:
|
||||||
|
@ -32,7 +33,7 @@ jobs:
|
||||||
- runs-on: aws-amd64
|
- runs-on: aws-amd64
|
||||||
use-self-hosted: false
|
use-self-hosted: false
|
||||||
|
|
||||||
container: ghcr.io/emqx/emqx-builder/4.4-23:${{ matrix.otp }}-${{ matrix.os }}
|
container: ghcr.io/emqx/emqx-builder/4.4-24:${{ matrix.otp }}-${{ matrix.os }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: AutoModality/action-clean@v1
|
- uses: AutoModality/action-clean@v1
|
||||||
|
|
|
@ -5,7 +5,7 @@ on: [pull_request]
|
||||||
jobs:
|
jobs:
|
||||||
check_deps_integrity:
|
check_deps_integrity:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
container: ghcr.io/emqx/emqx-builder/4.4-23:24.3.4.2-1-ubuntu20.04
|
container: ghcr.io/emqx/emqx-builder/4.4-24:24.3.4.2-1-ubuntu20.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
|
@ -7,7 +7,7 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
prepare:
|
prepare:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
container: ghcr.io/emqx/emqx-builder/4.4-23:24.3.4.2-1-ubuntu20.04
|
container: ghcr.io/emqx/emqx-builder/4.4-24:24.3.4.2-1-ubuntu20.04
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
profiles: ${{ steps.detect-profiles.outputs.profiles}}
|
profiles: ${{ steps.detect-profiles.outputs.profiles}}
|
||||||
|
|
|
@ -5,7 +5,7 @@ on: workflow_dispatch
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
container: ghcr.io/emqx/emqx-builder/4.4-23:24.3.4.2-1-ubuntu20.04
|
container: ghcr.io/emqx/emqx-builder/4.4-24:24.3.4.2-1-ubuntu20.04
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
env:
|
env:
|
||||||
|
|
|
@ -200,7 +200,7 @@ jobs:
|
||||||
|
|
||||||
relup_test_plan:
|
relup_test_plan:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
container: ghcr.io/emqx/emqx-builder/4.4-23:24.3.4.2-1-ubuntu20.04
|
container: ghcr.io/emqx/emqx-builder/4.4-24:24.3.4.2-1-ubuntu20.04
|
||||||
outputs:
|
outputs:
|
||||||
profile: ${{ steps.profile-and-versions.outputs.profile }}
|
profile: ${{ steps.profile-and-versions.outputs.profile }}
|
||||||
vsn: ${{ steps.profile-and-versions.outputs.vsn }}
|
vsn: ${{ steps.profile-and-versions.outputs.vsn }}
|
||||||
|
@ -251,7 +251,7 @@ jobs:
|
||||||
otp:
|
otp:
|
||||||
- 24.3.4.2-1
|
- 24.3.4.2-1
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
container: ghcr.io/emqx/emqx-builder/4.4-23:24.3.4.2-1-ubuntu20.04
|
container: ghcr.io/emqx/emqx-builder/4.4-24:24.3.4.2-1-ubuntu20.04
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
shell: bash
|
shell: bash
|
||||||
|
@ -288,7 +288,7 @@ jobs:
|
||||||
- relup_test_plan
|
- relup_test_plan
|
||||||
- relup_test_build
|
- relup_test_build
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
container: ghcr.io/emqx/emqx-builder/4.4-23:24.3.4.2-1-ubuntu20.04
|
container: ghcr.io/emqx/emqx-builder/4.4-24:24.3.4.2-1-ubuntu20.04
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
|
|
@ -12,7 +12,7 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
prepare:
|
prepare:
|
||||||
runs-on: aws-amd64
|
runs-on: aws-amd64
|
||||||
container: ghcr.io/emqx/emqx-builder/4.4-23:24.3.4.2-1-ubuntu20.04
|
container: ghcr.io/emqx/emqx-builder/4.4-24:24.3.4.2-1-ubuntu20.04
|
||||||
outputs:
|
outputs:
|
||||||
fast_ct_apps: ${{ steps.run_find_apps.outputs.fast_ct_apps }}
|
fast_ct_apps: ${{ steps.run_find_apps.outputs.fast_ct_apps }}
|
||||||
docker_ct_apps: ${{ steps.run_find_apps.outputs.docker_ct_apps }}
|
docker_ct_apps: ${{ steps.run_find_apps.outputs.docker_ct_apps }}
|
||||||
|
@ -58,7 +58,7 @@ jobs:
|
||||||
eunit_and_proper:
|
eunit_and_proper:
|
||||||
needs: prepare
|
needs: prepare
|
||||||
runs-on: aws-amd64
|
runs-on: aws-amd64
|
||||||
container: ghcr.io/emqx/emqx-builder/4.4-23:24.3.4.2-1-ubuntu20.04
|
container: ghcr.io/emqx/emqx-builder/4.4-24:24.3.4.2-1-ubuntu20.04
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -86,7 +86,7 @@ jobs:
|
||||||
fast_ct:
|
fast_ct:
|
||||||
needs: prepare
|
needs: prepare
|
||||||
runs-on: ${{ matrix.runs-on }}
|
runs-on: ${{ matrix.runs-on }}
|
||||||
container: ghcr.io/emqx/emqx-builder/4.4-23:24.3.4.2-1-ubuntu20.04
|
container: ghcr.io/emqx/emqx-builder/4.4-24:24.3.4.2-1-ubuntu20.04
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -249,7 +249,7 @@ jobs:
|
||||||
- fast_ct
|
- fast_ct
|
||||||
- docker_ct
|
- docker_ct
|
||||||
runs-on: aws-amd64
|
runs-on: aws-amd64
|
||||||
container: ghcr.io/emqx/emqx-builder/4.4-23:24.3.4.2-1-ubuntu20.04
|
container: ghcr.io/emqx/emqx-builder/4.4-24:24.3.4.2-1-ubuntu20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: AutoModality/action-clean@v1
|
- uses: AutoModality/action-clean@v1
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
|
|
|
@ -44,7 +44,10 @@ check_acl(ClientInfo, PubSub, Topic, _AclResult, #{acl := ACLParams = #{path :=
|
||||||
Username = maps:get(username, ClientInfo1, undefined),
|
Username = maps:get(username, ClientInfo1, undefined),
|
||||||
case check_acl_request(ACLParams, ClientInfo1) of
|
case check_acl_request(ACLParams, ClientInfo1) of
|
||||||
{ok, 200, <<"ignore">>} -> ok;
|
{ok, 200, <<"ignore">>} -> ok;
|
||||||
{ok, 200, _Body} -> {stop, allow};
|
{ok, 200, _Body} ->
|
||||||
|
?LOG(debug, "Allow ~s to topic ~ts, username: ~ts",
|
||||||
|
[PubSub, Topic, Username]),
|
||||||
|
{stop, allow};
|
||||||
{ok, Code, _Body} ->
|
{ok, Code, _Body} ->
|
||||||
?LOG(warning, "Deny ~s to topic ~ts, username: ~ts, http response code: ~p",
|
?LOG(warning, "Deny ~s to topic ~ts, username: ~ts, http response code: ~p",
|
||||||
[PubSub, Topic, Username, Code]),
|
[PubSub, Topic, Username, Code]),
|
||||||
|
@ -74,4 +77,3 @@ check_acl_request(ACLParams =
|
||||||
|
|
||||||
access(subscribe) -> 1;
|
access(subscribe) -> 1;
|
||||||
access(publish) -> 2.
|
access(publish) -> 2.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_auth_http,
|
{application, emqx_auth_http,
|
||||||
[{description, "EMQ X Authentication/ACL with HTTP API"},
|
[{description, "EMQ X Authentication/ACL with HTTP API"},
|
||||||
{vsn, "4.3.10"}, % strict semver, bump manually!
|
{vsn, "4.3.11"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_auth_http_sup]},
|
{registered, [emqx_auth_http_sup]},
|
||||||
{applications, [kernel,stdlib,ehttpc]},
|
{applications, [kernel,stdlib,ehttpc]},
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.3.9",[{load_module,emqx_auth_http_app,brutal_purge,soft_purge,[]}]},
|
[{"4.3.10",
|
||||||
|
[{load_module,emqx_auth_http,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_http,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.9",
|
||||||
|
[{load_module,emqx_auth_http,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_http,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_http_app,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.8",
|
{"4.3.8",
|
||||||
[{load_module,emqx_auth_http_app,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_auth_http_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_http,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_http,brutal_purge,soft_purge,[]},
|
||||||
|
@ -39,7 +45,13 @@
|
||||||
{load_module,emqx_auth_http_cli,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_http_cli,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4.3.[0-1]">>,[{restart_application,emqx_auth_http}]},
|
{<<"4.3.[0-1]">>,[{restart_application,emqx_auth_http}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.3.9",[{load_module,emqx_auth_http_app,brutal_purge,soft_purge,[]}]},
|
[{"4.3.10",
|
||||||
|
[{load_module,emqx_auth_http,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_http,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.9",
|
||||||
|
[{load_module,emqx_auth_http,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_http,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_http_app,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.8",
|
{"4.3.8",
|
||||||
[{load_module,emqx_auth_http_app,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_auth_http_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_http,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_http,brutal_purge,soft_purge,[]},
|
||||||
|
|
|
@ -41,19 +41,20 @@ check(ClientInfo, AuthResult, #{auth := AuthParms = #{path := Path},
|
||||||
{ok, 200, <<"ignore">>} ->
|
{ok, 200, <<"ignore">>} ->
|
||||||
ok;
|
ok;
|
||||||
{ok, 200, Body} ->
|
{ok, 200, Body} ->
|
||||||
|
?LOG(debug, "Auth succeeded from path: ~ts, username: ~ts", [Path, Username]),
|
||||||
IsSuperuser = is_superuser(SuperParams, ClientInfo),
|
IsSuperuser = is_superuser(SuperParams, ClientInfo),
|
||||||
{stop, AuthResult#{is_superuser => IsSuperuser,
|
{stop, AuthResult#{is_superuser => IsSuperuser,
|
||||||
auth_result => success,
|
auth_result => success,
|
||||||
anonymous => false,
|
anonymous => false,
|
||||||
mountpoint => mountpoint(Body, ClientInfo)}};
|
mountpoint => mountpoint(Body, ClientInfo)}};
|
||||||
{ok, Code, _Body} ->
|
{ok, Code, _Body} ->
|
||||||
?LOG(warning, "Deny connection from path: ~s, username: ~ts, http "
|
?LOG(warning, "Deny connection from path: ~ts, username: ~ts, http "
|
||||||
"response code: ~p",
|
"response code: ~p",
|
||||||
[Path, Username, Code]),
|
[Path, Username, Code]),
|
||||||
{stop, AuthResult#{auth_result => http_to_connack_error(Code),
|
{stop, AuthResult#{auth_result => http_to_connack_error(Code),
|
||||||
anonymous => false}};
|
anonymous => false}};
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
?LOG_SENSITIVE(warning, "Deny connection from path: ~s, username: ~ts, due to "
|
?LOG_SENSITIVE(warning, "Deny connection from path: ~ts, username: ~ts, due to "
|
||||||
"request http-server failed: ~0p", [Path, Username, Error]),
|
"request http-server failed: ~0p", [Path, Username, Error]),
|
||||||
%%FIXME later: server_unavailable is not right.
|
%%FIXME later: server_unavailable is not right.
|
||||||
{stop, AuthResult#{auth_result => server_unavailable,
|
{stop, AuthResult#{auth_result => server_unavailable,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_auth_jwt,
|
{application, emqx_auth_jwt,
|
||||||
[{description, "EMQ X Authentication with JWT"},
|
[{description, "EMQ X Authentication with JWT"},
|
||||||
{vsn, "4.4.8"}, % strict semver, bump manually!
|
{vsn, "4.4.9"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_auth_jwt_sup]},
|
{registered, [emqx_auth_jwt_sup]},
|
||||||
{applications, [kernel,stdlib,jose]},
|
{applications, [kernel,stdlib,jose]},
|
||||||
|
|
|
@ -1,38 +1,18 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.4.7",[{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]}]},
|
[{"4.4.8",
|
||||||
{"4.4.6",
|
|
||||||
[{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.5",
|
|
||||||
[{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.4",
|
{<<"4\\.4\\.[2-7]">>,
|
||||||
[{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.3",
|
|
||||||
[{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.2",
|
|
||||||
[{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.4\\.[0-1]">>,[{restart_application,emqx_auth_jwt}]},
|
{<<"4\\.4\\.[0-1]">>,[{restart_application,emqx_auth_jwt}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.4.7",[{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]}]},
|
[{"4.4.8",
|
||||||
{"4.4.6",
|
|
||||||
[{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.5",
|
|
||||||
[{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.4",
|
{<<"4\\.4\\.[2-7]">>,
|
||||||
[{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.3",
|
|
||||||
[{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.2",
|
|
||||||
[{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.4\\.[0-1]">>,[{restart_application,emqx_auth_jwt}]},
|
{<<"4\\.4\\.[0-1]">>,[{restart_application,emqx_auth_jwt}]},
|
||||||
|
|
|
@ -51,8 +51,14 @@ check_auth(ClientInfo, AuthResult, #{from := From, checklists := Checklists}) ->
|
||||||
{error, not_token} ->
|
{error, not_token} ->
|
||||||
ok;
|
ok;
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"Auth from JWT failed, Client: ~p, Reason: ~p",
|
||||||
|
[ClientInfo, Reason]),
|
||||||
{stop, AuthResult#{auth_result => Reason, anonymous => false}};
|
{stop, AuthResult#{auth_result => Reason, anonymous => false}};
|
||||||
{ok, Claims} ->
|
{ok, Claims} ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"Auth from JWT succeeded, Client: ~p",
|
||||||
|
[ClientInfo]),
|
||||||
{stop, maps:merge(AuthResult, verify_claims(Checklists, Claims, ClientInfo))}
|
{stop, maps:merge(AuthResult, verify_claims(Checklists, Claims, ClientInfo))}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -99,13 +99,13 @@ handle_cast(_Msg, State) ->
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
|
||||||
handle_info({timeout, _TRef, refresh}, State = #state{addr = Addr}) ->
|
handle_info({timeout, _TRef, refresh}, State = #state{addr = Addr}) ->
|
||||||
NState = try
|
try
|
||||||
true = ets:insert(?TAB, {remote, request_jwks(Addr)}),
|
true = ets:insert(?TAB, {remote, request_jwks(Addr)})
|
||||||
State
|
catch Err:Reason ->
|
||||||
catch _:_ ->
|
?LOG_SENSITIVE(warning, "Request JWKS failed, jwks_addr: ~p, reason: ~p",
|
||||||
State
|
[Addr, {Err, Reason}])
|
||||||
end,
|
end,
|
||||||
{noreply, reset_timer(NState)};
|
{noreply, reset_timer(State)};
|
||||||
|
|
||||||
handle_info({request_jwks, Options}, State) ->
|
handle_info({request_jwks, Options}, State) ->
|
||||||
Remote = key2jwt_value(jwks_addr, fun request_jwks/1, Options),
|
Remote = key2jwt_value(jwks_addr, fun request_jwks/1, Options),
|
||||||
|
|
|
@ -29,8 +29,16 @@
|
||||||
check_acl(ClientInfo, PubSub, Topic, NoMatchAction, State) ->
|
check_acl(ClientInfo, PubSub, Topic, NoMatchAction, State) ->
|
||||||
case do_check_acl(ClientInfo, PubSub, Topic, NoMatchAction, State) of
|
case do_check_acl(ClientInfo, PubSub, Topic, NoMatchAction, State) of
|
||||||
ok -> ok;
|
ok -> ok;
|
||||||
{stop, allow} -> {stop, allow};
|
{stop, allow} ->
|
||||||
{stop, deny} -> {stop, deny}
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[LDAP] Allow Topic: ~p, Action: ~p for Client: ~p",
|
||||||
|
[Topic, PubSub, ClientInfo]),
|
||||||
|
{stop, allow};
|
||||||
|
{stop, deny} ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[LDAP] Deny Topic: ~p, Action: ~p for Client: ~p",
|
||||||
|
[Topic, PubSub, ClientInfo]),
|
||||||
|
{stop, deny}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
do_check_acl(#{username := <<$$, _/binary>>}, _PubSub, _Topic, _NoMatchAction, _State) ->
|
do_check_acl(#{username := <<$$, _/binary>>}, _PubSub, _Topic, _NoMatchAction, _State) ->
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_auth_ldap,
|
{application, emqx_auth_ldap,
|
||||||
[{description, "EMQ X Authentication/ACL with LDAP"},
|
[{description, "EMQ X Authentication/ACL with LDAP"},
|
||||||
{vsn, "4.3.6"}, % strict semver, bump manually!
|
{vsn, "4.3.7"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_auth_ldap_sup]},
|
{registered, [emqx_auth_ldap_sup]},
|
||||||
{applications, [kernel,stdlib,eldap2,ecpool]},
|
{applications, [kernel,stdlib,eldap2,ecpool]},
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.3.5",
|
[{"4.3.6",
|
||||||
|
[{load_module,emqx_acl_ldap,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_ldap,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.5",
|
||||||
[{load_module,emqx_acl_ldap,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_ldap,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_ldap,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_ldap,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_ldap_cli,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_ldap_cli,brutal_purge,soft_purge,[]}]},
|
||||||
|
@ -21,7 +24,10 @@
|
||||||
{load_module,emqx_acl_ldap,brutal_purge,soft_purge,[]},
|
{load_module,emqx_acl_ldap,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_ldap_cli,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_ldap_cli,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.3.5",
|
[{"4.3.6",
|
||||||
|
[{load_module,emqx_acl_ldap,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_ldap,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.5",
|
||||||
[{load_module,emqx_acl_ldap,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_ldap,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_ldap,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_ldap,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_ldap_cli,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_ldap_cli,brutal_purge,soft_purge,[]}]},
|
||||||
|
|
|
@ -58,6 +58,9 @@ check(ClientInfo = #{username := Username, password := Password}, AuthResult,
|
||||||
end,
|
end,
|
||||||
case CheckResult of
|
case CheckResult of
|
||||||
ok ->
|
ok ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[LDAP] Auth from ldap succeeded, Client: ~p",
|
||||||
|
[ClientInfo]),
|
||||||
{stop, AuthResult#{auth_result => success, anonymous => false}};
|
{stop, AuthResult#{auth_result => success, anonymous => false}};
|
||||||
{error, not_found} ->
|
{error, not_found} ->
|
||||||
ok;
|
ok;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
-module(emqx_acl_mnesia).
|
-module(emqx_acl_mnesia).
|
||||||
|
|
||||||
-include("emqx_auth_mnesia.hrl").
|
-include("emqx_auth_mnesia.hrl").
|
||||||
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
|
||||||
%% ACL Callbacks
|
%% ACL Callbacks
|
||||||
-export([ init/0
|
-export([ init/0
|
||||||
|
@ -43,8 +44,14 @@ check_acl(ClientInfo = #{ clientid := Clientid }, PubSub, Topic, _NoMatchAction,
|
||||||
|
|
||||||
case match(ClientInfo, PubSub, Topic, Acls) of
|
case match(ClientInfo, PubSub, Topic, Acls) of
|
||||||
allow ->
|
allow ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[Mnesia] Allow Topic: ~p, Action: ~p for Client: ~p",
|
||||||
|
[Topic, PubSub, ClientInfo]),
|
||||||
{stop, allow};
|
{stop, allow};
|
||||||
deny ->
|
deny ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[Mnesia] Deny Topic: ~p, Action: ~p for Client: ~p",
|
||||||
|
[Topic, PubSub, ClientInfo]),
|
||||||
{stop, deny};
|
{stop, deny};
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_auth_mnesia,
|
{application, emqx_auth_mnesia,
|
||||||
[{description, "EMQ X Authentication with Mnesia"},
|
[{description, "EMQ X Authentication with Mnesia"},
|
||||||
{vsn, "4.3.10"}, % strict semver, bump manually
|
{vsn, "4.3.11"}, % strict semver, bump manually
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{applications, [kernel,stdlib,mnesia]},
|
{applications, [kernel,stdlib,mnesia]},
|
||||||
|
|
|
@ -1,13 +1,25 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.3.9",[{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
[{"4.3.10",
|
||||||
{"4.3.8",[{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
[{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.9",
|
||||||
|
[{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.8",
|
||||||
|
[{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.7",
|
{"4.3.7",
|
||||||
[{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.3\\.[5-6]">>,
|
{<<"4\\.3\\.[5-6]">>,
|
||||||
[{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_acl_mnesia_db,brutal_purge,soft_purge,[]},
|
{load_module,emqx_acl_mnesia_db,brutal_purge,soft_purge,[]},
|
||||||
|
@ -35,13 +47,25 @@
|
||||||
{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]},
|
{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.3.9",[{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
[{"4.3.10",
|
||||||
{"4.3.8",[{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
[{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.9",
|
||||||
|
[{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.8",
|
||||||
|
[{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.7",
|
{"4.3.7",
|
||||||
[{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.3\\.[5-6]">>,
|
{<<"4\\.3\\.[5-6]">>,
|
||||||
[{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_acl_mnesia_db,brutal_purge,soft_purge,[]},
|
{load_module,emqx_acl_mnesia_db,brutal_purge,soft_purge,[]},
|
||||||
|
|
|
@ -70,6 +70,9 @@ check(ClientInfo = #{ clientid := Clientid
|
||||||
?LOG(info, "[Mnesia] Auth from mnesia failed: ~p", [Info]),
|
?LOG(info, "[Mnesia] Auth from mnesia failed: ~p", [Info]),
|
||||||
{stop, AuthResult#{anonymous => false, auth_result => password_error}};
|
{stop, AuthResult#{anonymous => false, auth_result => password_error}};
|
||||||
_ ->
|
_ ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[Mnesia] Auth from mnesia succeeded, Client: ~p",
|
||||||
|
[ClientInfo]),
|
||||||
{stop, AuthResult#{anonymous => false, auth_result => success}}
|
{stop, AuthResult#{anonymous => false, auth_result => success}}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -38,8 +38,16 @@ check_acl(ClientInfo, PubSub, Topic, _AclResult, Env = #{aclquery := AclQuery})
|
||||||
[] -> ok;
|
[] -> ok;
|
||||||
Rows ->
|
Rows ->
|
||||||
try match(ClientInfo, Topic, topics(PubSub, Rows)) of
|
try match(ClientInfo, Topic, topics(PubSub, Rows)) of
|
||||||
matched -> {stop, allow};
|
matched ->
|
||||||
nomatch -> {stop, deny}
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[MongoDB] Allow Topic: ~p, Action: ~p for Client: ~p",
|
||||||
|
[Topic, PubSub, ClientInfo]),
|
||||||
|
{stop, allow};
|
||||||
|
nomatch ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[MongoDB] Deny Topic: ~p, Action: ~p for Client: ~p",
|
||||||
|
[Topic, PubSub, ClientInfo]),
|
||||||
|
{stop, deny}
|
||||||
catch
|
catch
|
||||||
_Err:Reason->
|
_Err:Reason->
|
||||||
?LOG(error, "[MongoDB] Check mongo ~p ACL failed, got ACL config: ~p, error: :~p",
|
?LOG(error, "[MongoDB] Check mongo ~p ACL failed, got ACL config: ~p, error: :~p",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_auth_mongo,
|
{application, emqx_auth_mongo,
|
||||||
[{description, "EMQ X Authentication/ACL with MongoDB"},
|
[{description, "EMQ X Authentication/ACL with MongoDB"},
|
||||||
{vsn, "4.4.5"}, % strict semver, bump manually!
|
{vsn, "4.4.6"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_auth_mongo_sup]},
|
{registered, [emqx_auth_mongo_sup]},
|
||||||
{applications, [kernel,stdlib,mongodb,ecpool]},
|
{applications, [kernel,stdlib,mongodb,ecpool]},
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.4.4",[{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
[{"4.4.5",
|
||||||
|
[{load_module,emqx_acl_mongo,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.4.4",
|
||||||
|
[{load_module,emqx_acl_mongo,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.4\\.[2-3]">>,
|
{<<"4\\.4\\.[2-3]">>,
|
||||||
[{load_module,emqx_auth_mongo_app,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_mongo,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mongo_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.1",
|
{"4.4.1",
|
||||||
[{load_module,emqx_auth_mongo_app,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_mongo,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mongo_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mongo_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mongo_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.0",
|
{"4.4.0",
|
||||||
|
@ -15,12 +22,19 @@
|
||||||
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_acl_mongo,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_acl_mongo,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.4.4",[{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
[{"4.4.5",
|
||||||
{<<"4\\.4\\.[2-3]">>,
|
[{load_module,emqx_acl_mongo,brutal_purge,soft_purge,[]},
|
||||||
[{load_module,emqx_auth_mongo_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.4.4",
|
||||||
|
[{load_module,emqx_acl_mongo,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
||||||
|
{<<"4\\.4\\.[2-3]">>,
|
||||||
|
[{load_module,emqx_acl_mongo,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mongo_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.1",
|
{"4.4.1",
|
||||||
[{load_module,emqx_auth_mongo_app,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_mongo,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mongo_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mongo_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mongo_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_mongo,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.0",
|
{"4.4.0",
|
||||||
|
|
|
@ -68,6 +68,9 @@ check(ClientInfo = #{password := Password}, AuthResult,
|
||||||
case Result of
|
case Result of
|
||||||
ok ->
|
ok ->
|
||||||
?tp(emqx_auth_mongo_superuser_check_authn_ok, #{}),
|
?tp(emqx_auth_mongo_superuser_check_authn_ok, #{}),
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[MongoDB] Auth from mongo succeeded, Client: ~p",
|
||||||
|
[ClientInfo]),
|
||||||
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
||||||
anonymous => false,
|
anonymous => false,
|
||||||
auth_result => success}};
|
auth_result => success}};
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
{deps,
|
{deps, []}.
|
||||||
[
|
|
||||||
{mysql, {git, "https://github.com/emqx/mysql-otp", {tag, "1.7.1"}}}
|
|
||||||
]}.
|
|
||||||
|
|
||||||
{edoc_opts, [{preprocess, true}]}.
|
{edoc_opts, [{preprocess, true}]}.
|
||||||
{erl_opts, [warn_unused_vars,
|
{erl_opts, [warn_unused_vars,
|
||||||
|
|
|
@ -29,8 +29,16 @@
|
||||||
check_acl(ClientInfo, PubSub, Topic, NoMatchAction, #{pool := Pool} = State) ->
|
check_acl(ClientInfo, PubSub, Topic, NoMatchAction, #{pool := Pool} = State) ->
|
||||||
case do_check_acl(Pool, ClientInfo, PubSub, Topic, NoMatchAction, State) of
|
case do_check_acl(Pool, ClientInfo, PubSub, Topic, NoMatchAction, State) of
|
||||||
ok -> ok;
|
ok -> ok;
|
||||||
{stop, allow} -> {stop, allow};
|
{stop, allow} ->
|
||||||
{stop, deny} -> {stop, deny}
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[MySQL] Allow Topic: ~p, Action: ~p for Client: ~p",
|
||||||
|
[Topic, PubSub, ClientInfo]),
|
||||||
|
{stop, allow};
|
||||||
|
{stop, deny} ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[MySQL] Allow Topic: ~p, Action: ~p for Client: ~p",
|
||||||
|
[Topic, PubSub, ClientInfo]),
|
||||||
|
{stop, deny}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
do_check_acl(_Pool, #{username := <<$$, _/binary>>}, _PubSub, _Topic, _NoMatchAction, _State) ->
|
do_check_acl(_Pool, #{username := <<$$, _/binary>>}, _PubSub, _Topic, _NoMatchAction, _State) ->
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_auth_mysql,
|
{application, emqx_auth_mysql,
|
||||||
[{description, "EMQ X Authentication/ACL with MySQL"},
|
[{description, "EMQ X Authentication/ACL with MySQL"},
|
||||||
{vsn, "4.3.4"}, % strict semver, bump manually!
|
{vsn, "4.3.5"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_auth_mysql_sup]},
|
{registered, [emqx_auth_mysql_sup]},
|
||||||
{applications, [kernel,stdlib,mysql,ecpool]},
|
{applications, [kernel,stdlib,mysql,ecpool]},
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.3.3",
|
[{"4.3.4",
|
||||||
[{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mysql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mysql_cli,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.3",
|
||||||
|
[{load_module,emqx_acl_mysql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mysql_cli,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_mysql_cli,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.3\\.[1-2]">>,
|
{<<"4\\.3\\.[1-2]">>,
|
||||||
[{load_module,emqx_auth_mysql_cli,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_mysql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mysql_cli,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mysql_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mysql_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.0",
|
{"4.3.0",
|
||||||
|
@ -13,11 +20,17 @@
|
||||||
{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_acl_mysql,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_acl_mysql,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.3.3",
|
[{"4.3.4",
|
||||||
[{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_acl_mysql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mysql_cli,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.3",
|
||||||
|
[{load_module,emqx_acl_mysql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mysql_cli,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_mysql_cli,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.3\\.[1-2]">>,
|
{<<"4\\.3\\.[1-2]">>,
|
||||||
[{load_module,emqx_auth_mysql_cli,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_mysql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_mysql_cli,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mysql_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mysql_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.0",
|
{"4.3.0",
|
||||||
|
@ -25,5 +38,4 @@
|
||||||
{load_module,emqx_auth_mysql_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mysql_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_acl_mysql,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_acl_mysql,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}]
|
{<<".*">>,[]}]}.
|
||||||
}.
|
|
||||||
|
|
|
@ -46,6 +46,9 @@ check(ClientInfo = #{password := Password}, AuthResult,
|
||||||
end,
|
end,
|
||||||
case CheckPass of
|
case CheckPass of
|
||||||
ok ->
|
ok ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[MySQL] Auth from mysql succeeded, Client: ~p",
|
||||||
|
[ClientInfo]),
|
||||||
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
||||||
anonymous => false,
|
anonymous => false,
|
||||||
auth_result => success}};
|
auth_result => success}};
|
||||||
|
|
|
@ -36,9 +36,17 @@ do_check_acl(Pool, ClientInfo, PubSub, Topic, _NoMatchAction, #{acl_query := {Ac
|
||||||
{ok, _, Rows} ->
|
{ok, _, Rows} ->
|
||||||
Rules = filter(PubSub, compile(Rows)),
|
Rules = filter(PubSub, compile(Rows)),
|
||||||
case match(ClientInfo, Topic, Rules) of
|
case match(ClientInfo, Topic, Rules) of
|
||||||
{matched, allow} -> {stop, allow};
|
{matched, allow} ->
|
||||||
{matched, deny} -> {stop, deny};
|
?LOG_SENSITIVE(debug,
|
||||||
nomatch -> ok
|
"[Postgres] Allow Topic: ~p, Action: ~p for Client: ~p",
|
||||||
|
[Topic, PubSub, ClientInfo]),
|
||||||
|
{stop, allow};
|
||||||
|
{matched, deny} ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[Postgres] Deny Topic: ~p, Action: ~p for Client: ~p",
|
||||||
|
[Topic, PubSub, ClientInfo]),
|
||||||
|
{stop, deny};
|
||||||
|
nomatch -> ok
|
||||||
end;
|
end;
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
?LOG(error, "[Postgres] do_check_acl error: ~p~n", [Reason]),
|
?LOG(error, "[Postgres] do_check_acl error: ~p~n", [Reason]),
|
||||||
|
@ -105,4 +113,3 @@ empty(null) -> true;
|
||||||
empty("") -> true;
|
empty("") -> true;
|
||||||
empty(<<>>) -> true;
|
empty(<<>>) -> true;
|
||||||
empty(_) -> false.
|
empty(_) -> false.
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_auth_pgsql,
|
{application, emqx_auth_pgsql,
|
||||||
[{description, "EMQ X Authentication/ACL with PostgreSQL"},
|
[{description, "EMQ X Authentication/ACL with PostgreSQL"},
|
||||||
{vsn, "4.4.4"}, % strict semver, bump manually!
|
{vsn, "4.4.5"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_auth_pgsql_sup]},
|
{registered, [emqx_auth_pgsql_sup]},
|
||||||
{applications, [kernel,stdlib,epgsql,ecpool]},
|
{applications, [kernel,stdlib,epgsql,ecpool]},
|
||||||
|
|
|
@ -1,20 +1,29 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.4.3",
|
[{"4.4.4",
|
||||||
[{load_module,emqx_auth_pgsql_cli,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_pgsql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_pgsql,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.4.3",
|
||||||
|
[{load_module,emqx_acl_pgsql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_pgsql_cli,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_pgsql,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_pgsql,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.4\\.[0-2]">>,
|
{<<"4\\.4\\.[0-2]">>,
|
||||||
[{load_module,emqx_auth_pgsql_cli,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_pgsql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_pgsql_cli,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_pgsql,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_pgsql,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_pgsql_app,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_pgsql_app,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.4.3",
|
[{"4.4.4",
|
||||||
[{load_module,emqx_auth_pgsql_cli,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_pgsql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_pgsql,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.4.3",
|
||||||
|
[{load_module,emqx_acl_pgsql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_pgsql_cli,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_pgsql,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_pgsql,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.4\\.[0-2]">>,
|
{<<"4\\.4\\.[0-2]">>,
|
||||||
[{load_module,emqx_auth_pgsql_cli,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_pgsql,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_pgsql_cli,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_pgsql,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_pgsql,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_pgsql_app,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_pgsql_app,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}]}.
|
{<<".*">>,[]}]}.
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,9 @@ check(ClientInfo = #{password := Password}, AuthResult,
|
||||||
end,
|
end,
|
||||||
case CheckPass of
|
case CheckPass of
|
||||||
ok ->
|
ok ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[Postgres] Auth from pgsql succeeded, Client: ~p",
|
||||||
|
[ClientInfo]),
|
||||||
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
||||||
anonymous => false,
|
anonymous => false,
|
||||||
auth_result => success}};
|
auth_result => success}};
|
||||||
|
|
|
@ -33,8 +33,16 @@ check_acl(ClientInfo, PubSub, Topic, _AclResult,
|
||||||
{ok, []} -> ok;
|
{ok, []} -> ok;
|
||||||
{ok, Rules} ->
|
{ok, Rules} ->
|
||||||
case match(ClientInfo, PubSub, Topic, Rules) of
|
case match(ClientInfo, PubSub, Topic, Rules) of
|
||||||
allow -> {stop, allow};
|
allow ->
|
||||||
nomatch -> {stop, deny}
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[Redis] Allow Topic: ~p, Action: ~p for Client: ~p",
|
||||||
|
[Topic, PubSub, ClientInfo]),
|
||||||
|
{stop, allow};
|
||||||
|
nomatch ->
|
||||||
|
?LOG_SENSITIVE(debug,
|
||||||
|
"[Redis] Deny Topic: ~p, Action: ~p for Client: ~p",
|
||||||
|
[Topic, PubSub, ClientInfo]),
|
||||||
|
{stop, deny}
|
||||||
end;
|
end;
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
?LOG(error, "[Redis] do_check_acl error: ~p", [Reason]),
|
?LOG(error, "[Redis] do_check_acl error: ~p", [Reason]),
|
||||||
|
@ -71,4 +79,3 @@ feed_var(Str, Var, Val) ->
|
||||||
b2i(Bin) -> list_to_integer(binary_to_list(Bin)).
|
b2i(Bin) -> list_to_integer(binary_to_list(Bin)).
|
||||||
|
|
||||||
description() -> "Redis ACL Module".
|
description() -> "Redis ACL Module".
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_auth_redis,
|
{application, emqx_auth_redis,
|
||||||
[{description, "EMQ X Authentication/ACL with Redis"},
|
[{description, "EMQ X Authentication/ACL with Redis"},
|
||||||
{vsn, "4.3.4"}, % strict semver, bump manually!
|
{vsn, "4.3.5"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_auth_redis_sup]},
|
{registered, [emqx_auth_redis_sup]},
|
||||||
{applications, [kernel,stdlib,eredis,eredis_cluster,ecpool]},
|
{applications, [kernel,stdlib,eredis,eredis_cluster,ecpool]},
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.3.3",
|
[{"4.3.4",
|
||||||
[{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_redis,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.3",
|
||||||
|
[{load_module,emqx_acl_redis,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_redis_cli,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_redis_cli,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.3\\.[1-2]">>,
|
{<<"4\\.3\\.[1-2]">>,
|
||||||
[{load_module,emqx_auth_redis_cli,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_redis,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_redis_cli,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_redis_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_redis_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.0",
|
{"4.3.0",
|
||||||
|
@ -14,11 +18,15 @@
|
||||||
{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_acl_redis,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_acl_redis,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.3.3",
|
[{"4.3.4",
|
||||||
[{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_redis,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.3",
|
||||||
|
[{load_module,emqx_acl_redis,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_redis_cli,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_redis_cli,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.3\\.[1-2]">>,
|
{<<"4\\.3\\.[1-2]">>,
|
||||||
[{load_module,emqx_auth_redis_cli,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_acl_redis,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_auth_redis_cli,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_redis_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_redis_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.3.0",
|
{"4.3.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_bridge_mqtt,
|
{application, emqx_bridge_mqtt,
|
||||||
[{description, "EMQ X Bridge to MQTT Broker"},
|
[{description, "EMQ X Bridge to MQTT Broker"},
|
||||||
{vsn, "4.3.7"}, % strict semver, bump manually!
|
{vsn, "4.3.8"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{applications, [kernel,stdlib,replayq,emqtt]},
|
{applications, [kernel,stdlib,replayq,emqtt]},
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.3.6",
|
[{"4.3.7",
|
||||||
|
[{load_module,emqx_bridge_mqtt_actions,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.6",
|
||||||
[{load_module,emqx_bridge_connect,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_bridge_connect,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_bridge_mqtt_actions,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_bridge_mqtt_actions,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.3\\.[4-5]">>,
|
{<<"4\\.3\\.[4-5]">>,
|
||||||
|
@ -21,7 +23,9 @@
|
||||||
{load_module,emqx_bridge_worker,brutal_purge,soft_purge,[]},
|
{load_module,emqx_bridge_worker,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_bridge_mqtt_actions,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_bridge_mqtt_actions,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.3.6",
|
[{"4.3.7",
|
||||||
|
[{load_module,emqx_bridge_mqtt_actions,brutal_purge,soft_purge,[]}]},
|
||||||
|
{"4.3.6",
|
||||||
[{load_module,emqx_bridge_connect,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_bridge_connect,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_bridge_mqtt_actions,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_bridge_mqtt_actions,brutal_purge,soft_purge,[]}]},
|
||||||
{<<"4\\.3\\.[4-5]">>,
|
{<<"4\\.3\\.[4-5]">>,
|
||||||
|
|
|
@ -111,11 +111,11 @@
|
||||||
zh => <<"桥接挂载点"/utf8>>},
|
zh => <<"桥接挂载点"/utf8>>},
|
||||||
description => #{
|
description => #{
|
||||||
en => <<"MountPoint for bridge topic:<br/>"
|
en => <<"MountPoint for bridge topic:<br/>"
|
||||||
"Example: The topic of messages sent to `topic1` on local node "
|
"Example: The topic of messages sent to <code>topic1</code> on local node "
|
||||||
"will be transformed to `bridge/aws/${node}/topic1`">>,
|
"will be transformed to <code>bridge/aws/${node}/topic1</code>">>,
|
||||||
zh => <<"桥接主题的挂载点:<br/>"
|
zh => <<"桥接主题的挂载点:<br/>"
|
||||||
"示例: 本地节点向 `topic1` 发消息,远程桥接节点的主题"
|
"示例: 本地节点向 <code>topic1</code> 发消息,远程桥接节点的主题"
|
||||||
"会变换为 `bridge/aws/${node}/topic1`"/utf8>>
|
"会变换为 <code>bridge/aws/${node}/topic1</code>"/utf8>>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
disk_cache => #{
|
disk_cache => #{
|
||||||
|
@ -267,10 +267,10 @@
|
||||||
type => string,
|
type => string,
|
||||||
required => true,
|
required => true,
|
||||||
default => <<"emqx2@127.0.0.1">>,
|
default => <<"emqx2@127.0.0.1">>,
|
||||||
title => #{en => <<"EMQ X Node Name">>,
|
title => #{en => <<"EMQX Node Name">>,
|
||||||
zh => <<"EMQ X 节点名称"/utf8>>},
|
zh => <<"EMQX 节点名称"/utf8>>},
|
||||||
description => #{en => <<"EMQ X Remote Node Name">>,
|
description => #{en => <<"EMQX Remote Node Name">>,
|
||||||
zh => <<"远程 EMQ X 节点名称 "/utf8>>}
|
zh => <<"远程 EMQX 节点名称 "/utf8>>}
|
||||||
},
|
},
|
||||||
mountpoint => #{
|
mountpoint => #{
|
||||||
order => 2,
|
order => 2,
|
||||||
|
@ -280,11 +280,11 @@
|
||||||
title => #{en => <<"Bridge MountPoint">>,
|
title => #{en => <<"Bridge MountPoint">>,
|
||||||
zh => <<"桥接挂载点"/utf8>>},
|
zh => <<"桥接挂载点"/utf8>>},
|
||||||
description => #{en => <<"MountPoint for bridge topic<br/>"
|
description => #{en => <<"MountPoint for bridge topic<br/>"
|
||||||
"Example: The topic of messages sent to `topic1` on local node "
|
"Example: The topic of messages sent to <code>topic1</code> on local node "
|
||||||
"will be transformed to `bridge/aws/${node}/topic1`">>,
|
"will be transformed to <code>bridge/emqx/${node}/topic1</code>">>,
|
||||||
zh => <<"桥接主题的挂载点<br/>"
|
zh => <<"桥接主题的挂载点<br/>"
|
||||||
"示例: 本地节点向 `topic1` 发消息,远程桥接节点的主题"
|
"示例: 本地节点向 <code>topic1</code> 发消息,远程桥接节点的主题"
|
||||||
"会变换为 `bridge/aws/${node}/topic1`"/utf8>>}
|
"会变换为 <code>bridge/emqx/${node}/topic1</code>"/utf8>>}
|
||||||
},
|
},
|
||||||
pool_size => #{
|
pool_size => #{
|
||||||
order => 3,
|
order => 3,
|
||||||
|
@ -358,7 +358,7 @@
|
||||||
destroy => on_resource_destroy,
|
destroy => on_resource_destroy,
|
||||||
params => ?RESOURCE_CONFIG_SPEC_RPC,
|
params => ?RESOURCE_CONFIG_SPEC_RPC,
|
||||||
title => #{en => <<"EMQX Bridge">>, zh => <<"EMQX Bridge"/utf8>>},
|
title => #{en => <<"EMQX Bridge">>, zh => <<"EMQX Bridge"/utf8>>},
|
||||||
description => #{en => <<"EMQ X RPC Bridge">>, zh => <<"EMQ X RPC 消息桥接"/utf8>>}
|
description => #{en => <<"EMQX RPC Bridge">>, zh => <<"EMQX RPC 消息桥接"/utf8>>}
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-rule_action(#{
|
-rule_action(#{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{deps,
|
{deps,
|
||||||
[
|
[
|
||||||
{gen_coap, {git, "https://github.com/emqx/gen_coap", {tag, "v0.4.2"}}}
|
{gen_coap, {git, "https://github.com/emqx/gen_coap", {tag, "v0.4.3"}}}
|
||||||
]}.
|
]}.
|
||||||
|
|
|
@ -90,6 +90,11 @@
|
||||||
{datatype, {enum, [true, false]}}
|
{datatype, {enum, [true, false]}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
{mapping, "management.listener.http.proxy_header", "emqx_management.listeners", [
|
||||||
|
{default, false},
|
||||||
|
{datatype, {enum, [true, false]}}
|
||||||
|
]}.
|
||||||
|
|
||||||
{mapping, "management.listener.https", "emqx_management.listeners", [
|
{mapping, "management.listener.https", "emqx_management.listeners", [
|
||||||
{datatype, [integer, ip]}
|
{datatype, [integer, ip]}
|
||||||
]}.
|
]}.
|
||||||
|
@ -186,6 +191,11 @@
|
||||||
{datatype, {enum, [true, false]}}
|
{datatype, {enum, [true, false]}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
{mapping, "management.listener.https.proxy_header", "emqx_management.listeners", [
|
||||||
|
{default, false},
|
||||||
|
{datatype, {enum, [true, false]}}
|
||||||
|
]}.
|
||||||
|
|
||||||
{translation, "emqx_management.application", fun(Conf) ->
|
{translation, "emqx_management.application", fun(Conf) ->
|
||||||
Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
|
Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
|
||||||
Opts = fun(Prefix) ->
|
Opts = fun(Prefix) ->
|
||||||
|
@ -202,7 +212,9 @@ end}.
|
||||||
Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
|
Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
|
||||||
Opts = fun(Prefix) ->
|
Opts = fun(Prefix) ->
|
||||||
Filter([{num_acceptors, cuttlefish:conf_get(Prefix ++ ".acceptors", Conf)},
|
Filter([{num_acceptors, cuttlefish:conf_get(Prefix ++ ".acceptors", Conf)},
|
||||||
{max_connections, cuttlefish:conf_get(Prefix ++ ".max_clients", Conf)}])
|
{max_connections, cuttlefish:conf_get(Prefix ++ ".max_clients", Conf)},
|
||||||
|
{proxy_header, cuttlefish:conf_get(Prefix ++ ".proxy_header", Conf)}
|
||||||
|
])
|
||||||
end,
|
end,
|
||||||
TcpOpts = fun(Prefix) ->
|
TcpOpts = fun(Prefix) ->
|
||||||
Filter([{backlog, cuttlefish:conf_get(Prefix ++ ".backlog", Conf, undefined)},
|
Filter([{backlog, cuttlefish:conf_get(Prefix ++ ".backlog", Conf, undefined)},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_management,
|
{application, emqx_management,
|
||||||
[{description, "EMQ X Management API and CLI"},
|
[{description, "EMQ X Management API and CLI"},
|
||||||
{vsn, "4.4.12"}, % strict semver, bump manually!
|
{vsn, "4.4.13"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_management_sup]},
|
{registered, [emqx_management_sup]},
|
||||||
{applications, [kernel,stdlib,emqx_plugin_libs,minirest]},
|
{applications, [kernel,stdlib,emqx_plugin_libs,minirest]},
|
||||||
|
|
|
@ -167,7 +167,7 @@ cluster_query(Params, {Tab, QsSchema}, QueryFun) ->
|
||||||
Start = if Page > 1 -> (Page-1) * Limit;
|
Start = if Page > 1 -> (Page-1) * Limit;
|
||||||
true -> 0
|
true -> 0
|
||||||
end,
|
end,
|
||||||
Nodes = ekka_mnesia:running_nodes(),
|
Nodes = lists:sort(ekka_mnesia:running_nodes()),
|
||||||
Rows = do_cluster_query(Nodes, Qs, QueryFun, Start, Limit+1, []),
|
Rows = do_cluster_query(Nodes, Qs, QueryFun, Start, Limit+1, []),
|
||||||
Meta = #{page => Page, limit => Limit},
|
Meta = #{page => Page, limit => Limit},
|
||||||
NMeta = case CodCnt =:= 0 of
|
NMeta = case CodCnt =:= 0 of
|
||||||
|
|
|
@ -52,12 +52,12 @@ stop_listeners() ->
|
||||||
start_listener({Proto, Port, Options}) when Proto == http ->
|
start_listener({Proto, Port, Options}) when Proto == http ->
|
||||||
Dispatch = [{"/status", emqx_mgmt_http, []},
|
Dispatch = [{"/status", emqx_mgmt_http, []},
|
||||||
{"/api/v4/[...]", minirest, http_handlers()}],
|
{"/api/v4/[...]", minirest, http_handlers()}],
|
||||||
minirest:start_http(listener_name(Proto), ranch_opts(Port, Options), Dispatch);
|
minirest:start_http(listener_name(Proto), ranch_opts(Port, Options), Dispatch, proto_opts(Options));
|
||||||
|
|
||||||
start_listener({Proto, Port, Options}) when Proto == https ->
|
start_listener({Proto, Port, Options}) when Proto == https ->
|
||||||
Dispatch = [{"/status", emqx_mgmt_http, []},
|
Dispatch = [{"/status", emqx_mgmt_http, []},
|
||||||
{"/api/v4/[...]", minirest, http_handlers()}],
|
{"/api/v4/[...]", minirest, http_handlers()}],
|
||||||
minirest:start_https(listener_name(Proto), ranch_opts(Port, Options), Dispatch).
|
minirest:start_https(listener_name(Proto), ranch_opts(Port, Options), Dispatch, proto_opts(Options)).
|
||||||
|
|
||||||
ranch_opts(Port, Options0) ->
|
ranch_opts(Port, Options0) ->
|
||||||
NumAcceptors = proplists:get_value(num_acceptors, Options0, 4),
|
NumAcceptors = proplists:get_value(num_acceptors, Options0, 4),
|
||||||
|
@ -68,6 +68,7 @@ ranch_opts(Port, Options0) ->
|
||||||
({inet6, false}, Acc) -> Acc;
|
({inet6, false}, Acc) -> Acc;
|
||||||
({ipv6_v6only, true}, Acc) -> [{ipv6_v6only, true} | Acc];
|
({ipv6_v6only, true}, Acc) -> [{ipv6_v6only, true} | Acc];
|
||||||
({ipv6_v6only, false}, Acc) -> Acc;
|
({ipv6_v6only, false}, Acc) -> Acc;
|
||||||
|
({proxy_header, _}, Acc) -> Acc;
|
||||||
({K, V}, Acc)->
|
({K, V}, Acc)->
|
||||||
[{K, V} | Acc]
|
[{K, V} | Acc]
|
||||||
end, [], Options0),
|
end, [], Options0),
|
||||||
|
@ -77,6 +78,9 @@ ranch_opts(Port, Options0) ->
|
||||||
socket_opts => [{port, Port} | Options]},
|
socket_opts => [{port, Port} | Options]},
|
||||||
Res.
|
Res.
|
||||||
|
|
||||||
|
proto_opts(Options) ->
|
||||||
|
maps:with([proxy_header], maps:from_list(Options)).
|
||||||
|
|
||||||
stop_listener({Proto, Port, _}) ->
|
stop_listener({Proto, Port, _}) ->
|
||||||
io:format("Stop http:management listener on ~s successfully.~n",[format(Port)]),
|
io:format("Stop http:management listener on ~s successfully.~n",[format(Port)]),
|
||||||
minirest:stop_http(listener_name(Proto)).
|
minirest:stop_http(listener_name(Proto)).
|
||||||
|
|
|
@ -794,13 +794,7 @@ t_keepalive(_Config) ->
|
||||||
Path = api_path(["clients", ClientId, "keepalive"]),
|
Path = api_path(["clients", ClientId, "keepalive"]),
|
||||||
{ok, NotFound} = request_api(put, Path, "interval=5", AuthHeader, [#{}]),
|
{ok, NotFound} = request_api(put, Path, "interval=5", AuthHeader, [#{}]),
|
||||||
?assertEqual("{\"message\":\"not_found\",\"code\":112}", NotFound),
|
?assertEqual("{\"message\":\"not_found\",\"code\":112}", NotFound),
|
||||||
{ok, C1} = emqtt:start_link(#{username => Username, clientid => ClientId}),
|
C1 = keepalive_ok(61, 0, Username, ClientId, Path, AuthHeader),
|
||||||
{ok, _} = emqtt:connect(C1),
|
|
||||||
{ok, Ok} = request_api(put, Path, "interval=5", AuthHeader, [#{}]),
|
|
||||||
?assertEqual("{\"code\":0}", Ok),
|
|
||||||
[Pid] = emqx_cm:lookup_channels(list_to_binary(ClientId)),
|
|
||||||
#{conninfo := #{keepalive := Keepalive}} = emqx_connection:info(Pid),
|
|
||||||
?assertEqual(5, Keepalive),
|
|
||||||
{ok, Error1} = request_api(put, Path, "interval=-1", AuthHeader, [#{}]),
|
{ok, Error1} = request_api(put, Path, "interval=-1", AuthHeader, [#{}]),
|
||||||
{ok, Error2} = request_api(put, Path, "interval=65536", AuthHeader, [#{}]),
|
{ok, Error2} = request_api(put, Path, "interval=65536", AuthHeader, [#{}]),
|
||||||
ErrMsg = #{<<"code">> => 102,
|
ErrMsg = #{<<"code">> => 102,
|
||||||
|
@ -808,9 +802,26 @@ t_keepalive(_Config) ->
|
||||||
?assertEqual(ErrMsg, jiffy:decode(Error1, [return_maps])),
|
?assertEqual(ErrMsg, jiffy:decode(Error1, [return_maps])),
|
||||||
?assertEqual(Error1, Error2),
|
?assertEqual(Error1, Error2),
|
||||||
emqtt:disconnect(C1),
|
emqtt:disconnect(C1),
|
||||||
|
%% test change keepalive from 0 to 60
|
||||||
|
C2 = keepalive_ok(0, 60, Username, ClientId, Path, AuthHeader),
|
||||||
|
emqtt:disconnect(C2),
|
||||||
|
%% test change keepalive from 60 to 0
|
||||||
|
C3 = keepalive_ok(60, 0, Username, ClientId, Path, AuthHeader),
|
||||||
|
emqtt:disconnect(C3),
|
||||||
application:stop(emqx_dashboard),
|
application:stop(emqx_dashboard),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
keepalive_ok(InitSec, UpdateSec, Username, ClientId, Path, AuthHeader) ->
|
||||||
|
{ok, C1} = emqtt:start_link(#{username => Username, clientid => ClientId, keepalive => InitSec}),
|
||||||
|
{ok, _} = emqtt:connect(C1),
|
||||||
|
Qs = "interval=" ++ integer_to_list(UpdateSec),
|
||||||
|
{ok, Ok} = request_api(put, Path, Qs, AuthHeader, [#{}]),
|
||||||
|
?assertEqual("{\"code\":0}", Ok),
|
||||||
|
[Pid] = emqx_cm:lookup_channels(list_to_binary(ClientId)),
|
||||||
|
#{conninfo := #{keepalive := Keepalive}} = emqx_connection:info(Pid),
|
||||||
|
?assertEqual(UpdateSec, Keepalive),
|
||||||
|
C1.
|
||||||
|
|
||||||
t_status_ok(_Config) ->
|
t_status_ok(_Config) ->
|
||||||
{ok, #{ body := Resp
|
{ok, #{ body := Resp
|
||||||
, status_code := StatusCode
|
, status_code := StatusCode
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_prometheus,
|
{application, emqx_prometheus,
|
||||||
[{description, "Prometheus for EMQ X"},
|
[{description, "Prometheus for EMQ X"},
|
||||||
{vsn, "4.3.1"}, % strict semver, bump manually!
|
{vsn, "4.3.2"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_prometheus_sup]},
|
{registered, [emqx_prometheus_sup]},
|
||||||
{applications, [kernel,stdlib,prometheus]},
|
{applications, [kernel,stdlib,prometheus]},
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.3.0",
|
[{"4.3.1",[{load_module,emqx_prometheus,brutal_purge,soft_purge,[]}]},
|
||||||
[{load_module,emqx_prometheus,brutal_purge,soft_purge,[]}]},
|
{"4.3.0",[{load_module,emqx_prometheus,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.3.0",
|
[{"4.3.1",[{load_module,emqx_prometheus,brutal_purge,soft_purge,[]}]},
|
||||||
[{load_module,emqx_prometheus,brutal_purge,soft_purge,[]}]},
|
{"4.3.0",[{load_module,emqx_prometheus,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}]}.
|
{<<".*">>,[]}]}.
|
||||||
|
|
|
@ -185,6 +185,10 @@ emqx_collect(emqx_connections_count, Stats) ->
|
||||||
gauge_metric(?C('connections.count', Stats));
|
gauge_metric(?C('connections.count', Stats));
|
||||||
emqx_collect(emqx_connections_max, Stats) ->
|
emqx_collect(emqx_connections_max, Stats) ->
|
||||||
gauge_metric(?C('connections.max', Stats));
|
gauge_metric(?C('connections.max', Stats));
|
||||||
|
emqx_collect(emqx_live_connections_count, Stats) ->
|
||||||
|
gauge_metric(?C('live_connections.count', Stats));
|
||||||
|
emqx_collect(emqx_live_connections_max, Stats) ->
|
||||||
|
gauge_metric(?C('live_connections.max', Stats));
|
||||||
|
|
||||||
%% sessions
|
%% sessions
|
||||||
emqx_collect(emqx_sessions_count, Stats) ->
|
emqx_collect(emqx_sessions_count, Stats) ->
|
||||||
|
@ -471,6 +475,8 @@ emqx_collect(emqx_cluster_nodes_stopped, ClusterData) ->
|
||||||
emqx_stats() ->
|
emqx_stats() ->
|
||||||
[ emqx_connections_count
|
[ emqx_connections_count
|
||||||
, emqx_connections_max
|
, emqx_connections_max
|
||||||
|
, emqx_live_connections_count
|
||||||
|
, emqx_live_connections_max
|
||||||
, emqx_sessions_count
|
, emqx_sessions_count
|
||||||
, emqx_sessions_max
|
, emqx_sessions_max
|
||||||
, emqx_topics_count
|
, emqx_topics_count
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_retainer,
|
{application, emqx_retainer,
|
||||||
[{description, "EMQ X Retainer"},
|
[{description, "EMQ X Retainer"},
|
||||||
{vsn, "4.4.3"}, % strict semver, bump manually!
|
{vsn, "4.4.4"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_retainer_sup]},
|
{registered, [emqx_retainer_sup]},
|
||||||
{applications, [kernel,stdlib]},
|
{applications, [kernel,stdlib]},
|
||||||
|
|
|
@ -1,15 +1,27 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.4.2",[{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}]},
|
[{"4.4.3",[{load_module,emqx_retainer,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.1",[{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}]},
|
{"4.4.2",[{load_module,emqx_retainer,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
|
{"4.4.1",[{load_module,emqx_retainer,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
{"4.4.0",
|
{"4.4.0",
|
||||||
[{load_module,emqx_retainer_cli,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_retainer,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_retainer_cli,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.4.2",[{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}]},
|
[{"4.4.3",[{load_module,emqx_retainer,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.1",[{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}]},
|
{"4.4.2",[{load_module,emqx_retainer,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
|
{"4.4.1",[{load_module,emqx_retainer,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
{"4.4.0",
|
{"4.4.0",
|
||||||
[{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_retainer,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_retainer_cli,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_retainer_cli,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}]}.
|
{<<".*">>,[]}]}.
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
-include_lib("emqx/include/emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("stdlib/include/ms_transform.hrl").
|
-include_lib("stdlib/include/ms_transform.hrl").
|
||||||
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
-logger_header("[Retainer]").
|
-logger_header("[Retainer]").
|
||||||
|
|
||||||
|
@ -74,11 +75,12 @@ on_session_subscribed(_, Topic, #{rh := Rh, is_new := IsNew}) ->
|
||||||
|
|
||||||
%% @private
|
%% @private
|
||||||
dispatch(Pid, Topic) ->
|
dispatch(Pid, Topic) ->
|
||||||
Msgs = case emqx_topic:wildcard(Topic) of
|
MsgsT = case emqx_topic:wildcard(Topic) of
|
||||||
false -> read_messages(Topic);
|
false -> read_messages(Topic);
|
||||||
true -> match_messages(Topic)
|
true -> match_messages(Topic)
|
||||||
end,
|
end,
|
||||||
Now = erlang:system_time(millisecond),
|
Now = erlang:system_time(millisecond),
|
||||||
|
Msgs = drop_banned_messages(MsgsT),
|
||||||
[Pid ! {deliver, Topic, refresh_timestamp_expiry(Msg, Now)} || Msg <- sort_retained(Msgs)].
|
[Pid ! {deliver, Topic, refresh_timestamp_expiry(Msg, Now)} || Msg <- sort_retained(Msgs)].
|
||||||
|
|
||||||
%% RETAIN flag set to 1 and payload containing zero bytes
|
%% RETAIN flag set to 1 and payload containing zero bytes
|
||||||
|
@ -332,3 +334,21 @@ refresh_timestamp_expiry(Msg = #message{headers =
|
||||||
|
|
||||||
refresh_timestamp_expiry(Msg, Now) ->
|
refresh_timestamp_expiry(Msg, Now) ->
|
||||||
Msg#message{timestamp = Now}.
|
Msg#message{timestamp = Now}.
|
||||||
|
|
||||||
|
drop_banned_messages(Msgs) ->
|
||||||
|
lists:filter(fun(Msg) ->
|
||||||
|
case emqx_banned:look_up({clientid, Msg#message.from}) of
|
||||||
|
[] ->
|
||||||
|
true;
|
||||||
|
_ ->
|
||||||
|
?tp(
|
||||||
|
notice,
|
||||||
|
ignore_retained_message_deliver,
|
||||||
|
#{
|
||||||
|
reason => "client is banned",
|
||||||
|
clientid => Msg#message.from
|
||||||
|
}
|
||||||
|
),
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end, Msgs).
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
||||||
|
@ -189,6 +190,53 @@ t_stop_publish_clear_msg(_) ->
|
||||||
|
|
||||||
ok = emqtt:disconnect(C1).
|
ok = emqtt:disconnect(C1).
|
||||||
|
|
||||||
|
t_deliver_when_banned(_) ->
|
||||||
|
Client1 = <<"c1">>,
|
||||||
|
Client2 = <<"c2">>,
|
||||||
|
|
||||||
|
{ok, C1} = emqtt:start_link([{clientid, Client1}, {clean_start, true}, {proto_ver, v5}]),
|
||||||
|
{ok, _} = emqtt:connect(C1),
|
||||||
|
|
||||||
|
lists:foreach(
|
||||||
|
fun(I) ->
|
||||||
|
Topic = erlang:list_to_binary(io_lib:format("retained/~p", [I])),
|
||||||
|
Msg = emqx_message:make(Client2, 0, Topic, <<"this is a retained message">>),
|
||||||
|
Msg2 = emqx_message:set_flag(retain, Msg),
|
||||||
|
emqx:publish(Msg2)
|
||||||
|
end,
|
||||||
|
lists:seq(1, 3)
|
||||||
|
),
|
||||||
|
|
||||||
|
Now = erlang:system_time(second),
|
||||||
|
Who = {clientid, Client2},
|
||||||
|
|
||||||
|
emqx_banned:create(#{
|
||||||
|
who => Who,
|
||||||
|
by => <<"test">>,
|
||||||
|
reason => <<"test">>,
|
||||||
|
at => Now,
|
||||||
|
until => Now + 120
|
||||||
|
}),
|
||||||
|
timer:sleep(100),
|
||||||
|
|
||||||
|
snabbkaffe:start_trace(),
|
||||||
|
|
||||||
|
{ok, SubRef} =
|
||||||
|
snabbkaffe_collector:subscribe(?match_event(#{?snk_kind := ignore_retained_message_deliver}),
|
||||||
|
_NEvents = 3,
|
||||||
|
_Timeout = 10000,
|
||||||
|
0),
|
||||||
|
|
||||||
|
{ok, #{}, [0]} = emqtt:subscribe(C1, <<"retained/+">>, [{qos, 0}, {rh, 0}]),
|
||||||
|
{ok, Trace} = snabbkaffe_collector:receive_events(SubRef),
|
||||||
|
?assertEqual(3, length(?of_kind(ignore_retained_message_deliver, Trace))),
|
||||||
|
|
||||||
|
snabbkaffe:stop(),
|
||||||
|
|
||||||
|
emqx_banned:delete(Who),
|
||||||
|
{ok, #{}, [0]} = emqtt:unsubscribe(C1, <<"retained/+">>),
|
||||||
|
ok = emqtt:disconnect(C1).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Helper functions
|
%% Helper functions
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -1,22 +1,32 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.4.14",[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
[{<<"4\\.4\\.1[3-4]">>,
|
||||||
{"4.4.13",[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
{"4.4.12",
|
{"4.4.12",
|
||||||
[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_jwt_worker,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_jwt_worker,brutal_purge,soft_purge,[]},
|
||||||
{update,emqx_rule_engine_jwt_sup,supervisor},
|
{update,emqx_rule_engine_jwt_sup,supervisor},
|
||||||
{load_module,emqx_rule_engine_jwt,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine_jwt,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.11",
|
{"4.4.11",
|
||||||
[{load_module,emqx_rule_engine_jwt_worker,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_engine_jwt_worker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{update,emqx_rule_engine_jwt_sup,supervisor},
|
{update,emqx_rule_engine_jwt_sup,supervisor},
|
||||||
{load_module,emqx_rule_engine_jwt,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_jwt,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_api,brutal_purge,soft_purge,[]},
|
||||||
{apply,{emqx_rule_engine_sup,ensure_api_delegator_started,[]}},
|
{apply,{emqx_rule_engine_sup,ensure_api_delegator_started,[]}},
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
{"4.4.10",
|
{"4.4.10",
|
||||||
[{add_module,emqx_rule_engine_jwt},
|
[{add_module,emqx_rule_engine_jwt},
|
||||||
{add_module,emqx_rule_engine_jwt_worker},
|
{add_module,emqx_rule_engine_jwt_worker},
|
||||||
|
@ -222,15 +232,24 @@
|
||||||
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_runtime,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.4.14",[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
[{<<"4\\.4\\.1[3-4]">>,
|
||||||
{"4.4.13",[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
{"4.4.12",
|
{"4.4.12",
|
||||||
[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_engine,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_engine_jwt_worker,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_jwt_worker,brutal_purge,soft_purge,[]},
|
||||||
{update,emqx_rule_engine_jwt_sup,supervisor},
|
{update,emqx_rule_engine_jwt_sup,supervisor},
|
||||||
{load_module,emqx_rule_engine_jwt,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_engine_jwt,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.11",
|
{"4.4.11",
|
||||||
[{load_module,emqx_rule_engine_jwt_worker,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_rule_engine_jwt_worker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_events,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_monitor,brutal_purge,soft_purge,[]},
|
||||||
{update,emqx_rule_engine_jwt_sup,supervisor},
|
{update,emqx_rule_engine_jwt_sup,supervisor},
|
||||||
{load_module,emqx_rule_engine_jwt,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_engine_jwt,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
, create_resource/1
|
, create_resource/1
|
||||||
, test_resource/1
|
, test_resource/1
|
||||||
, start_resource/1
|
, start_resource/1
|
||||||
|
, start_all_resources_of_type/1
|
||||||
, get_resource_status/1
|
, get_resource_status/1
|
||||||
, is_resource_alive/1
|
, is_resource_alive/1
|
||||||
, is_resource_alive/2
|
, is_resource_alive/2
|
||||||
|
@ -354,19 +355,27 @@ do_check_and_update_resource(#{id := Id, type := Type, description := NewDescrip
|
||||||
-spec(start_resource(resource_id()) -> ok | {error, Reason :: term()}).
|
-spec(start_resource(resource_id()) -> ok | {error, Reason :: term()}).
|
||||||
start_resource(ResId) ->
|
start_resource(ResId) ->
|
||||||
case emqx_rule_registry:find_resource(ResId) of
|
case emqx_rule_registry:find_resource(ResId) of
|
||||||
{ok, #resource{type = ResType, config = Config}} ->
|
{ok, Res} ->
|
||||||
{ok, #resource_type{on_create = {Mod, Create}}}
|
do_start_resource(Res);
|
||||||
= emqx_rule_registry:find_resource_type(ResType),
|
|
||||||
try
|
|
||||||
init_resource_with_retrier(Mod, Create, ResId, Config),
|
|
||||||
refresh_actions_of_a_resource(ResId)
|
|
||||||
catch
|
|
||||||
throw:Reason -> {error, Reason}
|
|
||||||
end;
|
|
||||||
not_found ->
|
not_found ->
|
||||||
{error, {resource_not_found, ResId}}
|
{error, {resource_not_found, ResId}}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
do_start_resource(#resource{id = ResId, type = ResType, config = Config}) ->
|
||||||
|
{ok, #resource_type{on_create = {Mod, Create}}}
|
||||||
|
= emqx_rule_registry:find_resource_type(ResType),
|
||||||
|
try
|
||||||
|
init_resource_with_retrier(Mod, Create, ResId, Config),
|
||||||
|
refresh_actions_of_a_resource(ResId)
|
||||||
|
catch
|
||||||
|
throw:Reason -> {error, Reason}
|
||||||
|
end.
|
||||||
|
|
||||||
|
-spec(start_all_resources_of_type(resource_type_name()) -> [{resource_id(), ok | {error, term()}}]).
|
||||||
|
start_all_resources_of_type(Type) ->
|
||||||
|
[{ResId, do_start_resource(Res)}
|
||||||
|
|| #resource{id = ResId} = Res <- emqx_rule_registry:get_resources_by_type(Type)].
|
||||||
|
|
||||||
-spec(test_resource(#{type := _, config := _, _ => _}) -> ok | {error, Reason :: term()}).
|
-spec(test_resource(#{type := _, config := _, _ => _}) -> ok | {error, Reason :: term()}).
|
||||||
test_resource(#{type := Type} = Params) ->
|
test_resource(#{type := Type} = Params) ->
|
||||||
case emqx_rule_registry:find_resource_type(Type) of
|
case emqx_rule_registry:find_resource_type(Type) of
|
||||||
|
@ -520,19 +529,27 @@ refresh_resource(#resource{id = ResId, type = Type, config = Config}) ->
|
||||||
refresh_rules_when_boot() ->
|
refresh_rules_when_boot() ->
|
||||||
lists:foreach(fun
|
lists:foreach(fun
|
||||||
(#rule{enabled = true} = Rule) ->
|
(#rule{enabled = true} = Rule) ->
|
||||||
try refresh_rule(Rule)
|
ensure_rule_retrier(Rule);
|
||||||
catch _:_ ->
|
(#rule{enabled = false, state = refresh_failed_at_bootup} = Rule) ->
|
||||||
%% We set the enable = false when rule init failed to avoid bad rules running
|
%% the rule was previously disabled by emqx so we need to retry it
|
||||||
%% without actions created properly.
|
ensure_rule_retrier(Rule);
|
||||||
%% The init failure might be caused by a disconnected resource, in this case the
|
(#rule{enabled = false, id = RuleId}) ->
|
||||||
%% actions can not be created, so the rules won't work.
|
?LOG(warning, "rule ~s was disabled by the user, won't re-enable it", [RuleId])
|
||||||
%% After the user fixed the problem he can enable it manually,
|
|
||||||
%% doing so will also recreate the actions.
|
|
||||||
emqx_rule_registry:add_rule(Rule#rule{enabled = false, state = refresh_failed_at_bootup})
|
|
||||||
end;
|
|
||||||
(_) -> ok
|
|
||||||
end, emqx_rule_registry:get_rules()).
|
end, emqx_rule_registry:get_rules()).
|
||||||
|
|
||||||
|
ensure_rule_retrier(#rule{id = RuleId} = Rule) ->
|
||||||
|
try refresh_rule(Rule)
|
||||||
|
catch _:_ ->
|
||||||
|
%% We set the enable = false when rule init failed to avoid bad rules running
|
||||||
|
%% without actions created properly.
|
||||||
|
%% The init failure might be caused by a disconnected resource, in this case the
|
||||||
|
%% actions can not be created, so the rules won't work.
|
||||||
|
%% After the user fixed the problem he can enable it manually,
|
||||||
|
%% doing so will also recreate the actions.
|
||||||
|
emqx_rule_registry:add_rule(Rule#rule{enabled = false, state = refresh_failed_at_bootup}),
|
||||||
|
emqx_rule_monitor:ensure_rule_retrier(RuleId)
|
||||||
|
end.
|
||||||
|
|
||||||
refresh_rule(#rule{id = RuleId, for = Topics, actions = Actions}) ->
|
refresh_rule(#rule{id = RuleId, for = Topics, actions = Actions}) ->
|
||||||
ok = emqx_rule_metrics:create_rule_metrics(RuleId),
|
ok = emqx_rule_metrics:create_rule_metrics(RuleId),
|
||||||
lists:foreach(fun emqx_rule_events:load/1, Topics),
|
lists:foreach(fun emqx_rule_events:load/1, Topics),
|
||||||
|
|
|
@ -853,9 +853,25 @@ printable_maps(Headers) ->
|
||||||
value => Value
|
value => Value
|
||||||
} || {Key, Value} <- V0]
|
} || {Key, Value} <- V0]
|
||||||
};
|
};
|
||||||
|
(K, V, AccIn) when is_map(V) ->
|
||||||
|
AccIn#{K => printable_maps(V)};
|
||||||
|
(K, V, AccIn) when is_list(V) ->
|
||||||
|
AccIn#{K => printable_list(V)};
|
||||||
(_K, V, AccIn) when is_tuple(V) ->
|
(_K, V, AccIn) when is_tuple(V) ->
|
||||||
%% internal header
|
%% internal header, remove it
|
||||||
AccIn;
|
AccIn;
|
||||||
(K, V, AccIn) ->
|
(K, V, AccIn) ->
|
||||||
AccIn#{K => V}
|
AccIn#{K => V}
|
||||||
end, #{}, Headers).
|
end, #{}, Headers).
|
||||||
|
|
||||||
|
printable_list(L) ->
|
||||||
|
lists:filtermap(fun printable_element/1, L).
|
||||||
|
|
||||||
|
printable_element(E) when is_map(E) ->
|
||||||
|
{true, printable_maps(E)};
|
||||||
|
printable_element(E) when is_tuple(E) ->
|
||||||
|
false;
|
||||||
|
printable_element(E) when is_list(E) ->
|
||||||
|
{true, printable_list(E)};
|
||||||
|
printable_element(E) ->
|
||||||
|
{true, E}.
|
||||||
|
|
|
@ -33,16 +33,21 @@
|
||||||
, stop/0
|
, stop/0
|
||||||
, async_refresh_resources_rules/0
|
, async_refresh_resources_rules/0
|
||||||
, ensure_resource_retrier/1
|
, ensure_resource_retrier/1
|
||||||
|
, ensure_rule_retrier/1
|
||||||
|
, retry_loop/2
|
||||||
, retry_loop/3
|
, retry_loop/3
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%% fot test
|
-export([ put_resource_retry_interval/1
|
||||||
-export([ put_retry_interval/1
|
, put_rule_retry_interval/1
|
||||||
, get_retry_interval/0
|
, get_resource_retry_interval/0
|
||||||
, erase_retry_interval/0
|
, get_rule_retry_interval/0
|
||||||
|
, erase_resource_retry_interval/0
|
||||||
|
, erase_rule_retry_interval/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-define(T_RETRY, 60000).
|
-define(T_RESOURCE_RETRY, 15000).
|
||||||
|
-define(T_RULE_RETRY, 20000).
|
||||||
|
|
||||||
start_link() ->
|
start_link() ->
|
||||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||||
|
@ -54,23 +59,33 @@ init([]) ->
|
||||||
_ = erlang:process_flag(trap_exit, true),
|
_ = erlang:process_flag(trap_exit, true),
|
||||||
{ok, #{retryers => #{}}}.
|
{ok, #{retryers => #{}}}.
|
||||||
|
|
||||||
put_retry_interval(I) when is_integer(I) andalso I >= 10 ->
|
put_resource_retry_interval(I) when is_integer(I) andalso I >= 10 ->
|
||||||
_ = persistent_term:put({?MODULE, resource_restart_interval}, I),
|
_ = persistent_term:put({?MODULE, resource_restart_interval}, I),
|
||||||
ok.
|
ok.
|
||||||
|
put_rule_retry_interval(I) when is_integer(I) andalso I >= 10 ->
|
||||||
erase_retry_interval() ->
|
_ = persistent_term:put({?MODULE, rule_restart_interval}, I),
|
||||||
_ = persistent_term:erase({?MODULE, resource_restart_interval}),
|
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
get_retry_interval() ->
|
erase_resource_retry_interval() ->
|
||||||
persistent_term:get({?MODULE, resource_restart_interval}, ?T_RETRY).
|
_ = persistent_term:erase({?MODULE, resource_restart_interval}),
|
||||||
|
ok.
|
||||||
|
erase_rule_retry_interval() ->
|
||||||
|
_ = persistent_term:erase({?MODULE, rule_restart_interval}),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
get_resource_retry_interval() ->
|
||||||
|
persistent_term:get({?MODULE, resource_restart_interval}, ?T_RESOURCE_RETRY).
|
||||||
|
get_rule_retry_interval() ->
|
||||||
|
persistent_term:get({?MODULE, rule_restart_interval}, ?T_RULE_RETRY).
|
||||||
|
|
||||||
async_refresh_resources_rules() ->
|
async_refresh_resources_rules() ->
|
||||||
gen_server:cast(?MODULE, async_refresh).
|
gen_server:cast(?MODULE, async_refresh).
|
||||||
|
|
||||||
ensure_resource_retrier(ResId) ->
|
ensure_resource_retrier(ResId) ->
|
||||||
Interval = get_retry_interval(),
|
gen_server:cast(?MODULE, {create_restart_handler, resource, ResId}).
|
||||||
gen_server:cast(?MODULE, {create_restart_handler, resource, ResId, Interval}).
|
|
||||||
|
ensure_rule_retrier(RuleId) ->
|
||||||
|
gen_server:cast(?MODULE, {create_restart_handler, rule, RuleId}).
|
||||||
|
|
||||||
handle_call(_Msg, _From, State) ->
|
handle_call(_Msg, _From, State) ->
|
||||||
{reply, ok, State}.
|
{reply, ok, State}.
|
||||||
|
@ -82,12 +97,12 @@ handle_cast(async_refresh, State) ->
|
||||||
Pid = spawn_link(fun do_async_refresh/0),
|
Pid = spawn_link(fun do_async_refresh/0),
|
||||||
{noreply, State#{boot_refresh_pid => Pid}};
|
{noreply, State#{boot_refresh_pid => Pid}};
|
||||||
|
|
||||||
handle_cast({create_restart_handler, Tag, Obj, Interval}, State) ->
|
handle_cast({create_restart_handler, Tag, Obj}, State) ->
|
||||||
Objects = maps:get(Tag, State, #{}),
|
Objects = maps:get(Tag, State, #{}),
|
||||||
NewState = case maps:find(Obj, Objects) of
|
NewState = case maps:find(Obj, Objects) of
|
||||||
error ->
|
error ->
|
||||||
update_object(Tag, Obj,
|
update_object(Tag, Obj,
|
||||||
create_restart_handler(Tag, Obj, Interval), State);
|
create_restart_handler(Tag, Obj), State);
|
||||||
{ok, _Pid} ->
|
{ok, _Pid} ->
|
||||||
State
|
State
|
||||||
end,
|
end,
|
||||||
|
@ -130,13 +145,17 @@ update_object(Tag, Obj, Retryer, State) ->
|
||||||
retryers => Retryers#{Retryer => {Tag, Obj}}
|
retryers => Retryers#{Retryer => {Tag, Obj}}
|
||||||
}.
|
}.
|
||||||
|
|
||||||
create_restart_handler(Tag, Obj, Interval) ->
|
create_restart_handler(Tag, Obj) ->
|
||||||
?LOG(info, "starting_a_retry_loop for ~p ~p, with delay interval: ~p", [Tag, Obj, Interval]),
|
?LOG(warning, "starting_a_retry_loop for ~p ~p", [Tag, Obj]),
|
||||||
%% spawn a dedicated process to handle the restarting asynchronously
|
%% spawn a dedicated process to handle the restarting asynchronously
|
||||||
spawn_link(?MODULE, retry_loop, [Tag, Obj, Interval]).
|
spawn_link(?MODULE, retry_loop, [Tag, Obj]).
|
||||||
|
|
||||||
retry_loop(resource, ResId, Interval) ->
|
%% retry_loop/3 is to avoid crashes during relup
|
||||||
timer:sleep(Interval),
|
retry_loop(Tag, ResId, _Interval) ->
|
||||||
|
retry_loop(Tag, ResId).
|
||||||
|
|
||||||
|
retry_loop(resource, ResId) ->
|
||||||
|
timer:sleep(get_resource_retry_interval()),
|
||||||
case emqx_rule_registry:find_resource(ResId) of
|
case emqx_rule_registry:find_resource(ResId) of
|
||||||
{ok, #resource{type = Type, config = Config}} ->
|
{ok, #resource{type = Type, config = Config}} ->
|
||||||
try
|
try
|
||||||
|
@ -154,10 +173,30 @@ retry_loop(resource, ResId, Interval) ->
|
||||||
end,
|
end,
|
||||||
?LOG_SENSITIVE(warning, "init_resource_retry_failed ~p, ~0p", [ResId, LogContext]),
|
?LOG_SENSITIVE(warning, "init_resource_retry_failed ~p, ~0p", [ResId, LogContext]),
|
||||||
%% keep looping
|
%% keep looping
|
||||||
?MODULE:retry_loop(resource, ResId, Interval)
|
?MODULE:retry_loop(resource, ResId)
|
||||||
end;
|
end;
|
||||||
not_found ->
|
not_found ->
|
||||||
ok
|
ok
|
||||||
|
end;
|
||||||
|
|
||||||
|
retry_loop(rule, RuleId) ->
|
||||||
|
timer:sleep(get_rule_retry_interval()),
|
||||||
|
case emqx_rule_registry:get_rule(RuleId) of
|
||||||
|
{ok, #rule{enabled = false, state = refresh_failed_at_bootup} = Rule} ->
|
||||||
|
try
|
||||||
|
emqx_rule_engine:refresh_rule(Rule),
|
||||||
|
emqx_rule_registry:add_rule(Rule#rule{enabled = true, state = normal}),
|
||||||
|
?LOG(warning, "rule ~s has been refreshed and re-enabled", [RuleId])
|
||||||
|
catch
|
||||||
|
Err:Reason:ST ->
|
||||||
|
?LOG(warning, "init_rule failed: ~p, ~0p",
|
||||||
|
[{Err, Reason}, ST]),
|
||||||
|
?MODULE:retry_loop(rule, RuleId)
|
||||||
|
end;
|
||||||
|
{ok, #rule{enabled = false, state = State}} when State =/= refresh_failed_at_bootup ->
|
||||||
|
?LOG(warning, "rule ~s was disabled by the user, won't re-enable it", [RuleId]);
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
do_async_refresh() ->
|
do_async_refresh() ->
|
||||||
|
@ -171,6 +210,6 @@ refresh_and_enable_rules_of_resource(ResId) ->
|
||||||
fun (#rule{id = Id, enabled = false, state = refresh_failed_at_bootup} = Rule) ->
|
fun (#rule{id = Id, enabled = false, state = refresh_failed_at_bootup} = Rule) ->
|
||||||
emqx_rule_engine:refresh_rule(Rule),
|
emqx_rule_engine:refresh_rule(Rule),
|
||||||
emqx_rule_registry:add_rule(Rule#rule{enabled = true, state = normal}),
|
emqx_rule_registry:add_rule(Rule#rule{enabled = true, state = normal}),
|
||||||
?LOG(info, "rule ~s is refreshed and re-enabled", [Id]);
|
?LOG(warning, "rule ~s is refreshed and re-enabled", [Id]);
|
||||||
(_) -> ok
|
(_) -> ok
|
||||||
end, emqx_rule_registry:find_rules_depends_on_resource(ResId)).
|
end, emqx_rule_registry:find_rules_depends_on_resource(ResId)).
|
||||||
|
|
|
@ -36,18 +36,44 @@ t_mod_hook_fun(_) ->
|
||||||
]].
|
]].
|
||||||
|
|
||||||
t_printable_maps(_) ->
|
t_printable_maps(_) ->
|
||||||
Headers = #{peerhost => {127,0,0,1},
|
TestMap = #{
|
||||||
peername => {{127,0,0,1}, 9980},
|
peerhost => {127,0,0,1},
|
||||||
sockname => {{127,0,0,1}, 1883},
|
peername => {{127,0,0,1}, 9980},
|
||||||
redispatch_to => {<<"group">>, <<"sub/topic/+">>},
|
sockname => {{127,0,0,1}, 1883},
|
||||||
shared_dispatch_ack => {self(), ref}
|
redispatch_to => {<<"group">>, <<"sub/topic/+">>},
|
||||||
},
|
shared_dispatch_ack => {self(), ref},
|
||||||
|
string => <<"abc">>,
|
||||||
|
atom => abc,
|
||||||
|
integer => 1,
|
||||||
|
float => 1.0,
|
||||||
|
simple_list => [1, 1.0, a, "abc", <<"abc">>, {a,b}]
|
||||||
|
},
|
||||||
|
Headers = TestMap#{
|
||||||
|
map => TestMap,
|
||||||
|
map_list => [
|
||||||
|
TestMap#{
|
||||||
|
map => TestMap
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
Converted = emqx_rule_events:printable_maps(Headers),
|
Converted = emqx_rule_events:printable_maps(Headers),
|
||||||
?assertMatch(
|
Verify = fun(Result) ->
|
||||||
#{peerhost := <<"127.0.0.1">>,
|
?assertMatch(
|
||||||
peername := <<"127.0.0.1:9980">>,
|
#{peerhost := <<"127.0.0.1">>,
|
||||||
sockname := <<"127.0.0.1:1883">>
|
peername := <<"127.0.0.1:9980">>,
|
||||||
}, Converted),
|
sockname := <<"127.0.0.1:1883">>,
|
||||||
?assertNot(maps:is_key(redispatch_to, Converted)),
|
string := <<"abc">>,
|
||||||
?assertNot(maps:is_key(shared_dispatch_ack, Converted)),
|
atom := abc,
|
||||||
|
integer := 1,
|
||||||
|
float := 1.0,
|
||||||
|
simple_list := [1, 1.0, a, "abc", <<"abc">>] %% {a,b} is removed
|
||||||
|
}, Result),
|
||||||
|
?assertNot(maps:is_key(redispatch_to, Result)),
|
||||||
|
?assertNot(maps:is_key(shared_dispatch_ack, Result)),
|
||||||
|
%% make sure the result is jsonable
|
||||||
|
_ = emqx_json:encode(Result)
|
||||||
|
end,
|
||||||
|
Verify(maps:get(map, Converted)),
|
||||||
|
Verify(maps:get(map, lists:nth(1, maps:get(map_list, Converted)))),
|
||||||
|
Verify(Converted),
|
||||||
ok.
|
ok.
|
||||||
|
|
|
@ -48,7 +48,7 @@ end_per_suite(_Config) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
init_per_testcase(t_restart_resource, Config) ->
|
init_per_testcase(t_restart_resource, Config) ->
|
||||||
emqx_rule_monitor:put_retry_interval(100),
|
emqx_rule_monitor:put_resource_retry_interval(100),
|
||||||
Opts = [public, named_table, set, {read_concurrency, true}],
|
Opts = [public, named_table, set, {read_concurrency, true}],
|
||||||
_ = ets:new(?RES_PARAMS_TAB, [{keypos, #resource_params.id}|Opts]),
|
_ = ets:new(?RES_PARAMS_TAB, [{keypos, #resource_params.id}|Opts]),
|
||||||
ets:new(t_restart_resource, [named_table, public]),
|
ets:new(t_restart_resource, [named_table, public]),
|
||||||
|
@ -90,12 +90,13 @@ end_per_testcase(_, Config) ->
|
||||||
|
|
||||||
common_init_per_testcase() ->
|
common_init_per_testcase() ->
|
||||||
AlarmOpts = [{actions, [log, publish]}, {size_limit, 1000}, {validity_period, 86400}],
|
AlarmOpts = [{actions, [log, publish]}, {size_limit, 1000}, {validity_period, 86400}],
|
||||||
|
_ = emqx_alarm:mnesia(boot),
|
||||||
{ok, _} = emqx_alarm:start_link(AlarmOpts),
|
{ok, _} = emqx_alarm:start_link(AlarmOpts),
|
||||||
{ok, _} = emqx_rule_monitor:start_link().
|
{ok, _} = emqx_rule_monitor:start_link().
|
||||||
|
|
||||||
common_end_per_testcases() ->
|
common_end_per_testcases() ->
|
||||||
ok = emqx_alarm:stop(),
|
ok = emqx_alarm:stop(),
|
||||||
emqx_rule_monitor:erase_retry_interval(),
|
emqx_rule_monitor:erase_resource_retry_interval(),
|
||||||
emqx_rule_monitor:stop().
|
emqx_rule_monitor:stop().
|
||||||
|
|
||||||
t_restart_resource(_) ->
|
t_restart_resource(_) ->
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
{plugins, [rebar3_proper]}.
|
{plugins, [rebar3_proper]}.
|
||||||
|
|
||||||
{deps,
|
{deps,
|
||||||
[{esockd, {git, "https://github.com/emqx/esockd", {tag, "5.8.7"}}},
|
[{cuttlefish, {git, "https://github.com/emqx/cuttlefish", {tag, "v3.0.0"}}}
|
||||||
{cuttlefish, {git, "https://github.com/emqx/cuttlefish", {tag, "v3.0.0"}}}
|
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
{edoc_opts, [{preprocess, true}]}.
|
{edoc_opts, [{preprocess, true}]}.
|
||||||
|
|
8
build
8
build
|
@ -205,6 +205,14 @@ make_zip() {
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
ubuntu22)
|
||||||
|
case "$PKG_VSN" in
|
||||||
|
4.4.15*)
|
||||||
|
# this is the first version for amzn2, no relup
|
||||||
|
has_relup='no'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
macos*)
|
macos*)
|
||||||
case "$PKG_VSN" in
|
case "$PKG_VSN" in
|
||||||
4.4.12*)
|
4.4.12*)
|
||||||
|
|
|
@ -1,7 +1,53 @@
|
||||||
|
|
||||||
# v4.4.15
|
# v4.4.15
|
||||||
|
|
||||||
## Enhancements
|
## Enhancements
|
||||||
|
|
||||||
- The MongoDB library has been upgraded to support MongoDB version 5.1 and greater.
|
- The MongoDB library has been upgraded to support MongoDB version 5.1 and greater.
|
||||||
|
|
||||||
|
- Support HAProxy protocol for dashboard API [9803](https://github.com/emqx/emqx/pull/9803).
|
||||||
|
|
||||||
|
- Added Ubuntu 22.04 package release [#9831](https://github.com/emqx/emqx/pull/9831).
|
||||||
|
|
||||||
|
- Improve the integration of the `banned` and the `delayed` feature [#9790](https://github.com/emqx/emqx/pull/9790).
|
||||||
|
Now when publishing a delayed message will check first if its source client is banned, if true, this publish will be ignored.
|
||||||
|
|
||||||
|
- Security enhancement for retained messages [#9790](https://github.com/emqx/emqx/pull/9790).
|
||||||
|
The retained messages will not be published if the publisher client is banned.
|
||||||
|
|
||||||
|
- Now the corresponding session will be kicked when client is banned by `clientid` [#9904](https://github.com/emqx/emqx/pull/9904).
|
||||||
|
|
||||||
|
- Add more debug logs for authentication and ACL [#9943](https://github.com/emqx/emqx/pull/9943).
|
||||||
|
|
||||||
|
- Expose the stats `live_connections.count` and `live_connections.max` to Prometheus [#9929](https://github.com/emqx/emqx/pull/9929).
|
||||||
|
|
||||||
## Bug fixes
|
## Bug fixes
|
||||||
|
|
||||||
|
- Fixed an error when forward MQTT messages with User-Property using the `republish` action [#9942](https://github.com/emqx/emqx/pull/9942).
|
||||||
|
|
||||||
|
- fix some issues in descriptions of the actions, resources amd emqx-modules [#9931](https://github.com/emqx/emqx/pull/9931).
|
||||||
|
|
||||||
|
- fix there's no error logs when query the JWKS server failed [#9931](https://github.com/emqx/emqx/pull/9931).
|
||||||
|
|
||||||
|
- The returned client lists of HTTP query `GET /api/v4/clients?_page=2&_limit=20` to different nodes might be inconsistent [#9926](https://github.com/emqx/emqx/pull/9926).
|
||||||
|
|
||||||
|
- Fix the problem that new MQTT TLS connections failed to establish after release hot upgrade [#9810](https://github.com/emqx/emqx/pull/9810).
|
||||||
|
For more detailed information please see: [emqx/esockd#170](https://github.com/emqx/esockd/pull/170).
|
||||||
|
|
||||||
|
- Fix a problem in the log message format of MQTT packets [#9858](https://github.com/emqx/emqx/pull/9858).
|
||||||
|
Before this fix, a comma was missing between the flags (DUP) of the fixed header
|
||||||
|
and the fields (ClientId) of the variable header:
|
||||||
|
```
|
||||||
|
2023-01-29T13:40:36.567692+08:00 [debug] 127.0.0.1:50393 [MQTT] RECV CONNECT(Q0, R0, D0ClientId=test_client, ... Password=undefined)
|
||||||
|
```
|
||||||
|
|
||||||
|
- Avoid crash logs in CoAP gateway when receiving liveness checking packets from Load Balancer [#9869](https://github.com/emqx/emqx/pull/9869).
|
||||||
|
|
||||||
|
- Fix the exclusive topics aren't removed when the session has already been cleaned [#9868](https://github.com/emqx/emqx/pull/9868).
|
||||||
|
|
||||||
|
- fix the emqx reports `{case_clause,{error,closed}}` error log message when websocket connections interrupted [emqx/cowboy#8](https://github.com/emqx/cowboy/pull/8).
|
||||||
|
|
||||||
|
- fix sometimes the rules cannot be enabled automatically after emqx is restarted [#9911](https://github.com/emqx/emqx/pull/9911).
|
||||||
|
|
||||||
|
- fix the `{badarg,[{ets,lookup,[gproc,{shared, ...` error logs during shutdown [#9919](https://github.com/emqx/emqx/pull/9919).
|
||||||
|
|
||||||
|
- Fix crash when updating a client's keepalive via the HTTP API if it connects with keepalive disabled [#9933](https://github.com/emqx/emqx/pull/9933).
|
||||||
|
|
|
@ -2,6 +2,53 @@
|
||||||
|
|
||||||
## 增强
|
## 增强
|
||||||
|
|
||||||
- MongoDB库已升级至支持MongoDB 5.1及以上版本[#9707](https://github.com/emqx/emqx/pull/9707)。
|
## 修复
|
||||||
|
|
||||||
|
- MongoDB 库已升级至支持 MongoDB 5.1 及以上版本[#9707](https://github.com/emqx/emqx/pull/9707)。
|
||||||
|
|
||||||
|
- 现在 dashboard 支持 `HAProxy` 协议了 [9803](https://github.com/emqx/emqx/pull/9803)。
|
||||||
|
|
||||||
|
- 发布 Ubuntu 22.04 安装包 [#9831](https://github.com/emqx/emqx/pull/9831)。
|
||||||
|
|
||||||
|
- 增强 `封禁` 和 `延迟消息` 这两个功能的集成性 [#9790](https://github.com/emqx/emqx/pull/9790)。
|
||||||
|
现在发送延迟消息前,会先检查消息的来源客户端是否被封禁了,如果是,这条延迟消息将会被忽略。
|
||||||
|
|
||||||
|
- 增强 `保留消息` 的安全性 [#9790](https://github.com/emqx/emqx/pull/9790)。
|
||||||
|
现在投递保留消息前,会先过滤掉来源客户端被封禁了的那些消息。
|
||||||
|
|
||||||
|
- 现在客户端通过 `clientid` 被封禁时将会踢掉对应的会话 [#9904](https://github.com/emqx/emqx/pull/9904)。
|
||||||
|
|
||||||
|
- 为认证和授权添加了更多调试日志 [#9943](https://github.com/emqx/emqx/pull/9943)。
|
||||||
|
|
||||||
|
- 将统计数据 `live_connections.count` 和 `live_connections.max` 公开给 Prometheus [#9929](https://github.com/emqx/emqx/pull/9929).
|
||||||
|
|
||||||
## 修复
|
## 修复
|
||||||
|
|
||||||
|
- 修复使用 `消息重发布` 动作转发带 User-Property 的 MQTT 消息时出错的问题 [#9942](https://github.com/emqx/emqx/pull/9942)。
|
||||||
|
|
||||||
|
- 修复资源、动作以及模块里的一些描述错误 [#9931](https://github.com/emqx/emqx/pull/9931)。
|
||||||
|
|
||||||
|
- 修复请求 JWKS 服务失败的时候,没有日志打印的问题 [#9931](https://github.com/emqx/emqx/pull/9931)。
|
||||||
|
|
||||||
|
- 使用 HTTP API `GET /api/v4/clients?_page=2&_limit=20` 请求客户端列表时,请求发送到不同的 emqx 节点,返回的客户端列表可能不一致 [#9926](https://github.com/emqx/emqx/pull/9926)。
|
||||||
|
|
||||||
|
- 修复版本热升级之后,新的 MQTT TLS 连接建立失败的问题 [#9810](https://github.com/emqx/emqx/pull/9810)。
|
||||||
|
详情见:[emqx/esockd#170](https://github.com/emqx/esockd/pull/170)
|
||||||
|
|
||||||
|
- 修复 MQTT 报文的日志打印格式的问题 [#9858](https://github.com/emqx/emqx/pull/9858)。
|
||||||
|
在此修复之前,固定报文头的标志位(DUP)和后面的可变报文头的字段(ClientId)之间漏掉了一个逗号做分隔:
|
||||||
|
```
|
||||||
|
2023-01-29T13:40:36.567692+08:00 [debug] 127.0.0.1:50393 [MQTT] RECV CONNECT(Q0, R0, D0ClientId=test_client, ... Password=undefined)
|
||||||
|
```
|
||||||
|
|
||||||
|
- 修复 CoAP 网关在收到负载均衡的心跳检查报文时产生的崩溃日志 [#9869](https://github.com/emqx/emqx/pull/9869)。
|
||||||
|
|
||||||
|
- 修复会话关闭后,其持有的排他订阅主题没有被释放的问题 [#9868](https://github.com/emqx/emqx/pull/9868)。
|
||||||
|
|
||||||
|
- 修复 Websocket 连接中断时日志报 `{case_clause,{error,closed}}` 错误的问题 [emqx/cowboy#8](https://github.com/emqx/cowboy/pull/8)。
|
||||||
|
|
||||||
|
- 修复某些情况下,重启 emqx 后规则无法自动启用的问题 [#9911](https://github.com/emqx/emqx/pull/9911)。
|
||||||
|
|
||||||
|
- 修复停止 emqx 的时候,日志出现 `{badarg,[{ets,lookup,[gproc,{shared, ...` 错误的问题 [#9919](https://github.com/emqx/emqx/pull/9919)。
|
||||||
|
|
||||||
|
- 修复当客户端连接禁用 keepalive时, 通过 HTTP API 更新其 keepalive 会崩溃的问题 [#9933](https://github.com/emqx/emqx/pull/9933)。
|
||||||
|
|
|
@ -40,6 +40,9 @@ Parameter | Description | Default Value
|
||||||
`image.pullPolicy` | The image pull policy | `IfNotPresent`
|
`image.pullPolicy` | The image pull policy | `IfNotPresent`
|
||||||
`image.pullSecrets ` | The image pull secrets (does not add image pull secrets to deployed pods) |``[]``
|
`image.pullSecrets ` | The image pull secrets (does not add image pull secrets to deployed pods) |``[]``
|
||||||
`recreatePods` | Forces the recreation of pods during upgrades, which can be useful to always apply the most recent configuration. | `false`
|
`recreatePods` | Forces the recreation of pods during upgrades, which can be useful to always apply the most recent configuration. | `false`
|
||||||
|
`serviceAccount.create` | If `true`, create a new service account | `true`
|
||||||
|
`serviceAccount.name` | Service account to be used. If not set and `serviceAccount.create` is `true`, a name is generated using the fullname template |
|
||||||
|
`serviceAccount.annotations` | Annotations to add to the service account |
|
||||||
`podAnnotations ` | Annotations for pod | `{}`
|
`podAnnotations ` | Annotations for pod | `{}`
|
||||||
`podManagementPolicy`| To redeploy a chart with existing PVC(s), the value must be set to Parallel to avoid deadlock | `Parallel`
|
`podManagementPolicy`| To redeploy a chart with existing PVC(s), the value must be set to Parallel to avoid deadlock | `Parallel`
|
||||||
`persistence.enabled` | Enable EMQX persistence using PVC | `false`
|
`persistence.enabled` | Enable EMQX persistence using PVC | `false`
|
||||||
|
|
|
@ -64,6 +64,7 @@ spec:
|
||||||
checksum/config: {{ $configData | sha256sum | quote }}
|
checksum/config: {{ $configData | sha256sum | quote }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
spec:
|
spec:
|
||||||
|
serviceAccountName: {{ include "emqx.serviceAccountName" . }}
|
||||||
volumes:
|
volumes:
|
||||||
{{- if .Values.emqxLoadedPlugins }}
|
{{- if .Values.emqxLoadedPlugins }}
|
||||||
- name: emqx-loaded-plugins
|
- name: emqx-loaded-plugins
|
||||||
|
@ -107,9 +108,6 @@ spec:
|
||||||
secret:
|
secret:
|
||||||
secretName: {{ $licenseSecretName }}
|
secretName: {{ $licenseSecretName }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- if eq (.Values.emqxConfig.EMQX_CLUSTER__DISCOVERY | default "k8s") "k8s" }}
|
|
||||||
serviceAccountName: {{ include "emqx.fullname" . }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.podSecurityContext.enabled }}
|
{{- if .Values.podSecurityContext.enabled }}
|
||||||
securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }}
|
securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
|
@ -30,3 +30,14 @@ Create chart name and version as used by the chart label.
|
||||||
{{- define "emqx.chart" -}}
|
{{- define "emqx.chart" -}}
|
||||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create the name of the service account to use
|
||||||
|
*/}}
|
||||||
|
{{- define "emqx.serviceAccountName" -}}
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- default (include "emqx.fullname" .) .Values.serviceAccount.name }}
|
||||||
|
{{- else }}
|
||||||
|
{{- default "default" .Values.serviceAccount.name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
|
@ -1,10 +1,23 @@
|
||||||
{{- if eq (.Values.emqxConfig.EMQX_CLUSTER__DISCOVERY | default "k8s") "k8s" }}
|
{{- if .Values.serviceAccount.create }}
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ServiceAccount
|
kind: ServiceAccount
|
||||||
metadata:
|
metadata:
|
||||||
namespace: {{ .Release.Namespace }}
|
namespace: {{ .Release.Namespace }}
|
||||||
name: {{ include "emqx.fullname" . }}
|
name: {{ include "emqx.serviceAccountName" . }}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: {{ include "emqx.name" . }}
|
||||||
|
helm.sh/chart: {{ include "emqx.chart" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
{{- with .Values.serviceAccount.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- if eq (.Values.emqxConfig.EMQX_CLUSTER__DISCOVERY | default "k8s") "k8s" }}
|
||||||
kind: Role
|
kind: Role
|
||||||
{{- if semverCompare ">=1.17-0" .Capabilities.KubeVersion.GitVersion }}
|
{{- if semverCompare ">=1.17-0" .Capabilities.KubeVersion.GitVersion }}
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
@ -23,7 +36,12 @@ rules:
|
||||||
- get
|
- get
|
||||||
- watch
|
- watch
|
||||||
- list
|
- list
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
{{- if .Values.serviceAccount.create }}
|
||||||
|
{{- if eq (.Values.emqxConfig.EMQX_CLUSTER__DISCOVERY | default "k8s") "k8s" }}
|
||||||
kind: RoleBinding
|
kind: RoleBinding
|
||||||
{{- if semverCompare ">=1.17-0" .Capabilities.KubeVersion.GitVersion }}
|
{{- if semverCompare ">=1.17-0" .Capabilities.KubeVersion.GitVersion }}
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
@ -35,10 +53,11 @@ metadata:
|
||||||
name: {{ include "emqx.fullname" . }}
|
name: {{ include "emqx.fullname" . }}
|
||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: {{ include "emqx.fullname" . }}
|
name: {{ include "emqx.serviceAccountName" . }}
|
||||||
namespace: {{ .Release.Namespace }}
|
namespace: {{ .Release.Namespace }}
|
||||||
roleRef:
|
roleRef:
|
||||||
kind: Role
|
kind: Role
|
||||||
name: {{ include "emqx.fullname" . }}
|
name: {{ include "emqx.fullname" . }}
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
|
@ -14,6 +14,16 @@ image:
|
||||||
# pullSecrets:
|
# pullSecrets:
|
||||||
# - myRegistryKeySecretName
|
# - myRegistryKeySecretName
|
||||||
|
|
||||||
|
serviceAccount:
|
||||||
|
# Specifies whether a service account should be created
|
||||||
|
# If set false, means you need create service account by yourself
|
||||||
|
create: true
|
||||||
|
# The name of the service account to use.
|
||||||
|
# If not set and create is true, a name is generated using the fullname template
|
||||||
|
name: ""
|
||||||
|
# Annotations to add to the service account
|
||||||
|
annotations: {}
|
||||||
|
|
||||||
## Forces the recreation of pods during helm upgrades. This can be useful to update configuration values even if the container image did not change.
|
## Forces the recreation of pods during helm upgrades. This can be useful to update configuration values even if the container image did not change.
|
||||||
recreatePods: false
|
recreatePods: false
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ reload(Env) ->
|
||||||
unload(Env), load(Env).
|
unload(Env), load(Env).
|
||||||
|
|
||||||
description() ->
|
description() ->
|
||||||
"EMQ X Internal ACL Module".
|
"EMQX Internal ACL Module".
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% ACL callbacks
|
%% ACL callbacks
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
-include_lib("emqx/include/emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
-logger_header("[Delayed]").
|
-logger_header("[Delayed]").
|
||||||
|
|
||||||
|
@ -94,7 +95,7 @@ unload(_Env) ->
|
||||||
emqx_mod_sup:stop_child(?MODULE).
|
emqx_mod_sup:stop_child(?MODULE).
|
||||||
|
|
||||||
description() ->
|
description() ->
|
||||||
"EMQ X Delayed Publish Module".
|
"EMQX Delayed Publish Module".
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Hooks
|
%% Hooks
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -228,7 +229,20 @@ do_publish(Key = {Ts, _Id}, Now, Acc) when Ts =< Now ->
|
||||||
case mnesia:dirty_read(?TAB, Key) of
|
case mnesia:dirty_read(?TAB, Key) of
|
||||||
[] -> ok;
|
[] -> ok;
|
||||||
[#delayed_message{msg = Msg}] ->
|
[#delayed_message{msg = Msg}] ->
|
||||||
emqx_pool:async_submit(fun emqx:publish/1, [Msg])
|
case emqx_banned:look_up({clientid, Msg#message.from}) of
|
||||||
|
[] ->
|
||||||
|
emqx_pool:async_submit(fun emqx:publish/1, [Msg]);
|
||||||
|
_ ->
|
||||||
|
?tp(
|
||||||
|
notice,
|
||||||
|
ignore_delayed_message_publish,
|
||||||
|
#{
|
||||||
|
reason => "client is banned",
|
||||||
|
clienid => Msg#message.from
|
||||||
|
}
|
||||||
|
),
|
||||||
|
ok
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
do_publish(mnesia:dirty_next(?TAB, Key), Now, [Key|Acc]).
|
do_publish(mnesia:dirty_next(?TAB, Key), Now, [Key|Acc]).
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ unload(_Env) ->
|
||||||
emqx_hooks:del('client.disconnected', {?MODULE, on_client_disconnected}).
|
emqx_hooks:del('client.disconnected', {?MODULE, on_client_disconnected}).
|
||||||
|
|
||||||
description() ->
|
description() ->
|
||||||
"EMQ X Presence Module".
|
"EMQX Presence Module".
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Callbacks
|
%% Callbacks
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -71,7 +71,7 @@ unload(_) ->
|
||||||
emqx_hooks:del('message.publish', {?MODULE, rewrite_publish}).
|
emqx_hooks:del('message.publish', {?MODULE, rewrite_publish}).
|
||||||
|
|
||||||
description() ->
|
description() ->
|
||||||
"EMQ X Topic Rewrite Module".
|
"EMQX Topic Rewrite Module".
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Internal functions
|
%% Internal functions
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -46,4 +46,4 @@ unload(_Env) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
description() ->
|
description() ->
|
||||||
"EMQ X Slow Subscribers Statistics Module".
|
"EMQX Slow Subscribers Statistics Module".
|
||||||
|
|
|
@ -71,7 +71,7 @@ unload(_) ->
|
||||||
emqx_hooks:del('client.connected', {?MODULE, on_client_connected}).
|
emqx_hooks:del('client.connected', {?MODULE, on_client_connected}).
|
||||||
|
|
||||||
description() ->
|
description() ->
|
||||||
"EMQ X Subscription Module".
|
"EMQX Subscription Module".
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Internal functions
|
%% Internal functions
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -113,7 +113,7 @@ unload(_Env) ->
|
||||||
emqx_mod_sup:stop_child(?MODULE).
|
emqx_mod_sup:stop_child(?MODULE).
|
||||||
|
|
||||||
description() ->
|
description() ->
|
||||||
"EMQ X Topic Metrics Module".
|
"EMQX Topic Metrics Module".
|
||||||
|
|
||||||
on_message_publish(#message{topic = Topic, qos = QoS}) ->
|
on_message_publish(#message{topic = Topic, qos = QoS}) ->
|
||||||
case is_registered(Topic) of
|
case is_registered(Topic) of
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
-spec description() -> string().
|
-spec description() -> string().
|
||||||
description() ->
|
description() ->
|
||||||
"EMQ X Trace Module".
|
"EMQX Trace Module".
|
||||||
|
|
||||||
-spec load(any()) -> ok.
|
-spec load(any()) -> ok.
|
||||||
load(_Env) ->
|
load(_Env) ->
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_modules,
|
{application, emqx_modules,
|
||||||
[{description, "EMQ X Module Management"},
|
[{description, "EMQ X Module Management"},
|
||||||
{vsn, "4.4.8"},
|
{vsn, "4.4.9"},
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{applications, [kernel,stdlib]},
|
{applications, [kernel,stdlib]},
|
||||||
{mod, {emqx_modules_app, []}},
|
{mod, {emqx_modules_app, []}},
|
||||||
|
|
|
@ -1,81 +1,75 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.4.7",[{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}]},
|
[{<<"4\\.4\\.[6-8]">>,
|
||||||
{"4.4.6",
|
[{load_module,emqx_mod_acl_internal,brutal_purge,soft_purge,[]},
|
||||||
[{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.5",
|
|
||||||
[{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_modules,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.4",
|
|
||||||
[{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_modules,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.3",
|
|
||||||
[{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_modules,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.2",
|
|
||||||
[{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_modules,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.1",
|
|
||||||
[{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_modules,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_subscription,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.0",
|
|
||||||
[{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_modules,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_subscription,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_mod_presence,brutal_purge,soft_purge,[]},
|
{load_module,emqx_mod_presence,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_mod_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_mod_slow_subs,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_subscription,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_topic_metrics,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_trace,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
|
{<<"4\\.4\\.[1-5]">>,
|
||||||
|
[{load_module,emqx_mod_acl_internal,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_presence,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_slow_subs,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_subscription,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_topic_metrics,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_trace,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_modules,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
|
{"4.4.0",
|
||||||
|
[{load_module,emqx_mod_acl_internal,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_presence,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_slow_subs,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_subscription,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_topic_metrics,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_trace,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_modules,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_sup,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.4.7",[{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}]},
|
[{<<"4\\.4\\.[6-8]">>,
|
||||||
{"4.4.6",
|
[{load_module,emqx_mod_acl_internal,brutal_purge,soft_purge,[]},
|
||||||
[{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.5",
|
|
||||||
[{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_modules,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.4",
|
|
||||||
[{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_modules,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.3",
|
|
||||||
[{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_modules,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.2",
|
|
||||||
[{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_modules,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.1",
|
|
||||||
[{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_modules,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_subscription,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.4.0",
|
|
||||||
[{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_modules,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_subscription,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_mod_presence,brutal_purge,soft_purge,[]},
|
{load_module,emqx_mod_presence,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_mod_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_mod_slow_subs,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_subscription,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_topic_metrics,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_trace,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
|
{<<"4\\.4\\.[1-5]">>,
|
||||||
|
[{load_module,emqx_mod_acl_internal,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_presence,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_slow_subs,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_subscription,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_topic_metrics,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_trace,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_modules,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
|
{"4.4.0",
|
||||||
|
[{load_module,emqx_mod_acl_internal,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_delayed,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_presence,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_slow_subs,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_subscription,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_topic_metrics,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_trace,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_trace_api,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_modules,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_mod_sup,brutal_purge,soft_purge,[]}
|
||||||
|
]},
|
||||||
{<<".*">>,[]}]}.
|
{<<".*">>,[]}]}.
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
-include_lib("emqx/include/emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Setups
|
%% Setups
|
||||||
|
@ -78,3 +79,46 @@ t_delayed_message(_) ->
|
||||||
EmptyKey = mnesia:dirty_all_keys(emqx_mod_delayed),
|
EmptyKey = mnesia:dirty_all_keys(emqx_mod_delayed),
|
||||||
?assertEqual([], EmptyKey),
|
?assertEqual([], EmptyKey),
|
||||||
ok = emqx_mod_delayed:unload([]).
|
ok = emqx_mod_delayed:unload([]).
|
||||||
|
|
||||||
|
t_banned_delayed(_) ->
|
||||||
|
ok = emqx_mod_delayed:load([]),
|
||||||
|
ClientId1 = <<"bc1">>,
|
||||||
|
ClientId2 = <<"bc2">>,
|
||||||
|
|
||||||
|
Now = erlang:system_time(second),
|
||||||
|
Who = {clientid, ClientId2},
|
||||||
|
emqx_banned:create(#{
|
||||||
|
who => Who,
|
||||||
|
by => <<"test">>,
|
||||||
|
reason => <<"test">>,
|
||||||
|
at => Now,
|
||||||
|
until => Now + 120
|
||||||
|
}),
|
||||||
|
|
||||||
|
snabbkaffe:start_trace(),
|
||||||
|
|
||||||
|
{ok, SubRef} =
|
||||||
|
snabbkaffe_collector:subscribe(?match_event(#{?snk_kind := ignore_delayed_message_publish}),
|
||||||
|
_NEvents = 2,
|
||||||
|
_Timeout = 10000,
|
||||||
|
0),
|
||||||
|
|
||||||
|
lists:foreach(
|
||||||
|
fun(ClientId) ->
|
||||||
|
Msg = emqx_message:make(ClientId, <<"$delayed/1/bc">>, <<"payload">>),
|
||||||
|
emqx_mod_delayed:on_message_publish(Msg)
|
||||||
|
end,
|
||||||
|
[ClientId1, ClientId1, ClientId1, ClientId2, ClientId2]
|
||||||
|
),
|
||||||
|
|
||||||
|
?assertMatch({ok, [#{?snk_kind := ignore_delayed_message_publish},
|
||||||
|
#{?snk_kind := ignore_delayed_message_publish}
|
||||||
|
]},
|
||||||
|
snabbkaffe_collector:receive_events(SubRef)),
|
||||||
|
|
||||||
|
snabbkaffe:stop(),
|
||||||
|
|
||||||
|
emqx_banned:delete(Who),
|
||||||
|
EmptyKey = mnesia:dirty_all_keys(emqx_mod_delayed),
|
||||||
|
?assertEqual([], EmptyKey),
|
||||||
|
ok = emqx_mod_delayed:unload([]).
|
||||||
|
|
11
rebar.config
11
rebar.config
|
@ -41,19 +41,19 @@
|
||||||
[ {gpb, "4.11.2"} %% gpb only used to build, but not for release, pin it here to avoid fetching a wrong version due to rebar plugins scattered in all the deps
|
[ {gpb, "4.11.2"} %% gpb only used to build, but not for release, pin it here to avoid fetching a wrong version due to rebar plugins scattered in all the deps
|
||||||
, {redbug, "2.0.7"}
|
, {redbug, "2.0.7"}
|
||||||
, {covertool, {git, "https://github.com/zmstone/covertool", {tag, "2.0.4.1"}}}
|
, {covertool, {git, "https://github.com/zmstone/covertool", {tag, "2.0.4.1"}}}
|
||||||
, {ehttpc, {git, "https://github.com/emqx/ehttpc", {tag, "0.4.2"}}}
|
, {ehttpc, {git, "https://github.com/emqx/ehttpc", {tag, "0.4.4"}}}
|
||||||
, {gun, {git, "https://github.com/emqx/gun", {tag, "1.3.8"}}}
|
, {gun, {git, "https://github.com/emqx/gun", {tag, "1.3.8"}}}
|
||||||
, {eredis_cluster, {git, "https://github.com/emqx/eredis_cluster", {tag, "0.7.4"}}}
|
, {eredis_cluster, {git, "https://github.com/emqx/eredis_cluster", {tag, "0.7.4"}}}
|
||||||
, {gproc, {git, "https://github.com/uwiger/gproc", {tag, "0.9.0"}}}
|
, {gproc, {git, "https://github.com/uwiger/gproc", {tag, "0.9.0"}}}
|
||||||
, {jiffy, {git, "https://github.com/emqx/jiffy", {tag, "1.0.5"}}}
|
, {jiffy, {git, "https://github.com/emqx/jiffy", {tag, "1.0.5"}}}
|
||||||
, {cowboy, {git, "https://github.com/emqx/cowboy", {tag, "2.9.0"}}}
|
, {cowboy, {git, "https://github.com/emqx/cowboy", {tag, "2.9.1"}}}
|
||||||
, {esockd, {git, "https://github.com/emqx/esockd", {tag, "5.8.7"}}}
|
, {esockd, {git, "https://github.com/emqx/esockd", {tag, "5.8.8"}}}
|
||||||
, {ekka, {git, "https://github.com/emqx/ekka", {tag, "0.8.1.11"}}}
|
, {ekka, {git, "https://github.com/emqx/ekka", {tag, "0.8.1.11"}}}
|
||||||
, {gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "3.0.1"}}}
|
, {gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "3.0.1"}}}
|
||||||
, {cuttlefish, {git, "https://github.com/emqx/cuttlefish", {tag, "v3.3.6"}}}
|
, {cuttlefish, {git, "https://github.com/emqx/cuttlefish", {tag, "v3.3.6"}}}
|
||||||
, {minirest, {git, "https://github.com/emqx/minirest", {tag, "0.3.10"}}}
|
, {minirest, {git, "https://github.com/emqx/minirest", {tag, "0.3.11"}}}
|
||||||
, {ecpool, {git, "https://github.com/emqx/ecpool", {tag, "0.5.2"}}}
|
, {ecpool, {git, "https://github.com/emqx/ecpool", {tag, "0.5.2"}}}
|
||||||
, {replayq, {git, "https://github.com/emqx/replayq", {tag, "0.3.4"}}}
|
, {replayq, {git, "https://github.com/emqx/replayq", {tag, "0.3.5"}}}
|
||||||
, {pbkdf2, {git, "https://github.com/emqx/erlang-pbkdf2.git", {branch, "2.0.4"}}}
|
, {pbkdf2, {git, "https://github.com/emqx/erlang-pbkdf2.git", {branch, "2.0.4"}}}
|
||||||
, {emqtt, {git, "https://github.com/emqx/emqtt", {tag, "1.2.3.1"}}}
|
, {emqtt, {git, "https://github.com/emqx/emqtt", {tag, "1.2.3.1"}}}
|
||||||
, {rulesql, {git, "https://github.com/emqx/rulesql", {tag, "0.1.5"}}}
|
, {rulesql, {git, "https://github.com/emqx/rulesql", {tag, "0.1.5"}}}
|
||||||
|
@ -63,6 +63,7 @@
|
||||||
, {snabbkaffe, {git, "https://github.com/kafka4beam/snabbkaffe.git", {tag, "1.0.3"}}}
|
, {snabbkaffe, {git, "https://github.com/kafka4beam/snabbkaffe.git", {tag, "1.0.3"}}}
|
||||||
, {lc, {git, "https://github.com/emqx/lc.git", {tag, "0.3.2"}}}
|
, {lc, {git, "https://github.com/emqx/lc.git", {tag, "0.3.2"}}}
|
||||||
, {mongodb, {git,"https://github.com/emqx/mongodb-erlang", {tag, "v3.0.19"}}}
|
, {mongodb, {git,"https://github.com/emqx/mongodb-erlang", {tag, "v3.0.19"}}}
|
||||||
|
, {mysql, {git, "https://github.com/emqx/mysql-otp", {tag, "1.7.2"}}}
|
||||||
, {epgsql, {git, "https://github.com/emqx/epgsql.git", {tag, "4.6.0"}}}
|
, {epgsql, {git, "https://github.com/emqx/epgsql.git", {tag, "4.6.0"}}}
|
||||||
, {grpc, {git, "https://github.com/emqx/grpc-erl", {tag, "0.6.7"}}}
|
, {grpc, {git, "https://github.com/emqx/grpc-erl", {tag, "0.6.7"}}}
|
||||||
]}.
|
]}.
|
||||||
|
|
|
@ -176,6 +176,11 @@ filter_froms(Froms0, AvailableVersionsIndex) ->
|
||||||
{"amzn2", _} ->
|
{"amzn2", _} ->
|
||||||
Excluded = [list_to_binary(["4.4.", integer_to_list(X)]) || X <- lists:seq(0,11)],
|
Excluded = [list_to_binary(["4.4.", integer_to_list(X)]) || X <- lists:seq(0,11)],
|
||||||
lists:filter(fun(Vsn) -> not lists:member(Vsn, Excluded) end, Froms0);
|
lists:filter(fun(Vsn) -> not lists:member(Vsn, Excluded) end, Froms0);
|
||||||
|
%% ubuntu22.04 is introduced since v4.4.15 and e4.4.15
|
||||||
|
%% exclude tags before them
|
||||||
|
{"ubuntu22.04", _} ->
|
||||||
|
Excluded = [list_to_binary(["4.4.", integer_to_list(X)]) || X <- lists:seq(0,14)],
|
||||||
|
lists:filter(fun(Vsn) -> not lists:member(Vsn, Excluded) end, Froms0);
|
||||||
%% macos arm64 (M1/M2) packages are introduced since v4.4.12 and e4.4.12
|
%% macos arm64 (M1/M2) packages are introduced since v4.4.12 and e4.4.12
|
||||||
%% exclude tags before them
|
%% exclude tags before them
|
||||||
{"macos" ++ _, "aarch64" ++ _} ->
|
{"macos" ++ _, "aarch64" ++ _} ->
|
||||||
|
|
|
@ -2,23 +2,57 @@
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{"4.4.14",
|
[{"4.4.14",
|
||||||
[{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.13",
|
{"4.4.13",
|
||||||
[{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_app,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.12",
|
{"4.4.12",
|
||||||
[{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_app,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.11",
|
{"4.4.11",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{add_module,emqx_cover},
|
{add_module,emqx_cover},
|
||||||
|
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
||||||
|
@ -26,7 +60,12 @@
|
||||||
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_channel,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_channel,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.10",
|
{"4.4.10",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{add_module,emqx_cover},
|
{add_module,emqx_cover},
|
||||||
{add_module,emqx_ocsp_cache},
|
{add_module,emqx_ocsp_cache},
|
||||||
{add_module,emqx_crl_cache},
|
{add_module,emqx_crl_cache},
|
||||||
|
@ -47,7 +86,12 @@
|
||||||
{apply,{application,set_env,
|
{apply,{application,set_env,
|
||||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||||
{"4.4.9",
|
{"4.4.9",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{add_module,emqx_cover},
|
{add_module,emqx_cover},
|
||||||
{add_module,emqx_ocsp_cache},
|
{add_module,emqx_ocsp_cache},
|
||||||
{add_module,emqx_crl_cache},
|
{add_module,emqx_crl_cache},
|
||||||
|
@ -74,7 +118,12 @@
|
||||||
{apply,{application,set_env,
|
{apply,{application,set_env,
|
||||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||||
{"4.4.8",
|
{"4.4.8",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{add_module,emqx_cover},
|
{add_module,emqx_cover},
|
||||||
{add_module,emqx_ocsp_cache},
|
{add_module,emqx_ocsp_cache},
|
||||||
{add_module,emqx_crl_cache},
|
{add_module,emqx_crl_cache},
|
||||||
|
@ -102,7 +151,12 @@
|
||||||
{apply,{application,set_env,
|
{apply,{application,set_env,
|
||||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||||
{"4.4.7",
|
{"4.4.7",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{add_module,emqx_cover},
|
{add_module,emqx_cover},
|
||||||
{add_module,emqx_ocsp_cache},
|
{add_module,emqx_ocsp_cache},
|
||||||
{add_module,emqx_crl_cache},
|
{add_module,emqx_crl_cache},
|
||||||
|
@ -130,7 +184,12 @@
|
||||||
{apply,{application,set_env,
|
{apply,{application,set_env,
|
||||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||||
{"4.4.6",
|
{"4.4.6",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{add_module,emqx_cover},
|
{add_module,emqx_cover},
|
||||||
{add_module,emqx_ocsp_cache},
|
{add_module,emqx_ocsp_cache},
|
||||||
{add_module,emqx_crl_cache},
|
{add_module,emqx_crl_cache},
|
||||||
|
@ -158,7 +217,12 @@
|
||||||
{apply,{application,set_env,
|
{apply,{application,set_env,
|
||||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||||
{"4.4.5",
|
{"4.4.5",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{add_module,emqx_cover},
|
{add_module,emqx_cover},
|
||||||
{add_module,emqx_ocsp_cache},
|
{add_module,emqx_ocsp_cache},
|
||||||
{add_module,emqx_crl_cache},
|
{add_module,emqx_crl_cache},
|
||||||
|
@ -188,7 +252,11 @@
|
||||||
{apply,{application,set_env,
|
{apply,{application,set_env,
|
||||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||||
{"4.4.4",
|
{"4.4.4",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{add_module,emqx_cover},
|
{add_module,emqx_cover},
|
||||||
{add_module,emqx_ocsp_cache},
|
{add_module,emqx_ocsp_cache},
|
||||||
{add_module,emqx_crl_cache},
|
{add_module,emqx_crl_cache},
|
||||||
|
@ -225,7 +293,10 @@
|
||||||
{apply,{application,set_env,
|
{apply,{application,set_env,
|
||||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||||
{"4.4.3",
|
{"4.4.3",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
{add_module,emqx_cover},
|
{add_module,emqx_cover},
|
||||||
{add_module,emqx_ocsp_cache},
|
{add_module,emqx_ocsp_cache},
|
||||||
{add_module,emqx_crl_cache},
|
{add_module,emqx_crl_cache},
|
||||||
|
@ -269,7 +340,10 @@
|
||||||
{apply,{application,set_env,
|
{apply,{application,set_env,
|
||||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||||
{"4.4.2",
|
{"4.4.2",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
{add_module,emqx_cover},
|
{add_module,emqx_cover},
|
||||||
{add_module,emqx_ocsp_cache},
|
{add_module,emqx_ocsp_cache},
|
||||||
{add_module,emqx_crl_cache},
|
{add_module,emqx_crl_cache},
|
||||||
|
@ -314,7 +388,9 @@
|
||||||
{apply,{application,set_env,
|
{apply,{application,set_env,
|
||||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||||
{"4.4.1",
|
{"4.4.1",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
{add_module,emqx_cover},
|
{add_module,emqx_cover},
|
||||||
{add_module,emqx_ocsp_cache},
|
{add_module,emqx_ocsp_cache},
|
||||||
{add_module,emqx_crl_cache},
|
{add_module,emqx_crl_cache},
|
||||||
|
@ -364,7 +440,9 @@
|
||||||
{apply,{application,set_env,
|
{apply,{application,set_env,
|
||||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||||
{"4.4.0",
|
{"4.4.0",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
{add_module,emqx_cover},
|
{add_module,emqx_cover},
|
||||||
{add_module,emqx_ocsp_cache},
|
{add_module,emqx_ocsp_cache},
|
||||||
{add_module,emqx_crl_cache},
|
{add_module,emqx_crl_cache},
|
||||||
|
@ -417,22 +495,56 @@
|
||||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{"4.4.14",
|
[{"4.4.14",
|
||||||
[{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.13",
|
{"4.4.13",
|
||||||
[{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_app,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.12",
|
{"4.4.12",
|
||||||
[{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_app,brutal_purge,soft_purge,[]}]},
|
||||||
{"4.4.11",
|
{"4.4.11",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||||
|
@ -441,7 +553,12 @@
|
||||||
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
||||||
{delete_module,emqx_cover}]},
|
{delete_module,emqx_cover}]},
|
||||||
{"4.4.10",
|
{"4.4.10",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
|
@ -459,7 +576,12 @@
|
||||||
{delete_module,emqx_crl_cache},
|
{delete_module,emqx_crl_cache},
|
||||||
{delete_module,emqx_ocsp_cache}]},
|
{delete_module,emqx_ocsp_cache}]},
|
||||||
{"4.4.9",
|
{"4.4.9",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
|
@ -482,7 +604,12 @@
|
||||||
{delete_module,emqx_crl_cache},
|
{delete_module,emqx_crl_cache},
|
||||||
{delete_module,emqx_ocsp_cache}]},
|
{delete_module,emqx_ocsp_cache}]},
|
||||||
{"4.4.8",
|
{"4.4.8",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
|
@ -506,7 +633,12 @@
|
||||||
{delete_module,emqx_crl_cache},
|
{delete_module,emqx_crl_cache},
|
||||||
{delete_module,emqx_ocsp_cache}]},
|
{delete_module,emqx_ocsp_cache}]},
|
||||||
{"4.4.7",
|
{"4.4.7",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
|
@ -530,7 +662,12 @@
|
||||||
{delete_module,emqx_crl_cache},
|
{delete_module,emqx_crl_cache},
|
||||||
{delete_module,emqx_ocsp_cache}]},
|
{delete_module,emqx_ocsp_cache}]},
|
||||||
{"4.4.6",
|
{"4.4.6",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
|
@ -554,7 +691,12 @@
|
||||||
{delete_module,emqx_crl_cache},
|
{delete_module,emqx_crl_cache},
|
||||||
{delete_module,emqx_ocsp_cache}]},
|
{delete_module,emqx_ocsp_cache}]},
|
||||||
{"4.4.5",
|
{"4.4.5",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_broker,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||||
|
@ -580,7 +722,11 @@
|
||||||
{delete_module,emqx_crl_cache},
|
{delete_module,emqx_crl_cache},
|
||||||
{delete_module,emqx_ocsp_cache}]},
|
{delete_module,emqx_ocsp_cache}]},
|
||||||
{"4.4.4",
|
{"4.4.4",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
|
@ -613,7 +759,10 @@
|
||||||
{delete_module,emqx_crl_cache},
|
{delete_module,emqx_crl_cache},
|
||||||
{delete_module,emqx_ocsp_cache}]},
|
{delete_module,emqx_ocsp_cache}]},
|
||||||
{"4.4.3",
|
{"4.4.3",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||||
|
@ -652,7 +801,10 @@
|
||||||
{delete_module,emqx_crl_cache},
|
{delete_module,emqx_crl_cache},
|
||||||
{delete_module,emqx_ocsp_cache}]},
|
{delete_module,emqx_ocsp_cache}]},
|
||||||
{"4.4.2",
|
{"4.4.2",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_banned,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
{load_module,emqx_listeners,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_router_helper,brutal_purge,soft_purge,[]},
|
{load_module,emqx_router_helper,brutal_purge,soft_purge,[]},
|
||||||
|
@ -692,7 +844,9 @@
|
||||||
{delete_module,emqx_crl_cache},
|
{delete_module,emqx_crl_cache},
|
||||||
{delete_module,emqx_ocsp_cache}]},
|
{delete_module,emqx_ocsp_cache}]},
|
||||||
{"4.4.1",
|
{"4.4.1",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_router_helper,brutal_purge,soft_purge,[]},
|
{load_module,emqx_router_helper,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
||||||
|
@ -737,7 +891,9 @@
|
||||||
{delete_module,emqx_crl_cache},
|
{delete_module,emqx_crl_cache},
|
||||||
{delete_module,emqx_ocsp_cache}]},
|
{delete_module,emqx_ocsp_cache}]},
|
||||||
{"4.4.0",
|
{"4.4.0",
|
||||||
[{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_vm,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_keepalive,brutal_purge,soft_purge,[]},
|
||||||
|
{load_module,emqx_rule_actions_trans,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
{load_module,emqx_kernel_sup,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_router_helper,brutal_purge,soft_purge,[]},
|
{load_module,emqx_router_helper,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_router,brutal_purge,soft_purge,[]},
|
{load_module,emqx_router,brutal_purge,soft_purge,[]},
|
||||||
|
|
58
src/emqx.erl
58
src/emqx.erl
|
@ -65,6 +65,8 @@
|
||||||
|
|
||||||
%% Troubleshooting
|
%% Troubleshooting
|
||||||
-export([ set_debug_secret/1
|
-export([ set_debug_secret/1
|
||||||
|
, default_started_applications/0
|
||||||
|
, expand_apps/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-define(APP, ?MODULE).
|
-define(APP, ?MODULE).
|
||||||
|
@ -252,14 +254,6 @@ is_application_running(App) ->
|
||||||
StartedApps = proplists:get_value(started, application:info()),
|
StartedApps = proplists:get_value(started, application:info()),
|
||||||
proplists:is_defined(App, StartedApps).
|
proplists:is_defined(App, StartedApps).
|
||||||
|
|
||||||
-ifdef(EMQX_ENTERPRISE).
|
|
||||||
default_started_applications() ->
|
|
||||||
[gproc, esockd, ranch, cowboy, ekka, emqx].
|
|
||||||
-else.
|
|
||||||
default_started_applications() ->
|
|
||||||
[gproc, esockd, ranch, cowboy, ekka, emqx, emqx_modules].
|
|
||||||
-endif.
|
|
||||||
|
|
||||||
-ifdef(EMQX_ENTERPRISE).
|
-ifdef(EMQX_ENTERPRISE).
|
||||||
on_reboot() ->
|
on_reboot() ->
|
||||||
try
|
try
|
||||||
|
@ -290,6 +284,54 @@ on_shutdown(_) ->
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Internal functions
|
%% Internal functions
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
-ifdef(EMQX_ENTERPRISE).
|
||||||
|
applications_need_restart() ->
|
||||||
|
[gproc, esockd, ranch, cowboy, ekka, emqx].
|
||||||
|
-else.
|
||||||
|
applications_need_restart() ->
|
||||||
|
[gproc, esockd, ranch, cowboy, ekka, emqx, emqx_modules].
|
||||||
|
-endif.
|
||||||
|
|
||||||
|
-define(PK_START_APPS, {?MODULE, default_started_applications}).
|
||||||
|
default_started_applications() ->
|
||||||
|
case persistent_term:get(?PK_START_APPS, undefined) of
|
||||||
|
undefined ->
|
||||||
|
AppNames = expand_apps(applications_need_restart()),
|
||||||
|
ok = persistent_term:put(?PK_START_APPS, AppNames),
|
||||||
|
AppNames;
|
||||||
|
AppNames ->
|
||||||
|
AppNames
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% expand the application list with dependent apps.
|
||||||
|
expand_apps(AppNames) ->
|
||||||
|
AllApps = application:which_applications(),
|
||||||
|
remove_duplicated(
|
||||||
|
lists:flatmap(fun(AppName) ->
|
||||||
|
expand_an_app(AppName, AllApps)
|
||||||
|
end, AppNames)).
|
||||||
|
|
||||||
|
expand_an_app(AppNameA, AllApps) ->
|
||||||
|
expand_an_app(AppNameA, AllApps, [AppNameA]).
|
||||||
|
|
||||||
|
expand_an_app(_AppNameA, [], Acc) ->
|
||||||
|
Acc;
|
||||||
|
expand_an_app(AppNameA, [{AppNameB, _Descr, _Vsn} | AllApps], Acc) ->
|
||||||
|
{ok, DepAppNames} = application:get_key(AppNameB, applications),
|
||||||
|
case lists:member(AppNameA, DepAppNames) of
|
||||||
|
true -> %% AppNameB depends on AppNameA
|
||||||
|
NewAcc = Acc ++ expand_an_app(AppNameB, AllApps),
|
||||||
|
expand_an_app(AppNameA, AllApps, NewAcc);
|
||||||
|
false ->
|
||||||
|
expand_an_app(AppNameA, AllApps, Acc)
|
||||||
|
end.
|
||||||
|
|
||||||
|
remove_duplicated([]) -> [];
|
||||||
|
remove_duplicated([E | Elems]) ->
|
||||||
|
case lists:member(E, Elems) of
|
||||||
|
true -> remove_duplicated(Elems);
|
||||||
|
false -> [E] ++ remove_duplicated(Elems)
|
||||||
|
end.
|
||||||
|
|
||||||
reload_config(ConfFile) ->
|
reload_config(ConfFile) ->
|
||||||
{ok, [Conf]} = file:consult(ConfFile),
|
{ok, [Conf]} = file:consult(ConfFile),
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
-include("emqx.hrl").
|
-include("emqx.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("types.hrl").
|
-include("types.hrl").
|
||||||
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
-logger_header("[Banned]").
|
-logger_header("[Banned]").
|
||||||
|
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
, create/1
|
, create/1
|
||||||
, delete/1
|
, delete/1
|
||||||
, info/1
|
, info/1
|
||||||
|
, look_up/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
|
@ -94,13 +96,15 @@ create(#{who := Who,
|
||||||
reason := Reason,
|
reason := Reason,
|
||||||
at := At,
|
at := At,
|
||||||
until := Until}) ->
|
until := Until}) ->
|
||||||
mnesia:dirty_write(?BANNED_TAB, #banned{who = Who,
|
insert_banned(#banned{
|
||||||
by = By,
|
who = Who,
|
||||||
reason = Reason,
|
by = By,
|
||||||
at = At,
|
reason = Reason,
|
||||||
until = Until});
|
at = At,
|
||||||
|
until = Until
|
||||||
|
});
|
||||||
create(Banned) when is_record(Banned, banned) ->
|
create(Banned) when is_record(Banned, banned) ->
|
||||||
mnesia:dirty_write(?BANNED_TAB, Banned).
|
insert_banned(Banned).
|
||||||
|
|
||||||
-spec(delete({clientid, emqx_types:clientid()}
|
-spec(delete({clientid, emqx_types:clientid()}
|
||||||
| {username, emqx_types:username()}
|
| {username, emqx_types:username()}
|
||||||
|
@ -111,6 +115,9 @@ delete(Who) ->
|
||||||
info(InfoKey) ->
|
info(InfoKey) ->
|
||||||
mnesia:table_info(?BANNED_TAB, InfoKey).
|
mnesia:table_info(?BANNED_TAB, InfoKey).
|
||||||
|
|
||||||
|
look_up(Who) ->
|
||||||
|
mnesia:dirty_read(?BANNED_TAB, Who).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -159,3 +166,20 @@ expire_banned_items(Now) ->
|
||||||
(_, _Acc) -> ok
|
(_, _Acc) -> ok
|
||||||
end, ok, ?BANNED_TAB).
|
end, ok, ?BANNED_TAB).
|
||||||
|
|
||||||
|
insert_banned(Banned) ->
|
||||||
|
mnesia:dirty_write(?BANNED_TAB, Banned),
|
||||||
|
on_banned(Banned).
|
||||||
|
|
||||||
|
on_banned(#banned{who = {clientid, ClientId}}) ->
|
||||||
|
%% kick the session if the client is banned by clientid
|
||||||
|
?tp(
|
||||||
|
warning,
|
||||||
|
kick_session_due_to_banned,
|
||||||
|
#{
|
||||||
|
clientid => ClientId
|
||||||
|
}
|
||||||
|
),
|
||||||
|
emqx_cm:kick_session(ClientId),
|
||||||
|
ok;
|
||||||
|
on_banned(_) ->
|
||||||
|
ok.
|
||||||
|
|
|
@ -183,8 +183,7 @@ do_unsubscribe(Topic, SubPid, SubOpts) ->
|
||||||
true = ets:delete(?SUBOPTION, {SubPid, Topic}),
|
true = ets:delete(?SUBOPTION, {SubPid, Topic}),
|
||||||
true = ets:delete_object(?SUBSCRIPTION, {SubPid, Topic}),
|
true = ets:delete_object(?SUBSCRIPTION, {SubPid, Topic}),
|
||||||
Group = maps:get(share, SubOpts, undefined),
|
Group = maps:get(share, SubOpts, undefined),
|
||||||
do_unsubscribe(Group, Topic, SubPid, SubOpts),
|
do_unsubscribe(Group, Topic, SubPid, SubOpts).
|
||||||
emqx_exclusive_subscription:unsubscribe(Topic, SubOpts).
|
|
||||||
|
|
||||||
do_unsubscribe(undefined, Topic, SubPid, SubOpts) ->
|
do_unsubscribe(undefined, Topic, SubPid, SubOpts) ->
|
||||||
clean_subscribe(SubOpts, Topic, SubPid);
|
clean_subscribe(SubOpts, Topic, SubPid);
|
||||||
|
@ -344,9 +343,12 @@ subscriber_down(SubPid) ->
|
||||||
|
|
||||||
clean_subscribe(SubOpts, Topic, SubPid) ->
|
clean_subscribe(SubOpts, Topic, SubPid) ->
|
||||||
case maps:get(shard, SubOpts, 0) of
|
case maps:get(shard, SubOpts, 0) of
|
||||||
0 -> true = ets:delete_object(?SUBSCRIBER, {Topic, SubPid}),
|
0 ->
|
||||||
|
true = ets:delete_object(?SUBSCRIBER, {Topic, SubPid}),
|
||||||
|
ok = emqx_exclusive_subscription:unsubscribe(Topic, SubOpts),
|
||||||
ok = cast(pick(Topic), {unsubscribed, Topic});
|
ok = cast(pick(Topic), {unsubscribed, Topic});
|
||||||
I -> true = ets:delete_object(?SUBSCRIBER, {{shard, Topic, I}, SubPid}),
|
I ->
|
||||||
|
true = ets:delete_object(?SUBSCRIBER, {{shard, Topic, I}, SubPid}),
|
||||||
ok = cast(pick({Topic, I}), {unsubscribed, Topic, I})
|
ok = cast(pick({Topic, I}), {unsubscribed, Topic, I})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -434,7 +434,7 @@ handle_msg({'$gen_cast', Req}, State) ->
|
||||||
{ok, NewState};
|
{ok, NewState};
|
||||||
|
|
||||||
handle_msg({Inet, _Sock, Data}, State) when Inet == tcp; Inet == ssl ->
|
handle_msg({Inet, _Sock, Data}, State) when Inet == tcp; Inet == ssl ->
|
||||||
?LOG(debug, "RECV ~0p", [Data]),
|
?LOG(debug, "RECV ~w", [Data]),
|
||||||
Oct = iolist_size(Data),
|
Oct = iolist_size(Data),
|
||||||
inc_counter(incoming_bytes, Oct),
|
inc_counter(incoming_bytes, Oct),
|
||||||
ok = emqx_metrics:inc('bytes.received', Oct),
|
ok = emqx_metrics:inc('bytes.received', Oct),
|
||||||
|
|
|
@ -147,6 +147,7 @@ handle_info({timeout, TRef, {refresh, URL}},
|
||||||
{noreply, ensure_timer(URL, State, ?RETRY_TIMEOUT)};
|
{noreply, ensure_timer(URL, State, ?RETRY_TIMEOUT)};
|
||||||
{ok, _CRLs} ->
|
{ok, _CRLs} ->
|
||||||
?LOG(debug, "fetched crl response for ~p", [URL]),
|
?LOG(debug, "fetched crl response for ~p", [URL]),
|
||||||
|
?tp(crl_refresh_timer_done, #{url => URL}),
|
||||||
{noreply, ensure_timer(URL, State)}
|
{noreply, ensure_timer(URL, State)}
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
|
|
|
@ -73,6 +73,7 @@ check(NewVal, KeepAlive = #keepalive{statval = OldVal,
|
||||||
true -> {error, timeout}
|
true -> {error, timeout}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-define(IS_KEEPALIVE(Interval), Interval >= 0 andalso Interval =< 65535000).
|
||||||
%% from mqtt-v3.1.1 specific
|
%% from mqtt-v3.1.1 specific
|
||||||
%% A Keep Alive value of zero (0) has the effect of turning off the keep alive mechanism.
|
%% A Keep Alive value of zero (0) has the effect of turning off the keep alive mechanism.
|
||||||
%% This means that, in this case, the Server is not required
|
%% This means that, in this case, the Server is not required
|
||||||
|
@ -85,7 +86,10 @@ check(NewVal, KeepAlive = #keepalive{statval = OldVal,
|
||||||
%% typically this is a few minutes.
|
%% typically this is a few minutes.
|
||||||
%% The maximum value is (65535s) 18 hours 12 minutes and 15 seconds.
|
%% The maximum value is (65535s) 18 hours 12 minutes and 15 seconds.
|
||||||
|
|
||||||
%% @doc Update keepalive's interval
|
%% @doc Update keepalive interval
|
||||||
-spec(set(interval, non_neg_integer(), keepalive()) -> keepalive()).
|
%% The keepalive() is undefined when connecting via keepalive=0.
|
||||||
set(interval, Interval, KeepAlive) when Interval >= 0 andalso Interval =< 65535000 ->
|
-spec(set(interval, non_neg_integer(), keepalive() | undefined) -> keepalive()).
|
||||||
|
set(interval, Interval, undefined) when ?IS_KEEPALIVE(Interval) ->
|
||||||
|
init(Interval);
|
||||||
|
set(interval, Interval, KeepAlive) when ?IS_KEEPALIVE(Interval) ->
|
||||||
KeepAlive#keepalive{interval = Interval}.
|
KeepAlive#keepalive{interval = Interval}.
|
||||||
|
|
|
@ -430,7 +430,7 @@ format_header(#mqtt_packet_header{type = Type,
|
||||||
Header = io_lib:format("~s(Q~p, R~p, D~p", [type_name(Type), QoS, i(Retain), i(Dup)]),
|
Header = io_lib:format("~s(Q~p, R~p, D~p", [type_name(Type), QoS, i(Retain), i(Dup)]),
|
||||||
case S == undefined of
|
case S == undefined of
|
||||||
true -> [Header, ")"];
|
true -> [Header, ")"];
|
||||||
false -> [Header, S, ")"]
|
false -> [Header, ", ", S, ")"]
|
||||||
end.
|
end.
|
||||||
|
|
||||||
format_variable(undefined, _) ->
|
format_variable(undefined, _) ->
|
||||||
|
|
|
@ -32,6 +32,7 @@ post_release_upgrade(FromRelVsn, _) ->
|
||||||
{_, CurrRelVsn} = ?EMQX_RELEASE,
|
{_, CurrRelVsn} = ?EMQX_RELEASE,
|
||||||
?INFO("emqx has been upgraded from ~s to ~s!", [FromRelVsn, CurrRelVsn]),
|
?INFO("emqx has been upgraded from ~s to ~s!", [FromRelVsn, CurrRelVsn]),
|
||||||
maybe_refresh_jwt_module(FromRelVsn),
|
maybe_refresh_jwt_module(FromRelVsn),
|
||||||
|
_ = maybe_restart_oracle_resources(FromRelVsn),
|
||||||
reload_components().
|
reload_components().
|
||||||
|
|
||||||
%% What to do after downgraded to an old release vsn.
|
%% What to do after downgraded to an old release vsn.
|
||||||
|
@ -93,3 +94,27 @@ maybe_refresh_jwt_module(_) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
|
|
||||||
|
-ifdef(EMQX_ENTERPRISE).
|
||||||
|
maybe_restart_oracle_resources("4.4." ++ PatchVsn0) ->
|
||||||
|
try
|
||||||
|
case list_to_integer(PatchVsn0) of
|
||||||
|
PatchVsn when PatchVsn =< 14 ->
|
||||||
|
emqx_rule_engine:start_all_resources_of_type(backend_oracle);
|
||||||
|
_ -> ok
|
||||||
|
end
|
||||||
|
catch
|
||||||
|
Err:Reason:ST ->
|
||||||
|
?INFO("maybe_restart_oracle_resources failed: ~p", [{Err, Reason, ST}]),
|
||||||
|
ok
|
||||||
|
end;
|
||||||
|
maybe_restart_oracle_resources(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
-else.
|
||||||
|
|
||||||
|
maybe_restart_oracle_resources(_) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
-endif.
|
||||||
|
|
|
@ -380,14 +380,19 @@ read_otp_version() ->
|
||||||
Filename = filename:join([ReleasesDir, emqx_app:get_release(), "BUILT_ON"]),
|
Filename = filename:join([ReleasesDir, emqx_app:get_release(), "BUILT_ON"]),
|
||||||
case file:read_file(Filename) of
|
case file:read_file(Filename) of
|
||||||
{ok, BuiltOn} ->
|
{ok, BuiltOn} ->
|
||||||
%% running on EQM X release
|
%% running on EQMX release
|
||||||
BuiltOn;
|
BuiltOn;
|
||||||
{error, enoent} ->
|
{error, enoent} ->
|
||||||
%% running tests etc.
|
|
||||||
OtpMajor = erlang:system_info(otp_release),
|
OtpMajor = erlang:system_info(otp_release),
|
||||||
OtpVsnFile = filename:join([ReleasesDir, OtpMajor, "OTP_VERSION"]),
|
OtpVsnFile = filename:join([ReleasesDir, OtpMajor, "OTP_VERSION"]),
|
||||||
{ok, Vsn} = file:read_file(OtpVsnFile),
|
case file:read_file(OtpVsnFile) of
|
||||||
Vsn
|
{ok, Vsn} ->
|
||||||
|
%% this happens when running in test where system's OTP is in use
|
||||||
|
Vsn;
|
||||||
|
_ ->
|
||||||
|
%% when the code is cover-compiled
|
||||||
|
iolist_to_binary(OtpMajor)
|
||||||
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
parse_built_on(BuiltOn) ->
|
parse_built_on(BuiltOn) ->
|
||||||
|
|
|
@ -336,7 +336,7 @@ websocket_handle({binary, Data}, State) when is_list(Data) ->
|
||||||
websocket_handle({binary, iolist_to_binary(Data)}, State);
|
websocket_handle({binary, iolist_to_binary(Data)}, State);
|
||||||
|
|
||||||
websocket_handle({binary, Data}, State) ->
|
websocket_handle({binary, Data}, State) ->
|
||||||
?LOG(debug, "RECV ~0p", [Data]),
|
?LOG(debug, "RECV ~w", [Data]),
|
||||||
ok = inc_recv_stats(1, iolist_size(Data)),
|
ok = inc_recv_stats(1, iolist_size(Data)),
|
||||||
NState = ensure_stats_timer(State),
|
NState = ensure_stats_timer(State),
|
||||||
return(parse_incoming(Data, NState));
|
return(parse_incoming(Data, NState));
|
||||||
|
|
|
@ -21,11 +21,12 @@
|
||||||
|
|
||||||
-include_lib("emqx/include/emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||||
|
|
||||||
all() -> emqx_ct:all(?MODULE).
|
all() -> emqx_ct:all(?MODULE).
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
application:load(emqx),
|
emqx_ct_helpers:start_apps([]),
|
||||||
ok = ekka:start(),
|
ok = ekka:start(),
|
||||||
%% for coverage
|
%% for coverage
|
||||||
ok = emqx_banned:mnesia(copy),
|
ok = emqx_banned:mnesia(copy),
|
||||||
|
@ -34,7 +35,8 @@ init_per_suite(Config) ->
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(_Config) ->
|
||||||
ekka:stop(),
|
ekka:stop(),
|
||||||
ekka_mnesia:ensure_stopped(),
|
ekka_mnesia:ensure_stopped(),
|
||||||
ekka_mnesia:delete_schema().
|
ekka_mnesia:delete_schema(),
|
||||||
|
emqx_ct_helpers:stop_apps([]).
|
||||||
|
|
||||||
t_add_delete(_) ->
|
t_add_delete(_) ->
|
||||||
Banned = #banned{who = {clientid, <<"TestClient">>},
|
Banned = #banned{who = {clientid, <<"TestClient">>},
|
||||||
|
@ -84,7 +86,10 @@ t_check(_) ->
|
||||||
?assertEqual(0, emqx_banned:info(size)).
|
?assertEqual(0, emqx_banned:info(size)).
|
||||||
|
|
||||||
t_unused(_) ->
|
t_unused(_) ->
|
||||||
{ok, Banned} = emqx_banned:start_link(),
|
Banned = case emqx_banned:start_link() of
|
||||||
|
{ok, Pid} -> Pid;
|
||||||
|
{error, {already_started, Pid}} -> Pid
|
||||||
|
end,
|
||||||
ok = emqx_banned:create(#banned{who = {clientid, <<"BannedClient">>},
|
ok = emqx_banned:create(#banned{who = {clientid, <<"BannedClient">>},
|
||||||
until = erlang:system_time(second)}),
|
until = erlang:system_time(second)}),
|
||||||
?assertEqual(ignored, gen_server:call(Banned, unexpected_req)),
|
?assertEqual(ignored, gen_server:call(Banned, unexpected_req)),
|
||||||
|
@ -93,3 +98,22 @@ t_unused(_) ->
|
||||||
timer:sleep(500), %% expiry timer
|
timer:sleep(500), %% expiry timer
|
||||||
ok = emqx_banned:stop().
|
ok = emqx_banned:stop().
|
||||||
|
|
||||||
|
t_kick(_) ->
|
||||||
|
ClientId = <<"client">>,
|
||||||
|
snabbkaffe:start_trace(),
|
||||||
|
|
||||||
|
Now = erlang:system_time(second),
|
||||||
|
Who = {clientid, ClientId},
|
||||||
|
|
||||||
|
emqx_banned:create(#{
|
||||||
|
who => Who,
|
||||||
|
by => <<"test">>,
|
||||||
|
reason => <<"test">>,
|
||||||
|
at => Now,
|
||||||
|
until => Now + 120
|
||||||
|
}),
|
||||||
|
|
||||||
|
Trace = snabbkaffe:collect_trace(),
|
||||||
|
snabbkaffe:stop(),
|
||||||
|
emqx_banned:delete(Who),
|
||||||
|
?assertEqual(1, length(?of_kind(kick_session_due_to_banned, Trace))).
|
||||||
|
|
|
@ -43,7 +43,7 @@ init_per_testcase(TestCase, Config)
|
||||||
TestCase =:= t_filled_cache;
|
TestCase =:= t_filled_cache;
|
||||||
TestCase =:= t_revoked ->
|
TestCase =:= t_revoked ->
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
CRLFile = filename:join([DataDir, "crl.pem"]),
|
CRLFile = filename:join([DataDir, "intermediate-revoked.crl.pem"]),
|
||||||
{ok, CRLPem} = file:read_file(CRLFile),
|
{ok, CRLPem} = file:read_file(CRLFile),
|
||||||
[{'CertificateList', CRLDer, not_encrypted}] = public_key:pem_decode(CRLPem),
|
[{'CertificateList', CRLDer, not_encrypted}] = public_key:pem_decode(CRLPem),
|
||||||
ServerPid = start_crl_server(CRLPem),
|
ServerPid = start_crl_server(CRLPem),
|
||||||
|
@ -53,9 +53,44 @@ init_per_testcase(TestCase, Config)
|
||||||
, {crl_der, CRLDer}
|
, {crl_der, CRLDer}
|
||||||
, {http_server, ServerPid}
|
, {http_server, ServerPid}
|
||||||
| Config];
|
| Config];
|
||||||
|
init_per_testcase(t_revoke_then_refresh, Config) ->
|
||||||
|
DataDir = ?config(data_dir, Config),
|
||||||
|
CRLFileNotRevoked = filename:join([DataDir, "intermediate-not-revoked.crl.pem"]),
|
||||||
|
{ok, CRLPemNotRevoked} = file:read_file(CRLFileNotRevoked),
|
||||||
|
[{'CertificateList', CRLDerNotRevoked, not_encrypted}] = public_key:pem_decode(CRLPemNotRevoked),
|
||||||
|
CRLFileRevoked = filename:join([DataDir, "intermediate-revoked.crl.pem"]),
|
||||||
|
{ok, CRLPemRevoked} = file:read_file(CRLFileRevoked),
|
||||||
|
[{'CertificateList', CRLDerRevoked, not_encrypted}] = public_key:pem_decode(CRLPemRevoked),
|
||||||
|
ServerPid = start_crl_server(CRLPemNotRevoked),
|
||||||
|
OldListeners = emqx:get_env(listeners),
|
||||||
|
OldRefreshInterval = emqx:get_env(crl_cache_refresh_interval),
|
||||||
|
NewRefreshInterval = timer:seconds(10),
|
||||||
|
ExtraHandler =
|
||||||
|
fun(emqx) ->
|
||||||
|
application:set_env(emqx, crl_cache_refresh_interval, NewRefreshInterval),
|
||||||
|
ok;
|
||||||
|
(_) ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
ok = setup_crl_options(Config, #{is_cached => true, extra_handler => ExtraHandler}),
|
||||||
|
ok = snabbkaffe:start_trace(),
|
||||||
|
{ok, {ok, _}} =
|
||||||
|
?wait_async_action(
|
||||||
|
emqx_crl_cache:refresh_config(),
|
||||||
|
#{?snk_kind := crl_cache_refresh_config},
|
||||||
|
_Timeout = 10_000),
|
||||||
|
[ {crl_pem_not_revoked, CRLPemNotRevoked}
|
||||||
|
, {crl_der_not_revoked, CRLDerNotRevoked}
|
||||||
|
, {crl_pem_revoked, CRLPemRevoked}
|
||||||
|
, {crl_der_revoked, CRLDerRevoked}
|
||||||
|
, {http_server, ServerPid}
|
||||||
|
, {old_configs, [ {listeners, OldListeners}
|
||||||
|
, {crl_cache_refresh_interval, OldRefreshInterval}
|
||||||
|
]}
|
||||||
|
| Config];
|
||||||
init_per_testcase(t_not_cached_and_unreachable, Config) ->
|
init_per_testcase(t_not_cached_and_unreachable, Config) ->
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
CRLFile = filename:join([DataDir, "crl.pem"]),
|
CRLFile = filename:join([DataDir, "intermediate-revoked.crl.pem"]),
|
||||||
{ok, CRLPem} = file:read_file(CRLFile),
|
{ok, CRLPem} = file:read_file(CRLFile),
|
||||||
[{'CertificateList', CRLDer, not_encrypted}] = public_key:pem_decode(CRLPem),
|
[{'CertificateList', CRLDer, not_encrypted}] = public_key:pem_decode(CRLPem),
|
||||||
application:stop(cowboy),
|
application:stop(cowboy),
|
||||||
|
@ -65,7 +100,7 @@ init_per_testcase(t_not_cached_and_unreachable, Config) ->
|
||||||
| Config];
|
| Config];
|
||||||
init_per_testcase(t_refresh_config, Config) ->
|
init_per_testcase(t_refresh_config, Config) ->
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
CRLFile = filename:join([DataDir, "crl.pem"]),
|
CRLFile = filename:join([DataDir, "intermediate-revoked.crl.pem"]),
|
||||||
{ok, CRLPem} = file:read_file(CRLFile),
|
{ok, CRLPem} = file:read_file(CRLFile),
|
||||||
[{'CertificateList', CRLDer, not_encrypted}] = public_key:pem_decode(CRLPem),
|
[{'CertificateList', CRLDer, not_encrypted}] = public_key:pem_decode(CRLPem),
|
||||||
TestPid = self(),
|
TestPid = self(),
|
||||||
|
@ -88,7 +123,7 @@ init_per_testcase(t_refresh_config, Config) ->
|
||||||
| Config];
|
| Config];
|
||||||
init_per_testcase(_TestCase, Config) ->
|
init_per_testcase(_TestCase, Config) ->
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
CRLFile = filename:join([DataDir, "crl.pem"]),
|
CRLFile = filename:join([DataDir, "intermediate-revoked.crl.pem"]),
|
||||||
{ok, CRLPem} = file:read_file(CRLFile),
|
{ok, CRLPem} = file:read_file(CRLFile),
|
||||||
[{'CertificateList', CRLDer, not_encrypted}] = public_key:pem_decode(CRLPem),
|
[{'CertificateList', CRLDer, not_encrypted}] = public_key:pem_decode(CRLPem),
|
||||||
TestPid = self(),
|
TestPid = self(),
|
||||||
|
@ -118,6 +153,30 @@ end_per_testcase(TestCase, Config)
|
||||||
clear_crl_cache(),
|
clear_crl_cache(),
|
||||||
ok = snabbkaffe:stop(),
|
ok = snabbkaffe:stop(),
|
||||||
ok;
|
ok;
|
||||||
|
end_per_testcase(t_revoke_then_refresh, Config) ->
|
||||||
|
ServerPid = ?config(http_server, Config),
|
||||||
|
emqx_crl_cache_http_server:stop(ServerPid),
|
||||||
|
emqx_ct_helpers:stop_apps([]),
|
||||||
|
OldConfigs = ?config(old_configs, Config),
|
||||||
|
clear_crl_cache(),
|
||||||
|
emqx_ct_helpers:stop_apps([]),
|
||||||
|
emqx_ct_helpers:change_emqx_opts(
|
||||||
|
ssl_twoway, [ {crl_options, [ {crl_check_enabled, false}
|
||||||
|
, {crl_cache_urls, []}
|
||||||
|
]}
|
||||||
|
]),
|
||||||
|
clear_crl_cache(),
|
||||||
|
lists:foreach(
|
||||||
|
fun({Key, MValue}) ->
|
||||||
|
case MValue of
|
||||||
|
undefined -> ok;
|
||||||
|
Value -> application:set_env(emqx, Key, Value)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
OldConfigs),
|
||||||
|
application:stop(cowboy),
|
||||||
|
ok = snabbkaffe:stop(),
|
||||||
|
ok;
|
||||||
end_per_testcase(t_not_cached_and_unreachable, _Config) ->
|
end_per_testcase(t_not_cached_and_unreachable, _Config) ->
|
||||||
emqx_ct_helpers:stop_apps([]),
|
emqx_ct_helpers:stop_apps([]),
|
||||||
emqx_ct_helpers:change_emqx_opts(
|
emqx_ct_helpers:change_emqx_opts(
|
||||||
|
@ -229,7 +288,7 @@ force_cacertfile(Cacertfile) ->
|
||||||
application:set_env(emqx, listeners, SSLListeners ++ OtherListeners),
|
application:set_env(emqx, listeners, SSLListeners ++ OtherListeners),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
setup_crl_options(Config, #{is_cached := IsCached}) ->
|
setup_crl_options(Config, Opts = #{is_cached := IsCached}) ->
|
||||||
DataDir = ?config(data_dir, Config),
|
DataDir = ?config(data_dir, Config),
|
||||||
Cacertfile = filename:join(DataDir, "ca-chain.cert.pem"),
|
Cacertfile = filename:join(DataDir, "ca-chain.cert.pem"),
|
||||||
Certfile = filename:join(DataDir, "server.cert.pem"),
|
Certfile = filename:join(DataDir, "server.cert.pem"),
|
||||||
|
@ -238,6 +297,7 @@ setup_crl_options(Config, #{is_cached := IsCached}) ->
|
||||||
false -> [];
|
false -> [];
|
||||||
true -> ["http://localhost:9878/intermediate.crl.pem"]
|
true -> ["http://localhost:9878/intermediate.crl.pem"]
|
||||||
end,
|
end,
|
||||||
|
ExtraHandler = maps:get(extra_handler, Opts, fun(_) -> ok end),
|
||||||
Handler =
|
Handler =
|
||||||
fun(emqx) ->
|
fun(emqx) ->
|
||||||
emqx_ct_helpers:change_emqx_opts(
|
emqx_ct_helpers:change_emqx_opts(
|
||||||
|
@ -255,8 +315,10 @@ setup_crl_options(Config, #{is_cached := IsCached}) ->
|
||||||
]),
|
]),
|
||||||
%% emqx_ct_helpers:change_emqx_opts has cacertfile hardcoded....
|
%% emqx_ct_helpers:change_emqx_opts has cacertfile hardcoded....
|
||||||
ok = force_cacertfile(Cacertfile),
|
ok = force_cacertfile(Cacertfile),
|
||||||
|
ExtraHandler(emqx),
|
||||||
ok;
|
ok;
|
||||||
(_) ->
|
(App) ->
|
||||||
|
ExtraHandler(App),
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
emqx_ct_helpers:start_apps([], Handler),
|
emqx_ct_helpers:start_apps([], Handler),
|
||||||
|
@ -546,3 +608,39 @@ t_revoked(Config) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
?assertMatch({error, {{shutdown, {tls_alert, {certificate_revoked, _}}}, _}}, emqtt:connect(C)),
|
?assertMatch({error, {{shutdown, {tls_alert, {certificate_revoked, _}}}, _}}, emqtt:connect(C)),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
t_revoke_then_refresh(Config) ->
|
||||||
|
DataDir = ?config(data_dir, Config),
|
||||||
|
CRLPemRevoked = ?config(crl_pem_revoked, Config),
|
||||||
|
ClientCert = filename:join(DataDir, "client-revoked.cert.pem"),
|
||||||
|
ClientKey = filename:join(DataDir, "client-revoked.key.pem"),
|
||||||
|
{ok, C0} = emqtt:start_link([ {ssl, true}
|
||||||
|
, {ssl_opts, [ {certfile, ClientCert}
|
||||||
|
, {keyfile, ClientKey}
|
||||||
|
]}
|
||||||
|
, {port, 8883}
|
||||||
|
]),
|
||||||
|
%% At first, the CRL contains no revoked entries, so the client
|
||||||
|
%% should be allowed connection.
|
||||||
|
?assertMatch({ok, _}, emqtt:connect(C0)),
|
||||||
|
emqtt:stop(C0),
|
||||||
|
|
||||||
|
%% Now we update the CRL on the server and wait for the cache to
|
||||||
|
%% be refreshed.
|
||||||
|
ok = snabbkaffe:start_trace(),
|
||||||
|
{true, {ok, _}} =
|
||||||
|
?wait_async_action(
|
||||||
|
emqx_crl_cache_http_server:set_crl(CRLPemRevoked),
|
||||||
|
#{?snk_kind := crl_refresh_timer_done},
|
||||||
|
70_000),
|
||||||
|
|
||||||
|
%% The *same client* should now be denied connection.
|
||||||
|
{ok, C1} = emqtt:start_link([ {ssl, true}
|
||||||
|
, {ssl_opts, [ {certfile, ClientCert}
|
||||||
|
, {keyfile, ClientKey}
|
||||||
|
]}
|
||||||
|
, {port, 8883}
|
||||||
|
]),
|
||||||
|
process_flag(trap_exit, true),
|
||||||
|
?assertMatch({error, {{shutdown, {tls_alert, {certificate_revoked, _}}}, _}}, emqtt:connect(C1)),
|
||||||
|
ok.
|
||||||
|
|
|
@ -2,67 +2,67 @@
|
||||||
MIIF+zCCA+OgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwbzELMAkGA1UEBhMCU0Ux
|
MIIF+zCCA+OgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwbzELMAkGA1UEBhMCU0Ux
|
||||||
EjAQBgNVBAgMCVN0b2NraG9sbTESMBAGA1UEBwwJU3RvY2tob2xtMRIwEAYDVQQK
|
EjAQBgNVBAgMCVN0b2NraG9sbTESMBAGA1UEBwwJU3RvY2tob2xtMRIwEAYDVQQK
|
||||||
DAlNeU9yZ05hbWUxETAPBgNVBAsMCE15Um9vdENBMREwDwYDVQQDDAhNeVJvb3RD
|
DAlNeU9yZ05hbWUxETAPBgNVBAsMCE15Um9vdENBMREwDwYDVQQDDAhNeVJvb3RD
|
||||||
QTAeFw0yMjA2MTMxMjQyMDVaFw0zMjA2MTAxMjQyMDVaMGsxCzAJBgNVBAYTAlNF
|
QTAeFw0yMzAxMTIxMzA4MTZaFw0zMzAxMDkxMzA4MTZaMGsxCzAJBgNVBAYTAlNF
|
||||||
MRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAoMCU15T3JnTmFtZTEZMBcGA1UE
|
MRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAoMCU15T3JnTmFtZTEZMBcGA1UE
|
||||||
CwwQTXlJbnRlcm1lZGlhdGVDQTEZMBcGA1UEAwwQTXlJbnRlcm1lZGlhdGVDQTCC
|
CwwQTXlJbnRlcm1lZGlhdGVDQTEZMBcGA1UEAwwQTXlJbnRlcm1lZGlhdGVDQTCC
|
||||||
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAN32wUPOGrLjVHY37ICI4sWH
|
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALQG7dMeU/y9HDNHzhydR0bm
|
||||||
2GBEYgGtoKyZTfLKqK8W965uxHxMKKeKC7Ro93ScT4giR2GdsCvMyLP4Dlv7FxL7
|
wN9UGplqJOJPwqJRaZZcrn9umgJ9SU2il2ceEVxMDwzBWCRKJO5/H9A9k13SqsXM
|
||||||
rWEHc7vbP22uT4NQQ0hgfl4ch8rTiSl/5FfynOuvMHnKh58z+lGyQ/uqKqAzc6OD
|
2c2c9xXfIF1kb820lCm1Uow5hZ/auDjxliNk9kNJDigCRi3QoIs/dVeWzFsgEC2l
|
||||||
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
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
-----BEGIN CERTIFICATE-----
|
-----BEGIN CERTIFICATE-----
|
||||||
MIIFzzCCA7egAwIBAgIUVYtdlrTMH1BoMy9JpiiL/FXv5NMwDQYJKoZIhvcNAQEL
|
MIIFzzCCA7egAwIBAgIUYjc7hD7/UJ0/VPADfNfp/WpOwRowDQYJKoZIhvcNAQEL
|
||||||
BQAwbzELMAkGA1UEBhMCU0UxEjAQBgNVBAgMCVN0b2NraG9sbTESMBAGA1UEBwwJ
|
BQAwbzELMAkGA1UEBhMCU0UxEjAQBgNVBAgMCVN0b2NraG9sbTESMBAGA1UEBwwJ
|
||||||
U3RvY2tob2xtMRIwEAYDVQQKDAlNeU9yZ05hbWUxETAPBgNVBAsMCE15Um9vdENB
|
U3RvY2tob2xtMRIwEAYDVQQKDAlNeU9yZ05hbWUxETAPBgNVBAsMCE15Um9vdENB
|
||||||
MREwDwYDVQQDDAhNeVJvb3RDQTAeFw0yMjA2MTMxMjQyMDVaFw00MjA2MDgxMjQy
|
MREwDwYDVQQDDAhNeVJvb3RDQTAeFw0yMzAxMTIxMzA4MTRaFw00MzAxMDcxMzA4
|
||||||
MDVaMG8xCzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAcM
|
MTRaMG8xCzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAcM
|
||||||
CVN0b2NraG9sbTESMBAGA1UECgwJTXlPcmdOYW1lMREwDwYDVQQLDAhNeVJvb3RD
|
CVN0b2NraG9sbTESMBAGA1UECgwJTXlPcmdOYW1lMREwDwYDVQQLDAhNeVJvb3RD
|
||||||
QTERMA8GA1UEAwwITXlSb290Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
|
QTERMA8GA1UEAwwITXlSb290Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
|
||||||
AoICAQDRKeWdrXluKLuVxTXxpWbCzBm/6x+kg8EjhIKUm9Mq0t+cOLC1sn99s4E0
|
AoICAQCnBwSOYVJw47IoMHMXTVDtOYvUt3rqsurEhFcB4O8xmf2mmwr6m7s8A5Ft
|
||||||
/NBA7jc3O+hQ9S2fZuMp9OUXuf8HjjtlKQY2M9T9kCE9Yxc+ygpcPEvDYl0ke/1r
|
AvAehg1GvnXT3t/KiyU7BK+acTwcErGyZwS2wvdB0lpHWSpOn/u5y+4ZETvQefcj
|
||||||
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
|
||||||
G2LZ
|
cbTm
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
|
|
@ -2,31 +2,31 @@
|
||||||
MIIFnDCCA4SgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCU0Ux
|
MIIFnDCCA4SgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCU0Ux
|
||||||
EjAQBgNVBAgMCVN0b2NraG9sbTESMBAGA1UECgwJTXlPcmdOYW1lMRkwFwYDVQQL
|
EjAQBgNVBAgMCVN0b2NraG9sbTESMBAGA1UECgwJTXlPcmdOYW1lMRkwFwYDVQQL
|
||||||
DBBNeUludGVybWVkaWF0ZUNBMRkwFwYDVQQDDBBNeUludGVybWVkaWF0ZUNBMB4X
|
DBBNeUludGVybWVkaWF0ZUNBMRkwFwYDVQQDDBBNeUludGVybWVkaWF0ZUNBMB4X
|
||||||
DTIyMDYxMzEyNDIwNVoXDTIzMDYyMzEyNDIwNVowfTELMAkGA1UEBhMCU0UxEjAQ
|
DTIzMDExMjEzMDgxNloXDTMzMDQxOTEzMDgxNlowfTELMAkGA1UEBhMCU0UxEjAQ
|
||||||
BgNVBAgMCVN0b2NraG9sbTESMBAGA1UEBwwJU3RvY2tob2xtMRIwEAYDVQQKDAlN
|
BgNVBAgMCVN0b2NraG9sbTESMBAGA1UEBwwJU3RvY2tob2xtMRIwEAYDVQQKDAlN
|
||||||
eU9yZ05hbWUxGTAXBgNVBAsMEE15SW50ZXJtZWRpYXRlQ0ExFzAVBgNVBAMMDmNs
|
eU9yZ05hbWUxGTAXBgNVBAsMEE15SW50ZXJtZWRpYXRlQ0ExFzAVBgNVBAMMDmNs
|
||||||
aWVudC1yZXZva2VkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA584w
|
aWVudC1yZXZva2VkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs+R6
|
||||||
VAczDWrlIJXm6+0oYepacPPrVEMC9WwsQFO5GbBDdxrBvxgQ5u8/DDNEtYk0sJMt
|
PDtIxVlUoLYbDBbaVcxgoLjnWcvqL8wSqyWuqi/Y3cjuNYCziR9nR5dWajtkBjzJ
|
||||||
zgSLxsYK5duhrwVyICXpKgxMI2fKdKP0zxB/eB4V0vrc6FqR4L8D8XoNPKSaTnjv
|
HyhgAr6gBVSRt4RRmDXoOcprK3GcpowAr65UAmC4hdH0af6FdKjKCnFw67byUg52
|
||||||
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
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue