Skip to content

Commit

Permalink
Merge pull request redhat-openstack#269 from Mayflower/master
Browse files Browse the repository at this point in the history
Add new Resources for Queue and Bindings.
  • Loading branch information
cmurphy committed Jan 14, 2015
2 parents cf30101 + a2f802c commit 4657e57
Show file tree
Hide file tree
Showing 9 changed files with 637 additions and 0 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,35 @@ rabbitmq_exchange { 'myexchange@myhost':
}
```

### rabbitmq\_queue

```puppet
rabbitmq_queue { 'myqueue@myhost':
user => 'dan',
password => 'bar',
durable => true,
auto_delete => false,
arguments => {
x-message-ttl => 123,
x-dead-letter-exchange => 'other'
},
ensure => present,
}
```

### rabbitmq\_binding

```puppet
rabbitmq_binding { 'myexchange@myqueue@myhost':
user => 'dan',
password => 'bar',
destination_type => 'queue',
routing_key => '#',
arguments => {},
ensure => present,
}
```

### rabbitmq\_user\_permissions

```puppet
Expand Down
110 changes: 110 additions & 0 deletions lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb
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
105 changes: 105 additions & 0 deletions lib/puppet/provider/rabbitmq_queue/rabbitmqadmin.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
require 'json'
require 'puppet'
Puppet::Type.type(:rabbitmq_queue).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].rpartition('@').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_queues(vhost)
rabbitmqctl('list_queues', '-q', '-p', vhost, 'name', 'durable', 'auto_delete', 'arguments').split(/\n/)
end

def self.instances
resources = []
all_vhosts.each do |vhost|
all_queues(vhost).collect do |line|
name, durable, auto_delete, arguments = line.split()
# 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
queue = {
:durable => durable,
:auto_delete => auto_delete,
:arguments => JSON.parse(arguments),
:ensure => :present,
:name => "%s@%s" % [name, vhost],
}
resources << new(queue) if queue[:name]
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].rpartition('@').first
arguments = resource[:arguments]
if arguments.nil?
arguments = {}
end
rabbitmqadmin('declare',
'queue',
vhost_opt,
"--user=#{resource[:user]}",
"--password=#{resource[:password]}",
"name=#{name}",
"durable=#{resource[:durable]}",
"auto_delete=#{resource[:auto_delete]}",
"arguments=#{arguments.to_json}"
)
@property_hash[:ensure] = :present
end

def destroy
vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : ''
name = resource[:name].rpartition('@').first
rabbitmqadmin('delete', 'queue', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "name=#{name}")
@property_hash[:ensure] = :absent
end

end
96 changes: 96 additions & 0 deletions lib/puppet/type/rabbitmq_binding.rb
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

0 comments on commit 4657e57

Please sign in to comment.