New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: implement configuration and user data export/import #10676
feat: implement configuration and user data export/import #10676
Conversation
f1dce5c
to
4a63a5a
Compare
bb72066
to
af5231f
Compare
0241e41
to
4ae42de
Compare
apps/emqx_authn/src/emqx_authn.erl
Outdated
AuthnList = maps:get(<<"authentication">>, RawConf, []), | ||
lists:foreach( | ||
fun(Authn) -> | ||
case update_conf(update_req(Authn)) of | ||
%% Assume not_found error | ||
{error, _} -> | ||
{ok, _} = update_conf(create_req(Authn)); | ||
{ok, _} -> | ||
ok | ||
end | ||
end, | ||
AuthnList | ||
). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need support delete action, for deleting authn not exist in rawConf.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: it has been agreed to merge imported data with the existing one (without deleting) in the first iteration to keep it consistent with EMQX4.4 data import behaviour (https://emqx.atlassian.net/browse/EMQX-9203?focusedCommentId=28667).
Replacing (restore backup) may be implemented later, as it was discussed on the demo meeting.
85039da
to
a796f46
Compare
ef5367c
to
28cab51
Compare
28cab51
to
a55a2ec
Compare
true -> | ||
%% 4.x backup files are anyway not compatible and will be treated as invalid, | ||
%% before this step. | ||
maybe_print( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be done differently.
My point was that: it's hard to ensure forward compatibility, but at the same time, disallowing newer version imports may be too strict.
Alternatively, we can add some info about forward-compatibility to META.hocon, e.g.
min_major_version=5
min_minor_version=1
And when we import the backup, we can compare it with EMQX version and disallow import if it's not supported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Group review feedback: disallow 'downgrade' import (if backup is newer than EMQX - don't allow import).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed to disallow importing data if backup version is newer than EMQX version.
RawConf1 = emqx_authz:maybe_write_acl_file(RawConf), | ||
emqx_hocon:check( | ||
emqx_conf:schema_module(), | ||
maps:merge(emqx:get_raw_config([]), RawConf1), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is to validate the whole config before trying to import its individual root keys.
I use maps:merge/2
just to put existing values for required keys like node
(no need for deep merging).
I wonder if there are better alternatives.. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed and agreed that it must be fine.
prepare_new_backup(Opts) -> | ||
{{Y, M, D}, {H, MM, S}} = _DateTime = local_datetime(), | ||
BackupBaseName = str( | ||
io_lib:format("emqx-export-~p-~p-~p-~p-~p-~p", [Y, M, D, H, MM, S]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Maybe smth like
io_lib:format(
"~0p.~2..0b.~2..0b.~2..0b.~2..0b.~2..0b.~3..0b",
[Y, M, D, HH, MM, SS, Ts rem 1000]
)
as in recent Stone's commit to make e.g. names more sorting-friendly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, great idea!
But I think it's better to keep dashes as separators for date/time, e,g:
io_lib:format("emqx-export-~0p-~2..0b-~2..0b-~2..0b-~2..0b-~2..0b.~3..0b",
[Y, M, D, HH, MM, SS, Ts rem 1000])
%% emqx-export-2023-06-01-13-06-49.135.tar.gz.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
apps/emqx_authn/src/emqx_authn.erl
Outdated
end | ||
end, | ||
{[], #{}}, | ||
AuthnList |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EMQX schema also supports individual authenticator config as "authentication" value, so it may appear in the raw config:
emqx/apps/emqx/src/emqx_schema.erl
Line 2872 in b5f24c4
converter => fun ensure_array/2, |
Do we handle this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a helper to handle it, thanks!
apps/emqx_authn/src/emqx_authn.erl
Outdated
-define(IMPORT_OPTS, #{rawconf_with_defaults => true, override_to => cluster}). | ||
|
||
import_data(RawConf) -> | ||
AuthnList = maps:get(<<"authentication">>, RawConf, []), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AuthnList = maps:get(<<"authentication">>, RawConf, []), | |
AuthnList = maps:get(?CONF_NS_BINARY, RawConf, []), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, changed all the occurrences in authn and authz
b272c1a
to
8aeebc4
Compare
8aeebc4
to
ba64428
Compare
changes/ce/feat-10676.en.md
Outdated
@@ -0,0 +1,4 @@ | |||
Implement configuration and user data import/export CLI. | |||
|
|||
The tool allows to export configuration and built-in database data from a running |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
The tool allows to export configuration and built-in database data from a running | |
The `emqx ctl export` and `emqx ctl import` commands allow to export configuration and built-in database data from a running |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed, thanks
Closes: EMQX-9203
ba64428
to
e4d09d4
Compare
Enhancements
|
增强
|
Fixes EMQX-9203
Summary
🤖 Generated by Copilot at f1dce5c
This pull request adds data backup features for various EMQ X modules and applications, allowing users to export and import their configurations, authentication sources, authorization rules, users, api keys, banned clients, listeners, bridges, and auto subscribe topics as JSON files. It also updates some application versions, comment styles, and formatting functions. It mainly uses base64 encoding and decoding, JSON encoding and decoding, and file reading and writing functions to handle the data backup logic. The main files involved are
emqx_authn.erl
,emqx_authz.erl
,emqx_bridge.erl
,emqx_dashboard_admin.erl
,emqx_exhook_mgr.erl
,emqx_gateway_conf.erl
,emqx_listeners.erl
,emqx_mgmt_api_api_keys.erl
,emqx_mgmt_auth.erl
,emqx_mgmt_cli.erl
,emqx_mgmt_data_backup.erl
, andemqx_tls_lib.erl
.PR Checklist
Please convert it to a draft if any of the following conditions are not met. Reviewers may skip over until all the items are checked:
changes/{ce,ee}/(feat|perf|fix)-<PR-id>.en.md
filesChecklist for CI (.github/workflows) changes
changes/
dir for user-facing artifacts update