chore(sync-apps): re-sync apps from dev/v4.3.0 branch
This commit is contained in:
parent
fc0b912cde
commit
a2b4e50a8d
|
@ -63,8 +63,10 @@ check(ClientInfo = #{ clientid := Clientid
|
||||||
emqx_metrics:inc(?AUTH_METRICS(ignore)),
|
emqx_metrics:inc(?AUTH_METRICS(ignore)),
|
||||||
ok;
|
ok;
|
||||||
List ->
|
List ->
|
||||||
case match_password(NPassword, HashType, List) of
|
case [ Hash || <<Salt:4/binary, Hash/binary>> <- lists:sort(fun emqx_auth_mnesia_cli:comparing/2, List),
|
||||||
false ->
|
Hash =:= hash(NPassword, Salt, HashType)
|
||||||
|
] of
|
||||||
|
[] ->
|
||||||
?LOG(error, "[Mnesia] Auth from mnesia failed: ~p", [ClientInfo]),
|
?LOG(error, "[Mnesia] Auth from mnesia failed: ~p", [ClientInfo]),
|
||||||
emqx_metrics:inc(?AUTH_METRICS(failure)),
|
emqx_metrics:inc(?AUTH_METRICS(failure)),
|
||||||
{stop, AuthResult#{anonymous => false, auth_result => password_error}};
|
{stop, AuthResult#{anonymous => false, auth_result => password_error}};
|
||||||
|
@ -76,34 +78,7 @@ check(ClientInfo = #{ clientid := Clientid
|
||||||
|
|
||||||
description() -> "Authentication with Mnesia".
|
description() -> "Authentication with Mnesia".
|
||||||
|
|
||||||
match_password(Password, HashType, HashList) ->
|
|
||||||
lists:any(
|
|
||||||
fun(Secret) ->
|
|
||||||
case is_salt_hash(Secret, HashType) of
|
|
||||||
true ->
|
|
||||||
<<Salt:4/binary, Hash/binary>> = Secret,
|
|
||||||
Hash =:= hash(Password, Salt, HashType);
|
|
||||||
_ ->
|
|
||||||
Secret =:= hash(Password, HashType)
|
|
||||||
end
|
|
||||||
end, HashList).
|
|
||||||
|
|
||||||
hash(undefined, HashType) ->
|
|
||||||
hash(<<>>, HashType);
|
|
||||||
hash(Password, HashType) ->
|
|
||||||
emqx_passwd:hash(HashType, Password).
|
|
||||||
|
|
||||||
hash(undefined, SaltBin, HashType) ->
|
hash(undefined, SaltBin, HashType) ->
|
||||||
hash(<<>>, SaltBin, HashType);
|
hash(<<>>, SaltBin, HashType);
|
||||||
hash(Password, SaltBin, HashType) ->
|
hash(Password, SaltBin, HashType) ->
|
||||||
emqx_passwd:hash(HashType, <<SaltBin/binary, Password/binary>>).
|
emqx_passwd:hash(HashType, <<SaltBin/binary, Password/binary>>).
|
||||||
|
|
||||||
is_salt_hash(_, plain) ->
|
|
||||||
true;
|
|
||||||
is_salt_hash(Secret, HashType) ->
|
|
||||||
not (byte_size(Secret) == len(HashType)).
|
|
||||||
|
|
||||||
len(md5) -> 32;
|
|
||||||
len(sha) -> 40;
|
|
||||||
len(sha256) -> 64;
|
|
||||||
len(sha512) -> 128.
|
|
||||||
|
|
|
@ -87,10 +87,16 @@ description() -> "Authentication with MongoDB".
|
||||||
is_superuser(_Pool, undefined, _ClientInfo) ->
|
is_superuser(_Pool, undefined, _ClientInfo) ->
|
||||||
false;
|
false;
|
||||||
is_superuser(Pool, #superquery{collection = Coll, field = Field, selector = Selector}, ClientInfo) ->
|
is_superuser(Pool, #superquery{collection = Coll, field = Field, selector = Selector}, ClientInfo) ->
|
||||||
Row = query(Pool, Coll, maps:from_list(replvars(Selector, ClientInfo))),
|
case query(Pool, Coll, maps:from_list(replvars(Selector, ClientInfo))) of
|
||||||
case maps:get(Field, Row, false) of
|
undefined -> false;
|
||||||
true -> true;
|
{error, Reason} ->
|
||||||
_False -> false
|
?LOG(error, "[MongoDB] Can't connect to MongoDB server: ~0p", [Reason]),
|
||||||
|
false;
|
||||||
|
Row ->
|
||||||
|
case maps:get(Field, Row, false) of
|
||||||
|
true -> true;
|
||||||
|
_False -> false
|
||||||
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
replvars(VarList, ClientInfo) ->
|
replvars(VarList, ClientInfo) ->
|
||||||
|
|
|
@ -39,6 +39,14 @@ auth.pgsql.encoding = utf8
|
||||||
## Value: true | false
|
## Value: true | false
|
||||||
auth.pgsql.ssl = false
|
auth.pgsql.ssl = false
|
||||||
|
|
||||||
|
## TLS version
|
||||||
|
## You can configure multi-version use "," split,
|
||||||
|
## default value is :tlsv1.2
|
||||||
|
## Example:
|
||||||
|
## tlsv1.1,tlsv1.2,tlsv1.3
|
||||||
|
##
|
||||||
|
## auth.pgsql.ssl.tls_versions = tlsv1.2
|
||||||
|
|
||||||
## SSL keyfile.
|
## SSL keyfile.
|
||||||
##
|
##
|
||||||
## Value: File
|
## Value: File
|
||||||
|
|
|
@ -35,6 +35,11 @@
|
||||||
{datatype, {enum, [true, false]}}
|
{datatype, {enum, [true, false]}}
|
||||||
]}.
|
]}.
|
||||||
|
|
||||||
|
{mapping, "auth.pgsql.ssl.tls_versions", "emqx_auth_pgsql.server", [
|
||||||
|
{default, "tlsv1.2"},
|
||||||
|
{datatype, string}
|
||||||
|
]}.
|
||||||
|
|
||||||
{mapping, "auth.pgsql.ssl_opts.keyfile", "emqx_auth_pgsql.server", [
|
{mapping, "auth.pgsql.ssl_opts.keyfile", "emqx_auth_pgsql.server", [
|
||||||
{datatype, string}
|
{datatype, string}
|
||||||
]}.
|
]}.
|
||||||
|
@ -62,6 +67,8 @@
|
||||||
DB = cuttlefish:conf_get("auth.pgsql.database", Conf),
|
DB = cuttlefish:conf_get("auth.pgsql.database", Conf),
|
||||||
Encoding = cuttlefish:conf_get("auth.pgsql.encoding", Conf),
|
Encoding = cuttlefish:conf_get("auth.pgsql.encoding", Conf),
|
||||||
Ssl = cuttlefish:conf_get("auth.pgsql.ssl", Conf),
|
Ssl = cuttlefish:conf_get("auth.pgsql.ssl", Conf),
|
||||||
|
SslVersions = [list_to_atom(Value)
|
||||||
|
||Value <- string:tokens(cuttlefish:conf_get("auth.pgsql.ssl.tls_versions", Conf), " ,")],
|
||||||
|
|
||||||
Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
|
Filter = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
|
||||||
SslOpts = fun(Prefix) ->
|
SslOpts = fun(Prefix) ->
|
||||||
|
@ -85,7 +92,7 @@
|
||||||
{database, DB},
|
{database, DB},
|
||||||
{encoding, Encoding},
|
{encoding, Encoding},
|
||||||
{ssl, Ssl},
|
{ssl, Ssl},
|
||||||
{ssl_opts, SslOpts("auth.pgsql.ssl_opts")}]
|
{ssl_opts,[{versions, SslVersions}] ++ SslOpts("auth.pgsql.ssl_opts")}]
|
||||||
end}.
|
end}.
|
||||||
|
|
||||||
{mapping, "auth.pgsql.auth_query", "emqx_auth_pgsql.auth_query", [
|
{mapping, "auth.pgsql.auth_query", "emqx_auth_pgsql.auth_query", [
|
||||||
|
|
|
@ -29,9 +29,9 @@
|
||||||
-include_lib("common_test/include/ct.hrl").
|
-include_lib("common_test/include/ct.hrl").
|
||||||
|
|
||||||
%%setp1 init table
|
%%setp1 init table
|
||||||
-define(DROP_ACL_TABLE, "DROP TABLE IF EXISTS mqtt_acl_test").
|
-define(DROP_ACL_TABLE, "DROP TABLE IF EXISTS mqtt_acl").
|
||||||
|
|
||||||
-define(CREATE_ACL_TABLE, "CREATE TABLE mqtt_acl_test (
|
-define(CREATE_ACL_TABLE, "CREATE TABLE mqtt_acl (
|
||||||
id SERIAL primary key,
|
id SERIAL primary key,
|
||||||
allow integer,
|
allow integer,
|
||||||
ipaddr character varying(60),
|
ipaddr character varying(60),
|
||||||
|
@ -40,23 +40,23 @@
|
||||||
access integer,
|
access integer,
|
||||||
topic character varying(100))").
|
topic character varying(100))").
|
||||||
|
|
||||||
-define(INIT_ACL, "INSERT INTO mqtt_acl_test (id, allow, ipaddr, username, clientid, access, topic)
|
-define(INIT_ACL, "INSERT INTO mqtt_acl (id, allow, ipaddr, username, clientid, access, topic)
|
||||||
VALUES
|
VALUES
|
||||||
(1,1,'127.0.0.1','u1','c1',1,'t1'),
|
(1,1,'127.0.0.1','u1','c1',1,'t1'),
|
||||||
(2,0,'127.0.0.1','u2','c2',1,'t1'),
|
(2,0,'127.0.0.1','u2','c2',1,'t1'),
|
||||||
(3,1,'10.10.0.110','u1','c1',1,'t1'),
|
(3,1,'10.10.0.110','u1','c1',1,'t1'),
|
||||||
(4,1,'127.0.0.1','u3','c3',3,'t1')").
|
(4,1,'127.0.0.1','u3','c3',3,'t1')").
|
||||||
|
|
||||||
-define(DROP_AUTH_TABLE, "DROP TABLE IF EXISTS mqtt_user_test").
|
-define(DROP_AUTH_TABLE, "DROP TABLE IF EXISTS mqtt_user").
|
||||||
|
|
||||||
-define(CREATE_AUTH_TABLE, "CREATE TABLE mqtt_user_test (
|
-define(CREATE_AUTH_TABLE, "CREATE TABLE mqtt_user (
|
||||||
id SERIAL primary key,
|
id SERIAL primary key,
|
||||||
is_superuser boolean,
|
is_superuser boolean,
|
||||||
username character varying(100),
|
username character varying(100),
|
||||||
password character varying(100),
|
password character varying(100),
|
||||||
salt character varying(40))").
|
salt character varying(40))").
|
||||||
|
|
||||||
-define(INIT_AUTH, "INSERT INTO mqtt_user_test (id, is_superuser, username, password, salt)
|
-define(INIT_AUTH, "INSERT INTO mqtt_user (id, is_superuser, username, password, salt)
|
||||||
VALUES
|
VALUES
|
||||||
(1, true, 'plain', 'plain', 'salt'),
|
(1, true, 'plain', 'plain', 'salt'),
|
||||||
(2, false, 'md5', '1bc29b36f623ba82aaf6724fd3b16718', 'salt'),
|
(2, false, 'md5', '1bc29b36f623ba82aaf6724fd3b16718', 'salt'),
|
||||||
|
@ -67,61 +67,25 @@
|
||||||
(7, false, 'bcrypt', '$2y$16$rEVsDarhgHYB0TGnDFJzyu5f.T.Ha9iXMTk9J36NCMWWM7O16qyaK', 'salt')").
|
(7, false, 'bcrypt', '$2y$16$rEVsDarhgHYB0TGnDFJzyu5f.T.Ha9iXMTk9J36NCMWWM7O16qyaK', 'salt')").
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
[{group, ssl}, {group, nossl}].
|
emqx_ct:all(?MODULE).
|
||||||
|
|
||||||
groups() ->
|
init_per_suite(Config) ->
|
||||||
Cases = emqx_ct:all(?MODULE),
|
emqx_ct_helpers:start_apps([emqx_auth_pgsql]),
|
||||||
[{ssl, [sequence], Cases}, {nossl, [sequence], Cases}].
|
drop_acl(),
|
||||||
|
drop_auth(),
|
||||||
init_per_group(Name, Config) ->
|
init_auth(),
|
||||||
case Name of
|
init_acl(),
|
||||||
ssl ->
|
set_special_configs(),
|
||||||
emqx_ct_helpers:start_apps([emqx_auth_pgsql], fun set_special_configs_ssl/1);
|
|
||||||
nossl ->
|
|
||||||
emqx_ct_helpers:start_apps([emqx_auth_pgsql], fun set_special_configs/1)
|
|
||||||
end,
|
|
||||||
init_auth_(),
|
|
||||||
init_acl_(),
|
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
end_per_group(_, Config) ->
|
end_per_suite(Config) ->
|
||||||
drop_auth_(),
|
|
||||||
drop_acl_(),
|
|
||||||
emqx_ct_helpers:stop_apps([emqx_auth_pgsql]),
|
emqx_ct_helpers:stop_apps([emqx_auth_pgsql]),
|
||||||
Config.
|
Config.
|
||||||
|
|
||||||
set_special_configs_ssl(Name) ->
|
set_special_configs() ->
|
||||||
Server = application:get_env(?APP, server, []),
|
|
||||||
Path = emqx_ct_helpers:deps_path(emqx_auth_pgsql, "test/emqx_auth_pgsql_SUITE_data/"),
|
|
||||||
Sslopts = [{keyfile, Path ++ "/client-key.pem"},
|
|
||||||
{certfile, Path ++ "/client-cert.pem"},
|
|
||||||
{cacertfile, Path ++ "/ca.pem"}],
|
|
||||||
Temp = lists:keyreplace(ssl, 1, Server, {ssl, true}),
|
|
||||||
application:set_env(?APP, server, Temp),
|
|
||||||
application:set_env(?APP, server, lists:keyreplace(ssl_opts, 1, Temp, {ssl_opts, Sslopts})),
|
|
||||||
set_special_configs(Name).
|
|
||||||
|
|
||||||
set_special_configs(emqx) ->
|
|
||||||
application:set_env(emqx, acl_nomatch, deny),
|
application:set_env(emqx, acl_nomatch, deny),
|
||||||
application:set_env(emqx, acl_file,
|
|
||||||
emqx_ct_helpers:deps_path(emqx, "test/emqx_SUITE_data/acl.conf")),
|
|
||||||
application:set_env(emqx, allow_anonymous, false),
|
application:set_env(emqx, allow_anonymous, false),
|
||||||
application:set_env(emqx, enable_acl_cache, false),
|
application:set_env(emqx, enable_acl_cache, false).
|
||||||
application:set_env(emqx, plugins_loaded_file,
|
|
||||||
emqx_ct_helpers:deps_path(emqx, "test/emqx_SUITE_data/loaded_plugins"));
|
|
||||||
|
|
||||||
set_special_configs(emqx_auth_pgsql) ->
|
|
||||||
Server = application:get_env(?APP, server, []),
|
|
||||||
application:set_env(?APP, server,
|
|
||||||
lists:keyreplace(password,
|
|
||||||
1,
|
|
||||||
lists:keyreplace(pool_size, 1, Server, {pool_size, 1}),
|
|
||||||
{password, "public"})),
|
|
||||||
application:set_env(?APP, acl_query, "select allow, ipaddr, username, clientid, access, topic from mqtt_acl_test where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'"),
|
|
||||||
application:set_env(?APP, super_query, "select is_superuser from mqtt_user_test where username = '%u' limit 1"),
|
|
||||||
application:set_env(?APP, auth_query, "select password from mqtt_user_test where username = '%u' limit 1");
|
|
||||||
set_special_configs(_App) ->
|
|
||||||
ok.
|
|
||||||
|
|
||||||
t_comment_config(_) ->
|
t_comment_config(_) ->
|
||||||
AuthCount = length(emqx_hooks:lookup('client.authenticate')),
|
AuthCount = length(emqx_hooks:lookup('client.authenticate')),
|
||||||
|
@ -136,7 +100,7 @@ t_comment_config(_) ->
|
||||||
t_placeholders(_) ->
|
t_placeholders(_) ->
|
||||||
ClientA = #{username => <<"plain">>, clientid => <<"plain">>, zone => external},
|
ClientA = #{username => <<"plain">>, clientid => <<"plain">>, zone => external},
|
||||||
reload([{password_hash, plain},
|
reload([{password_hash, plain},
|
||||||
{auth_query, "select password from mqtt_user_test where username = '%u' and 'a_cn_val' = '%C' limit 1"}]),
|
{auth_query, "select password from mqtt_user where username = '%u' and 'a_cn_val' = '%C' limit 1"}]),
|
||||||
{error, not_authorized} =
|
{error, not_authorized} =
|
||||||
emqx_access_control:authenticate(ClientA#{password => <<"plain">>}),
|
emqx_access_control:authenticate(ClientA#{password => <<"plain">>}),
|
||||||
{error, not_authorized} =
|
{error, not_authorized} =
|
||||||
|
@ -144,7 +108,7 @@ t_placeholders(_) ->
|
||||||
{ok, _} =
|
{ok, _} =
|
||||||
emqx_access_control:authenticate(ClientA#{password => <<"plain">>, cn => <<"a_cn_val">>}),
|
emqx_access_control:authenticate(ClientA#{password => <<"plain">>, cn => <<"a_cn_val">>}),
|
||||||
|
|
||||||
reload([{auth_query, "select password from mqtt_user_test where username = '%c' and 'a_dn_val' = '%d' limit 1"}]),
|
reload([{auth_query, "select password from mqtt_user where username = '%c' and 'a_dn_val' = '%d' limit 1"}]),
|
||||||
{error, not_authorized} =
|
{error, not_authorized} =
|
||||||
emqx_access_control:authenticate(ClientA#{password => <<"plain">>}),
|
emqx_access_control:authenticate(ClientA#{password => <<"plain">>}),
|
||||||
{error, not_authorized} =
|
{error, not_authorized} =
|
||||||
|
@ -152,12 +116,11 @@ t_placeholders(_) ->
|
||||||
{ok, _} =
|
{ok, _} =
|
||||||
emqx_access_control:authenticate(ClientA#{password => <<"plain">>, dn => <<"a_dn_val">>}),
|
emqx_access_control:authenticate(ClientA#{password => <<"plain">>, dn => <<"a_dn_val">>}),
|
||||||
|
|
||||||
reload([{auth_query, "select password from mqtt_user_test where username = '%u' and '192.168.1.5' = '%a' limit 1"}]),
|
reload([{auth_query, "select password from mqtt_user where username = '%u' and '192.168.1.5' = '%a' limit 1"}]),
|
||||||
{error, not_authorized} =
|
{error, not_authorized} =
|
||||||
emqx_access_control:authenticate(ClientA#{password => <<"plain">>}),
|
emqx_access_control:authenticate(ClientA#{password => <<"plain">>}),
|
||||||
{ok, _} =
|
{ok, _} =
|
||||||
emqx_access_control:authenticate(ClientA#{password => <<"plain">>, peerhost => {192,168,1,5}}).
|
emqx_access_control:authenticate(ClientA#{password => <<"plain">>, peerhost => {192,168,1,5}}).
|
||||||
|
|
||||||
t_check_auth(_) ->
|
t_check_auth(_) ->
|
||||||
Plain = #{clientid => <<"client1">>, username => <<"plain">>, zone => external},
|
Plain = #{clientid => <<"client1">>, username => <<"plain">>, zone => external},
|
||||||
Md5 = #{clientid => <<"md5">>, username => <<"md5">>, zone => external},
|
Md5 = #{clientid => <<"md5">>, username => <<"md5">>, zone => external},
|
||||||
|
@ -167,29 +130,39 @@ t_check_auth(_) ->
|
||||||
BcryptFoo = #{clientid => <<"bcrypt_foo">>, username => <<"bcrypt_foo">>, zone => external},
|
BcryptFoo = #{clientid => <<"bcrypt_foo">>, username => <<"bcrypt_foo">>, zone => external},
|
||||||
User1 = #{clientid => <<"bcrypt_foo">>, username => <<"user">>, zone => external},
|
User1 = #{clientid => <<"bcrypt_foo">>, username => <<"user">>, zone => external},
|
||||||
Bcrypt = #{clientid => <<"bcrypt">>, username => <<"bcrypt">>, zone => external},
|
Bcrypt = #{clientid => <<"bcrypt">>, username => <<"bcrypt">>, zone => external},
|
||||||
reload([{password_hash, plain},
|
BcryptWrong = #{clientid => <<"bcrypt_wrong">>, username => <<"bcrypt_wrong">>, zone => external},
|
||||||
{auth_query, "select password from mqtt_user_test where username = '%u' limit 1"}]),
|
reload([{password_hash, plain}]),
|
||||||
{ok, #{is_superuser := true}} = emqx_access_control:authenticate(Plain#{password => <<"plain">>}),
|
{ok,#{is_superuser := true}} =
|
||||||
|
emqx_access_control:authenticate(Plain#{password => <<"plain">>}),
|
||||||
reload([{password_hash, md5}]),
|
reload([{password_hash, md5}]),
|
||||||
{ok, #{is_superuser := false}} = emqx_access_control:authenticate(Md5#{password => <<"md5">>}),
|
{ok,#{is_superuser := false}} =
|
||||||
|
emqx_access_control:authenticate(Md5#{password => <<"md5">>}),
|
||||||
reload([{password_hash, sha}]),
|
reload([{password_hash, sha}]),
|
||||||
{ok, #{is_superuser := false}} = emqx_access_control:authenticate(Sha#{password => <<"sha">>}),
|
{ok,#{is_superuser := false}} =
|
||||||
|
emqx_access_control:authenticate(Sha#{password => <<"sha">>}),
|
||||||
reload([{password_hash, sha256}]),
|
reload([{password_hash, sha256}]),
|
||||||
{ok, #{is_superuser := false}} = emqx_access_control:authenticate(Sha256#{password => <<"sha256">>}),
|
{ok,#{is_superuser := false}} =
|
||||||
|
emqx_access_control:authenticate(Sha256#{password => <<"sha256">>}),
|
||||||
reload([{password_hash, bcrypt}]),
|
reload([{password_hash, bcrypt}]),
|
||||||
{ok, #{is_superuser := false}} = emqx_access_control:authenticate(Bcrypt#{password => <<"password">>}),
|
{ok,#{is_superuser := false}} =
|
||||||
|
emqx_access_control:authenticate(Bcrypt#{password => <<"password">>}),
|
||||||
|
{error, not_authorized} =
|
||||||
|
emqx_access_control:authenticate(BcryptWrong#{password => <<"password">>}),
|
||||||
%%pbkdf2 sha
|
%%pbkdf2 sha
|
||||||
reload([{password_hash, {pbkdf2, sha, 1, 16}}, {auth_query, "select password, salt from mqtt_user_test where username = '%u' limit 1"}]),
|
reload([{password_hash, {pbkdf2, sha, 1, 16}},
|
||||||
{ok, #{is_superuser := false}} = emqx_access_control:authenticate(Pbkdf2#{password => <<"password">>}),
|
{auth_query, "select password, salt from mqtt_user where username = '%u' limit 1"}]),
|
||||||
|
{ok,#{is_superuser := false}} =
|
||||||
|
emqx_access_control:authenticate(Pbkdf2#{password => <<"password">>}),
|
||||||
reload([{password_hash, {salt, bcrypt}}]),
|
reload([{password_hash, {salt, bcrypt}}]),
|
||||||
{ok, #{is_superuser := false}} = emqx_access_control:authenticate(BcryptFoo#{password => <<"foo">>}),
|
{ok,#{is_superuser := false}} =
|
||||||
|
emqx_access_control:authenticate(BcryptFoo#{password => <<"foo">>}),
|
||||||
{error, _} = emqx_access_control:authenticate(User1#{password => <<"foo">>}),
|
{error, _} = emqx_access_control:authenticate(User1#{password => <<"foo">>}),
|
||||||
{error, not_authorized} = emqx_access_control:authenticate(Bcrypt#{password => <<"password">>}).
|
{error, not_authorized} = emqx_access_control:authenticate(Bcrypt#{password => <<"password">>}).
|
||||||
|
|
||||||
t_check_acl(_) ->
|
t_check_acl(_) ->
|
||||||
emqx_modules:load_module(emqx_mod_acl_internal, false),
|
emqx_modules:load_module(emqx_mod_acl_internal, false),
|
||||||
User1 = #{zone => external, peerhost => {127,0,0,1}, clientid => <<"c1">>, username => <<"u1">>},
|
User1 = #{zone => external, peerhost => {127,0,0,1}, clientid => <<"c1">>, username => <<"u1">>},
|
||||||
User2 = #{zone => external, peerhost => {127,0,0,1}, clientid => <<"c2">>, username => <<"u2">>},
|
User2 = #{zone => external, peerhost => {127,0,0,1}, clientid => <<"c2">>, username => <<"u2">>},
|
||||||
reload([{acl_query, "select allow, ipaddr, username, clientid, access, topic from mqtt_acl_test where ipaddr = '%a' or username = '%u' or username = '$all' or clientid = '%c'"}]),
|
|
||||||
allow = emqx_access_control:check_acl(User1, subscribe, <<"t1">>),
|
allow = emqx_access_control:check_acl(User1, subscribe, <<"t1">>),
|
||||||
deny = emqx_access_control:check_acl(User2, subscribe, <<"t1">>),
|
deny = emqx_access_control:check_acl(User2, subscribe, <<"t1">>),
|
||||||
User3 = #{zone => external, peerhost => {10,10,0,110}, clientid => <<"c1">>, username => <<"u1">>},
|
User3 = #{zone => external, peerhost => {10,10,0,110}, clientid => <<"c1">>, username => <<"u1">>},
|
||||||
|
@ -203,7 +176,7 @@ t_check_acl(_) ->
|
||||||
allow = emqx_access_control:check_acl(User5, publish, <<"t1">>).
|
allow = emqx_access_control:check_acl(User5, publish, <<"t1">>).
|
||||||
|
|
||||||
t_acl_super(_) ->
|
t_acl_super(_) ->
|
||||||
reload([{password_hash, plain}, {auth_query, "select password from mqtt_user_test where username = '%u' limit 1"}]),
|
reload([{password_hash, plain}, {auth_query, "select password from mqtt_user where username = '%u' limit 1"}]),
|
||||||
{ok, C} = emqtt:start_link([{host, "localhost"}, {clientid, <<"simpleClient">>},
|
{ok, C} = emqtt:start_link([{host, "localhost"}, {clientid, <<"simpleClient">>},
|
||||||
{username, <<"plain">>}, {password, <<"plain">>}]),
|
{username, <<"plain">>}, {password, <<"plain">>}]),
|
||||||
{ok, _} = emqtt:connect(C),
|
{ok, _} = emqtt:connect(C),
|
||||||
|
@ -226,22 +199,22 @@ reload(Config) when is_list(Config) ->
|
||||||
[application:set_env(?APP, K, V) || {K, V} <- Config],
|
[application:set_env(?APP, K, V) || {K, V} <- Config],
|
||||||
application:start(?APP).
|
application:start(?APP).
|
||||||
|
|
||||||
init_acl_() ->
|
init_acl() ->
|
||||||
{ok, Pid} = ecpool_worker:client(gproc_pool:pick_worker({ecpool, ?POOL})),
|
{ok, Pid} = ecpool_worker:client(gproc_pool:pick_worker({ecpool, ?POOL})),
|
||||||
{ok, [], []} = epgsql:squery(Pid, ?DROP_ACL_TABLE),
|
{ok, [], []} = epgsql:squery(Pid, ?DROP_ACL_TABLE),
|
||||||
{ok, [], []} = epgsql:squery(Pid, ?CREATE_ACL_TABLE),
|
{ok, [], []} = epgsql:squery(Pid, ?CREATE_ACL_TABLE),
|
||||||
{ok, _} = epgsql:equery(Pid, ?INIT_ACL).
|
{ok, _} = epgsql:equery(Pid, ?INIT_ACL).
|
||||||
|
|
||||||
drop_acl_() ->
|
drop_acl() ->
|
||||||
{ok, Pid} = ecpool_worker:client(gproc_pool:pick_worker({ecpool, ?POOL})),
|
{ok, Pid} = ecpool_worker:client(gproc_pool:pick_worker({ecpool, ?POOL})),
|
||||||
{ok, [], []}= epgsql:squery(Pid, ?DROP_ACL_TABLE).
|
{ok, [], []}= epgsql:squery(Pid, ?DROP_ACL_TABLE).
|
||||||
|
|
||||||
init_auth_() ->
|
init_auth() ->
|
||||||
{ok, Pid} = ecpool_worker:client(gproc_pool:pick_worker({ecpool, ?POOL})),
|
{ok, Pid} = ecpool_worker:client(gproc_pool:pick_worker({ecpool, ?POOL})),
|
||||||
{ok, [], []} = epgsql:squery(Pid, ?DROP_AUTH_TABLE),
|
{ok, [], []} = epgsql:squery(Pid, ?DROP_AUTH_TABLE),
|
||||||
{ok, [], []} = epgsql:squery(Pid, ?CREATE_AUTH_TABLE),
|
{ok, [], []} = epgsql:squery(Pid, ?CREATE_AUTH_TABLE),
|
||||||
{ok, _} = epgsql:equery(Pid, ?INIT_AUTH).
|
{ok, _} = epgsql:equery(Pid, ?INIT_AUTH).
|
||||||
|
|
||||||
drop_auth_() ->
|
drop_auth() ->
|
||||||
{ok, Pid} = ecpool_worker:client(gproc_pool:pick_worker({ecpool, ?POOL})),
|
{ok, Pid} = ecpool_worker:client(gproc_pool:pick_worker({ecpool, ?POOL})),
|
||||||
{ok, [], []} = epgsql:squery(Pid, ?DROP_AUTH_TABLE).
|
{ok, [], []} = epgsql:squery(Pid, ?DROP_AUTH_TABLE).
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDAzCCAeugAwIBAgIBATANBgkqhkiG9w0BAQsFADA8MTowOAYDVQQDDDFNeVNR
|
|
||||||
TF9TZXJ2ZXJfOC4wLjE5X0F1dG9fR2VuZXJhdGVkX0NBX0NlcnRpZmljYXRlMB4X
|
|
||||||
DTIwMDYxMTAzMzg0NloXDTMwMDYwOTAzMzg0NlowPDE6MDgGA1UEAwwxTXlTUUxf
|
|
||||||
U2VydmVyXzguMC4xOV9BdXRvX0dlbmVyYXRlZF9DQV9DZXJ0aWZpY2F0ZTCCASIw
|
|
||||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANJBlAYvTQ6euY4HcSn4syH7kq9s
|
|
||||||
KcG+OMjPUrj+KFEElCzgNuIhaS0f3ORQGB1PNcvVcfdXUI3WX332gWbr9s1b7Xl1
|
|
||||||
JKJfDXs+26Cm6NhONTE3sPHnbTSmQEFb52hwAtjQmcY3IQs1AgxKFFHJfnCBEWfE
|
|
||||||
ePBQaiuYk1XDESMdWpMLrPnYQaj9MpAOUxjlmZCayzPWlF0j0IWvfsF5TqZL7tFK
|
|
||||||
9p5F/DzyZ4n1mqPVEoUmq5ZdSKj2TQkpWTMHBWHEDQQqXbyE1FGJR7zEUFeuG1KT
|
|
||||||
sVBg7iZEC93SygZTbgUZSQXIwQCsO6xZ8MB2XDJkPbWp/3Wc6c8I6P09F48CAwEA
|
|
||||||
AaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEADKz6bIpP5anp
|
|
||||||
GgLB0jkclRWuMlS4qqIt4itSsMXPJ/ezpHwECixmgW2TIQl6S1woRkUeMxhT2/Ay
|
|
||||||
Sn/7aKxuzRagyE5NEGOvrOuAP5RO2ZdNJ/X3/Rh533fK1sOTEEbSsWUvW6iSkZef
|
|
||||||
rsfZBVP32xBhRWkKRdLeLB4W99ADMa0IrTmZPCXHSSE2V4e1o6zWLXcOZeH1Qh8N
|
|
||||||
SkelBweR+8r1Fbvy1r3s7eH7DCbYoGEDVLQGOLvzHKBisQHmoDnnF5E9g1eeNRdg
|
|
||||||
o+vhOKfYCOzeNREJIqS42PHcGhdNRk90ycigPmfUJclz1mDHoMjKR2S5oosTpr65
|
|
||||||
tNPx3CL7GA==
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,19 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDBDCCAeygAwIBAgIBAzANBgkqhkiG9w0BAQsFADA8MTowOAYDVQQDDDFNeVNR
|
|
||||||
TF9TZXJ2ZXJfOC4wLjE5X0F1dG9fR2VuZXJhdGVkX0NBX0NlcnRpZmljYXRlMB4X
|
|
||||||
DTIwMDYxMTAzMzg0N1oXDTMwMDYwOTAzMzg0N1owQDE+MDwGA1UEAww1TXlTUUxf
|
|
||||||
U2VydmVyXzguMC4xOV9BdXRvX0dlbmVyYXRlZF9DbGllbnRfQ2VydGlmaWNhdGUw
|
|
||||||
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVYSWpOvCTupz82fc85Opv
|
|
||||||
EQ7rkB8X2oOMyBCpkyHKBIr1ZQgRDWBp9UVOASq3GnSElm6+T3Kb1QbOffa8GIlw
|
|
||||||
sjAueKdq5L2eSkmPIEQ7eoO5kEW+4V866hE1LeL/PmHg2lGP0iqZiJYtElhHNQO8
|
|
||||||
3y9I7cm3xWMAA3SSWikVtpJRn3qIp2QSrH+tK+/HHbE5QwtPxdir4ULSCSOaM5Yh
|
|
||||||
Wi5Oto88TZqe1v7SXC864JVvO4LuS7TuSreCdWZyPXTJFBFeCEWSAxonKZrqHbBe
|
|
||||||
CwKML6/0NuzjaQ51c2tzmVI6xpHj3nnu4cSRx6Jf9WBm+35vm0wk4pohX3ptdzeV
|
|
||||||
AgMBAAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAByQ5zSNeFUH
|
|
||||||
Aw7JlpZHtHaSEeiiyBHke20ziQ07BK1yi/ms2HAWwQkpZv149sjNuIRH8pkTmkZn
|
|
||||||
g8PDzSefjLbC9AsWpWV0XNV22T/cdobqLqMBDDZ2+5bsV+jTrOigWd9/AHVZ93PP
|
|
||||||
IJN8HJn6rtvo2l1bh/CdsX14uVSdofXnuWGabNTydqtMvmCerZsdf6qKqLL+PYwm
|
|
||||||
RDpgWiRUY7KPBSSlKm/9lJzA+bOe4dHeJzxWFVCJcbpoiTFs1je1V8kKQaHtuW39
|
|
||||||
ifX6LTKUMlwEECCbDKM8Yq2tm8NjkjCcnFDtKg8zKGPUu+jrFMN5otiC3wnKcP7r
|
|
||||||
O9EkaPcgYH8=
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,27 +0,0 @@
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
MIIEowIBAAKCAQEA1WElqTrwk7qc/Nn3POTqbxEO65AfF9qDjMgQqZMhygSK9WUI
|
|
||||||
EQ1gafVFTgEqtxp0hJZuvk9ym9UGzn32vBiJcLIwLninauS9nkpJjyBEO3qDuZBF
|
|
||||||
vuFfOuoRNS3i/z5h4NpRj9IqmYiWLRJYRzUDvN8vSO3Jt8VjAAN0klopFbaSUZ96
|
|
||||||
iKdkEqx/rSvvxx2xOUMLT8XYq+FC0gkjmjOWIVouTraPPE2antb+0lwvOuCVbzuC
|
|
||||||
7ku07kq3gnVmcj10yRQRXghFkgMaJyma6h2wXgsCjC+v9Dbs42kOdXNrc5lSOsaR
|
|
||||||
49557uHEkceiX/VgZvt+b5tMJOKaIV96bXc3lQIDAQABAoIBAF7yjXmSOn7h6P0y
|
|
||||||
WCuGiTLG2mbDiLJqj2LTm2Z5i+2Cu/qZ7E76Ls63TxF4v3MemH5vGfQhEhR5ZD/6
|
|
||||||
GRJ1sKKvB3WGRqjwA9gtojHH39S/nWGy6vYW/vMOOH37XyjIr3EIdIaUtFQBTSHd
|
|
||||||
Kd71niYrAbVn6fyWHolhADwnVmTMOl5OOAhCdEF4GN3b5aIhIu8BJ7EUzTtHBJIj
|
|
||||||
CAEfjZFjDs1y1cIgGFJkuIQxMfCpq5recU2qwip7YO6fk//WEjOPu7kSf5IEswL8
|
|
||||||
jg1dea9rGBV6KaD2xsgsC6Ll6Sb4BbsrHMfflG3K2Lk3RdVqqTFp1Fn1PTLQE/1S
|
|
||||||
S/SZPYECgYEA9qYcHKHd0+Q5Ty5wgpxKGa4UCWkpwvfvyv4bh8qlmxueB+l2AIdo
|
|
||||||
ZvkM8gTPagPQ3WypAyC2b9iQu70uOJo1NizTtKnpjDdN1YpDjISJuS/P0x73gZwy
|
|
||||||
gmoM5AzMtN4D6IbxXtXnPaYICvwLKU80ouEN5ZPM4/ODLUu6gsp0v2UCgYEA3Xgi
|
|
||||||
zMC4JF0vEKEaK0H6QstaoXUmw/lToZGH3TEojBIkb/2LrHUclygtONh9kJSFb89/
|
|
||||||
jbmRRLAOrx3HZKCNGUmF4H9k5OQyAIv6OGBinvLGqcbqnyNlI+Le8zxySYwKMlEj
|
|
||||||
EMrBCLmSyi0CGFrbZ3mlj/oCET/ql9rNvcK+DHECgYAEx5dH3sMjtgp+RFId1dWB
|
|
||||||
xePRgt4yTwewkVgLO5wV82UOljGZNQaK6Eyd7AXw8f38LHzh+KJQbIvxd2sL4cEi
|
|
||||||
OaAoohpKg0/Y0YMZl//rPMf0OWdmdZZs/I0fZjgZUSwWN3c59T8z7KG/RL8an9RP
|
|
||||||
S7kvN7wCttdV61/D5RR6GQKBgDxCe/WKWpBKaovzydMLWLTj7/0Oi0W3iXHkzzr4
|
|
||||||
LTgvl4qBSofaNbVLUUKuZTv5rXUG2IYPf99YqCYtzBstNDc1MiAriaBeFtzfOW4t
|
|
||||||
i6gEFtoLLbuvPc3N5Sv5vn8Ug5G9UfU3td5R4AbyyCcoUZqOFuZd+EIJSiOXfXOs
|
|
||||||
kVmBAoGBAIU9aPAqhU5LX902oq8KsrpdySONqv5mtoStvl3wo95WIqXNEsFY60wO
|
|
||||||
q02jKQmJJ2MqhkJm2EoF2Mq8+40EZ5sz8LdgeQ/M0yQ9lAhPi4rftwhpe55Ma9dk
|
|
||||||
SE9X1c/DMCBEaIjJqVXdy0/EeArwpb8sHkguVVAZUWxzD+phm1gs
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
|
@ -1,21 +0,0 @@
|
||||||
# - Connection Settings -
|
|
||||||
|
|
||||||
listen_addresses = '*'
|
|
||||||
port = 5432 # (change requires restart)
|
|
||||||
max_connections = 100 # (change requires restart)
|
|
||||||
# - SSL -
|
|
||||||
|
|
||||||
ssl = on
|
|
||||||
ssl_cert_file = '/etc/postgresql/server-cert.pem'
|
|
||||||
ssl_key_file = '/etc/postgresql/server-key.pem'
|
|
||||||
shared_buffers = 128MB # min 128kB
|
|
||||||
checkpoint_timeout = 5min # range 30s-1d
|
|
||||||
max_wal_size = 1GB
|
|
||||||
min_wal_size = 80MB
|
|
||||||
datestyle = 'iso, mdy'
|
|
||||||
timezone = 'Etc/UTC'
|
|
||||||
lc_messages = 'en_US.utf8' # locale for system error message
|
|
||||||
lc_monetary = 'en_US.utf8' # locale for monetary formatting
|
|
||||||
lc_numeric = 'en_US.utf8' # locale for number formatting
|
|
||||||
lc_time = 'en_US.utf8' # locale for time formatting
|
|
||||||
default_text_search_config = 'pg_catalog.english'
|
|
|
@ -1,19 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDBDCCAeygAwIBAgIBAjANBgkqhkiG9w0BAQsFADA8MTowOAYDVQQDDDFNeVNR
|
|
||||||
TF9TZXJ2ZXJfOC4wLjE5X0F1dG9fR2VuZXJhdGVkX0NBX0NlcnRpZmljYXRlMB4X
|
|
||||||
DTIwMDYxMTAzMzg0NloXDTMwMDYwOTAzMzg0NlowQDE+MDwGA1UEAww1TXlTUUxf
|
|
||||||
U2VydmVyXzguMC4xOV9BdXRvX0dlbmVyYXRlZF9TZXJ2ZXJfQ2VydGlmaWNhdGUw
|
|
||||||
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCcEnEm5hqP1EbEJycOz8Ua
|
|
||||||
NWp29QdpFUzTWhkKGhVXk+0msmNTw4NBAFB42moY44OU8wvDideOlJNhPRWveD8z
|
|
||||||
G2lxzJA91p0UK4et8ia9MmeuCGhdC9jxJ8X69WNlUiPyy0hI/ZsqRq9Z0C2eW0iL
|
|
||||||
JPXsy4X8Xpw3SFwoXf5pR9RFY5Pb2tuyxqmSestu2VXT/NQjJg4CVDR3mFcHPXZB
|
|
||||||
4elRzH0WshExEGkgy0bg20MJeRc2Qdb5Xx+EakbmwroDWaCn3NSGqQ7jv6Vw0doy
|
|
||||||
TGvS6h6RHBxnyqRfRgKGlCoOMG9/5+rFJC00QpCUG2vHXHWGoWlMlJ3foN7rj5v9
|
|
||||||
AgMBAAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAJ5zt2rj4Ag6
|
|
||||||
zpN59AWC1Fur8g8l41ksHkSpKPp+PtyO/ngvbMqBpfmK1e7JCKZv/68QXfMyWWAI
|
|
||||||
hwalqZkXXWHKjuz3wE7dE25PXFXtGJtcZAaj10xt98fzdqt8lQSwh2kbfNwZIz1F
|
|
||||||
sgAStgE7+ZTcqTgvNB76Os1UK0to+/P0VBWktaVFdyub4Nc2SdPVnZNvrRBXBwOD
|
|
||||||
3V8ViwywDOFoE7DvCvwx/SVsvoC0Z4j3AMMovO6oHicP7uU83qsQgm1Qru3YeoLR
|
|
||||||
+DoVi7IPHbWvN7MqFYn3YjNlByO2geblY7MR0BlqbFlmFrqLsUfjsh2ys7/U/knC
|
|
||||||
dN/klu446fI=
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,27 +0,0 @@
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
MIIEowIBAAKCAQEAnBJxJuYaj9RGxCcnDs/FGjVqdvUHaRVM01oZChoVV5PtJrJj
|
|
||||||
U8ODQQBQeNpqGOODlPMLw4nXjpSTYT0Vr3g/MxtpccyQPdadFCuHrfImvTJnrgho
|
|
||||||
XQvY8SfF+vVjZVIj8stISP2bKkavWdAtnltIiyT17MuF/F6cN0hcKF3+aUfURWOT
|
|
||||||
29rbssapknrLbtlV0/zUIyYOAlQ0d5hXBz12QeHpUcx9FrIRMRBpIMtG4NtDCXkX
|
|
||||||
NkHW+V8fhGpG5sK6A1mgp9zUhqkO47+lcNHaMkxr0uoekRwcZ8qkX0YChpQqDjBv
|
|
||||||
f+fqxSQtNEKQlBtrx1x1hqFpTJSd36De64+b/QIDAQABAoIBAFiah66Dt9SruLkn
|
|
||||||
WR8piUaFyLlcBib8Nq9OWSTJBhDAJERxxb4KIvvGB+l0ZgNXNp5bFPSfzsZdRwZP
|
|
||||||
PX5uj8Kd71Dxx3mz211WESMJdEC42u+MSmN4lGLkJ5t/sDwXU91E1vbJM0ve8THV
|
|
||||||
4/Ag9qA4DX2vVZOeyqT/6YHpSsPNZplqzrbAiwrfHwkctHfgqwOf3QLfhmVQgfCS
|
|
||||||
VwidBldEUv2whSIiIxh4Rv5St4kA68IBCbJxdpOpyuQBkk6CkxZ7VN9FqOuSd4Pk
|
|
||||||
Wm7iWyBMZsCmELZh5XAXld4BEt87C5R4CvbPBDZxAv3THk1DNNvpy3PFQfwARRFb
|
|
||||||
SAToYMECgYEAyL7U8yxpzHDYWd3oCx6vTi9p9N/z0FfAkWrRF6dm4UcSklNiT1Aq
|
|
||||||
EOnTA+SaW8tV3E64gCWcY23gNP8so/ZseWj6L+peHwtchaP9+KB7yGw2A+05+lOx
|
|
||||||
VetLTjAOmfpiUXFe5w1q4C1RGhLjZjjzW+GvwdAuchQgUEFaomrV+PUCgYEAxwfH
|
|
||||||
cmVGFbAktcjU4HSRjKSfawCrut+3YUOLybyku3Q/hP9amG8qkVTFe95CTLjLe2D0
|
|
||||||
ccaTTpofFEJ32COeck0g0Ujn/qQ+KXRoauOYs4FB1DtqMpqB78wufWEUpDpbd9/h
|
|
||||||
J+gJdC/IADd4tJW9zA92g8IA7ZtFmqDtiSpQ0ekCgYAQGkaorvJZpN+l7cf0RGTZ
|
|
||||||
h7IfI2vCVZer0n6tQA9fmLzjoe6r4AlPzAHSOR8sp9XeUy43kUzHKQQoHCPvjw/K
|
|
||||||
eWJAP7OHF/k2+x2fOPhU7mEy1W+mJdp+wt4Kio5RSaVjVQ3AyPG+w8PSrJszEvRq
|
|
||||||
dWMMz+851WV2KpfjmWBKlQKBgQC++4j4DZQV5aMkSKV1CIZOBf3vaIJhXKEUFQPD
|
|
||||||
PmB4fBEjpwCg+zNGp6iktt65zi17o8qMjrb1mtCt2SY04eD932LZUHNFlwcLMmes
|
|
||||||
Ad+aiDLJ24WJL1f16eDGcOyktlblDZB5gZ/ovJzXEGOkLXglosTfo77OQculmDy2
|
|
||||||
/UL2WQKBgGeKasmGNfiYAcWio+KXgFkHXWtAXB9B91B1OFnCa40wx+qnl71MIWQH
|
|
||||||
PQ/CZFNWOfGiNEJIZjrHsfNJoeXkhq48oKcT0AVCDYyLV0VxDO4ejT95mGW6njNd
|
|
||||||
JpvmhwwAjOvuWVr0tn4iXlSK8irjlJHmwcRjLTJq97vE9fsA2MjI
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
|
@ -83,6 +83,7 @@ The MQTT message will be translated to an LwM2M DISCOVER command and sent to the
|
||||||
- "register": LwM2M Register
|
- "register": LwM2M Register
|
||||||
- "update": LwM2M Update
|
- "update": LwM2M Update
|
||||||
- "data" contains the query options and the object-list of the register message
|
- "data" contains the query options and the object-list of the register message
|
||||||
|
- The *update* message is only published if the object-list changed.
|
||||||
|
|
||||||
### Downlink Command and Uplink Response (LwM2M Device Management & Service Enablement Interface)
|
### Downlink Command and Uplink Response (LwM2M Device Management & Service Enablement Interface)
|
||||||
|
|
||||||
|
@ -113,6 +114,7 @@ The MQTT message will be translated to an LwM2M DISCOVER command and sent to the
|
||||||
"path": {?ResourcePath}
|
"path": {?ResourcePath}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
- {?ResourcePath}: String, LwM2M full resource path. e.g. "3/0", "/3/0/0", "/3/0/6/0"
|
||||||
- **If {?MsgType} = "write" (single write)**:
|
- **If {?MsgType} = "write" (single write)**:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
@ -121,6 +123,8 @@ The MQTT message will be translated to an LwM2M DISCOVER command and sent to the
|
||||||
"value": {?Value}
|
"value": {?Value}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
- {?ValueType}: String, can be: "Time", "String", "Integer", "Float", "Boolean", "Opaque", "Objlnk"
|
||||||
|
- {?Value}: Value of the resource, depends on "type".
|
||||||
- **If {?MsgType} = "write" (batch write)**:
|
- **If {?MsgType} = "write" (batch write)**:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
@ -183,21 +187,6 @@ The MQTT message will be translated to an LwM2M DISCOVER command and sent to the
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- {?ObjectInstanceID}: Integer, LwM2M Object Instance ID
|
- {?ObjectInstanceID}: Integer, LwM2M Object Instance ID
|
||||||
- {?ResourcePath}: String, LwM2M full resource path. e.g. "3/0", "/3/0/0", "/3/0/6/0"
|
|
||||||
- {?Content}:
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"name": {?ResourceName},
|
|
||||||
"path": {?ResourcePath},
|
|
||||||
"type": {?ValueType},
|
|
||||||
"value": {?Value}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
- {?ResourceName}: String, LwM2M resource description, e.g. "Available Power Sources"
|
|
||||||
- {?ValueType}: String, can be: "Time", "String", "Integer", "Float", "Boolean", "Opaque", "Objlnk"
|
|
||||||
- {?Value}: Value of resource, depends on the {?ValueType}.
|
|
||||||
|
|
||||||
- **The response of LwM2M will be converted to following MQTT message:**
|
- **The response of LwM2M will be converted to following MQTT message:**
|
||||||
- **Method:** PUBLISH
|
- **Method:** PUBLISH
|
||||||
|
@ -262,17 +251,11 @@ The MQTT message will be translated to an LwM2M DISCOVER command and sent to the
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": {?ResourceName},
|
|
||||||
"path": {?ResourcePath},
|
"path": {?ResourcePath},
|
||||||
"type": {?ValueType},
|
|
||||||
"value": {?Value}
|
"value": {?Value}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
- {?ResourceName}: String, LwM2M resource description, e.g. "Available Power Sources"
|
|
||||||
- {?ResourcePath}: String, LwM2M resource full path. e.g. "3/0", "/3/0/0", "/3/0/6/0"
|
|
||||||
- {?ValueType}: String, can be: "Time", "String", "Integer", "Float", "Boolean", "Opaque", "Objlnk"
|
|
||||||
- {?Value}: Value of the resource, depends on "type".
|
|
||||||
|
|
||||||
- **If {?MsgType} = "ack", "data" does not exists**
|
- **If {?MsgType} = "ack", "data" does not exists**
|
||||||
|
|
||||||
|
@ -308,11 +291,10 @@ The MQTT message will be translated to an LwM2M DISCOVER command and sent to the
|
||||||
"data": {
|
"data": {
|
||||||
"code": {?StatusCode},
|
"code": {?StatusCode},
|
||||||
"codeMsg": {?CodeMsg},
|
"codeMsg": {?CodeMsg},
|
||||||
|
"reqPath": {?RequestPath},
|
||||||
"content": [
|
"content": [
|
||||||
{
|
{
|
||||||
"name": {?ResourceName},
|
|
||||||
"path": {?ResourcePath},
|
"path": {?ResourcePath},
|
||||||
"type": {?ValueType},
|
|
||||||
"value": {?Value}
|
"value": {?Value}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -338,11 +320,12 @@ The MQTT message will be translated to an LwM2M DISCOVER command and sent to the
|
||||||
"data": {
|
"data": {
|
||||||
"code": {?StatusCode},
|
"code": {?StatusCode},
|
||||||
"codeMsg": {?CodeMsg},
|
"codeMsg": {?CodeMsg},
|
||||||
|
"reqPath": {?RequestPath},
|
||||||
"content": [
|
"content": [
|
||||||
"name": {?ResourceName},
|
{
|
||||||
"path": {?ResourcePath},
|
"path": {?ResourcePath},
|
||||||
"type": {?ValueType},
|
"value": {?Value}
|
||||||
"value": {?Value}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -571,7 +571,7 @@ get_alarms(Type) ->
|
||||||
[{Node, get_alarms(Node, Type)} || Node <- ekka_mnesia:running_nodes()].
|
[{Node, get_alarms(Node, Type)} || Node <- ekka_mnesia:running_nodes()].
|
||||||
|
|
||||||
get_alarms(Node, Type) when Node =:= node() ->
|
get_alarms(Node, Type) when Node =:= node() ->
|
||||||
emqx_alarm:get_alarms(Type);
|
add_duration_field(emqx_alarm:get_alarms(Type));
|
||||||
get_alarms(Node, Type) ->
|
get_alarms(Node, Type) ->
|
||||||
rpc_call(Node, get_alarms, [Node, Type]).
|
rpc_call(Node, get_alarms, [Node, Type]).
|
||||||
|
|
||||||
|
@ -588,6 +588,17 @@ delete_all_deactivated_alarms(Node) when Node =:= node() ->
|
||||||
delete_all_deactivated_alarms(Node) ->
|
delete_all_deactivated_alarms(Node) ->
|
||||||
rpc_call(Node, delete_deactivated_alarms, [Node]).
|
rpc_call(Node, delete_deactivated_alarms, [Node]).
|
||||||
|
|
||||||
|
add_duration_field(Alarms) ->
|
||||||
|
Now = erlang:system_time(microsecond),
|
||||||
|
add_duration_field(Alarms, Now, []).
|
||||||
|
|
||||||
|
add_duration_field([], _Now, Acc) ->
|
||||||
|
Acc;
|
||||||
|
add_duration_field([Alarm = #{activated := true, activate_at := ActivateAt}| Rest], Now, Acc) ->
|
||||||
|
add_duration_field(Rest, Now, [Alarm#{duration => Now - ActivateAt} | Acc]);
|
||||||
|
add_duration_field([Alarm = #{activated := false, activate_at := ActivateAt, deactivate_at := DeactivateAt}| Rest], Now, Acc) ->
|
||||||
|
add_duration_field(Rest, Now, [Alarm#{duration => DeactivateAt - ActivateAt} | Acc]).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Banned API
|
%% Banned API
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -48,6 +48,229 @@ json data
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Before EMQ X v4.0.0
|
||||||
|
The prometheus data simple is:
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# TYPE erlang_vm_ets_limit gauge
|
||||||
|
erlang_vm_ets_limit 2097152
|
||||||
|
# TYPE erlang_vm_logical_processors gauge
|
||||||
|
erlang_vm_logical_processors 2
|
||||||
|
# TYPE erlang_vm_logical_processors_available gauge
|
||||||
|
erlang_vm_logical_processors_available 2
|
||||||
|
# TYPE erlang_vm_logical_processors_online gauge
|
||||||
|
erlang_vm_logical_processors_online 2
|
||||||
|
# TYPE erlang_vm_port_count gauge
|
||||||
|
erlang_vm_port_count 19
|
||||||
|
# TYPE erlang_vm_port_limit gauge
|
||||||
|
erlang_vm_port_limit 1048576
|
||||||
|
# TYPE erlang_vm_process_count gauge
|
||||||
|
erlang_vm_process_count 460
|
||||||
|
# TYPE erlang_vm_process_limit gauge
|
||||||
|
erlang_vm_process_limit 2097152
|
||||||
|
# TYPE erlang_vm_schedulers gauge
|
||||||
|
erlang_vm_schedulers 2
|
||||||
|
# TYPE erlang_vm_schedulers_online gauge
|
||||||
|
erlang_vm_schedulers_online 2
|
||||||
|
# TYPE erlang_vm_smp_support untyped
|
||||||
|
erlang_vm_smp_support 1
|
||||||
|
# TYPE erlang_vm_threads untyped
|
||||||
|
erlang_vm_threads 1
|
||||||
|
# TYPE erlang_vm_thread_pool_size gauge
|
||||||
|
erlang_vm_thread_pool_size 32
|
||||||
|
# TYPE erlang_vm_time_correction untyped
|
||||||
|
erlang_vm_time_correction 1
|
||||||
|
# TYPE erlang_vm_statistics_context_switches counter
|
||||||
|
erlang_vm_statistics_context_switches 39850
|
||||||
|
# TYPE erlang_vm_statistics_garbage_collection_number_of_gcs counter
|
||||||
|
erlang_vm_statistics_garbage_collection_number_of_gcs 17116
|
||||||
|
# TYPE erlang_vm_statistics_garbage_collection_words_reclaimed counter
|
||||||
|
erlang_vm_statistics_garbage_collection_words_reclaimed 55711819
|
||||||
|
# TYPE erlang_vm_statistics_garbage_collection_bytes_reclaimed counter
|
||||||
|
erlang_vm_statistics_garbage_collection_bytes_reclaimed 445694552
|
||||||
|
# TYPE erlang_vm_statistics_bytes_received_total counter
|
||||||
|
erlang_vm_statistics_bytes_received_total 400746
|
||||||
|
# TYPE erlang_vm_statistics_bytes_output_total counter
|
||||||
|
erlang_vm_statistics_bytes_output_total 337197
|
||||||
|
# TYPE erlang_vm_statistics_reductions_total counter
|
||||||
|
erlang_vm_statistics_reductions_total 21157980
|
||||||
|
# TYPE erlang_vm_statistics_run_queues_length_total gauge
|
||||||
|
erlang_vm_statistics_run_queues_length_total 0
|
||||||
|
# TYPE erlang_vm_statistics_runtime_milliseconds counter
|
||||||
|
erlang_vm_statistics_runtime_milliseconds 6559
|
||||||
|
# TYPE erlang_vm_statistics_wallclock_time_milliseconds counter
|
||||||
|
erlang_vm_statistics_wallclock_time_milliseconds 261243
|
||||||
|
# TYPE erlang_vm_memory_atom_bytes_total gauge
|
||||||
|
erlang_vm_memory_atom_bytes_total{usage="used"} 1814822
|
||||||
|
erlang_vm_memory_atom_bytes_total{usage="free"} 22459
|
||||||
|
# TYPE erlang_vm_memory_bytes_total gauge
|
||||||
|
erlang_vm_memory_bytes_total{kind="system"} 109820104
|
||||||
|
erlang_vm_memory_bytes_total{kind="processes"} 44983656
|
||||||
|
# TYPE erlang_vm_dets_tables gauge
|
||||||
|
erlang_vm_dets_tables 1
|
||||||
|
# TYPE erlang_vm_ets_tables gauge
|
||||||
|
erlang_vm_ets_tables 139
|
||||||
|
# TYPE erlang_vm_memory_processes_bytes_total gauge
|
||||||
|
erlang_vm_memory_processes_bytes_total{usage="used"} 44983656
|
||||||
|
erlang_vm_memory_processes_bytes_total{usage="free"} 0
|
||||||
|
# TYPE erlang_vm_memory_system_bytes_total gauge
|
||||||
|
erlang_vm_memory_system_bytes_total{usage="atom"} 1837281
|
||||||
|
erlang_vm_memory_system_bytes_total{usage="binary"} 595872
|
||||||
|
erlang_vm_memory_system_bytes_total{usage="code"} 40790577
|
||||||
|
erlang_vm_memory_system_bytes_total{usage="ets"} 37426896
|
||||||
|
erlang_vm_memory_system_bytes_total{usage="other"} 29169478
|
||||||
|
# TYPE erlang_mnesia_held_locks gauge
|
||||||
|
erlang_mnesia_held_locks 0
|
||||||
|
# TYPE erlang_mnesia_lock_queue gauge
|
||||||
|
erlang_mnesia_lock_queue 0
|
||||||
|
# TYPE erlang_mnesia_transaction_participants gauge
|
||||||
|
erlang_mnesia_transaction_participants 0
|
||||||
|
# TYPE erlang_mnesia_transaction_coordinators gauge
|
||||||
|
erlang_mnesia_transaction_coordinators 0
|
||||||
|
# TYPE erlang_mnesia_failed_transactions counter
|
||||||
|
erlang_mnesia_failed_transactions 2
|
||||||
|
# TYPE erlang_mnesia_committed_transactions counter
|
||||||
|
erlang_mnesia_committed_transactions 239
|
||||||
|
# TYPE erlang_mnesia_logged_transactions counter
|
||||||
|
erlang_mnesia_logged_transactions 60
|
||||||
|
# TYPE erlang_mnesia_restarted_transactions counter
|
||||||
|
erlang_mnesia_restarted_transactions 0
|
||||||
|
# TYPE emqx_packets_auth_received counter
|
||||||
|
emqx_packets_auth_received 0
|
||||||
|
# TYPE emqx_packets_auth_sent counter
|
||||||
|
emqx_packets_auth_sent 0
|
||||||
|
# TYPE emqx_packets_received counter
|
||||||
|
emqx_packets_received 0
|
||||||
|
# TYPE emqx_packets_sent counter
|
||||||
|
emqx_packets_sent 0
|
||||||
|
# TYPE emqx_packets_connect counter
|
||||||
|
emqx_packets_connect 0
|
||||||
|
# TYPE emqx_packets_connack_sent counter
|
||||||
|
emqx_packets_connack_sent 0
|
||||||
|
# TYPE emqx_packets_connack_error counter
|
||||||
|
emqx_packets_connack_error 0
|
||||||
|
# TYPE emqx_packets_connack_auth_error counter
|
||||||
|
emqx_packets_connack_auth_error 0
|
||||||
|
# TYPE emqx_packets_disconnect_received counter
|
||||||
|
emqx_packets_disconnect_received 0
|
||||||
|
# TYPE emqx_packets_disconnect_sent counter
|
||||||
|
emqx_packets_disconnect_sent 0
|
||||||
|
# TYPE emqx_packets_subscribe counter
|
||||||
|
emqx_packets_subscribe 0
|
||||||
|
# TYPE emqx_packets_subscribe_error counter
|
||||||
|
emqx_packets_subscribe_error 0
|
||||||
|
# TYPE emqx_packets_subscribe_auth_error counter
|
||||||
|
emqx_packets_subscribe_auth_error 0
|
||||||
|
# TYPE emqx_packets_suback counter
|
||||||
|
emqx_packets_suback 0
|
||||||
|
# TYPE emqx_packets_unsubscribe counter
|
||||||
|
emqx_packets_unsubscribe 0
|
||||||
|
# TYPE emqx_packets_unsubscribe_error counter
|
||||||
|
emqx_packets_unsubscribe_error 0
|
||||||
|
# TYPE emqx_packets_unsuback counter
|
||||||
|
emqx_packets_unsuback 0
|
||||||
|
# TYPE emqx_packets_publish_received counter
|
||||||
|
emqx_packets_publish_received 0
|
||||||
|
# TYPE emqx_packets_publish_sent counter
|
||||||
|
emqx_packets_publish_sent 0
|
||||||
|
# TYPE emqx_packets_publish_auth_error counter
|
||||||
|
emqx_packets_publish_auth_error 0
|
||||||
|
# TYPE emqx_packets_publish_error counter
|
||||||
|
emqx_packets_publish_error 0
|
||||||
|
# TYPE emqx_packets_puback_received counter
|
||||||
|
emqx_packets_puback_received 0
|
||||||
|
# TYPE emqx_packets_puback_sent counter
|
||||||
|
emqx_packets_puback_sent 0
|
||||||
|
# TYPE emqx_packets_puback_missed counter
|
||||||
|
emqx_packets_puback_missed 0
|
||||||
|
# TYPE emqx_packets_pubrec_received counter
|
||||||
|
emqx_packets_pubrec_received 0
|
||||||
|
# TYPE emqx_packets_pubrec_sent counter
|
||||||
|
emqx_packets_pubrec_sent 0
|
||||||
|
# TYPE emqx_packets_pubrec_missed counter
|
||||||
|
emqx_packets_pubrec_missed 0
|
||||||
|
# TYPE emqx_packets_pubrel_received counter
|
||||||
|
emqx_packets_pubrel_received 0
|
||||||
|
# TYPE emqx_packets_pubrel_sent counter
|
||||||
|
emqx_packets_pubrel_sent 0
|
||||||
|
# TYPE emqx_packets_pubrel_missed counter
|
||||||
|
emqx_packets_pubrel_missed 0
|
||||||
|
# TYPE emqx_packets_pubcomp_received counter
|
||||||
|
emqx_packets_pubcomp_received 0
|
||||||
|
# TYPE emqx_packets_pubcomp_sent counter
|
||||||
|
emqx_packets_pubcomp_sent 0
|
||||||
|
# TYPE emqx_packets_pubcomp_missed counter
|
||||||
|
emqx_packets_pubcomp_missed 0
|
||||||
|
# TYPE emqx_packets_pingreq counter
|
||||||
|
emqx_packets_pingreq 0
|
||||||
|
# TYPE emqx_packets_pingresp counter
|
||||||
|
emqx_packets_pingresp 0
|
||||||
|
# TYPE emqx_bytes_received counter
|
||||||
|
emqx_bytes_received 0
|
||||||
|
# TYPE emqx_bytes_sent counter
|
||||||
|
emqx_bytes_sent 0
|
||||||
|
# TYPE emqx_connections_count gauge
|
||||||
|
emqx_connections_count 0
|
||||||
|
# TYPE emqx_connections_max gauge
|
||||||
|
emqx_connections_max 0
|
||||||
|
# TYPE emqx_retained_count gauge
|
||||||
|
emqx_retained_count 3
|
||||||
|
# TYPE emqx_retained_max gauge
|
||||||
|
emqx_retained_max 3
|
||||||
|
# TYPE emqx_routes_count gauge
|
||||||
|
emqx_routes_count 0
|
||||||
|
# TYPE emqx_routes_max gauge
|
||||||
|
emqx_routes_max 0
|
||||||
|
# TYPE emqx_sessions_count gauge
|
||||||
|
emqx_sessions_count 0
|
||||||
|
# TYPE emqx_sessions_max gauge
|
||||||
|
emqx_sessions_max 0
|
||||||
|
# TYPE emqx_subscriptions_count gauge
|
||||||
|
emqx_subscriptions_count 0
|
||||||
|
# TYPE emqx_subscriptions_max gauge
|
||||||
|
emqx_subscriptions_max 0
|
||||||
|
# TYPE emqx_topics_count gauge
|
||||||
|
emqx_topics_count 0
|
||||||
|
# TYPE emqx_topics_max gauge
|
||||||
|
emqx_topics_max 0
|
||||||
|
# TYPE emqx_vm_cpu_use gauge
|
||||||
|
emqx_vm_cpu_use 100.0
|
||||||
|
# TYPE emqx_vm_cpu_idle gauge
|
||||||
|
emqx_vm_cpu_idle 0.0
|
||||||
|
# TYPE emqx_vm_run_queue gauge
|
||||||
|
emqx_vm_run_queue 1
|
||||||
|
# TYPE emqx_vm_process_messages_in_queues gauge
|
||||||
|
emqx_vm_process_messages_in_queues 0
|
||||||
|
# TYPE emqx_messages_received counter
|
||||||
|
emqx_messages_received 0
|
||||||
|
# TYPE emqx_messages_sent counter
|
||||||
|
emqx_messages_sent 0
|
||||||
|
# TYPE emqx_messages_dropped counter
|
||||||
|
emqx_messages_dropped 0
|
||||||
|
# TYPE emqx_messages_retained counter
|
||||||
|
emqx_messages_retained 3
|
||||||
|
# TYPE emqx_messages_qos0_received counter
|
||||||
|
emqx_messages_qos0_received 0
|
||||||
|
# TYPE emqx_messages_qos0_sent counter
|
||||||
|
emqx_messages_qos0_sent 0
|
||||||
|
# TYPE emqx_messages_qos1_received counter
|
||||||
|
emqx_messages_qos1_received 0
|
||||||
|
# TYPE emqx_messages_qos1_sent counter
|
||||||
|
emqx_messages_qos1_sent 0
|
||||||
|
# TYPE emqx_messages_qos2_received counter
|
||||||
|
emqx_messages_qos2_received 0
|
||||||
|
# TYPE emqx_messages_qos2_expired counter
|
||||||
|
emqx_messages_qos2_expired 0
|
||||||
|
# TYPE emqx_messages_qos2_sent counter
|
||||||
|
emqx_messages_qos2_sent 0
|
||||||
|
# TYPE emqx_messages_qos2_dropped counter
|
||||||
|
emqx_messages_qos2_dropped 0
|
||||||
|
# TYPE emqx_messages_forward counter
|
||||||
|
emqx_messages_forward 0
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue