Merge pull request #10985 from zmstone/0608-rename-cluster-call-cmd

0608 rename cluster call cmd
This commit is contained in:
zhongwencool 2023-06-09 10:56:18 +08:00 committed by GitHub
commit daa5450218
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 103 additions and 57 deletions

View File

@ -3018,7 +3018,7 @@ non_empty_string(_) -> {error, invalid_string}.
%% hosts can be successfully parsed.
%% 3. parsing: Done at runtime in each module which uses this config
servers_sc(Meta0, ParseOpts) ->
%% if this filed has a default value
%% if this field has a default value
%% then it is not NOT required
%% NOTE: maps:is_key is not the solution because #{default => undefined} is legit
HasDefault = (maps:get(default, Meta0, undefined) =/= undefined),
@ -3079,7 +3079,7 @@ servers_validator(Opts, Required) ->
%% we should remove field from config if it's empty
throw("cannot_be_empty");
"undefined" when Required ->
%% when the filed is not set in config file
%% when the field is not set in config file
%% NOTE: assuming nobody is going to name their server "undefined"
throw("cannot_be_empty");
"undefined" ->

View File

@ -181,7 +181,7 @@ t_create_with_config_values_wont_work(_Config) ->
InvalidConfigs
).
%% creating without a require filed should return error
%% creating without a require field should return error
t_create_invalid_config(_Config) ->
AuthzConfig = raw_redis_authz_config(),
C = maps:without([<<"server">>], AuthzConfig),

View File

@ -95,33 +95,33 @@ namespace() -> "bridge_influxdb".
roots() -> [].
fields("post_api_v1") ->
method_fileds(post, influxdb_api_v1);
method_fields(post, influxdb_api_v1);
fields("post_api_v2") ->
method_fileds(post, influxdb_api_v2);
method_fields(post, influxdb_api_v2);
fields("put_api_v1") ->
method_fileds(put, influxdb_api_v1);
method_fields(put, influxdb_api_v1);
fields("put_api_v2") ->
method_fileds(put, influxdb_api_v2);
method_fields(put, influxdb_api_v2);
fields("get_api_v1") ->
method_fileds(get, influxdb_api_v1);
method_fields(get, influxdb_api_v1);
fields("get_api_v2") ->
method_fileds(get, influxdb_api_v2);
method_fields(get, influxdb_api_v2);
fields(Type) when
Type == influxdb_api_v1 orelse Type == influxdb_api_v2
->
influxdb_bridge_common_fields() ++
connector_fields(Type).
method_fileds(post, ConnectorType) ->
method_fields(post, ConnectorType) ->
influxdb_bridge_common_fields() ++
connector_fields(ConnectorType) ++
type_name_fields(ConnectorType);
method_fileds(get, ConnectorType) ->
method_fields(get, ConnectorType) ->
influxdb_bridge_common_fields() ++
connector_fields(ConnectorType) ++
type_name_fields(ConnectorType) ++
emqx_bridge_schema:status_fields();
method_fileds(put, ConnectorType) ->
method_fields(put, ConnectorType) ->
influxdb_bridge_common_fields() ++
connector_fields(ConnectorType).

View File

@ -22,36 +22,32 @@
unload/0
]).
-include_lib("hocon/include/hoconsc.hrl").
%% kept cluster_call for compatibility
-define(CLUSTER_CALL, cluster_call).
-define(CONF, conf).
load() ->
emqx_ctl:register_command(?CLUSTER_CALL, {?MODULE, admins}, []),
emqx_ctl:register_command(?CLUSTER_CALL, {?MODULE, admins}, [hidden]),
emqx_ctl:register_command(?CONF, {?MODULE, conf}, []).
unload() ->
emqx_ctl:unregister_command(?CLUSTER_CALL),
emqx_ctl:unregister_command(?CONF).
conf(["show", "--keys-only"]) ->
print(emqx_config:get_root_names());
conf(["show_keys" | _]) ->
print_keys(get_config());
conf(["show"]) ->
print_hocon(get_config());
conf(["show", Key]) ->
print_hocon(get_config(Key));
conf(["load", Path]) ->
load_config(Path);
conf(["cluster_sync" | Args]) ->
admins(Args);
conf(_) ->
emqx_ctl:usage(
[
%% TODO add reload
%{"conf reload", "reload etc/emqx.conf on local node"},
{"conf show --keys-only", "print all keys"},
{"conf show", "print all running configures"},
{"conf show <key>", "print a specific configuration"},
{"conf load <path>", "load a hocon file to all nodes"}
]
).
emqx_ctl:usage(usage_conf() ++ usage_sync()).
admins(["status"]) ->
status();
@ -87,14 +83,34 @@ admins(["fast_forward", Node0, ToTnxId]) ->
emqx_cluster_rpc:fast_forward_to_commit(Node, TnxId),
status();
admins(_) ->
emqx_ctl:usage(
[
{"cluster_call status", "status"},
{"cluster_call skip [node]", "increase one commit on specific node"},
{"cluster_call tnxid <TnxId>", "get detailed about TnxId"},
{"cluster_call fast_forward [node] [tnx_id]", "fast forwards to tnx_id"}
]
).
emqx_ctl:usage(usage_sync()).
usage_conf() ->
[
%% TODO add reload
%{"conf reload", "reload etc/emqx.conf on local node"},
{"conf show_keys", "Print all config keys"},
{"conf show [<key>]",
"Print in-use configs (including default values) under the given key. "
"Print ALL keys if key is not provided"},
{"conf load <path>",
"Load a HOCON format config file."
"The config is overlay on top of the existing configs. "
"The current node will initiate a cluster wide config change "
"transaction to sync the changes to other nodes in the cluster. "
"NOTE: do not make runtime config changes during rolling upgrade."}
].
usage_sync() ->
[
{"conf cluster_sync status", "Show cluster config sync status summary"},
{"conf cluster_sync skip [node]", "Increase one commit on specific node"},
{"conf cluster_sync tnxid <TnxId>",
"Display detailed information of the config change transaction at TnxId"},
{"conf cluster_sync fast_forward [node] [tnx_id]",
"Fast-forward config change transaction to tnx_id on the given node."
"WARNING: This results in inconsistent configs among the clustered nodes."}
].
status() ->
emqx_ctl:print("-----------------------------------------------\n"),
@ -116,14 +132,39 @@ status() ->
),
emqx_ctl:print("-----------------------------------------------\n").
print_keys(Config) ->
print(lists:sort(maps:keys(Config))).
print(Json) ->
emqx_ctl:print("~ts~n", [emqx_logger_jsonfmt:best_effort_json(Json)]).
print_hocon(Hocon) ->
emqx_ctl:print("~ts~n", [hocon_pp:do(Hocon, #{})]).
get_config() -> emqx_config:fill_defaults(emqx:get_raw_config([])).
get_config(Key) -> emqx_config:fill_defaults(#{Key => emqx:get_raw_config([Key])}).
get_config() ->
drop_hidden_roots(emqx_config:fill_defaults(emqx:get_raw_config([]))).
drop_hidden_roots(Conf) ->
Hidden = hidden_roots(),
maps:without(Hidden, Conf).
hidden_roots() ->
SchemaModule = emqx_conf:schema_module(),
Roots = hocon_schema:roots(SchemaModule),
lists:filtermap(
fun({BinName, {_RefName, Schema}}) ->
case hocon_schema:field_schema(Schema, importance) =/= ?IMPORTANCE_HIDDEN of
true ->
false;
false ->
{true, BinName}
end
end,
Roots
).
get_config(Key) ->
emqx_config:fill_defaults(#{Key => emqx:get_raw_config([Key])}).
-define(OPTIONS, #{rawconf_with_defaults => true, override_to => cluster}).
load_config(Path) ->

View File

@ -1323,7 +1323,7 @@ roots(Module) ->
lists:map(fun({_BinName, Root}) -> Root end, hocon_schema:roots(Module)).
%% Like authentication schema, authorization schema is incomplete in emqx_schema
%% module, this function replaces the root filed "authorization" with a new schema
%% module, this function replaces the root field "authorization" with a new schema
emqx_schema_high_prio_roots() ->
Roots = emqx_schema:roots(high),
Authz =

View File

@ -157,18 +157,21 @@ help() ->
print("No commands available.~n");
Cmds ->
print("Usage: ~ts~n", ["emqx ctl"]),
lists:foreach(
fun({_, {Mod, Cmd}, _}) ->
print("~110..-s~n", [""]),
apply(Mod, Cmd, [usage])
end,
Cmds
)
lists:foreach(fun print_usage/1, Cmds)
end;
false ->
print("Command table is initializing.~n")
end.
print_usage({_, {Mod, Cmd}, Opts}) ->
case proplists:get_bool(hidden, Opts) of
true ->
ok;
false ->
print("~110..-s~n", [""]),
apply(Mod, Cmd, [usage])
end.
-spec print(io:format()) -> ok.
print(Msg) ->
io:format("~ts", [format(Msg, [])]).

View File

@ -0,0 +1,2 @@
Renamed emqx ctl command 'cluster_call' to 'conf cluster_sync'.
The old command 'cluster_call' is still a valid command, but not included in usage info.

View File

@ -101,23 +101,23 @@ namespace() -> "bridge_redis".
roots() -> [].
fields("post_single") ->
method_fileds(post, redis_single);
method_fields(post, redis_single);
fields("post_sentinel") ->
method_fileds(post, redis_sentinel);
method_fields(post, redis_sentinel);
fields("post_cluster") ->
method_fileds(post, redis_cluster);
method_fields(post, redis_cluster);
fields("put_single") ->
method_fileds(put, redis_single);
method_fields(put, redis_single);
fields("put_sentinel") ->
method_fileds(put, redis_sentinel);
method_fields(put, redis_sentinel);
fields("put_cluster") ->
method_fileds(put, redis_cluster);
method_fields(put, redis_cluster);
fields("get_single") ->
method_fileds(get, redis_single);
method_fields(get, redis_single);
fields("get_sentinel") ->
method_fileds(get, redis_sentinel);
method_fields(get, redis_sentinel);
fields("get_cluster") ->
method_fileds(get, redis_cluster);
method_fields(get, redis_cluster);
fields(Type) when
Type == redis_single orelse Type == redis_sentinel orelse Type == redis_cluster
->
@ -126,16 +126,16 @@ fields(Type) when
fields("creation_opts_" ++ Type) ->
resource_creation_fields(Type).
method_fileds(post, ConnectorType) ->
method_fields(post, ConnectorType) ->
redis_bridge_common_fields(ConnectorType) ++
connector_fields(ConnectorType) ++
type_name_fields(ConnectorType);
method_fileds(get, ConnectorType) ->
method_fields(get, ConnectorType) ->
redis_bridge_common_fields(ConnectorType) ++
connector_fields(ConnectorType) ++
type_name_fields(ConnectorType) ++
emqx_bridge_schema:status_fields();
method_fileds(put, ConnectorType) ->
method_fields(put, ConnectorType) ->
redis_bridge_common_fields(ConnectorType) ++
connector_fields(ConnectorType).

View File

@ -84,7 +84,7 @@ There are 4 complex data types in EMQX's HOCON config:
1. Array: `[ElementType]`
::: tip Tip
If map filed name is a positive integer number, it is interpreted as an alternative representation of an `Array`.
If map field name is a positive integer number, it is interpreted as an alternative representation of an `Array`.
For example:
```
myarray.1 = 74
@ -120,7 +120,7 @@ If we consider the whole EMQX config as a tree,
to reference a primitive value, we can use a dot-separated names form string for
the path from the tree-root (always a Struct) down to the primitive values at tree-leaves.
Each segment of the dotted string is a Struct filed name or Map key.
Each segment of the dotted string is a Struct field name or Map key.
For Array elements, 1-based index is used.
below are some examples