diff --git a/README.md b/README.md index 2176a6a90..48e61ac8c 100644 --- a/README.md +++ b/README.md @@ -222,6 +222,7 @@ RabbitMQ Environment Variables in rabbitmq_env.config ####`erlang_cookie` The erlang cookie to use for clustering - must be the same between all nodes. +This value has no default and must be set explicitly if using clustering. ###`key_content` @@ -454,6 +455,16 @@ rabbitmq_plugin {'rabbitmq_stomp': } ``` +### rabbitmq\_erlang\_cookie + +This is essentially a private type used by the rabbitmq::config class +to manage the erlang cookie. It replaces the rabbitmq_erlang_cookie fact +from earlier versions of this module. It manages the content of the cookie +usually located at /var/lib/rabbitmq/.erlang.cookie, which includes +stopping the rabbitmq service and wiping out the database at +/var/lib/rabbitmq/mnesia if the user agrees to it. We don't recommend using +this type directly. + ##Limitations This module has been built on and tested against Puppet 2.7 and higher. diff --git a/lib/facter/rabbitmq_erlang_cookie.rb b/lib/facter/rabbitmq_erlang_cookie.rb deleted file mode 100644 index 474e12885..000000000 --- a/lib/facter/rabbitmq_erlang_cookie.rb +++ /dev/null @@ -1,16 +0,0 @@ -# Fact: rabbitmq_erlang_cookie -# -# Purpose: To determine the current erlang cookie value. -# -# Resolution: Returns the cookie. -Facter.add(:rabbitmq_erlang_cookie) do - confine :osfamily => %w[Debian RedHat Suse] - - setcode do - if File.exists?('/var/lib/rabbitmq/.erlang.cookie') - File.read('/var/lib/rabbitmq/.erlang.cookie') - else - nil - end - end -end diff --git a/lib/puppet/provider/rabbitmq_erlang_cookie/ruby.rb b/lib/puppet/provider/rabbitmq_erlang_cookie/ruby.rb new file mode 100644 index 000000000..6e05b7811 --- /dev/null +++ b/lib/puppet/provider/rabbitmq_erlang_cookie/ruby.rb @@ -0,0 +1,38 @@ +require 'puppet' +require 'set' +Puppet::Type.type(:rabbitmq_erlang_cookie).provide(:ruby) do + + defaultfor :feature => :posix + has_command(:puppet, 'puppet') do + environment :PATH => '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin' + end + + def exists? + # Hack to prevent the create method from being called. + # We never need to create or destroy this resource, only change its value + true + end + + def content=(value) + if resource[:force] == :true # Danger! + puppet('resource', 'service', resource[:service_name], 'ensure=stopped') + FileUtils.rm_rf('/var/lib/rabbitmq/mnesia') + File.open(resource[:path], 'w') do |cookie| + cookie.chmod(0400) + cookie.write(value) + end + FileUtils.chown('rabbitmq', 'rabbitmq', resource[:path]) + else + fail("The current erlang cookie needs to change. In order to do this the RabbitMQ database needs to be wiped. Please set force => true to allow this to happen automatically.") + end + end + + def content + if File.exists?(resource[:path]) + File.read(resource[:path]) + else + '' + end + end + +end diff --git a/lib/puppet/type/rabbitmq_erlang_cookie.rb b/lib/puppet/type/rabbitmq_erlang_cookie.rb new file mode 100644 index 000000000..564af5253 --- /dev/null +++ b/lib/puppet/type/rabbitmq_erlang_cookie.rb @@ -0,0 +1,22 @@ +Puppet::Type.newtype(:rabbitmq_erlang_cookie) do + desc 'Type to manage the rabbitmq erlang cookie securely' + + newparam(:path, :namevar => true) + + newproperty(:content) do + desc 'Content of cookie' + newvalues(/^\S+$/) + def change_to_s(current, desired) + "The rabbitmq erlang cookie was changed" + end + end + + newparam(:force) do + defaultto(:false) + newvalues(:true, :false) + end + + newparam(:service_name) do + newvalues(/^\S+$/) + end +end diff --git a/manifests/config.pp b/manifests/config.pp index d07861a03..95b7ab213 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -97,37 +97,19 @@ require => File['/etc/rabbitmq'], } - if $config_cluster { - file { 'erlang_cookie': - ensure => 'present', - path => '/var/lib/rabbitmq/.erlang.cookie', - owner => 'rabbitmq', - group => 'rabbitmq', - mode => '0400', - content => $erlang_cookie, - replace => true, - before => File['rabbitmq.config'], - notify => Class['rabbitmq::service'], - } - - # rabbitmq_erlang_cookie is a fact in this module. - if $erlang_cookie != $::rabbitmq_erlang_cookie { - # Safety check. - if $wipe_db_on_cookie_change { - exec { 'wipe_db': - command => "puppet resource service ${service_name} ensure=stopped; rm -rf /var/lib/rabbitmq/mnesia", - path => '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin', - } - File['erlang_cookie'] { - require => Exec['wipe_db'], - } - } else { - fail("ERROR: The current erlang cookie is ${::rabbitmq_erlang_cookie} and needs to change to ${erlang_cookie}. In order to do this the RabbitMQ database needs to be wiped. Please set the parameter called wipe_db_on_cookie_change to true to allow this to happen automatically.") + if $erlang_cookie == undef { + fail('You must set the $erlang_cookie value in order to configure clustering.') + } else { + rabbitmq_erlang_cookie { '/var/lib/rabbitmq/.erlang.cookie': + content => $erlang_cookie, + force => $wipe_db_on_cookie_change, + service_name => $service_name, + before => File['rabbitmq.config'], + notify => Class['rabbitmq::service'], } } - } diff --git a/manifests/params.pp b/manifests/params.pp index 40d50c9e6..219a41e93 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -59,7 +59,7 @@ $delete_guest_user = false $env_config = 'rabbitmq/rabbitmq-env.conf.erb' $env_config_path = '/etc/rabbitmq/rabbitmq-env.conf' - $erlang_cookie = 'EOKOWXQREETZSHFNTPEY' + $erlang_cookie = undef $node_ip_address = 'UNSET' $plugin_dir = "/usr/lib/rabbitmq/lib/rabbitmq_server-${version}/plugins" $port = '5672' diff --git a/spec/acceptance/clustering_spec.rb b/spec/acceptance/clustering_spec.rb index 04627fa6f..438c65ba1 100644 --- a/spec/acceptance/clustering_spec.rb +++ b/spec/acceptance/clustering_spec.rb @@ -1,13 +1,38 @@ require 'spec_helper_acceptance' describe 'rabbitmq clustering' do - context 'rabbitmq::config_cluster => true' do + context 'rabbitmq::wipe_db_on_cookie_change => false' do it 'should run successfully' do pp = <<-EOS class { 'rabbitmq': config_cluster => true, cluster_nodes => ['rabbit1', 'rabbit2'], cluster_node_type => 'ram', + erlang_cookie => 'TESTCOOKIE', + wipe_db_on_cookie_change => false, + } + if $::osfamily == 'RedHat' { + class { 'erlang': epel_enable => true} + Class['erlang'] -> Class['rabbitmq'] + } + EOS + + apply_manifest(pp, :expect_failures => true) + end + + describe file('/var/lib/rabbitmq/.erlang.cookie') do + it { should_not contain 'TESTCOOKIE' } + end + + end + context 'rabbitmq::wipe_db_on_cookie_change => true' do + it 'should run successfully' do + pp = <<-EOS + class { 'rabbitmq': + config_cluster => true, + cluster_nodes => ['rabbit1', 'rabbit2'], + cluster_node_type => 'ram', + erlang_cookie => 'TESTCOOKIE', wipe_db_on_cookie_change => true, } if $::osfamily == 'RedHat' { @@ -15,7 +40,7 @@ class { 'erlang': epel_enable => true} Class['erlang'] -> Class['rabbitmq'] } EOS - + apply_manifest(pp, :catch_failures => true) end @@ -29,6 +54,7 @@ class { 'erlang': epel_enable => true} describe file('/var/lib/rabbitmq/.erlang.cookie') do it { should be_file } + it { should contain 'TESTCOOKIE' } end end end diff --git a/spec/classes/rabbitmq_spec.rb b/spec/classes/rabbitmq_spec.rb index f8595093b..a24c01ff8 100644 --- a/spec/classes/rabbitmq_spec.rb +++ b/spec/classes/rabbitmq_spec.rb @@ -223,7 +223,6 @@ context "on #{distro}" do let(:facts) {{ :osfamily => distro, - :rabbitmq_erlang_cookie => 'EOKOWXQREETZSHFNTPEY', :lsbdistcodename => 'squeeze', :lsbdistid => 'Debian' }} @@ -278,22 +277,21 @@ end context 'configures config_cluster' do - let(:facts) {{ :osfamily => distro, :rabbitmq_erlang_cookie => 'ORIGINAL', :lsbdistid => 'Debian' }} + let(:facts) {{ :osfamily => distro, :lsbdistid => 'Debian' }} let(:params) {{ :config_cluster => true, :cluster_nodes => ['hare-1', 'hare-2'], :cluster_node_type => 'ram', - :erlang_cookie => 'TESTCOOKIE', :wipe_db_on_cookie_change => false }} describe 'with defaults' do it 'fails' do - expect{subject}.to raise_error(/^ERROR: The current erlang cookie is ORIGINAL/) + expect{subject}.to raise_error(/^You must set the \$erlang_cookie value/) end end - describe 'with wipe_db_on_cookie_change set' do + describe 'with erlang_cookie set' do let(:params) {{ :config_cluster => true, :cluster_nodes => ['hare-1', 'hare-2'], @@ -301,22 +299,8 @@ :erlang_cookie => 'TESTCOOKIE', :wipe_db_on_cookie_change => true }} - it 'wipes the database' do - should contain_exec('wipe_db') - should contain_file('erlang_cookie') - end - end - - describe 'correctly when cookies match' do - let(:params) {{ - :config_cluster => true, - :cluster_nodes => ['hare-1', 'hare-2'], - :cluster_node_type => 'ram', - :erlang_cookie => 'ORIGINAL', - :wipe_db_on_cookie_change => true - }} - it 'and doesnt wipe anything' do - should contain_file('erlang_cookie') + it 'contains the rabbitmq_erlang_cookie' do + should contain_rabbitmq_erlang_cookie('/var/lib/rabbitmq/.erlang.cookie') end end @@ -334,11 +318,6 @@ }) end - it 'for erlang_cookie' do - should contain_file('erlang_cookie').with({ - 'content' => 'ORIGINAL', - }) - end end end diff --git a/spec/unit/facts/rabbitmq_erlang_cookie_spec.rb b/spec/unit/facts/rabbitmq_erlang_cookie_spec.rb deleted file mode 100644 index f4daf79bd..000000000 --- a/spec/unit/facts/rabbitmq_erlang_cookie_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'spec_helper' - -describe 'rabbitmq_erlang_cookie', :type => :fact do - before(:each) { Facter.clear } - - it 'works correctly' do - Facter.fact(:osfamily).stubs(:value).returns('RedHat') - File.stubs(:exists?).with('/var/lib/rabbitmq/.erlang.cookie').returns(true) - File.stubs(:read).with('/var/lib/rabbitmq/.erlang.cookie').returns('THISISACOOKIE') - Facter.fact(:rabbitmq_erlang_cookie).value.should == 'THISISACOOKIE' - end - - it 'fails if file doesnt exist' do - Facter.fact(:osfamily).stubs(:value).returns('RedHat') - File.stubs(:exists?).with('/var/lib/rabbitmq/.erlang.cookie').returns(false) - Facter.fact(:rabbitmq_erlang_cookie).value.should == nil - end - -end