diff --git a/attributes/default.rb b/attributes/default.rb index af4167f7..f7c4807d 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -71,6 +71,12 @@ default['rabbitmq']['config_template_cookbook'] = 'rabbitmq' # override this if you wish to provide `rabbitmq-env.config.erb` in your own wrapper cookbook default['rabbitmq']['config-env_template_cookbook'] = 'rabbitmq' +# override this if you wish to use the ini-like configuration format +default['rabbitmq']['config_source'] = 'rabbitmq.config.erb' +default['rabbitmq']['config_style']['use_new_style'] = false +if node['rabbitmq']['config_style']['use_new_style'] + default['rabbitmq']['config_source'] = 'rabbitmq.conf.erb' +end # rabbitmq.config defaults default['rabbitmq']['default_user'] = 'guest' diff --git a/libraries/default.rb b/libraries/default.rb index 73a904ed..4b882143 100644 --- a/libraries/default.rb +++ b/libraries/default.rb @@ -59,10 +59,15 @@ def installed_rabbitmq_version def rabbitmq_config_file_path configured_path = node['rabbitmq']['config'] + ext = if node['rabbitmq']['config_style']['use_new_style'] + 'conf' + else + 'config' + end # If no extension is configured, append it. if ::File.extname(configured_path).empty? - "#{configured_path}.config" + "#{configured_path}.#{ext}" else configured_path end diff --git a/recipes/default.rb b/recipes/default.rb index 711c89d2..375f6ad7 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -296,7 +296,7 @@ class Chef::Recipe template rabbitmq_config_file_path do sensitive true if Gem::Version.new(Chef::VERSION.to_s) >= Gem::Version.new('11.14.2') - source 'rabbitmq.config.erb' + source node['rabbitmq']['config_source'] cookbook node['rabbitmq']['config_template_cookbook'] owner 'root' group 'root' @@ -309,6 +309,19 @@ class Chef::Recipe notifies :restart, "service[#{node['rabbitmq']['service_name']}]" end +template "#{node['rabbitmq']['config_root']}/advanced.config" do + source 'rabbitmq.advanced.config.erb' + cookbook node['rabbitmq']['config_template_cookbook'] + owner 'root' + group 'root' + mode '644' + notifies :restart, "service[#{node['rabbitmq']['service_name']}]" + variables( + kernel: format_kernel_parameters + ) + only_if { node['rabbitmq']['config_style']['use_new_style'] } +end + template "/etc/default/#{node['rabbitmq']['service_name']}" do source 'default.rabbitmq-server.erb' owner 'root' diff --git a/spec/default_spec.rb b/spec/default_spec.rb index 2b40a102..773f9e7f 100644 --- a/spec/default_spec.rb +++ b/spec/default_spec.rb @@ -29,7 +29,7 @@ user: 'root', group: 'root', source: 'rabbitmq-env.conf.erb', - mode: 00644) + mode: '644') end it 'has no erl args by default' do @@ -48,6 +48,11 @@ end end + it 'has advanced config set (new_style)' do + node.override['rabbitmq']['config_style']['use_new_style'] = true + expect(chef_run).to render_file(file.name).with_content('RABBITMQ_ADVANCED_CONFIG_FILE=/etc/rabbitmq/advanced.config') + end + it 'has no additional_env_settings default' do expect(chef_run).not_to render_file(file.name).with_content(/^# Additional ENV settings/) end @@ -124,7 +129,7 @@ user: 'root', group: 'root', source: 'default.rabbitmq-server.erb', - mode: 00644 + mode: '644' ) end @@ -133,7 +138,7 @@ user: 'root', group: 'root', source: 'rabbitmq.config.erb', - mode: 00644) + mode: '644') if Gem::Version.new(Chef::VERSION.to_s) >= Gem::Version.new('11.14.2') expect(chef_run).to create_template('/etc/rabbitmq/rabbitmq.config').with(sensitive: true) @@ -142,6 +147,21 @@ end end + it 'creates a template rabbitmq.conf with attributes (new_style)' do + node.override['rabbitmq']['config_style']['use_new_style'] = true + expect(chef_run).to create_template('/etc/rabbitmq/rabbitmq.conf').with( + user: 'root', + group: 'root', + source: node['rabbitmq']['config_source'], + mode: '644') + + if Gem::Version.new(Chef::VERSION.to_s) >= Gem::Version.new('11.14.2') + expect(chef_run).to create_template('/etc/rabbitmq/rabbitmq.conf').with(sensitive: true) + else + expect(chef_run).to create_template('/etc/rabbitmq/rabbitmq.conf').with(sensitive: false) + end + end + it 'should set additional rabbitmq config' do node.override['rabbitmq']['additional_rabbit_configs'] = { 'foo' => 'bar' } expect(chef_run).to render_file('/etc/rabbitmq/rabbitmq.config').with_content('foo, bar') @@ -204,6 +224,64 @@ expect(chef_run).to render_file('/etc/rabbitmq/rabbitmq.config').with_content( /{ssl_listeners, \[5670\]},/) end + + # New config style + it 'has no ssl ciphers specified by default' do + expect(chef_run).not_to render_file('/etc/rabbitmq/rabbitmq.conf').with_content( + /ssl_options.ciphers.*/) + end + + it 'enables secure renegotiation by default (new_style)' do + node.override['rabbitmq']['ssl'] = true + node.override['rabbitmq']['config_style']['use_new_style'] = true + expect(chef_run).to render_file('/etc/rabbitmq/rabbitmq.conf').with_content( + 'ssl_options.secure_renegotiate = true') + end + + it 'uses server cipher suite preference by default (new_style)' do + node.override['rabbitmq']['ssl'] = true + node.override['rabbitmq']['config_style']['use_new_style'] = true + expect(chef_run).to render_file('/etc/rabbitmq/rabbitmq.conf').with_content( + 'ssl_options.honor_cipher_order = true') + end + + it 'uses server ECC curve preference by default (new_style)' do + node.override['rabbitmq']['ssl'] = true + node.override['rabbitmq']['config_style']['use_new_style'] = true + expect(chef_run).to render_file('/etc/rabbitmq/rabbitmq.conf').with_content( + 'ssl_options.honor_ecc_order = true') + end + + it 'allows web console ssl ciphers (new_style)' do + node.override['rabbitmq']['web_console_ssl'] = true + node.override['rabbitmq']['config_style']['use_new_style'] = true + node.override['rabbitmq']['ssl_ciphers'] = ['"ECDHE-ECDSA-AES256-SHA384"', '"ECDH-ECDSA-AES256-SHA384"'] + ['management.ssl.ciphers.1 = ECDHE-ECDSA-AES256-SHA384', + 'management.ssl.ciphers.2 = ECDH-ECDSA-AES256-SHA384'].each do |line| + expect(chef_run).to render_file('/etc/rabbitmq/rabbitmq.conf').with_content(line) + end + end + + it 'enables TLS listeners by default (new_style)' do + node.override['rabbitmq']['ssl'] = true + node.override['rabbitmq']['config_style']['use_new_style'] = true + expect(chef_run).to render_file('/etc/rabbitmq/rabbitmq.conf').with_content('listeners.ssl.default = 5671') + end + + it 'enables TLS listener, if set (new_style)' do + node.override['rabbitmq']['ssl'] = true + node.override['rabbitmq']['config_style']['use_new_style'] = true + node.override['rabbitmq']['ssl_listen_interface'] = '0.0.0.0' + expect(chef_run).to render_file('/etc/rabbitmq/rabbitmq.conf').with_content( + 'listeners.ssl.1 = 0.0.0.0:5671') + end + + it 'overrides TLS listener port, if set (new_style)' do + node.override['rabbitmq']['ssl'] = true + node.override['rabbitmq']['ssl_port'] = 5670 + node.override['rabbitmq']['config_style']['use_new_style'] = true + expect(chef_run).to render_file('/etc/rabbitmq/rabbitmq.conf').with_content('listeners.ssl.default = 5670') + end end describe 'TCP listener options' do @@ -212,6 +290,12 @@ expect(chef_run).to render_file('/etc/rabbitmq/rabbitmq.config').with_content('{"192.168.1.10", 5672}') end + it 'allows interface to be overridden (new_style)' do + node.override['rabbitmq']['config_style']['use_new_style'] = true + node.override['rabbitmq']['tcp_listen_interface'] = '192.168.1.10' + expect(chef_run).to render_file('/etc/rabbitmq/rabbitmq.conf').with_content('192.168.1.10:5672') + end + it 'allows AMQP port to be overridden' do node.override['rabbitmq']['port'] = 5674 expect(chef_run).to render_file('/etc/rabbitmq/rabbitmq.config').with_content('[5674]') @@ -323,7 +407,21 @@ user: 'root', group: 'root', source: 'default.rabbitmq-server.erb', - mode: 00644) + mode: '644') + end + + describe 'uses distro version' do + before do + node.override['rabbitmq']['use_distro_version'] = true + end + + it 'should install rabbitmq-server package' do + expect(chef_run).to install_package('rabbitmq-server') + end + + it 'should install the logrotate package' do + expect(chef_run).to install_package('logrotate') + end end end diff --git a/templates/default/advanced.config.erb b/templates/default/advanced.config.erb new file mode 100644 index 00000000..7e872242 --- /dev/null +++ b/templates/default/advanced.config.erb @@ -0,0 +1,23 @@ + %% ---------------------------------------------------------------------------- + %% Advanced Erlang Networking/Clustering Options. + %% + +[ + <% if node['rabbitmq']['kernel'] -%> + {kernel, [ + <%= @kernel %> + ]} + <% end -%> + <% if node['rabbitmq']['ldap']['enabled'] -%> + , + {rabbitmq_auth_backend_ldap, [ + <% node['rabbitmq']['ldap']['conf'].each_with_index do |(key, value), index| -%> + <% if index == 0 %> + {<%= key %>, <%= value %>} + <% else %> + ,{<%= key %>, <%= value %>} + <% end %> + <% end %> + ]} + <% end -%> +]. diff --git a/templates/default/rabbitmq-env.conf.erb b/templates/default/rabbitmq-env.conf.erb index 9b82eb13..8c25e1da 100644 --- a/templates/default/rabbitmq-env.conf.erb +++ b/templates/default/rabbitmq-env.conf.erb @@ -20,6 +20,7 @@ export ERL_EPMD_ADDRESS=<%= node['rabbitmq']['erl_networking_bind_address'] %> <% if node['rabbitmq']['mnesiadir'] -%>MNESIA_BASE=<%= node['rabbitmq']['mnesiadir'] %><% end %> <% if node['rabbitmq']['server_additional_erl_args'] -%>SERVER_ADDITIONAL_ERL_ARGS='<%= node['rabbitmq']['server_additional_erl_args'] %>'<% end %> <% if node['rabbitmq']['ctl_erl_args'] -%>CTL_ERL_ARGS='<%= node['rabbitmq']['ctl_erl_args'] %>'<% end %> +<% if node['rabbitmq']['config_style']['use_new_style'] -%>RABBITMQ_ADVANCED_CONFIG_FILE=/etc/rabbitmq/advanced.config<% end %> <% if node['rabbitmq']['additional_env_settings'] -%> # Additional ENV settings <% node['rabbitmq']['additional_env_settings'].each do |line| -%> diff --git a/templates/default/rabbitmq.conf.erb b/templates/default/rabbitmq.conf.erb new file mode 100644 index 00000000..ab79338f --- /dev/null +++ b/templates/default/rabbitmq.conf.erb @@ -0,0 +1,131 @@ +### +## Generated by Chef +### + +default_user = <%= node['rabbitmq']['default_user'] %> +default_pass = <%= node['rabbitmq']['default_pass'] %> +heartbeat = <%= node['rabbitmq']['heartbeat'] %> +auth_backends.1 = <%= node['rabbitmq']['auth_backends'] %> + +<% if node['rabbitmq']['web_console_ssl'] -%> + <% if node['rabbitmq']['management']['load_definitions'] %> +management.load_definitions = <%= node['rabbitmq']['management']['definitions_file'] %> + <% end -%> + <% if node['rabbitmq']['web_console_interface'] -%> +management.ssl.ip = <%= node['rabbitmq']['web_console_interface'] %> + <% end -%> +management.ssl.port = <%= node['rabbitmq']['web_console_ssl_port'] %> +management.ssl.cacertfile = <%= node['rabbitmq']['ssl_cacert'] %> +management.ssl.certfile = <%= node['rabbitmq']['ssl_cert'] %> +management.ssl.keyfile = <%= node['rabbitmq']['ssl_key'] %> + <% if @ssl_versions -%> +<%= @ssl_versions.tr("'", '').split(",").map.with_index(1) { |ver, index| "management.ssl.versions.#{index} = #{ver}" }.join("\n") %> + <% end %> + <% if @ssl_ciphers -%> +<%= @ssl_ciphers.tr('"', '').split(',').map.with_index(1) { |cipher, index| "management.ssl.ciphers.#{index} = #{cipher}" }.join("\n") %> + <% end %> +<% else %> + <% if node['rabbitmq']['management']['load_definitions'] %> +management.load_definitions = <%= node['rabbitmq']['management']['definitions_file'] %> + <% end -%> +management.tcp.port = <%= node['rabbitmq']['web_console_port'] %> + <% if node['rabbitmq']['web_console_interface'] -%> +management.tcp.ip = <%= node['rabbitmq']['web_console_interface'] %> + <% end -%> +<% end %> + +<% if node['rabbitmq']['clustering']['enable'] -%> +# Cluster + <% if node['rabbitmq']['clustering']['use_auto_clustering'] -%> +cluster_formation.peer_discovery_backend = classic_config +<%= node['rabbitmq']['clustering']['cluster_nodes'].map.with_index(1) { |instance, index| "cluster_formation.classic_config.nodes.#{index} = #{instance['name']}" }.join("\n") %> + <% end %> + <% if node['rabbitmq']['clustering']['cluster_formation']['peer_discovery_backend'] -%> +cluster_formation.peer_discovery_backend = <%= node['rabbitmq']['clustering']['cluster_formation']['peer_discovery_backend'] %> + <% @backend = node['rabbitmq']['clustering']['cluster_formation']['peer_discovery_backend'] %> +<%= node['rabbitmq']['clustering']['cluster_formation'][@backend].map { |key, value| "cluster_formation.#{@backend}.#{key} = #{value}" }.join("\n") %> + <% end %> +cluster_partition_handling = <%= node['rabbitmq']['clustering']['cluster_partition_handling'] %> +<% end %> + +<% if node['rabbitmq']['ssl'] -%> +# SSL + <% if node['rabbitmq']['ssl_listen_interface'] %> +listeners.ssl.1 = <%= node['rabbitmq']['ssl_listen_interface'] %>:<%= node['rabbitmq']['ssl_port'] %> + <% else %> +listeners.ssl.default = <%= node['rabbitmq']['ssl_port'] %> + <% end %> +ssl_options.cacertfile = <%= node['rabbitmq']['ssl_cacert'] %> +ssl_options.certfile = <%= node['rabbitmq']['ssl_cert'] %> +ssl_options.keyfile = <%= node['rabbitmq']['ssl_key'] %> +ssl_options.verify = <%= node['rabbitmq']['ssl_verify'] %> +ssl_options.fail_if_no_peer_cert = <%= node['rabbitmq']['ssl_fail_if_no_peer_cert'] %> + <% if @ssl_versions -%> +<%= @ssl_versions.tr("'", '').split(",").map.with_index(1) { |ver, index| "ssl_options.versions.#{index} = #{ver}" }.join("\n") %> + <% end %> + <% if @ssl_ciphers -%> +<%= @ssl_ciphers.tr('"', '').split(',').map.with_index(1) { |cipher, index| "ssl_options.ciphers.#{index} = #{cipher}" }.join("\n") %> + <% end %> + <% if node['rabbitmq']['ssl_secure_renegotiate'] -%> +ssl_options.secure_renegotiate = <%= node['rabbitmq']['ssl_secure_renegotiate'] %> + <% end -%> + <% if node['rabbitmq']['ssl_honor_cipher_order'] -%> +ssl_options.honor_cipher_order = <%= node['rabbitmq']['ssl_honor_cipher_order'] %> + <% end -%> + <% if node['rabbitmq']['ssl_honor_ecc_order'] -%> +ssl_options.honor_ecc_order = <%= node['rabbitmq']['ssl_honor_ecc_order'] %> + <% end -%> +<% end %> + +# Networking +<% if node['rabbitmq']['tcp_listen_interface'] -%> +listeners.tcp.1 = <%= node['rabbitmq']['tcp_listen_interface'] %>:<%= node['rabbitmq']['port'] %> +<% else %> +listeners.tcp.default = <%= node['rabbitmq']['port'] %> +<% end -%> +<% if node['rabbitmq']['tcp_listen'] -%> +tcp_listen_options.backlog = <%= node['rabbitmq']['tcp_listen_backlog'] %> +tcp_listen_options.nodelay = <%= node['rabbitmq']['tcp_listen_nodelay'] %> +tcp_listen_options.exit_on_close = <%= node['rabbitmq']['tcp_listen_exit_on_close'] %> +tcp_listen_options.keepalive = <%= node['rabbitmq']['tcp_listen_keepalive'] %> + <% if node['rabbitmq']['tcp_listen_buffer'] -%> +tcp_listen_options.buffer = <%= node['rabbitmq']['tcp_listen_buffer'] %> + <% end -%> + <% if node['rabbitmq']['tcp_listen_sndbuf'] -%> +tcp_listen_options.sndbuf = <%= node['rabbitmq']['tcp_listen_sndbuf'] %> + <% end -%> + <% if node['rabbitmq']['tcp_listen_recbuf'] -%> +tcp_listen_options.recbuf = <%= node['rabbitmq']['tcp_listen_recbuf'] %> + <% end -%> +tcp_listen_options.linger.on = <%= node['rabbitmq']['tcp_listen_linger'] %> +tcp_listen_options.linger.timeout = <%= node['rabbitmq']['tcp_listen_linger_timeout'] %> +<% end %> + +<% if node['rabbitmq']['log_levels'] -%> +# Logging +<%= node['rabbitmq']['log_levels'].map{ |key, value| "log.#{key}.level = #{value} "}.join("\n") %> +<% end %> + +<% if node['rabbitmq']['disk_free_limit_relative'] -%> +disk_free_limit.relative = <%= node['rabbitmq']['disk_free_limit_relative'].to_f %> +<% end %> +<% if node['rabbitmq']['disk_free_limit'] -%> +disk_free_limit.absolute = <%= node['rabbitmq']['disk_free_limit'] %> +<% end %> +<% if node['rabbitmq']['vm_memory_high_watermark'] -%> +vm_memory_high_watermark.relative = <%= node['rabbitmq']['vm_memory_high_watermark'] %> +<% end %> +<% if node['rabbitmq']['channel_max'] -%> +channel_max = <%= node['rabbitmq']['channel_max'] %> +<% end %> +<% if node['rabbitmq']['loopback_users'] -%> +<%= node['rabbitmq']['loopback_users'].map { |user| "loopback_users.#{user} = true" }.join("\n") %> +<% end %> + +<% node['rabbitmq']['additional_rabbit_configs'].each do |key,value| -%> +<%= key %> = <%= value %> +<% end -%> + +<% node['rabbitmq']['conf'].each do |key,value| -%> +<%= key %> = <%= value %> +<% end -%>