From 46f02ecdcc2fe155e18695f243238ecccfbd7d04 Mon Sep 17 00:00:00 2001 From: William Yardley Date: Tue, 16 Aug 2016 10:04:49 -0700 Subject: [PATCH 1/2] Add support for multiple bindings with same source/dest/vhost but different routing key (MODULES-3679) --- .../rabbitmq_binding/rabbitmqadmin.rb | 21 ++-- lib/puppet/type/rabbitmq_binding.rb | 75 +++++++++++--- spec/acceptance/queue_spec.rb | 99 +++++++++++++++++-- .../unit/puppet/type/rabbitmq_binding_spec.rb | 17 ---- 4 files changed, 160 insertions(+), 52 deletions(-) diff --git a/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb b/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb index 382839414..927cbb0ee 100644 --- a/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb +++ b/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb @@ -19,7 +19,7 @@ def should_vhost if @should_vhost @should_vhost else - @should_vhost = resource[:name].split('@').last + @should_vhost = resource[:vhost] end end @@ -51,11 +51,14 @@ def self.instances end unless(source_name.empty?) binding = { + :source => source_name, + :dest => destination_name, + :vhost => vhost, :destination_type => destination_type, :routing_key => routing_key, :arguments => JSON.parse(arguments), :ensure => :present, - :name => "%s@%s@%s" % [source_name, destination_name, vhost], + :name => "%s@%s@%s@%s" % [source_name, destination_name, vhost, routing_key], } resources << new(binding) if binding[:name] end @@ -65,9 +68,9 @@ def self.instances end def self.prefetch(resources) - packages = instances + bindings = instances resources.keys.each do |name| - if provider = packages.find{ |pkg| pkg.name == name } + if provider = bindings.find{ |route| route.source == source && route.dest == dest && route.vhost == vhost && route.routing_key == routing_key } resources[name].provider = provider end end @@ -79,8 +82,6 @@ def exists? def create vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : '' - name = resource[:name].split('@').first - destination = resource[:name].split('@')[1] arguments = resource[:arguments] if arguments.nil? arguments = {} @@ -92,8 +93,8 @@ def create "--password=#{resource[:password]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf', - "source=#{name}", - "destination=#{destination}", + "source=#{resource[:source]}", + "destination=#{resource[:dest]}", "arguments=#{arguments.to_json}", "routing_key=#{resource[:routing_key]}", "destination_type=#{resource[:destination_type]}" @@ -103,9 +104,7 @@ def create def destroy vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : '' - name = resource[:name].split('@').first - destination = resource[:name].split('@')[1] - rabbitmqadmin('delete', 'binding', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf', "source=#{name}", "destination_type=#{resource[:destination_type]}", "destination=#{destination}", "properties_key=#{resource[:routing_key]}") + rabbitmqadmin('delete', 'binding', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf', "source=#{resource[:source]}", "destination_type=#{resource[:destination_type]}", "destination=#{resource[:dest]}", "properties_key=#{resource[:routing_key]}") @property_hash[:ensure] = :absent end diff --git a/lib/puppet/type/rabbitmq_binding.rb b/lib/puppet/type/rabbitmq_binding.rb index 130948003..fd090caeb 100644 --- a/lib/puppet/type/rabbitmq_binding.rb +++ b/lib/puppet/type/rabbitmq_binding.rb @@ -11,9 +11,61 @@ end end - newparam(:name, :namevar => true) do - desc 'source and destination of bind' - newvalues(/^\S*@\S+@\S+$/) + # Match patterns without '@' as arbitrary names; match patterns with + # src@dst@vhost to their named params for backwards compatibility. + def self.title_patterns + [ + [ + /(^([^@]*)$)/m, + [ + [ :name ] + ] + ], + [ + /^(\S+)@(\S+)@(\S+)$/m, + [ + [ :source ], + [ :dest ], + [ :vhost ] + ] + ] + ] + end + + newparam(:name) do + desc 'resource name, either source@dest@vhost or arbitrary name with params' + + isnamevar + end + + newparam(:source) do + desc 'source of binding' + + newvalues(/^\S+$/) + isnamevar + end + + newparam(:dest, :namevar => true) do + desc 'destination of binding' + + newvalues(/^\S+$/) + isnamevar + end + + newparam(:vhost, :namevar => true) do + desc 'vhost' + + newvalues(/^\S+$/) + defaultto('/') + isnamevar + end + + newparam(:routing_key, :namevar => true) do + desc 'binding routing_key' + + newvalues(/^\S*$/) + defaultto('#') + isnamevar end newparam(:destination_type) do @@ -21,11 +73,6 @@ newvalues(/queue|exchange/) defaultto('queue') end - - newparam(:routing_key) do - desc 'binding routing_key' - newvalues(/^\S*$/) - end newparam(:arguments) do desc 'binding arguments' @@ -48,7 +95,7 @@ end autorequire(:rabbitmq_vhost) do - [self[:name].split('@')[2]] + setup_autorequire('vhost') end autorequire(:rabbitmq_exchange) do @@ -65,21 +112,21 @@ autorequire(:rabbitmq_user_permissions) do [ - "#{self[:user]}@#{self[:name].split('@')[1]}", - "#{self[:user]}@#{self[:name].split('@')[0]}" + "#{self[:user]}@#{self[:source]}", + "#{self[:user]}@#{self[:dest]}" ] end def setup_autorequire(type) destination_type = value(:destination_type) if type == 'exchange' - rval = ["#{self[:name].split('@')[0]}@#{self[:name].split('@')[2]}"] + rval = ["#{self[:source]}@#{self[:vhost]}"] if destination_type == type - rval.push("#{self[:name].split('@')[1]}@#{self[:name].split('@')[2]}") + rval.push("#{self[:dest]}@#{self[:vhost]}") end else if destination_type == type - rval = ["#{self[:name].split('@')[1]}@#{self[:name].split('@')[2]}"] + rval = ["#{self[:dest]}@#{self[:vhost]}"] else rval = [] end diff --git a/spec/acceptance/queue_spec.rb b/spec/acceptance/queue_spec.rb index a1643a632..abf946bbd 100644 --- a/spec/acceptance/queue_spec.rb +++ b/spec/acceptance/queue_spec.rb @@ -2,8 +2,7 @@ describe 'rabbitmq binding:' do - - context "create binding and queue resources when rabbit using default management port" do + context "create binding and queue resources when using default management port" do it 'should run successfully' do pp = <<-EOS if $::osfamily == 'RedHat' { @@ -22,7 +21,7 @@ class { '::rabbitmq': password => 'bar', tags => ['monitoring', 'tag1'], } -> - + rabbitmq_user_permissions { 'dan@host1': configure_permission => '.*', read_permission => '.*', @@ -55,7 +54,7 @@ class { '::rabbitmq': routing_key => '#', ensure => present, } - + EOS apply_manifest(pp, :catch_failures => true) @@ -68,7 +67,7 @@ class { '::rabbitmq': expect(r.exit_code).to be_zero end end - + it 'should have the queue' do shell('rabbitmqctl list_queues -q -p host1') do |r| expect(r.stdout).to match(/queue1/) @@ -78,7 +77,87 @@ class { '::rabbitmq': end - context "create binding and queue resources when rabbit using a non-default management port" do + + context "create multiple bindings when same source / dest / vhost but different routing keys" do + it 'should run successfully' do + pp = <<-EOS + if $::osfamily == 'RedHat' { + class { 'erlang': epel_enable => true } + Class['erlang'] -> Class['::rabbitmq'] + } + class { '::rabbitmq': + service_manage => true, + port => '5672', + delete_guest_user => true, + admin_enable => true, + } -> + + rabbitmq_user { 'dan': + admin => true, + password => 'bar', + tags => ['monitoring', 'tag1'], + } -> + + rabbitmq_user_permissions { 'dan@host1': + configure_permission => '.*', + read_permission => '.*', + write_permission => '.*', + } + + rabbitmq_vhost { 'host1': + ensure => present, + } -> + + rabbitmq_exchange { 'exchange1@host1': + user => 'dan', + password => 'bar', + type => 'topic', + ensure => present, + } -> + + rabbitmq_queue { 'queue1@host1': + user => 'dan', + password => 'bar', + durable => true, + auto_delete => false, + ensure => present, + } -> + + rabbitmq_binding { 'binding 1': + source => 'exchange1', + user => 'dan', + password => 'bar', + destination_type => 'queue', + routing_key => 'test1', + ensure => present, + } -> + + rabbitmq_binding { 'binding 2': + source => 'exchange1', + user => 'dan', + password => 'bar', + destination_type => 'queue', + routing_key => 'test2', + ensure => present, + } + + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'should have the bindings' do + shell('rabbitmqctl list_bindings -q -p host1') do |r| + expect(r.stdout).to match(/exchange1\sexchange\squeue1\squeue\stest1/) + expect(r.stdout).to match(/exchange1\sexchange\squeue1\squeue\stest2/) + expect(r.exit_code).to be_zero + end + end + + end + + context "create binding and queue resources when using a non-default management port" do it 'should run successfully' do pp = <<-EOS if $::osfamily == 'RedHat' { @@ -98,7 +177,7 @@ class { '::rabbitmq': password => 'bar', tags => ['monitoring', 'tag1'], } -> - + rabbitmq_user_permissions { 'dan@host2': configure_permission => '.*', read_permission => '.*', @@ -131,7 +210,7 @@ class { '::rabbitmq': routing_key => '#', ensure => present, } - + EOS apply_manifest(pp, :catch_failures => true) @@ -144,7 +223,7 @@ class { '::rabbitmq': expect(r.exit_code).to be_zero end end - + it 'should have the queue' do shell('rabbitmqctl list_queues -q -p host2') do |r| expect(r.stdout).to match(/queue2/) @@ -153,5 +232,5 @@ class { '::rabbitmq': end end - + end diff --git a/spec/unit/puppet/type/rabbitmq_binding_spec.rb b/spec/unit/puppet/type/rabbitmq_binding_spec.rb index 2a5262017..cf88570f1 100644 --- a/spec/unit/puppet/type/rabbitmq_binding_spec.rb +++ b/spec/unit/puppet/type/rabbitmq_binding_spec.rb @@ -15,23 +15,6 @@ Puppet::Type.type(:rabbitmq_binding).new({}) }.to raise_error(Puppet::Error, 'Title or name must be provided') end - it 'should not allow whitespace in the name' do - expect { - @binding[:name] = 'b r' - }.to raise_error(Puppet::Error, /Valid values match/) - end - it 'should not allow names without one @' do - expect { - @binding[:name] = 'b_r' - }.to raise_error(Puppet::Error, /Valid values match/) - end - - it 'should not allow names without two @' do - expect { - @binding[:name] = 'b@r' - }.to raise_error(Puppet::Error, /Valid values match/) - end - it 'should accept an binding destination_type' do @binding[:destination_type] = :exchange @binding[:destination_type].should == :exchange From 33b9b997a0222381a37952522f70cafebd55fcc0 Mon Sep 17 00:00:00 2001 From: Gavin Williams Date: Wed, 16 Aug 2017 17:37:04 +0100 Subject: [PATCH 2/2] Increase test coverage --- README.md | 28 ++++ .../rabbitmq_binding/rabbitmqadmin.rb | 20 ++- lib/puppet/type/rabbitmq_binding.rb | 38 +++-- spec/acceptance/queue_spec.rb | 6 +- .../rabbitmq_binding/rabbitmqadmin_spec.rb | 142 ++++++++++++++++-- .../unit/puppet/type/rabbitmq_binding_spec.rb | 18 ++- 6 files changed, 212 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 3bacefcec..849e085a0 100644 --- a/README.md +++ b/README.md @@ -595,6 +595,34 @@ rabbitmq_binding { 'myexchange@myqueue@myvhost': } ``` +```puppet +rabbitmq_binding { 'binding 1': + source => 'myexchange', + destination => 'myqueue', + vhost => 'myvhost', + user => 'dan', + password => 'bar', + destination_type => 'queue', + routing_key => 'key1', + arguments => {}, + ensure => present, +} + +rabbitmq_binding { 'binding 2': + source => 'myexchange', + destination => 'myqueue', + vhost => 'myvhost', + user => 'dan', + password => 'bar', + destination_type => 'queue', + routing_key => 'key2', + arguments => {}, + ensure => present, +} + +``` + + ### rabbitmq\_user\_permissions ```puppet diff --git a/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb b/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb index 927cbb0ee..c41d21d1c 100644 --- a/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb +++ b/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb @@ -1,5 +1,7 @@ require 'json' require 'puppet' +require 'digest' + Puppet::Type.type(:rabbitmq_binding).provide(:rabbitmqadmin) do if Puppet::PUPPETVERSION.to_f < 3 @@ -15,6 +17,9 @@ end defaultfor :feature => :posix + # Without this, the composite namevar stuff doesn't work properly. + mk_resource_methods + def should_vhost if @should_vhost @should_vhost @@ -49,16 +54,17 @@ def self.instances else arguments = '{}' end + hashed_name = Digest::SHA256.hexdigest "%s@%s@%s@%s" % [source_name, destination_name, vhost, routing_key] unless(source_name.empty?) binding = { :source => source_name, - :dest => destination_name, + :destination => destination_name, :vhost => vhost, :destination_type => destination_type, :routing_key => routing_key, :arguments => JSON.parse(arguments), :ensure => :present, - :name => "%s@%s@%s@%s" % [source_name, destination_name, vhost, routing_key], + :name => hashed_name, } resources << new(binding) if binding[:name] end @@ -67,10 +73,12 @@ def self.instances resources end + # see + # https://github.com/puppetlabs/puppetlabs-netapp/blob/d0a655665463c69c932f835ba8756be32417a4e9/lib/puppet/provider/netapp_qtree/sevenmode.rb#L66-L73 def self.prefetch(resources) bindings = instances - resources.keys.each do |name| - if provider = bindings.find{ |route| route.source == source && route.dest == dest && route.vhost == vhost && route.routing_key == routing_key } + resources.each do |name, res| + if provider = bindings.find{ |binding| binding.source == res[:source] && binding.destination == res[:destination] && binding.vhost == res[:vhost] && binding.routing_key == res[:routing_key] } resources[name].provider = provider end end @@ -94,7 +102,7 @@ def create '-c', '/etc/rabbitmq/rabbitmqadmin.conf', "source=#{resource[:source]}", - "destination=#{resource[:dest]}", + "destination=#{resource[:destination]}", "arguments=#{arguments.to_json}", "routing_key=#{resource[:routing_key]}", "destination_type=#{resource[:destination_type]}" @@ -104,7 +112,7 @@ def create def destroy vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : '' - rabbitmqadmin('delete', 'binding', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf', "source=#{resource[:source]}", "destination_type=#{resource[:destination_type]}", "destination=#{resource[:dest]}", "properties_key=#{resource[:routing_key]}") + rabbitmqadmin('delete', 'binding', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf', "source=#{resource[:source]}", "destination_type=#{resource[:destination_type]}", "destination=#{resource[:destination]}", "properties_key=#{resource[:routing_key]}") @property_hash[:ensure] = :absent end diff --git a/lib/puppet/type/rabbitmq_binding.rb b/lib/puppet/type/rabbitmq_binding.rb index fd090caeb..7de3b7dac 100644 --- a/lib/puppet/type/rabbitmq_binding.rb +++ b/lib/puppet/type/rabbitmq_binding.rb @@ -12,7 +12,7 @@ end # Match patterns without '@' as arbitrary names; match patterns with - # src@dst@vhost to their named params for backwards compatibility. + # src@destination@vhost to their named params for backwards compatibility. def self.title_patterns [ [ @@ -22,10 +22,11 @@ def self.title_patterns ] ], [ - /^(\S+)@(\S+)@(\S+)$/m, + /^((\S+)@(\S+)@(\S+))$/m, [ + [ :name ], [ :source ], - [ :dest ], + [ :destination], [ :vhost ] ] ] @@ -33,26 +34,26 @@ def self.title_patterns end newparam(:name) do - desc 'resource name, either source@dest@vhost or arbitrary name with params' - + desc 'resource name, either source@destination@vhost or arbitrary name with params' + isnamevar end - newparam(:source) do + newproperty(:source) do desc 'source of binding' newvalues(/^\S+$/) isnamevar end - newparam(:dest, :namevar => true) do + newproperty(:destination) do desc 'destination of binding' newvalues(/^\S+$/) isnamevar end - newparam(:vhost, :namevar => true) do + newproperty(:vhost) do desc 'vhost' newvalues(/^\S+$/) @@ -60,21 +61,20 @@ def self.title_patterns isnamevar end - newparam(:routing_key, :namevar => true) do + newproperty(:routing_key) do desc 'binding routing_key' newvalues(/^\S*$/) - defaultto('#') isnamevar end - newparam(:destination_type) do + newproperty(:destination_type) do desc 'binding destination_type' newvalues(/queue|exchange/) defaultto('queue') end - newparam(:arguments) do + newproperty(:arguments) do desc 'binding arguments' defaultto {} validate do |value| @@ -113,7 +113,7 @@ def self.title_patterns autorequire(:rabbitmq_user_permissions) do [ "#{self[:user]}@#{self[:source]}", - "#{self[:user]}@#{self[:dest]}" + "#{self[:user]}@#{self[:destination]}" ] end @@ -122,11 +122,11 @@ def setup_autorequire(type) if type == 'exchange' rval = ["#{self[:source]}@#{self[:vhost]}"] if destination_type == type - rval.push("#{self[:dest]}@#{self[:vhost]}") + rval.push("#{self[:destination]}@#{self[:vhost]}") end else if destination_type == type - rval = ["#{self[:dest]}@#{self[:vhost]}"] + rval = ["#{self[:destination]}@#{self[:vhost]}"] else rval = [] end @@ -140,4 +140,12 @@ def validate_argument(argument) end end + # Validate that we have both source and destination now that these are not + # necessarily only coming from the resource title. + validate do + unless self[:source] and self[:destination] + raise ArgumentError, "Source and destination must both be defined." + end + end + end diff --git a/spec/acceptance/queue_spec.rb b/spec/acceptance/queue_spec.rb index abf946bbd..646bb8f49 100644 --- a/spec/acceptance/queue_spec.rb +++ b/spec/acceptance/queue_spec.rb @@ -78,7 +78,7 @@ class { '::rabbitmq': end - context "create multiple bindings when same source / dest / vhost but different routing keys" do + context "create multiple bindings when same source / destination / vhost but different routing keys" do it 'should run successfully' do pp = <<-EOS if $::osfamily == 'RedHat' { @@ -125,7 +125,9 @@ class { '::rabbitmq': rabbitmq_binding { 'binding 1': source => 'exchange1', + destination => 'queue1', user => 'dan', + vhost => 'host1', password => 'bar', destination_type => 'queue', routing_key => 'test1', @@ -134,7 +136,9 @@ class { '::rabbitmq': rabbitmq_binding { 'binding 2': source => 'exchange1', + destination => 'queue1', user => 'dan', + vhost => 'host1', password => 'bar', destination_type => 'queue', routing_key => 'test2', diff --git a/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb b/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb index e165d557c..82762bde8 100644 --- a/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb +++ b/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb @@ -7,24 +7,111 @@ describe provider_class do before :each do @resource = Puppet::Type::Rabbitmq_binding.new( - {:name => 'source@target@/', - :destination_type => :queue, - :routing_key => 'blablub', - :arguments => {} + { + :name => 'source@target@/', + :destination_type => :queue, + :routing_key => 'blablub', + :arguments => {} } ) @provider = provider_class.new(@resource) end - it 'should return instances' do - provider_class.expects(:rabbitmqctl).with('list_vhosts', '-q').returns <<-EOT + describe "#instances" do + it 'should return instances' do + provider_class.expects(:rabbitmqctl).with('list_vhosts', '-q').returns <<-EOT / EOT - provider_class.expects(:rabbitmqctl).with('list_bindings', '-q', '-p', '/', 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments').returns <<-EOT - queue queue queue [] + provider_class.expects(:rabbitmqctl).with('list_bindings', '-q', '-p', '/', 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments').returns <<-EOT +exchange\tdst_queue\tqueue\t*\t[] EOT - instances = provider_class.instances - instances.size.should == 1 + instances = provider_class.instances + instances.size.should == 1 + instances.map do |prov| + { + :source => prov.get(:source), + :destination => prov.get(:destination), + :vhost => prov.get(:vhost), + :routing_key => prov.get(:routing_key) + } + end.should == [ + { + :source => 'exchange', + :destination => 'dst_queue', + :vhost => '/', + :routing_key => '*' + } + ] + end + + it 'should return multiple instances' do + provider_class.expects(:rabbitmqctl).with('list_vhosts', '-q').returns <<-EOT +/ +EOT + provider_class.expects(:rabbitmqctl).with('list_bindings', '-q', '-p', '/', 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments').returns <<-EOT +exchange\tdst_queue\tqueue\trouting_one\t[] +exchange\tdst_queue\tqueue\trouting_two\t[] +EOT + instances = provider_class.instances + instances.size.should == 2 + instances.map do |prov| + { + :source => prov.get(:source), + :destination => prov.get(:destination), + :vhost => prov.get(:vhost), + :routing_key => prov.get(:routing_key) + } + end.should == [ + { + :source => 'exchange', + :destination => 'dst_queue', + :vhost => '/', + :routing_key => 'routing_one' + }, + { + :source => 'exchange', + :destination => 'dst_queue', + :vhost => '/', + :routing_key => 'routing_two' + } + ] + end + end + + describe "Test for prefetch error" do + it "exists" do + provider_class.expects(:rabbitmqctl).with('list_vhosts', '-q').returns <<-EOT +/ +EOT + provider_class.expects(:rabbitmqctl).with('list_bindings', '-q', '-p', '/', 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments').returns <<-EOT +exchange\tdst_queue\tqueue\t*\t[] +EOT + + provider_class.prefetch({}) + end + + it "matches" do + # Test resource to match against + @resource = Puppet::Type::Rabbitmq_binding.new( + { + :name => 'binding1', + :source => 'exchange1', + :destination => 'destqueue', + :destination_type => :queue, + :routing_key => 'blablubd', + :arguments => {} + } + ) + + provider_class.expects(:rabbitmqctl).with('list_vhosts', '-q').returns <<-EOT +/ +EOT + provider_class.expects(:rabbitmqctl).with('list_bindings', '-q', '-p', '/', 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments').returns <<-EOT +exchange\tdst_queue\tqueue\t*\t[] +EOT + + provider_class.prefetch({ "binding1" => @resource}) + end end it 'should call rabbitmqadmin to create' do @@ -40,12 +127,13 @@ context 'specifying credentials' do before :each do @resource = Puppet::Type::Rabbitmq_binding.new( - {:name => 'source@test2@/', - :destination_type => :queue, - :routing_key => 'blablubd', - :arguments => {}, - :user => 'colin', - :password => 'secret' + { + :name => 'source@test2@/', + :destination_type => :queue, + :routing_key => 'blablubd', + :arguments => {}, + :user => 'colin', + :password => 'secret' } ) @provider = provider_class.new(@resource) @@ -56,4 +144,26 @@ @provider.create end end + + context 'new queue_bindings' do + before :each do + @resource = Puppet::Type::Rabbitmq_binding.new( + { + :name => 'binding1', + :source => 'exchange1', + :destination => 'destqueue', + :destination_type => :queue, + :routing_key => 'blablubd', + :arguments => {} + } + ) + @provider = provider_class.new(@resource) + end + + it 'should call rabbitmqadmin to create' do + @provider.expects(:rabbitmqadmin).with('declare', 'binding', '--vhost=/', '--user=guest', '--password=guest', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'source=exchange1', 'destination=destqueue', 'arguments={}', 'routing_key=blablubd', 'destination_type=queue') + @provider.create + end + end + end diff --git a/spec/unit/puppet/type/rabbitmq_binding_spec.rb b/spec/unit/puppet/type/rabbitmq_binding_spec.rb index cf88570f1..a3646076c 100644 --- a/spec/unit/puppet/type/rabbitmq_binding_spec.rb +++ b/spec/unit/puppet/type/rabbitmq_binding_spec.rb @@ -15,16 +15,30 @@ Puppet::Type.type(:rabbitmq_binding).new({}) }.to raise_error(Puppet::Error, 'Title or name must be provided') end + it 'should error when missing source' do + expect { + Puppet::Type.type(:rabbitmq_binding).new( + :name => 'test binding', + :destination => 'foobar' + ) + }.to raise_error(Puppet::Error, /Source and destination must both be defined/) + end + it 'should error when missing destination' do + expect { + Puppet::Type.type(:rabbitmq_binding).new( + :name => 'test binding', + :source => 'foobar' + ) + }.to raise_error(Puppet::Error, /Source and destination must both be defined/) + end it 'should accept an binding destination_type' do @binding[:destination_type] = :exchange @binding[:destination_type].should == :exchange end - it 'should accept a user' do @binding[:user] = :root @binding[:user].should == :root end - it 'should accept a password' do @binding[:password] = :PaSsw0rD @binding[:password].should == :PaSsw0rD