feat(conf): merge all conf to emqx.conf
This commit is contained in:
parent
fb2f2741a4
commit
918a26e921
|
@ -39,7 +39,7 @@ emqx_test(){
|
||||||
unzip -q "${PACKAGE_PATH}/${packagename}"
|
unzip -q "${PACKAGE_PATH}/${packagename}"
|
||||||
export EMQX_ZONE__EXTERNAL__SERVER_KEEPALIVE=60 \
|
export EMQX_ZONE__EXTERNAL__SERVER_KEEPALIVE=60 \
|
||||||
EMQX_MQTT__MAX_TOPIC_ALIAS=10
|
EMQX_MQTT__MAX_TOPIC_ALIAS=10
|
||||||
sed -i '/emqx_telemetry/d' "${PACKAGE_PATH}"/emqx/data/loaded_plugins
|
# sed -i '/emqx_telemetry/d' "${PACKAGE_PATH}"/emqx/data/loaded_plugins
|
||||||
|
|
||||||
echo "running ${packagename} start"
|
echo "running ${packagename} start"
|
||||||
if ! "${PACKAGE_PATH}"/emqx/bin/emqx start; then
|
if ! "${PACKAGE_PATH}"/emqx/bin/emqx start; then
|
||||||
|
@ -115,7 +115,7 @@ emqx_test(){
|
||||||
running_test(){
|
running_test(){
|
||||||
export EMQX_ZONE__EXTERNAL__SERVER_KEEPALIVE=60 \
|
export EMQX_ZONE__EXTERNAL__SERVER_KEEPALIVE=60 \
|
||||||
EMQX_MQTT__MAX_TOPIC_ALIAS=10
|
EMQX_MQTT__MAX_TOPIC_ALIAS=10
|
||||||
sed -i '/emqx_telemetry/d' /var/lib/emqx/loaded_plugins
|
# sed -i '/emqx_telemetry/d' /var/lib/emqx/loaded_plugins
|
||||||
|
|
||||||
if ! emqx start; then
|
if ! emqx start; then
|
||||||
cat /var/log/emqx/erlang.log.1 || true
|
cat /var/log/emqx/erlang.log.1 || true
|
||||||
|
|
|
@ -38,7 +38,7 @@ services:
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
sed -i "s 127.0.0.1 $$(ip route show |grep "link" |awk '{print $$1}') g" /opt/emqx/etc/acl.conf
|
sed -i "s 127.0.0.1 $$(ip route show |grep "link" |awk '{print $$1}') g" /opt/emqx/etc/acl.conf
|
||||||
sed -i '/emqx_telemetry/d' /opt/emqx/data/loaded_plugins
|
# sed -i '/emqx_telemetry/d' /opt/emqx/data/loaded_plugins
|
||||||
/opt/emqx/bin/emqx foreground
|
/opt/emqx/bin/emqx foreground
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "/opt/emqx/bin/emqx_ctl", "status"]
|
test: ["CMD", "/opt/emqx/bin/emqx_ctl", "status"]
|
||||||
|
@ -62,7 +62,7 @@ services:
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
sed -i "s 127.0.0.1 $$(ip route show |grep "link" |awk '{print $$1}') g" /opt/emqx/etc/acl.conf
|
sed -i "s 127.0.0.1 $$(ip route show |grep "link" |awk '{print $$1}') g" /opt/emqx/etc/acl.conf
|
||||||
sed -i '/emqx_telemetry/d' /opt/emqx/data/loaded_plugins
|
# sed -i '/emqx_telemetry/d' /opt/emqx/data/loaded_plugins
|
||||||
/opt/emqx/bin/emqx foreground
|
/opt/emqx/bin/emqx foreground
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "/opt/emqx/bin/emqx", "ping"]
|
test: ["CMD", "/opt/emqx/bin/emqx", "ping"]
|
||||||
|
|
|
@ -179,7 +179,7 @@ jobs:
|
||||||
cd source
|
cd source
|
||||||
pkg_name=$(basename _packages/${{ matrix.profile }}/${{ matrix.profile }}-*.zip)
|
pkg_name=$(basename _packages/${{ matrix.profile }}/${{ matrix.profile }}-*.zip)
|
||||||
unzip -q _packages/${{ matrix.profile }}/$pkg_name
|
unzip -q _packages/${{ matrix.profile }}/$pkg_name
|
||||||
gsed -i '/emqx_telemetry/d' ./emqx/data/loaded_plugins
|
# gsed -i '/emqx_telemetry/d' ./emqx/data/loaded_plugins
|
||||||
./emqx/bin/emqx start || cat emqx/log/erlang.log.1
|
./emqx/bin/emqx start || cat emqx/log/erlang.log.1
|
||||||
ready='no'
|
ready='no'
|
||||||
for i in {1..10}; do
|
for i in {1..10}; do
|
||||||
|
|
|
@ -108,7 +108,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
pkg_name=$(basename _packages/${EMQX_NAME}/emqx-*.zip)
|
pkg_name=$(basename _packages/${EMQX_NAME}/emqx-*.zip)
|
||||||
unzip -q _packages/${EMQX_NAME}/$pkg_name
|
unzip -q _packages/${EMQX_NAME}/$pkg_name
|
||||||
gsed -i '/emqx_telemetry/d' ./emqx/data/loaded_plugins
|
# gsed -i '/emqx_telemetry/d' ./emqx/data/loaded_plugins
|
||||||
./emqx/bin/emqx start || cat emqx/log/erlang.log.1
|
./emqx/bin/emqx start || cat emqx/log/erlang.log.1
|
||||||
ready='no'
|
ready='no'
|
||||||
for i in {1..10}; do
|
for i in {1..10}; do
|
||||||
|
|
|
@ -48,13 +48,13 @@ jobs:
|
||||||
echo "['$(date -u +"%Y-%m-%dT%H:%M:%SZ")']:waiting emqx";
|
echo "['$(date -u +"%Y-%m-%dT%H:%M:%SZ")']:waiting emqx";
|
||||||
sleep 5;
|
sleep 5;
|
||||||
done
|
done
|
||||||
- name: verify EMQX_LOADED_PLUGINS override working
|
# - name: verify EMQX_LOADED_PLUGINS override working
|
||||||
run: |
|
# run: |
|
||||||
expected="{emqx_sn, true}."
|
# expected="{emqx_sn, true}."
|
||||||
output=$(docker exec -i node1.emqx.io bash -c "cat data/loaded_plugins" | tail -n1)
|
# output=$(docker exec -i node1.emqx.io bash -c "cat data/loaded_plugins" | tail -n1)
|
||||||
if [ "$expected" != "$output" ]; then
|
# if [ "$expected" != "$output" ]; then
|
||||||
exit 1
|
# exit 1
|
||||||
fi
|
# fi
|
||||||
- name: make paho tests
|
- name: make paho tests
|
||||||
run: |
|
run: |
|
||||||
if ! docker exec -i python /scripts/pytest.sh; then
|
if ! docker exec -i python /scripts/pytest.sh; then
|
||||||
|
|
|
@ -45,6 +45,6 @@ emqx_dialyzer_*_plt
|
||||||
*/emqx_dashboard/priv/www
|
*/emqx_dashboard/priv/www
|
||||||
dist.zip
|
dist.zip
|
||||||
scripts/git-token
|
scripts/git-token
|
||||||
etc/*.seg
|
apps/*/etc/*.all
|
||||||
_upgrade_base/
|
_upgrade_base/
|
||||||
TAGS
|
TAGS
|
||||||
|
|
8
Makefile
8
Makefile
|
@ -73,7 +73,8 @@ coveralls: $(REBAR)
|
||||||
@ENABLE_COVER_COMPILE=1 $(REBAR) as test coveralls send
|
@ENABLE_COVER_COMPILE=1 $(REBAR) as test coveralls send
|
||||||
|
|
||||||
.PHONY: $(REL_PROFILES)
|
.PHONY: $(REL_PROFILES)
|
||||||
$(REL_PROFILES:%=%): $(REBAR) get-dashboard
|
|
||||||
|
$(REL_PROFILES:%=%): $(REBAR) get-dashboard conf-segs
|
||||||
@$(REBAR) as $(@) do compile,release
|
@$(REBAR) as $(@) do compile,release
|
||||||
|
|
||||||
## Not calling rebar3 clean because
|
## Not calling rebar3 clean because
|
||||||
|
@ -111,7 +112,7 @@ xref: $(REBAR)
|
||||||
dialyzer: $(REBAR)
|
dialyzer: $(REBAR)
|
||||||
@$(REBAR) as check dialyzer
|
@$(REBAR) as check dialyzer
|
||||||
|
|
||||||
COMMON_DEPS := $(REBAR) get-dashboard $(CONF_SEGS)
|
COMMON_DEPS := $(REBAR) get-dashboard conf-segs
|
||||||
|
|
||||||
## rel target is to create release package without relup
|
## rel target is to create release package without relup
|
||||||
.PHONY: $(REL_PROFILES:%=%-rel) $(PKG_PROFILES:%=%-rel)
|
.PHONY: $(REL_PROFILES:%=%-rel) $(PKG_PROFILES:%=%-rel)
|
||||||
|
@ -152,3 +153,6 @@ quickrun:
|
||||||
./_build/$(PROFILE)/rel/emqx/bin/emqx console
|
./_build/$(PROFILE)/rel/emqx/bin/emqx console
|
||||||
|
|
||||||
include docker.mk
|
include docker.mk
|
||||||
|
|
||||||
|
conf-segs:
|
||||||
|
@scripts/merge-config.escript
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
%% [ACL](https://docs.emqx.io/broker/v3/en/config.html)
|
|
||||||
%%
|
|
||||||
%% -type(who() :: all | binary() |
|
|
||||||
%% {ipaddr, esockd_access:cidr()} |
|
|
||||||
%% {client, binary()} |
|
|
||||||
%% {user, binary()}).
|
|
||||||
%%
|
|
||||||
%% -type(access() :: subscribe | publish | pubsub).
|
|
||||||
%%
|
|
||||||
%% -type(topic() :: binary()).
|
|
||||||
%%
|
|
||||||
%% -type(rule() :: {allow, all} |
|
|
||||||
%% {allow, who(), access(), list(topic())} |
|
|
||||||
%% {deny, all} |
|
|
||||||
%% {deny, who(), access(), list(topic())}).
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
|
|
||||||
{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.
|
|
||||||
|
|
||||||
{allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
|
|
||||||
|
|
||||||
{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.
|
|
||||||
|
|
||||||
{allow, all}.
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
%% For paho interoperability test cases
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
|
|
||||||
{deny, {client, "myclientid"}, subscribe, ["test/nosubscribe"]}.
|
|
||||||
|
|
||||||
{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.
|
|
||||||
|
|
||||||
{allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.
|
|
||||||
|
|
||||||
{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.
|
|
||||||
|
|
||||||
{allow, all}.
|
|
||||||
|
|
|
@ -108,8 +108,7 @@
|
||||||
descr :: string(),
|
descr :: string(),
|
||||||
vendor :: string() | undefined,
|
vendor :: string() | undefined,
|
||||||
active = false :: boolean(),
|
active = false :: boolean(),
|
||||||
info = #{} :: map(),
|
info = #{} :: map()
|
||||||
type :: atom()
|
|
||||||
}).
|
}).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -1,111 +0,0 @@
|
||||||
%% -*- mode: erlang -*-
|
|
||||||
{VSN,
|
|
||||||
[
|
|
||||||
{"4.3.4",
|
|
||||||
[{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]}
|
|
||||||
]},
|
|
||||||
{"4.3.3",
|
|
||||||
[{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]}
|
|
||||||
]},
|
|
||||||
{"4.3.2",
|
|
||||||
[{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_http_lib,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_channel,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]}
|
|
||||||
]},
|
|
||||||
{"4.3.1",
|
|
||||||
[{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_congestion,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_node_dump,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_channel,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_http_lib,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.3.0",
|
|
||||||
[{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_logger_jsonfmt,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_congestion,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_trie,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_node_dump,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_channel,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_metrics,brutal_purge,soft_purge,[]},
|
|
||||||
{apply,{emqx_metrics,upgrade_retained_delayed_counter_type,[]}},
|
|
||||||
{load_module,emqx_http_lib,brutal_purge,soft_purge,[]}]},
|
|
||||||
{<<".*">>,[]}],
|
|
||||||
[
|
|
||||||
{"4.3.4",
|
|
||||||
[{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]}
|
|
||||||
]},
|
|
||||||
{"4.3.3",
|
|
||||||
[{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]}
|
|
||||||
]},
|
|
||||||
{"4.3.2",
|
|
||||||
[{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_http_lib,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_channel,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]}
|
|
||||||
]},
|
|
||||||
{"4.3.1",
|
|
||||||
[{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_congestion,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_node_dump,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_channel,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_http_lib,brutal_purge,soft_purge,[]}]},
|
|
||||||
{"4.3.0",
|
|
||||||
[{load_module,emqx_packet,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_shared_sub,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_logger_jsonfmt,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_ws_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_connection,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_congestion,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_frame,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_trie,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_cm,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_node_dump,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_channel,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_logger_textfmt,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_metrics,brutal_purge,soft_purge,[]},
|
|
||||||
{load_module,emqx_http_lib,brutal_purge,soft_purge,[]}]},
|
|
||||||
{<<".*">>,[]}]}.
|
|
|
@ -227,7 +227,6 @@ shutdown() ->
|
||||||
shutdown(Reason) ->
|
shutdown(Reason) ->
|
||||||
?LOG(critical, "emqx shutdown for ~s", [Reason]),
|
?LOG(critical, "emqx shutdown for ~s", [Reason]),
|
||||||
_ = emqx_alarm_handler:unload(),
|
_ = emqx_alarm_handler:unload(),
|
||||||
_ = emqx_plugins:unload(),
|
|
||||||
lists:foreach(fun application:stop/1
|
lists:foreach(fun application:stop/1
|
||||||
, lists:reverse(default_started_applications())
|
, lists:reverse(default_started_applications())
|
||||||
).
|
).
|
||||||
|
|
|
@ -51,7 +51,7 @@ start(_Type, _Args) ->
|
||||||
ok = ekka_rlog:wait_for_shards(?EMQX_SHARDS, infinity),
|
ok = ekka_rlog:wait_for_shards(?EMQX_SHARDS, infinity),
|
||||||
{ok, Sup} = emqx_sup:start_link(),
|
{ok, Sup} = emqx_sup:start_link(),
|
||||||
ok = start_autocluster(),
|
ok = start_autocluster(),
|
||||||
ok = emqx_plugins:init(),
|
% ok = emqx_plugins:init(),
|
||||||
_ = emqx_plugins:load(),
|
_ = emqx_plugins:load(),
|
||||||
_ = start_ce_modules(),
|
_ = start_ce_modules(),
|
||||||
emqx_boot:is_enabled(listeners) andalso (ok = emqx_listeners:start()),
|
emqx_boot:is_enabled(listeners) andalso (ok = emqx_listeners:start()),
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
|
|
||||||
-logger_header("[Plugins]").
|
-logger_header("[Plugins]").
|
||||||
|
|
||||||
-export([init/0]).
|
|
||||||
|
|
||||||
-export([ load/0
|
-export([ load/0
|
||||||
, load/1
|
, load/1
|
||||||
, unload/0
|
, unload/0
|
||||||
|
@ -30,8 +28,6 @@
|
||||||
, reload/1
|
, reload/1
|
||||||
, list/0
|
, list/0
|
||||||
, find_plugin/1
|
, find_plugin/1
|
||||||
, generate_configs/1
|
|
||||||
, apply_configs/1
|
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-export([funlog/2]).
|
-export([funlog/2]).
|
||||||
|
@ -41,35 +37,14 @@
|
||||||
-compile(nowarn_export_all).
|
-compile(nowarn_export_all).
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
-dialyzer({no_match, [ plugin_loaded/2
|
|
||||||
, plugin_unloaded/2
|
|
||||||
]}).
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% APIs
|
%% APIs
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
%% @doc Init plugins' config
|
|
||||||
-spec(init() -> ok).
|
|
||||||
init() ->
|
|
||||||
case emqx:get_env(plugins_etc_dir) of
|
|
||||||
undefined -> ok;
|
|
||||||
PluginsEtc ->
|
|
||||||
CfgFiles = [filename:join(PluginsEtc, File) ||
|
|
||||||
File <- filelib:wildcard("*.config", PluginsEtc)],
|
|
||||||
lists:foreach(fun init_config/1, CfgFiles)
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% @doc Load all plugins when the broker started.
|
%% @doc Load all plugins when the broker started.
|
||||||
-spec(load() -> ok | ignore | {error, term()}).
|
-spec(load() -> ok | ignore | {error, term()}).
|
||||||
load() ->
|
load() ->
|
||||||
ok = load_ext_plugins(emqx:get_env(expand_plugins_dir)),
|
ok = load_ext_plugins(emqx:get_env(expand_plugins_dir)).
|
||||||
case emqx:get_env(plugins_loaded_file) of
|
|
||||||
undefined -> ignore; %% No plugins available
|
|
||||||
File ->
|
|
||||||
_ = ensure_file(File),
|
|
||||||
with_loaded_file(File, fun(Names) -> load_plugins(Names, false) end)
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% @doc Load a Plugin
|
%% @doc Load a Plugin
|
||||||
-spec(load(atom()) -> ok | {error, term()}).
|
-spec(load(atom()) -> ok | {error, term()}).
|
||||||
|
@ -82,17 +57,13 @@ load(PluginName) when is_atom(PluginName) ->
|
||||||
?LOG(notice, "Plugin ~s is already started", [PluginName]),
|
?LOG(notice, "Plugin ~s is already started", [PluginName]),
|
||||||
{error, already_started};
|
{error, already_started};
|
||||||
{_, false} ->
|
{_, false} ->
|
||||||
load_plugin(PluginName, true)
|
load_plugin(PluginName)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @doc Unload all plugins before broker stopped.
|
%% @doc Unload all plugins before broker stopped.
|
||||||
-spec(unload() -> list() | {error, term()}).
|
-spec(unload() -> ok).
|
||||||
unload() ->
|
unload() ->
|
||||||
case emqx:get_env(plugins_loaded_file) of
|
stop_plugins(list()).
|
||||||
undefined -> ignore;
|
|
||||||
File ->
|
|
||||||
with_loaded_file(File, fun stop_plugins/1)
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% @doc UnLoad a Plugin
|
%% @doc UnLoad a Plugin
|
||||||
-spec(unload(atom()) -> ok | {error, term()}).
|
-spec(unload(atom()) -> ok | {error, term()}).
|
||||||
|
@ -105,7 +76,7 @@ unload(PluginName) when is_atom(PluginName) ->
|
||||||
?LOG(error, "Plugin ~s is not started", [PluginName]),
|
?LOG(error, "Plugin ~s is not started", [PluginName]),
|
||||||
{error, not_started};
|
{error, not_started};
|
||||||
{_, _} ->
|
{_, _} ->
|
||||||
unload_plugin(PluginName, true)
|
unload_plugin(PluginName)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
reload(PluginName) when is_atom(PluginName)->
|
reload(PluginName) when is_atom(PluginName)->
|
||||||
|
@ -126,8 +97,8 @@ reload(PluginName) when is_atom(PluginName)->
|
||||||
-spec(list() -> [emqx_types:plugin()]).
|
-spec(list() -> [emqx_types:plugin()]).
|
||||||
list() ->
|
list() ->
|
||||||
StartedApps = names(started_app),
|
StartedApps = names(started_app),
|
||||||
lists:map(fun({Name, _, [Type| _]}) ->
|
lists:map(fun({Name, _, _}) ->
|
||||||
Plugin = plugin(Name, Type),
|
Plugin = plugin(Name),
|
||||||
case lists:member(Name, StartedApps) of
|
case lists:member(Name, StartedApps) of
|
||||||
true -> Plugin#plugin{active = true};
|
true -> Plugin#plugin{active = true};
|
||||||
false -> Plugin
|
false -> Plugin
|
||||||
|
@ -144,12 +115,6 @@ find_plugin(Name, Plugins) ->
|
||||||
%% Internal functions
|
%% Internal functions
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
init_config(CfgFile) ->
|
|
||||||
{ok, [AppsEnv]} = file:consult(CfgFile),
|
|
||||||
lists:foreach(fun({App, Envs}) ->
|
|
||||||
[application:set_env(App, Par, Val) || {Par, Val} <- Envs]
|
|
||||||
end, AppsEnv).
|
|
||||||
|
|
||||||
%% load external plugins which are placed in etc/plugins dir
|
%% load external plugins which are placed in etc/plugins dir
|
||||||
load_ext_plugins(undefined) -> ok;
|
load_ext_plugins(undefined) -> ok;
|
||||||
load_ext_plugins(Dir) ->
|
load_ext_plugins(Dir) ->
|
||||||
|
@ -173,15 +138,15 @@ load_ext_plugin(PluginDir) ->
|
||||||
?LOG(alert, "plugin_app_file_not_found: ~s", [AppFile]),
|
?LOG(alert, "plugin_app_file_not_found: ~s", [AppFile]),
|
||||||
error({plugin_app_file_not_found, AppFile})
|
error({plugin_app_file_not_found, AppFile})
|
||||||
end,
|
end,
|
||||||
ok = load_plugin_app(AppName, Ebin),
|
ok = load_plugin_app(AppName, Ebin).
|
||||||
try
|
% try
|
||||||
ok = generate_configs(AppName, PluginDir)
|
% ok = generate_configs(AppName, PluginDir)
|
||||||
catch
|
% catch
|
||||||
throw : {conf_file_not_found, ConfFile} ->
|
% throw : {conf_file_not_found, ConfFile} ->
|
||||||
%% this is maybe a dependency of an external plugin
|
% %% this is maybe a dependency of an external plugin
|
||||||
?LOG(debug, "config_load_error_ignored for app=~p, path=~s", [AppName, ConfFile]),
|
% ?LOG(debug, "config_load_error_ignored for app=~p, path=~s", [AppName, ConfFile]),
|
||||||
ok
|
% ok
|
||||||
end.
|
% end.
|
||||||
|
|
||||||
load_plugin_app(AppName, Ebin) ->
|
load_plugin_app(AppName, Ebin) ->
|
||||||
_ = code:add_patha(Ebin),
|
_ = code:add_patha(Ebin),
|
||||||
|
@ -199,57 +164,24 @@ load_plugin_app(AppName, Ebin) ->
|
||||||
{error, {already_loaded, _}} -> ok
|
{error, {already_loaded, _}} -> ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
ensure_file(File) ->
|
|
||||||
case filelib:is_file(File) of false -> write_loaded([]); true -> ok end.
|
|
||||||
|
|
||||||
with_loaded_file(File, SuccFun) ->
|
|
||||||
case read_loaded(File) of
|
|
||||||
{ok, Names0} ->
|
|
||||||
Names = filter_plugins(Names0),
|
|
||||||
SuccFun(Names);
|
|
||||||
{error, Error} ->
|
|
||||||
?LOG(alert, "Failed to read: ~p, error: ~p", [File, Error]),
|
|
||||||
{error, Error}
|
|
||||||
end.
|
|
||||||
|
|
||||||
filter_plugins(Names) ->
|
|
||||||
lists:filtermap(fun(Name1) when is_atom(Name1) -> {true, Name1};
|
|
||||||
({Name1, true}) -> {true, Name1};
|
|
||||||
({_Name1, false}) -> false
|
|
||||||
end, Names).
|
|
||||||
|
|
||||||
load_plugins(Names, Persistent) ->
|
|
||||||
Plugins = list(),
|
|
||||||
NotFound = Names -- names(Plugins),
|
|
||||||
case NotFound of
|
|
||||||
[] -> ok;
|
|
||||||
NotFound -> ?LOG(alert, "cannot_find_plugins: ~p", [NotFound])
|
|
||||||
end,
|
|
||||||
NeedToLoad = Names -- NotFound -- names(started_app),
|
|
||||||
lists:foreach(fun(Name) ->
|
|
||||||
Plugin = find_plugin(Name, Plugins),
|
|
||||||
load_plugin(Plugin#plugin.name, Persistent)
|
|
||||||
end, NeedToLoad).
|
|
||||||
|
|
||||||
%% Stop plugins
|
%% Stop plugins
|
||||||
stop_plugins(Names) ->
|
stop_plugins(Plugins) ->
|
||||||
_ = [stop_app(App) || App <- Names],
|
_ = [stop_app(Plugin#plugin.name) || Plugin <- Plugins],
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
plugin(AppName, Type) ->
|
plugin(AppName) ->
|
||||||
case application:get_all_key(AppName) of
|
case application:get_all_key(AppName) of
|
||||||
{ok, Attrs} ->
|
{ok, Attrs} ->
|
||||||
Descr = proplists:get_value(description, Attrs, ""),
|
Descr = proplists:get_value(description, Attrs, ""),
|
||||||
#plugin{name = AppName, descr = Descr, type = plugin_type(Type)};
|
#plugin{name = AppName, descr = Descr};
|
||||||
undefined -> error({plugin_not_found, AppName})
|
undefined -> error({plugin_not_found, AppName})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
load_plugin(Name, Persistent) ->
|
load_plugin(Name) ->
|
||||||
try
|
try
|
||||||
ok = ?MODULE:generate_configs(Name),
|
|
||||||
case load_app(Name) of
|
case load_app(Name) of
|
||||||
ok ->
|
ok ->
|
||||||
start_app(Name, fun(App) -> plugin_loaded(App, Persistent) end);
|
start_app(Name);
|
||||||
{error, Error0} ->
|
{error, Error0} ->
|
||||||
{error, Error0}
|
{error, Error0}
|
||||||
end
|
end
|
||||||
|
@ -268,22 +200,21 @@ load_app(App) ->
|
||||||
{error, Error}
|
{error, Error}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
start_app(App, SuccFun) ->
|
start_app(App) ->
|
||||||
case application:ensure_all_started(App) of
|
case application:ensure_all_started(App) of
|
||||||
{ok, Started} ->
|
{ok, Started} ->
|
||||||
?LOG(info, "Started plugins: ~p", [Started]),
|
?LOG(info, "Started plugins: ~p", [Started]),
|
||||||
?LOG(info, "Load plugin ~s successfully", [App]),
|
?LOG(info, "Load plugin ~s successfully", [App]),
|
||||||
_ = SuccFun(App),
|
|
||||||
ok;
|
ok;
|
||||||
{error, {ErrApp, Reason}} ->
|
{error, {ErrApp, Reason}} ->
|
||||||
?LOG(error, "Load plugin ~s failed, cannot start plugin ~s for ~0p", [App, ErrApp, Reason]),
|
?LOG(error, "Load plugin ~s failed, cannot start plugin ~s for ~0p", [App, ErrApp, Reason]),
|
||||||
{error, {ErrApp, Reason}}
|
{error, {ErrApp, Reason}}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
unload_plugin(App, Persistent) ->
|
unload_plugin(App) ->
|
||||||
case stop_app(App) of
|
case stop_app(App) of
|
||||||
ok ->
|
ok ->
|
||||||
_ = plugin_unloaded(App, Persistent), ok;
|
ok;
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
{error, Reason}
|
{error, Reason}
|
||||||
end.
|
end.
|
||||||
|
@ -307,133 +238,5 @@ names(started_app) ->
|
||||||
names(Plugins) ->
|
names(Plugins) ->
|
||||||
[Name || #plugin{name = Name} <- Plugins].
|
[Name || #plugin{name = Name} <- Plugins].
|
||||||
|
|
||||||
plugin_loaded(_Name, false) ->
|
|
||||||
ok;
|
|
||||||
plugin_loaded(Name, true) ->
|
|
||||||
case read_loaded() of
|
|
||||||
{ok, Names} ->
|
|
||||||
case lists:member(Name, Names) of
|
|
||||||
false ->
|
|
||||||
%% write file if plugin is loaded
|
|
||||||
write_loaded(lists:append(Names, [{Name, true}]));
|
|
||||||
true ->
|
|
||||||
ignore
|
|
||||||
end;
|
|
||||||
{error, Error} ->
|
|
||||||
?LOG(error, "Cannot read loaded plugins: ~p", [Error])
|
|
||||||
end.
|
|
||||||
|
|
||||||
plugin_unloaded(_Name, false) ->
|
|
||||||
ok;
|
|
||||||
plugin_unloaded(Name, true) ->
|
|
||||||
case read_loaded() of
|
|
||||||
{ok, Names0} ->
|
|
||||||
Names = filter_plugins(Names0),
|
|
||||||
case lists:member(Name, Names) of
|
|
||||||
true ->
|
|
||||||
write_loaded(lists:delete(Name, Names));
|
|
||||||
false ->
|
|
||||||
?LOG(error, "Cannot find ~s in loaded_file", [Name])
|
|
||||||
end;
|
|
||||||
{error, Error} ->
|
|
||||||
?LOG(error, "Cannot read loaded_plugins: ~p", [Error])
|
|
||||||
end.
|
|
||||||
|
|
||||||
read_loaded() ->
|
|
||||||
case emqx:get_env(plugins_loaded_file) of
|
|
||||||
undefined -> {error, not_found};
|
|
||||||
File -> read_loaded(File)
|
|
||||||
end.
|
|
||||||
|
|
||||||
read_loaded(File) -> file:consult(File).
|
|
||||||
|
|
||||||
write_loaded(AppNames) ->
|
|
||||||
FilePath = emqx:get_env(plugins_loaded_file),
|
|
||||||
case file:write_file(FilePath, [io_lib:format("~p.~n", [Name]) || Name <- AppNames]) of
|
|
||||||
ok -> ok;
|
|
||||||
{error, Error} ->
|
|
||||||
?LOG(error, "Write File ~p Error: ~p", [FilePath, Error]),
|
|
||||||
{error, Error}
|
|
||||||
end.
|
|
||||||
|
|
||||||
plugin_type(auth) -> auth;
|
|
||||||
plugin_type(protocol) -> protocol;
|
|
||||||
plugin_type(backend) -> backend;
|
|
||||||
plugin_type(bridge) -> bridge;
|
|
||||||
plugin_type(_) -> feature.
|
|
||||||
|
|
||||||
|
|
||||||
funlog(Key, Value) ->
|
funlog(Key, Value) ->
|
||||||
?LOG(info, "~s = ~p", [string:join(Key, "."), Value]).
|
?LOG(info, "~s = ~p", [string:join(Key, "."), Value]).
|
||||||
|
|
||||||
generate_configs(App) ->
|
|
||||||
PluginConfDir = emqx:get_env(plugins_etc_dir),
|
|
||||||
PluginSchemaDir = code:priv_dir(App),
|
|
||||||
generate_configs(App, PluginConfDir, PluginSchemaDir).
|
|
||||||
|
|
||||||
generate_configs(App, PluginDir) ->
|
|
||||||
PluginConfDir = filename:join([PluginDir, "etc"]),
|
|
||||||
PluginSchemaDir = filename:join([PluginDir, "priv"]),
|
|
||||||
generate_configs(App, PluginConfDir, PluginSchemaDir).
|
|
||||||
|
|
||||||
generate_configs(App, PluginConfDir, PluginSchemaDir) ->
|
|
||||||
ConfigFile = filename:join([PluginConfDir, App]) ++ ".config",
|
|
||||||
case filelib:is_file(ConfigFile) of
|
|
||||||
true ->
|
|
||||||
{ok, [Configs]} = file:consult(ConfigFile),
|
|
||||||
apply_configs(Configs);
|
|
||||||
false ->
|
|
||||||
SchemaFile = filename:join([PluginSchemaDir, App]) ++ ".schema",
|
|
||||||
case filelib:is_file(SchemaFile) of
|
|
||||||
true ->
|
|
||||||
AppsEnv = do_generate_configs(App),
|
|
||||||
apply_configs(AppsEnv);
|
|
||||||
false ->
|
|
||||||
SchemaMod = lists:concat([App, "_schema"]),
|
|
||||||
ConfName = filename:join([PluginConfDir, App]) ++ ".conf",
|
|
||||||
SchemaFile1 = filename:join([code:lib_dir(App), "ebin", SchemaMod]) ++ ".beam",
|
|
||||||
do_generate_hocon_configs(App, ConfName, SchemaFile1)
|
|
||||||
end
|
|
||||||
end.
|
|
||||||
|
|
||||||
do_generate_configs(App) ->
|
|
||||||
Name1 = filename:join([emqx:get_env(plugins_etc_dir), App]) ++ ".conf",
|
|
||||||
Name2 = filename:join([code:lib_dir(App), "etc", App]) ++ ".conf",
|
|
||||||
ConfFile = case {filelib:is_file(Name1), filelib:is_file(Name2)} of
|
|
||||||
{true, _} -> Name1;
|
|
||||||
{false, true} -> Name2;
|
|
||||||
{false, false} -> error({config_not_found, [Name1, Name2]})
|
|
||||||
end,
|
|
||||||
SchemaFile = filename:join([code:priv_dir(App), App]) ++ ".schema",
|
|
||||||
case filelib:is_file(SchemaFile) of
|
|
||||||
true ->
|
|
||||||
Schema = cuttlefish_schema:files([SchemaFile]),
|
|
||||||
Conf = cuttlefish_conf:file(ConfFile),
|
|
||||||
cuttlefish_generator:map(Schema, Conf, undefined, fun ?MODULE:funlog/2);
|
|
||||||
false ->
|
|
||||||
error({schema_not_found, SchemaFile})
|
|
||||||
end.
|
|
||||||
|
|
||||||
do_generate_hocon_configs(App, ConfName, SchemaFile) ->
|
|
||||||
SchemaMod = lists:concat([App, "_schema"]),
|
|
||||||
case {filelib:is_file(ConfName), filelib:is_file(SchemaFile)} of
|
|
||||||
{true, true} ->
|
|
||||||
{ok, RawConfig} = hocon:load(ConfName, #{format => richmap}),
|
|
||||||
_ = hocon_schema:check(list_to_atom(SchemaMod), RawConfig, #{atom_key => true,
|
|
||||||
return_plain => true}),
|
|
||||||
ok;
|
|
||||||
% emqx_config:update_config([App], Config);
|
|
||||||
{true, false} ->
|
|
||||||
error({schema_not_found, [SchemaFile]});
|
|
||||||
{false, true} ->
|
|
||||||
error({config_not_found, [ConfName]});
|
|
||||||
{false, false} ->
|
|
||||||
error({conf_and_schema_not_found, [ConfName, SchemaFile]})
|
|
||||||
end.
|
|
||||||
|
|
||||||
apply_configs([]) ->
|
|
||||||
ok;
|
|
||||||
apply_configs([{App, Config} | More]) ->
|
|
||||||
lists:foreach(fun({Key, _}) -> application:unset_env(App, Key) end, application:get_all_env(App)),
|
|
||||||
lists:foreach(fun({Key, Val}) -> application:set_env(App, Key, Val) end, Config),
|
|
||||||
apply_configs(More).
|
|
||||||
|
|
|
@ -65,6 +65,12 @@ includes() ->
|
||||||
[ "emqx_data_bridge"
|
[ "emqx_data_bridge"
|
||||||
, "emqx_telemetry"
|
, "emqx_telemetry"
|
||||||
, "emqx_retainer"
|
, "emqx_retainer"
|
||||||
|
, "emqx_statsd"
|
||||||
|
, "emqx_authn"
|
||||||
|
, "emqx_authz"
|
||||||
|
, "emqx_bridge_mqtt"
|
||||||
|
, "emqx_modules"
|
||||||
|
, "emqx_management"
|
||||||
].
|
].
|
||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
|
|
|
@ -63,64 +63,28 @@ t_load(_) ->
|
||||||
?assertEqual({error, not_started}, emqx_plugins:unload(emqx_hocon_plugin)),
|
?assertEqual({error, not_started}, emqx_plugins:unload(emqx_hocon_plugin)),
|
||||||
|
|
||||||
application:set_env(emqx, expand_plugins_dir, undefined),
|
application:set_env(emqx, expand_plugins_dir, undefined),
|
||||||
application:set_env(emqx, plugins_loaded_file, undefined),
|
application:set_env(emqx, plugins_loaded_file, undefined).
|
||||||
?assertEqual(ignore, emqx_plugins:load()),
|
|
||||||
?assertEqual(ignore, emqx_plugins:unload()).
|
|
||||||
|
|
||||||
|
|
||||||
t_init_config(_) ->
|
|
||||||
ConfFile = "emqx_mini_plugin.config",
|
|
||||||
Data = "[{emqx_mini_plugin,[{mininame ,test}]}].",
|
|
||||||
file:write_file(ConfFile, list_to_binary(Data)),
|
|
||||||
?assertEqual(ok, emqx_plugins:init_config(ConfFile)),
|
|
||||||
file:delete(ConfFile),
|
|
||||||
?assertEqual({ok,test}, application:get_env(emqx_mini_plugin, mininame)).
|
|
||||||
|
|
||||||
t_load_ext_plugin(_) ->
|
t_load_ext_plugin(_) ->
|
||||||
?assertError({plugin_app_file_not_found, _},
|
?assertError({plugin_app_file_not_found, _},
|
||||||
emqx_plugins:load_ext_plugin("./not_existed_path/")).
|
emqx_plugins:load_ext_plugin("./not_existed_path/")).
|
||||||
|
|
||||||
t_list(_) ->
|
t_list(_) ->
|
||||||
?assertMatch([{plugin, _, _, _, _, _, _, _} | _ ], emqx_plugins:list()).
|
?assertMatch([{plugin, _, _, _, _, _, _} | _ ], emqx_plugins:list()).
|
||||||
|
|
||||||
t_find_plugin(_) ->
|
t_find_plugin(_) ->
|
||||||
?assertMatch({plugin, emqx_mini_plugin, _, _, _, _, _, _}, emqx_plugins:find_plugin(emqx_mini_plugin)),
|
?assertMatch({plugin, emqx_mini_plugin, _, _, _, _, _}, emqx_plugins:find_plugin(emqx_mini_plugin)),
|
||||||
?assertMatch({plugin, emqx_hocon_plugin, _, _, _, _, _, _}, emqx_plugins:find_plugin(emqx_hocon_plugin)).
|
?assertMatch({plugin, emqx_hocon_plugin, _, _, _, _, _}, emqx_plugins:find_plugin(emqx_hocon_plugin)).
|
||||||
|
|
||||||
t_plugin_type(_) ->
|
|
||||||
?assertEqual(auth, emqx_plugins:plugin_type(auth)),
|
|
||||||
?assertEqual(protocol, emqx_plugins:plugin_type(protocol)),
|
|
||||||
?assertEqual(backend, emqx_plugins:plugin_type(backend)),
|
|
||||||
?assertEqual(bridge, emqx_plugins:plugin_type(bridge)),
|
|
||||||
?assertEqual(feature, emqx_plugins:plugin_type(undefined)).
|
|
||||||
|
|
||||||
t_with_loaded_file(_) ->
|
|
||||||
?assertMatch({error, _}, emqx_plugins:with_loaded_file("./not_existed_path/", fun(_) -> ok end)).
|
|
||||||
|
|
||||||
t_plugin_loaded(_) ->
|
|
||||||
?assertEqual(ok, emqx_plugins:plugin_loaded(emqx_mini_plugin, false)),
|
|
||||||
?assertEqual(ok, emqx_plugins:plugin_loaded(emqx_mini_plugin, true)),
|
|
||||||
?assertEqual(ok, emqx_plugins:plugin_loaded(emqx_hocon_plugin, false)),
|
|
||||||
?assertEqual(ok, emqx_plugins:plugin_loaded(emqx_hocon_plugin, true)).
|
|
||||||
|
|
||||||
t_plugin_unloaded(_) ->
|
|
||||||
?assertEqual(ok, emqx_plugins:plugin_unloaded(emqx_mini_plugin, false)),
|
|
||||||
?assertEqual(ok, emqx_plugins:plugin_unloaded(emqx_mini_plugin, true)),
|
|
||||||
?assertEqual(ok, emqx_plugins:plugin_unloaded(emqx_hocon_plugin, false)),
|
|
||||||
?assertEqual(ok, emqx_plugins:plugin_unloaded(emqx_hocon_plugin, true)).
|
|
||||||
|
|
||||||
t_plugin(_) ->
|
t_plugin(_) ->
|
||||||
try
|
try
|
||||||
emqx_plugins:plugin(not_existed_plugin, undefined)
|
emqx_plugins:plugin(not_existed_plugin)
|
||||||
catch
|
catch
|
||||||
_Error:Reason:_Stacktrace ->
|
_Error:Reason:_Stacktrace ->
|
||||||
?assertEqual({plugin_not_found,not_existed_plugin}, Reason)
|
?assertEqual({plugin_not_found,not_existed_plugin}, Reason)
|
||||||
end,
|
end,
|
||||||
?assertMatch({plugin, emqx_mini_plugin, _, _, _, _, _, _}, emqx_plugins:plugin(emqx_mini_plugin, undefined)),
|
?assertMatch({plugin, emqx_mini_plugin, _, _, _, _, _}, emqx_plugins:plugin(emqx_mini_plugin)),
|
||||||
?assertMatch({plugin, emqx_hocon_plugin, _, _, _, _, _, _}, emqx_plugins:plugin(emqx_hocon_plugin, undefined)).
|
?assertMatch({plugin, emqx_hocon_plugin, _, _, _, _, _}, emqx_plugins:plugin(emqx_hocon_plugin)).
|
||||||
|
|
||||||
t_filter_plugins(_) ->
|
|
||||||
?assertEqual([name1, name2], emqx_plugins:filter_plugins([name1, {name2,true}, {name3, false}])).
|
|
||||||
|
|
||||||
t_load_plugin(_) ->
|
t_load_plugin(_) ->
|
||||||
ok = meck:new(application, [unstick, non_strict, passthrough, no_history]),
|
ok = meck:new(application, [unstick, non_strict, passthrough, no_history]),
|
||||||
|
@ -133,9 +97,9 @@ t_load_plugin(_) ->
|
||||||
ok = meck:new(emqx_plugins, [unstick, non_strict, passthrough, no_history]),
|
ok = meck:new(emqx_plugins, [unstick, non_strict, passthrough, no_history]),
|
||||||
ok = meck:expect(emqx_plugins, generate_configs, fun(_) -> ok end),
|
ok = meck:expect(emqx_plugins, generate_configs, fun(_) -> ok end),
|
||||||
ok = meck:expect(emqx_plugins, apply_configs, fun(_) -> ok end),
|
ok = meck:expect(emqx_plugins, apply_configs, fun(_) -> ok end),
|
||||||
?assertMatch({error, _}, emqx_plugins:load_plugin(already_loaded_app, true)),
|
?assertMatch({error, _}, emqx_plugins:load_plugin(already_loaded_app)),
|
||||||
?assertMatch(ok, emqx_plugins:load_plugin(normal, true)),
|
?assertMatch(ok, emqx_plugins:load_plugin(normal)),
|
||||||
?assertMatch({error,_}, emqx_plugins:load_plugin(error_app, true)),
|
?assertMatch({error,_}, emqx_plugins:load_plugin(error_app)),
|
||||||
|
|
||||||
ok = meck:unload(emqx_plugins),
|
ok = meck:unload(emqx_plugins),
|
||||||
ok = meck:unload(application).
|
ok = meck:unload(application).
|
||||||
|
@ -146,8 +110,8 @@ t_unload_plugin(_) ->
|
||||||
(error_app) -> {error, error};
|
(error_app) -> {error, error};
|
||||||
(_) -> ok end),
|
(_) -> ok end),
|
||||||
|
|
||||||
?assertEqual(ok, emqx_plugins:unload_plugin(not_started_app, true)),
|
?assertEqual(ok, emqx_plugins:unload_plugin(not_started_app)),
|
||||||
?assertEqual(ok, emqx_plugins:unload_plugin(normal, true)),
|
?assertEqual(ok, emqx_plugins:unload_plugin(normal)),
|
||||||
?assertEqual({error,error}, emqx_plugins:unload_plugin(error_app, true)),
|
?assertEqual({error,error}, emqx_plugins:unload_plugin(error_app)),
|
||||||
|
|
||||||
ok = meck:unload(application).
|
ok = meck:unload(application).
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
authn: {
|
emqx_authn: {
|
||||||
chains: [
|
chains: [
|
||||||
# {
|
# {
|
||||||
# id: "chain1"
|
# id: "chain1"
|
||||||
|
|
|
@ -38,11 +38,8 @@ stop(_State) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
initialize() ->
|
initialize() ->
|
||||||
ConfFile = filename:join([emqx:get_env(plugins_etc_dir), ?APP]) ++ ".conf",
|
#{chains := Chains,
|
||||||
{ok, RawConfig} = hocon:load(ConfFile),
|
bindings := Bindings} = emqx_config:get([authn], #{chains => [], bindings => []}),
|
||||||
#{authn := #{chains := Chains,
|
|
||||||
bindings := Bindings}}
|
|
||||||
= hocon_schema:check_plain(emqx_authn_schema, RawConfig, #{atom_key => true, nullable => true}),
|
|
||||||
initialize_chains(Chains),
|
initialize_chains(Chains),
|
||||||
initialize_bindings(Bindings).
|
initialize_bindings(Bindings).
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,9 @@
|
||||||
, authenticator_name/0
|
, authenticator_name/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
structs() -> [authn].
|
structs() -> ["emqx_authn"].
|
||||||
|
|
||||||
fields(authn) ->
|
fields("emqx_authn") ->
|
||||||
[ {chains, fun chains/1}
|
[ {chains, fun chains/1}
|
||||||
, {bindings, fun bindings/1}];
|
, {bindings, fun bindings/1}];
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ fields(pgsql) ->
|
||||||
, {config, hoconsc:t(hoconsc:ref(emqx_authn_pgsql, config))}
|
, {config, hoconsc:t(hoconsc:ref(emqx_authn_pgsql, config))}
|
||||||
].
|
].
|
||||||
|
|
||||||
chains(type) -> hoconsc:array({union, [hoconsc:ref('simple-chain')]});
|
chains(type) -> hoconsc:array({union, [hoconsc:ref(?MODULE, 'simple-chain')]});
|
||||||
chains(default) -> [];
|
chains(default) -> [];
|
||||||
chains(_) -> undefined.
|
chains(_) -> undefined.
|
||||||
|
|
||||||
|
@ -89,10 +89,10 @@ chain_id(nullable) -> false;
|
||||||
chain_id(_) -> undefined.
|
chain_id(_) -> undefined.
|
||||||
|
|
||||||
simple_authenticators(type) ->
|
simple_authenticators(type) ->
|
||||||
hoconsc:array({union, [ hoconsc:ref('built-in-database')
|
hoconsc:array({union, [ hoconsc:ref(?MODULE, 'built-in-database')
|
||||||
, hoconsc:ref(jwt)
|
, hoconsc:ref(?MODULE, jwt)
|
||||||
, hoconsc:ref(mysql)
|
, hoconsc:ref(?MODULE, mysql)
|
||||||
, hoconsc:ref(pgsql)]});
|
, hoconsc:ref(?MODULE, pgsql)]});
|
||||||
simple_authenticators(default) -> [];
|
simple_authenticators(default) -> [];
|
||||||
simple_authenticators(_) -> undefined.
|
simple_authenticators(_) -> undefined.
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ authenticator_name(type) -> authenticator_name();
|
||||||
authenticator_name(nullable) -> false;
|
authenticator_name(nullable) -> false;
|
||||||
authenticator_name(_) -> undefined.
|
authenticator_name(_) -> undefined.
|
||||||
|
|
||||||
bindings(type) -> hoconsc:array(hoconsc:ref(binding));
|
bindings(type) -> hoconsc:array(hoconsc:ref(?MODULE, binding));
|
||||||
bindings(default) -> [];
|
bindings(default) -> [];
|
||||||
bindings(_) -> undefined.
|
bindings(_) -> undefined.
|
||||||
|
|
||||||
|
|
|
@ -36,11 +36,7 @@ register_metrics() ->
|
||||||
|
|
||||||
init() ->
|
init() ->
|
||||||
ok = register_metrics(),
|
ok = register_metrics(),
|
||||||
Conf = filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'),
|
Rules = emqx_config:get([emqx_authz, rules], []),
|
||||||
{ok, RawConf} = hocon:load(Conf),
|
|
||||||
#{emqx_authz := #{rules := Rules}} = hocon_schema:check_plain(emqx_authz_schema, RawConf, #{atom_key => true}),
|
|
||||||
emqx_config:put([emqx_authz], #{rules => Rules}),
|
|
||||||
% Rules = emqx_config:get([emqx_authz, rules], []),
|
|
||||||
NRules = [compile(Rule) || Rule <- Rules],
|
NRules = [compile(Rule) || Rule <- Rules],
|
||||||
ok = emqx_hooks:add('client.authorize', {?MODULE, authorize, [NRules]}, -1).
|
ok = emqx_hooks:add('client.authorize', {?MODULE, authorize, [NRules]}, -1).
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,7 @@ set_special_configs(emqx) ->
|
||||||
application:set_env(emqx, enable_acl_cache, false),
|
application:set_env(emqx, enable_acl_cache, false),
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(emqx_authz) ->
|
set_special_configs(emqx_authz) ->
|
||||||
application:set_env(emqx, plugins_etc_dir,
|
emqx_config:put([emqx_authz], #{rules => []}),
|
||||||
emqx_ct_helpers:deps_path(emqx_authz, "test")),
|
|
||||||
Conf = #{<<"emqx_authz">> => #{<<"rules">> => []}},
|
|
||||||
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)),
|
|
||||||
% emqx_config:put([emqx_authz], #{rules => []}),
|
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(_App) ->
|
set_special_configs(_App) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
|
@ -55,22 +55,13 @@ set_special_configs(emqx) ->
|
||||||
application:set_env(emqx, enable_acl_cache, false),
|
application:set_env(emqx, enable_acl_cache, false),
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(emqx_authz) ->
|
set_special_configs(emqx_authz) ->
|
||||||
application:set_env(emqx, plugins_etc_dir,
|
emqx_config:put([emqx_authz], #{rules => []}),
|
||||||
emqx_ct_helpers:deps_path(emqx_authz, "test")),
|
|
||||||
Conf = #{<<"emqx_authz">> => #{<<"rules">> => []}},
|
|
||||||
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)),
|
|
||||||
% emqx_config:put([emqx_authz], #{rules => []}),
|
|
||||||
ok;
|
ok;
|
||||||
|
|
||||||
set_special_configs(emqx_management) ->
|
set_special_configs(emqx_management) ->
|
||||||
application:set_env(emqx, plugins_etc_dir,
|
emqx_config:put([emqx_management], #{listeners => [#{protocol => "http", port => 8081}],
|
||||||
emqx_ct_helpers:deps_path(emqx_management, "test")),
|
default_application_id => <<"admin">>,
|
||||||
Conf = #{<<"emqx_management">> => #{
|
default_application_secret => <<"public">>}),
|
||||||
<<"listeners">> => [#{
|
|
||||||
<<"protocol">> => <<"http">>
|
|
||||||
}]}
|
|
||||||
},
|
|
||||||
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'emqx_management.conf'), jsx:encode(Conf)),
|
|
||||||
ok;
|
ok;
|
||||||
|
|
||||||
set_special_configs(_App) ->
|
set_special_configs(_App) ->
|
||||||
|
|
|
@ -47,22 +47,12 @@ set_special_configs(emqx) ->
|
||||||
emqx_ct_helpers:deps_path(emqx, "test/loaded_plguins")),
|
emqx_ct_helpers:deps_path(emqx, "test/loaded_plguins")),
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(emqx_authz) ->
|
set_special_configs(emqx_authz) ->
|
||||||
application:set_env(emqx, plugins_etc_dir,
|
Rules = [#{config =>#{<<"meck">> => <<"fake">>},
|
||||||
emqx_ct_helpers:deps_path(emqx_authz, "test")),
|
principal => all,
|
||||||
Conf = #{<<"emqx_authz">> =>
|
sql => <<"fake sql">>,
|
||||||
#{<<"rules">> =>
|
type => mysql}
|
||||||
[#{<<"config">> =>#{<<"meck">> => <<"fake">>},
|
],
|
||||||
<<"principal">> => all,
|
emqx_config:put([emqx_authz], #{rules => Rules}),
|
||||||
<<"sql">> => <<"fake sql">>,
|
|
||||||
<<"type">> => mysql}
|
|
||||||
]}},
|
|
||||||
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)),
|
|
||||||
% Rules = [#{config =>#{<<"meck">> => <<"fake">>},
|
|
||||||
% principal => all,
|
|
||||||
% sql => <<"fake sql">>,
|
|
||||||
% type => mysql}
|
|
||||||
% ],
|
|
||||||
% emqx_config:put([emqx_authz], #{rules => Rules}),
|
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(_App) ->
|
set_special_configs(_App) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
|
@ -47,22 +47,12 @@ set_special_configs(emqx) ->
|
||||||
emqx_ct_helpers:deps_path(emqx, "test/loaded_plguins")),
|
emqx_ct_helpers:deps_path(emqx, "test/loaded_plguins")),
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(emqx_authz) ->
|
set_special_configs(emqx_authz) ->
|
||||||
application:set_env(emqx, plugins_etc_dir,
|
Rules = [#{config =>#{<<"meck">> => <<"fake">>},
|
||||||
emqx_ct_helpers:deps_path(emqx_authz, "test")),
|
principal => all,
|
||||||
Conf = #{<<"emqx_authz">> =>
|
sql => <<"fake sql">>,
|
||||||
#{<<"rules">> =>
|
type => pgsql}
|
||||||
[#{<<"config">> =>#{<<"meck">> => <<"fake">>},
|
],
|
||||||
<<"principal">> => all,
|
emqx_config:put([emqx_authz], #{rules => Rules}),
|
||||||
<<"sql">> => <<"fake sql">>,
|
|
||||||
<<"type">> => pgsql}
|
|
||||||
]}},
|
|
||||||
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)),
|
|
||||||
% Rules = [#{config =>#{<<"meck">> => <<"fake">>},
|
|
||||||
% principal => all,
|
|
||||||
% sql => <<"fake sql">>,
|
|
||||||
% type => pgsql}
|
|
||||||
% ],
|
|
||||||
% emqx_config:put([emqx_authz], #{rules => Rules}),
|
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(_App) ->
|
set_special_configs(_App) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
|
@ -47,28 +47,12 @@ set_special_configs(emqx) ->
|
||||||
emqx_ct_helpers:deps_path(emqx, "test/loaded_plguins")),
|
emqx_ct_helpers:deps_path(emqx, "test/loaded_plguins")),
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(emqx_authz) ->
|
set_special_configs(emqx_authz) ->
|
||||||
application:set_env(emqx, plugins_etc_dir,
|
Rules = [#{config =>#{<<"meck">> => <<"fake">>},
|
||||||
emqx_ct_helpers:deps_path(emqx_authz, "test")),
|
principal => all,
|
||||||
Conf = #{<<"emqx_authz">> =>
|
cmd => <<"fake cmd">>,
|
||||||
#{<<"rules">> =>
|
type => redis}
|
||||||
[#{<<"config">> =>#{
|
],
|
||||||
<<"server">> => <<"127.0.0.1:6379">>,
|
emqx_config:put([emqx_authz], #{rules => Rules}),
|
||||||
<<"password">> => <<"public">>,
|
|
||||||
<<"pool_size">> => 1,
|
|
||||||
<<"auto_reconnect">> => true,
|
|
||||||
<<"ssl">> => #{<<"enable">> => false}
|
|
||||||
},
|
|
||||||
<<"principal">> => all,
|
|
||||||
<<"cmd">> => <<"fake cmd">>,
|
|
||||||
<<"type">> => redis}
|
|
||||||
]}},
|
|
||||||
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'authz.conf'), jsx:encode(Conf)),
|
|
||||||
% Rules = [#{config =>#{<<"meck">> => <<"fake">>},
|
|
||||||
% principal => all,
|
|
||||||
% cmd => <<"fake cmd">>,
|
|
||||||
% type => redis}
|
|
||||||
% ],
|
|
||||||
% emqx_config:put([emqx_authz], #{rules => Rules}),
|
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(_App) ->
|
set_special_configs(_App) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
|
@ -3,54 +3,56 @@
|
||||||
##====================================================================
|
##====================================================================
|
||||||
|
|
||||||
emqx_bridge_mqtt:{
|
emqx_bridge_mqtt:{
|
||||||
bridges:[{
|
bridges:[
|
||||||
name: "mqtt1"
|
# {
|
||||||
start_type: auto
|
# name: "mqtt1"
|
||||||
forwards: ["test/#"],
|
# start_type: auto
|
||||||
forward_mountpoint: ""
|
# forwards: ["test/#"],
|
||||||
reconnect_interval: "30s"
|
# forward_mountpoint: ""
|
||||||
batch_size: 100
|
# reconnect_interval: "30s"
|
||||||
queue:{
|
# batch_size: 100
|
||||||
replayq_dir: false
|
# queue:{
|
||||||
|
# replayq_dir: "{{ platform_data_dir }}/replayq/bridge_mqtt/"
|
||||||
# replayq_seg_bytes: "100MB"
|
# replayq_seg_bytes: "100MB"
|
||||||
# replayq_offload_mode: false
|
# replayq_offload_mode: false
|
||||||
# replayq_max_total_bytes: "1GB"
|
# replayq_max_total_bytes: "1GB"
|
||||||
},
|
# },
|
||||||
config:{
|
# config:{
|
||||||
conn_type: mqtt
|
# conn_type: mqtt
|
||||||
address: "127.0.0.1:1883"
|
# address: "127.0.0.1:1883"
|
||||||
proto_ver: v4
|
# proto_ver: v4
|
||||||
bridge_mode: true
|
# bridge_mode: true
|
||||||
clientid: "client1"
|
# clientid: "client1"
|
||||||
clean_start: true
|
# clean_start: true
|
||||||
username: "username1"
|
# username: "username1"
|
||||||
password: ""
|
# password: ""
|
||||||
keepalive: 300
|
# keepalive: 300
|
||||||
subscriptions: [{
|
# subscriptions: [{
|
||||||
topic: "t/#"
|
# topic: "t/#"
|
||||||
qos: 1
|
# qos: 1
|
||||||
}]
|
# }]
|
||||||
receive_mountpoint: ""
|
# receive_mountpoint: ""
|
||||||
retry_interval: "30s"
|
# retry_interval: "30s"
|
||||||
max_inflight: 32
|
# max_inflight: 32
|
||||||
}
|
# }
|
||||||
},
|
# },
|
||||||
{
|
# {
|
||||||
name: "rpc1"
|
# name: "rpc1"
|
||||||
start_type: auto
|
# start_type: auto
|
||||||
forwards: ["test/#"],
|
# forwards: ["test/#"],
|
||||||
forward_mountpoint: ""
|
# forward_mountpoint: ""
|
||||||
reconnect_interval: "30s"
|
# reconnect_interval: "30s"
|
||||||
batch_size: 100
|
# batch_size: 100
|
||||||
queue:{
|
# queue:{
|
||||||
replayq_dir: "{{ platform_data_dir }}/replayq/bridge_mqtt/"
|
# replayq_dir: "{{ platform_data_dir }}/replayq/bridge_mqtt/"
|
||||||
replayq_seg_bytes: "100MB"
|
# replayq_seg_bytes: "100MB"
|
||||||
replayq_offload_mode: false
|
# replayq_offload_mode: false
|
||||||
replayq_max_total_bytes: "1GB"
|
# replayq_max_total_bytes: "1GB"
|
||||||
},
|
# },
|
||||||
config:{
|
# config:{
|
||||||
conn_type: rpc
|
# conn_type: rpc
|
||||||
node: "emqx@127.0.0.1"
|
# node: "emqx@127.0.0.1"
|
||||||
}
|
# }
|
||||||
}]
|
# }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
structs() -> ["emqx_bridge_mqtt"].
|
structs() -> ["emqx_bridge_mqtt"].
|
||||||
|
|
||||||
fields("emqx_bridge_mqtt") ->
|
fields("emqx_bridge_mqtt") ->
|
||||||
[ {bridges, hoconsc:array("bridges")}
|
[ {bridges, hoconsc:array(hoconsc:ref(?MODULE, "bridges"))}
|
||||||
];
|
];
|
||||||
|
|
||||||
fields("bridges") ->
|
fields("bridges") ->
|
||||||
|
@ -36,8 +36,8 @@ fields("bridges") ->
|
||||||
, {forward_mountpoint, emqx_schema:t(string())}
|
, {forward_mountpoint, emqx_schema:t(string())}
|
||||||
, {reconnect_interval, emqx_schema:t(emqx_schema:duration_ms(), undefined, "30s")}
|
, {reconnect_interval, emqx_schema:t(emqx_schema:duration_ms(), undefined, "30s")}
|
||||||
, {batch_size, emqx_schema:t(integer(), undefined, 100)}
|
, {batch_size, emqx_schema:t(integer(), undefined, 100)}
|
||||||
, {queue, emqx_schema:t(hoconsc:ref("queue"))}
|
, {queue, emqx_schema:t(hoconsc:ref(?MODULE, "queue"))}
|
||||||
, {config, hoconsc:union([hoconsc:ref("mqtt"), hoconsc:ref("rpc")])}
|
, {config, hoconsc:union([hoconsc:ref(?MODULE, "mqtt"), hoconsc:ref(?MODULE, "rpc")])}
|
||||||
];
|
];
|
||||||
|
|
||||||
fields("mqtt") ->
|
fields("mqtt") ->
|
||||||
|
|
|
@ -40,18 +40,7 @@
|
||||||
-define(OVERVIEWS, ['alarms/activated', 'alarms/deactivated', banned, brokers, stats, metrics, listeners, clients, subscriptions, routes, plugins]).
|
-define(OVERVIEWS, ['alarms/activated', 'alarms/deactivated', banned, brokers, stats, metrics, listeners, clients, subscriptions, routes, plugins]).
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
[{group, overview},
|
emqx_ct:all(?MODULE).
|
||||||
{group, admins},
|
|
||||||
{group, rest},
|
|
||||||
{group, cli}
|
|
||||||
].
|
|
||||||
|
|
||||||
groups() ->
|
|
||||||
[{overview, [sequence], [t_overview]},
|
|
||||||
{admins, [sequence], [t_admins_add_delete]},
|
|
||||||
{rest, [sequence], [t_rest_api]},
|
|
||||||
{cli, [sequence], [t_cli]}
|
|
||||||
].
|
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
emqx_ct_helpers:start_apps([emqx_management, emqx_dashboard],fun set_special_configs/1),
|
emqx_ct_helpers:start_apps([emqx_management, emqx_dashboard],fun set_special_configs/1),
|
||||||
|
@ -62,29 +51,27 @@ end_per_suite(_Config) ->
|
||||||
ekka_mnesia:ensure_stopped().
|
ekka_mnesia:ensure_stopped().
|
||||||
|
|
||||||
set_special_configs(emqx_management) ->
|
set_special_configs(emqx_management) ->
|
||||||
application:set_env(emqx, plugins_etc_dir,
|
emqx_config:put([emqx_management], #{listeners => [#{protocol => "http", port => 8081}],
|
||||||
emqx_ct_helpers:deps_path(emqx_management, "test")),
|
default_application_id => <<"admin">>,
|
||||||
Conf = #{<<"emqx_management">> => #{
|
default_application_secret => <<"public">>}),
|
||||||
<<"listeners">> => [#{
|
|
||||||
<<"protocol">> => <<"http">>
|
|
||||||
}]}
|
|
||||||
},
|
|
||||||
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'emqx_management.conf'), jsx:encode(Conf)),
|
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(_) ->
|
set_special_configs(_) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
t_overview(_) ->
|
t_overview(_) ->
|
||||||
|
mnesia:clear_table(mqtt_admin),
|
||||||
|
emqx_dashboard_admin:add_user(<<"admin">>, <<"public">>, <<"tag">>),
|
||||||
[?assert(request_dashboard(get, api_path(erlang:atom_to_list(Overview)), auth_header_()))|| Overview <- ?OVERVIEWS].
|
[?assert(request_dashboard(get, api_path(erlang:atom_to_list(Overview)), auth_header_()))|| Overview <- ?OVERVIEWS].
|
||||||
|
|
||||||
t_admins_add_delete(_) ->
|
t_admins_add_delete(_) ->
|
||||||
|
mnesia:clear_table(mqtt_admin),
|
||||||
ok = emqx_dashboard_admin:add_user(<<"username">>, <<"password">>, <<"tag">>),
|
ok = emqx_dashboard_admin:add_user(<<"username">>, <<"password">>, <<"tag">>),
|
||||||
ok = emqx_dashboard_admin:add_user(<<"username1">>, <<"password1">>, <<"tag1">>),
|
ok = emqx_dashboard_admin:add_user(<<"username1">>, <<"password1">>, <<"tag1">>),
|
||||||
Admins = emqx_dashboard_admin:all_users(),
|
Admins = emqx_dashboard_admin:all_users(),
|
||||||
?assertEqual(3, length(Admins)),
|
?assertEqual(2, length(Admins)),
|
||||||
ok = emqx_dashboard_admin:remove_user(<<"username1">>),
|
ok = emqx_dashboard_admin:remove_user(<<"username1">>),
|
||||||
Users = emqx_dashboard_admin:all_users(),
|
Users = emqx_dashboard_admin:all_users(),
|
||||||
?assertEqual(2, length(Users)),
|
?assertEqual(1, length(Users)),
|
||||||
ok = emqx_dashboard_admin:change_password(<<"username">>, <<"password">>, <<"pwd">>),
|
ok = emqx_dashboard_admin:change_password(<<"username">>, <<"password">>, <<"pwd">>),
|
||||||
timer:sleep(10),
|
timer:sleep(10),
|
||||||
?assert(request_dashboard(get, api_path("brokers"), auth_header_("username", "pwd"))),
|
?assert(request_dashboard(get, api_path("brokers"), auth_header_("username", "pwd"))),
|
||||||
|
@ -93,6 +80,8 @@ t_admins_add_delete(_) ->
|
||||||
?assertNotEqual(true, request_dashboard(get, api_path("brokers"), auth_header_("username", "pwd"))).
|
?assertNotEqual(true, request_dashboard(get, api_path("brokers"), auth_header_("username", "pwd"))).
|
||||||
|
|
||||||
t_rest_api(_Config) ->
|
t_rest_api(_Config) ->
|
||||||
|
mnesia:clear_table(mqtt_admin),
|
||||||
|
emqx_dashboard_admin:add_user(<<"admin">>, <<"public">>, <<"administrator">>),
|
||||||
{ok, Res0} = http_get("users"),
|
{ok, Res0} = http_get("users"),
|
||||||
|
|
||||||
?assertEqual([#{<<"username">> => <<"admin">>,
|
?assertEqual([#{<<"username">> => <<"admin">>,
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
## EMQ X Bridge Plugin
|
## EMQ X Bridge Plugin
|
||||||
##--------------------------------------------------------------------
|
##--------------------------------------------------------------------
|
||||||
|
|
||||||
emqx_data_bridge.bridges: [
|
emqx_data_bridge:{
|
||||||
|
bridges:[
|
||||||
# {name: "mysql_bridge_1"
|
# {name: "mysql_bridge_1"
|
||||||
# type: mysql
|
# type: mysql
|
||||||
# config: {
|
# config: {
|
||||||
|
@ -123,4 +124,6 @@ emqx_data_bridge.bridges: [
|
||||||
# ssl: false
|
# ssl: false
|
||||||
# }
|
# }
|
||||||
# }
|
# }
|
||||||
|
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_management,
|
{application, emqx_management,
|
||||||
[{description, "EMQ X Management API and CLI"},
|
[{description, "EMQ X Management API and CLI"},
|
||||||
{vsn, "4.4.0"}, % strict semver, bump manually!
|
{vsn, "5.0.0"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_management_sup]},
|
{registered, [emqx_management_sup]},
|
||||||
{applications, [kernel,stdlib,minirest]},
|
{applications, [kernel,stdlib,minirest]},
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
%% -*- mode: erlang -*-
|
|
||||||
{VSN,
|
|
||||||
[ {<<"4.3.[0-2]">>,
|
|
||||||
[ {restart_application, emqx_management}
|
|
||||||
]},
|
|
||||||
{<<".*">>, []}
|
|
||||||
],
|
|
||||||
[ {<<"4.3.[0-2]">>,
|
|
||||||
[ {restart_application, emqx_management}
|
|
||||||
]},
|
|
||||||
{<<".*">>, []}
|
|
||||||
]
|
|
||||||
}.
|
|
|
@ -28,7 +28,7 @@ fields("emqx_management") ->
|
||||||
[ {default_application_id, fun default_application_id/1}
|
[ {default_application_id, fun default_application_id/1}
|
||||||
, {default_application_secret, fun default_application_secret/1}
|
, {default_application_secret, fun default_application_secret/1}
|
||||||
, {max_row_limit, fun max_row_limit/1}
|
, {max_row_limit, fun max_row_limit/1}
|
||||||
, {listeners, hoconsc:array(hoconsc:union([hoconsc:ref("http"), hoconsc:ref("https")]))}
|
, {listeners, hoconsc:array(hoconsc:union([hoconsc:ref(?MODULE, "http"), hoconsc:ref(?MODULE, "https")]))}
|
||||||
];
|
];
|
||||||
|
|
||||||
fields("http") ->
|
fields("http") ->
|
||||||
|
|
|
@ -525,7 +525,7 @@ check_row_limit([Tab|Tables], Limit) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
max_row_limit() ->
|
max_row_limit() ->
|
||||||
application:get_env(?APP, max_row_limit, ?MAX_ROW_LIMIT).
|
emqx_config:get([?APP, max_row_limit], ?MAX_ROW_LIMIT).
|
||||||
|
|
||||||
table_size(Tab) -> ets:info(Tab, size).
|
table_size(Tab) -> ets:info(Tab, size).
|
||||||
|
|
||||||
|
|
|
@ -106,10 +106,8 @@ format({Node, Plugins}) ->
|
||||||
|
|
||||||
format(#plugin{name = Name,
|
format(#plugin{name = Name,
|
||||||
descr = Descr,
|
descr = Descr,
|
||||||
active = Active,
|
active = Active}) ->
|
||||||
type = Type}) ->
|
|
||||||
#{name => Name,
|
#{name => Name,
|
||||||
description => iolist_to_binary(Descr),
|
description => iolist_to_binary(Descr),
|
||||||
active => Active,
|
active => Active}.
|
||||||
type => Type}.
|
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,6 @@
|
||||||
-include("emqx_mgmt.hrl").
|
-include("emqx_mgmt.hrl").
|
||||||
|
|
||||||
start(_Type, _Args) ->
|
start(_Type, _Args) ->
|
||||||
Conf = filename:join(emqx:get_env(plugins_etc_dir), 'emqx_management.conf'),
|
|
||||||
{ok, RawConf} = hocon:load(Conf),
|
|
||||||
#{emqx_management := Config} =
|
|
||||||
hocon_schema:check_plain(emqx_management_schema, RawConf, #{atom_key => true}),
|
|
||||||
[application:set_env(?APP, Key, maps:get(Key, Config)) || Key <- maps:keys(Config)],
|
|
||||||
{ok, Sup} = emqx_mgmt_sup:start_link(),
|
{ok, Sup} = emqx_mgmt_sup:start_link(),
|
||||||
ok = ekka_rlog:wait_for_shards([?MANAGEMENT_SHARD], infinity),
|
ok = ekka_rlog:wait_for_shards([?MANAGEMENT_SHARD], infinity),
|
||||||
_ = emqx_mgmt_auth:add_default_app(),
|
_ = emqx_mgmt_auth:add_default_app(),
|
||||||
|
|
|
@ -68,14 +68,14 @@ mnesia(copy) ->
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
-spec(add_default_app() -> ok | {ok, appsecret()} | {error, term()}).
|
-spec(add_default_app() -> ok | {ok, appsecret()} | {error, term()}).
|
||||||
add_default_app() ->
|
add_default_app() ->
|
||||||
AppId = application:get_env(?APP, default_application_id, undefined),
|
AppId = emqx_config:get([?APP, default_application_id], undefined),
|
||||||
AppSecret = application:get_env(?APP, default_application_secret, undefined),
|
AppSecret = emqx_config:get([?APP, default_application_secret], undefined),
|
||||||
case {AppId, AppSecret} of
|
case {AppId, AppSecret} of
|
||||||
{undefined, _} -> ok;
|
{undefined, _} -> ok;
|
||||||
{_, undefined} -> ok;
|
{_, undefined} -> ok;
|
||||||
{_, _} ->
|
{_, _} ->
|
||||||
AppId1 = erlang:list_to_binary(AppId),
|
AppId1 = to_binary(AppId),
|
||||||
AppSecret1 = erlang:list_to_binary(AppSecret),
|
AppSecret1 = to_binary(AppSecret),
|
||||||
add_app(AppId1, <<"Default">>, AppSecret1, <<"Application user">>, true, undefined)
|
add_app(AppId1, <<"Default">>, AppSecret1, <<"Application user">>, true, undefined)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -210,3 +210,6 @@ is_authorized(AppId, AppSecret) ->
|
||||||
|
|
||||||
is_expired(undefined) -> true;
|
is_expired(undefined) -> true;
|
||||||
is_expired(Expired) -> Expired >= erlang:system_time(second).
|
is_expired(Expired) -> Expired >= erlang:system_time(second).
|
||||||
|
|
||||||
|
to_binary(L) when is_list(L) -> list_to_binary(L);
|
||||||
|
to_binary(B) when is_binary(B) -> B.
|
||||||
|
|
|
@ -80,7 +80,7 @@ stop_listener({Proto, Port, _}) ->
|
||||||
listeners() ->
|
listeners() ->
|
||||||
[{list_to_atom(Protocol), Port, maps:to_list(maps:without([protocol, port], Map))}
|
[{list_to_atom(Protocol), Port, maps:to_list(maps:without([protocol, port], Map))}
|
||||||
|| Map = #{protocol := Protocol,port := Port}
|
|| Map = #{protocol := Protocol,port := Port}
|
||||||
<- application:get_env(?APP, listeners, [])].
|
<- emqx_config:get([emqx_management, listeners], [])].
|
||||||
|
|
||||||
listener_name(Proto) ->
|
listener_name(Proto) ->
|
||||||
list_to_atom(atom_to_list(Proto) ++ ":management").
|
list_to_atom(atom_to_list(Proto) ++ ":management").
|
||||||
|
|
|
@ -29,50 +29,19 @@
|
||||||
-define(LOG_HANDLER_ID, [file, default]).
|
-define(LOG_HANDLER_ID, [file, default]).
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
[{group, manage_apps},
|
emqx_ct:all(?MODULE).
|
||||||
{group, check_cli}].
|
|
||||||
|
|
||||||
groups() ->
|
|
||||||
[{manage_apps, [sequence],
|
|
||||||
[t_app
|
|
||||||
]},
|
|
||||||
{check_cli, [sequence],
|
|
||||||
[t_cli,
|
|
||||||
t_log_cmd,
|
|
||||||
t_mgmt_cmd,
|
|
||||||
t_status_cmd,
|
|
||||||
t_clients_cmd,
|
|
||||||
t_vm_cmd,
|
|
||||||
t_plugins_cmd,
|
|
||||||
t_trace_cmd,
|
|
||||||
t_broker_cmd,
|
|
||||||
t_router_cmd,
|
|
||||||
t_subscriptions_cmd,
|
|
||||||
t_listeners_cmd_old,
|
|
||||||
t_listeners_cmd_new
|
|
||||||
]}].
|
|
||||||
|
|
||||||
apps() ->
|
|
||||||
[emqx_management, emqx_retainer].
|
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
ekka_mnesia:start(),
|
ekka_mnesia:start(),
|
||||||
emqx_mgmt_auth:mnesia(boot),
|
emqx_mgmt_auth:mnesia(boot),
|
||||||
emqx_ct_helpers:start_apps(apps(), fun set_special_configs/1),
|
emqx_ct_helpers:start_apps([emqx_retainer, emqx_management], fun set_special_configs/1),
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(_Config) ->
|
||||||
emqx_ct_helpers:stop_apps(apps()).
|
emqx_ct_helpers:stop_apps([emqx_management, emqx_retainer]).
|
||||||
|
|
||||||
set_special_configs(emqx_management) ->
|
set_special_configs(emqx_management) ->
|
||||||
application:set_env(emqx, plugins_etc_dir,
|
emqx_config:put([emqx_management], #{listeners => [#{protocol => "http", port => 8081}]}),
|
||||||
emqx_ct_helpers:deps_path(emqx_management, "test")),
|
|
||||||
Conf = #{<<"emqx_management">> => #{
|
|
||||||
<<"listeners">> => [#{
|
|
||||||
<<"protocol">> => <<"http">>
|
|
||||||
}]}
|
|
||||||
},
|
|
||||||
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'emqx_management.conf'), jsx:encode(Conf)),
|
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(_App) ->
|
set_special_configs(_App) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
|
@ -51,14 +51,9 @@ end_per_testcase(_, Config) ->
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
set_special_configs(emqx_management) ->
|
set_special_configs(emqx_management) ->
|
||||||
application:set_env(emqx, plugins_etc_dir,
|
emqx_config:put([emqx_management], #{listeners => [#{protocol => "http", port => 8081}],
|
||||||
emqx_ct_helpers:deps_path(emqx_management, "test")),
|
default_application_id => <<"admin">>,
|
||||||
Conf = #{<<"emqx_management">> => #{
|
default_application_secret => <<"public">>}),
|
||||||
<<"listeners">> => [#{
|
|
||||||
<<"protocol">> => <<"http">>
|
|
||||||
}]}
|
|
||||||
},
|
|
||||||
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'emqx_management.conf'), jsx:encode(Conf)),
|
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(_App) ->
|
set_special_configs(_App) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
|
@ -143,6 +143,8 @@ cli(_) ->
|
||||||
{"modules reload <Module>", "Reload module"}
|
{"modules reload <Module>", "Reload module"}
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
name(Name) when is_binary(Name) ->
|
||||||
|
name(binary_to_atom(Name, utf8));
|
||||||
name(delayed) -> emqx_mod_delayed;
|
name(delayed) -> emqx_mod_delayed;
|
||||||
name(presence) -> emqx_mod_presence;
|
name(presence) -> emqx_mod_presence;
|
||||||
name(recon) -> emqx_mod_recon;
|
name(recon) -> emqx_mod_recon;
|
||||||
|
|
|
@ -37,15 +37,9 @@ init_per_suite(Config) ->
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
set_special_configs(emqx_management) ->
|
set_special_configs(emqx_management) ->
|
||||||
application:set_env(emqx, modules_loaded_file, emqx_ct_helpers:deps_path(emqx, "test/emqx_SUITE_data/loaded_modules")),
|
emqx_config:put([emqx_management], #{listeners => [#{protocol => "http", port => 8081}],
|
||||||
application:set_env(emqx, plugins_etc_dir,
|
default_application_id => <<"admin">>,
|
||||||
emqx_ct_helpers:deps_path(emqx_management, "test")),
|
default_application_secret => <<"public">>}),
|
||||||
Conf = #{<<"emqx_management">> => #{
|
|
||||||
<<"listeners">> => [#{
|
|
||||||
<<"protocol">> => <<"http">>
|
|
||||||
}]}
|
|
||||||
},
|
|
||||||
ok = file:write_file(filename:join(emqx:get_env(plugins_etc_dir), 'emqx_management.conf'), jsx:encode(Conf)),
|
|
||||||
ok;
|
ok;
|
||||||
set_special_configs(_) ->
|
set_special_configs(_) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
|
@ -5,4 +5,4 @@
|
||||||
{platform_etc_dir, "etc"}.
|
{platform_etc_dir, "etc"}.
|
||||||
{platform_lib_dir, "lib"}.
|
{platform_lib_dir, "lib"}.
|
||||||
{platform_log_dir, "log"}.
|
{platform_log_dir, "log"}.
|
||||||
{platform_plugins_dir, "plugins"}.
|
{platform_plugins_dir, "data/plugins"}.
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
{emqx_management, true}.
|
|
||||||
{emqx_dashboard, true}.
|
|
||||||
{emqx_retainer, {{enable_plugin_emqx_retainer}}}.
|
|
|
@ -127,8 +127,9 @@ prod_compile_opts() ->
|
||||||
prod_overrides() ->
|
prod_overrides() ->
|
||||||
[{add, [ {erl_opts, [deterministic]}]}].
|
[{add, [ {erl_opts, [deterministic]}]}].
|
||||||
|
|
||||||
relup_deps(Profile) ->
|
relup_deps(_Profile) ->
|
||||||
{post_hooks, [{"(linux|darwin|solaris|freebsd|netbsd|openbsd)", compile, "scripts/inject-deps.escript " ++ atom_to_list(Profile)}]}.
|
% {post_hooks, [{"(linux|darwin|solaris|freebsd|netbsd|openbsd)", compile, "scripts/inject-deps.escript " ++ atom_to_list(Profile)}]}.
|
||||||
|
{post_hooks, []}.
|
||||||
|
|
||||||
profiles() ->
|
profiles() ->
|
||||||
Vsn = get_vsn(),
|
Vsn = get_vsn(),
|
||||||
|
@ -192,9 +193,8 @@ overlay_vars_rel(RelType) ->
|
||||||
cloud -> "vm.args";
|
cloud -> "vm.args";
|
||||||
edge -> "vm.args.edge"
|
edge -> "vm.args.edge"
|
||||||
end,
|
end,
|
||||||
[
|
|
||||||
{enable_plugin_emqx_retainer, true}
|
[ {vm_args_file, VmArgs}
|
||||||
, {vm_args_file, VmArgs}
|
|
||||||
].
|
].
|
||||||
|
|
||||||
%% vars per packaging type, bin(zip/tar.gz/docker) or pkg(rpm/deb)
|
%% vars per packaging type, bin(zip/tar.gz/docker) or pkg(rpm/deb)
|
||||||
|
@ -204,7 +204,7 @@ overlay_vars_pkg(bin) ->
|
||||||
, {platform_etc_dir, "etc"}
|
, {platform_etc_dir, "etc"}
|
||||||
, {platform_lib_dir, "lib"}
|
, {platform_lib_dir, "lib"}
|
||||||
, {platform_log_dir, "log"}
|
, {platform_log_dir, "log"}
|
||||||
, {platform_plugins_dir, "etc/plugins"}
|
, {platform_plugins_dir, "plugins"}
|
||||||
, {runner_root_dir, "$(cd $(dirname $(readlink $0 || echo $0))/..; pwd -P)"}
|
, {runner_root_dir, "$(cd $(dirname $(readlink $0 || echo $0))/..; pwd -P)"}
|
||||||
, {runner_bin_dir, "$RUNNER_ROOT_DIR/bin"}
|
, {runner_bin_dir, "$RUNNER_ROOT_DIR/bin"}
|
||||||
, {runner_etc_dir, "$RUNNER_ROOT_DIR/etc"}
|
, {runner_etc_dir, "$RUNNER_ROOT_DIR/etc"}
|
||||||
|
@ -219,7 +219,7 @@ overlay_vars_pkg(pkg) ->
|
||||||
, {platform_etc_dir, "/etc/emqx"}
|
, {platform_etc_dir, "/etc/emqx"}
|
||||||
, {platform_lib_dir, ""}
|
, {platform_lib_dir, ""}
|
||||||
, {platform_log_dir, "/var/log/emqx"}
|
, {platform_log_dir, "/var/log/emqx"}
|
||||||
, {platform_plugins_dir, "/var/lib/emqx/plugins"}
|
, {platform_plugins_dir, "/var/lib/enqx/plugins"}
|
||||||
, {runner_root_dir, "/usr/lib/emqx"}
|
, {runner_root_dir, "/usr/lib/emqx"}
|
||||||
, {runner_bin_dir, "/usr/bin"}
|
, {runner_bin_dir, "/usr/bin"}
|
||||||
, {runner_etc_dir, "/etc/emqx"}
|
, {runner_etc_dir, "/etc/emqx"}
|
||||||
|
@ -255,8 +255,12 @@ relx_apps(ReleaseType) ->
|
||||||
, emqx_connector
|
, emqx_connector
|
||||||
, emqx_data_bridge
|
, emqx_data_bridge
|
||||||
, emqx_rule_engine
|
, emqx_rule_engine
|
||||||
|
, emqx_rule_actions
|
||||||
, emqx_bridge_mqtt
|
, emqx_bridge_mqtt
|
||||||
, emqx_modules
|
, emqx_modules
|
||||||
|
, emqx_management
|
||||||
|
, emqx_retainer
|
||||||
|
, emqx_statsd
|
||||||
]
|
]
|
||||||
++ [emqx_telemetry || not is_enterprise()]
|
++ [emqx_telemetry || not is_enterprise()]
|
||||||
++ [emqx_license || is_enterprise()]
|
++ [emqx_license || is_enterprise()]
|
||||||
|
@ -279,25 +283,13 @@ is_app(Name) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
relx_plugin_apps(ReleaseType) ->
|
relx_plugin_apps(ReleaseType) ->
|
||||||
[ emqx_retainer
|
[]
|
||||||
, emqx_management
|
|
||||||
, emqx_dashboard
|
|
||||||
, emqx_sn
|
|
||||||
, emqx_coap
|
|
||||||
, emqx_stomp
|
|
||||||
, emqx_statsd
|
|
||||||
, emqx_rule_actions
|
|
||||||
]
|
|
||||||
++ relx_plugin_apps_per_rel(ReleaseType)
|
++ relx_plugin_apps_per_rel(ReleaseType)
|
||||||
++ relx_plugin_apps_enterprise(is_enterprise())
|
++ relx_plugin_apps_enterprise(is_enterprise())
|
||||||
++ relx_plugin_apps_extra().
|
++ relx_plugin_apps_extra().
|
||||||
|
|
||||||
relx_plugin_apps_per_rel(cloud) ->
|
relx_plugin_apps_per_rel(cloud) ->
|
||||||
[ emqx_lwm2m
|
[];
|
||||||
, emqx_exhook
|
|
||||||
, emqx_exproto
|
|
||||||
, emqx_prometheus
|
|
||||||
];
|
|
||||||
relx_plugin_apps_per_rel(edge) ->
|
relx_plugin_apps_per_rel(edge) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -313,11 +305,11 @@ relx_plugin_apps_extra() ->
|
||||||
relx_overlay(ReleaseType) ->
|
relx_overlay(ReleaseType) ->
|
||||||
[ {mkdir, "log/"}
|
[ {mkdir, "log/"}
|
||||||
, {mkdir, "data/"}
|
, {mkdir, "data/"}
|
||||||
|
, {mkdir, "plugins"}
|
||||||
, {mkdir, "data/mnesia"}
|
, {mkdir, "data/mnesia"}
|
||||||
, {mkdir, "data/configs"}
|
, {mkdir, "data/configs"}
|
||||||
, {mkdir, "data/patches"}
|
, {mkdir, "data/patches"}
|
||||||
, {mkdir, "data/scripts"}
|
, {mkdir, "data/scripts"}
|
||||||
, {template, "data/loaded_plugins.tmpl", "data/loaded_plugins"}
|
|
||||||
, {template, "data/emqx_vars", "releases/emqx_vars"}
|
, {template, "data/emqx_vars", "releases/emqx_vars"}
|
||||||
, {template, "data/BUILT_ON", "releases/{{release_version}}/BUILT_ON"}
|
, {template, "data/BUILT_ON", "releases/{{release_version}}/BUILT_ON"}
|
||||||
, {copy, "bin/emqx", "bin/emqx"}
|
, {copy, "bin/emqx", "bin/emqx"}
|
||||||
|
@ -337,12 +329,8 @@ relx_overlay(ReleaseType) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
etc_overlay(ReleaseType) ->
|
etc_overlay(ReleaseType) ->
|
||||||
PluginApps = relx_plugin_apps(ReleaseType),
|
Templates = emqx_etc_overlay(ReleaseType),
|
||||||
Templates = emqx_etc_overlay(ReleaseType) ++
|
|
||||||
lists:append([plugin_etc_overlays(App) || App <- PluginApps]) ++
|
|
||||||
[community_plugin_etc_overlays(App) || App <- relx_plugin_apps_extra()],
|
|
||||||
[ {mkdir, "etc/"}
|
[ {mkdir, "etc/"}
|
||||||
, {mkdir, "etc/plugins"}
|
|
||||||
, {copy, "{{base_dir}}/lib/emqx/etc/certs","etc/"}
|
, {copy, "{{base_dir}}/lib/emqx/etc/certs","etc/"}
|
||||||
] ++
|
] ++
|
||||||
lists:map(
|
lists:map(
|
||||||
|
@ -352,7 +340,7 @@ etc_overlay(ReleaseType) ->
|
||||||
++ extra_overlay(ReleaseType).
|
++ extra_overlay(ReleaseType).
|
||||||
|
|
||||||
extra_overlay(cloud) ->
|
extra_overlay(cloud) ->
|
||||||
[ {copy,"{{base_dir}}/lib/emqx_lwm2m/lwm2m_xml","etc/"}
|
[
|
||||||
];
|
];
|
||||||
extra_overlay(edge) ->
|
extra_overlay(edge) ->
|
||||||
[].
|
[].
|
||||||
|
@ -366,42 +354,9 @@ emqx_etc_overlay(edge) ->
|
||||||
].
|
].
|
||||||
|
|
||||||
emqx_etc_overlay_common() ->
|
emqx_etc_overlay_common() ->
|
||||||
[{"{{base_dir}}/lib/emqx/etc/acl.conf", "etc/acl.conf"},
|
[ {"{{base_dir}}/lib/emqx/etc/emqx.conf.all", "etc/emqx.conf"}
|
||||||
{"{{base_dir}}/lib/emqx/etc/emqx.conf", "etc/emqx.conf"},
|
, {"{{base_dir}}/lib/emqx/etc/ssl_dist.conf", "etc/ssl_dist.conf"}
|
||||||
{"{{base_dir}}/lib/emqx/etc/ssl_dist.conf", "etc/ssl_dist.conf"},
|
].
|
||||||
{"{{base_dir}}/lib/emqx_data_bridge/etc/emqx_data_bridge.conf", "etc/plugins/emqx_data_bridge.conf"},
|
|
||||||
{"{{base_dir}}/lib/emqx_telemetry/etc/emqx_telemetry.conf", "etc/plugins/emqx_telemetry.conf"},
|
|
||||||
{"{{base_dir}}/lib/emqx_authn/etc/emqx_authn.conf", "etc/plugins/emqx_authn.conf"},
|
|
||||||
{"{{base_dir}}/lib/emqx_authz/etc/emqx_authz.conf", "etc/plugins/authz.conf"},
|
|
||||||
{"{{base_dir}}/lib/emqx_rule_engine/etc/emqx_rule_engine.conf", "etc/plugins/emqx_rule_engine.conf"},
|
|
||||||
{"{{base_dir}}/lib/emqx_bridge_mqtt/etc/emqx_bridge_mqtt.conf", "etc/plugins/emqx_bridge_mqtt.conf"},
|
|
||||||
{"{{base_dir}}/lib/emqx_modules/etc/emqx_modules.conf", "etc/plugins/emqx_modules.conf"},
|
|
||||||
%% TODO: check why it has to end with .paho
|
|
||||||
%% and why it is put to etc/plugins dir
|
|
||||||
{"{{base_dir}}/lib/emqx/etc/acl.conf.paho", "etc/plugins/acl.conf.paho"}].
|
|
||||||
|
|
||||||
plugin_etc_overlays(App0) ->
|
|
||||||
App = atom_to_list(App0),
|
|
||||||
ConfFiles = find_conf_files(App),
|
|
||||||
%% NOTE: not filename:join here since relx translates it for windows
|
|
||||||
[{"{{base_dir}}/lib/"++ App ++"/etc/" ++ F, "etc/plugins/" ++ F}
|
|
||||||
|| F <- ConfFiles].
|
|
||||||
|
|
||||||
community_plugin_etc_overlays(App0) ->
|
|
||||||
App = atom_to_list(App0),
|
|
||||||
{"{{base_dir}}/lib/"++ App ++"/etc/" ++ App ++ ".conf", "etc/plugins/" ++ App ++ ".conf"}.
|
|
||||||
|
|
||||||
%% NOTE: for apps fetched as rebar dependency (there is so far no such an app)
|
|
||||||
%% the overlay should be hand-coded but not to rely on build-time wildcards.
|
|
||||||
find_conf_files(App) ->
|
|
||||||
Dir1 = filename:join(["apps", App, "etc"]),
|
|
||||||
filelib:wildcard("*.conf", Dir1) ++
|
|
||||||
case is_enterprise() of
|
|
||||||
true ->
|
|
||||||
Dir2 = filename:join(["lib-ee", App, "etc"]),
|
|
||||||
filelib:wildcard("*.conf", Dir2);
|
|
||||||
false -> []
|
|
||||||
end.
|
|
||||||
|
|
||||||
get_vsn() ->
|
get_vsn() ->
|
||||||
PkgVsn = os:cmd("./pkg-vsn.sh"),
|
PkgVsn = os:cmd("./pkg-vsn.sh"),
|
||||||
|
|
|
@ -7,7 +7,7 @@ cd -P -- "$(dirname -- "$0")/.."
|
||||||
|
|
||||||
find_app() {
|
find_app() {
|
||||||
local appdir="$1"
|
local appdir="$1"
|
||||||
find "${appdir}" -mindepth 1 -maxdepth 1 -type d | grep -vE "emqx_exhook|emqx_exproto|emqx_lwm2m|emqx_sn|emqx_coap|emqx_stomp"
|
find "${appdir}" -mindepth 1 -maxdepth 1 -type d | grep -vE "emqx_exhook|emqx_exproto|emqx_lwm2m|emqx_sn|emqx_coap|emqx_stomp|emqx_dashboard"
|
||||||
}
|
}
|
||||||
|
|
||||||
find_app 'apps'
|
find_app 'apps'
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/usr/bin/env escript
|
||||||
|
|
||||||
|
%% This script reads up emqx.conf and split the sections
|
||||||
|
%% and dump sections to separate files.
|
||||||
|
%% Sections are grouped between CONFIG_SECTION_BGN and
|
||||||
|
%% CONFIG_SECTION_END pairs
|
||||||
|
%%
|
||||||
|
%% NOTE: this feature is so far not used in opensource
|
||||||
|
%% edition due to backward-compatibility reasons.
|
||||||
|
|
||||||
|
-mode(compile).
|
||||||
|
|
||||||
|
main(_) ->
|
||||||
|
BaseConf = "apps/emqx/etc/emqx.conf",
|
||||||
|
{ok, Bin} = file:read_file(BaseConf),
|
||||||
|
Apps = filelib:wildcard("emqx_*", "apps/"),
|
||||||
|
Conf = lists:foldl(fun(App, Acc) ->
|
||||||
|
case lists:member(App, ["emqx_exhook",
|
||||||
|
"emqx_exproto",
|
||||||
|
"emqx_lwm2m",
|
||||||
|
"emqx_sn",
|
||||||
|
"emqx_coap",
|
||||||
|
"emqx_stomp",
|
||||||
|
"emqx_dashboard"]) of
|
||||||
|
true -> Acc;
|
||||||
|
false ->
|
||||||
|
Filename = filename:join([apps, App, "etc", App]) ++ ".conf",
|
||||||
|
case filelib:is_regular(Filename) of
|
||||||
|
true ->
|
||||||
|
{ok, Bin1} = file:read_file(Filename),
|
||||||
|
<<Acc/binary, "\r\n", Bin1/binary>>;
|
||||||
|
false -> Acc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end, Bin, Apps),
|
||||||
|
ok = file:write_file("apps/emqx/etc/emqx.conf.all", Conf).
|
Loading…
Reference in New Issue