diff --git a/lib/facter/erl_ssl_path.rb b/lib/facter/erl_ssl_path.rb new file mode 100644 index 000000000..c6955de44 --- /dev/null +++ b/lib/facter/erl_ssl_path.rb @@ -0,0 +1,16 @@ +# Fact to get the ssl path for the erlang distribution in the current +# system as described in the RabbitMQ docs [1]. +# +# [1] https://www.rabbitmq.com/clustering-ssl.html +Facter.add('erl_ssl_path') do + setcode do + data = false + if Facter::Util::Resolution.which('erl') + Facter::Util::Resolution.with_env('HOME' => '/root') do + data = Facter::Core::Execution.execute("erl -eval 'io:format(\"~p\", [code:lib_dir(ssl, ebin)]),halt().' -noshell") + end + end + # erl returns the string with quotes, strip them off + data.gsub!(/\A"|"\Z/, '') + end +end diff --git a/manifests/config.pp b/manifests/config.pp index 1c5d84250..28c098823 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -69,6 +69,7 @@ $ipv6 = $rabbitmq::ipv6 $inetrc_config = $rabbitmq::inetrc_config $inetrc_config_path = $rabbitmq::inetrc_config_path + $ssl_erl_dist = $rabbitmq::ssl_erl_dist if $ssl_only { $default_ssl_env_variables = {} @@ -93,25 +94,37 @@ # Handle env variables. $_environment_variables = $default_ssl_env_variables + $inetrc_env + $rabbitmq::environment_variables - if $ipv6 { + if $ipv6 or $ssl_erl_dist { # must append "-proto_dist inet6_tcp" to any provided ERL_ARGS for # both the server and rabbitmqctl, being careful not to mess up - # quoting - $ipv6_env = ['SERVER', 'CTL'].reduce({}) |$memo, $item| { + # quoting. If both IPv6 and TLS are enabled, we must use "inet6_tls". + # Finally, if only TLS is enabled (no IPv6), the -proto_dist value to use + # is "inet_tls". + if $ipv6 and $ssl_erl_dist { + $proto_dist = 'inet6_tls' + $ssl_path = " -pa ${::erl_ssl_path} " + } elsif $ssl_erl_dist { + $proto_dist = 'inet_tls' + $ssl_path = " -pa ${::erl_ssl_path} " + } else { + $proto_dist = 'inet6_tcp' + $ssl_path = '' + } + $ipv6_or_tls_env = ['SERVER', 'CTL'].reduce({}) |$memo, $item| { $orig = $_environment_variables["RABBITMQ_${item}_ERL_ARGS"] $munged = $orig ? { # already quoted, keep quoting - /^([\'\"])(.*)\1/ => "${1}${2} -proto_dist inet6_tcp${1}", + /^([\'\"])(.*)\1/ => "${1}${2}${ssl_path} -proto_dist ${proto_dist}${1}", # unset, add our own quoted value - undef => '"-proto_dist inet6_tcp"', + undef => "\"${ssl_path}-proto_dist ${proto_dist}\"", # previously unquoted value, add quoting - default => "\"${orig} -proto_dist inet6_tcp\"", + default => "\"${orig}${ssl_path} -proto_dist ${proto_dist}\"", } merge($memo, {"RABBITMQ_${item}_ERL_ARGS" => $munged}) } - $environment_variables = $_environment_variables + $ipv6_env + $environment_variables = $_environment_variables + $ipv6_or_tls_env } else { $environment_variables = $_environment_variables } diff --git a/manifests/init.pp b/manifests/init.pp index ca660e599..aa49bec08 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -90,6 +90,7 @@ Boolean $ipv6 = $rabbitmq::params::ipv6, String $inetrc_config = $rabbitmq::params::inetrc_config, Stdlib::Absolutepath $inetrc_config_path = $rabbitmq::params::inetrc_config_path, + Boolean $ssl_erl_dist = $rabbitmq::params::ssl_erl_dist, ) inherits rabbitmq::params { # Validate install parameters. diff --git a/manifests/params.pp b/manifests/params.pp index 1b91d3d29..46a09a2f9 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -114,4 +114,5 @@ $ipv6 = false $inetrc_config = 'rabbitmq/inetrc.erb' $inetrc_config_path = '/etc/rabbitmq/inetrc' + $ssl_erl_dist = false } diff --git a/spec/classes/rabbitmq_spec.rb b/spec/classes/rabbitmq_spec.rb index 3cbda3d4b..be3171d5f 100644 --- a/spec/classes/rabbitmq_spec.rb +++ b/spec/classes/rabbitmq_spec.rb @@ -1018,6 +1018,49 @@ with_content(%r{^RABBITMQ_CTL_ERL_ARGS="bar -proto_dist inet6_tcp"$}) end end + + context 'with SSL and without other erl args' do + let(:params) { + { :ipv6 => true, + :ssl_erl_dist => true } + } + it 'enables inet6 distribution' do + is_expected.to contain_file('rabbitmq-env.config') \ + .with_content(%r{^RABBITMQ_SERVER_ERL_ARGS=" -pa /usr/lib64/erlang/lib/ssl-7.3.3.1/ebin -proto_dist inet6_tls"$}) \ + .with_content(%r{^RABBITMQ_CTL_ERL_ARGS=" -pa /usr/lib64/erlang/lib/ssl-7.3.3.1/ebin -proto_dist inet6_tls"$}) + end + end + + context 'with SSL and other quoted erl args' do + let(:params) { + { :ipv6 => true, + :ssl_erl_dist => true, + :environment_variables => { 'RABBITMQ_SERVER_ERL_ARGS' => '"some quoted args"', + 'RABBITMQ_CTL_ERL_ARGS' => '"other quoted args"'} } + } + + it 'enables inet6 distribution and quote properly' do + is_expected.to contain_file('rabbitmq-env.config') \ + .with_content(%r{^RABBITMQ_SERVER_ERL_ARGS="some quoted args -pa /usr/lib64/erlang/lib/ssl-7.3.3.1/ebin -proto_dist inet6_tls"$}) \ + .with_content(%r{^RABBITMQ_CTL_ERL_ARGS="other quoted args -pa /usr/lib64/erlang/lib/ssl-7.3.3.1/ebin -proto_dist inet6_tls"$}) + end + end + + context 'with SSL and with other unquoted erl args' do + let(:params) { + { :ipv6 => true, + :ssl_erl_dist => true, + :environment_variables => { 'RABBITMQ_SERVER_ERL_ARGS' => 'foo', + 'RABBITMQ_CTL_ERL_ARGS' => 'bar'} } + } + + it 'enables inet6 distribution and quote properly' do + is_expected.to contain_file('rabbitmq-env.config') \ + .with_content(%r{^RABBITMQ_SERVER_ERL_ARGS="foo -pa /usr/lib64/erlang/lib/ssl-7.3.3.1/ebin -proto_dist inet6_tls"$}) \ + .with_content(%r{^RABBITMQ_CTL_ERL_ARGS="bar -pa /usr/lib64/erlang/lib/ssl-7.3.3.1/ebin -proto_dist inet6_tls"$}) + end + + end end describe 'config_variables options' do diff --git a/spec/spec_helper_local.rb b/spec/spec_helper_local.rb index 2d2bc27c1..a3b29b4a9 100644 --- a/spec/spec_helper_local.rb +++ b/spec/spec_helper_local.rb @@ -4,3 +4,4 @@ add_custom_fact :puppetversion, Puppet.version # Facter, but excluded from rspec-puppet-facts add_custom_fact :staging_http_get, '' # puppet-staging add_custom_fact :rabbitmq_version, '3.6.1' # puppet-rabbitmq +add_custom_fact :erl_ssl_path, '/usr/lib64/erlang/lib/ssl-7.3.3.1/ebin' # puppet-rabbitmq