Selaa lähdekoodia

refactor: close managment http 8081 (#5564)

DDDHuang 4 vuotta sitten
vanhempi
commit
86231f795d
37 muutettua tiedostoa jossa 88 lisäystä ja 1626 poistoa
  1. 3 3
      .ci/build_packages/tests.sh
  2. 3 3
      .ci/docker-compose-file/haproxy/haproxy.cfg
  3. 1 1
      .github/workflows/build_packages.yaml
  4. 1 1
      .github/workflows/build_slim_packages.yaml
  5. 1 1
      apps/emqx/rebar.config
  6. 1 1
      apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/rebar.config
  7. 1 1
      apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/rebar.config
  8. 22 11
      apps/emqx_authz/test/emqx_authz_api_SUITE.erl
  9. 1 1
      apps/emqx_dashboard/src/emqx_dashboard_schema.erl
  10. 0 1
      apps/emqx_machine/src/emqx_machine_schema.erl
  11. 0 42
      apps/emqx_management/etc/emqx_management.conf
  12. 1 45
      apps/emqx_management/include/emqx_mgmt.hrl
  13. 2 32
      apps/emqx_management/src/emqx_management_schema.erl
  14. 1 3
      apps/emqx_management/src/emqx_mgmt.erl
  15. 0 214
      apps/emqx_management/src/emqx_mgmt_api_apps.erl
  16. 0 47
      apps/emqx_management/src/emqx_mgmt_api_authz.erl
  17. 0 166
      apps/emqx_management/src/emqx_mgmt_api_banned.erl
  18. 0 47
      apps/emqx_management/src/emqx_mgmt_api_brokers.erl
  19. 0 113
      apps/emqx_management/src/emqx_mgmt_api_plugins.erl
  20. 0 247
      apps/emqx_management/src/emqx_mgmt_api_pubsub.erl
  21. 1 3
      apps/emqx_management/src/emqx_mgmt_app.erl
  22. 0 216
      apps/emqx_management/src/emqx_mgmt_auth.erl
  23. 0 50
      apps/emqx_management/src/emqx_mgmt_cli.erl
  24. 0 136
      apps/emqx_management/src/emqx_mgmt_http.erl
  25. 3 12
      apps/emqx_management/test/emqx_mgmt_alarms_api_SUITE.erl
  26. 28 8
      apps/emqx_management/test/emqx_mgmt_api_test_util.erl
  27. 0 110
      apps/emqx_management/test/emqx_mgmt_apps_api_SUITE.erl
  28. 2 13
      apps/emqx_management/test/emqx_mgmt_clients_api_SUITE.erl
  29. 2 11
      apps/emqx_management/test/emqx_mgmt_listeners_api_SUITE.erl
  30. 2 11
      apps/emqx_management/test/emqx_mgmt_metrics_api_SUITE.erl
  31. 2 11
      apps/emqx_management/test/emqx_mgmt_nodes_api_SUITE.erl
  32. 2 13
      apps/emqx_management/test/emqx_mgmt_publish_api_SUITE.erl
  33. 3 12
      apps/emqx_management/test/emqx_mgmt_routes_api_SUITE.erl
  34. 2 11
      apps/emqx_management/test/emqx_mgmt_stats_api_SUITE.erl
  35. 2 13
      apps/emqx_management/test/emqx_mgmt_subscription_api_SUITE.erl
  36. 1 3
      deploy/charts/emqx/templates/StatefulSet.yaml
  37. 0 13
      deploy/charts/emqx/templates/service.yaml

+ 3 - 3
.ci/build_packages/tests.sh

@@ -48,7 +48,7 @@ emqx_test(){
                     exit 1
                 fi
                 IDLE_TIME=0
-                while ! curl http://localhost:8081/api/v5/status >/dev/null 2>&1; do
+                while ! curl http://localhost:18083/api/v5/status >/dev/null 2>&1; do
                     if [ $IDLE_TIME -gt 10 ]
                     then
                         echo "emqx running error"
@@ -139,7 +139,7 @@ EOF
         exit 1
     fi
     IDLE_TIME=0
-    while ! curl http://localhost:8081/api/v5/status >/dev/null 2>&1; do
+    while ! curl http://localhost:18083/api/v5/status >/dev/null 2>&1; do
         if [ $IDLE_TIME -gt 10 ]
         then
             echo "emqx running error"
@@ -168,7 +168,7 @@ EOF
             exit 1
         fi
         IDLE_TIME=0
-        while ! curl http://localhost:8081/api/v5/status >/dev/null 2>&1; do
+        while ! curl http://localhost:18083/api/v5/status >/dev/null 2>&1; do
             if [ $IDLE_TIME -gt 10 ]
             then
                 echo "emqx service error"

+ 3 - 3
.ci/docker-compose-file/haproxy/haproxy.cfg

@@ -33,7 +33,7 @@ defaults
 frontend emqx_mgmt
    mode tcp
    option tcplog
-   bind *:8081
+   bind *:18083
    default_backend emqx_mgmt_back
 
 frontend emqx_dashboard
@@ -45,8 +45,8 @@ frontend emqx_dashboard
 backend emqx_mgmt_back
     mode http
     # balance static-rr
-    server emqx-1 node1.emqx.io:8081
-    server emqx-2 node2.emqx.io:8081
+    server emqx-1 node1.emqx.io:18083
+    server emqx-2 node2.emqx.io:18083
 
 backend emqx_dashboard_back
     mode http

+ 1 - 1
.github/workflows/build_packages.yaml

@@ -197,7 +197,7 @@ jobs:
         ./emqx/bin/emqx start || cat emqx/log/erlang.log.1
         ready='no'
         for i in {1..10}; do
-          if curl -fs 127.0.0.1:8081/api/v5/status > /dev/null; then
+          if curl -fs 127.0.0.1:18083/api/v5/status > /dev/null; then
             ready='yes'
             break
           fi

+ 1 - 1
.github/workflows/build_slim_packages.yaml

@@ -113,7 +113,7 @@ jobs:
         ./emqx/bin/emqx start || cat emqx/log/erlang.log.1
         ready='no'
         for i in {1..10}; do
-          if curl -fs 127.0.0.1:8081/api/v5/status > /dev/null; then
+          if curl -fs 127.0.0.1:18083/api/v5/status > /dev/null; then
             ready='yes'
             break
           fi

+ 1 - 1
apps/emqx/rebar.config

@@ -28,7 +28,7 @@
        [{deps,
            [ meck
            , {bbmustache,"1.10.0"}
-           , {emqx_ct_helpers, {git,"https://github.com/emqx/emqx-ct-helpers", {branch,"hocon"}}}
+           , {emqx_ct_helpers, {git,"https://github.com/emqx/emqx-ct-helpers.git", {branch,"hocon"}}}
            , {emqtt, {git, "https://github.com/emqx/emqtt", {tag, "1.4.2"}}}
            ]},
          {extra_src_dirs, [{"test",[recursive]}]}

+ 1 - 1
apps/emqx/test/emqx_plugins_SUITE_data/emqx_hocon_plugin/rebar.config

@@ -17,7 +17,7 @@
 
 {profiles,
     [{test, [
-        {deps, [ {emqx_ct_helper, {git, "https://github.com/emqx/emqx-ct-helpers", {tag, "v1.1.4"}}}
+        {deps, [{emqx_ct_helpers, {git,"https://github.com/emqx/emqx-ct-helpers.git", {branch,"hocon"}}}
                ]}
     ]}
 ]}.

+ 1 - 1
apps/emqx/test/emqx_plugins_SUITE_data/emqx_mini_plugin/rebar.config

@@ -17,7 +17,7 @@
 
 {profiles,
     [{test, [
-        {deps, [ {emqx_ct_helper, {git, "https://github.com/emqx/emqx-ct-helpers", {tag, "v1.1.4"}}}
+        {deps, [{emqx_ct_helpers, {git,"https://github.com/emqx/emqx-ct-helpers.git", {branch,"hocon"}}}
                ]}
     ]}
 ]}.

+ 22 - 11
apps/emqx_authz/test/emqx_authz_api_SUITE.erl

@@ -33,7 +33,7 @@
                       , auth_header/2
                       ]).
 
--define(HOST, "http://127.0.0.1:8081/").
+-define(HOST, "http://127.0.0.1:18083/").
 -define(API_VERSION, "v5").
 -define(BASE_PATH, "api").
 
@@ -100,11 +100,9 @@ init_per_suite(Config) ->
     meck:expect(emqx_resource, health_check, fun(_) -> ok end),
     meck:expect(emqx_resource, remove, fun(_) -> ok end ),
 
-    ekka_mnesia:start(),
-    emqx_mgmt_auth:mnesia(boot),
-
     ok = emqx_config:init_load(emqx_authz_schema, ?CONF_DEFAULT),
-    ok = emqx_ct_helpers:start_apps([emqx_management, emqx_authz], fun set_special_configs/1),
+
+    ok = emqx_ct_helpers:start_apps([emqx_authz, emqx_dashboard], fun set_special_configs/1),
     {ok, _} = emqx:update_config([authorization, cache, enable], false),
     {ok, _} = emqx:update_config([authorization, no_match], deny),
 
@@ -112,13 +110,20 @@ init_per_suite(Config) ->
 
 end_per_suite(_Config) ->
     {ok, _} = emqx_authz:update(replace, []),
-    emqx_ct_helpers:stop_apps([emqx_resource, emqx_authz, emqx_management]),
+    emqx_ct_helpers:stop_apps([emqx_resource, emqx_authz, emqx_dashboard]),
     meck:unload(emqx_resource),
     ok.
 
-set_special_configs(emqx_management) ->
-    emqx_config:put([emqx_management], #{listeners => [#{protocol => http, port => 8081}],
-        applications =>[#{id => "admin", secret => "public"}]}),
+set_special_configs(emqx_dashboard) ->
+    Config = #{
+        default_username => <<"admin">>,
+        default_password => <<"public">>,
+        listeners => [#{
+            protocol => http,
+            port => 18083
+        }]
+    },
+    emqx_config:put([emqx_dashboard], Config),
     ok;
 set_special_configs(emqx_authz) ->
     emqx_config:put([authorization_rules], #{rules => []}),
@@ -225,8 +230,8 @@ t_move_rule(_) ->
 
 request(Method, Url, Body) ->
     Request = case Body of
-        [] -> {Url, [auth_header("admin", "public")]};
-        _ -> {Url, [auth_header("admin", "public")], "application/json", jsx:encode(Body)}
+        [] -> {Url, [auth_header_()]};
+        _ -> {Url, [auth_header_()], "application/json", jsx:encode(Body)}
     end,
     ct:pal("Method: ~p, Request: ~p", [Method, Request]),
     case httpc:request(Method, Request, [], [{body_format, binary}]) of
@@ -245,3 +250,9 @@ uri(Parts) when is_list(Parts) ->
 
 get_rules(Result) ->
     maps:get(<<"rules">>, jsx:decode(Result), []).
+
+auth_header_() ->
+    Username = <<"admin">>,
+    Password = <<"public">>,
+    {ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
+    {"Authorization", "Bearer " ++ binary_to_list(Token)}.

+ 1 - 1
apps/emqx_dashboard/src/emqx_dashboard_schema.erl

@@ -33,7 +33,7 @@ fields("emqx_dashboard") ->
 
 fields("http") ->
     [ {"protocol", hoconsc:enum([http, https])}
-    , {"port", emqx_schema:t(integer(), undefined, 8081)}
+    , {"port", emqx_schema:t(integer(), undefined, 18083)}
     , {"num_acceptors", emqx_schema:t(integer(), undefined, 4)}
     , {"max_connections", emqx_schema:t(integer(), undefined, 512)}
     , {"backlog", emqx_schema:t(integer(), undefined, 1024)}

+ 0 - 1
apps/emqx_machine/src/emqx_machine_schema.erl

@@ -51,7 +51,6 @@
         , emqx_auto_subscribe_schema
         , emqx_bridge_mqtt_schema
         , emqx_modules_schema
-        , emqx_management_schema
         , emqx_dashboard_schema
         , emqx_gateway_schema
         , emqx_prometheus_schema

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 42
apps/emqx_management/etc/emqx_management.conf


+ 1 - 45
apps/emqx_management/include/emqx_mgmt.hrl

@@ -14,50 +14,6 @@
 %% limitations under the License.
 %%--------------------------------------------------------------------
 
-%% Return Codes
--define(SUCCESS, 0).  %% Success
--define(ERROR1, 101). %% badrpc
--define(ERROR2, 102). %% Unknown error
--define(ERROR3, 103). %% Username or password error
--define(ERROR4, 104). %% Empty username or password
--define(ERROR5, 105). %% User does not exist
--define(ERROR6, 106). %% Admin can not be deleted
--define(ERROR7, 107). %% Missing request parameter
--define(ERROR8, 108). %% Request parameter type error
--define(ERROR9, 109). %% Request parameter is not a json
--define(ERROR10, 110). %% Plugin has been loaded
--define(ERROR11, 111). %% Plugin has been unloaded
--define(ERROR12, 112). %% Client not online
--define(ERROR13, 113). %% User already exist
--define(ERROR14, 114). %% OldPassword error
--define(ERROR15, 115). %% bad topic
-
--define(VERSIONS, ["4.0", "4.1", "4.2", "4.3"]).
-
 -define(MANAGEMENT_SHARD, emqx_management_shard).
 
--define(GENERATE_API_METADATA(MetaData),
-    maps:fold(
-        fun(Method, MethodDef0, NextMetaData) ->
-            Default = #{
-                tags => [?MODULE],
-                security => [#{application => []}]},
-            MethodDef =
-                lists:foldl(
-                    fun(Key, NMethodDef) ->
-                        case maps:is_key(Key, NMethodDef) of
-                            true ->
-                                NMethodDef;
-                            false ->
-                                maps:put(Key, maps:get(Key, Default), NMethodDef)
-                        end
-                    end, MethodDef0, maps:keys(Default)),
-            maps:put(Method, MethodDef, NextMetaData)
-        end,
-        #{}, MetaData)).
-
--define(GENERATE_API(Path, MetaData, Function),
-    {Path, ?GENERATE_API_METADATA(MetaData), Function}).
-
--define(GENERATE_APIS(Apis),
-    [?GENERATE_API(Path, MetaData, Function) || {Path, MetaData, Function} <- Apis]).
+-define(MAX_ROW_LIMIT, 100).

+ 2 - 32
apps/emqx_management/src/emqx_management_schema.erl

@@ -22,36 +22,6 @@
 -export([ structs/0
         , fields/1]).
 
-structs() -> ["emqx_management"].
+structs() -> [].
 
-fields("emqx_management") ->
-    [ {applications, hoconsc:array(hoconsc:ref(?MODULE, "application"))}
-    , {max_row_limit, fun max_row_limit/1}
-    , {listeners, hoconsc:array(hoconsc:union([hoconsc:ref(?MODULE, "http"), hoconsc:ref(?MODULE, "https")]))}
-    ];
-
-fields("application") ->
-    [ {"id", emqx_schema:t(string(), undefined, "admin")}
-    , {"secret", emqx_schema:t(string(), undefined, "public")}
-    ];
-
-
-fields("http") ->
-    [ {"protocol", hoconsc:enum([http, https])}
-    , {"port", emqx_schema:t(integer(), undefined, 8081)}
-    , {"num_acceptors", emqx_schema:t(integer(), undefined, 4)}
-    , {"max_connections", emqx_schema:t(integer(), undefined, 512)}
-    , {"backlog", emqx_schema:t(integer(), undefined, 1024)}
-    , {"send_timeout", emqx_schema:t(emqx_schema:duration(), undefined, "15s")}
-    , {"send_timeout_close", emqx_schema:t(boolean(), undefined, true)}
-    , {"inet6", emqx_schema:t(boolean(), undefined, false)}
-    , {"ipv6_v6only", emqx_schema:t(boolean(), undefined, false)}
-    ];
-
-fields("https") ->
-    emqx_schema:ssl(#{enable => true}) ++ fields("http").
-
-max_row_limit(type) -> integer();
-max_row_limit(default) -> 1000;
-max_row_limit(nullable) -> false;
-max_row_limit(_) -> undefined.
+fields(_) -> [].

+ 1 - 3
apps/emqx_management/src/emqx_mgmt.erl

@@ -114,8 +114,6 @@
 -export([ return/0
         , return/1]).
 
--define(MAX_ROW_LIMIT, 10000).
-
 -define(APP, emqx_management).
 
 %% TODO: remove these function after all api use minirest version 1.X
@@ -590,7 +588,7 @@ check_row_limit([Tab|Tables], Limit) ->
     end.
 
 max_row_limit() ->
-    emqx:get_config([?APP, max_row_limit], ?MAX_ROW_LIMIT).
+    ?MAX_ROW_LIMIT.
 
 table_size(Tab) -> ets:info(Tab, size).
 

+ 0 - 214
apps/emqx_management/src/emqx_mgmt_api_apps.erl

@@ -1,214 +0,0 @@
-%%--------------------------------------------------------------------
-%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%--------------------------------------------------------------------
-
--module(emqx_mgmt_api_apps).
-
--behaviour(minirest_api).
-
--import(emqx_mgmt_util, [ schema/1
-                        , schema/2
-                        , object_schema/1
-                        , object_schema/2
-                        , object_array_schema/2
-                        , error_schema/1
-                        , error_schema/2
-                        , properties/1
-                        ]).
-
--export([api_spec/0]).
-
--export([ apps/2
-        , app/2]).
-
--define(BAD_APP_ID, 'BAD_APP_ID').
--define(APP_ID_NOT_FOUND, <<"{\"code\": \"BAD_APP_ID\", \"reason\": \"App id not found\"}">>).
-
-api_spec() ->
-    {
-        [apps_api(), app_api()],
-        []
-    }.
-
-properties() ->
-    properties([
-        {app_id, string, <<"App ID">>},
-        {secret, string, <<"App Secret">>},
-        {name, string, <<"Dsiplay name">>},
-        {desc, string, <<"App description">>},
-        {status, boolean, <<"Enable or disable">>},
-        {expired, integer, <<"Expired time">>}
-    ]).
-
-%% not export schema
-app_without_secret_schema() ->
-    maps:without([secret], properties()).
-
-apps_api() ->
-    Metadata = #{
-        get => #{
-            description => <<"List EMQ X apps">>,
-            responses => #{
-                <<"200">> =>
-                    object_array_schema(app_without_secret_schema(), <<"All apps">>)
-                }
-        },
-        post => #{
-            description => <<"EMQ X create apps">>,
-            'requestBody' => schema(app),
-            responses => #{
-                <<"200">> =>
-                    schema(app_secret, <<"Create apps">>),
-                <<"400">> =>
-                    error_schema(<<"App ID already exist">>, [?BAD_APP_ID])
-            }
-        }
-    },
-    {"/apps", Metadata, apps}.
-
-app_api() ->
-    Metadata = #{
-        get => #{
-            description => <<"EMQ X apps">>,
-            parameters => [#{
-                name => app_id,
-                in => path,
-                required => true,
-                schema => #{type => string}}],
-            responses => #{
-                <<"404">> =>
-                    error_schema(<<"App id not found">>),
-                <<"200">> =>
-                    object_schema(app_without_secret_schema(), <<"Get App">>)}},
-        delete => #{
-            description => <<"EMQ X apps">>,
-            parameters => [#{
-                name => app_id,
-                in => path,
-                required => true,
-                schema => #{type => string}
-            }],
-            responses => #{
-                <<"200">> => schema(<<"Remove app ok">>)}},
-        put => #{
-            description => <<"EMQ X update apps">>,
-            parameters => [#{
-                name => app_id,
-                in => path,
-                required => true,
-                schema => #{type => string}
-            }],
-            'requestBody' => object_schema(app_without_secret_schema()),
-            responses => #{
-                <<"404">> =>
-                    error_schema(<<"App id not found">>, [?BAD_APP_ID]),
-                <<"200">> =>
-                    object_schema(app_without_secret_schema(), <<"Update ok">>)}}},
-    {"/apps/:app_id", Metadata, app}.
-
-%%%==============================================================================================
-%% parameters trans
-apps(get, _Params) ->
-    list(#{});
-
-apps(post, #{body := Data}) ->
-    Parameters = #{
-        app_id  => maps:get(<<"app_id">>, Data),
-        name    => maps:get(<<"name">>, Data),
-        secret  => maps:get(<<"secret">>, Data),
-        desc    => maps:get(<<"desc">>, Data),
-        status  => maps:get(<<"status">>, Data),
-        expired => maps:get(<<"expired">>, Data, undefined)
-    },
-    create(Parameters).
-
-app(get, #{bindings := #{app_id := AppID}}) ->
-    lookup(#{app_id => AppID});
-
-app(delete, #{bindings := #{app_id := AppID}}) ->
-    delete(#{app_id => AppID});
-
-app(put, #{bindings := #{app_id := AppID}, body := Data}) ->
-    Parameters = #{
-        app_id  => AppID,
-        name    => maps:get(<<"name">>, Data),
-        desc    => maps:get(<<"desc">>, Data),
-        status  => maps:get(<<"status">>, Data),
-        expired => maps:get(<<"expired">>, Data, undefined)
-    },
-    update(Parameters).
-
-
-%%%==============================================================================================
-%% api apply
-list(_) ->
-    {200, [format_without_app_secret(Apps) || Apps <- emqx_mgmt_auth:list_apps()]}.
-
-create(#{app_id := AppID, name := Name, secret := Secret,
-    desc := Desc, status := Status, expired := Expired}) ->
-    case emqx_mgmt_auth:add_app(AppID, Name, Secret, Desc, Status, Expired) of
-        {ok, AppSecret} ->
-            {200, #{secret => AppSecret}};
-        {error, alread_existed} ->
-            Message = list_to_binary(io_lib:format("appid ~p already existed", [AppID])),
-            {400, #{code => 'BAD_APP_ID', message => Message}};
-        {error, Reason} ->
-            Response = #{code => 'UNKNOW_ERROR',
-                message => list_to_binary(io_lib:format("~p", [Reason]))},
-            {500, Response}
-    end.
-
-lookup(#{app_id := AppID}) ->
-    case emqx_mgmt_auth:lookup_app(AppID) of
-        undefined ->
-            {404, ?APP_ID_NOT_FOUND};
-        App ->
-            Response = format_with_app_secret(App),
-            {200, Response}
-    end.
-
-delete(#{app_id := AppID}) ->
-    _ = emqx_mgmt_auth:del_app(AppID),
-    {200}.
-
-update(App = #{app_id := AppID, name := Name, desc := Desc, status := Status, expired := Expired}) ->
-    case emqx_mgmt_auth:update_app(AppID, Name, Desc, Status, Expired) of
-        ok ->
-            {200, App};
-        {error, not_found} ->
-            {404, ?APP_ID_NOT_FOUND};
-        {error, Reason} ->
-            Response = #{code => 'UNKNOW_ERROR', message => list_to_binary(io_lib:format("~p", [Reason]))},
-            {500, Response}
-    end.
-
-%%%==============================================================================================
-%% format
-format_without_app_secret(App) ->
-    format_without([secret], App).
-
-format_with_app_secret(App) ->
-    format_without([], App).
-
-format_without(List, {AppID, AppSecret, Name, Desc, Status, Expired}) ->
-    Data = #{
-        app_id => AppID,
-        secret => AppSecret,
-        name => Name,
-        desc => Desc,
-        status => Status,
-        expired => Expired
-    },
-    maps:without(List, Data).

+ 0 - 47
apps/emqx_management/src/emqx_mgmt_api_authz.erl

@@ -1,47 +0,0 @@
-%%--------------------------------------------------------------------
-%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%--------------------------------------------------------------------
-
--module(emqx_mgmt_api_authz).
-
--include("emqx_mgmt.hrl").
-
--rest_api(#{name   => clean_authz_cache_all,
-            method => 'DELETE',
-            path   => "/authz-cache",
-            func   => clean_all,
-            descr  => "Clean authz cache on all nodes"}).
-
--rest_api(#{name   => clean_authz_cache_node,
-            method => 'DELETE',
-            path   => "nodes/:atom:node/authz-cache",
-            func   => clean_node,
-            descr  => "Clean authz cache on specific node"}).
-
--export([ clean_all/2
-        , clean_node/2
-        ]).
-
-clean_all(_Bindings, _Params) ->
-    case emqx_mgmt:clean_authz_cache_all() of
-      ok -> emqx_mgmt:return();
-      {error, Reason} -> emqx_mgmt:return({error, ?ERROR1, Reason})
-    end.
-
-clean_node(#{node := Node}, _Params) ->
-    case emqx_mgmt:clean_authz_cache_all(Node) of
-      ok -> emqx_mgmt:return();
-      {error, Reason} -> emqx_mgmt:return({error, ?ERROR1, Reason})
-    end.

+ 0 - 166
apps/emqx_management/src/emqx_mgmt_api_banned.erl

@@ -1,166 +0,0 @@
-%%--------------------------------------------------------------------
-%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%--------------------------------------------------------------------
-
--module(emqx_mgmt_api_banned).
-
--include_lib("emqx/include/emqx.hrl").
-
--include("emqx_mgmt.hrl").
-
--rest_api(#{name   => list_banned,
-            method => 'GET',
-            path   => "/banned/",
-            func   => list,
-            descr  => "List banned"}).
-
--rest_api(#{name   => create_banned,
-            method => 'POST',
-            path   => "/banned/",
-            func   => create,
-            descr  => "Create banned"}).
-
--rest_api(#{name   => delete_banned,
-            method => 'DELETE',
-            path   => "/banned/:as/:who",
-            func   => delete,
-            descr  => "Delete banned"}).
-
--export([ list/2
-        , create/2
-        , delete/2
-        ]).
-
-list(_Bindings, Params) ->
-    emqx_mgmt:return({ok, emqx_mgmt_api:paginate(emqx_banned, Params, fun format/1)}).
-
-create(_Bindings, Params) ->
-    case pipeline([fun ensure_required/1,
-                   fun validate_params/1], Params) of
-        {ok, NParams} ->
-            {ok, Banned} = pack_banned(NParams),
-            ok = emqx_mgmt:create_banned(Banned),
-            emqx_mgmt:return({ok, maps:from_list(Params)});
-        {error, Code, Message} ->
-            emqx_mgmt:return({error, Code, Message})
-    end.
-
-delete(#{as := As, who := Who}, _) ->
-    Params = [{<<"who">>, bin(emqx_mgmt_util:urldecode(Who))},
-              {<<"as">>, bin(emqx_mgmt_util:urldecode(As))}],
-    case pipeline([fun ensure_required/1,
-                   fun validate_params/1], Params) of
-        {ok, NParams} ->
-            do_delete(proplists:get_value(<<"as">>, NParams), proplists:get_value(<<"who">>, NParams)),
-            emqx_mgmt:return();
-        {error, Code, Message} ->
-            emqx_mgmt:return({error, Code, Message})
-    end.
-
-pipeline([], Params) ->
-    {ok, Params};
-pipeline([Fun|More], Params) ->
-    case Fun(Params) of
-        {ok, NParams} ->
-            pipeline(More, NParams);
-        {error, Code, Message} ->
-            {error, Code, Message}
-    end.
-
-%% Plugs
-ensure_required(Params) when is_list(Params) ->
-    #{required_params := RequiredParams, message := Msg} = required_params(),
-    AllIncluded = lists:all(fun(Key) ->
-                      lists:keymember(Key, 1, Params)
-                  end, RequiredParams),
-    case AllIncluded of
-        true -> {ok, Params};
-        false ->
-            {error, ?ERROR7, Msg}
-    end.
-
-validate_params(Params) ->
-    #{enum_values := AsEnums, message := Msg} = enum_values(as),
-    case lists:member(proplists:get_value(<<"as">>, Params), AsEnums) of
-        true -> {ok, Params};
-        false ->
-            {error, ?ERROR8, Msg}
-    end.
-
-pack_banned(Params) ->
-    Now = erlang:system_time(second),
-    do_pack_banned(Params, #{by => <<"user">>, at => Now, until => Now + 300}).
-
-do_pack_banned([], #{who := Who,  by := By, reason := Reason, at := At, until := Until}) ->
-    {ok, #banned{who = Who, by = By, reason = Reason, at = At, until = Until}};
-do_pack_banned([{<<"who">>, Who} | Params], Banned) ->
-    case lists:keytake(<<"as">>, 1, Params) of
-        {value, {<<"as">>, <<"peerhost">>}, Params2} ->
-            {ok, IPAddress} = inet:parse_address(str(Who)),
-            do_pack_banned(Params2, Banned#{who => {peerhost, IPAddress}});
-        {value, {<<"as">>, <<"clientid">>}, Params2} ->
-            do_pack_banned(Params2, Banned#{who => {clientid, Who}});
-        {value, {<<"as">>, <<"username">>}, Params2} ->
-            do_pack_banned(Params2, Banned#{who => {username, Who}})
-    end;
-do_pack_banned([P1 = {<<"as">>, _}, P2 | Params], Banned) ->
-    do_pack_banned([P2, P1 | Params], Banned);
-do_pack_banned([{<<"by">>, By} | Params], Banned) ->
-    do_pack_banned(Params, Banned#{by => By});
-do_pack_banned([{<<"reason">>, Reason} | Params], Banned) ->
-    do_pack_banned(Params, Banned#{reason => Reason});
-do_pack_banned([{<<"at">>, At} | Params], Banned) ->
-    do_pack_banned(Params, Banned#{at => At});
-do_pack_banned([{<<"until">>, Until} | Params], Banned) ->
-    do_pack_banned(Params, Banned#{until => Until});
-do_pack_banned([_P | Params], Banned) -> %% ignore other params
-    do_pack_banned(Params, Banned).
-
-do_delete(<<"peerhost">>, Who) ->
-    {ok, IPAddress} = inet:parse_address(str(Who)),
-    emqx_mgmt:delete_banned({peerhost, IPAddress});
-do_delete(<<"username">>, Who) ->
-    emqx_mgmt:delete_banned({username, bin(Who)});
-do_delete(<<"clientid">>, Who) ->
-    emqx_mgmt:delete_banned({clientid, bin(Who)}).
-
-required_params() ->
-    #{required_params => [<<"who">>, <<"as">>],
-      message => <<"missing mandatory params: ['who', 'as']">> }.
-
-enum_values(as) ->
-    #{enum_values => [<<"clientid">>, <<"username">>, <<"peerhost">>],
-      message => <<"value of 'as' must be one of: ['clientid', 'username', 'peerhost']">> }.
-
-%% Internal Functions
-
-format(BannedList) when is_list(BannedList) ->
-    [format(Ban) || Ban <- BannedList];
-format(#banned{who = {As, Who}, by = By, reason = Reason, at = At, until = Until}) ->
-    #{who => case As of
-                 peerhost -> bin(inet:ntoa(Who));
-                 _ -> Who
-             end,
-      as => As, by => By, reason => Reason, at => At, until => Until}.
-
-bin(L) when is_list(L) ->
-    list_to_binary(L);
-bin(B) when is_binary(B) ->
-    B.
-
-str(B) when is_binary(B) ->
-    binary_to_list(B);
-str(L) when is_list(L) ->
-    L.

+ 0 - 47
apps/emqx_management/src/emqx_mgmt_api_brokers.erl

@@ -1,47 +0,0 @@
-%%--------------------------------------------------------------------
-%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%--------------------------------------------------------------------
-
--module(emqx_mgmt_api_brokers).
-
--include("emqx_mgmt.hrl").
-
--rest_api(#{name   => list_brokers,
-            method => 'GET',
-            path   => "/brokers/",
-            func   => list,
-            descr  => "A list of brokers in the cluster"}).
-
--rest_api(#{name   => get_broker,
-            method => 'GET',
-            path   => "/brokers/:atom:node",
-            func   => get,
-            descr  => "Get broker info of a node"}).
-
--export([ list/2
-        , get/2
-        ]).
-
-list(_Bindings, _Params) ->
-    emqx_mgmt:return({ok, [Info || {_Node, Info} <- emqx_mgmt:list_brokers()]}).
-
-get(#{node := Node}, _Params) ->
-    case emqx_mgmt:lookup_broker(Node) of
-        {error, Reason} -> 
-            emqx_mgmt:return({error, ?ERROR2, Reason});
-        Info -> 
-            emqx_mgmt:return({ok, Info})
-    end.
-

+ 0 - 113
apps/emqx_management/src/emqx_mgmt_api_plugins.erl

@@ -1,113 +0,0 @@
-%%--------------------------------------------------------------------
-%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%--------------------------------------------------------------------
-
--module(emqx_mgmt_api_plugins).
-
--include("emqx_mgmt.hrl").
-
--include_lib("emqx/include/emqx.hrl").
-
--rest_api(#{name   => list_all_plugins,
-            method => 'GET',
-            path   => "/plugins/",
-            func   => list,
-            descr  => "List all plugins in the cluster"}).
-
--rest_api(#{name   => list_node_plugins,
-            method => 'GET',
-            path   => "/nodes/:atom:node/plugins/",
-            func   => list,
-            descr  => "List all plugins on a node"}).
-
--rest_api(#{name   => load_node_plugin,
-            method => 'PUT',
-            path   => "/nodes/:atom:node/plugins/:atom:plugin/load",
-            func   => load,
-            descr  => "Load a plugin"}).
-
--rest_api(#{name   => unload_node_plugin,
-            method => 'PUT',
-            path   => "/nodes/:atom:node/plugins/:atom:plugin/unload",
-            func   => unload,
-            descr  => "Unload a plugin"}).
-
--rest_api(#{name   => reload_node_plugin,
-            method => 'PUT',
-            path   => "/nodes/:atom:node/plugins/:atom:plugin/reload",
-            func   => reload,
-            descr  => "Reload a plugin"}).
-
--rest_api(#{name   => unload_plugin,
-            method => 'PUT',
-            path   => "/plugins/:atom:plugin/unload",
-            func   => unload,
-            descr  => "Unload a plugin in the cluster"}).
-
--rest_api(#{name   => reload_plugin,
-            method => 'PUT',
-            path   => "/plugins/:atom:plugin/reload",
-            func   => reload,
-            descr  => "Reload a plugin in the cluster"}).
-
--export([ list/2
-        , load/2
-        , unload/2
-        , reload/2
-        ]).
-
-list(#{node := Node}, _Params) ->
-    emqx_mgmt:return({ok, [format(Plugin) || Plugin <- emqx_mgmt:list_plugins(Node)]});
-
-list(_Bindings, _Params) ->
-    emqx_mgmt:return({ok, [format({Node, Plugins}) || {Node, Plugins} <- emqx_mgmt:list_plugins()]}).
-
-load(#{node := Node, plugin := Plugin}, _Params) ->
-    emqx_mgmt:return(emqx_mgmt:load_plugin(Node, Plugin)).
-
-unload(#{node := Node, plugin := Plugin}, _Params) ->
-    emqx_mgmt:return(emqx_mgmt:unload_plugin(Node, Plugin));
-
-unload(#{plugin := Plugin}, _Params) ->
-    Results = [emqx_mgmt:unload_plugin(Node, Plugin) || {Node, _Info} <- emqx_mgmt:list_nodes()],
-    case lists:filter(fun(Item) -> Item =/= ok end, Results) of
-        [] ->
-            emqx_mgmt:return(ok);
-        Errors ->
-            emqx_mgmt:return(lists:last(Errors))
-    end.
-
-reload(#{node := Node, plugin := Plugin}, _Params) ->
-    emqx_mgmt:return(emqx_mgmt:reload_plugin(Node, Plugin));
-
-reload(#{plugin := Plugin}, _Params) ->
-    Results = [emqx_mgmt:reload_plugin(Node, Plugin) || {Node, _Info} <- emqx_mgmt:list_nodes()],
-    case lists:filter(fun(Item) -> Item =/= ok end, Results) of
-        [] ->
-            emqx_mgmt:return(ok);
-        Errors ->
-            emqx_mgmt:return(lists:last(Errors))
-    end.
-
-format({Node, Plugins}) ->
-    #{node => Node, plugins => [format(Plugin) || Plugin <- Plugins]};
-
-format(#plugin{name = Name,
-               descr = Descr,
-               active = Active}) ->
-    #{name => Name,
-      description => iolist_to_binary(Descr),
-      active => Active}.
-

+ 0 - 247
apps/emqx_management/src/emqx_mgmt_api_pubsub.erl

@@ -1,247 +0,0 @@
-%%--------------------------------------------------------------------
-%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%--------------------------------------------------------------------
-
--module(emqx_mgmt_api_pubsub).
-
--include_lib("emqx/include/emqx.hrl").
--include_lib("emqx/include/emqx_mqtt.hrl").
--include("emqx_mgmt.hrl").
-
--rest_api(#{name   => mqtt_subscribe,
-            method => 'POST',
-            path   => "/mqtt/subscribe",
-            func   => subscribe,
-            descr  => "Subscribe a topic"}).
-
--rest_api(#{name   => mqtt_publish,
-            method => 'POST',
-            path   => "/mqtt/publish",
-            func   => publish,
-            descr  => "Publish a MQTT message"}).
-
--rest_api(#{name   => mqtt_unsubscribe,
-            method => 'POST',
-            path   => "/mqtt/unsubscribe",
-            func   => unsubscribe,
-            descr  => "Unsubscribe a topic"}).
-
--rest_api(#{name   => mqtt_subscribe_batch,
-            method => 'POST',
-            path   => "/mqtt/subscribe_batch",
-            func   => subscribe_batch,
-            descr  => "Batch subscribes topics"}).
-
--rest_api(#{name   => mqtt_publish_batch,
-            method => 'POST',
-            path   => "/mqtt/publish_batch",
-            func   => publish_batch,
-            descr  => "Batch publish MQTT messages"}).
-
--rest_api(#{name   => mqtt_unsubscribe_batch,
-            method => 'POST',
-            path   => "/mqtt/unsubscribe_batch",
-            func   => unsubscribe_batch,
-            descr  => "Batch unsubscribes topics"}).
-
--export([ subscribe/2
-        , publish/2
-        , unsubscribe/2
-        , subscribe_batch/2
-        , publish_batch/2
-        , unsubscribe_batch/2
-        ]).
-
-subscribe(_Bindings, Params) ->
-    logger:debug("API subscribe Params:~p", [Params]),
-    {ClientId, Topic, QoS} = parse_subscribe_params(Params),
-    emqx_mgmt:return(do_subscribe(ClientId, Topic, QoS)).
-
-publish(_Bindings, Params) ->
-    logger:debug("API publish Params:~p", [Params]),
-    {ClientId, Topic, Qos, Retain, Payload} = parse_publish_params(Params),
-    case do_publish(ClientId, Topic, Qos, Retain, Payload) of
-        {ok, MsgIds} ->
-            case proplists:get_value(<<"return">>, Params, undefined) of
-                undefined -> emqx_mgmt:return(ok);
-                _Val ->
-                    case proplists:get_value(<<"topics">>, Params, undefined) of
-                        undefined -> emqx_mgmt:return({ok, #{msgid => lists:last(MsgIds)}});
-                        _ -> emqx_mgmt:return({ok, #{msgids => MsgIds}})
-                    end
-            end;
-        Result ->
-            emqx_mgmt:return(Result)
-    end.
-
-unsubscribe(_Bindings, Params) ->
-    logger:debug("API unsubscribe Params:~p", [Params]),
-    {ClientId, Topic} = parse_unsubscribe_params(Params),
-    emqx_mgmt:return(do_unsubscribe(ClientId, Topic)).
-
-subscribe_batch(_Bindings, Params) ->
-    logger:debug("API subscribe batch Params:~p", [Params]),
-    emqx_mgmt:return({ok, loop_subscribe(Params)}).
-
-publish_batch(_Bindings, Params) ->
-    logger:debug("API publish batch Params:~p", [Params]),
-    emqx_mgmt:return({ok, loop_publish(Params)}).
-
-unsubscribe_batch(_Bindings, Params) ->
-    logger:debug("API unsubscribe batch Params:~p", [Params]),
-    emqx_mgmt:return({ok, loop_unsubscribe(Params)}).
-
-loop_subscribe(Params) ->
-    loop_subscribe(Params, []).
-loop_subscribe([], Result) ->
-    lists:reverse(Result);
-loop_subscribe([Params | ParamsN], Acc) ->
-    {ClientId, Topic, QoS} = parse_subscribe_params(Params),
-    Code = case do_subscribe(ClientId, Topic, QoS) of
-        ok -> 0;
-        {_, Code0, _Reason} -> Code0
-    end,
-    Result = #{clientid => ClientId,
-               topic => resp_topic(proplists:get_value(<<"topic">>, Params), proplists:get_value(<<"topics">>, Params, <<"">>)),
-               code => Code},
-    loop_subscribe(ParamsN, [Result | Acc]).
-
-loop_publish(Params) ->
-    loop_publish(Params, []).
-loop_publish([], Result) ->
-    lists:reverse(Result);
-loop_publish([Params | ParamsN], Acc) ->
-    {ClientId, Topic, Qos, Retain, Payload} = parse_publish_params(Params),
-    Code = case do_publish(ClientId, Topic, Qos, Retain, Payload) of
-        {ok, _} -> 0;
-        {_, Code0, _} -> Code0
-    end,
-    Result = #{topic => resp_topic(proplists:get_value(<<"topic">>, Params), proplists:get_value(<<"topics">>, Params, <<"">>)),
-               code => Code},
-    loop_publish(ParamsN, [Result | Acc]).
-
-loop_unsubscribe(Params) ->
-    loop_unsubscribe(Params, []).
-loop_unsubscribe([], Result) ->
-    lists:reverse(Result);
-loop_unsubscribe([Params | ParamsN], Acc) ->
-    {ClientId, Topic} = parse_unsubscribe_params(Params),
-    Code = case do_unsubscribe(ClientId, Topic) of
-        ok -> 0;
-        {_, Code0, _} -> Code0
-    end,
-    Result = #{clientid => ClientId,
-               topic => resp_topic(proplists:get_value(<<"topic">>, Params), proplists:get_value(<<"topics">>, Params, <<"">>)),
-               code => Code},
-    loop_unsubscribe(ParamsN, [Result | Acc]).
-
-do_subscribe(_ClientId, [], _QoS) ->
-    {ok, ?ERROR15, bad_topic};
-do_subscribe(ClientId, Topics, QoS) ->
-    TopicTable = parse_topic_filters(Topics, QoS),
-    case emqx_mgmt:subscribe(ClientId, TopicTable) of
-        {error, Reason} -> {ok, ?ERROR12, Reason};
-        _ -> ok
-    end.
-
-do_publish(_ClientId, [], _Qos, _Retain, _Payload) ->
-    {ok, ?ERROR15, bad_topic};
-do_publish(ClientId, Topics, Qos, Retain, Payload) ->
-    MsgIds = lists:map(fun(Topic) ->
-        Msg = emqx_message:make(ClientId, Qos, Topic, Payload),
-        _ = emqx_mgmt:publish(Msg#message{flags = #{retain => Retain}}),
-        emqx_guid:to_hexstr(Msg#message.id)
-    end, Topics),
-    {ok, MsgIds}.
-
-do_unsubscribe(ClientId, Topic) ->
-    case validate_by_filter(Topic) of
-        true ->
-            case emqx_mgmt:unsubscribe(ClientId, Topic) of
-                {error, Reason} -> {ok, ?ERROR12, Reason};
-                _ -> ok
-            end;
-        false ->
-            {ok, ?ERROR15, bad_topic}
-    end.
-
-parse_subscribe_params(Params) ->
-    ClientId = proplists:get_value(<<"clientid">>, Params),
-    Topics   = topics(filter, proplists:get_value(<<"topic">>, Params), proplists:get_value(<<"topics">>, Params, <<"">>)),
-    QoS      = proplists:get_value(<<"qos">>, Params, 0),
-    {ClientId, Topics, QoS}.
-
-parse_publish_params(Params) ->
-    Topics   = topics(name, proplists:get_value(<<"topic">>, Params), proplists:get_value(<<"topics">>, Params, <<"">>)),
-    ClientId = proplists:get_value(<<"clientid">>, Params),
-    Payload  = decode_payload(proplists:get_value(<<"payload">>, Params, <<>>),
-                              proplists:get_value(<<"encoding">>, Params, <<"plain">>)),
-    Qos      = proplists:get_value(<<"qos">>, Params, 0),
-    Retain   = proplists:get_value(<<"retain">>, Params, false),
-    Payload1 = maybe_maps_to_binary(Payload),
-    {ClientId, Topics, Qos, Retain, Payload1}.
-
-parse_unsubscribe_params(Params) ->
-    ClientId = proplists:get_value(<<"clientid">>, Params),
-    Topic    = proplists:get_value(<<"topic">>, Params),
-    {ClientId, Topic}.
-
-topics(Type, undefined, Topics0) ->
-    Topics = binary:split(Topics0, <<",">>, [global]),
-    case Type of
-        name -> lists:filter(fun(T) -> validate_by_name(T) end, Topics);
-        filter -> lists:filter(fun(T) -> validate_by_filter(T) end, Topics)
-    end;
-
-topics(Type, Topic, _) ->
-    topics(Type, undefined, Topic).
-
-%%TODO:
-% validate(qos, Qos) ->
-%    (Qos >= ?QOS_0) and (Qos =< ?QOS_2).
-
-validate_by_filter(Topic) ->
-    validate_topic({filter, Topic}).
-
-validate_by_name(Topic) ->
-    validate_topic({name, Topic}).
-
-validate_topic({Type, Topic}) ->
-    try emqx_topic:validate({Type, Topic}) of
-        true -> true
-    catch
-        error:_Reason -> false
-    end.
-
-parse_topic_filters(Topics, Qos) ->
-    [begin
-         {Topic, Opts} = emqx_topic:parse(Topic0),
-         {Topic, Opts#{qos => Qos}}
-     end || Topic0 <- Topics].
-
-resp_topic(undefined, Topics) -> Topics;
-resp_topic(Topic, _) -> Topic.
-
-decode_payload(Payload, <<"base64">>) -> base64:decode(Payload);
-decode_payload(Payload, _) -> Payload.
-
-maybe_maps_to_binary(Payload) when is_binary(Payload) -> Payload;
-maybe_maps_to_binary(Payload) ->
-  try
-      emqx_json:encode(Payload)
-  catch
-      _C : _E : S ->
-         error({encode_payload_fail, S})
-  end.

+ 1 - 3
apps/emqx_management/src/emqx_mgmt_app.erl

@@ -29,10 +29,8 @@
 start(_Type, _Args) ->
     {ok, Sup} = emqx_mgmt_sup:start_link(),
     ok = ekka_rlog:wait_for_shards([?MANAGEMENT_SHARD], infinity),
-    _ = emqx_mgmt_auth:add_default_app(),
-    emqx_mgmt_http:start_listeners(),
     emqx_mgmt_cli:load(),
     {ok, Sup}.
 
 stop(_State) ->
-    emqx_mgmt_http:stop_listeners().
+    ok.

+ 0 - 216
apps/emqx_management/src/emqx_mgmt_auth.erl

@@ -1,216 +0,0 @@
-%%--------------------------------------------------------------------
-%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%--------------------------------------------------------------------
-
--module(emqx_mgmt_auth).
-
-%% Mnesia Bootstrap
--export([mnesia/1]).
--boot_mnesia({mnesia, [boot]}).
--copy_mnesia({mnesia, [copy]}).
-
-%% APP Management API
--export([ add_default_app/0
-        , add_app/2
-        , add_app/5
-        , add_app/6
-        , force_add_app/6
-        , lookup_app/1
-        , get_appsecret/1
-        , update_app/2
-        , update_app/5
-        , del_app/1
-        , list_apps/0
-        ]).
-
-%% APP Auth/Authorization API
--export([is_authorized/2]).
-
--define(APP, emqx_management).
-
--record(mqtt_app, {id, secret, name, desc, status, expired}).
-
--type(appid() :: binary()).
-
--type(appsecret() :: binary()).
-
--include("emqx_mgmt.hrl").
-
-%%--------------------------------------------------------------------
-%% Mnesia Bootstrap
-%%--------------------------------------------------------------------
-
-mnesia(boot) ->
-    ok = ekka_mnesia:create_table(mqtt_app, [
-                {rlog_shard, ?MANAGEMENT_SHARD},
-                {disc_copies, [node()]},
-                {record_name, mqtt_app},
-                {attributes, record_info(fields, mqtt_app)}]);
-
-mnesia(copy) ->
-    ok = ekka_mnesia:copy_table(mqtt_app, disc_copies).
-
-%%--------------------------------------------------------------------
-%% Manage Apps
-%%--------------------------------------------------------------------
--spec(add_default_app() -> list()).
-add_default_app() ->
-    Apps = emqx:get_config([?APP, applications], []),
-    [ begin
-          case {AppId, AppSecret} of
-              {undefined, _} -> ok;
-              {_, undefined} -> ok;
-              {_, _} ->
-                  AppId1 = to_binary(AppId),
-                  AppSecret1 = to_binary(AppSecret),
-                  add_app(AppId1, <<"Default">>, AppSecret1, <<"Application user">>, true, undefined)
-          end
-      end
-        || #{id := AppId, secret := AppSecret} <- Apps].
-
--spec(add_app(appid(), binary()) -> {ok, appsecret()} | {error, term()}).
-add_app(AppId, Name) when is_binary(AppId) ->
-    add_app(AppId, Name, <<"Application user">>, true, undefined).
-
--spec(add_app(appid(), binary(), binary(), boolean(), integer() | undefined)
-      -> {ok, appsecret()}
-       | {error, term()}).
-add_app(AppId, Name, Desc, Status, Expired) when is_binary(AppId) ->
-    add_app(AppId, Name, undefined, Desc, Status, Expired).
-
--spec(add_app(appid(), binary(), binary() | undefined, binary(), boolean(), integer() | undefined)
-      -> {ok, appsecret()}
-       | {error, term()}).
-add_app(AppId, Name, Secret, Desc, Status, Expired) when is_binary(AppId) ->
-    Secret1 = generate_appsecret_if_need(Secret),
-    App = #mqtt_app{id = AppId,
-                    secret = Secret1,
-                    name = Name,
-                    desc = Desc,
-                    status = Status,
-                    expired = Expired},
-    AddFun = fun() ->
-                 case mnesia:wread({mqtt_app, AppId}) of
-                     [] -> mnesia:write(App);
-                     _  -> mnesia:abort(alread_existed)
-                 end
-             end,
-    case ekka_mnesia:transaction(?MANAGEMENT_SHARD, AddFun) of
-        {atomic, ok} -> {ok, Secret1};
-        {aborted, Reason} -> {error, Reason}
-    end.
-
-force_add_app(AppId, Name, Secret, Desc, Status, Expired) ->
-    AddFun = fun() ->
-                 mnesia:write(#mqtt_app{id = AppId,
-                                        secret = Secret,
-                                        name = Name,
-                                        desc = Desc,
-                                        status = Status,
-                                        expired = Expired})
-             end,
-    case ekka_mnesia:transaction(?MANAGEMENT_SHARD, AddFun) of
-        {atomic, ok} -> ok;
-        {aborted, Reason} -> {error, Reason}
-    end.
-
--spec(generate_appsecret_if_need(binary() | undefined) -> binary()).
-generate_appsecret_if_need(InSecrt) when is_binary(InSecrt), byte_size(InSecrt) > 0 ->
-    InSecrt;
-generate_appsecret_if_need(_) ->
-    emqx_guid:to_base62(emqx_guid:gen()).
-
--spec(get_appsecret(appid()) -> {appsecret() | undefined}).
-get_appsecret(AppId) when is_binary(AppId) ->
-    case mnesia:dirty_read(mqtt_app, AppId) of
-        [#mqtt_app{secret = Secret}] -> Secret;
-        [] -> undefined
-    end.
-
--spec(lookup_app(appid()) -> undefined | {appid(), appsecret(), binary(), binary(), boolean(), integer() | undefined}).
-lookup_app(AppId) when is_binary(AppId) ->
-    case mnesia:dirty_read(mqtt_app, AppId) of
-        [#mqtt_app{id = AppId,
-                   secret = AppSecret,
-                   name = Name,
-                   desc = Desc,
-                   status = Status,
-                   expired = Expired}] -> {AppId, AppSecret, Name, Desc, Status, Expired};
-        [] -> undefined
-    end.
-
--spec(update_app(appid(), boolean()) -> ok | {error, term()}).
-update_app(AppId, Status) ->
-    case mnesia:dirty_read(mqtt_app, AppId) of
-        [App = #mqtt_app{}] ->
-            Fun = fun() -> mnesia:write(App#mqtt_app{status = Status}) end,
-            case ekka_mnesia:transaction(?MANAGEMENT_SHARD, Fun) of
-                {atomic, ok} -> ok;
-                {aborted, Reason} -> {error, Reason}
-            end;
-        [] ->
-            {error, not_found}
-    end.
-
--spec(update_app(appid(), binary(), binary(), boolean(), integer() | undefined) -> ok | {error, term()}).
-update_app(AppId, Name, Desc, Status, Expired) ->
-    case mnesia:dirty_read(mqtt_app, AppId) of
-        [App = #mqtt_app{}] ->
-            case ekka_mnesia:transaction(
-                   ?MANAGEMENT_SHARD,
-                   fun() -> mnesia:write(App#mqtt_app{name = Name,
-                                                      desc = Desc,
-                                                      status = Status,
-                                                      expired = Expired}) end) of
-                {atomic, ok} -> ok;
-                {aborted, Reason} -> {error, Reason}
-            end;
-        [] ->
-            {error, not_found}
-    end.
-
--spec(del_app(appid()) -> ok | {error, term()}).
-del_app(AppId) when is_binary(AppId) ->
-    case ekka_mnesia:transaction(?MANAGEMENT_SHARD, fun mnesia:delete/1, [{mqtt_app, AppId}]) of
-        {atomic, Ok} -> Ok;
-        {aborted, Reason} -> {error, Reason}
-    end.
-
--spec(list_apps() -> [{appid(), appsecret(), binary(), binary(), boolean(), integer() | undefined}]).
-list_apps() ->
-    [ {AppId, AppSecret, Name, Desc, Status, Expired} || #mqtt_app{id = AppId,
-                                                                   secret = AppSecret,
-                                                                   name = Name,
-                                                                   desc = Desc,
-                                                                   status = Status,
-                                                                   expired = Expired} <- ets:tab2list(mqtt_app) ].
-%%--------------------------------------------------------------------
-%% Authenticate App
-%%--------------------------------------------------------------------
-
--spec(is_authorized(appid(), appsecret()) -> boolean()).
-is_authorized(AppId, AppSecret) ->
-    case lookup_app(AppId) of
-        {_, AppSecret1, _, _, Status, Expired} ->
-            Status andalso is_expired(Expired) andalso AppSecret =:= AppSecret1;
-        _ ->
-            false
-    end.
-
-is_expired(undefined) -> true;
-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.

+ 0 - 50
apps/emqx_management/src/emqx_mgmt_cli.erl

@@ -37,7 +37,6 @@
         , mnesia/1
         , trace/1
         , log/1
-        , mgmt/1
         , authz/1
         ]).
 
@@ -61,55 +60,6 @@ load() ->
 is_cmd(Fun) ->
     not lists:member(Fun, [init, load, module_info]).
 
-mgmt(["insert", AppId, Name]) ->
-    case emqx_mgmt_auth:add_app(list_to_binary(AppId), list_to_binary(Name)) of
-        {ok, Secret} ->
-            emqx_ctl:print("AppSecret: ~s~n", [Secret]);
-        {error, already_existed} ->
-            emqx_ctl:print("Error: already existed~n");
-        {error, Reason} ->
-            emqx_ctl:print("Error: ~p~n", [Reason])
-    end;
-
-mgmt(["lookup", AppId]) ->
-    case emqx_mgmt_auth:lookup_app(list_to_binary(AppId)) of
-        {AppId1, AppSecret, Name, Desc, Status, Expired} ->
-            emqx_ctl:print("app_id: ~s~nsecret: ~s~nname: ~s~ndesc: ~s~nstatus: ~s~nexpired: ~p~n",
-                           [AppId1, AppSecret, Name, Desc, Status, Expired]);
-        undefined ->
-            emqx_ctl:print("Not Found.~n")
-    end;
-
-mgmt(["update", AppId, Status]) ->
-    case emqx_mgmt_auth:update_app(list_to_binary(AppId), list_to_atom(Status)) of
-        ok ->
-            emqx_ctl:print("update successfully.~n");
-        {error, Reason} ->
-            emqx_ctl:print("Error: ~p~n", [Reason])
-    end;
-
-mgmt(["delete", AppId]) ->
-    case emqx_mgmt_auth:del_app(list_to_binary(AppId)) of
-        ok -> emqx_ctl:print("ok~n");
-        {error, not_found} ->
-            emqx_ctl:print("Error: app not found~n");
-        {error, Reason} ->
-            emqx_ctl:print("Error: ~p~n", [Reason])
-    end;
-
-mgmt(["list"]) ->
-    lists:foreach(fun({AppId, AppSecret, Name, Desc, Status, Expired}) ->
-                      emqx_ctl:print("app_id: ~s, secret: ~s, name: ~s, desc: ~s, status: ~s, expired: ~p~n",
-                                    [AppId, AppSecret, Name, Desc, Status, Expired])
-                  end, emqx_mgmt_auth:list_apps());
-
-mgmt(_) ->
-    emqx_ctl:usage([{"mgmt list",                    "List Applications"},
-                    {"mgmt insert <AppId> <Name>",   "Add Application of REST API"},
-                    {"mgmt update <AppId> <status>", "Update Application of REST API"},
-                    {"mgmt lookup <AppId>",          "Get Application of REST API"},
-                    {"mgmt delete <AppId>",          "Delete Application of REST API"}]).
-
 %%--------------------------------------------------------------------
 %% @doc Node status
 

+ 0 - 136
apps/emqx_management/src/emqx_mgmt_http.erl

@@ -1,136 +0,0 @@
-%%--------------------------------------------------------------------
-%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%--------------------------------------------------------------------
--module(emqx_mgmt_http).
-
--export([ start_listeners/0
-        , stop_listeners/0
-        , start_listener/1
-        , stop_listener/1]).
-
-%% Authorization
--export([authorize_appid/1]).
-
--include_lib("emqx/include/emqx.hrl").
--include_lib("emqx/include/logger.hrl").
-
--define(APP, emqx_management).
-
--define(BASE_PATH, "/api/v5").
-
-%%--------------------------------------------------------------------
-%% Start/Stop Listeners
-%%--------------------------------------------------------------------
-
-start_listeners() ->
-    lists:foreach(fun start_listener/1, listeners()).
-
-stop_listeners() ->
-    lists:foreach(fun stop_listener/1, listeners()).
-
-start_listener({Proto, Port, Options}) ->
-    {ok, _} = application:ensure_all_started(minirest),
-    Authorization = {?MODULE, authorize_appid},
-    RanchOptions = ranch_opts(Port, Options),
-    GlobalSpec = #{
-        openapi => "3.0.0",
-        info => #{title => "EMQ X API", version => "5.0.0"},
-        servers => [#{url => ?BASE_PATH}],
-        tags => [#{
-            name => configs,
-            description => <<"The query string parameter `conf_path` is of jq format.">>,
-            externalDocs => #{
-                description => "Find out more about the path syntax in jq",
-                url => "https://stedolan.github.io/jq/manual/"
-            }
-        }],
-        components => #{
-            schemas => #{},
-            securitySchemes => #{
-                application => #{
-                    type => apiKey,
-                    name => "authorization",
-                    in => header}}}},
-    Minirest = #{
-        protocol => Proto,
-        base_path => ?BASE_PATH,
-        modules => api_modules(),
-        authorization => Authorization,
-        security => [#{application => []}],
-        swagger_global_spec => GlobalSpec},
-    MinirestOptions = maps:merge(Minirest, RanchOptions),
-    {ok, _} = minirest:start(listener_name(Proto), MinirestOptions),
-    ?ULOG("Start ~p listener on ~p successfully.~n", [listener_name(Proto), Port]).
-
-ranch_opts(Port, Options0) ->
-    Options = lists:foldl(
-                  fun
-                      ({K, _V}, Acc) when K =:= max_connections orelse K =:= num_acceptors -> Acc;
-                      ({inet6, true}, Acc) -> [inet6 | Acc];
-                      ({inet6, false}, Acc) -> Acc;
-                      ({ipv6_v6only, true}, Acc) -> [{ipv6_v6only, true} | Acc];
-                      ({ipv6_v6only, false}, Acc) -> Acc;
-                      ({K, V}, Acc)->
-                          [{K, V} | Acc]
-                  end, [], Options0),
-    maps:from_list([{port, Port} | Options]).
-
-stop_listener({Proto, Port, _}) ->
-    ?ULOG("Stop http:management listener on ~s successfully.~n",[format(Port)]),
-    minirest:stop(listener_name(Proto)).
-
-listeners() ->
-    [{Protocol, Port, maps:to_list(maps:without([protocol, port], Map))}
-        || Map = #{protocol := Protocol,port := Port}
-        <- emqx:get_config([emqx_management, listeners], [])].
-
-listener_name(Proto) ->
-    list_to_atom(atom_to_list(Proto) ++ ":management").
-
-authorize_appid(Req) ->
-    case cowboy_req:parse_header(<<"authorization">>, Req) of
-        {basic, AppId, AppSecret} ->
-            case emqx_mgmt_auth:is_authorized(AppId, AppSecret) of
-                true -> ok;
-                false -> {401, #{<<"WWW-Authenticate">> => <<"Basic Realm=\"minirest-server\"">>}, <<"UNAUTHORIZED">>}
-            end;
-        _ ->
-            {401, #{<<"WWW-Authenticate">> => <<"Basic Realm=\"minirest-server\"">>}, <<"UNAUTHORIZED">>}
-    end.
-
-format(Port) when is_integer(Port) ->
-    io_lib:format("0.0.0.0:~w", [Port]);
-format({Addr, Port}) when is_list(Addr) ->
-    io_lib:format("~s:~w", [Addr, Port]);
-format({Addr, Port}) when is_tuple(Addr) ->
-    io_lib:format("~s:~w", [inet:ntoa(Addr), Port]).
-
-apps() ->
-    Apps = [App || {App, _, _} <- application:loaded_applications(), App =/= emqx_dashboard],
-    lists:filter(fun(App) ->
-        case re:run(atom_to_list(App), "^emqx") of
-            {match,[{0,4}]} -> true;
-            _ -> false
-        end
-    end, Apps).
-
--ifdef(TEST).
-api_modules() ->
-    minirest_api:find_api_modules(apps()).
--else.
-api_modules() ->
-    minirest_api:find_api_modules(apps()) -- [emqx_mgmt_api_apps].
--endif.
-

+ 3 - 12
apps/emqx_management/test/emqx_mgmt_alarms_api_SUITE.erl

@@ -25,23 +25,14 @@
 -define(DE_ACT_ALARM, test_de_act_alarm).
 
 all() ->
-    [t_alarms_api, t_delete_alarms_api].
+    emqx_ct:all(?MODULE).
 
 init_per_suite(Config) ->
-    ekka_mnesia:start(),
-    emqx_mgmt_auth:mnesia(boot),
-    emqx_ct_helpers:start_apps([emqx_management], fun set_special_configs/1),
+    emqx_mgmt_api_test_util:init_suite(),
     Config.
 
 end_per_suite(_) ->
-    emqx_ct_helpers:stop_apps([emqx_management]).
-
-set_special_configs(emqx_management) ->
-    emqx_config:put([emqx_management], #{listeners => [#{protocol => http, port => 8081}],
-        applications =>[#{id => "admin", secret => "public"}]}),
-    ok;
-set_special_configs(_App) ->
-    ok.
+    emqx_mgmt_api_test_util:end_suite().
 
 t_alarms_api(_) ->
     ok = emqx_alarm:activate(?ACT_ALARM),

+ 28 - 8
apps/emqx_management/test/emqx_mgmt_api_test_util.erl

@@ -17,9 +17,32 @@
 -compile(export_all).
 -compile(nowarn_export_all).
 
--define(SERVER, "http://127.0.0.1:8081").
+-define(SERVER, "http://127.0.0.1:18083").
 -define(BASE_PATH, "/api/v5").
 
+init_suite() ->
+    ekka_mnesia:start(),
+    application:load(emqx_management),
+    emqx_ct_helpers:start_apps([emqx_dashboard], fun set_special_configs/1).
+
+end_suite() ->
+    application:unload(emqx_management),
+    emqx_ct_helpers:stop_apps([emqx_dashboard]).
+
+set_special_configs(emqx_dashboard) ->
+    Config = #{
+        default_username => <<"admin">>,
+        default_password => <<"public">>,
+        listeners => [#{
+            protocol => http,
+            port => 18083
+        }]
+    },
+    emqx_config:put([emqx_dashboard], Config),
+    ok;
+set_special_configs(_App) ->
+    ok.
+
 request_api(Method, Url) ->
     request_api(Method, Url, [], auth_header_(), []).
 
@@ -55,13 +78,10 @@ do_request_api(Method, Request)->
     end.
 
 auth_header_() ->
-    AppId = <<"admin">>,
-    AppSecret = <<"public">>,
-    auth_header_(binary_to_list(AppId), binary_to_list(AppSecret)).
-
-auth_header_(User, Pass) ->
-    Encoded = base64:encode_to_string(lists:append([User,":",Pass])),
-    {"Authorization","Basic " ++ Encoded}.
+    Username = <<"admin">>,
+    Password = <<"public">>,
+    {ok, Token} = emqx_dashboard_admin:sign_token(Username, Password),
+    {"Authorization", "Bearer " ++ binary_to_list(Token)}.
 
 api_path(Parts)->
     ?SERVER ++ filename:join([?BASE_PATH | Parts]).

+ 0 - 110
apps/emqx_management/test/emqx_mgmt_apps_api_SUITE.erl

@@ -1,110 +0,0 @@
-%%--------------------------------------------------------------------
-%% Copyright (c) 2020-2021 EMQ Technologies Co., Ltd. All Rights Reserved.
-%%
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%%
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%--------------------------------------------------------------------
--module(emqx_mgmt_apps_api_SUITE).
-
--compile(export_all).
--compile(nowarn_export_all).
-
--include_lib("eunit/include/eunit.hrl").
-
-all() ->
-    emqx_ct:all(?MODULE).
-
-init_per_suite(Config) ->
-    ekka_mnesia:start(),
-    emqx_mgmt_auth:mnesia(boot),
-    emqx_ct_helpers:start_apps([emqx_management], fun set_special_configs/1),
-    Config.
-
-end_per_suite(_) ->
-    emqx_ct_helpers:stop_apps([emqx_management]).
-
-set_special_configs(emqx_management) ->
-    emqx_config:put([emqx_management], #{listeners => [#{protocol => http, port => 8081}],
-        applications =>[#{id => "admin", secret => "public"}]}),
-    ok;
-set_special_configs(_App) ->
-    ok.
-
-t_list_app(_) ->
-    Path = emqx_mgmt_api_test_util:api_path(["apps"]),
-    {ok, Body} = emqx_mgmt_api_test_util:request_api(get, Path),
-    Data = emqx_json:decode(Body, [return_maps]),
-    AdminApp = hd(Data),
-    Admin = maps:get(<<"app_id">>, AdminApp),
-    ?assertEqual(<<"admin">>, Admin).
-
-t_get_app(_) ->
-    Path = emqx_mgmt_api_test_util:api_path(["apps/admin"]),
-    {ok, Body} = emqx_mgmt_api_test_util:request_api(get, Path),
-    AdminApp = emqx_json:decode(Body, [return_maps]),
-    ?assertEqual(<<"admin">>, maps:get(<<"app_id">>, AdminApp)),
-    ?assertEqual(<<"public">>, maps:get(<<"secret">>, AdminApp)).
-
-t_add_app(_) ->
-    AuthHeader = emqx_mgmt_api_test_util:auth_header_(),
-    AppId = <<"test_app_id">>,
-    TestAppPath = emqx_mgmt_api_test_util:api_path(["apps", AppId]),
-    AppSecret = <<"test_app_secret">>,
-
-    %% new test app
-    Path = emqx_mgmt_api_test_util:api_path(["apps"]),
-    RequestBody = #{
-        app_id => AppId,
-        secret => AppSecret,
-        desc => <<"test desc">>,
-        name => <<"test_app_name">>,
-        expired => erlang:system_time(second) + 3000,
-        status => true
-    },
-    {ok, Body} = emqx_mgmt_api_test_util:request_api(post, Path, "", AuthHeader, RequestBody),
-    TestAppSecret = emqx_json:decode(Body, [return_maps]),
-    ?assertEqual(AppSecret, maps:get(<<"secret">>, TestAppSecret)),
-
-    %% get new test app
-    {ok, GetApp} = emqx_mgmt_api_test_util:request_api(get, TestAppPath),
-    TestApp = emqx_json:decode(GetApp, [return_maps]),
-    ?assertEqual(AppId, maps:get(<<"app_id">>, TestApp)),
-    ?assertEqual(AppSecret, maps:get(<<"secret">>, TestApp)),
-
-    %% update app
-    Desc2 = <<"test desc 2">>,
-    Name2 = <<"test_app_name_2">>,
-    PutBody = #{
-        desc => Desc2,
-        name => Name2,
-        expired => erlang:system_time(second) + 3000,
-        status => false
-    },
-    {ok, PutApp} = emqx_mgmt_api_test_util:request_api(put, TestAppPath, "", AuthHeader, PutBody),
-    TestApp1 = emqx_json:decode(PutApp, [return_maps]),
-    ?assertEqual(Desc2, maps:get(<<"desc">>, TestApp1)),
-    ?assertEqual(Name2, maps:get(<<"name">>, TestApp1)),
-    ?assertEqual(false, maps:get(<<"status">>, TestApp1)),
-
-    %% after update
-    {ok, GetApp2} = emqx_mgmt_api_test_util:request_api(get, TestAppPath),
-    TestApp2 = emqx_json:decode(GetApp2, [return_maps]),
-    ?assertEqual(Desc2, maps:get(<<"desc">>, TestApp2)),
-    ?assertEqual(Name2, maps:get(<<"name">>, TestApp2)),
-    ?assertEqual(false, maps:get(<<"status">>, TestApp2)),
-
-    %% delete new app
-    {ok, _} = emqx_mgmt_api_test_util:request_api(delete, TestAppPath),
-
-    %% after delete
-    ?assertEqual({error,{"HTTP/1.1",404,"Not Found"}},
-        emqx_mgmt_api_test_util:request_api(get, TestAppPath)).

+ 2 - 13
apps/emqx_management/test/emqx_mgmt_clients_api_SUITE.erl

@@ -19,26 +19,15 @@
 
 -include_lib("eunit/include/eunit.hrl").
 
--define(APP, emqx_management).
-
 all() ->
     emqx_ct:all(?MODULE).
 
 init_per_suite(Config) ->
-    ekka_mnesia:start(),
-    emqx_mgmt_auth:mnesia(boot),
-    emqx_ct_helpers:start_apps([emqx_management], fun set_special_configs/1),
+    emqx_mgmt_api_test_util:init_suite(),
     Config.
 
 end_per_suite(_) ->
-    emqx_ct_helpers:stop_apps([emqx_management]).
-
-set_special_configs(emqx_management) ->
-    emqx_config:put([emqx_management], #{listeners => [#{protocol => http, port => 8081}],
-        applications =>[#{id => "admin", secret => "public"}]}),
-    ok;
-set_special_configs(_App) ->
-    ok.
+    emqx_mgmt_api_test_util:end_suite().
 
 t_clients(_) ->
     process_flag(trap_exit, true),

+ 2 - 11
apps/emqx_management/test/emqx_mgmt_listeners_api_SUITE.erl

@@ -24,20 +24,11 @@ all() ->
     emqx_ct:all(?MODULE).
 
 init_per_suite(Config) ->
-    ekka_mnesia:start(),
-    emqx_mgmt_auth:mnesia(boot),
-    emqx_ct_helpers:start_apps([emqx_management], fun set_special_configs/1),
+    emqx_mgmt_api_test_util:init_suite(),
     Config.
 
 end_per_suite(_) ->
-    emqx_ct_helpers:stop_apps([emqx_management]).
-
-set_special_configs(emqx_management) ->
-    emqx_config:put([emqx_management], #{listeners => [#{protocol => http, port => 8081}],
-        applications =>[#{id => "admin", secret => "public"}]}),
-    ok;
-set_special_configs(_App) ->
-    ok.
+    emqx_mgmt_api_test_util:end_suite().
 
 t_list_listeners(_) ->
     Path = emqx_mgmt_api_test_util:api_path(["listeners"]),

+ 2 - 11
apps/emqx_management/test/emqx_mgmt_metrics_api_SUITE.erl

@@ -24,20 +24,11 @@ all() ->
     emqx_ct:all(?MODULE).
 
 init_per_suite(Config) ->
-    ekka_mnesia:start(),
-    emqx_mgmt_auth:mnesia(boot),
-    emqx_ct_helpers:start_apps([emqx_management], fun set_special_configs/1),
+    emqx_mgmt_api_test_util:init_suite(),
     Config.
 
 end_per_suite(_) ->
-    emqx_ct_helpers:stop_apps([emqx_management]).
-
-set_special_configs(emqx_management) ->
-    emqx_config:put([emqx_management], #{listeners => [#{protocol => http, port => 8081}],
-        applications =>[#{id => "admin", secret => "public"}]}),
-    ok;
-set_special_configs(_App) ->
-    ok.
+    emqx_mgmt_api_test_util:end_suite().
 
 t_metrics_api(_) ->
     MetricsPath = emqx_mgmt_api_test_util:api_path(["metrics?aggregate=true"]),

+ 2 - 11
apps/emqx_management/test/emqx_mgmt_nodes_api_SUITE.erl

@@ -24,20 +24,11 @@ all() ->
     emqx_ct:all(?MODULE).
 
 init_per_suite(Config) ->
-    ekka_mnesia:start(),
-    emqx_mgmt_auth:mnesia(boot),
-    emqx_ct_helpers:start_apps([emqx_management], fun set_special_configs/1),
+    emqx_mgmt_api_test_util:init_suite(),
     Config.
 
 end_per_suite(_) ->
-    emqx_ct_helpers:stop_apps([emqx_management]).
-
-set_special_configs(emqx_management) ->
-    emqx_config:put([emqx_management], #{listeners => [#{protocol => http, port => 8081}],
-        applications =>[#{id => "admin", secret => "public"}]}),
-    ok;
-set_special_configs(_App) ->
-    ok.
+    emqx_mgmt_api_test_util:end_suite().
 
 t_nodes_api(_) ->
     NodesPath = emqx_mgmt_api_test_util:api_path(["nodes"]),

+ 2 - 13
apps/emqx_management/test/emqx_mgmt_publish_api_SUITE.erl

@@ -26,26 +26,15 @@
 -define(TOPIC1, <<"api_topic1">>).
 -define(TOPIC2, <<"api_topic2">>).
 
-
 all() ->
     emqx_ct:all(?MODULE).
 
 init_per_suite(Config) ->
-    ekka_mnesia:start(),
-    emqx_mgmt_auth:mnesia(boot),
-    emqx_ct_helpers:start_apps([emqx_management], fun set_special_configs/1),
+    emqx_mgmt_api_test_util:init_suite(),
     Config.
 
-
 end_per_suite(_) ->
-    emqx_ct_helpers:stop_apps([emqx_management]).
-
-set_special_configs(emqx_management) ->
-    emqx_config:put([emqx_management], #{listeners => [#{protocol => http, port => 8081}],
-        applications =>[#{id => "admin", secret => "public"}]}),
-    ok;
-set_special_configs(_App) ->
-    ok.
+    emqx_mgmt_api_test_util:end_suite().
 
 t_publish_api(_) ->
     {ok, Client} = emqtt:start_link(#{username => <<"api_username">>, clientid => <<"api_clientid">>}),

+ 3 - 12
apps/emqx_management/test/emqx_mgmt_routes_api_SUITE.erl

@@ -24,20 +24,11 @@ all() ->
     emqx_ct:all(?MODULE).
 
 init_per_suite(Config) ->
-    ekka_mnesia:start(),
-    emqx_mgmt_auth:mnesia(boot),
-    emqx_ct_helpers:start_apps([emqx_management], fun set_special_configs/1),
+    emqx_mgmt_api_test_util:init_suite(),
     Config.
 
 end_per_suite(_) ->
-    emqx_ct_helpers:stop_apps([emqx_management]).
-
-set_special_configs(emqx_management) ->
-    emqx_config:put([emqx_management], #{listeners => [#{protocol => http, port => 8081}],
-        applications =>[#{id => "admin", secret => "public"}]}),
-    ok;
-set_special_configs(_App) ->
-    ok.
+    emqx_mgmt_api_test_util:end_suite().
 
 t_nodes_api(_) ->
     Topic = <<"test_topic">>,
@@ -62,4 +53,4 @@ t_nodes_api(_) ->
     {ok, RouteResponse} = emqx_mgmt_api_test_util:request_api(get, RoutePath),
     RouteData = emqx_json:decode(RouteResponse, [return_maps]),
     ?assertEqual(Topic, maps:get(<<"topic">>, RouteData)),
-    ?assertEqual(atom_to_binary(node(), utf8), maps:get(<<"node">>, RouteData)).
+    ?assertEqual(atom_to_binary(node(), utf8), maps:get(<<"node">>, RouteData)).

+ 2 - 11
apps/emqx_management/test/emqx_mgmt_stats_api_SUITE.erl

@@ -24,20 +24,11 @@ all() ->
     emqx_ct:all(?MODULE).
 
 init_per_suite(Config) ->
-    ekka_mnesia:start(),
-    emqx_mgmt_auth:mnesia(boot),
-    emqx_ct_helpers:start_apps([emqx_management], fun set_special_configs/1),
+    emqx_mgmt_api_test_util:init_suite(),
     Config.
 
 end_per_suite(_) ->
-    emqx_ct_helpers:stop_apps([emqx_management]).
-
-set_special_configs(emqx_management) ->
-    emqx_config:put([emqx_management], #{listeners => [#{protocol => http, port => 8081}],
-        applications =>[#{id => "admin", secret => "public"}]}),
-    ok;
-set_special_configs(_App) ->
-    ok.
+    emqx_mgmt_api_test_util:end_suite().
 
 t_stats_api(_) ->
     StatsPath = emqx_mgmt_api_test_util:api_path(["stats?aggregate=true"]),

+ 2 - 13
apps/emqx_management/test/emqx_mgmt_subscription_api_SUITE.erl

@@ -27,26 +27,15 @@
 -define(TOPIC1, <<"0000">>).
 -define(TOPIC2, <<"0001">>).
 
-
 all() ->
     emqx_ct:all(?MODULE).
 
 init_per_suite(Config) ->
-    ekka_mnesia:start(),
-    emqx_mgmt_auth:mnesia(boot),
-    emqx_ct_helpers:start_apps([emqx_management], fun set_special_configs/1),
+    emqx_mgmt_api_test_util:init_suite(),
     Config.
 
-
 end_per_suite(_) ->
-    emqx_ct_helpers:stop_apps([emqx_management]).
-
-set_special_configs(emqx_management) ->
-    emqx_config:put([emqx_management], #{listeners => [#{protocol => http, port => 8081}],
-        applications =>[#{id => "admin", secret => "public"}]}),
-    ok;
-set_special_configs(_App) ->
-    ok.
+    emqx_mgmt_api_test_util:end_suite().
 
 t_subscription_api(_) ->
     {ok, Client} = emqtt:start_link(#{username => ?USERNAME, clientid => ?CLIENTID}),

+ 1 - 3
deploy/charts/emqx/templates/StatefulSet.yaml

@@ -94,8 +94,6 @@ spec:
             containerPort: {{ .Values.emqxConfig.EMQX_LISTENERS__TCP__DEFAULT | default 1883 }}
           - name: mqttssl
             containerPort: {{ .Values.emqxConfig.EMQX_LISTENERS__SSL__DEFAULT | default 8883 }}
-          - name: mgmt
-            containerPort: {{ .Values.emqxConfig.EMQX_MANAGEMENT__LISTENER__HTTP | default 8081 }}
           - name: ws
             containerPort: {{ .Values.emqxConfig.EMQX_LISTENERS__WS__DEFAULT | default 8083 }}
           - name: wss
@@ -140,7 +138,7 @@ spec:
           readinessProbe:
             httpGet:
               path: /api/v5/status
-              port: {{ .Values.emqxConfig.EMQX_MANAGEMENT__LISTENER__HTTP | default 8081 }}
+              port: {{ .Values.emqxConfig.EMQX_DASHBOARD__LISTENER__HTTP | default 18083 }}
             initialDelaySeconds: 5
             periodSeconds: 5
     {{- with .Values.nodeSelector }}

+ 0 - 13
deploy/charts/emqx/templates/service.yaml

@@ -55,15 +55,6 @@ spec:
     {{- else if eq .Values.service.type "ClusterIP" }}
     nodePort: null
     {{- end }}
-  - name: mgmt
-    port: {{ .Values.service.mgmt | default 8081 }}
-    protocol: TCP
-    targetPort: mgmt
-    {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.mgmt)) }}
-    nodePort: {{ .Values.service.nodePorts.mgmt }}
-    {{- else if eq .Values.service.type "ClusterIP" }}
-    nodePort: null
-    {{- end }}
   - name: ws
     port: {{ .Values.service.ws | default 8083 }}
     protocol: TCP
@@ -136,10 +127,6 @@ spec:
     port: {{ .Values.service.mqttssl | default 8883 }}
     protocol: TCP
     targetPort: mqttssl
-  - name: mgmt
-    port: {{ .Values.service.mgmt | default 8081 }}
-    protocol: TCP
-    targetPort: mgmt
   - name: ws
     port: {{ .Values.service.ws | default 8083 }}
     protocol: TCP