diff options
| author | Jean-Sébastien Pédron <jean-sebastien.pedron@dumbbell.fr> | 2016-05-30 18:04:27 +0200 |
|---|---|---|
| committer | Jean-Sébastien Pédron <jean-sebastien.pedron@dumbbell.fr> | 2016-05-30 18:09:17 +0200 |
| commit | ec5a71d79ac5e8e200ce51827a3fb2c4b8887de1 (patch) | |
| tree | cb9ee81f328b284972d54f3f5e78984b401d1639 /test | |
| parent | 455644498e97f91c7005bed85d2519db5f506030 (diff) | |
| download | rabbitmq-server-git-ec5a71d79ac5e8e200ce51827a3fb2c4b8887de1.tar.gz | |
config_schema_SUITE: Copy Cuttlefish schema in the testsuite data directory
We must do that instead of adding the plugins as test dependencies
because doing this introduces a circular dependency: all plugins depend
on rabbitmq-server.
With the circular dependency in place, the broker was compiled with
$(ERLC_OPTS) compiler flags, because the build was triggered by the
first plugin. Therefore we missed all the $(TEST_ERLC_OPTS) additions.
With the circular dependency fixed, the broker is again built with
$(TEST_ERLC_OPTIS): `src/truncate.erl` depends on the `-DTEST=1` flag.
In the longer term, we must move the testcases depending on the plugins'
schemas to their corresponding plugin.
Diffstat (limited to 'test')
13 files changed, 1941 insertions, 11 deletions
diff --git a/test/config_schema_SUITE.erl b/test/config_schema_SUITE.erl index b1362aac28..79e7220e98 100644 --- a/test/config_schema_SUITE.erl +++ b/test/config_schema_SUITE.erl @@ -57,11 +57,10 @@ init_per_testcase(Testcase, Config) -> ]), Config2 = case Testcase of run_snippets -> - SchemaDir = filename:join(?config(priv_dir, Config1), "schema"), + SchemaDir = filename:join(?config(data_dir, Config1), "schema"), ResultsDir = filename:join(?config(priv_dir, Config1), "results"), Snippets = filename:join(?config(data_dir, Config1), "snippets.config"), - ok = file:make_dir(SchemaDir), ok = file:make_dir(ResultsDir), rabbit_ct_helpers:set_config(Config1, [ {schema_dir, SchemaDir}, @@ -88,7 +87,6 @@ run_snippets(Config) -> ?MODULE, run_snippets1, [Config]). run_snippets1(Config) -> - prepare_plugin_schemas(Config), {ok, [Snippets]} = file:consult(?config(conf_snippets, Config)), lists:map( fun({N, S, C, P}) -> ok = test_snippet(Config, {integer_to_list(N), S, []}, C, P); @@ -128,14 +126,6 @@ generate_config(Config, ConfFile, AdvancedFile) -> rabbit_config:generate_config_file([ConfFile], ResultsDir, ScriptDir, SchemaDir, AdvancedFile). -prepare_plugin_schemas(Config) -> - SchemaDir = ?config(schema_dir, Config), - DepsDir = ?config(erlang_mk_depsdir, Config), - Files = filelib:wildcard( - filename:join(DepsDir, "*/priv/schema/*.schema")), - [ file:copy(File, filename:join([SchemaDir, filename:basename(File)])) - || File <- Files ]. - deepsort(List) -> case is_proplist(List) of true -> diff --git a/test/config_schema_SUITE_data/schema/rabbitmq.schema b/test/config_schema_SUITE_data/schema/rabbitmq.schema new file mode 100644 index 0000000000..19040da409 --- /dev/null +++ b/test/config_schema_SUITE_data/schema/rabbitmq.schema @@ -0,0 +1,961 @@ +% ============================== +% Rabbit app section +% ============================== + +%% +%% Network Connectivity +%% ==================== +%% + +%% By default, RabbitMQ will listen on all interfaces, using +%% the standard (reserved) AMQP port. +%% +%% {tcp_listeners, [5672]}, +%% To listen on a specific interface, provide a tuple of {IpAddress, Port}. +%% For example, to listen only on localhost for both IPv4 and IPv6: +%% +%% {tcp_listeners, [{"127.0.0.1", 5672}, +%% {"[::1]", 5672}]}, + +{mapping, "listeners.tcp", "rabbit.tcp_listeners",[ + {datatype, {enum, [none]}} +]}. + +{mapping, "listeners.tcp.$name", "rabbit.tcp_listeners",[ + {datatype, [integer, ip]} +]}. + +{translation, "rabbit.tcp_listeners", +fun(Conf) -> + case cuttlefish:conf_get("listeners.tcp", Conf, undefined) of + none -> []; + _ -> + Settings = cuttlefish_variable:filter_by_prefix("listeners.tcp", Conf), + [ V || {_, V} <- Settings ] + end +end}. + +%% SSL listeners are configured in the same fashion as TCP listeners, +%% including the option to control the choice of interface. +%% +%% {ssl_listeners, [5671]}, + +{mapping, "listeners.ssl", "rabbit.ssl_listeners",[ + {datatype, {enum, [none]}} +]}. + +{mapping, "listeners.ssl.$name", "rabbit.ssl_listeners",[ + {datatype, [integer, ip]} +]}. + +{translation, "rabbit.ssl_listeners", +fun(Conf) -> + case cuttlefish:conf_get("listeners.ssl", Conf, undefined) of + none -> []; + _ -> + Settings = cuttlefish_variable:filter_by_prefix("listeners.ssl", Conf), + [ V || {_, V} <- Settings ] + end +end}. + +%% Number of Erlang processes that will accept connections for the TCP +%% and SSL listeners. +%% +%% {num_tcp_acceptors, 10}, +%% {num_ssl_acceptors, 1}, + +{mapping, "num_acceptors.ssl", "rabbit.num_ssl_acceptors", [ + {datatype, integer} +]}. + +{mapping, "num_acceptors.tcp", "rabbit.num_tcp_acceptors", [ + {datatype, integer} +]}. + + +%% Maximum time for AMQP 0-8/0-9/0-9-1 handshake (after socket connection +%% and SSL handshake), in milliseconds. +%% +%% {handshake_timeout, 10000}, + +{mapping, "handshake_timeout", "rabbit.handshake_timeout", [ + {datatype, integer} +]}. + +%% Set to 'true' to perform reverse DNS lookups when accepting a +%% connection. Hostnames will then be shown instead of IP addresses +%% in rabbitmqctl and the management plugin. +%% +%% {reverse_dns_lookups, true}, + +{mapping, "reverse_dns_lookups", "rabbit.reverse_dns_lookups", [ + {datatype, {enum, [true, false]}} +]}. + +{mapping, "erlang.K", "vm_args.+K", [ + {default, "true"}, + {level, advanced} +]}. + +%% +%% Security / AAA +%% ============== +%% + +%% The default "guest" user is only permitted to access the server +%% via a loopback interface (e.g. localhost). +%% {loopback_users, [<<"guest">>]}, +%% +%% Uncomment the following line if you want to allow access to the +%% guest user from anywhere on the network. +%% {loopback_users, []}, + +{mapping, "loopback_users", "rabbit.loopback_users", [ + {datatype, {enum, [none]}} +]}. + +{mapping, "loopback_users.$user", "rabbit.loopback_users", [ + {datatype, atom} +]}. + +{translation, "rabbit.loopback_users", +fun(Conf) -> + None = cuttlefish:conf_get("loopback_users", Conf, undefined), + case None of + none -> []; + _ -> + Settings = cuttlefish_variable:filter_by_prefix("loopback_users", Conf), + [ list_to_binary(U) || {["loopback_users", U], V} <- Settings, V == true ] + end +end}. + +%% Configuring SSL. +%% See http://www.rabbitmq.com/ssl.html for full documentation. +%% +%% {ssl_options, [{cacertfile, "/path/to/testca/cacert.pem"}, +%% {certfile, "/path/to/server/cert.pem"}, +%% {keyfile, "/path/to/server/key.pem"}, +%% {verify, verify_peer}, +%% {fail_if_no_peer_cert, false}]}, + +%% SSL options section ======================================================== + +{mapping, "ssl_allow_poodle_attack", "rabbit.ssl_allow_poodle_attack", +[{datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options", "rabbit.ssl_options", [ + {datatype, {enum, [none]}} +]}. + +{translation, "rabbit.ssl_options", +fun(Conf) -> + case cuttlefish:conf_get("ssl_options", Conf, undefined) of + none -> []; + _ -> cuttlefish:invalid("Invalid ssl_options") + end +end}. + +{mapping, "ssl_options.verify", "rabbit.ssl_options.verify", [ + {datatype, {enum, [verify_peer, verify_none]}}]}. + +{mapping, "ssl_options.fail_if_no_peer_cert", "rabbit.ssl_options.fail_if_no_peer_cert", [ + {datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options.cacertfile", "rabbit.ssl_options.cacertfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{mapping, "ssl_options.certfile", "rabbit.ssl_options.certfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{mapping, "ssl_options.cacerts.$name", "rabbit.ssl_options.cacerts", + [{datatype, string}]}. + +{translation, "rabbit.ssl_options.cacerts", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("ssl_options.cacerts", Conf), + [ list_to_binary(V) || {_, V} <- Settings ] +end}. + +{mapping, "ssl_options.cert", "rabbit.ssl_options.cert", + [{datatype, string}]}. + +{translation, "rabbit.ssl_options.cert", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("ssl_options.cert", Conf)) +end}. + +{mapping, "ssl_options.client_renegotiation", "rabbit.ssl_options.client_renegotiation", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options.crl_check", "rabbit.ssl_options.crl_check", + [{datatype, [{enum, [true, false, peer, best_effort]}]}]}. + +{mapping, "ssl_options.depth", "rabbit.ssl_options.depth", + [{datatype, integer}, {validators, ["byte"]}]}. + +{mapping, "ssl_options.dh", "rabbit.ssl_options.dh", + [{datatype, string}]}. + +{translation, "rabbit.ssl_options.dh", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("ssl_options.dh", Conf)) +end}. + +{mapping, "ssl_options.dhfile", "rabbit.ssl_options.dhfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{mapping, "ssl_options.honor_cipher_order", "rabbit.ssl_options.honor_cipher_order", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options.key.RSAPrivateKey", "rabbit.ssl_options.key", + [{datatype, string}]}. + +{mapping, "ssl_options.key.DSAPrivateKey", "rabbit.ssl_options.key", + [{datatype, string}]}. + +{mapping, "ssl_options.key.PrivateKeyInfo", "rabbit.ssl_options.key", + [{datatype, string}]}. + +{translation, "rabbit.ssl_options.key", +fun(Conf) -> + case cuttlefish_variable:filter_by_prefix("ssl_options.key", Conf) of + [{[_,_,Key], Val}|_] -> {list_to_atom(Key), list_to_binary(Val)}; + _ -> undefined + end +end}. + +{mapping, "ssl_options.keyfile", "rabbit.ssl_options.keyfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{mapping, "ssl_options.log_alert", "rabbit.ssl_options.log_alert", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options.password", "rabbit.ssl_options.password", + [{datatype, string}]}. + +{mapping, "ssl_options.psk_identity", "rabbit.ssl_options.psk_identity", + [{datatype, string}]}. + +{mapping, "ssl_options.reuse_sessions", "rabbit.ssl_options.reuse_sessions", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options.secure_renegotiate", "rabbit.ssl_options.secure_renegotiate", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "ssl_options.versions.$version", "rabbit.ssl_options.versions", + [{datatype, atom}]}. + +{translation, "rabbit.ssl_options.versions", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("ssl_options.versions", Conf), + [ V || {_, V} <- Settings ] +end}. + +%% =========================================================================== + +%% Choose the available SASL mechanism(s) to expose. +%% The two default (built in) mechanisms are 'PLAIN' and +%% 'AMQPLAIN'. Additional mechanisms can be added via +%% plugins. +%% +%% See http://www.rabbitmq.com/authentication.html for more details. +%% +%% {auth_mechanisms, ['PLAIN', 'AMQPLAIN']}, + +{mapping, "auth_mechanisms.$name", "rabbit.auth_mechanisms", [ + {datatype, atom}]}. + +{translation, "rabbit.auth_mechanisms", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("auth_mechanisms", Conf), + [ V || {_, V} <- Settings ] +end}. + + +%% Select an authentication backend to use. RabbitMQ provides an +%% internal backend in the core. +%% +%% {auth_backends, [rabbit_auth_backend_internal]}, + +{translation, "rabbit.auth_backends", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("auth_backends", Conf), + BackendModule = fun + (internal) -> rabbit_auth_backend_internal; + (ldap) -> rabbit_auth_backend_ldap; + (http) -> rabbit_auth_backend_http; + (amqp) -> rabbit_auth_backend_amqp; + (dummy) -> rabbit_auth_backend_dummy; + (Other) when is_atom(Other) -> Other; + (_) -> cuttlefish:invalid("Unknown/unsupported auth backend") + end, + AuthBackends = [{Num, {default, BackendModule(V)}} || {["auth_backends", Num], V} <- Settings], + AuthNBackends = [{Num, {authn, BackendModule(V)}} || {["auth_backends", Num, "authn"], V} <- Settings], + AuthZBackends = [{Num, {authz, BackendModule(V)}} || {["auth_backends", Num, "authz"], V} <- Settings], + Backends = lists:foldl( + fun({NumStr, {Type, V}}, Acc) -> + Num = case catch list_to_integer(NumStr) of + N when is_integer(N) -> N; + Err -> + cuttlefish:invalid( + iolist_to_binary(io_lib:format( + "Auth backend position in the chain should be an integer ~p", [Err]))) + end, + NewVal = case dict:find(Num, Acc) of + {ok, {AuthN, AuthZ}} -> + case {Type, AuthN, AuthZ} of + {authn, undefined, _} -> + {V, AuthZ}; + {authz, _, undefined} -> + {AuthN, V}; + _ -> + cuttlefish:invalid( + iolist_to_binary( + io_lib:format( + "Auth backend already defined for the ~pth ~p backend", + [Num, Type]))) + end; + error -> + case Type of + authn -> {V, undefined}; + authz -> {undefined, V}; + default -> {V, V} + end + end, + dict:store(Num, NewVal, Acc) + end, + dict:new(), + AuthBackends ++ AuthNBackends ++ AuthZBackends), + lists:map( + fun + ({Num, {undefined, AuthZ}}) -> + cuttlefish:warn( + io_lib:format( + "Auth backend undefined for the ~pth authz backend. Using ~p", + [Num, AuthZ])), + {AuthZ, AuthZ}; + ({Num, {AuthN, undefined}}) -> + cuttlefish:warn( + io_lib:format( + "Authz backend undefined for the ~pth authn backend. Using ~p", + [Num, AuthN])), + {AuthN, AuthN}; + ({_Num, {Auth, Auth}}) -> Auth; + ({_Num, {AuthN, AuthZ}}) -> {AuthN, AuthZ} + end, + lists:keysort(1, dict:to_list(Backends))) +end}. + +{mapping, "auth_backends.$num", "rabbit.auth_backends", [ + {datatype, atom} +]}. + +{mapping, "auth_backends.$num.authn", "rabbit.auth_backends",[ + {datatype, atom} +]}. + +{mapping, "auth_backends.$num.authz", "rabbit.auth_backends",[ + {datatype, atom} +]}. + +%% This pertains to both the rabbitmq_auth_mechanism_ssl plugin and +%% STOMP ssl_cert_login configurations. See the rabbitmq_stomp +%% configuration section later in this file and the README in +%% https://github.com/rabbitmq/rabbitmq-auth-mechanism-ssl for further +%% details. +%% +%% To use the SSL cert's CN instead of its DN as the username +%% +%% {ssl_cert_login_from, common_name}, + +{mapping, "ssl_cert_login_from", "rabbit.ssl_cert_login_from", [ + {datatype, {enum, [distinguished_name, common_name]}} +]}. + +%% SSL handshake timeout, in milliseconds. +%% +%% {ssl_handshake_timeout, 5000}, + +{mapping, "ssl_handshake_timeout", "rabbit.ssl_handshake_timeout", [ + {datatype, integer} +]}. + +%% Password hashing implementation. Will only affect newly +%% created users. To recalculate hash for an existing user +%% it's necessary to update her password. +%% +%% When importing definitions exported from versions earlier +%% than 3.6.0, it is possible to go back to MD5 (only do this +%% as a temporary measure!) by setting this to rabbit_password_hashing_md5. +%% +%% To use SHA-512, set to rabbit_password_hashing_sha512. +%% +%% {password_hashing_module, rabbit_password_hashing_sha256}, + +{mapping, "password_hashing_module", "rabbit.password_hashing_module", [ + {datatype, atom} +]}. + +%% +%% Default User / VHost +%% ==================== +%% + +%% On first start RabbitMQ will create a vhost and a user. These +%% config items control what gets created. See +%% http://www.rabbitmq.com/access-control.html for further +%% information about vhosts and access control. +%% +%% {default_vhost, <<"/">>}, +%% {default_user, <<"guest">>}, +%% {default_pass, <<"guest">>}, +%% {default_permissions, [<<".*">>, <<".*">>, <<".*">>]}, + +{mapping, "default_vhost", "rabbit.default_vhost", [ + {datatype, string} +]}. + +{translation, "rabbit.default_vhost", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("default_vhost", Conf)) +end}. + +{mapping, "default_user", "rabbit.default_user", [ + {datatype, string} +]}. + +{translation, "rabbit.default_user", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("default_user", Conf)) +end}. + +{mapping, "default_pass", "rabbit.default_pass", [ + {datatype, string} +]}. + +{translation, "rabbit.default_pass", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("default_pass", Conf)) +end}. + +{mapping, "default_permissions.configure", "rabbit.default_permissions", [ + {datatype, string} +]}. + +{mapping, "default_permissions.read", "rabbit.default_permissions", [ + {datatype, string} +]}. + +{mapping, "default_permissions.write", "rabbit.default_permissions", [ + {datatype, string} +]}. + +{translation, "rabbit.default_permissions", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("default_permissions", Conf), + Configure = proplists:get_value(["default_permissions", "configure"], Settings), + Read = proplists:get_value(["default_permissions", "read"], Settings), + Write = proplists:get_value(["default_permissions", "write"], Settings), + [list_to_binary(Configure), list_to_binary(Read), list_to_binary(Write)] +end}. + +%% Tags for default user +%% +%% For more details about tags, see the documentation for the +%% Management Plugin at http://www.rabbitmq.com/management.html. +%% +%% {default_user_tags, [administrator]}, + +{mapping, "default_user_tags.$tag", "rabbit.default_user_tags", + [{datatype, {enum, [true, false]}}]}. + +{translation, "rabbit.default_user_tags", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("default_user_tags", Conf), + [ list_to_atom(Key) || {[_,Key], Val} <- Settings, Val == true ] +end}. + +%% +%% Additional network and protocol related configuration +%% ===================================================== +%% + +%% Set the default AMQP heartbeat delay (in seconds). +%% +%% {heartbeat, 600}, + +{mapping, "heartbeat", "rabbit.heartbeat", [{datatype, integer}]}. + +%% Set the max permissible size of an AMQP frame (in bytes). +%% +%% {frame_max, 131072}, + +{mapping, "frame_max", "rabbit.frame_max", [{datatype, bytesize}]}. + +%% Set the max frame size the server will accept before connection +%% tuning occurs +%% +%% {initial_frame_max, 4096}, + +{mapping, "initial_frame_max", "rabbit.initial_frame_max", [{datatype, bytesize}]}. + +%% Set the max permissible number of channels per connection. +%% 0 means "no limit". +%% +%% {channel_max, 128}, + +{mapping, "channel_max", "rabbit.channel_max", [{datatype, integer}]}. + +%% Customising Socket Options. +%% +%% See (http://www.erlang.org/doc/man/inet.html#setopts-2) for +%% further documentation. +%% +%% {tcp_listen_options, [{backlog, 128}, +%% {nodelay, true}, +%% {exit_on_close, false}]}, + +%% TCP listener section ====================================================== + +{mapping, "tcp_listen_options", "rabbit.tcp_listen_options", [ + {datatype, {enum, [none]}}]}. + +{translation, "rabbit.tcp_listen_options", +fun(Conf) -> + case cuttlefish:conf_get("tcp_listen_options", undefined) of + none -> []; + _ -> cuttlefish:invalid("Invalid tcp_listen_options") + end +end}. + +{mapping, "tcp_listen_options.backlog", "rabbit.tcp_listen_options.backlog", [ + {datatype, integer} +]}. + +{mapping, "tcp_listen_options.nodelay", "rabbit.tcp_listen_options.nodelay", [ + {datatype, {enum, [true, false]}} +]}. + +{mapping, "tcp_listen_options.buffer", "rabbit.tcp_listen_options.buffer", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.delay_send", "rabbit.tcp_listen_options.delay_send", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "tcp_listen_options.dontroute", "rabbit.tcp_listen_options.dontroute", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "tcp_listen_options.exit_on_close", "rabbit.tcp_listen_options.exit_on_close", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "tcp_listen_options.fd", "rabbit.tcp_listen_options.fd", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.high_msgq_watermark", "rabbit.tcp_listen_options.high_msgq_watermark", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.high_watermark", "rabbit.tcp_listen_options.high_watermark", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.keepalive", "rabbit.tcp_listen_options.keepalive", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "tcp_listen_options.low_msgq_watermark", "rabbit.tcp_listen_options.low_msgq_watermark", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.low_watermark", "rabbit.tcp_listen_options.low_watermark", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.port", "rabbit.tcp_listen_options.port", + [{datatype, integer}, {validators, ["port"]}]}. + +{mapping, "tcp_listen_options.priority", "rabbit.tcp_listen_options.priority", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.recbuf", "rabbit.tcp_listen_options.recbuf", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.send_timeout", "rabbit.tcp_listen_options.send_timeout", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.send_timeout_close", "rabbit.tcp_listen_options.send_timeout_close", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "tcp_listen_options.sndbuf", "rabbit.tcp_listen_options.sndbuf", + [{datatype, integer}]}. + +{mapping, "tcp_listen_options.tos", "rabbit.tcp_listen_options.tos", + [{datatype, integer}]}. + +%% ========================================================================== + +%% +%% Resource Limits & Flow Control +%% ============================== +%% +%% See http://www.rabbitmq.com/memory.html for full details. + +%% Memory-based Flow Control threshold. +%% +%% {vm_memory_high_watermark, 0.4}, + +%% Alternatively, we can set a limit (in bytes) of RAM used by the node. +%% +%% {vm_memory_high_watermark, {absolute, 1073741824}}, +%% +%% Or you can set absolute value using memory units (with RabbitMQ 3.6.0+). +%% +%% {vm_memory_high_watermark, {absolute, "1024M"}}, +%% +%% Supported units suffixes: +%% +%% kb, KB: kibibytes (2^10 bytes) +%% mb, MB: mebibytes (2^20) +%% gb, GB: gibibytes (2^30) + +{mapping, "vm_memory_high_watermark.relative", "rabbit.vm_memory_high_watermark", [ + {datatype, float}]}. + +{mapping, "vm_memory_high_watermark.absolute", "rabbit.vm_memory_high_watermark", [ + {datatype, [integer, string]}]}. + + +{translation, "rabbit.vm_memory_high_watermark", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("vm_memory_high_watermark", Conf), + Absolute = proplists:get_value(["vm_memory_high_watermark", "absolute"], Settings), + Relative = proplists:get_value(["vm_memory_high_watermark", "relative"], Settings), + case {Absolute, Relative} of + {undefined, undefined} -> cuttlefish:invalid("No vm watermark defined"); + {_, undefined} -> {absolute, Absolute}; + _ -> Relative + end +end}. + +%% Fraction of the high watermark limit at which queues start to +%% page message out to disc in order to free up memory. +%% +%% Values greater than 0.9 can be dangerous and should be used carefully. +%% +%% {vm_memory_high_watermark_paging_ratio, 0.5}, + +{mapping, "vm_memory_high_watermark_paging_ratio", + "rabbit.vm_memory_high_watermark_paging_ratio", + [{datatype, float}, {validators, ["less_than_1"]}]}. + +%% Interval (in milliseconds) at which we perform the check of the memory +%% levels against the watermarks. +%% +%% {memory_monitor_interval, 2500}, + +{mapping, "memory_monitor_interval", "rabbit.memory_monitor_interval", + [{datatype, integer}]}. + +%% Set disk free limit (in bytes). Once free disk space reaches this +%% lower bound, a disk alarm will be set - see the documentation +%% listed above for more details. +%% +%% {disk_free_limit, 50000000}, +%% +%% Or you can set it using memory units (same as in vm_memory_high_watermark) +%% with RabbitMQ 3.6.0+. +%% {disk_free_limit, "50MB"}, +%% {disk_free_limit, "50000kB"}, +%% {disk_free_limit, "2GB"}, + +%% Alternatively, we can set a limit relative to total available RAM. +%% +%% Values lower than 1.0 can be dangerous and should be used carefully. +%% {disk_free_limit, {mem_relative, 2.0}}, + +{mapping, "disk_free_limit.relative", "rabbit.disk_free_limit", [ + {datatype, float}]}. + +{mapping, "disk_free_limit.absolute", "rabbit.disk_free_limit", [ + {datatype, [integer, string]}]}. + + +{translation, "rabbit.disk_free_limit", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("disk_free_limit", Conf), + Absolute = proplists:get_value(["disk_free_limit", "absolute"], Settings), + Relative = proplists:get_value(["disk_free_limit", "relative"], Settings), + case {Absolute, Relative} of + {undefined, undefined} -> cuttlefish:invalid("No disk limit defined"); + {_, undefined} -> Absolute; + _ -> {mem_relative, Relative} + end +end}. + +%% +%% Clustering +%% ===================== +%% + +%% How to respond to cluster partitions. +%% See http://www.rabbitmq.com/partitions.html for further details. +%% +%% {cluster_partition_handling, ignore}, + +{mapping, "cluster_partition_handling", "rabbit.cluster_partition_handling", + [{datatype, {enum, [ignore, pause_minority, autoheal, pause_if_all_down]}}]}. + +{mapping, "cluster_partition_handling.pause_if_all_down.recover", + "rabbit.cluster_partition_handling", + [{datatype, {enum, [ignore, autoheal]}}]}. + +{mapping, "cluster_partition_handling.pause_if_all_down.nodes.$name", + "rabbit.cluster_partition_handling", + [{datatype, atom}]}. + +{translation, "rabbit.cluster_partition_handling", +fun(Conf) -> + case cuttlefish:conf_get("cluster_partition_handling", Conf) of + pause_if_all_down -> + PauseIfAllDownNodes = cuttlefish_variable:filter_by_prefix( + "cluster_partition_handling.pause_if_all_down.nodes", + Conf), + case PauseIfAllDownNodes of + [] -> + cuttlefish:invalid("Nodes required for pause_if_all_down"); + _ -> + Nodes = [ V || {K,V} <- PauseIfAllDownNodes ], + PauseIfAllDownRecover = cuttlefish:conf_get( + "cluster_partition_handling.pause_if_all_down.recover", + Conf), + case PauseIfAllDownRecover of + Recover when Recover == ignore; Recover == autoheal -> + {pause_if_all_down, Nodes, Recover}; + Invalid -> + cuttlefish:invalid("Recover strategy required for pause_if_all_down") + end + end; + Other -> Other + end +end}. + +%% Mirror sync batch size, in messages. Increasing this will speed +%% up syncing but total batch size in bytes must not exceed 2 GiB. +%% Available in RabbitMQ 3.6.0 or later. +%% +%% {mirroring_sync_batch_size, 4096}, + +{mapping, "mirroring_sync_batch_size", "rabbit.mirroring_sync_batch_size", + [{datatype, bytesize}, {validators, ["size_less_than_2G"]}]}. + +%% Make clustering happen *automatically* at startup - only applied +%% to nodes that have just been reset or started for the first time. +%% See http://www.rabbitmq.com/clustering.html#auto-config for +%% further details. +%% +%% {cluster_nodes, {['rabbit@my.host.com'], disc}}, + +{mapping, "cluster_nodes.disc.$node", "rabbit.cluster_nodes", + [{datatype, atom}]}. + +{mapping, "cluster_nodes.ram.$node", "rabbit.cluster_nodes", + [{datatype, atom}]}. + +{translation, "rabbit.cluster_nodes", +fun(Conf) -> + DiskNodes = [ V || {_, V} <- cuttlefish_variable:filter_by_prefix("cluster_nodes.disc", Conf)], + RamNodes = [ V || {_, V} <- cuttlefish_variable:filter_by_prefix("cluster_nodes.ram", Conf)], + + case {DiskNodes, RamNodes} of + {_, []} -> {DiskNodes, disc}; + {[], _} -> {RamNodes, ram} + end +end}. + + +%% Interval (in milliseconds) at which we send keepalive messages +%% to other cluster members. Note that this is not the same thing +%% as net_ticktime; missed keepalive messages will not cause nodes +%% to be considered down. +%% +%% {cluster_keepalive_interval, 10000}, + +{mapping, "cluster_keepalive_interval", "rabbit.cluster_keepalive_interval", + [{datatype, integer}]}. + + +{mapping, "queue_master_locator", "rabbit.queue_master_locator", + [{datatype, string}]}. + +{translation, "rabbit.queue_master_locator", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("queue_master_locator", Conf)) +end}. + +%% +%% Statistics Collection +%% ===================== +%% + +%% Set (internal) statistics collection granularity. +%% +%% {collect_statistics, none}, + +{mapping, "collect_statistics", "rabbit.collect_statistics", + [{datatype, {enum, [none, coarse, fine]}}]}. + +%% Statistics collection interval (in milliseconds). Increasing +%% this will reduce the load on management database. +%% +%% {collect_statistics_interval, 5000}, + +{mapping, "collect_statistics_interval", "rabbit.collect_statistics_interval", + [{datatype, integer}]}. + +%% +%% Misc/Advanced Options +%% ===================== +%% +%% NB: Change these only if you understand what you are doing! +%% + +%% Explicitly enable/disable hipe compilation. +%% +%% {hipe_compile, true}, + +{mapping, "hipe_compile", "rabbit.hipe_compile", + [{datatype, {enum, [true, false]}}]}. + +%% Timeout used when waiting for Mnesia tables in a cluster to +%% become available. +%% +%% {mnesia_table_loading_timeout, 30000}, + +{mapping, "mnesia_table_loading_timeout", "rabbit.mnesia_table_loading_timeout", + [{datatype, integer}]}. + +%% Size in bytes below which to embed messages in the queue index. See +%% http://www.rabbitmq.com/persistence-conf.html +%% +%% {queue_index_embed_msgs_below, 4096} + +{mapping, "queue_index_embed_msgs_below", "rabbit.queue_index_embed_msgs_below", + [{datatype, bytesize}]}. + +% ========================== +% Lager section +% ========================== + +{mapping, "log.dir", "lager.log_root", [ + {datatype, string}, + {validators, ["dir_writable"]}]}. + +{mapping, "log.console", "lager.handlers", [ + {datatype, {enum, [true, false]}} +]}. + +{mapping, "log.syslog", "lager.handlers", [ + {datatype, {enum, [true, false]}} +]}. +{mapping, "log.file", "lager.handlers", [ + {datatype, [{enum, [false]}, string]} +]}. + +{mapping, "log.file.level", "lager.handlers", [ + {datatype, {enum, [debug, info, warning, error]}} +]}. +{mapping, "log.$handler.level", "lager.handlers", [ + {datatype, {enum, [debug, info, warning, error]}} +]}. +{mapping, "log.file.rotation.date", "lager.handlers", [ + {datatype, string} +]}. +{mapping, "log.file.rotation.size", "lager.handlers", [ + {datatype, integer} +]}. +{mapping, "log.file.rotation.count", "lager.handlers", [ + {datatype, integer} +]}. + +{mapping, "log.syslog.identity", "lager.handlers", [ + {datatype, string} +]}. +{mapping, "log.syslog.facility", "lager.handlers", [ + {datatype, atom} +]}. + +{translation, "lager.handlers", +fun(Conf) -> + ConsoleHandler = case cuttlefish:conf_get("log.console", Conf, false) of + true -> + ConsoleLevel = cuttlefish:conf_get("log.console.level", Conf, info), + [{lager_console_backend, ConsoleLevel}]; + false -> [] + end, + FileHandler = case cuttlefish:conf_get("log.file", Conf, false) of + false -> []; + File -> + FileLevel = cuttlefish:conf_get("log.file.level", Conf, info), + RotationDate = cuttlefish:conf_get("log.file.rotation.date", Conf, ""), + RotationSize = cuttlefish:conf_get("log.file.rotation.size", Conf, 0), + RotationCount = cuttlefish:conf_get("log.file.rotation.count", Conf, 10), + [{lager_file_backend, [{file, File}, + {level, FileLevel}, + {date, RotationDate}, + {size, RotationSize}, + {count, RotationCount}]}] + end, + SyslogHandler = case cuttlefish:conf_get("log.syslog", Conf, false) of + false -> []; + true -> + SyslogLevel = cuttlefish:conf_get("log.syslog.level", Conf, info), + Identity = cuttlefish:conf_get("log.syslog.identity", Conf), + Facility = cuttlefish:conf_get("log.syslog.facility", Conf), + [{lager_syslog_backend, [Identity, Facility, SyslogLevel]}] + end, + case ConsoleHandler ++ FileHandler ++ SyslogHandler of + [] -> undefined; + Other -> Other + end +end}. + + +% =============================== +% Validators +% =============================== + +{validator, "size_less_than_2G", "Byte size should be less than 2G and greater than 0", +fun(Size) when is_integer(Size) -> + Size > 0 andalso Size < 2147483648 +end}. + +{validator, "less_than_1", "Flooat is not beetween 0 and 1", +fun(Float) when is_float(Float) -> + Float > 0 andalso Float < 1 +end}. + +{validator, "port", "Invalid port number", +fun(Port) when is_integer(Port) -> + Port > 0 andalso Port < 65535 +end}. + +{validator, "byte", "Integer is not 0<i<255", +fun(Int) when is_integer(Int) -> + Int > 0 andalso Int < 255 +end}. + +{validator, "dir_writable", "Cannot create file in dir", +fun(Dir) -> + TestFile = filename:join(Dir, "test_file"), + file:delete(TestFile), + Res = ok == file:write_file(TestFile, <<"test">>), + file:delete(TestFile), + Res +end}. + +{validator, "file_accessible", "file doesnt exist or unaccessible", +fun(File) -> + ReadFile = file:read_file_info(File), + element(1, ReadFile) == ok +end}. + +{validator, "is_ip", "string is a valid IP address", +fun(IpStr) -> + Res = inet:parse_address(IpStr), + element(1, Res) == ok +end}. diff --git a/test/config_schema_SUITE_data/schema/rabbitmq_amqp1_0.schema b/test/config_schema_SUITE_data/schema/rabbitmq_amqp1_0.schema new file mode 100644 index 0000000000..e6cfb68262 --- /dev/null +++ b/test/config_schema_SUITE_data/schema/rabbitmq_amqp1_0.schema @@ -0,0 +1,31 @@ +%% ---------------------------------------------------------------------------- +%% RabbitMQ AMQP 1.0 Support +%% +%% See https://github.com/rabbitmq/rabbitmq-amqp1.0/blob/stable/README.md +%% for details +%% ---------------------------------------------------------------------------- + +% {rabbitmq_amqp1_0,[ +%% Connections that are not authenticated with SASL will connect as this +%% account. See the README for more information. +%% +%% Please note that setting this will allow clients to connect without +%% authenticating! +%% +%% {default_user, "guest"}, +{mapping, "amqp1_0.default_user", "rabbitmq_amqp1_0.default_user", + [{datatype, [{enum, [none]}, string]}]}. +%% Enable protocol strict mode. See the README for more information. +%% +%% {protocol_strict_mode, false} +% ]}, +{mapping, "amqp1_0.protocol_strict_mode", "rabbitmq_amqp1_0.protocol_strict_mode", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "amqp1_0.default_vhost", "rabbitmq_amqp1_0.default_vhost", + [{datatype, string}]}. + +{translation , "rabbitmq_amqp1_0.default_vhost", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("amqp1_0.default_vhost", Conf)) +end}.
\ No newline at end of file diff --git a/test/config_schema_SUITE_data/schema/rabbitmq_auth_backend_amqp.schema b/test/config_schema_SUITE_data/schema/rabbitmq_auth_backend_amqp.schema new file mode 100644 index 0000000000..a30efb6c03 --- /dev/null +++ b/test/config_schema_SUITE_data/schema/rabbitmq_auth_backend_amqp.schema @@ -0,0 +1,27 @@ +{mapping, "rabbitmq_auth_backend_amqp.username", "rabbitmq_auth_backend_amqp.username", + [{datatype, string}]}. + +{translation, "rabbitmq_auth_backend_amqp.username", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("rabbitmq_auth_backend_amqp.username", Conf)) +end}. + +{mapping, "rabbitmq_auth_backend_amqp.vhost", "rabbitmq_auth_backend_amqp.vhost", + [{datatype, string}]}. + +{translation, "rabbitmq_auth_backend_amqp.vhost", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("rabbitmq_auth_backend_amqp.vhost", Conf)) +end}. + +{mapping, "rabbitmq_auth_backend_amqp.exchange", "rabbitmq_auth_backend_amqp.exchange", + [{datatype, string}]}. + +{translation, "rabbitmq_auth_backend_amqp.exchange", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("rabbitmq_auth_backend_amqp.exchange", Conf)) +end}. + + +{mapping, "rabbitmq_auth_backend_amqp.timeout", "rabbitmq_auth_backend_amqp.timeout", + [{datatype, [{enum, [infinity]}, integer]}]}. diff --git a/test/config_schema_SUITE_data/schema/rabbitmq_auth_backend_http.schema b/test/config_schema_SUITE_data/schema/rabbitmq_auth_backend_http.schema new file mode 100644 index 0000000000..f10eb6710b --- /dev/null +++ b/test/config_schema_SUITE_data/schema/rabbitmq_auth_backend_http.schema @@ -0,0 +1,15 @@ + +%% ========================================================================== +%% ---------------------------------------------------------------------------- +%% RabbitMQ HTTP Authorization +%% +%% ---------------------------------------------------------------------------- + +{mapping, "rabbitmq_auth_backend_http.user_path", "rabbitmq_auth_backend_http.user_path", + [{datatype, string}, {validators, ["uri"]}]}. + +{mapping, "rabbitmq_auth_backend_http.vhost_path", "rabbitmq_auth_backend_http.vhost_path", + [{datatype, string}, {validators, ["uri"]}]}. + +{mapping, "rabbitmq_auth_backend_http.resource_path", "rabbitmq_auth_backend_http.resource_path", + [{datatype, string}, {validators, ["uri"]}]}. diff --git a/test/config_schema_SUITE_data/schema/rabbitmq_auth_backend_ldap.schema b/test/config_schema_SUITE_data/schema/rabbitmq_auth_backend_ldap.schema new file mode 100644 index 0000000000..334fd014c1 --- /dev/null +++ b/test/config_schema_SUITE_data/schema/rabbitmq_auth_backend_ldap.schema @@ -0,0 +1,183 @@ +%% ---------------------------------------------------------------------------- +%% RabbitMQ LDAP Plugin +%% +%% See http://www.rabbitmq.com/ldap.html for details. +%% +%% ---------------------------------------------------------------------------- + +% {rabbitmq_auth_backend_ldap, +% [ +%% +%% Connecting to the LDAP server(s) +%% ================================ +%% + +%% Specify servers to bind to. You *must* set this in order for the plugin +%% to work properly. +%% +%% {servers, ["your-server-name-goes-here"]}, + +{mapping, "rabbitmq_auth_backend_ldap.servers", "rabbitmq_auth_backend_ldap.servers", + [{datatype, {enum, [none]}}]}. + +{mapping, "rabbitmq_auth_backend_ldap.servers.$server", "rabbitmq_auth_backend_ldap.servers", + [{datatype, string}]}. + +{translation, "rabbitmq_auth_backend_ldap.servers", +fun(Conf) -> + case cuttlefish:conf_get("rabbitmq_auth_backend_ldap.servers", Conf, undefined) of + none -> []; + _ -> + Settings = cuttlefish_variable:filter_by_prefix("rabbitmq_auth_backend_ldap.servers", Conf), + [ V || {_, V} <- Settings ] + end +end}. + +%% Connect to the LDAP server using SSL +%% +%% {use_ssl, false}, + +{mapping, "rabbitmq_auth_backend_ldap.use_ssl", "rabbitmq_auth_backend_ldap.use_ssl", + [{datatype, {enum, [true, false]}}]}. + +%% Specify the LDAP port to connect to +%% +%% {port, 389}, + +{mapping, "rabbitmq_auth_backend_ldap.port", "rabbitmq_auth_backend_ldap.port", + [{datatype, integer}]}. + +%% LDAP connection timeout, in milliseconds or 'infinity' +%% +%% {timeout, infinity}, + +{mapping, "rabbitmq_auth_backend_ldap.timeout", "rabbitmq_auth_backend_ldap.timeout", + [{datatype, [integer, {atom, infinity}]}]}. + +%% Enable logging of LDAP queries. +%% One of +%% - false (no logging is performed) +%% - true (verbose logging of the logic used by the plugin) +%% - network (as true, but additionally logs LDAP network traffic) +%% +%% Defaults to false. +%% +%% {log, false}, + +{mapping, "rabbitmq_auth_backend_ldap.log", "rabbitmq_auth_backend_ldap.log", + [{datatype, {enum, [true, false, network]}}]}. + +%% +%% Authentication +%% ============== +%% + +%% Pattern to convert the username given through AMQP to a DN before +%% binding +%% +%% {user_dn_pattern, "cn=${username},ou=People,dc=example,dc=com"}, + +{mapping, "rabbitmq_auth_backend_ldap.user_dn_pattern", "rabbitmq_auth_backend_ldap.user_dn_pattern", + [{datatype, string}]}. + +%% Alternatively, you can convert a username to a Distinguished +%% Name via an LDAP lookup after binding. See the documentation for +%% full details. + +%% When converting a username to a dn via a lookup, set these to +%% the name of the attribute that represents the user name, and the +%% base DN for the lookup query. +%% +%% {dn_lookup_attribute, "userPrincipalName"}, +%% {dn_lookup_base, "DC=gopivotal,DC=com"}, + +{mapping, "rabbitmq_auth_backend_ldap.dn_lookup_attribute", "rabbitmq_auth_backend_ldap.dn_lookup_attribute", + [{datatype, [{enum, [none]}, string]}]}. + +{mapping, "rabbitmq_auth_backend_ldap.dn_lookup_base", "rabbitmq_auth_backend_ldap.dn_lookup_base", + [{datatype, [{enum, [none]}, string]}]}. + +{mapping, "rabbitmq_auth_backend_ldap.dn_lookup_bind", "rabbitmq_auth_backend_ldap.dn_lookup_bind", + [{datatype, [{enum, [as_user]}]}]}. + +{mapping, "rabbitmq_auth_backend_ldap.dn_lookup_bind.user_dn", "rabbitmq_auth_backend_ldap.dn_lookup_bind", + [{datatype, [string]}]}. + +{mapping, "rabbitmq_auth_backend_ldap.dn_lookup_bind.password", "rabbitmq_auth_backend_ldap.dn_lookup_bind", + [{datatype, [string]}]}. + +{translation, "rabbitmq_auth_backend_ldap.dn_lookup_bind", +fun(Conf) -> + case cuttlefish:conf_get("rabbitmq_auth_backend_ldap.dn_lookup_bind", Conf, undefined) of + as_user -> as_user; + _ -> + User = cuttlefish:conf_get("rabbitmq_auth_backend_ldap.dn_lookup_bind.user_dn", Conf), + Pass = cuttlefish:conf_get("rabbitmq_auth_backend_ldap.dn_lookup_bind.password", Conf), + case {User, Pass} of + {undefined, _} -> as_user; + {_, undefined} -> as_user; + _ -> {User, Pass} + end + end +end}. + +%% Controls how to bind for authorisation queries and also to +%% retrieve the details of users logging in without presenting a +%% password (e.g., SASL EXTERNAL). +%% One of +%% - as_user (to bind as the authenticated user - requires a password) +%% - anon (to bind anonymously) +%% - {UserDN, Password} (to bind with a specified user name and password) +%% +%% Defaults to 'as_user'. +%% +%% {other_bind, as_user}, + +{mapping, "rabbitmq_auth_backend_ldap.other_bind", "rabbitmq_auth_backend_ldap.other_bind", + [{datatype, {enum, [as_user, anon]}}]}. + +{mapping, "rabbitmq_auth_backend_ldap.other_bind.user_dn", "rabbitmq_auth_backend_ldap.other_bind", + [{datatype, string}]}. + +{mapping, "rabbitmq_auth_backend_ldap.other_bind.password", "rabbitmq_auth_backend_ldap.other_bind", + [{datatype, string}]}. + +{translation, "rabbitmq_auth_backend_ldap.other_bind", +fun(Conf) -> + case cuttlefish:conf_get("rabbitmq_auth_backend_ldap.other_bind", Conf, undefined) of + as_user -> as_user; + anon -> anon; + _ -> + User = cuttlefish:conf_get("rabbitmq_auth_backend_ldap.other_bind.user_dn", Conf), + Pass = cuttlefish:conf_get("rabbitmq_auth_backend_ldap.other_bind.password", Conf), + case {User, Pass} of + {undefined, _} -> as_user; + {_, undefined} -> as_user; + _ -> {User, Pass} + end + end +end}. + +%% +%% Authorisation +%% ============= +%% + +%% The LDAP plugin can perform a variety of queries against your +%% LDAP server to determine questions of authorisation. See +%% http://www.rabbitmq.com/ldap.html#authorisation for more +%% information. + +%% Set the query to use when determining vhost access +%% +%% {vhost_access_query, {in_group, +%% "ou=${vhost}-users,ou=vhosts,dc=example,dc=com"}}, + +%% Set the query to use when determining resource (e.g., queue) access +%% +%% {resource_access_query, {constant, true}}, + +%% Set queries to determine which tags a user has +%% +%% {tag_queries, []} +% ]}, diff --git a/test/config_schema_SUITE_data/schema/rabbitmq_clusterer.schema b/test/config_schema_SUITE_data/schema/rabbitmq_clusterer.schema new file mode 100644 index 0000000000..ba127f00c1 --- /dev/null +++ b/test/config_schema_SUITE_data/schema/rabbitmq_clusterer.schema @@ -0,0 +1,58 @@ +{mapping, "clusterer.config", "rabbitmq_clusterer.config", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{translation, "rabbitmq_clusterer.config", +fun(Conf) -> + case cuttlefish:conf_get("clusterer.config", Conf, undefined) of + String when is_list(String) -> + case cuttlefish_variable:filter_by_prefix("clusterer", Conf) of + [{["clusterer", "config"], String}] -> String; + _ -> cuttlefish:invalid("Config for clusterer defined in "++ + String ++ " file. " ++ + "All other clusterer configurations should be removed") + end; + _ -> [] + end +end}. + +{mapping, "clusterer.version", "rabbitmq_clusterer.config.version", + [{datatype, integer}]}. + +{mapping, "clusterer.nodes.$node", "rabbitmq_clusterer.config.nodes", + [{datatype, atom}]}. + +{mapping, "clusterer.nodes.ram.$node", "rabbitmq_clusterer.config.nodes", + [{datatype, atom}]}. + +{mapping, "clusterer.nodes.disk.$node", "rabbitmq_clusterer.config.nodes", + [{datatype, atom}]}. + +{mapping, "clusterer.nodes.disc.$node", "rabbitmq_clusterer.config.nodes", + [{datatype, atom}]}. + +{translation, "rabbitmq_clusterer.config.nodes", +fun(Conf) -> + DiskNodes = cuttlefish_variable:filter_by_prefix("clusterer.nodes", Conf) + ++ cuttlefish_variable:filter_by_prefix("clusterer.nodes.disk", Conf) + ++ cuttlefish_variable:filter_by_prefix("clusterer.nodes.disc", Conf), + RamNodes = cuttlefish_variable:filter_by_prefix("clusterer.nodes.ram", Conf), + [{Node, disk} || {_, Node} <- DiskNodes] ++ [{Node, ram} || Node <- RamNodes] +end}. + +{mapping, "clusterer.gospel", "rabbitmq_clusterer.config.gospel", + [{datatype, {enum, [reset]}}]}. + +{mapping, "clusterer.gospel.node", "rabbitmq_clusterer.config.gospel", + [{datatype, atom}]}. + +{translation, "rabbitmq_clusterer.config.gospel", +fun(Conf) -> + case cuttlefish:conf_get("clusterer.gospel", Conf, undefined) of + reset -> reset; + _ -> + {node, cuttlefish:conf_get("clusterer.gospel.node", Conf)} + end +end}. + + + diff --git a/test/config_schema_SUITE_data/schema/rabbitmq_management.schema b/test/config_schema_SUITE_data/schema/rabbitmq_management.schema new file mode 100644 index 0000000000..7ac6d21b93 --- /dev/null +++ b/test/config_schema_SUITE_data/schema/rabbitmq_management.schema @@ -0,0 +1,203 @@ +%% ---------------------------------------------------------------------------- +%% RabbitMQ Management Plugin +%% +%% See http://www.rabbitmq.com/management.html for details +%% ---------------------------------------------------------------------------- + + % {rabbitmq_management, + % [%% Pre-Load schema definitions from the following JSON file. See +%% http://www.rabbitmq.com/management.html#load-definitions +%% +%% {load_definitions, "/path/to/schema.json"}, +{mapping, "management.load_definitions", "rabbitmq_management.load_definitions", + [{datatype, string}, + {validators, ["file_accessible"]}]}. + +%% Log all requests to the management HTTP API to a file. +%% +%% {http_log_dir, "/path/to/access.log"}, + +{mapping, "management.http_log_dir", "rabbitmq_management.http_log_dir", + [{datatype, string}]}. + + +%% Change the port on which the HTTP listener listens, +%% specifying an interface for the web server to bind to. +%% Also set the listener to use SSL and provide SSL options. +%% +%% {listener, [{port, 12345}, +%% {ip, "127.0.0.1"}, +%% {ssl, true}, +%% {ssl_opts, [{cacertfile, "/path/to/cacert.pem"}, +%% {certfile, "/path/to/cert.pem"}, +%% {keyfile, "/path/to/key.pem"}]}]}, + +{mapping, "management.listener.port", "rabbitmq_management.listener.port", + [{datatype, integer}]}. + +{mapping, "management.listener.ip", "rabbitmq_management.listener.ip", + [{datatype, string}, + {validators, ["is_ip"]}]}. + +{mapping, "management.listener.ssl", "rabbitmq_management.listener.ssl", + [{datatype, {enum, [true, false]}}]}. + + +%% SSL options section ======================================================== + +{mapping, "management.listener.ssl_opts", "rabbitmq_management.listener.ssl_opts", [ + {datatype, {enum, [none]}} +]}. + +{translation, "rabbitmq_management.listener.ssl_opts", +fun(Conf) -> + case cuttlefish:conf_get("management.listener.ssl_opts", Conf, undefined) of + none -> []; + _ -> cuttlefish:invalid("Invalid management.listener.ssl_opts") + end +end}. + +{mapping, "management.listener.ssl_opts.verify", "rabbitmq_management.listener.ssl_opts.verify", [ + {datatype, {enum, [verify_peer, verify_none]}}]}. + +{mapping, "management.listener.ssl_opts.fail_if_no_peer_cert", "rabbitmq_management.listener.ssl_opts.fail_if_no_peer_cert", [ + {datatype, {enum, [true, false]}}]}. + +{mapping, "management.listener.ssl_opts.cacertfile", "rabbitmq_management.listener.ssl_opts.cacertfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{mapping, "management.listener.ssl_opts.certfile", "rabbitmq_management.listener.ssl_opts.certfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{mapping, "management.listener.ssl_opts.cacerts.$name", "rabbitmq_management.listener.ssl_opts.cacerts", + [{datatype, string}]}. + +{translation, "rabbitmq_management.listener.ssl_opts.cacerts", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("management.listener.ssl_opts.cacerts", Conf), + [ list_to_binary(V) || {_, V} <- Settings ] +end}. + +{mapping, "management.listener.ssl_opts.cert", "rabbitmq_management.listener.ssl_opts.cert", + [{datatype, string}]}. + +{translation, "rabbitmq_management.listener.ssl_opts.cert", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("management.listener.ssl_opts.cert", Conf)) +end}. + +{mapping, "management.listener.ssl_opts.client_renegotiation", "rabbitmq_management.listener.ssl_opts.client_renegotiation", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "management.listener.ssl_opts.crl_check", "rabbitmq_management.listener.ssl_opts.crl_check", + [{datatype, [{enum, [true, false, peer, best_effort]}]}]}. + +{mapping, "management.listener.ssl_opts.depth", "rabbitmq_management.listener.ssl_opts.depth", + [{datatype, integer}, {validators, ["byte"]}]}. + +{mapping, "management.listener.ssl_opts.dh", "rabbitmq_management.listener.ssl_opts.dh", + [{datatype, string}]}. + +{translation, "rabbitmq_management.listener.ssl_opts.dh", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("management.listener.ssl_opts.dh", Conf)) +end}. + +{mapping, "management.listener.ssl_opts.dhfile", "rabbitmq_management.listener.ssl_opts.dhfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{mapping, "management.listener.ssl_opts.honor_cipher_order", "rabbitmq_management.listener.ssl_opts.honor_cipher_order", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "management.listener.ssl_opts.key.RSAPrivateKey", "rabbitmq_management.listener.ssl_opts.key", + [{datatype, string}]}. + +{mapping, "management.listener.ssl_opts.key.DSAPrivateKey", "rabbitmq_management.listener.ssl_opts.key", + [{datatype, string}]}. + +{mapping, "management.listener.ssl_opts.key.PrivateKeyInfo", "rabbitmq_management.listener.ssl_opts.key", + [{datatype, string}]}. + +{translation, "rabbitmq_management.listener.ssl_opts.key", +fun(Conf) -> + case cuttlefish_variable:filter_by_prefix("management.listener.ssl_opts.key", Conf) of + [{[_,_,Key], Val}|_] -> {list_to_atom(Key), list_to_binary(Val)}; + _ -> undefined + end +end}. + +{mapping, "management.listener.ssl_opts.keyfile", "rabbitmq_management.listener.ssl_opts.keyfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. + +{mapping, "management.listener.ssl_opts.log_alert", "rabbitmq_management.listener.ssl_opts.log_alert", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "management.listener.ssl_opts.password", "rabbitmq_management.listener.ssl_opts.password", + [{datatype, string}]}. + +{mapping, "management.listener.ssl_opts.psk_identity", "rabbitmq_management.listener.ssl_opts.psk_identity", + [{datatype, string}]}. + +{mapping, "management.listener.ssl_opts.reuse_sessions", "rabbitmq_management.listener.ssl_opts.reuse_sessions", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "management.listener.ssl_opts.secure_renegotiate", "rabbitmq_management.listener.ssl_opts.secure_renegotiate", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "management.listener.ssl_opts.versions.$version", "rabbitmq_management.listener.ssl_opts.versions", + [{datatype, atom}]}. + +{translation, "rabbitmq_management.listener.ssl_opts.versions", +fun(Conf) -> + Settings = cuttlefish_variable:filter_by_prefix("management.listener.ssl_opts.versions", Conf), + [ V || {_, V} <- Settings ] +end}. + +%% =========================================================================== + + +%% One of 'basic', 'detailed' or 'none'. See +%% http://www.rabbitmq.com/management.html#fine-stats for more details. +%% {rates_mode, basic}, +{mapping, "management.rates_mode", "rabbitmq_management.rates_mode", + [{datatype, {enum, [basic, detailed, none]}}]}. + +%% Configure how long aggregated data (such as message rates and queue +%% lengths) is retained. Please read the plugin's documentation in +%% http://www.rabbitmq.com/management.html#configuration for more +%% details. +%% +%% {sample_retention_policies, +%% [{global, [{60, 5}, {3600, 60}, {86400, 1200}]}, +%% {basic, [{60, 5}, {3600, 60}]}, +%% {detailed, [{10, 5}]}]} +% ]}, + +{mapping, "management.sample_retention_policies.$section.$interval", + "rabbitmq_management.sample_retention_policies", + [{datatype, integer}]}. + +{translation, "rabbitmq_management.sample_retention_policies", +fun(Conf) -> + Global = cuttlefish_variable:filter_by_prefix("management.sample_retention_policies.global", Conf), + Basic = cuttlefish_variable:filter_by_prefix("management.sample_retention_policies.basic", Conf), + Detailed = cuttlefish_variable:filter_by_prefix("management.sample_retention_policies.detailed", Conf), + TranslateKey = fun("minute") -> 60; + ("hour") -> 3600; + ("day") -> 86400; + (Other) -> list_to_integer(Other) + end, + TranslatePolicy = fun(Section) -> + [ {TranslateKey(Key), Val} || {[_,_,_,Key], Val} <- Section ] + end, + [{global, TranslatePolicy(Global)}, + {basic, TranslatePolicy(Basic)}, + {detailed, TranslatePolicy(Detailed)}] +end}. + + +{validator, "is_dir", "is not directory", +fun(File) -> + ReadFile = file:list_dir(File), + element(1, ReadFile) == ok +end}. diff --git a/test/config_schema_SUITE_data/schema/rabbitmq_metronome.schema b/test/config_schema_SUITE_data/schema/rabbitmq_metronome.schema new file mode 100644 index 0000000000..53cf8f003e --- /dev/null +++ b/test/config_schema_SUITE_data/schema/rabbitmq_metronome.schema @@ -0,0 +1,9 @@ + +{mapping, "metronome.exchange", "rabbitmq_metronome.exchange", + [{datatype, string}]}. + +{translation, "rabbitmq_metronome.exchange", +fun(Conf) -> + Exchange = cuttlefish:conf_get("metronome.exchange", Conf), + list_to_binary(Exchange) +end}.
\ No newline at end of file diff --git a/test/config_schema_SUITE_data/schema/rabbitmq_mqtt.schema b/test/config_schema_SUITE_data/schema/rabbitmq_mqtt.schema new file mode 100644 index 0000000000..1daab5423d --- /dev/null +++ b/test/config_schema_SUITE_data/schema/rabbitmq_mqtt.schema @@ -0,0 +1,235 @@ +%% ---------------------------------------------------------------------------- +%% RabbitMQ MQTT Adapter +%% +%% See https://github.com/rabbitmq/rabbitmq-mqtt/blob/stable/README.md +%% for details +%% ---------------------------------------------------------------------------- + +% {rabbitmq_mqtt, +% [%% Set the default user name and password. Will be used as the default login +%% if a connecting client provides no other login details. +%% +%% Please note that setting this will allow clients to connect without +%% authenticating! +%% +%% {default_user, <<"guest">>}, +%% {default_pass, <<"guest">>}, + +{mapping, "mqtt.default_user", "rabbitmq_mqtt.default_user", [ + {datatype, string} +]}. + +{mapping, "mqtt.default_pass", "rabbitmq_mqtt.default_pass", [ + {datatype, string} +]}. + +{translation, "rabbitmq_mqtt.default_user", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("mqtt.default_user", Conf)) +end}. + +{translation, "rabbitmq_mqtt.default_pass", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("mqtt.default_pass", Conf)) +end}. + +%% Enable anonymous access. If this is set to false, clients MUST provide +%% login information in order to connect. See the default_user/default_pass +%% configuration elements for managing logins without authentication. +%% +%% {allow_anonymous, true}, + +{mapping, "mqtt.allow_anonymous", "rabbitmq_mqtt.allow_anonymous", + [{datatype, {enum, [true, false]}}]}. + +%% If you have multiple chosts, specify the one to which the +%% adapter connects. +%% +%% {vhost, <<"/">>}, + +{mapping, "mqtt.vhost", "rabbitmq_mqtt.vhost", [{datatype, string}]}. + +{translation, "rabbitmq_mqtt.vhost", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("mqtt.vhost", Conf)) +end}. + +%% Specify the exchange to which messages from MQTT clients are published. +%% +%% {exchange, <<"amq.topic">>}, + +{mapping, "mqtt.exchange", "rabbitmq_mqtt.exchange", [{datatype, string}]}. + +{translation, "rabbitmq_mqtt.exchange", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("mqtt.exchange", Conf)) +end}. + +%% Specify TTL (time to live) to control the lifetime of non-clean sessions. +%% +%% {subscription_ttl, 1800000}, +{mapping, "mqtt.subscription_ttl", "rabbitmq_mqtt.subscription_ttl", [ + {datatype, [{enum, [undefined, infinity]}, integer]} +]}. + +{translation, "rabbitmq_mqtt.subscription_ttl", +fun(Conf) -> + case cuttlefish:conf_get("mqtt.subscription_ttl", Conf, undefined) of + undefined -> undefined; + infinity -> undefined; + Ms -> Ms + end +end}. + +%% Set the prefetch count (governing the maximum number of unacknowledged +%% messages that will be delivered). +%% +%% {prefetch, 10}, +{mapping, "mqtt.prefetch", "rabbitmq_mqtt.prefetch", + [{datatype, integer}]}. + + +{mapping, "mqtt.retained_message_store", "rabbitmq_mqtt.retained_message_store", + [{datatype, atom}]}. + +{mapping, "mqtt.retained_message_store_dets_sync_interval", "rabbitmq_mqtt.retained_message_store_dets_sync_interval", + [{datatype, integer}]}. + + + +%% TCP/SSL Configuration (as per the broker configuration). +%% +%% {tcp_listeners, [1883]}, +%% {ssl_listeners, []}, + +{mapping, "mqtt.listeners.tcp", "rabbitmq_mqtt.tcp_listeners",[ + {datatype, {enum, [none]}} +]}. + +{mapping, "mqtt.listeners.tcp.$name", "rabbitmq_mqtt.tcp_listeners",[ + {datatype, [integer, ip]} +]}. + +{translation, "rabbitmq_mqtt.tcp_listeners", +fun(Conf) -> + case cuttlefish:conf_get("mqtt.listeners.tcp", Conf, undefined) of + none -> []; + _ -> + Settings = cuttlefish_variable:filter_by_prefix("mqtt.listeners.tcp", Conf), + [ V || {_, V} <- Settings ] + end +end}. + +{mapping, "mqtt.listeners.ssl", "rabbitmq_mqtt.ssl_listeners",[ + {datatype, {enum, [none]}} +]}. + +{mapping, "mqtt.listeners.ssl.$name", "rabbitmq_mqtt.ssl_listeners",[ + {datatype, [integer, ip]} +]}. + +{translation, "rabbitmq_mqtt.ssl_listeners", +fun(Conf) -> + case cuttlefish:conf_get("mqtt.listeners.ssl", Conf, undefined) of + none -> []; + _ -> + Settings = cuttlefish_variable:filter_by_prefix("mqtt.listeners.ssl", Conf), + [ V || {_, V} <- Settings ] + end +end}. + +%% Number of Erlang processes that will accept connections for the TCP +%% and SSL listeners. +%% +%% {num_tcp_acceptors, 10}, +%% {num_ssl_acceptors, 1}, + +{mapping, "mqtt.num_acceptors.ssl", "rabbitmq_mqtt.num_ssl_acceptors", [ + {datatype, integer} +]}. + +{mapping, "mqtt.num_acceptors.tcp", "rabbitmq_mqtt.num_tcp_acceptors", [ + {datatype, integer} +]}. + +{mapping, "mqtt.ssl_cert_login", "rabbitmq_mqtt.ssl_cert_login", [ + {datatype, {enum, [true, false]}}]}. + + +%% TCP/Socket options (as per the broker configuration). +%% +%% {tcp_listen_options, [{backlog, 128}, +%% {nodelay, true}]} +% ]}, + +%% TCP listener section ====================================================== + +{mapping, "mqtt.tcp_listen_options", "rabbitmq_mqtt.rabbit.tcp_listen_options", [ + {datatype, {enum, [none]}}]}. + +{translation, "rabbitmq_mqtt.rabbit.tcp_listen_options", +fun(Conf) -> + case cuttlefish:conf_get("mqtt.tcp_listen_options") of + none -> []; + _ -> cuttlefish:invalid("Invalid mqtt.tcp_listen_options") + end +end}. + +{mapping, "mqtt.tcp_listen_options.backlog", "rabbitmq_mqtt.tcp_listen_options.backlog", [ + {datatype, integer} +]}. + +{mapping, "mqtt.tcp_listen_options.nodelay", "rabbitmq_mqtt.tcp_listen_options.nodelay", [ + {datatype, {enum, [true, false]}} +]}. + +{mapping, "mqtt.tcp_listen_options.buffer", "rabbitmq_mqtt.tcp_listen_options.buffer", + [{datatype, integer}]}. + +{mapping, "mqtt.tcp_listen_options.delay_send", "rabbitmq_mqtt.tcp_listen_options.delay_send", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "mqtt.tcp_listen_options.dontroute", "rabbitmq_mqtt.tcp_listen_options.dontroute", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "mqtt.tcp_listen_options.exit_on_close", "rabbitmq_mqtt.tcp_listen_options.exit_on_close", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "mqtt.tcp_listen_options.fd", "rabbitmq_mqtt.tcp_listen_options.fd", + [{datatype, integer}]}. + +{mapping, "mqtt.tcp_listen_options.high_msgq_watermark", "rabbitmq_mqtt.tcp_listen_options.high_msgq_watermark", + [{datatype, integer}]}. + +{mapping, "mqtt.tcp_listen_options.high_watermark", "rabbitmq_mqtt.tcp_listen_options.high_watermark", + [{datatype, integer}]}. + +{mapping, "mqtt.tcp_listen_options.keepalive", "rabbitmq_mqtt.tcp_listen_options.keepalive", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "mqtt.tcp_listen_options.low_msgq_watermark", "rabbitmq_mqtt.tcp_listen_options.low_msgq_watermark", + [{datatype, integer}]}. + +{mapping, "mqtt.tcp_listen_options.low_watermark", "rabbitmq_mqtt.tcp_listen_options.low_watermark", + [{datatype, integer}]}. + +{mapping, "mqtt.tcp_listen_options.port", "rabbitmq_mqtt.tcp_listen_options.port", + [{datatype, integer}, {validators, ["port"]}]}. + +{mapping, "mqtt.tcp_listen_options.priority", "rabbitmq_mqtt.tcp_listen_options.priority", + [{datatype, integer}]}. + +{mapping, "mqtt.tcp_listen_options.recbuf", "rabbitmq_mqtt.tcp_listen_options.recbuf", + [{datatype, integer}]}. + +{mapping, "mqtt.tcp_listen_options.send_timeout", "rabbitmq_mqtt.tcp_listen_options.send_timeout", + [{datatype, integer}]}. + +{mapping, "mqtt.tcp_listen_options.send_timeout_close", "rabbitmq_mqtt.tcp_listen_options.send_timeout_close", + [{datatype, {enum, [true, false]}}]}. + +{mapping, "mqtt.tcp_listen_options.sndbuf", "rabbitmq_mqtt.tcp_listen_options.sndbuf", + [{datatype, integer}]}. + +{mapping, "mqtt.tcp_listen_options.tos", "rabbitmq_mqtt.tcp_listen_options.tos", + [{datatype, integer}]}. diff --git a/test/config_schema_SUITE_data/schema/rabbitmq_stomp.schema b/test/config_schema_SUITE_data/schema/rabbitmq_stomp.schema new file mode 100644 index 0000000000..b7619f0b28 --- /dev/null +++ b/test/config_schema_SUITE_data/schema/rabbitmq_stomp.schema @@ -0,0 +1,110 @@ +%% ========================================================================== +%% ---------------------------------------------------------------------------- +%% RabbitMQ Stomp Adapter +%% +%% See http://www.rabbitmq.com/stomp.html for details +%% ---------------------------------------------------------------------------- + +% {rabbitmq_stomp, +% [%% Network Configuration - the format is generally the same as for the broker + +%% Listen only on localhost (ipv4 & ipv6) on a specific port. +%% {tcp_listeners, [{"127.0.0.1", 61613}, +%% {"::1", 61613}]}, + +{mapping, "stomp.listeners.tcp", "rabbitmq_stomp.tcp_listeners",[ + {datatype, {enum, [none]}} +]}. + +{mapping, "stomp.listeners.tcp.$name", "rabbitmq_stomp.tcp_listeners",[ + {datatype, [integer, ip]} +]}. + +{translation, "rabbitmq_stomp.tcp_listeners", +fun(Conf) -> + case cuttlefish:conf_get("stomp.listeners.tcp", Conf, undefined) of + none -> []; + _ -> + Settings = cuttlefish_variable:filter_by_prefix("stomp.listeners.tcp", Conf), + [ V || {_, V} <- Settings ] + end +end}. + +{mapping, "stomp.listeners.ssl", "rabbitmq_stomp.ssl_listeners",[ + {datatype, {enum, [none]}} +]}. + +{mapping, "stomp.listeners.ssl.$name", "rabbitmq_stomp.ssl_listeners",[ + {datatype, [integer, ip]} +]}. + +{translation, "rabbitmq_stomp.ssl_listeners", +fun(Conf) -> + case cuttlefish:conf_get("stomp.listeners.ssl", Conf, undefined) of + none -> []; + _ -> + Settings = cuttlefish_variable:filter_by_prefix("stomp.listeners.ssl", Conf), + [ V || {_, V} <- Settings ] + end +end}. + +%% Number of Erlang processes that will accept connections for the TCP +%% and SSL listeners. +%% +%% {num_tcp_acceptors, 10}, +%% {num_ssl_acceptors, 1}, + +{mapping, "stomp.num_acceptors.ssl", "rabbitmq_stomp.num_ssl_acceptors", [ + {datatype, integer} +]}. + +{mapping, "stomp.num_acceptors.tcp", "rabbitmq_stomp.num_tcp_acceptors", [ + {datatype, integer} +]}. + +%% Additional SSL options + +%% Extract a name from the client's certificate when using SSL. +%% +%% {ssl_cert_login, true}, + +{mapping, "stomp.ssl_cert_login", "rabbitmq_stomp.ssl_cert_login", + [{datatype, {enum, [true, false]}}]}. + +%% Set a default user name and password. This is used as the default login +%% whenever a CONNECT frame omits the login and passcode headers. +%% +%% Please note that setting this will allow clients to connect without +%% authenticating! +%% +%% {default_user, [{login, "guest"}, +%% {passcode, "guest"}]}, + +{mapping, "stomp.default_vhost", "rabbitmq_stomp.default_vhost", [ + {datatype, string} +]}. + +{translation, "rabbitmq_stomp.default_vhost", +fun(Conf) -> + list_to_binary(cuttlefish:conf_get("stomp.default_vhost", Conf, "/")) +end}. + +{mapping, "stomp.default_user", "rabbitmq_stomp.default_user.login", [ + {datatype, string} +]}. + +{mapping, "stomp.default_pass", "rabbitmq_stomp.default_user.passcode", [ + {datatype, string} +]}. + +%% If a default user is configured, or you have configured use SSL client +%% certificate based authentication, you can choose to allow clients to +%% omit the CONNECT frame entirely. If set to true, the client is +%% automatically connected as the default user or user supplied in the +%% SSL certificate whenever the first frame sent on a session is not a +%% CONNECT frame. +%% +%% {implicit_connect, true} +% ]}, +{mapping, "stomp.implicit_connect", "rabbitmq_stomp.implicit_connect", + [{datatype, {enum, [true, false]}}]}. diff --git a/test/config_schema_SUITE_data/schema/rabbitmq_web_mqtt.schema b/test/config_schema_SUITE_data/schema/rabbitmq_web_mqtt.schema new file mode 100644 index 0000000000..acdab62c32 --- /dev/null +++ b/test/config_schema_SUITE_data/schema/rabbitmq_web_mqtt.schema @@ -0,0 +1,44 @@ +{mapping, "web_mqtt.num_acceptors.tcp", "rabbitmq_web_mqtt.num_tcp_acceptors", + [{datatype, integer}]}. +{mapping, "web_mqtt.num_acceptors.ssl", "rabbitmq_web_mqtt.num_ssl_acceptors", + [{datatype, integer}]}. + +{mapping, "web_mqtt.tcp.port", "rabbitmq_web_mqtt.tcp_config.port", + [{datatype, integer}]}. +{mapping, "web_mqtt.tcp.backlog", "rabbitmq_web_mqtt.tcp_config.backlog", + [{datatype, integer}]}. +{mapping, "web_mqtt.tcp.ip", "rabbitmq_web_mqtt.tcp_config.ip", + [{datatype, string}, {validators, ["is_ip"]}]}. + + +{mapping, "web_mqtt.ssl.port", "rabbitmq_web_mqtt.ssl_config.port", + [{datatype, integer}]}. +{mapping, "web_mqtt.ssl.backlog", "rabbitmq_web_mqtt.ssl_config.backlog", + [{datatype, integer}]}. +{mapping, "web_mqtt.ssl.ip", "rabbitmq_web_mqtt.ssl_config.ip", + [{datatype, string}, {validators, ["is_ip"]}]}. +{mapping, "web_mqtt.ssl.certfile", "rabbitmq_web_mqtt.ssl_config.certfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. +{mapping, "web_mqtt.ssl.keyfile", "rabbitmq_web_mqtt.ssl_config.keyfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. +{mapping, "web_mqtt.ssl.cacertfile", "rabbitmq_web_mqtt.ssl_config.cacertfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. +{mapping, "web_mqtt.ssl.password", "rabbitmq_web_mqtt.ssl_config.password", + [{datatype, string}]}. + + +{mapping, "web_mqtt.cowboy_opts.max_empty_lines", "rabbitmq_web_mqtt.cowboy_opts.max_empty_lines", + [{datatype, integer}]}. +{mapping, "web_mqtt.cowboy_opts.max_header_name_length", "rabbitmq_web_mqtt.cowboy_opts.max_header_name_length", + [{datatype, integer}]}. +{mapping, "web_mqtt.cowboy_opts.max_header_value_length", "rabbitmq_web_mqtt.cowboy_opts.max_header_value_length", + [{datatype, integer}]}. +{mapping, "web_mqtt.cowboy_opts.max_headers", "rabbitmq_web_mqtt.cowboy_opts.max_headers", + [{datatype, integer}]}. +{mapping, "web_mqtt.cowboy_opts.max_keepalive", "rabbitmq_web_mqtt.cowboy_opts.max_keepalive", + [{datatype, integer}]}. +{mapping, "web_mqtt.cowboy_opts.max_request_line_length", "rabbitmq_web_mqtt.cowboy_opts.max_request_line_length", + [{datatype, integer}]}. +{mapping, "web_mqtt.cowboy_opts.timeout", "rabbitmq_web_mqtt.cowboy_opts.timeout", + [{datatype, integer}]}. + diff --git a/test/config_schema_SUITE_data/schema/rabbitmq_web_stomp.schema b/test/config_schema_SUITE_data/schema/rabbitmq_web_stomp.schema new file mode 100644 index 0000000000..389da07d14 --- /dev/null +++ b/test/config_schema_SUITE_data/schema/rabbitmq_web_stomp.schema @@ -0,0 +1,64 @@ +{mapping, "web_stomp.port", "rabbitmq_web_stomp.port", + [{datatype, integer}]}. + +{mapping, "web_stomp.ws_frame", "rabbitmq_web_stomp.ws_frame", + [{datatype, {enum, [binary, text]}}]}. + +{mapping, "web_stomp.num_acceptors.tcp", "rabbitmq_web_stomp.num_tcp_acceptors", + [{datatype, integer}]}. + +{mapping, "web_stomp.num_acceptors.ssl", "rabbitmq_web_stomp.num_ssl_acceptors", + [{datatype, integer}]}. + +{mapping, "web_stomp.tcp.port", "rabbitmq_web_stomp.tcp_config.port", + [{datatype, integer}]}. +{mapping, "web_stomp.tcp.backlog", "rabbitmq_web_stomp.tcp_config.backlog", + [{datatype, integer}]}. +{mapping, "web_stomp.tcp.ip", "rabbitmq_web_stomp.tcp_config.ip", + [{datatype, string}, {validators, ["is_ip"]}]}. + + +{mapping, "web_stomp.ssl.port", "rabbitmq_web_stomp.ssl_config.port", + [{datatype, integer}]}. +{mapping, "web_stomp.ssl.backlog", "rabbitmq_web_stomp.ssl_config.backlog", + [{datatype, integer}]}. +{mapping, "web_stomp.ssl.ip", "rabbitmq_web_stomp.ssl_config.ip", + [{datatype, string}, {validators, ["is_ip"]}]}. +{mapping, "web_stomp.ssl.certfile", "rabbitmq_web_stomp.ssl_config.certfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. +{mapping, "web_stomp.ssl.keyfile", "rabbitmq_web_stomp.ssl_config.keyfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. +{mapping, "web_stomp.ssl.cacertfile", "rabbitmq_web_stomp.ssl_config.cacertfile", + [{datatype, string}, {validators, ["file_accessible"]}]}. +{mapping, "web_stomp.ssl.password", "rabbitmq_web_stomp.ssl_config.password", + [{datatype, string}]}. + + +{mapping, "web_stomp.cowboy_opts.max_empty_lines", "rabbitmq_web_stomp.cowboy_opts.max_empty_lines", + [{datatype, integer}]}. +{mapping, "web_stomp.cowboy_opts.max_header_name_length", "rabbitmq_web_stomp.cowboy_opts.max_header_name_length", + [{datatype, integer}]}. +{mapping, "web_stomp.cowboy_opts.max_header_value_length", "rabbitmq_web_stomp.cowboy_opts.max_header_value_length", + [{datatype, integer}]}. +{mapping, "web_stomp.cowboy_opts.max_headers", "rabbitmq_web_stomp.cowboy_opts.max_headers", + [{datatype, integer}]}. +{mapping, "web_stomp.cowboy_opts.max_keepalive", "rabbitmq_web_stomp.cowboy_opts.max_keepalive", + [{datatype, integer}]}. +{mapping, "web_stomp.cowboy_opts.max_request_line_length", "rabbitmq_web_stomp.cowboy_opts.max_request_line_length", + [{datatype, integer}]}. +{mapping, "web_stomp.cowboy_opts.timeout", "rabbitmq_web_stomp.cowboy_opts.timeout", + [{datatype, integer}]}. + + +{mapping, "web_stomp.sockjs_opts.url", "rabbitmq_web_stomp.sockjs_opts.sockjs_url", + [{datatype, string}]}. +{mapping, "web_stomp.sockjs_opts.websocket", "rabbitmq_web_stomp.sockjs_opts.websocket", + [{datatype, {enum, [true, false]}}]}. +{mapping, "web_stomp.sockjs_opts.cookie_needed", "rabbitmq_web_stomp.sockjs_opts.cookie_needed", + [{datatype, {enum, [true, false]}}]}. +{mapping, "web_stomp.sockjs_opts.heartbeat_delay", "rabbitmq_web_stomp.sockjs_opts.heartbeat_delay", + [{datatype, integer}]}. +{mapping, "web_stomp.sockjs_opts.disconnect_delay", "rabbitmq_web_stomp.sockjs_opts.disconnect_delay", + [{datatype, integer}]}. +{mapping, "web_stomp.sockjs_opts.response_limit", "rabbitmq_web_stomp.sockjs_opts.response_limit", + [{datatype, integer}]}. |
