diff --git a/README.md b/README.md index b6784f295..6a293d693 100644 --- a/README.md +++ b/README.md @@ -446,6 +446,12 @@ rabbitmq_exchange { 'myexchange@myhost': password => 'bar', type => 'topic', ensure => present, + internal => false, + auto_delete => false, + durable => true, + arguments => { + hash-header => 'message-distribution-hash' + } } ``` diff --git a/lib/puppet/provider/rabbitmq_exchange/rabbitmqadmin.rb b/lib/puppet/provider/rabbitmq_exchange/rabbitmqadmin.rb index 3651dc9cf..c1cff0957 100644 --- a/lib/puppet/provider/rabbitmq_exchange/rabbitmqadmin.rb +++ b/lib/puppet/provider/rabbitmq_exchange/rabbitmqadmin.rb @@ -36,7 +36,7 @@ def self.all_vhosts def self.all_exchanges(vhost) exchanges = [] self.run_with_retries { - rabbitmqctl('-q', 'list_exchanges', '-p', vhost, 'name', 'type') + rabbitmqctl('-q', 'list_exchanges', '-p', vhost, 'name', 'type', 'internal', 'durable', 'auto_delete', 'arguments') }.split(/\n/).each do |exchange| exchanges.push(exchange) end @@ -47,17 +47,30 @@ def self.instances resources = [] all_vhosts.each do |vhost| all_exchanges(vhost).each do |line| - name, type = line.split() + name, type, internal, durable, auto_delete, arguments = line.split() if type.nil? # if name is empty, it will wrongly get the type's value. # This way type will get the correct value type = name name = '' end + # Convert output of arguments from the rabbitmqctl command to a json string. + if !arguments.nil? + arguments = arguments.gsub(/^\[(.*)\]$/, "").gsub(/\{("(?:.|\\")*?"),/, '{\1:').gsub(/\},\{/, ",") + if arguments == "" + arguments = '{}' + end + else + arguments = '{}' + end exchange = { :type => type, :ensure => :present, + :internal => internal, + :durable => durable, + :auto_delete => auto_delete, :name => "%s@%s" % [name, vhost], + :arguments => JSON.parse(arguments), } resources << new(exchange) if exchange[:type] end @@ -81,7 +94,11 @@ def exists? def create vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : '' name = resource[:name].split('@')[0] - rabbitmqadmin('declare', 'exchange', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "name=#{name}", "type=#{resource[:type]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf') + arguments = resource[:arguments] + if arguments.nil? + arguments = {} + end + rabbitmqadmin('declare', 'exchange', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "name=#{name}", "type=#{resource[:type]}", "internal=#{resource[:internal]}", "durable=#{resource[:durable]}", "auto_delete=#{resource[:auto_delete]}", "arguments=#{arguments.to_json}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf') @property_hash[:ensure] = :present end diff --git a/lib/puppet/type/rabbitmq_exchange.rb b/lib/puppet/type/rabbitmq_exchange.rb index 6a96520c6..b2e88a8de 100644 --- a/lib/puppet/type/rabbitmq_exchange.rb +++ b/lib/puppet/type/rabbitmq_exchange.rb @@ -21,6 +21,26 @@ newvalues(/^\S+$/) end + newparam(:durable) do + desc 'Exchange durability to be set *on creation*' + newvalues(/^\S+$/) + end + + newparam(:auto_delete) do + desc 'Exchange auto delete option to be set *on creation*' + newvalues(/^\S+$/) + end + + newparam(:internal) do + desc 'Exchange internal option to be set *on creation*' + newvalues(/^\S+$/) + end + + newparam(:arguments) do + desc 'Exchange arguments example: {"hash-header": "message-distribution-hash"}' + defaultto {} + end + newparam(:user) do desc 'The user to use to connect to rabbitmq' defaultto('guest') diff --git a/spec/unit/puppet/provider/rabbitmq_exchange/rabbitmqadmin_spec.rb b/spec/unit/puppet/provider/rabbitmq_exchange/rabbitmqadmin_spec.rb index 6e956fe8b..10e39acfa 100644 --- a/spec/unit/puppet/provider/rabbitmq_exchange/rabbitmqadmin_spec.rb +++ b/spec/unit/puppet/provider/rabbitmq_exchange/rabbitmqadmin_spec.rb @@ -7,8 +7,15 @@ describe provider_class do before :each do @resource = Puppet::Type::Rabbitmq_exchange.new( - {:name => 'amq.direct@/', - :type => :topic} + {:name => 'test.headers@/', + :type => :headers, + :internal => :false, + :durable => :true, + :auto_delete => :false, + :arguments => { + "hash-headers" => "message-distribution-hash" + }, + } ) @provider = provider_class.new(@resource) end @@ -17,44 +24,51 @@ provider_class.expects(:rabbitmqctl).with('-q', 'list_vhosts').returns <<-EOT / EOT - provider_class.expects(:rabbitmqctl).with('-q', 'list_exchanges', '-p', '/', 'name', 'type').returns <<-EOT - direct - amq.direct direct - amq.fanout fanout - amq.headers headers - amq.match headers - amq.rabbitmq.log topic - amq.rabbitmq.trace topic - amq.topic topic + provider_class.expects(:rabbitmqctl).with('-q', 'list_exchanges', '-p', '/', 'name', 'type', 'internal', 'durable', 'auto_delete', 'arguments').returns <<-EOT + direct false true false [] +amq.direct direct false true false [] +amq.fanout fanout false true false [] +amq.headers headers false true false [] +amq.match headers false true false [] +amq.rabbitmq.log topic true true false [] +amq.rabbitmq.trace topic true true false [] +amq.topic topic false true false [] +test.headers x-consistent-hash false true false [{"hash-header","message-distribution-hash"}] EOT instances = provider_class.instances - instances.size.should == 8 + instances.size.should == 9 end - it 'should call rabbitmqadmin to create' do - @provider.expects(:rabbitmqadmin).with('declare', 'exchange', '--vhost=/', '--user=guest', '--password=guest', 'name=amq.direct', 'type=topic', '-c', '/etc/rabbitmq/rabbitmqadmin.conf') + it 'should call rabbitmqadmin to create as guest' do + @provider.expects(:rabbitmqadmin).with('declare', 'exchange', '--vhost=/', '--user=guest', '--password=guest', 'name=test.headers', 'type=headers', 'internal=false', 'durable=true', 'auto_delete=false', 'arguments={"hash-headers":"message-distribution-hash"}', '-c', '/etc/rabbitmq/rabbitmqadmin.conf') @provider.create end it 'should call rabbitmqadmin to destroy' do - @provider.expects(:rabbitmqadmin).with('delete', 'exchange', '--vhost=/', '--user=guest', '--password=guest', 'name=amq.direct', '-c', '/etc/rabbitmq/rabbitmqadmin.conf') + @provider.expects(:rabbitmqadmin).with('delete', 'exchange', '--vhost=/', '--user=guest', '--password=guest', 'name=test.headers', '-c', '/etc/rabbitmq/rabbitmqadmin.conf') @provider.destroy end context 'specifying credentials' do before :each do @resource = Puppet::Type::Rabbitmq_exchange.new( - {:name => 'amq.direct@/', - :type => :topic, + {:name => 'test.headers@/', + :type => :headers, + :internal => 'false', + :durable => 'true', + :auto_delete => 'false', :user => 'colin', :password => 'secret', - } + :arguments => { + "hash-header" => "message-distribution-hash" + }, + } ) @provider = provider_class.new(@resource) end - it 'should call rabbitmqadmin to create' do - @provider.expects(:rabbitmqadmin).with('declare', 'exchange', '--vhost=/', '--user=colin', '--password=secret', 'name=amq.direct', 'type=topic', '-c', '/etc/rabbitmq/rabbitmqadmin.conf') + it 'should call rabbitmqadmin to create with credentials' do + @provider.expects(:rabbitmqadmin).with('declare', 'exchange', '--vhost=/', '--user=colin', '--password=secret', 'name=test.headers', 'type=headers', 'internal=false', 'durable=true', 'auto_delete=false', 'arguments={"hash-header":"message-distribution-hash"}', '-c', '/etc/rabbitmq/rabbitmqadmin.conf') @provider.create end end diff --git a/spec/unit/puppet/type/rabbitmq_exchange_spec.rb b/spec/unit/puppet/type/rabbitmq_exchange_spec.rb index c4c2caa98..1500122cd 100644 --- a/spec/unit/puppet/type/rabbitmq_exchange_spec.rb +++ b/spec/unit/puppet/type/rabbitmq_exchange_spec.rb @@ -4,7 +4,10 @@ before :each do @exchange = Puppet::Type.type(:rabbitmq_exchange).new( :name => 'foo@bar', - :type => :topic + :type => :topic, + :internal => false, + :auto_delete => false, + :durable => true ) end it 'should accept an exchange name' do