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
|
||||
/src/ @qzhuyan
|
||||
/include/ @qzhuyan
|
||||
|
@ -5,13 +8,13 @@
|
|||
/test/ @qzhuyan
|
||||
|
||||
## CI
|
||||
/.github/ @id
|
||||
/.ci/ @id
|
||||
/scripts/ @id
|
||||
/build @id
|
||||
/deploy/ @id
|
||||
/.github/ @emqx/emqx-review-board @id
|
||||
/.ci/ @emqx/emqx-review-board @id
|
||||
/scripts/ @emqx/emqx-review-board @id
|
||||
/build @emqx/emqx-review-board @id
|
||||
/deploy/ @emqx/emqx-review-board @id
|
||||
|
||||
## Authenticatio & ACL
|
||||
## Authentication & ACL
|
||||
/apps/emqx_auth_*/ @savonarola
|
||||
/apps/emqx_psk_file/ @savonarola
|
||||
/apps/emqx_retainer/ @savonarola
|
||||
|
@ -31,13 +34,6 @@
|
|||
/apps/emqx_prometheus/ @zhongwencool
|
||||
/apps/emqx_recon/ @zhongwencool
|
||||
|
||||
|
||||
## Data integration
|
||||
/apps/emqx_rule_engine/ @thalesmg
|
||||
/apps/emqx_web_hook/ @thalesmg
|
||||
|
||||
## External Plugins
|
||||
/lib-extra/ @zmstone
|
||||
|
||||
## Default
|
||||
* @zmstone
|
||||
|
|
|
@ -13,7 +13,7 @@ jobs:
|
|||
os:
|
||||
- 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:
|
||||
- uses: actions/checkout@v3
|
||||
|
|
|
@ -157,6 +157,7 @@ jobs:
|
|||
- amd64
|
||||
- arm64
|
||||
os:
|
||||
- ubuntu22.04
|
||||
- ubuntu20.04
|
||||
- ubuntu18.04
|
||||
- ubuntu16.04
|
||||
|
@ -195,7 +196,7 @@ jobs:
|
|||
--profile "${PROFILE}" \
|
||||
--pkgtype "${PACKAGE}" \
|
||||
--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
|
||||
with:
|
||||
name: ${{ matrix.profile }}
|
||||
|
@ -271,7 +272,7 @@ jobs:
|
|||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
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
|
||||
EMQX_NAME=${{ matrix.profile }}
|
||||
file: source/deploy/docker/Dockerfile
|
||||
|
@ -287,7 +288,7 @@ jobs:
|
|||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
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
|
||||
EMQX_NAME=${{ matrix.profile }}
|
||||
file: source/deploy/docker/Dockerfile.enterprise
|
||||
|
|
|
@ -19,6 +19,7 @@ jobs:
|
|||
otp:
|
||||
- 24.3.4.2-1
|
||||
os:
|
||||
- ubuntu22.04
|
||||
- ubuntu20.04
|
||||
- el7
|
||||
runs-on:
|
||||
|
@ -32,7 +33,7 @@ jobs:
|
|||
- runs-on: aws-amd64
|
||||
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:
|
||||
- uses: AutoModality/action-clean@v1
|
||||
|
|
|
@ -5,7 +5,7 @@ on: [pull_request]
|
|||
jobs:
|
||||
check_deps_integrity:
|
||||
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:
|
||||
- uses: actions/checkout@v3
|
||||
|
|
|
@ -7,7 +7,7 @@ on:
|
|||
jobs:
|
||||
prepare:
|
||||
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:
|
||||
profiles: ${{ steps.detect-profiles.outputs.profiles}}
|
||||
|
|
|
@ -5,7 +5,7 @@ on: workflow_dispatch
|
|||
jobs:
|
||||
test:
|
||||
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:
|
||||
fail-fast: true
|
||||
env:
|
||||
|
|
|
@ -200,7 +200,7 @@ jobs:
|
|||
|
||||
relup_test_plan:
|
||||
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:
|
||||
profile: ${{ steps.profile-and-versions.outputs.profile }}
|
||||
vsn: ${{ steps.profile-and-versions.outputs.vsn }}
|
||||
|
@ -251,7 +251,7 @@ jobs:
|
|||
otp:
|
||||
- 24.3.4.2-1
|
||||
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:
|
||||
run:
|
||||
shell: bash
|
||||
|
@ -288,7 +288,7 @@ jobs:
|
|||
- relup_test_plan
|
||||
- relup_test_build
|
||||
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:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
|
@ -12,7 +12,7 @@ on:
|
|||
jobs:
|
||||
prepare:
|
||||
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:
|
||||
fast_ct_apps: ${{ steps.run_find_apps.outputs.fast_ct_apps }}
|
||||
docker_ct_apps: ${{ steps.run_find_apps.outputs.docker_ct_apps }}
|
||||
|
@ -58,7 +58,7 @@ jobs:
|
|||
eunit_and_proper:
|
||||
needs: prepare
|
||||
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:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
@ -86,7 +86,7 @@ jobs:
|
|||
fast_ct:
|
||||
needs: prepare
|
||||
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:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
@ -249,7 +249,7 @@ jobs:
|
|||
- fast_ct
|
||||
- docker_ct
|
||||
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:
|
||||
- uses: AutoModality/action-clean@v1
|
||||
- uses: actions/download-artifact@v3
|
||||
|
|
|
@ -44,7 +44,10 @@ check_acl(ClientInfo, PubSub, Topic, _AclResult, #{acl := ACLParams = #{path :=
|
|||
Username = maps:get(username, ClientInfo1, undefined),
|
||||
case check_acl_request(ACLParams, ClientInfo1) of
|
||||
{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} ->
|
||||
?LOG(warning, "Deny ~s to topic ~ts, username: ~ts, http response code: ~p",
|
||||
[PubSub, Topic, Username, Code]),
|
||||
|
@ -74,4 +77,3 @@ check_acl_request(ACLParams =
|
|||
|
||||
access(subscribe) -> 1;
|
||||
access(publish) -> 2.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_auth_http,
|
||||
[{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, []},
|
||||
{registered, [emqx_auth_http_sup]},
|
||||
{applications, [kernel,stdlib,ehttpc]},
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{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",
|
||||
[{load_module,emqx_auth_http_app,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,[]}]},
|
||||
{<<"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",
|
||||
[{load_module,emqx_auth_http_app,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;
|
||||
{ok, 200, Body} ->
|
||||
?LOG(debug, "Auth succeeded from path: ~ts, username: ~ts", [Path, Username]),
|
||||
IsSuperuser = is_superuser(SuperParams, ClientInfo),
|
||||
{stop, AuthResult#{is_superuser => IsSuperuser,
|
||||
auth_result => success,
|
||||
anonymous => false,
|
||||
mountpoint => mountpoint(Body, ClientInfo)}};
|
||||
{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",
|
||||
[Path, Username, Code]),
|
||||
{stop, AuthResult#{auth_result => http_to_connack_error(Code),
|
||||
anonymous => false}};
|
||||
{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]),
|
||||
%%FIXME later: server_unavailable is not right.
|
||||
{stop, AuthResult#{auth_result => server_unavailable,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_auth_jwt,
|
||||
[{description, "EMQ X Authentication with JWT"},
|
||||
{vsn, "4.4.8"}, % strict semver, bump manually!
|
||||
{vsn, "4.4.9"}, % strict semver, bump manually!
|
||||
{modules, []},
|
||||
{registered, [emqx_auth_jwt_sup]},
|
||||
{applications, [kernel,stdlib,jose]},
|
||||
|
|
|
@ -1,38 +1,18 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{VSN,
|
||||
[{"4.4.7",[{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]}]},
|
||||
{"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",
|
||||
[{"4.4.8",
|
||||
[{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]}]},
|
||||
{"4.4.4",
|
||||
[{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",
|
||||
{<<"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\\.[0-1]">>,[{restart_application,emqx_auth_jwt}]},
|
||||
{<<".*">>,[]}],
|
||||
[{"4.4.7",[{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]}]},
|
||||
{"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",
|
||||
[{"4.4.8",
|
||||
[{load_module,emqx_auth_jwt,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_auth_jwt_svr,brutal_purge,soft_purge,[]}]},
|
||||
{"4.4.4",
|
||||
[{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",
|
||||
{<<"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\\.[0-1]">>,[{restart_application,emqx_auth_jwt}]},
|
||||
|
|
|
@ -51,8 +51,14 @@ check_auth(ClientInfo, AuthResult, #{from := From, checklists := Checklists}) ->
|
|||
{error, not_token} ->
|
||||
ok;
|
||||
{error, Reason} ->
|
||||
?LOG_SENSITIVE(debug,
|
||||
"Auth from JWT failed, Client: ~p, Reason: ~p",
|
||||
[ClientInfo, Reason]),
|
||||
{stop, AuthResult#{auth_result => Reason, anonymous => false}};
|
||||
{ok, Claims} ->
|
||||
?LOG_SENSITIVE(debug,
|
||||
"Auth from JWT succeeded, Client: ~p",
|
||||
[ClientInfo]),
|
||||
{stop, maps:merge(AuthResult, verify_claims(Checklists, Claims, ClientInfo))}
|
||||
end
|
||||
end.
|
||||
|
|
|
@ -99,13 +99,13 @@ handle_cast(_Msg, State) ->
|
|||
{noreply, State}.
|
||||
|
||||
handle_info({timeout, _TRef, refresh}, State = #state{addr = Addr}) ->
|
||||
NState = try
|
||||
true = ets:insert(?TAB, {remote, request_jwks(Addr)}),
|
||||
State
|
||||
catch _:_ ->
|
||||
State
|
||||
try
|
||||
true = ets:insert(?TAB, {remote, request_jwks(Addr)})
|
||||
catch Err:Reason ->
|
||||
?LOG_SENSITIVE(warning, "Request JWKS failed, jwks_addr: ~p, reason: ~p",
|
||||
[Addr, {Err, Reason}])
|
||||
end,
|
||||
{noreply, reset_timer(NState)};
|
||||
{noreply, reset_timer(State)};
|
||||
|
||||
handle_info({request_jwks, Options}, State) ->
|
||||
Remote = key2jwt_value(jwks_addr, fun request_jwks/1, Options),
|
||||
|
|
|
@ -29,8 +29,16 @@
|
|||
check_acl(ClientInfo, PubSub, Topic, NoMatchAction, State) ->
|
||||
case do_check_acl(ClientInfo, PubSub, Topic, NoMatchAction, State) of
|
||||
ok -> ok;
|
||||
{stop, allow} -> {stop, allow};
|
||||
{stop, deny} -> {stop, deny}
|
||||
{stop, allow} ->
|
||||
?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.
|
||||
|
||||
do_check_acl(#{username := <<$$, _/binary>>}, _PubSub, _Topic, _NoMatchAction, _State) ->
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_auth_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, []},
|
||||
{registered, [emqx_auth_ldap_sup]},
|
||||
{applications, [kernel,stdlib,eldap2,ecpool]},
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{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_auth_ldap,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_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_auth_ldap,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,
|
||||
case CheckResult of
|
||||
ok ->
|
||||
?LOG_SENSITIVE(debug,
|
||||
"[LDAP] Auth from ldap succeeded, Client: ~p",
|
||||
[ClientInfo]),
|
||||
{stop, AuthResult#{auth_result => success, anonymous => false}};
|
||||
{error, not_found} ->
|
||||
ok;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
-module(emqx_acl_mnesia).
|
||||
|
||||
-include("emqx_auth_mnesia.hrl").
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
|
||||
%% ACL Callbacks
|
||||
-export([ init/0
|
||||
|
@ -43,8 +44,14 @@ check_acl(ClientInfo = #{ clientid := Clientid }, PubSub, Topic, _NoMatchAction,
|
|||
|
||||
case match(ClientInfo, PubSub, Topic, Acls) of
|
||||
allow ->
|
||||
?LOG_SENSITIVE(debug,
|
||||
"[Mnesia] Allow Topic: ~p, Action: ~p for Client: ~p",
|
||||
[Topic, PubSub, ClientInfo]),
|
||||
{stop, allow};
|
||||
deny ->
|
||||
?LOG_SENSITIVE(debug,
|
||||
"[Mnesia] Deny Topic: ~p, Action: ~p for Client: ~p",
|
||||
[Topic, PubSub, ClientInfo]),
|
||||
{stop, deny};
|
||||
_ ->
|
||||
ok
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_auth_mnesia,
|
||||
[{description, "EMQ X Authentication with Mnesia"},
|
||||
{vsn, "4.3.10"}, % strict semver, bump manually
|
||||
{vsn, "4.3.11"}, % strict semver, bump manually
|
||||
{modules, []},
|
||||
{registered, []},
|
||||
{applications, [kernel,stdlib,mnesia]},
|
||||
|
|
|
@ -1,13 +1,25 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{VSN,
|
||||
[{"4.3.9",[{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
||||
{"4.3.8",[{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
||||
[{"4.3.10",
|
||||
[{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",
|
||||
[{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,[]}]},
|
||||
{<<"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_api,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_auth_mnesia_app,brutal_purge,soft_purge,[]}]},
|
||||
{<<".*">>,[]}],
|
||||
[{"4.3.9",[{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
||||
{"4.3.8",[{load_module,emqx_acl_mnesia_cli,brutal_purge,soft_purge,[]}]},
|
||||
[{"4.3.10",
|
||||
[{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",
|
||||
[{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,[]}]},
|
||||
{<<"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_api,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]),
|
||||
{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}}
|
||||
end
|
||||
end.
|
||||
|
|
|
@ -38,8 +38,16 @@ check_acl(ClientInfo, PubSub, Topic, _AclResult, Env = #{aclquery := AclQuery})
|
|||
[] -> ok;
|
||||
Rows ->
|
||||
try match(ClientInfo, Topic, topics(PubSub, Rows)) of
|
||||
matched -> {stop, allow};
|
||||
nomatch -> {stop, deny}
|
||||
matched ->
|
||||
?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
|
||||
_Err:Reason->
|
||||
?LOG(error, "[MongoDB] Check mongo ~p ACL failed, got ACL config: ~p, error: :~p",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_auth_mongo,
|
||||
[{description, "EMQ X Authentication/ACL with MongoDB"},
|
||||
{vsn, "4.4.5"}, % strict semver, bump manually!
|
||||
{vsn, "4.4.6"}, % strict semver, bump manually!
|
||||
{modules, []},
|
||||
{registered, [emqx_auth_mongo_sup]},
|
||||
{applications, [kernel,stdlib,mongodb,ecpool]},
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{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]">>,
|
||||
[{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,[]}]},
|
||||
{"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,brutal_purge,soft_purge,[]}]},
|
||||
{"4.4.0",
|
||||
|
@ -15,12 +22,19 @@
|
|||
{load_module,emqx_auth_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",
|
||||
[{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]">>,
|
||||
[{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,[]}]},
|
||||
{"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,brutal_purge,soft_purge,[]}]},
|
||||
{"4.4.0",
|
||||
|
|
|
@ -68,6 +68,9 @@ check(ClientInfo = #{password := Password}, AuthResult,
|
|||
case Result of
|
||||
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),
|
||||
anonymous => false,
|
||||
auth_result => success}};
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
{deps,
|
||||
[
|
||||
{mysql, {git, "https://github.com/emqx/mysql-otp", {tag, "1.7.1"}}}
|
||||
]}.
|
||||
{deps, []}.
|
||||
|
||||
{edoc_opts, [{preprocess, true}]}.
|
||||
{erl_opts, [warn_unused_vars,
|
||||
|
|
|
@ -29,8 +29,16 @@
|
|||
check_acl(ClientInfo, PubSub, Topic, NoMatchAction, #{pool := Pool} = State) ->
|
||||
case do_check_acl(Pool, ClientInfo, PubSub, Topic, NoMatchAction, State) of
|
||||
ok -> ok;
|
||||
{stop, allow} -> {stop, allow};
|
||||
{stop, deny} -> {stop, deny}
|
||||
{stop, allow} ->
|
||||
?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.
|
||||
|
||||
do_check_acl(_Pool, #{username := <<$$, _/binary>>}, _PubSub, _Topic, _NoMatchAction, _State) ->
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_auth_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, []},
|
||||
{registered, [emqx_auth_mysql_sup]},
|
||||
{applications, [kernel,stdlib,mysql,ecpool]},
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{VSN,
|
||||
[{"4.3.3",
|
||||
[{"4.3.4",
|
||||
[{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,[]}]},
|
||||
{<<"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,brutal_purge,soft_purge,[]}]},
|
||||
{"4.3.0",
|
||||
|
@ -13,11 +20,17 @@
|
|||
{load_module,emqx_auth_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_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,[]}]},
|
||||
{<<"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,brutal_purge,soft_purge,[]}]},
|
||||
{"4.3.0",
|
||||
|
@ -25,5 +38,4 @@
|
|||
{load_module,emqx_auth_mysql_app,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_auth_mysql,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_acl_mysql,brutal_purge,soft_purge,[]}]},
|
||||
{<<".*">>,[]}]
|
||||
}.
|
||||
{<<".*">>,[]}]}.
|
||||
|
|
|
@ -46,6 +46,9 @@ check(ClientInfo = #{password := Password}, AuthResult,
|
|||
end,
|
||||
case CheckPass of
|
||||
ok ->
|
||||
?LOG_SENSITIVE(debug,
|
||||
"[MySQL] Auth from mysql succeeded, Client: ~p",
|
||||
[ClientInfo]),
|
||||
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
||||
anonymous => false,
|
||||
auth_result => success}};
|
||||
|
|
|
@ -36,8 +36,16 @@ do_check_acl(Pool, ClientInfo, PubSub, Topic, _NoMatchAction, #{acl_query := {Ac
|
|||
{ok, _, Rows} ->
|
||||
Rules = filter(PubSub, compile(Rows)),
|
||||
case match(ClientInfo, Topic, Rules) of
|
||||
{matched, allow} -> {stop, allow};
|
||||
{matched, deny} -> {stop, deny};
|
||||
{matched, allow} ->
|
||||
?LOG_SENSITIVE(debug,
|
||||
"[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;
|
||||
{error, Reason} ->
|
||||
|
@ -105,4 +113,3 @@ empty(null) -> true;
|
|||
empty("") -> true;
|
||||
empty(<<>>) -> true;
|
||||
empty(_) -> false.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_auth_pgsql,
|
||||
[{description, "EMQ X Authentication/ACL with PostgreSQL"},
|
||||
{vsn, "4.4.4"}, % strict semver, bump manually!
|
||||
{vsn, "4.4.5"}, % strict semver, bump manually!
|
||||
{modules, []},
|
||||
{registered, [emqx_auth_pgsql_sup]},
|
||||
{applications, [kernel,stdlib,epgsql,ecpool]},
|
||||
|
|
|
@ -1,20 +1,29 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{VSN,
|
||||
[{"4.4.3",
|
||||
[{load_module,emqx_auth_pgsql_cli,brutal_purge,soft_purge,[]},
|
||||
[{"4.4.4",
|
||||
[{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,[]}]},
|
||||
{<<"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_app,brutal_purge,soft_purge,[]}]},
|
||||
{<<".*">>,[]}],
|
||||
[{"4.4.3",
|
||||
[{load_module,emqx_auth_pgsql_cli,brutal_purge,soft_purge,[]},
|
||||
[{"4.4.4",
|
||||
[{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,[]}]},
|
||||
{<<"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_app,brutal_purge,soft_purge,[]}]},
|
||||
{<<".*">>,[]}]}.
|
||||
|
||||
|
|
|
@ -45,6 +45,9 @@ check(ClientInfo = #{password := Password}, AuthResult,
|
|||
end,
|
||||
case CheckPass of
|
||||
ok ->
|
||||
?LOG_SENSITIVE(debug,
|
||||
"[Postgres] Auth from pgsql succeeded, Client: ~p",
|
||||
[ClientInfo]),
|
||||
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
||||
anonymous => false,
|
||||
auth_result => success}};
|
||||
|
|
|
@ -33,8 +33,16 @@ check_acl(ClientInfo, PubSub, Topic, _AclResult,
|
|||
{ok, []} -> ok;
|
||||
{ok, Rules} ->
|
||||
case match(ClientInfo, PubSub, Topic, Rules) of
|
||||
allow -> {stop, allow};
|
||||
nomatch -> {stop, deny}
|
||||
allow ->
|
||||
?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;
|
||||
{error, 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)).
|
||||
|
||||
description() -> "Redis ACL Module".
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_auth_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, []},
|
||||
{registered, [emqx_auth_redis_sup]},
|
||||
{applications, [kernel,stdlib,eredis,eredis_cluster,ecpool]},
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{VSN,
|
||||
[{"4.3.3",
|
||||
[{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]},
|
||||
[{"4.3.4",
|
||||
[{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,[]}]},
|
||||
{<<"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,brutal_purge,soft_purge,[]}]},
|
||||
{"4.3.0",
|
||||
|
@ -14,11 +18,15 @@
|
|||
{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_acl_redis,brutal_purge,soft_purge,[]}]},
|
||||
{<<".*">>,[]}],
|
||||
[{"4.3.3",
|
||||
[{load_module,emqx_auth_redis,brutal_purge,soft_purge,[]},
|
||||
[{"4.3.4",
|
||||
[{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,[]}]},
|
||||
{<<"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,brutal_purge,soft_purge,[]}]},
|
||||
{"4.3.0",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_bridge_mqtt,
|
||||
[{description, "EMQ X Bridge to MQTT Broker"},
|
||||
{vsn, "4.3.7"}, % strict semver, bump manually!
|
||||
{vsn, "4.3.8"}, % strict semver, bump manually!
|
||||
{modules, []},
|
||||
{registered, []},
|
||||
{applications, [kernel,stdlib,replayq,emqtt]},
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{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_mqtt_actions,brutal_purge,soft_purge,[]}]},
|
||||
{<<"4\\.3\\.[4-5]">>,
|
||||
|
@ -21,7 +23,9 @@
|
|||
{load_module,emqx_bridge_worker,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_mqtt_actions,brutal_purge,soft_purge,[]}]},
|
||||
{<<"4\\.3\\.[4-5]">>,
|
||||
|
|
|
@ -111,11 +111,11 @@
|
|||
zh => <<"桥接挂载点"/utf8>>},
|
||||
description => #{
|
||||
en => <<"MountPoint for bridge topic:<br/>"
|
||||
"Example: The topic of messages sent to `topic1` on local node "
|
||||
"will be transformed to `bridge/aws/${node}/topic1`">>,
|
||||
"Example: The topic of messages sent to <code>topic1</code> on local node "
|
||||
"will be transformed to <code>bridge/aws/${node}/topic1</code>">>,
|
||||
zh => <<"桥接主题的挂载点:<br/>"
|
||||
"示例: 本地节点向 `topic1` 发消息,远程桥接节点的主题"
|
||||
"会变换为 `bridge/aws/${node}/topic1`"/utf8>>
|
||||
"示例: 本地节点向 <code>topic1</code> 发消息,远程桥接节点的主题"
|
||||
"会变换为 <code>bridge/aws/${node}/topic1</code>"/utf8>>
|
||||
}
|
||||
},
|
||||
disk_cache => #{
|
||||
|
@ -267,10 +267,10 @@
|
|||
type => string,
|
||||
required => true,
|
||||
default => <<"emqx2@127.0.0.1">>,
|
||||
title => #{en => <<"EMQ X Node Name">>,
|
||||
zh => <<"EMQ X 节点名称"/utf8>>},
|
||||
description => #{en => <<"EMQ X Remote Node Name">>,
|
||||
zh => <<"远程 EMQ X 节点名称 "/utf8>>}
|
||||
title => #{en => <<"EMQX Node Name">>,
|
||||
zh => <<"EMQX 节点名称"/utf8>>},
|
||||
description => #{en => <<"EMQX Remote Node Name">>,
|
||||
zh => <<"远程 EMQX 节点名称 "/utf8>>}
|
||||
},
|
||||
mountpoint => #{
|
||||
order => 2,
|
||||
|
@ -280,11 +280,11 @@
|
|||
title => #{en => <<"Bridge MountPoint">>,
|
||||
zh => <<"桥接挂载点"/utf8>>},
|
||||
description => #{en => <<"MountPoint for bridge topic<br/>"
|
||||
"Example: The topic of messages sent to `topic1` on local node "
|
||||
"will be transformed to `bridge/aws/${node}/topic1`">>,
|
||||
"Example: The topic of messages sent to <code>topic1</code> on local node "
|
||||
"will be transformed to <code>bridge/emqx/${node}/topic1</code>">>,
|
||||
zh => <<"桥接主题的挂载点<br/>"
|
||||
"示例: 本地节点向 `topic1` 发消息,远程桥接节点的主题"
|
||||
"会变换为 `bridge/aws/${node}/topic1`"/utf8>>}
|
||||
"示例: 本地节点向 <code>topic1</code> 发消息,远程桥接节点的主题"
|
||||
"会变换为 <code>bridge/emqx/${node}/topic1</code>"/utf8>>}
|
||||
},
|
||||
pool_size => #{
|
||||
order => 3,
|
||||
|
@ -358,7 +358,7 @@
|
|||
destroy => on_resource_destroy,
|
||||
params => ?RESOURCE_CONFIG_SPEC_RPC,
|
||||
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(#{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{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]}}
|
||||
]}.
|
||||
|
||||
{mapping, "management.listener.http.proxy_header", "emqx_management.listeners", [
|
||||
{default, false},
|
||||
{datatype, {enum, [true, false]}}
|
||||
]}.
|
||||
|
||||
{mapping, "management.listener.https", "emqx_management.listeners", [
|
||||
{datatype, [integer, ip]}
|
||||
]}.
|
||||
|
@ -186,6 +191,11 @@
|
|||
{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) ->
|
||||
Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
|
||||
Opts = fun(Prefix) ->
|
||||
|
@ -202,7 +212,9 @@ end}.
|
|||
Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
|
||||
Opts = fun(Prefix) ->
|
||||
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,
|
||||
TcpOpts = fun(Prefix) ->
|
||||
Filter([{backlog, cuttlefish:conf_get(Prefix ++ ".backlog", Conf, undefined)},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_management,
|
||||
[{description, "EMQ X Management API and CLI"},
|
||||
{vsn, "4.4.12"}, % strict semver, bump manually!
|
||||
{vsn, "4.4.13"}, % strict semver, bump manually!
|
||||
{modules, []},
|
||||
{registered, [emqx_management_sup]},
|
||||
{applications, [kernel,stdlib,emqx_plugin_libs,minirest]},
|
||||
|
|
|
@ -167,7 +167,7 @@ cluster_query(Params, {Tab, QsSchema}, QueryFun) ->
|
|||
Start = if Page > 1 -> (Page-1) * Limit;
|
||||
true -> 0
|
||||
end,
|
||||
Nodes = ekka_mnesia:running_nodes(),
|
||||
Nodes = lists:sort(ekka_mnesia:running_nodes()),
|
||||
Rows = do_cluster_query(Nodes, Qs, QueryFun, Start, Limit+1, []),
|
||||
Meta = #{page => Page, limit => Limit},
|
||||
NMeta = case CodCnt =:= 0 of
|
||||
|
|
|
@ -52,12 +52,12 @@ stop_listeners() ->
|
|||
start_listener({Proto, Port, Options}) when Proto == http ->
|
||||
Dispatch = [{"/status", emqx_mgmt_http, []},
|
||||
{"/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 ->
|
||||
Dispatch = [{"/status", emqx_mgmt_http, []},
|
||||
{"/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) ->
|
||||
NumAcceptors = proplists:get_value(num_acceptors, Options0, 4),
|
||||
|
@ -68,6 +68,7 @@ ranch_opts(Port, Options0) ->
|
|||
({inet6, false}, Acc) -> Acc;
|
||||
({ipv6_v6only, true}, Acc) -> [{ipv6_v6only, true} | Acc];
|
||||
({ipv6_v6only, false}, Acc) -> Acc;
|
||||
({proxy_header, _}, Acc) -> Acc;
|
||||
({K, V}, Acc)->
|
||||
[{K, V} | Acc]
|
||||
end, [], Options0),
|
||||
|
@ -77,6 +78,9 @@ ranch_opts(Port, Options0) ->
|
|||
socket_opts => [{port, Port} | Options]},
|
||||
Res.
|
||||
|
||||
proto_opts(Options) ->
|
||||
maps:with([proxy_header], maps:from_list(Options)).
|
||||
|
||||
stop_listener({Proto, Port, _}) ->
|
||||
io:format("Stop http:management listener on ~s successfully.~n",[format(Port)]),
|
||||
minirest:stop_http(listener_name(Proto)).
|
||||
|
|
|
@ -794,13 +794,7 @@ t_keepalive(_Config) ->
|
|||
Path = api_path(["clients", ClientId, "keepalive"]),
|
||||
{ok, NotFound} = request_api(put, Path, "interval=5", AuthHeader, [#{}]),
|
||||
?assertEqual("{\"message\":\"not_found\",\"code\":112}", NotFound),
|
||||
{ok, C1} = emqtt:start_link(#{username => Username, clientid => ClientId}),
|
||||
{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),
|
||||
C1 = keepalive_ok(61, 0, Username, ClientId, Path, AuthHeader),
|
||||
{ok, Error1} = request_api(put, Path, "interval=-1", AuthHeader, [#{}]),
|
||||
{ok, Error2} = request_api(put, Path, "interval=65536", AuthHeader, [#{}]),
|
||||
ErrMsg = #{<<"code">> => 102,
|
||||
|
@ -808,9 +802,26 @@ t_keepalive(_Config) ->
|
|||
?assertEqual(ErrMsg, jiffy:decode(Error1, [return_maps])),
|
||||
?assertEqual(Error1, Error2),
|
||||
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),
|
||||
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) ->
|
||||
{ok, #{ body := Resp
|
||||
, status_code := StatusCode
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_prometheus,
|
||||
[{description, "Prometheus for EMQ X"},
|
||||
{vsn, "4.3.1"}, % strict semver, bump manually!
|
||||
{vsn, "4.3.2"}, % strict semver, bump manually!
|
||||
{modules, []},
|
||||
{registered, [emqx_prometheus_sup]},
|
||||
{applications, [kernel,stdlib,prometheus]},
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{VSN,
|
||||
[{"4.3.0",
|
||||
[{load_module,emqx_prometheus,brutal_purge,soft_purge,[]}]},
|
||||
[{"4.3.1",[{load_module,emqx_prometheus,brutal_purge,soft_purge,[]}]},
|
||||
{"4.3.0",[{load_module,emqx_prometheus,brutal_purge,soft_purge,[]}]},
|
||||
{<<".*">>,[]}],
|
||||
[{"4.3.0",
|
||||
[{load_module,emqx_prometheus,brutal_purge,soft_purge,[]}]},
|
||||
[{"4.3.1",[{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));
|
||||
emqx_collect(emqx_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
|
||||
emqx_collect(emqx_sessions_count, Stats) ->
|
||||
|
@ -471,6 +475,8 @@ emqx_collect(emqx_cluster_nodes_stopped, ClusterData) ->
|
|||
emqx_stats() ->
|
||||
[ emqx_connections_count
|
||||
, emqx_connections_max
|
||||
, emqx_live_connections_count
|
||||
, emqx_live_connections_max
|
||||
, emqx_sessions_count
|
||||
, emqx_sessions_max
|
||||
, emqx_topics_count
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_retainer,
|
||||
[{description, "EMQ X Retainer"},
|
||||
{vsn, "4.4.3"}, % strict semver, bump manually!
|
||||
{vsn, "4.4.4"}, % strict semver, bump manually!
|
||||
{modules, []},
|
||||
{registered, [emqx_retainer_sup]},
|
||||
{applications, [kernel,stdlib]},
|
||||
|
|
|
@ -1,15 +1,27 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{VSN,
|
||||
[{"4.4.2",[{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}]},
|
||||
{"4.4.1",[{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}]},
|
||||
[{"4.4.3",[{load_module,emqx_retainer,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",
|
||||
[{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,[]}]},
|
||||
{<<".*">>,[]}],
|
||||
[{"4.4.2",[{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}]},
|
||||
{"4.4.1",[{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]}]},
|
||||
[{"4.4.3",[{load_module,emqx_retainer,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",
|
||||
[{load_module,emqx_retainer_sup,brutal_purge,soft_purge,[]},
|
||||
{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,[]}]},
|
||||
{<<".*">>,[]}]}.
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
-include_lib("emqx/include/emqx.hrl").
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
-include_lib("stdlib/include/ms_transform.hrl").
|
||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||
|
||||
-logger_header("[Retainer]").
|
||||
|
||||
|
@ -74,11 +75,12 @@ on_session_subscribed(_, Topic, #{rh := Rh, is_new := IsNew}) ->
|
|||
|
||||
%% @private
|
||||
dispatch(Pid, Topic) ->
|
||||
Msgs = case emqx_topic:wildcard(Topic) of
|
||||
MsgsT = case emqx_topic:wildcard(Topic) of
|
||||
false -> read_messages(Topic);
|
||||
true -> match_messages(Topic)
|
||||
end,
|
||||
Now = erlang:system_time(millisecond),
|
||||
Msgs = drop_banned_messages(MsgsT),
|
||||
[Pid ! {deliver, Topic, refresh_timestamp_expiry(Msg, Now)} || Msg <- sort_retained(Msgs)].
|
||||
|
||||
%% 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) ->
|
||||
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("common_test/include/ct.hrl").
|
||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||
|
||||
all() -> emqx_ct:all(?MODULE).
|
||||
|
||||
|
@ -189,6 +190,53 @@ t_stop_publish_clear_msg(_) ->
|
|||
|
||||
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
|
||||
%%--------------------------------------------------------------------
|
||||
|
|
|
@ -1,22 +1,32 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{VSN,
|
||||
[{"4.4.14",[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
||||
{"4.4.13",[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
||||
[{<<"4\\.4\\.1[3-4]">>,
|
||||
[{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",
|
||||
[{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,[]},
|
||||
{update,emqx_rule_engine_jwt_sup,supervisor},
|
||||
{load_module,emqx_rule_engine_jwt,brutal_purge,soft_purge,[]}]},
|
||||
{"4.4.11",
|
||||
[{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},
|
||||
{load_module,emqx_rule_engine_jwt,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_api,brutal_purge,soft_purge,[]},
|
||||
{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",
|
||||
[{add_module,emqx_rule_engine_jwt},
|
||||
{add_module,emqx_rule_engine_jwt_worker},
|
||||
|
@ -222,15 +232,24 @@
|
|||
{load_module,emqx_rule_engine,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.13",[{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]}]},
|
||||
[{<<"4\\.4\\.1[3-4]">>,
|
||||
[{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",
|
||||
[{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,[]},
|
||||
{update,emqx_rule_engine_jwt_sup,supervisor},
|
||||
{load_module,emqx_rule_engine_jwt,brutal_purge,soft_purge,[]}]},
|
||||
{"4.4.11",
|
||||
[{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},
|
||||
{load_module,emqx_rule_engine_jwt,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_rule_registry,brutal_purge,soft_purge,[]},
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
, create_resource/1
|
||||
, test_resource/1
|
||||
, start_resource/1
|
||||
, start_all_resources_of_type/1
|
||||
, get_resource_status/1
|
||||
, is_resource_alive/1
|
||||
, is_resource_alive/2
|
||||
|
@ -354,7 +355,13 @@ do_check_and_update_resource(#{id := Id, type := Type, description := NewDescrip
|
|||
-spec(start_resource(resource_id()) -> ok | {error, Reason :: term()}).
|
||||
start_resource(ResId) ->
|
||||
case emqx_rule_registry:find_resource(ResId) of
|
||||
{ok, #resource{type = ResType, config = Config}} ->
|
||||
{ok, Res} ->
|
||||
do_start_resource(Res);
|
||||
not_found ->
|
||||
{error, {resource_not_found, ResId}}
|
||||
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
|
||||
|
@ -362,11 +369,13 @@ start_resource(ResId) ->
|
|||
refresh_actions_of_a_resource(ResId)
|
||||
catch
|
||||
throw:Reason -> {error, Reason}
|
||||
end;
|
||||
not_found ->
|
||||
{error, {resource_not_found, ResId}}
|
||||
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()}).
|
||||
test_resource(#{type := Type} = Params) ->
|
||||
case emqx_rule_registry:find_resource_type(Type) of
|
||||
|
@ -520,6 +529,15 @@ refresh_resource(#resource{id = ResId, type = Type, config = Config}) ->
|
|||
refresh_rules_when_boot() ->
|
||||
lists:foreach(fun
|
||||
(#rule{enabled = true} = Rule) ->
|
||||
ensure_rule_retrier(Rule);
|
||||
(#rule{enabled = false, state = refresh_failed_at_bootup} = Rule) ->
|
||||
%% the rule was previously disabled by emqx so we need to retry it
|
||||
ensure_rule_retrier(Rule);
|
||||
(#rule{enabled = false, id = RuleId}) ->
|
||||
?LOG(warning, "rule ~s was disabled by the user, won't re-enable it", [RuleId])
|
||||
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
|
||||
|
@ -528,10 +546,9 @@ refresh_rules_when_boot() ->
|
|||
%% 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})
|
||||
end;
|
||||
(_) -> ok
|
||||
end, emqx_rule_registry:get_rules()).
|
||||
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}) ->
|
||||
ok = emqx_rule_metrics:create_rule_metrics(RuleId),
|
||||
|
|
|
@ -853,9 +853,25 @@ printable_maps(Headers) ->
|
|||
value => Value
|
||||
} || {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) ->
|
||||
%% internal header
|
||||
%% internal header, remove it
|
||||
AccIn;
|
||||
(K, V, AccIn) ->
|
||||
AccIn#{K => V}
|
||||
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
|
||||
, async_refresh_resources_rules/0
|
||||
, ensure_resource_retrier/1
|
||||
, ensure_rule_retrier/1
|
||||
, retry_loop/2
|
||||
, retry_loop/3
|
||||
]).
|
||||
|
||||
%% fot test
|
||||
-export([ put_retry_interval/1
|
||||
, get_retry_interval/0
|
||||
, erase_retry_interval/0
|
||||
-export([ put_resource_retry_interval/1
|
||||
, put_rule_retry_interval/1
|
||||
, get_resource_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() ->
|
||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
@ -54,23 +59,33 @@ init([]) ->
|
|||
_ = erlang:process_flag(trap_exit, true),
|
||||
{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),
|
||||
ok.
|
||||
|
||||
erase_retry_interval() ->
|
||||
_ = persistent_term:erase({?MODULE, resource_restart_interval}),
|
||||
put_rule_retry_interval(I) when is_integer(I) andalso I >= 10 ->
|
||||
_ = persistent_term:put({?MODULE, rule_restart_interval}, I),
|
||||
ok.
|
||||
|
||||
get_retry_interval() ->
|
||||
persistent_term:get({?MODULE, resource_restart_interval}, ?T_RETRY).
|
||||
erase_resource_retry_interval() ->
|
||||
_ = 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() ->
|
||||
gen_server:cast(?MODULE, async_refresh).
|
||||
|
||||
ensure_resource_retrier(ResId) ->
|
||||
Interval = get_retry_interval(),
|
||||
gen_server:cast(?MODULE, {create_restart_handler, resource, ResId, Interval}).
|
||||
gen_server:cast(?MODULE, {create_restart_handler, resource, ResId}).
|
||||
|
||||
ensure_rule_retrier(RuleId) ->
|
||||
gen_server:cast(?MODULE, {create_restart_handler, rule, RuleId}).
|
||||
|
||||
handle_call(_Msg, _From, State) ->
|
||||
{reply, ok, State}.
|
||||
|
@ -82,12 +97,12 @@ handle_cast(async_refresh, State) ->
|
|||
Pid = spawn_link(fun do_async_refresh/0),
|
||||
{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, #{}),
|
||||
NewState = case maps:find(Obj, Objects) of
|
||||
error ->
|
||||
update_object(Tag, Obj,
|
||||
create_restart_handler(Tag, Obj, Interval), State);
|
||||
create_restart_handler(Tag, Obj), State);
|
||||
{ok, _Pid} ->
|
||||
State
|
||||
end,
|
||||
|
@ -130,13 +145,17 @@ update_object(Tag, Obj, Retryer, State) ->
|
|||
retryers => Retryers#{Retryer => {Tag, Obj}}
|
||||
}.
|
||||
|
||||
create_restart_handler(Tag, Obj, Interval) ->
|
||||
?LOG(info, "starting_a_retry_loop for ~p ~p, with delay interval: ~p", [Tag, Obj, Interval]),
|
||||
create_restart_handler(Tag, Obj) ->
|
||||
?LOG(warning, "starting_a_retry_loop for ~p ~p", [Tag, Obj]),
|
||||
%% 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) ->
|
||||
timer:sleep(Interval),
|
||||
%% retry_loop/3 is to avoid crashes during relup
|
||||
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
|
||||
{ok, #resource{type = Type, config = Config}} ->
|
||||
try
|
||||
|
@ -154,10 +173,30 @@ retry_loop(resource, ResId, Interval) ->
|
|||
end,
|
||||
?LOG_SENSITIVE(warning, "init_resource_retry_failed ~p, ~0p", [ResId, LogContext]),
|
||||
%% keep looping
|
||||
?MODULE:retry_loop(resource, ResId, Interval)
|
||||
?MODULE:retry_loop(resource, ResId)
|
||||
end;
|
||||
not_found ->
|
||||
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.
|
||||
|
||||
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) ->
|
||||
emqx_rule_engine:refresh_rule(Rule),
|
||||
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
|
||||
end, emqx_rule_registry:find_rules_depends_on_resource(ResId)).
|
||||
|
|
|
@ -36,18 +36,44 @@ t_mod_hook_fun(_) ->
|
|||
]].
|
||||
|
||||
t_printable_maps(_) ->
|
||||
Headers = #{peerhost => {127,0,0,1},
|
||||
TestMap = #{
|
||||
peerhost => {127,0,0,1},
|
||||
peername => {{127,0,0,1}, 9980},
|
||||
sockname => {{127,0,0,1}, 1883},
|
||||
redispatch_to => {<<"group">>, <<"sub/topic/+">>},
|
||||
shared_dispatch_ack => {self(), ref}
|
||||
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),
|
||||
Verify = fun(Result) ->
|
||||
?assertMatch(
|
||||
#{peerhost := <<"127.0.0.1">>,
|
||||
peername := <<"127.0.0.1:9980">>,
|
||||
sockname := <<"127.0.0.1:1883">>
|
||||
}, Converted),
|
||||
?assertNot(maps:is_key(redispatch_to, Converted)),
|
||||
?assertNot(maps:is_key(shared_dispatch_ack, Converted)),
|
||||
sockname := <<"127.0.0.1:1883">>,
|
||||
string := <<"abc">>,
|
||||
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.
|
||||
|
|
|
@ -48,7 +48,7 @@ end_per_suite(_Config) ->
|
|||
ok.
|
||||
|
||||
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}],
|
||||
_ = ets:new(?RES_PARAMS_TAB, [{keypos, #resource_params.id}|Opts]),
|
||||
ets:new(t_restart_resource, [named_table, public]),
|
||||
|
@ -90,12 +90,13 @@ end_per_testcase(_, Config) ->
|
|||
|
||||
common_init_per_testcase() ->
|
||||
AlarmOpts = [{actions, [log, publish]}, {size_limit, 1000}, {validity_period, 86400}],
|
||||
_ = emqx_alarm:mnesia(boot),
|
||||
{ok, _} = emqx_alarm:start_link(AlarmOpts),
|
||||
{ok, _} = emqx_rule_monitor:start_link().
|
||||
|
||||
common_end_per_testcases() ->
|
||||
ok = emqx_alarm:stop(),
|
||||
emqx_rule_monitor:erase_retry_interval(),
|
||||
emqx_rule_monitor:erase_resource_retry_interval(),
|
||||
emqx_rule_monitor:stop().
|
||||
|
||||
t_restart_resource(_) ->
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
{plugins, [rebar3_proper]}.
|
||||
|
||||
{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}]}.
|
||||
|
|
8
build
8
build
|
@ -205,6 +205,14 @@ make_zip() {
|
|||
;;
|
||||
esac
|
||||
;;
|
||||
ubuntu22)
|
||||
case "$PKG_VSN" in
|
||||
4.4.15*)
|
||||
# this is the first version for amzn2, no relup
|
||||
has_relup='no'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
macos*)
|
||||
case "$PKG_VSN" in
|
||||
4.4.12*)
|
||||
|
|
|
@ -1,7 +1,53 @@
|
|||
|
||||
# v4.4.15
|
||||
|
||||
## Enhancements
|
||||
|
||||
- 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
|
||||
|
||||
- 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.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`
|
||||
`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 | `{}`
|
||||
`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`
|
||||
|
|
|
@ -64,6 +64,7 @@ spec:
|
|||
checksum/config: {{ $configData | sha256sum | quote }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "emqx.serviceAccountName" . }}
|
||||
volumes:
|
||||
{{- if .Values.emqxLoadedPlugins }}
|
||||
- name: emqx-loaded-plugins
|
||||
|
@ -107,9 +108,6 @@ spec:
|
|||
secret:
|
||||
secretName: {{ $licenseSecretName }}
|
||||
{{- end }}
|
||||
{{- if eq (.Values.emqxConfig.EMQX_CLUSTER__DISCOVERY | default "k8s") "k8s" }}
|
||||
serviceAccountName: {{ include "emqx.fullname" . }}
|
||||
{{- end }}
|
||||
{{- if .Values.podSecurityContext.enabled }}
|
||||
securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
|
|
|
@ -30,3 +30,14 @@ Create chart name and version as used by the chart label.
|
|||
{{- define "emqx.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- 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
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
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
|
||||
{{- if semverCompare ">=1.17-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
|
@ -23,7 +36,12 @@ rules:
|
|||
- get
|
||||
- watch
|
||||
- list
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
---
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- if eq (.Values.emqxConfig.EMQX_CLUSTER__DISCOVERY | default "k8s") "k8s" }}
|
||||
kind: RoleBinding
|
||||
{{- if semverCompare ">=1.17-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
|
@ -35,10 +53,11 @@ metadata:
|
|||
name: {{ include "emqx.fullname" . }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "emqx.fullname" . }}
|
||||
name: {{ include "emqx.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: {{ include "emqx.fullname" . }}
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
|
|
@ -14,6 +14,16 @@ image:
|
|||
# pullSecrets:
|
||||
# - 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.
|
||||
recreatePods: false
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ reload(Env) ->
|
|||
unload(Env), load(Env).
|
||||
|
||||
description() ->
|
||||
"EMQ X Internal ACL Module".
|
||||
"EMQX Internal ACL Module".
|
||||
%%--------------------------------------------------------------------
|
||||
%% ACL callbacks
|
||||
%%--------------------------------------------------------------------
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
-include_lib("emqx/include/emqx.hrl").
|
||||
-include_lib("emqx/include/logger.hrl").
|
||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||
|
||||
-logger_header("[Delayed]").
|
||||
|
||||
|
@ -94,7 +95,7 @@ unload(_Env) ->
|
|||
emqx_mod_sup:stop_child(?MODULE).
|
||||
|
||||
description() ->
|
||||
"EMQ X Delayed Publish Module".
|
||||
"EMQX Delayed Publish Module".
|
||||
%%--------------------------------------------------------------------
|
||||
%% Hooks
|
||||
%%--------------------------------------------------------------------
|
||||
|
@ -228,7 +229,20 @@ do_publish(Key = {Ts, _Id}, Now, Acc) when Ts =< Now ->
|
|||
case mnesia:dirty_read(?TAB, Key) of
|
||||
[] -> ok;
|
||||
[#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,
|
||||
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}).
|
||||
|
||||
description() ->
|
||||
"EMQ X Presence Module".
|
||||
"EMQX Presence Module".
|
||||
%%--------------------------------------------------------------------
|
||||
%% Callbacks
|
||||
%%--------------------------------------------------------------------
|
||||
|
|
|
@ -71,7 +71,7 @@ unload(_) ->
|
|||
emqx_hooks:del('message.publish', {?MODULE, rewrite_publish}).
|
||||
|
||||
description() ->
|
||||
"EMQ X Topic Rewrite Module".
|
||||
"EMQX Topic Rewrite Module".
|
||||
%%--------------------------------------------------------------------
|
||||
%% Internal functions
|
||||
%%--------------------------------------------------------------------
|
||||
|
|
|
@ -46,4 +46,4 @@ unload(_Env) ->
|
|||
ok.
|
||||
|
||||
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}).
|
||||
|
||||
description() ->
|
||||
"EMQ X Subscription Module".
|
||||
"EMQX Subscription Module".
|
||||
%%--------------------------------------------------------------------
|
||||
%% Internal functions
|
||||
%%--------------------------------------------------------------------
|
||||
|
|
|
@ -113,7 +113,7 @@ unload(_Env) ->
|
|||
emqx_mod_sup:stop_child(?MODULE).
|
||||
|
||||
description() ->
|
||||
"EMQ X Topic Metrics Module".
|
||||
"EMQX Topic Metrics Module".
|
||||
|
||||
on_message_publish(#message{topic = Topic, qos = QoS}) ->
|
||||
case is_registered(Topic) of
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
-spec description() -> string().
|
||||
description() ->
|
||||
"EMQ X Trace Module".
|
||||
"EMQX Trace Module".
|
||||
|
||||
-spec load(any()) -> ok.
|
||||
load(_Env) ->
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{application, emqx_modules,
|
||||
[{description, "EMQ X Module Management"},
|
||||
{vsn, "4.4.8"},
|
||||
{vsn, "4.4.9"},
|
||||
{modules, []},
|
||||
{applications, [kernel,stdlib]},
|
||||
{mod, {emqx_modules_app, []}},
|
||||
|
|
|
@ -1,81 +1,75 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{VSN,
|
||||
[{"4.4.7",[{load_module,emqx_mod_rewrite,brutal_purge,soft_purge,[]}]},
|
||||
{"4.4.6",
|
||||
[{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,[]},
|
||||
[{<<"4\\.4\\.[6-8]">>,
|
||||
[{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_sup,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_mod_trace_api,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,[]}
|
||||
]},
|
||||
{<<"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",
|
||||
[{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,[]},
|
||||
[{<<"4\\.4\\.[6-8]">>,
|
||||
[{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_sup,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_mod_trace_api,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,[]}
|
||||
]},
|
||||
{<<"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("eunit/include/eunit.hrl").
|
||||
-include_lib("emqx/include/emqx.hrl").
|
||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Setups
|
||||
|
@ -78,3 +79,46 @@ t_delayed_message(_) ->
|
|||
EmptyKey = mnesia:dirty_all_keys(emqx_mod_delayed),
|
||||
?assertEqual([], EmptyKey),
|
||||
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
|
||||
, {redbug, "2.0.7"}
|
||||
, {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"}}}
|
||||
, {eredis_cluster, {git, "https://github.com/emqx/eredis_cluster", {tag, "0.7.4"}}}
|
||||
, {gproc, {git, "https://github.com/uwiger/gproc", {tag, "0.9.0"}}}
|
||||
, {jiffy, {git, "https://github.com/emqx/jiffy", {tag, "1.0.5"}}}
|
||||
, {cowboy, {git, "https://github.com/emqx/cowboy", {tag, "2.9.0"}}}
|
||||
, {esockd, {git, "https://github.com/emqx/esockd", {tag, "5.8.7"}}}
|
||||
, {cowboy, {git, "https://github.com/emqx/cowboy", {tag, "2.9.1"}}}
|
||||
, {esockd, {git, "https://github.com/emqx/esockd", {tag, "5.8.8"}}}
|
||||
, {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"}}}
|
||||
, {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"}}}
|
||||
, {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"}}}
|
||||
, {emqtt, {git, "https://github.com/emqx/emqtt", {tag, "1.2.3.1"}}}
|
||||
, {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"}}}
|
||||
, {lc, {git, "https://github.com/emqx/lc.git", {tag, "0.3.2"}}}
|
||||
, {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"}}}
|
||||
, {grpc, {git, "https://github.com/emqx/grpc-erl", {tag, "0.6.7"}}}
|
||||
]}.
|
||||
|
|
|
@ -176,6 +176,11 @@ filter_froms(Froms0, AvailableVersionsIndex) ->
|
|||
{"amzn2", _} ->
|
||||
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);
|
||||
%% 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
|
||||
%% exclude tags before them
|
||||
{"macos" ++ _, "aarch64" ++ _} ->
|
||||
|
|
|
@ -2,23 +2,57 @@
|
|||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{VSN,
|
||||
[{"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,[]}]},
|
||||
{"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_cm,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,[]}]},
|
||||
{"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_cm,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,[]}]},
|
||||
{"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},
|
||||
{load_module,emqx,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_relup,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_misc,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_channel,brutal_purge,soft_purge,[]}]},
|
||||
{"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_ocsp_cache},
|
||||
{add_module,emqx_crl_cache},
|
||||
|
@ -47,7 +86,12 @@
|
|||
{apply,{application,set_env,
|
||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||
{"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_ocsp_cache},
|
||||
{add_module,emqx_crl_cache},
|
||||
|
@ -74,7 +118,12 @@
|
|||
{apply,{application,set_env,
|
||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||
{"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_ocsp_cache},
|
||||
{add_module,emqx_crl_cache},
|
||||
|
@ -102,7 +151,12 @@
|
|||
{apply,{application,set_env,
|
||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||
{"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_ocsp_cache},
|
||||
{add_module,emqx_crl_cache},
|
||||
|
@ -130,7 +184,12 @@
|
|||
{apply,{application,set_env,
|
||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||
{"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_ocsp_cache},
|
||||
{add_module,emqx_crl_cache},
|
||||
|
@ -158,7 +217,12 @@
|
|||
{apply,{application,set_env,
|
||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||
{"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_ocsp_cache},
|
||||
{add_module,emqx_crl_cache},
|
||||
|
@ -188,7 +252,11 @@
|
|||
{apply,{application,set_env,
|
||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||
{"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_ocsp_cache},
|
||||
{add_module,emqx_crl_cache},
|
||||
|
@ -225,7 +293,10 @@
|
|||
{apply,{application,set_env,
|
||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||
{"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_ocsp_cache},
|
||||
{add_module,emqx_crl_cache},
|
||||
|
@ -269,7 +340,10 @@
|
|||
{apply,{application,set_env,
|
||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||
{"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_ocsp_cache},
|
||||
{add_module,emqx_crl_cache},
|
||||
|
@ -314,7 +388,9 @@
|
|||
{apply,{application,set_env,
|
||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||
{"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_ocsp_cache},
|
||||
{add_module,emqx_crl_cache},
|
||||
|
@ -364,7 +440,9 @@
|
|||
{apply,{application,set_env,
|
||||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||
{"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_ocsp_cache},
|
||||
{add_module,emqx_crl_cache},
|
||||
|
@ -417,22 +495,56 @@
|
|||
[gen_rpc,insecure_auth_fallback_allowed,true]}}]},
|
||||
{<<".*">>,[]}],
|
||||
[{"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,[]}]},
|
||||
{"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_cm,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,[]}]},
|
||||
{"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_cm,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,[]}]},
|
||||
{"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_app,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_misc,brutal_purge,soft_purge,[]},
|
||||
|
@ -441,7 +553,12 @@
|
|||
{load_module,emqx_session,brutal_purge,soft_purge,[]},
|
||||
{delete_module,emqx_cover}]},
|
||||
{"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_kernel_sup,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_ocsp_cache}]},
|
||||
{"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_kernel_sup,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_ocsp_cache}]},
|
||||
{"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_kernel_sup,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_ocsp_cache}]},
|
||||
{"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_kernel_sup,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_ocsp_cache}]},
|
||||
{"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_kernel_sup,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_ocsp_cache}]},
|
||||
{"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_kernel_sup,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_ocsp_cache}]},
|
||||
{"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_kernel_sup,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||
|
@ -613,7 +759,10 @@
|
|||
{delete_module,emqx_crl_cache},
|
||||
{delete_module,emqx_ocsp_cache}]},
|
||||
{"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_kernel_sup,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_hooks,brutal_purge,soft_purge,[]},
|
||||
|
@ -652,7 +801,10 @@
|
|||
{delete_module,emqx_crl_cache},
|
||||
{delete_module,emqx_ocsp_cache}]},
|
||||
{"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_kernel_sup,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_ocsp_cache}]},
|
||||
{"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_router_helper,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_ocsp_cache}]},
|
||||
{"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_router_helper,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
|
||||
-export([ set_debug_secret/1
|
||||
, default_started_applications/0
|
||||
, expand_apps/1
|
||||
]).
|
||||
|
||||
-define(APP, ?MODULE).
|
||||
|
@ -252,14 +254,6 @@ is_application_running(App) ->
|
|||
StartedApps = proplists:get_value(started, application:info()),
|
||||
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).
|
||||
on_reboot() ->
|
||||
try
|
||||
|
@ -290,6 +284,54 @@ on_shutdown(_) ->
|
|||
%%--------------------------------------------------------------------
|
||||
%% 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) ->
|
||||
{ok, [Conf]} = file:consult(ConfFile),
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
-include("emqx.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("types.hrl").
|
||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||
|
||||
-logger_header("[Banned]").
|
||||
|
||||
|
@ -36,6 +37,7 @@
|
|||
, create/1
|
||||
, delete/1
|
||||
, info/1
|
||||
, look_up/1
|
||||
]).
|
||||
|
||||
%% gen_server callbacks
|
||||
|
@ -94,13 +96,15 @@ create(#{who := Who,
|
|||
reason := Reason,
|
||||
at := At,
|
||||
until := Until}) ->
|
||||
mnesia:dirty_write(?BANNED_TAB, #banned{who = Who,
|
||||
insert_banned(#banned{
|
||||
who = Who,
|
||||
by = By,
|
||||
reason = Reason,
|
||||
at = At,
|
||||
until = Until});
|
||||
until = Until
|
||||
});
|
||||
create(Banned) when is_record(Banned, banned) ->
|
||||
mnesia:dirty_write(?BANNED_TAB, Banned).
|
||||
insert_banned(Banned).
|
||||
|
||||
-spec(delete({clientid, emqx_types:clientid()}
|
||||
| {username, emqx_types:username()}
|
||||
|
@ -111,6 +115,9 @@ delete(Who) ->
|
|||
info(InfoKey) ->
|
||||
mnesia:table_info(?BANNED_TAB, InfoKey).
|
||||
|
||||
look_up(Who) ->
|
||||
mnesia:dirty_read(?BANNED_TAB, Who).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% gen_server callbacks
|
||||
%%--------------------------------------------------------------------
|
||||
|
@ -159,3 +166,20 @@ expire_banned_items(Now) ->
|
|||
(_, _Acc) -> ok
|
||||
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_object(?SUBSCRIPTION, {SubPid, Topic}),
|
||||
Group = maps:get(share, SubOpts, undefined),
|
||||
do_unsubscribe(Group, Topic, SubPid, SubOpts),
|
||||
emqx_exclusive_subscription:unsubscribe(Topic, SubOpts).
|
||||
do_unsubscribe(Group, Topic, SubPid, SubOpts).
|
||||
|
||||
do_unsubscribe(undefined, Topic, SubPid, SubOpts) ->
|
||||
clean_subscribe(SubOpts, Topic, SubPid);
|
||||
|
@ -344,9 +343,12 @@ subscriber_down(SubPid) ->
|
|||
|
||||
clean_subscribe(SubOpts, Topic, SubPid) ->
|
||||
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});
|
||||
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})
|
||||
end.
|
||||
|
||||
|
|
|
@ -434,7 +434,7 @@ handle_msg({'$gen_cast', Req}, State) ->
|
|||
{ok, NewState};
|
||||
|
||||
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),
|
||||
inc_counter(incoming_bytes, 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)};
|
||||
{ok, _CRLs} ->
|
||||
?LOG(debug, "fetched crl response for ~p", [URL]),
|
||||
?tp(crl_refresh_timer_done, #{url => URL}),
|
||||
{noreply, ensure_timer(URL, State)}
|
||||
end;
|
||||
_ ->
|
||||
|
|
|
@ -73,6 +73,7 @@ check(NewVal, KeepAlive = #keepalive{statval = OldVal,
|
|||
true -> {error, timeout}
|
||||
end.
|
||||
|
||||
-define(IS_KEEPALIVE(Interval), Interval >= 0 andalso Interval =< 65535000).
|
||||
%% from mqtt-v3.1.1 specific
|
||||
%% 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
|
||||
|
@ -85,7 +86,10 @@ check(NewVal, KeepAlive = #keepalive{statval = OldVal,
|
|||
%% typically this is a few minutes.
|
||||
%% The maximum value is (65535s) 18 hours 12 minutes and 15 seconds.
|
||||
|
||||
%% @doc Update keepalive's interval
|
||||
-spec(set(interval, non_neg_integer(), keepalive()) -> keepalive()).
|
||||
set(interval, Interval, KeepAlive) when Interval >= 0 andalso Interval =< 65535000 ->
|
||||
%% @doc Update keepalive interval
|
||||
%% The keepalive() is undefined when connecting via keepalive=0.
|
||||
-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}.
|
||||
|
|
|
@ -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)]),
|
||||
case S == undefined of
|
||||
true -> [Header, ")"];
|
||||
false -> [Header, S, ")"]
|
||||
false -> [Header, ", ", S, ")"]
|
||||
end.
|
||||
|
||||
format_variable(undefined, _) ->
|
||||
|
|
|
@ -32,6 +32,7 @@ post_release_upgrade(FromRelVsn, _) ->
|
|||
{_, CurrRelVsn} = ?EMQX_RELEASE,
|
||||
?INFO("emqx has been upgraded from ~s to ~s!", [FromRelVsn, CurrRelVsn]),
|
||||
maybe_refresh_jwt_module(FromRelVsn),
|
||||
_ = maybe_restart_oracle_resources(FromRelVsn),
|
||||
reload_components().
|
||||
|
||||
%% What to do after downgraded to an old release vsn.
|
||||
|
@ -93,3 +94,27 @@ maybe_refresh_jwt_module(_) ->
|
|||
ok.
|
||||
|
||||
-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"]),
|
||||
case file:read_file(Filename) of
|
||||
{ok, BuiltOn} ->
|
||||
%% running on EQM X release
|
||||
%% running on EQMX release
|
||||
BuiltOn;
|
||||
{error, enoent} ->
|
||||
%% running tests etc.
|
||||
OtpMajor = erlang:system_info(otp_release),
|
||||
OtpVsnFile = filename:join([ReleasesDir, OtpMajor, "OTP_VERSION"]),
|
||||
{ok, Vsn} = file:read_file(OtpVsnFile),
|
||||
Vsn
|
||||
case file:read_file(OtpVsnFile) of
|
||||
{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.
|
||||
|
||||
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, Data}, State) ->
|
||||
?LOG(debug, "RECV ~0p", [Data]),
|
||||
?LOG(debug, "RECV ~w", [Data]),
|
||||
ok = inc_recv_stats(1, iolist_size(Data)),
|
||||
NState = ensure_stats_timer(State),
|
||||
return(parse_incoming(Data, NState));
|
||||
|
|
|
@ -21,11 +21,12 @@
|
|||
|
||||
-include_lib("emqx/include/emqx.hrl").
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
-include_lib("snabbkaffe/include/snabbkaffe.hrl").
|
||||
|
||||
all() -> emqx_ct:all(?MODULE).
|
||||
|
||||
init_per_suite(Config) ->
|
||||
application:load(emqx),
|
||||
emqx_ct_helpers:start_apps([]),
|
||||
ok = ekka:start(),
|
||||
%% for coverage
|
||||
ok = emqx_banned:mnesia(copy),
|
||||
|
@ -34,7 +35,8 @@ init_per_suite(Config) ->
|
|||
end_per_suite(_Config) ->
|
||||
ekka:stop(),
|
||||
ekka_mnesia:ensure_stopped(),
|
||||
ekka_mnesia:delete_schema().
|
||||
ekka_mnesia:delete_schema(),
|
||||
emqx_ct_helpers:stop_apps([]).
|
||||
|
||||
t_add_delete(_) ->
|
||||
Banned = #banned{who = {clientid, <<"TestClient">>},
|
||||
|
@ -84,7 +86,10 @@ t_check(_) ->
|
|||
?assertEqual(0, emqx_banned:info(size)).
|
||||
|
||||
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">>},
|
||||
until = erlang:system_time(second)}),
|
||||
?assertEqual(ignored, gen_server:call(Banned, unexpected_req)),
|
||||
|
@ -93,3 +98,22 @@ t_unused(_) ->
|
|||
timer:sleep(500), %% expiry timer
|
||||
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_revoked ->
|
||||
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),
|
||||
[{'CertificateList', CRLDer, not_encrypted}] = public_key:pem_decode(CRLPem),
|
||||
ServerPid = start_crl_server(CRLPem),
|
||||
|
@ -53,9 +53,44 @@ init_per_testcase(TestCase, Config)
|
|||
, {crl_der, CRLDer}
|
||||
, {http_server, ServerPid}
|
||||
| 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) ->
|
||||
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),
|
||||
[{'CertificateList', CRLDer, not_encrypted}] = public_key:pem_decode(CRLPem),
|
||||
application:stop(cowboy),
|
||||
|
@ -65,7 +100,7 @@ init_per_testcase(t_not_cached_and_unreachable, Config) ->
|
|||
| Config];
|
||||
init_per_testcase(t_refresh_config, 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),
|
||||
[{'CertificateList', CRLDer, not_encrypted}] = public_key:pem_decode(CRLPem),
|
||||
TestPid = self(),
|
||||
|
@ -88,7 +123,7 @@ init_per_testcase(t_refresh_config, Config) ->
|
|||
| Config];
|
||||
init_per_testcase(_TestCase, 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),
|
||||
[{'CertificateList', CRLDer, not_encrypted}] = public_key:pem_decode(CRLPem),
|
||||
TestPid = self(),
|
||||
|
@ -118,6 +153,30 @@ end_per_testcase(TestCase, Config)
|
|||
clear_crl_cache(),
|
||||
ok = snabbkaffe:stop(),
|
||||
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) ->
|
||||
emqx_ct_helpers:stop_apps([]),
|
||||
emqx_ct_helpers:change_emqx_opts(
|
||||
|
@ -229,7 +288,7 @@ force_cacertfile(Cacertfile) ->
|
|||
application:set_env(emqx, listeners, SSLListeners ++ OtherListeners),
|
||||
ok.
|
||||
|
||||
setup_crl_options(Config, #{is_cached := IsCached}) ->
|
||||
setup_crl_options(Config, Opts = #{is_cached := IsCached}) ->
|
||||
DataDir = ?config(data_dir, Config),
|
||||
Cacertfile = filename:join(DataDir, "ca-chain.cert.pem"),
|
||||
Certfile = filename:join(DataDir, "server.cert.pem"),
|
||||
|
@ -238,6 +297,7 @@ setup_crl_options(Config, #{is_cached := IsCached}) ->
|
|||
false -> [];
|
||||
true -> ["http://localhost:9878/intermediate.crl.pem"]
|
||||
end,
|
||||
ExtraHandler = maps:get(extra_handler, Opts, fun(_) -> ok end),
|
||||
Handler =
|
||||
fun(emqx) ->
|
||||
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....
|
||||
ok = force_cacertfile(Cacertfile),
|
||||
ExtraHandler(emqx),
|
||||
ok;
|
||||
(_) ->
|
||||
(App) ->
|
||||
ExtraHandler(App),
|
||||
ok
|
||||
end,
|
||||
emqx_ct_helpers:start_apps([], Handler),
|
||||
|
@ -546,3 +608,39 @@ t_revoked(Config) ->
|
|||
process_flag(trap_exit, true),
|
||||
?assertMatch({error, {{shutdown, {tls_alert, {certificate_revoked, _}}}, _}}, emqtt:connect(C)),
|
||||
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
|
||||
EjAQBgNVBAgMCVN0b2NraG9sbTESMBAGA1UEBwwJU3RvY2tob2xtMRIwEAYDVQQK
|
||||
DAlNeU9yZ05hbWUxETAPBgNVBAsMCE15Um9vdENBMREwDwYDVQQDDAhNeVJvb3RD
|
||||
QTAeFw0yMjA2MTMxMjQyMDVaFw0zMjA2MTAxMjQyMDVaMGsxCzAJBgNVBAYTAlNF
|
||||
QTAeFw0yMzAxMTIxMzA4MTZaFw0zMzAxMDkxMzA4MTZaMGsxCzAJBgNVBAYTAlNF
|
||||
MRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAoMCU15T3JnTmFtZTEZMBcGA1UE
|
||||
CwwQTXlJbnRlcm1lZGlhdGVDQTEZMBcGA1UEAwwQTXlJbnRlcm1lZGlhdGVDQTCC
|
||||
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAN32wUPOGrLjVHY37ICI4sWH
|
||||
2GBEYgGtoKyZTfLKqK8W965uxHxMKKeKC7Ro93ScT4giR2GdsCvMyLP4Dlv7FxL7
|
||||
rWEHc7vbP22uT4NQQ0hgfl4ch8rTiSl/5FfynOuvMHnKh58z+lGyQ/uqKqAzc6OD
|
||||
6FypzSQO2R6JpA+kxKlbTYmOcsLiLFKjCjxyA1ibeozUaRHjPRM7VLHVxYfmpGm/
|
||||
86NJxtHrw4hwoKIM9bfURboxfn9R1YM14mZYA6Uw2pScS1+j79tNy74NQNYu1t9E
|
||||
cyPQk+AJdp2BsbR5KPYr1SMVLHlTwnzjk1IVW4wUUdX2h56ygmRNo9ui74ODfyud
|
||||
4cclg45SeRdOT0w5e3g20ZvfLZpIkhXk19EIIU/YbG6GpL8gLvBHkz6vvidE7L/2
|
||||
h2//alJBeWCvyOloIWYNYnwnHGeXR2c5pzNxHipkBSuMeBaLJOO7X9oqKVanu+xq
|
||||
nVagFhEYnd+T0PsPa5IVA73KiWMWWeFgJI0pRUydyp0/FhXEhkMWZNJHiscbxcdn
|
||||
hTdNCAbMfV/4fMar+d/QKY/GMWUVQ4OlXUoo3WjjRi4T8NJEjZGfLdKw5x81WM4A
|
||||
yqDV3OVVCBf1XrHH4IbvbUDgeG1OEGSV9pdvKX4Sm7226vdOc3HPfRnVyf/N1Pv7
|
||||
lzPbUlCheKbTW6Oeq97VAgMBAAGjgaQwgaEwHQYDVR0OBBYEFCuv1TkzC1fSgTfz
|
||||
E1m1u5pRCJsVMB8GA1UdIwQYMBaAFErA8sZMX6obhoo3XvUpaTy6Z4uhMBIGA1Ud
|
||||
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALQG7dMeU/y9HDNHzhydR0bm
|
||||
wN9UGplqJOJPwqJRaZZcrn9umgJ9SU2il2ceEVxMDwzBWCRKJO5/H9A9k13SqsXM
|
||||
2c2c9xXfIF1kb820lCm1Uow5hZ/auDjxliNk9kNJDigCRi3QoIs/dVeWzFsgEC2l
|
||||
gxRqauN2eNFb6/yXY788YALHBsCRV2NFOFXxtPsvLXpD9Q/8EqYsSMuLARRdHVNU
|
||||
ryaEF5lhShpcuz0TlIuTy2TiuXJUtJ+p7a4Z7friZ6JsrmQWsVQBj44F8TJRHWzW
|
||||
C7vm9c+dzEX9eqbr5iPL+L4ctMW9Lz6ePcYfIXne6CElusRUf8G+xM1uwovF9bpV
|
||||
+9IqY7tAu9G1iY9iNtJgNNDKOCcOGKcZCx6Cg1XYOEKReNnUMazvYeqRrrjV5WQ0
|
||||
vOcD5zcBRNTXCddCLa7U0guXP9mQrfuk4NTH1Bt77JieTJ8cfDXHwtaKf6aGbmZP
|
||||
wl1Xi/GuXNUP/xeog78RKyFwBmjt2JKwvWzMpfmH4mEkG9moh2alva+aEz6LIJuP
|
||||
16g6s0Q6c793/OvUtpNcewHw4Vjn39LD9o6VLp854G4n8dVpUWSbWS+sXD1ZE69H
|
||||
g/sMNMyq+09ufkbewY8xoCm/rQ1pqDZAVMWsstJEaYu7b/eb7R+RGOj1YECCV/Yp
|
||||
EZPdDotbSNRkIi2d/a1NAgMBAAGjgaQwgaEwHQYDVR0OBBYEFExwhjsVUom6tQ+S
|
||||
qq6xMUETvnPzMB8GA1UdIwQYMBaAFD90kfU5pc5l48THu0Ayj9SNpHuhMBIGA1Ud
|
||||
EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMDsGA1UdHwQ0MDIwMKAuoCyG
|
||||
Kmh0dHA6Ly9sb2NhbGhvc3Q6OTg3OC9pbnRlcm1lZGlhdGUuY3JsLnBlbTANBgkq
|
||||
hkiG9w0BAQsFAAOCAgEAtn/u/ZfmioZyh5DNETRNAftXWvxOyi2MK8soNEsaSbmq
|
||||
2ajkQwJ1MZ0+C5HuzsoEEoqStYtD3JG34ydPzQbMPwkTDg48+guu8ji30jYXGIfI
|
||||
RQQfseEj1hN8wTLEDAJGl17kJA+js6dcHkJp93qocOCoOwa5MAYB8ZZq/uRJlzVt
|
||||
ol6dvhBvhoxkKvJfrhg5dNISVBgIXrs5YOMyXqh6W3YMmepNjs05e5bcLYADyHCd
|
||||
f4TK9pgyys4OIVHiRZo0+hlaChKo4vDK7acgZOds7qxS/sxrwKe49FTIrAWWP6fG
|
||||
Ij2RHF91fLhi+10oVVSWtCyWRJOaSM4cenbLN36OUg1JswacsqojTCUylMAa8sAB
|
||||
RggZ+tt8LlARj3/pdz6IWrccabC+AGZQa1kOKl97hjsE0qy9V5WOiueJ+78u+BY5
|
||||
NXIoIyuPG0WCItb76jyn7UDjiCsJt7rfJ5t5rRVLpm8YRG43KuMWjXih/bT07YdE
|
||||
tA3X5Bk/XLQBqQbRKpR5+CKFhvXbNmKnuAdFbiG8UTFQdo/HGyBR7zzkF4vTqu8s
|
||||
2pMl4xFAMNnGsWQYce6YioQfYL3apgx9PIqgHr+IzXae6/NIpoIs9ShymEZP1jT5
|
||||
9DqKzmUQz3czc7RNXLUZbWxoWRtivrDJGPgbSHyMqVu4h2yLINftHSGegC+ZEgc=
|
||||
hkiG9w0BAQsFAAOCAgEAK6NgdWQYtPNKQNBGjsgtgqTRh+k30iqSO6Y3yE1KGABO
|
||||
EuQdVqkC2qUIbCB0M0qoV0ab50KNLfU6cbshggW4LDpcMpoQpI05fukNh1jm3ZuZ
|
||||
0xsB7vlmlsv00tpqmfIl/zykPDynHKOmFh/hJP/KetMy4+wDv4/+xP31UdEj5XvG
|
||||
HvMtuqOS23A+H6WPU7ol7KzKBnU2zz/xekvPbUD3JqV+ynP5bgbIZHAndd0o9T8e
|
||||
NFX23Us4cTenU2/ZlOq694bRzGaK+n3Ksz995Nbtzv5fbUgqmf7Mcq4iHGRVtV11
|
||||
MRyBrsXZp2vbF63c4hrf2Zd6SWRoaDKRhP2DMhajpH9zZASSTlfejg/ZRO2s+Clh
|
||||
YrSTkeMAdnRt6i/q4QRcOTCfsX75RFM5v67njvTXsSaSTnAwaPi78tRtf+WSh0EP
|
||||
VVPzy++BszBVlJ1VAf7soWZHCjZxZ8ZPqVTy5okoHwWQ09WmYe8GfulDh1oj0wbK
|
||||
3FjN7bODWHJN+bFf5aQfK+tumYKoPG8RXL6QxpEzjFWjxhIMJHHMKfDWnAV1o1+7
|
||||
/1/aDzq7MzEYBbrgQR7oE5ZHtyqhCf9LUgw0Kr7/8QWuNAdeDCJzjXRROU0hJczp
|
||||
dOyfRlLbHmLLmGOnROlx6LsGNQ17zuz6SPi7ei8/ylhykawDOAGkM1+xFakmQhM=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFzzCCA7egAwIBAgIUVYtdlrTMH1BoMy9JpiiL/FXv5NMwDQYJKoZIhvcNAQEL
|
||||
MIIFzzCCA7egAwIBAgIUYjc7hD7/UJ0/VPADfNfp/WpOwRowDQYJKoZIhvcNAQEL
|
||||
BQAwbzELMAkGA1UEBhMCU0UxEjAQBgNVBAgMCVN0b2NraG9sbTESMBAGA1UEBwwJ
|
||||
U3RvY2tob2xtMRIwEAYDVQQKDAlNeU9yZ05hbWUxETAPBgNVBAsMCE15Um9vdENB
|
||||
MREwDwYDVQQDDAhNeVJvb3RDQTAeFw0yMjA2MTMxMjQyMDVaFw00MjA2MDgxMjQy
|
||||
MDVaMG8xCzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAcM
|
||||
MREwDwYDVQQDDAhNeVJvb3RDQTAeFw0yMzAxMTIxMzA4MTRaFw00MzAxMDcxMzA4
|
||||
MTRaMG8xCzAJBgNVBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAcM
|
||||
CVN0b2NraG9sbTESMBAGA1UECgwJTXlPcmdOYW1lMREwDwYDVQQLDAhNeVJvb3RD
|
||||
QTERMA8GA1UEAwwITXlSb290Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
|
||||
AoICAQDRKeWdrXluKLuVxTXxpWbCzBm/6x+kg8EjhIKUm9Mq0t+cOLC1sn99s4E0
|
||||
/NBA7jc3O+hQ9S2fZuMp9OUXuf8HjjtlKQY2M9T9kCE9Yxc+ygpcPEvDYl0ke/1r
|
||||
m6eUOGS2LkIDHebuYbY+KGXjpaF15w49q199wQAk0sbdcCiv+OymBUxi3lrHepo3
|
||||
EBIjHtTwNtehgeiJfxCe8TLlLpbPdCsMNwlPvNa0E+1Ol1P9DfHPfK1Dt0ua8X5q
|
||||
ZBhnW1cawrwzrnth2ZtrSw7RaWhtNWFt/SdedGPgVUMIgFY2I7f2wT2hoe8R/D+e
|
||||
XLDzVMAW+yrlu/LlBaHE2Ffkk2La8mSHwJOvCZ/Q0V1mJnj6F4pfNemY4MnFX6Jm
|
||||
7u2TSWooowMppdNPCCRlGk+XS8lfmb9N/0RsOMSz5+1u8wOfFI6Z1GaH6K2Ne2xf
|
||||
VIBjhGRAiTCHDIFNYBCeAxR64zYeGFKv8L19oV6cbA6St7GMikfk5U/fyG9SUK88
|
||||
Fvjm+MrNDu/EEyjkKhK6I9ao3Pb4LcCofTcu44RBYT0HhkjqGWQgapm0i80NcRlL
|
||||
yK7wm5C8Tntmbehg1KE8iqSzAcBZu6L+j4qQ90T+AIHNTmRUa9dH2uhEej4hIhjd
|
||||
yJSJcDm4/CYEuK6WgZ6EuJadRy4QgPiH7zWCFXp/OGLvFmUEWQIDAQABo2MwYTAd
|
||||
BgNVHQ4EFgQUSsDyxkxfqhuGijde9SlpPLpni6EwHwYDVR0jBBgwFoAUSsDyxkxf
|
||||
qhuGijde9SlpPLpni6EwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw
|
||||
DQYJKoZIhvcNAQELBQADggIBAJQSy3WpS/j8emep2gJXB7jYxolhhN78DiJaqUZh
|
||||
0YXa19YaghAsk5YVqbe2XLAGyFqAmmGQ6ymCbULqkdSNUTLTvwHYGFYH7NizUaCS
|
||||
r9XaB9lizr7dwpd/8HwpqMq7rxNXLMNfl3iVywiKkah6r3goNwz9xgclOj1Q2Uly
|
||||
s5S3BaNnf8Q9ypygbUMOalYN6KzHloj52inX3fpGfOov0O/1+bkp/3SvATU0aRpB
|
||||
4bKLt99b69x1HSIkCNxeJQz2klgEMNQYGsnXOYCvnI0cOpGGDxQuIYiZbYbTJb7X
|
||||
FI7FfV0ryn55mMLgZboGezMhWGYeHpWfa7H0La1ZjgedBsu3HH5VaPuHOngFNa+X
|
||||
78vbWFcD09biZJwatwZlRjFGItaPSyhqSWJx1IqBZ98ZG9ziOVQ+kq1+uRecI/3S
|
||||
jNw8LFDnOH20UxJnhRddA7f7cFWkk3WRIIec+wvE7uOibHDwFmqCo6JeOhkZDF5f
|
||||
R1dfN4CZznMzbUb5iqUb4JwGdViijCaDHTEe3C3nKS1mPxt2kn3H1C37y71Fh5yu
|
||||
mStVxjZZTdbaP8WPEAEDhK+7eB6pAKa+ERXOlWY1L5nNkh4ahIw5837yIY60oyBh
|
||||
goiqX/Vy0wEJMa7HgXT3cDnW4NiXQA8nVKsRUiZco136YAATS89iLk3ibYJxzGP+
|
||||
G2LZ
|
||||
AoICAQCnBwSOYVJw47IoMHMXTVDtOYvUt3rqsurEhFcB4O8xmf2mmwr6m7s8A5Ft
|
||||
AvAehg1GvnXT3t/KiyU7BK+acTwcErGyZwS2wvdB0lpHWSpOn/u5y+4ZETvQefcj
|
||||
ZTdDOM9VN5nutpitgNb+1yL8sqSexfVbY7DnYYvFjOVBYoP/SGvM9jVjCad+0WL3
|
||||
FhuD+L8QAxzCieX3n9UMymlFwINQuEc+TDjuNcEqt+0J5EgS1fwzxb2RCVL0TNv4
|
||||
9a71hFGCNRj20AeZm99hbdufm7+0AFO7ocV5q43rLrWFUoBzqKPYIjga/cv/UdWZ
|
||||
c5RLRXw3JDSrCqkf/mOlaEhNPlmWRF9MSus5Da3wuwgGCaVzmrf30rWR5aHHcscG
|
||||
e+AOgJ4HayvBUQeb6ZlRXc0YlACiLToMKxuyxDyUcDfVEXpUIsDILF8dkiVQxEU3
|
||||
j9g6qjXiqPVdNiwpqXfBKObj8vNCzORnoHYs8cCgib3RgDVWeqkDmlSwlZE7CvQh
|
||||
U4Loj4l7813xxzYEKkVaT1JdXPWu42CG/b4Y/+f4V+3rkJkYzUwndX6kZNksIBai
|
||||
phmtvKt+CTdP1eAbT+C9AWWF3PT31+BIhuT0u9tR8BVSkXdQB8dG4M/AAJcTo640
|
||||
0mdYYOXT153gEKHJuUBm750ZTy+r6NjNvpw8VrMAakJwHqnIdQIDAQABo2MwYTAd
|
||||
BgNVHQ4EFgQUP3SR9TmlzmXjxMe7QDKP1I2ke6EwHwYDVR0jBBgwFoAUP3SR9Tml
|
||||
zmXjxMe7QDKP1I2ke6EwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw
|
||||
DQYJKoZIhvcNAQELBQADggIBAFMFv4C+I0+xOAb9v6G/IOpfPBZ1ez31EXKJJBra
|
||||
lulP4nRHQMeb310JS8BIeQ3dl+7+PkSxPABZSwc3jkxdSMvhc+Z4MQtTgos+Qsjs
|
||||
gH7sTqwWeeQ0lHYxWmkXijrh5OPRZwTKzYQlkcn85BCUXl2KDuNEdiqPbDTao+lc
|
||||
lA0/UAvC6NCyFKq/jqf4CmW5Kx6yG1v1LaE+IXn7cbIXj+DaehocVXi0wsXqj03Q
|
||||
DDUHuLHZP+LBsg4e91/0Jy2ekNRTYJifSqr+9ufHl0ZX1pFDZyf396IgZ5CQZ0PJ
|
||||
nRxZHlCfsxWxmxxdy3FQSE6YwXhdTjjoAa1ApZcKkkt1beJa6/oRLze/ux5x+5q+
|
||||
4QczufHd6rjoKBi6BM3FgFQ8As5iNohHXlMHd/xITo1Go3CWw2j9TGH5vzksOElK
|
||||
B0mcwwt2zwNEjvfytc+tI5jcfGN3tiT5fVHS8hw9dWKevypLL+55Ua9G8ZgDHasT
|
||||
XFRJHgmnbyFcaAe26D2dSKmhC9u2mHBH+MaI8dj3e7wNBfpxNgp41aFIk+QTmiFW
|
||||
VXFED6DHQ/Mxq93ACalHdYg18PlIYClbT6Pf2xXBnn33YPhn5xzoTZ+cDH/RpaQp
|
||||
s0UUTSJT1UTXgtXPnZWQfvKlMjJEIiVFiLEC0sgZRlWuZDRAY0CdZJJxvQp59lqu
|
||||
cbTm
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -2,31 +2,31 @@
|
|||
MIIFnDCCA4SgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCU0Ux
|
||||
EjAQBgNVBAgMCVN0b2NraG9sbTESMBAGA1UECgwJTXlPcmdOYW1lMRkwFwYDVQQL
|
||||
DBBNeUludGVybWVkaWF0ZUNBMRkwFwYDVQQDDBBNeUludGVybWVkaWF0ZUNBMB4X
|
||||
DTIyMDYxMzEyNDIwNVoXDTIzMDYyMzEyNDIwNVowfTELMAkGA1UEBhMCU0UxEjAQ
|
||||
DTIzMDExMjEzMDgxNloXDTMzMDQxOTEzMDgxNlowfTELMAkGA1UEBhMCU0UxEjAQ
|
||||
BgNVBAgMCVN0b2NraG9sbTESMBAGA1UEBwwJU3RvY2tob2xtMRIwEAYDVQQKDAlN
|
||||
eU9yZ05hbWUxGTAXBgNVBAsMEE15SW50ZXJtZWRpYXRlQ0ExFzAVBgNVBAMMDmNs
|
||||
aWVudC1yZXZva2VkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA584w
|
||||
VAczDWrlIJXm6+0oYepacPPrVEMC9WwsQFO5GbBDdxrBvxgQ5u8/DDNEtYk0sJMt
|
||||
zgSLxsYK5duhrwVyICXpKgxMI2fKdKP0zxB/eB4V0vrc6FqR4L8D8XoNPKSaTnjv
|
||||
NNh3wjLNvmBRfHRSUCe4zEvPZzMLuBIHXRR20prtA90FFV8fliNvMCBIbFkqthjf
|
||||
fQ/tSXXxNQNjacuHVfY+LVN3xu9Jjll4AaCKKz19rDexq9HTLLZ8y4jBD1eRobp+
|
||||
spKKu4HNpon+YMp3vJuNmxsTU+xBkbESWGJTFot7lZL1PVBvxdgbSd3OrPKI+QbK
|
||||
06FN3iBrcW3Yjp04LQIDAQABo4IBNjCCATIwCQYDVR0TBAIwADARBglghkgBhvhC
|
||||
aWVudC1yZXZva2VkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs+R6
|
||||
PDtIxVlUoLYbDBbaVcxgoLjnWcvqL8wSqyWuqi/Y3cjuNYCziR9nR5dWajtkBjzJ
|
||||
HyhgAr6gBVSRt4RRmDXoOcprK3GcpowAr65UAmC4hdH0af6FdKjKCnFw67byUg52
|
||||
f7ueXZ6t/XuuKxlU/f2rjXVwmmnlhBi5EHDkXxvfgWXJekDfsPbW9j0kaCUWCpfj
|
||||
rzGbfkXqrPkslO41PYlCbPxoiRItJjindFjcQySYvRq7A2uYMGsrxv4n3rzo5NGt
|
||||
goBmnGj61ii9WOdopcFxKirhIB9zrxC4x0opRfIaF/n1ZXk6NOnaDxu1LTZ18wfC
|
||||
ZB979ge6pleeKoPf7QIDAQABo4IBNjCCATIwCQYDVR0TBAIwADARBglghkgBhvhC
|
||||
AQEEBAMCBaAwMwYJYIZIAYb4QgENBCYWJE9wZW5TU0wgR2VuZXJhdGVkIENsaWVu
|
||||
dCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUSq+9djRFuryFk0Mdqlsy0chljWswHwYD
|
||||
VR0jBBgwFoAUK6/VOTMLV9KBN/MTWbW7mlEImxUwDgYDVR0PAQH/BAQDAgXgMB0G
|
||||
dCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUQeItXr3nc6CZ++G9UCoq1YlQ9oowHwYD
|
||||
VR0jBBgwFoAUTHCGOxVSibq1D5KqrrExQRO+c/MwDgYDVR0PAQH/BAQDAgXgMB0G
|
||||
A1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDA7BgNVHR8ENDAyMDCgLqAshipo
|
||||
dHRwOi8vbG9jYWxob3N0Ojk4NzgvaW50ZXJtZWRpYXRlLmNybC5wZW0wMQYIKwYB
|
||||
BQUHAQEEJTAjMCEGCCsGAQUFBzABhhVodHRwOi8vbG9jYWxob3N0Ojk4NzcwDQYJ
|
||||
KoZIhvcNAQELBQADggIBAD4XyEjAfU0VE+YRQXUxlqpeJdMij0Io9ZCf1j6JMNFl
|
||||
/p8vbOm6orK55bYWXCzRaIEkgOGlpQLDIXpViAjmBbXisA97hS1v6rW10W6LyNkN
|
||||
i7LC6kTgBi4yIV3FiQk5CIE3Tj22+0GjaepHc2bPGaLSRBaoe8uBvDlDqRjxW64H
|
||||
KYOIyux3WqauEziNEVklXG3VNX+6WfUw0jP9p4cglLaL43htwdavA1g7RP0wE1/6
|
||||
hvZ242jK4bvCGn/p7IDa8YtgXTufjQf6hJB9kRAJRqrSJQnihb6P9UZr2saaR7mp
|
||||
28w7a6L1RLSkCSpcwRoTHgTMkFwCD/h7NxZmpoOCBk4vrHY7SXG05ptb6o7x8TD7
|
||||
lRV/+ay8EIPWCKGpTrGWHGzjxiuXw4TqnfETlvz0rFUG4TapXwmWnaSwTUk5d10v
|
||||
olBQJ22CIidkKvoW/6bmD6mtyRX/F3KDTN7vHSsjvaty+TzqjWLLd2rjWpZi5xcc
|
||||
h/lOyWHXbFkakRT879USUvqU/Y6+2CpbZ2ssks4+bnD8Dsdq1fFLTXtLhBBFcz11
|
||||
amuwx923tJTY9f6e7y3X/TveCKcibo+aluA4ACkYix8mR/oFxmsulW6MTVcqZZ+i
|
||||
9+oo9hyOPQsJhWYISAtLBuDCqz9fKM4llmnuQZA55FuZBkSmHBRAXw5xwA+gbZcs
|
||||
KoZIhvcNAQELBQADggIBAIFuhokODd54/1B2JiNyG6FMq/2z8B+UquC2iw3p2pyM
|
||||
g/Jz4Ouvg6gGwUwmykEua06FRCxx5vJ5ahdhXvKst/zH/0qmYTFNMhNsDy76J/Ot
|
||||
Ss+VwQ8ddpEG3EIUI9BQxB3xL7z7kRQzploQjakNcDWtDt1BmN05Iy2vz4lnYJky
|
||||
Kss6ya9jEkNibHekhxJuchJ0fVGlVe74MO7RNDFG7+O3tMlxu0zH/LpW093V7BI2
|
||||
snXNAwQBizvWTrDKWLDu5JsX8KKkrmDtFTs9gegnxDCOYdtG5GbbMq+H1SjWUJPV
|
||||
wiXTF8/eE02s4Jzm7ZAxre4bRt/hAg7xTGmDQ1Hn+LzLn18I9LaW5ZWqSwwpgv+g
|
||||
Z/jiLO9DJ/y525Cl7DLCpSFoDTWlQXouKhcgALcVay/cXCsZ3oFZCustburLiJi/
|
||||
zgBeEk1gVpwljriJLeZifyfWtJx6yfgB/h6fid8XLsGRD+Yc8Tzs8J1LIgi+j4ZT
|
||||
UzKX3B85Kht/dr43UDMtWOF3edkOMaJu7rcg5tTsK+LIyHtXvebKPVvvA9f27Dz/
|
||||
4gmhAwwqS87Xv3FMVhZ03DNOJ6XAF+T6OTEqwYs+iK56IMSl1Jy+bCzo0j5jZVbl
|
||||
XFwGxUHzM7pfM6PDx657oUxG1QwM/fIWA18F+kY/yigXxq6pYMeAiQsPanOThgHp
|
||||
-----END CERTIFICATE-----
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue