From f03d4d090ed79ea067a86c77107dddaef097d516 Mon Sep 17 00:00:00 2001 From: zhongwencool Date: Tue, 11 Jul 2023 11:53:41 +0800 Subject: [PATCH] feat: add license setting get/put api --- lib-ee/emqx_license/src/emqx_license.erl | 15 +++- .../src/emqx_license_http_api.erl | 77 ++++++++++++++++--- .../emqx_license/src/emqx_license_schema.erl | 8 +- rel/i18n/emqx_license_http_api.hocon | 6 ++ rel/i18n/emqx_license_schema.hocon | 16 +++- 5 files changed, 104 insertions(+), 18 deletions(-) diff --git a/lib-ee/emqx_license/src/emqx_license.erl b/lib-ee/emqx_license/src/emqx_license.erl index 0918293a6..eaa9661e3 100644 --- a/lib-ee/emqx_license/src/emqx_license.erl +++ b/lib-ee/emqx_license/src/emqx_license.erl @@ -22,7 +22,8 @@ unload/0, read_license/0, read_license/1, - update_key/1 + update_key/1, + update_setting/1 ]). -define(CONF_KEY_PATH, [license]). @@ -64,6 +65,14 @@ update_key(Value) when is_binary(Value); is_list(Value) -> ), handle_config_update_result(Result). +update_setting(Setting) when is_map(Setting) -> + Result = emqx_conf:update( + ?CONF_KEY_PATH, + {setting, Setting}, + #{rawconf_with_defaults => true, override_to => cluster} + ), + handle_config_update_result(Result). + %%------------------------------------------------------------------------------ %% emqx_hooks %%------------------------------------------------------------------------------ @@ -96,6 +105,8 @@ check(_ConnInfo, AckProps) -> pre_config_update(_, Cmd, Conf) -> {ok, do_update(Cmd, Conf)}. +post_config_update(_Path, {setting, _}, NewConf, _Old, _AppEnvs) -> + {ok, NewConf}; post_config_update(_Path, _Cmd, NewConf, _Old, _AppEnvs) -> case read_license(NewConf) of {ok, License} -> @@ -122,6 +133,8 @@ do_update({key, Content}, Conf) when is_binary(Content); is_list(Content) -> {error, Reason} -> erlang:throw(Reason) end; +do_update({setting, Setting}, Conf) -> + maps:merge(Conf, Setting); do_update(NewConf, _PrevConf) -> #{<<"key">> := NewKey} = NewConf, do_update({key, NewKey}, NewConf). diff --git a/lib-ee/emqx_license/src/emqx_license_http_api.erl b/lib-ee/emqx_license/src/emqx_license_http_api.erl index ef0e1ee52..93b759a06 100644 --- a/lib-ee/emqx_license/src/emqx_license_http_api.erl +++ b/lib-ee/emqx_license/src/emqx_license_http_api.erl @@ -13,11 +13,14 @@ namespace/0, api_spec/0, paths/0, - schema/1 + schema/1, + fields/1 ]). +-define(LICENSE_TAGS, [<<"License">>]). -export([ - '/license'/2 + '/license'/2, + '/license/setting'/2 ]). -define(BAD_REQUEST, 'BAD_REQUEST'). @@ -29,14 +32,15 @@ api_spec() -> paths() -> [ - "/license" + "/license", + "/license/setting" ]. schema("/license") -> #{ 'operationId' => '/license', get => #{ - tags => [<<"license">>], + tags => ?LICENSE_TAGS, summary => <<"Get license info">>, description => ?DESC("desc_license_info_api"), responses => #{ @@ -51,18 +55,16 @@ schema("/license") -> } }, post => #{ - tags => [<<"license">>], + tags => ?LICENSE_TAGS, summary => <<"Update license key">>, description => ?DESC("desc_license_key_api"), 'requestBody' => emqx_dashboard_swagger:schema_with_examples( - emqx_license_schema:key_license(), + hoconsc:ref(?MODULE, key_license), #{ license_key => #{ summary => <<"License key string">>, value => #{ - <<"key">> => <<"xxx">>, - <<"connection_low_watermark">> => "75%", - <<"connection_high_watermark">> => "80%" + <<"key">> => <<"xxx">> } } } @@ -79,6 +81,28 @@ schema("/license") -> 400 => emqx_dashboard_swagger:error_codes([?BAD_REQUEST], <<"Bad license key">>) } } + }; +schema("/license/setting") -> + #{ + 'operationId' => '/license/setting', + get => #{ + tags => ?LICENSE_TAGS, + summary => <<"Get license setting">>, + description => ?DESC("desc_license_setting_api"), + responses => #{ + 200 => setting() + } + }, + post => #{ + tags => ?LICENSE_TAGS, + summary => <<"Update license setting">>, + description => ?DESC("desc_license_setting_api"), + 'requestBody' => setting(), + responses => #{ + 200 => setting(), + 400 => emqx_dashboard_swagger:error_codes([?BAD_REQUEST], <<"Bad setting value">>) + } + } }. sample_license_info_response() -> @@ -117,3 +141,38 @@ error_msg(Code, Msg) -> end; '/license'(post, _Params) -> {400, error_msg(?BAD_REQUEST, <<"Invalid request params">>)}. + +'/license/setting'(get, _Params) -> + {200, maps:remove(<<"key">>, emqx_config:get_raw([license]))}; +'/license/setting'(post, #{body := Setting}) -> + case emqx_license:update_setting(Setting) of + {error, Error} -> + ?SLOG(error, #{ + msg => "bad_license_setting", + reason => Error + }), + {400, error_msg(?BAD_REQUEST, <<"Bad license setting">>)}; + {ok, _} -> + ?SLOG(info, #{msg => "updated_license_setting"}), + '/license/setting'(get, undefined) + end. + +fields(key_license) -> + Key = lists:keyfind(key, 1, emqx_license_schema:fields(key_license)), + [ + Key, + %% FIXME: remove when 5.2.0 + {connection_low_watermark, #{ + type => emqx_schema:percent(), + deprecated => true, + desc => ?DESC(connection_low_watermark_field_deprecated) + }}, + {connection_high_watermark, #{ + type => emqx_schema:percent(), + deprecated => true, + desc => ?DESC(connection_high_watermark_field_deprecated) + }} + ]. + +setting() -> + lists:keydelete(key, 1, emqx_license_schema:fields(key_license)). diff --git a/lib-ee/emqx_license/src/emqx_license_schema.erl b/lib-ee/emqx_license/src/emqx_license_schema.erl index bb7868d8d..2132b0670 100644 --- a/lib-ee/emqx_license/src/emqx_license_schema.erl +++ b/lib-ee/emqx_license/src/emqx_license_schema.erl @@ -16,15 +16,14 @@ -export([roots/0, fields/1, validations/0, desc/1, tags/0]). -export([ - default_license/0, - key_license/0 + default_license/0 ]). roots() -> [ {license, hoconsc:mk( - key_license(), + hoconsc:ref(?MODULE, key_license), #{ desc => ?DESC(license_root) } @@ -64,9 +63,6 @@ desc(_) -> validations() -> [{check_license_watermark, fun check_license_watermark/1}]. -key_license() -> - hoconsc:ref(?MODULE, key_license). - check_license_watermark(Conf) -> case hocon_maps:get("license.connection_low_watermark", Conf) of undefined -> diff --git a/rel/i18n/emqx_license_http_api.hocon b/rel/i18n/emqx_license_http_api.hocon index 895041c18..63c9dc558 100644 --- a/rel/i18n/emqx_license_http_api.hocon +++ b/rel/i18n/emqx_license_http_api.hocon @@ -12,4 +12,10 @@ desc_license_key_api.desc: desc_license_key_api.label: """Update license""" +desc_license_setting_api.desc: +"""Update license setting""" + +desc_license_setting_api.label: +"""Update license setting""" + } diff --git a/rel/i18n/emqx_license_schema.hocon b/rel/i18n/emqx_license_schema.hocon index 3e4e37bff..51387ed39 100644 --- a/rel/i18n/emqx_license_schema.hocon +++ b/rel/i18n/emqx_license_schema.hocon @@ -12,6 +12,18 @@ connection_low_watermark_field.desc: connection_low_watermark_field.label: """Connection low watermark""" +connection_high_watermark_field_deprecated.desc: +"""deprecated use /license/setting instead""" + +connection_high_watermark_field_deprecated.label: +"""deprecated use /license/setting instead""" + +connection_low_watermark_field_deprecated.desc: +"""deprecated use /license/setting instead""" + +connection_low_watermark_field_deprecated.label: +"""deprecated use /license/setting instead""" + key_field.desc: """License string""" @@ -19,12 +31,12 @@ key_field.label: """License string""" license_root.desc: -"""Defines the EMQX Enterprise license. +"""Defines the EMQX Enterprise license. The default license has 100 connections limit, it is issued on 2023-01-09 and valid for 5 years (1825 days). -EMQX comes with a default trial license. For production use, please +EMQX comes with a default trial license. For production use, please visit https://www.emqx.com/apply-licenses/emqx to apply.""" license_root.label: