From 077ef073e5469c3de5eef15c8073ab5329f2bb4e Mon Sep 17 00:00:00 2001 From: ieQu1 <99872536+ieQu1@users.noreply.github.com> Date: Wed, 23 Mar 2022 16:44:06 +0100 Subject: [PATCH 1/3] docs(schema): Add descriptions to the schema --- .../emqx_limiter/src/emqx_limiter_schema.erl | 10 +-- apps/emqx/src/emqx_schema.erl | 68 ++++++++++++++----- apps/emqx_conf/src/emqx_conf_schema.erl | 2 +- apps/emqx_dashboard/etc/emqx_dashboard.conf | 4 +- .../src/emqx_dashboard_schema.erl | 15 ++-- apps/emqx_exhook/src/emqx_exhook_schema.erl | 5 +- apps/emqx_gateway/src/emqx_gateway_schema.erl | 28 +++++--- .../src/emqx_retainer_schema.erl | 2 +- 8 files changed, 95 insertions(+), 39 deletions(-) diff --git a/apps/emqx/src/emqx_limiter/src/emqx_limiter_schema.erl b/apps/emqx/src/emqx_limiter/src/emqx_limiter_schema.erl index 8421a7399..498f862e0 100644 --- a/apps/emqx/src/emqx_limiter/src/emqx_limiter_schema.erl +++ b/apps/emqx/src/emqx_limiter/src/emqx_limiter_schema.erl @@ -114,10 +114,10 @@ fields(limiter_opts) -> ]; fields(bucket_opts) -> - [ {rate, sc(rate(), #{desc => "The rate for this bucket"})} - , {capacity, sc(capacity(), #{desc => "The maximum number of tokens for this bucket"})} + [ {rate, sc(rate(), #{desc => "Rate for this bucket."})} + , {capacity, sc(capacity(), #{desc => "The maximum number of tokens for this bucket."})} , {initial, sc(initial(), #{default => "0", - desc => "The initial number of tokens for this bucket"})} + desc => "The initial number of tokens for this bucket."})} , {per_client, sc(ref(client_bucket), #{default => #{}, desc => "The rate limit for each user of the bucket," @@ -126,8 +126,8 @@ fields(bucket_opts) -> ]; fields(client_bucket) -> - [ {rate, sc(rate(), #{default => "infinity"})} - , {initial, sc(initial(), #{default => "0"})} + [ {rate, sc(rate(), #{default => "infinity", desc => "Rate for this bucket."})} + , {initial, sc(initial(), #{default => "0", desc => "The initial number of tokens for this bucket."})} %% low_water_mark add for emqx_channel and emqx_session %% both modules consume first and then check %% so we need to use this value to prevent excessive consumption diff --git a/apps/emqx/src/emqx_schema.erl b/apps/emqx/src/emqx_schema.erl index 4219f8463..065c9b54b 100644 --- a/apps/emqx/src/emqx_schema.erl +++ b/apps/emqx/src/emqx_schema.erl @@ -100,6 +100,11 @@ -elvis([{elvis_style, god_modules, disable}]). +-define(IDLE_TIMOUT_DESC, + "Close transport-layer connections from the clients that have not sent MQTT CONNECT\n" + "message within this interval." +). + namespace() -> undefined. roots() -> @@ -786,7 +791,7 @@ fields("force_gc") -> {"enable", sc( boolean(), - #{default => true} + #{default => true, desc => "Enable forced garbage collection."} )}, {"count", sc( @@ -905,24 +910,24 @@ fields("mqtt_quic_listener") -> {"enabled", sc( boolean(), - #{default => true} + #{default => true, desc => "Enable QUIC listener."} )}, %% TODO: ensure cacertfile is configurable {"certfile", sc( string(), - #{} + #{desc => "Path to the certificate."} )}, {"keyfile", sc( string(), - #{} + #{desc => "Path to the secret key file."} )}, {"ciphers", ciphers_schema(quic)}, {"idle_timeout", sc( duration(), - #{default => "15s"} + #{default => "15s", desc => ?IDLE_TIMOUT_DESC} )} ] ++ base_listener(); fields("ws_opts") -> @@ -957,9 +962,7 @@ fields("ws_opts") -> duration(), #{ default => "15s", - desc => - "The idle time after the TCP connection is established
\n" - " If no packets are received within this time, the connection will be closed." + desc => ?IDLE_TIMOUT_DESC } )}, {"max_frame_size", @@ -1652,17 +1655,30 @@ mqtt_listener() -> {"access_rules", sc( hoconsc:array(string()), - #{} + #{ + desc => + "The access control rules for this listener.
" + "See: https://github.com/emqtt/esockd#allowdeny" + } )}, {"proxy_protocol", sc( boolean(), - #{default => false} + #{ + default => false, + desc => + "Enable the Proxy Protocol V1/2 if the EMQX cluster is deployed\n" + " behind HAProxy or Nginx.
" + "See: https://www.haproxy.com/blog/haproxy/proxy-protocol/" + } )}, {"proxy_protocol_timeout", sc( duration(), - #{} + #{ + desc => + "Timeout for proxy protocol. EMQX will close the TCP connection if proxy protocol packet is not received within the timeout." + } )}, {?EMQX_AUTHENTICATION_CONFIG_ROOT_NAME, authentication("Per-listener authentication override")} @@ -1762,7 +1778,10 @@ common_ssl_opts_schema(Defaults) -> {"enable", sc( boolean(), - #{default => Df("enable", false)} + #{ + default => Df("enable", false), + desc => "Enable TLS." + } )}, {"cacertfile", sc( @@ -1808,12 +1827,20 @@ common_ssl_opts_schema(Defaults) -> {"verify", sc( hoconsc:enum([verify_peer, verify_none]), - #{default => Df("verify", verify_none)} + #{ + default => Df("verify", verify_none), + desc => + "Enable or disable peer verification." + } )}, {"reuse_sessions", sc( boolean(), - #{default => Df("reuse_sessions", true)} + #{ + default => Df("reuse_sessions", true), + desc => + "Enable TLS session reuse." + } )}, {"depth", sc( @@ -1850,7 +1877,9 @@ common_ssl_opts_schema(Defaults) -> typerefl:alias("string", any()), #{ default => <<"emqx_tls_psk:lookup">>, - converter => fun ?MODULE:parse_user_lookup_fun/1 + converter => fun ?MODULE:parse_user_lookup_fun/1, + desc => + "EMQX-internal callback that is used to lookup pre-shared key (PSK) identity." } )}, {"secure_renegotiate", @@ -1905,7 +1934,14 @@ server_ssl_opts_schema(Defaults, IsRanchListener) -> {"honor_cipher_order", sc( boolean(), - #{default => Df("honor_cipher_order", true)} + #{ + default => Df("honor_cipher_order", true), + desc => + "An important security setting, it forces the cipher to be set based\n" + " on the server-specified order instead of the client-specified order,\n" + " hence enforcing the (usually more properly configured) security\n" + " ordering of the server administrator." + } )}, {"client_renegotiation", sc( diff --git a/apps/emqx_conf/src/emqx_conf_schema.erl b/apps/emqx_conf/src/emqx_conf_schema.erl index e1fdf2361..871dc5331 100644 --- a/apps/emqx_conf/src/emqx_conf_schema.erl +++ b/apps/emqx_conf/src/emqx_conf_schema.erl @@ -622,7 +622,7 @@ fields("log") -> [ {"console_handler", ref("console_handler")} , {"file_handlers", sc(map(name, ref("log_file_handler")), - #{})} + #{desc => "Key-value list of file-based log handlers."})} , {"error_logger", sc(atom(), #{mapping => "kernel.error_logger", diff --git a/apps/emqx_dashboard/etc/emqx_dashboard.conf b/apps/emqx_dashboard/etc/emqx_dashboard.conf index 0fb0184fe..7fcb319dd 100644 --- a/apps/emqx_dashboard/etc/emqx_dashboard.conf +++ b/apps/emqx_dashboard/etc/emqx_dashboard.conf @@ -5,10 +5,10 @@ dashboard { default_username = "admin" default_password = "public" - ## notice: sample_interval should be divisible by 60. + ## Note: sample_interval should be divisible by 60. ## like 1s, 2s, 3s, 5s, 10s, 12s, 15s, 20s, 30s, 60s sample_interval = 10s - ## api jwt timeout. default is 30 minute + ## JWT token expiration time. token_expired_time = 60m listeners = [ { diff --git a/apps/emqx_dashboard/src/emqx_dashboard_schema.erl b/apps/emqx_dashboard/src/emqx_dashboard_schema.erl index 36ec75963..16328716a 100644 --- a/apps/emqx_dashboard/src/emqx_dashboard_schema.erl +++ b/apps/emqx_dashboard/src/emqx_dashboard_schema.erl @@ -38,8 +38,15 @@ Alternatively, the HTTP listener can specify a unique IP address for each listen but use the same port."})} , {default_username, fun default_username/1} , {default_password, fun default_password/1} - , {sample_interval, sc(emqx_schema:duration_s(), #{default => "10s"})} - , {token_expired_time, sc(emqx_schema:duration(), #{default => "30m"})} + , {sample_interval, sc(emqx_schema:duration_s(), + #{ default => "10s" + , desc => "How often to update metrics displayed in the dashboard.
" + "Note: `sample_interval` should be divisible by 60." + })} + , {token_expired_time, sc(emqx_schema:duration(), + #{ default => "30m" + , desc => "JWT token expiration time." + })} , {cors, fun cors/1} ]; @@ -113,9 +120,9 @@ cors(type) -> boolean(); cors(default) -> false; cors(required) -> false; cors(desc) -> -"""Support Cross-Origin Resource Sharing (CORS). +"Support Cross-Origin Resource Sharing (CORS). Allows a server to indicate any origins (domain, scheme, or port) other than -its own from which a browser should permit loading resources."""; +its own from which a browser should permit loading resources."; cors(_) -> undefined. sc(Type, Meta) -> hoconsc:mk(Type, Meta). diff --git a/apps/emqx_exhook/src/emqx_exhook_schema.erl b/apps/emqx_exhook/src/emqx_exhook_schema.erl index e95a46beb..6cc1ebfcd 100644 --- a/apps/emqx_exhook/src/emqx_exhook_schema.erl +++ b/apps/emqx_exhook/src/emqx_exhook_schema.erl @@ -89,7 +89,10 @@ ref(Field) -> failed_action() -> sc(hoconsc:enum([deny, ignore]), - #{default => deny}). + #{ default => deny + , desc => "The value that is returned when the request " + "to the gRPC server fails for any reason." + }). server_config() -> fields(server). diff --git a/apps/emqx_gateway/src/emqx_gateway_schema.erl b/apps/emqx_gateway/src/emqx_gateway_schema.erl index 09b0b7d1c..b01df7bb8 100644 --- a/apps/emqx_gateway/src/emqx_gateway_schema.erl +++ b/apps/emqx_gateway/src/emqx_gateway_schema.erl @@ -382,7 +382,7 @@ fields(udp_tcp_listeners) -> fields(tcp_listener) -> [ %% some special configs for tcp listener - {acceptors, sc(integer(), #{default => 16})} + {acceptors, sc(integer(), #{default => 16, desc => "Size of the acceptor pool."})} ] ++ tcp_opts() ++ proxy_protocol_opts() ++ @@ -404,17 +404,21 @@ fields(udp_listener) -> common_listener_opts(); fields(dtls_listener) -> - [ {acceptors, sc(integer(), #{default => 16})} + [ {acceptors, sc(integer(), #{default => 16, desc => "Size of the acceptor pool."})} ] ++ fields(udp_listener) ++ [{dtls, sc(ref(dtls_opts), #{desc => "DTLS listener options"})}]; fields(udp_opts) -> - [ {active_n, sc(integer(), #{default => 100})} - , {recbuf, sc(bytesize())} - , {sndbuf, sc(bytesize())} - , {buffer, sc(bytesize())} - , {reuseaddr, sc(boolean(), #{default => true})} + [ {active_n, sc(integer(), + #{ default => 100 + , desc => "Specify the {active, N} option for the socket.
" + "See: https://erlang.org/doc/man/inet.html#setopts-2" + })} + , {recbuf, sc(bytesize(), #{desc => "Size of the kernel-space receive buffer for the socket."})} + , {sndbuf, sc(bytesize(), #{desc => "Size of the kernel-space send buffer for the socket."})} + , {buffer, sc(bytesize(), #{desc => "Size of the user-space buffer for the socket."})} + , {reuseaddr, sc(boolean(), #{default => true, desc => "Allow local reuse of port numbers."})} ]; fields(dtls_opts) -> @@ -429,9 +433,9 @@ authentication_schema() -> sc(emqx_authn_schema:authenticator_type(), #{ required => {false, recursively} , desc => -"""Default authentication configs for all the gateway listeners.
+"Default authentication configs for all the gateway listeners.
For per-listener overrides see authentication -in listener configs""" +in listener configs" }). gateway_common_options() -> @@ -528,10 +532,16 @@ proxy_protocol_opts() -> [ {proxy_protocol, sc(boolean(), #{ default => false + , desc => "Enable the Proxy Protocol V1/2 if the EMQX cluster is deployed " + "behind HAProxy or Nginx.
" + "See: https://www.haproxy.com/blog/haproxy/proxy-protocol/" })} , {proxy_protocol_timeout, sc(duration(), #{ default => "15s" + , desc => "Timeout for proxy protocol.
" + "EMQX will close the TCP connection if proxy protocol packet is not " + "received within the timeout." })} ]. diff --git a/apps/emqx_retainer/src/emqx_retainer_schema.erl b/apps/emqx_retainer/src/emqx_retainer_schema.erl index 306ab5642..7868bc6fd 100644 --- a/apps/emqx_retainer/src/emqx_retainer_schema.erl +++ b/apps/emqx_retainer/src/emqx_retainer_schema.erl @@ -32,7 +32,7 @@ fields("retainer") -> ]; fields(mnesia_config) -> - [ {type, ?TYPE(hoconsc:union([built_in_database]))} + [ {type, hoconsc:mk(hoconsc:union([built_in_database]), #{desc => "Backend type."})} , {storage_type, sc(hoconsc:union([ram, disc]), "Specifies whether the messages are stored in RAM or persisted on disc.", ram)} From 1c651763621d7ee607b2b689134ce6de75ccee15 Mon Sep 17 00:00:00 2001 From: Dmitrii <99872536+ieQu1@users.noreply.github.com> Date: Thu, 24 Mar 2022 11:39:11 +0100 Subject: [PATCH 2/3] docs: Apply remark Co-authored-by: Thales Macedo Garitezi --- apps/emqx_dashboard/etc/emqx_dashboard.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/emqx_dashboard/etc/emqx_dashboard.conf b/apps/emqx_dashboard/etc/emqx_dashboard.conf index 7fcb319dd..180ba8c3a 100644 --- a/apps/emqx_dashboard/etc/emqx_dashboard.conf +++ b/apps/emqx_dashboard/etc/emqx_dashboard.conf @@ -5,7 +5,7 @@ dashboard { default_username = "admin" default_password = "public" - ## Note: sample_interval should be divisible by 60. + ## Note: sample_interval should be a divisor of 60. ## like 1s, 2s, 3s, 5s, 10s, 12s, 15s, 20s, 30s, 60s sample_interval = 10s ## JWT token expiration time. From fa8ab063687b3770ac2a5fe67874477293fb2485 Mon Sep 17 00:00:00 2001 From: Dmitrii <99872536+ieQu1@users.noreply.github.com> Date: Thu, 24 Mar 2022 11:39:35 +0100 Subject: [PATCH 3/3] docs: Apply remark Co-authored-by: Thales Macedo Garitezi --- apps/emqx_dashboard/src/emqx_dashboard_schema.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/emqx_dashboard/src/emqx_dashboard_schema.erl b/apps/emqx_dashboard/src/emqx_dashboard_schema.erl index 16328716a..3cd2cd195 100644 --- a/apps/emqx_dashboard/src/emqx_dashboard_schema.erl +++ b/apps/emqx_dashboard/src/emqx_dashboard_schema.erl @@ -41,7 +41,7 @@ but use the same port."})} , {sample_interval, sc(emqx_schema:duration_s(), #{ default => "10s" , desc => "How often to update metrics displayed in the dashboard.
" - "Note: `sample_interval` should be divisible by 60." + "Note: `sample_interval` should be a divisor of 60." })} , {token_expired_time, sc(emqx_schema:duration(), #{ default => "30m"