forked from redhat-openstack/openstack-puppet-modules
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ebc20c2
commit d998f94
Showing
4 changed files
with
315 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
require 'json' | ||
require 'puppet' | ||
Puppet::Type.type(:rabbitmq_binding).provide(:rabbitmqadmin) do | ||
|
||
if Puppet::PUPPETVERSION.to_f < 3 | ||
commands :rabbitmqctl => 'rabbitmqctl' | ||
commands :rabbitmqadmin => '/usr/local/bin/rabbitmqadmin' | ||
else | ||
has_command(:rabbitmqctl, 'rabbitmqctl') do | ||
environment :HOME => "/tmp" | ||
end | ||
has_command(:rabbitmqadmin, '/usr/local/bin/rabbitmqadmin') do | ||
environment :HOME => "/tmp" | ||
end | ||
end | ||
defaultfor :feature => :posix | ||
|
||
def should_vhost | ||
if @should_vhost | ||
@should_vhost | ||
else | ||
@should_vhost = resource[:name].split('@').last | ||
end | ||
end | ||
|
||
def self.all_vhosts | ||
vhosts = [] | ||
rabbitmqctl('list_vhosts', '-q').split(/\n/).collect do |vhost| | ||
vhosts.push(vhost) | ||
end | ||
vhosts | ||
end | ||
|
||
def self.all_bindings(vhost) | ||
rabbitmqctl('list_bindings', '-q', '-p', vhost, 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments').split(/\n/) | ||
end | ||
|
||
def self.instances | ||
resources = [] | ||
all_vhosts.each do |vhost| | ||
all_bindings(vhost).collect do |line| | ||
source_name, destination_name, destination_type, routing_key, arguments = line.split(/\t/) | ||
# 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 | ||
if (source_name != '') | ||
binding = { | ||
:destination_type => destination_type, | ||
:routing_key => routing_key, | ||
:arguments => JSON.parse(arguments), | ||
:ensure => :present, | ||
:name => "%s@%s@%s" % [source_name, destination_name, vhost], | ||
} | ||
resources << new(binding) if binding[:name] | ||
end | ||
end | ||
end | ||
resources | ||
end | ||
|
||
def self.prefetch(resources) | ||
packages = instances | ||
resources.keys.each do |name| | ||
if provider = packages.find{ |pkg| pkg.name == name } | ||
resources[name].provider = provider | ||
end | ||
end | ||
end | ||
|
||
def exists? | ||
@property_hash[:ensure] == :present | ||
end | ||
|
||
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 = {} | ||
end | ||
rabbitmqadmin('declare', | ||
'binding', | ||
vhost_opt, | ||
"--user=#{resource[:user]}", | ||
"--password=#{resource[:password]}", | ||
"source=#{name}", | ||
"destination=#{destination}", | ||
"arguments=#{arguments.to_json}", | ||
"routing_key=#{resource[:routing_key]}", | ||
"destination_type=#{resource[:destination_type]}" | ||
) | ||
@property_hash[:ensure] = :present | ||
end | ||
|
||
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]}", "source=#{name}", "destination_type=#{resource[:destination_type]}", "destination=#{destination}") | ||
@property_hash[:ensure] = :absent | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
Puppet::Type.newtype(:rabbitmq_binding) do | ||
desc 'Native type for managing rabbitmq bindings' | ||
|
||
ensurable do | ||
defaultto(:present) | ||
newvalue(:present) do | ||
provider.create | ||
end | ||
newvalue(:absent) do | ||
provider.destroy | ||
end | ||
end | ||
|
||
newparam(:name, :namevar => true) do | ||
desc 'source and destination of bind' | ||
newvalues(/^\S*@\S+@\S+$/) | ||
end | ||
|
||
newparam(:destination_type) do | ||
desc 'binding destination_type' | ||
newvalues(/queue|exchange/) | ||
defaultto('queue') | ||
end | ||
|
||
newparam(:routing_key) do | ||
desc 'binding routing_key' | ||
newvalues(/^\S*$/) | ||
end | ||
|
||
newparam(:arguments) do | ||
desc 'binding arguments' | ||
defaultto {} | ||
validate do |value| | ||
resource.validate_argument(value) | ||
end | ||
end | ||
|
||
newparam(:user) do | ||
desc 'The user to use to connect to rabbitmq' | ||
defaultto('guest') | ||
newvalues(/^\S+$/) | ||
end | ||
|
||
newparam(:password) do | ||
desc 'The password to use to connect to rabbitmq' | ||
defaultto('guest') | ||
newvalues(/\S+/) | ||
end | ||
|
||
autorequire(:rabbitmq_vhost) do | ||
[self[:name].split('@')[2]] | ||
end | ||
|
||
autorequire(:rabbitmq_exchange) do | ||
setup_autorequire('exchange') | ||
end | ||
|
||
autorequire(:rabbitmq_queue) do | ||
setup_autorequire('queue') | ||
end | ||
|
||
autorequire(:rabbitmq_user) do | ||
[self[:user]] | ||
end | ||
|
||
autorequire(:rabbitmq_user_permissions) do | ||
[ | ||
"#{self[:user]}@#{self[:name].split('@')[1]}", | ||
"#{self[:user]}@#{self[:name].split('@')[0]}" | ||
] | ||
end | ||
|
||
def setup_autorequire(type) | ||
destination_type = value(:destination_type) | ||
if type == 'exchange' | ||
rval = ["#{self[:name].split('@')[0]}@#{self[:name].split('@')[2]}"] | ||
if destination_type == type | ||
rval.push("#{self[:name].split('@')[1]}@#{self[:name].split('@')[2]}") | ||
end | ||
else | ||
if destination_type == type | ||
rval = ["#{self[:name].split('@')[1]}@#{self[:name].split('@')[2]}"] | ||
else | ||
rval = [] | ||
end | ||
end | ||
rval | ||
end | ||
|
||
def validate_argument(argument) | ||
unless [Hash].include?(argument.class) | ||
raise ArgumentError, "Invalid argument" | ||
end | ||
end | ||
|
||
end |
59 changes: 59 additions & 0 deletions
59
spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
require 'puppet' | ||
require 'mocha/api' | ||
RSpec.configure do |config| | ||
config.mock_with :mocha | ||
end | ||
provider_class = Puppet::Type.type(:rabbitmq_binding).provider(:rabbitmqadmin) | ||
describe provider_class do | ||
before :each do | ||
@resource = Puppet::Type::Rabbitmq_binding.new( | ||
{: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 | ||
/ | ||
EOT | ||
provider_class.expects(:rabbitmqctl).with('list_bindings', '-q', '-p', '/', 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments').returns <<-EOT | ||
queue queue queue [] | ||
EOT | ||
instances = provider_class.instances | ||
instances.size.should == 1 | ||
end | ||
|
||
it 'should call rabbitmqadmin to create' do | ||
@provider.expects(:rabbitmqadmin).with('declare', 'binding', '--vhost=/', '--user=guest', '--password=guest', 'source=source', 'destination=target', 'arguments={}', 'routing_key=blablub', 'destination_type=queue') | ||
@provider.create | ||
end | ||
|
||
it 'should call rabbitmqadmin to destroy' do | ||
@provider.expects(:rabbitmqadmin).with('delete', 'binding', '--vhost=/', '--user=guest', '--password=guest', 'source=source', 'destination_type=queue', 'destination=target') | ||
@provider.destroy | ||
end | ||
|
||
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' | ||
} | ||
) | ||
@provider = provider_class.new(@resource) | ||
end | ||
|
||
it 'should call rabbitmqadmin to create' do | ||
@provider.expects(:rabbitmqadmin).with('declare', 'binding', '--vhost=/', '--user=colin', '--password=secret', 'source=source', 'destination=test2', 'arguments={}', 'routing_key=blablubd', 'destination_type=queue') | ||
@provider.create | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
require 'puppet' | ||
require 'puppet/type/rabbitmq_binding' | ||
describe Puppet::Type.type(:rabbitmq_binding) do | ||
before :each do | ||
@binding = Puppet::Type.type(:rabbitmq_binding).new( | ||
:name => 'foo@blub@bar', | ||
:destination_type => :queue | ||
) | ||
end | ||
it 'should accept an queue name' do | ||
@binding[:name] = 'dan@dude@pl' | ||
@binding[:name].should == 'dan@dude@pl' | ||
end | ||
it 'should require a name' do | ||
expect { | ||
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 | ||
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 | ||
end | ||
end |