--- /dev/null
+Puppet::Type.type(:rabbitmq_plugin).provide(:default) do
+
+ def self.instances
+ []
+ end
+
+ def create
+ default_fail
+ end
+
+ def destroy
+ default_fail
+ end
+
+ def exists?
+ default_fail
+ end
+
+ def default_fail
+ fail('This is just the default provider for rabbitmq_plugin, all it does is fail')
+ end
+end
--- /dev/null
+Puppet::Type.type(:rabbitmq_plugin).provide(:rabbitmqplugins) do
+
+ commands :rabbitmqplugins => '/usr/lib/rabbitmq/bin/rabbitmq-plugins'
+ defaultfor :feature => :posix
+
+ def self.instances
+ rabbitmqplugins('list', '-E').split(/\n/).map do |line|
+ if line.split(/\s+/)[1] =~ /^(\S+)$/
+ new(:name => $1)
+ else
+ raise Puppet::Error, "Cannot parse invalid plugins line: #{line}"
+ end
+ end
+ end
+
+ def create
+ rabbitmqplugins('enable', resource[:name])
+ end
+
+ def destroy
+ rabbitmqplugins('disable', resource[:name])
+ end
+
+ def exists?
+ out = rabbitmqplugins('list', '-E').split(/\n/).detect do |line|
+ line.split(/\s+/)[1].match(/^#{resource[:name]}$/)
+ end
+ end
+
+end
--- /dev/null
+Puppet::Type.type(:rabbitmq_policy).provide(:default) do
+
+ def self.instances
+ []
+ end
+
+ def create
+ default_fail
+ end
+
+ def destroy
+ default_fail
+ end
+
+ def exists?
+ default_fail
+ end
+
+ def default_fail
+ fail('This is just the default provider for rabbitmq_policy, all it does is fail')
+ end
+end
+
--- /dev/null
+require 'puppet'
+Puppet::Type.type(:rabbitmq_policy).provide(:rabbitmqctl) do
+
+ commands :rabbitmqctl => 'rabbitmqctl'
+ defaultfor :feature => :posix
+
+ def should_vhost
+ if @should_vhost
+ @should_vhost
+ else
+ @should_vhost = resource[:vhost]
+ end
+ end
+
+ def self.instances
+ rabbitmqctl('list_policies', '-p', should_vhost).split(/\n/)[1..-2].detect do |line|
+ if line =~ /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+.*$/
+ new(:name => $2, :vhost => $1, :match => $3, :policy => $4)
+ else
+ raise Puppet::Error, "Cannot parse invalid user line: #{line}"
+ end
+ end
+ end
+
+ def create
+ rabbitmqctl('set_policy', '-p', should_vhost, resource[:name], resource[:match], resource[:policy])
+ end
+
+ def destroy
+ rabbitmqctl('clear_policy', '-p', should_vhost, resource[:name])
+ end
+
+ def exists?
+ out = rabbitmqctl('list_policies', '-p', should_vhost).split(/\n/)[1..-2].detect do |line|
+ line.match(/^\S+\s+#{resource[:name]}\s+\S+.*$/)
+ end
+ end
+
+end
--- /dev/null
+Puppet::Type.type(:rabbitmq_user).provide(:default) do
+
+ def self.instances
+ []
+ end
+
+ def create
+ default_fail
+ end
+
+ def destroy
+ default_fail
+ end
+
+ def exists?
+ default_fail
+ end
+
+ def default_fail
+ fail('This is just the default provider for rabbitmq_user, all it does is fail')
+ end
+end
--- /dev/null
+require 'puppet'
+Puppet::Type.type(:rabbitmq_user).provide(:rabbitmqctl) do
+
+ commands :rabbitmqctl => 'rabbitmqctl'
+ defaultfor :feature => :posix
+
+ def self.instances
+ rabbitmqctl('list_users').split(/\n/)[1..-2].collect do |line|
+ if line =~ /^(\S+)(\s+\S+|)$/
+ new(:name => $1)
+ else
+ raise Puppet::Error, "Cannot parse invalid user line: #{line}"
+ end
+ end
+ end
+
+ def create
+ rabbitmqctl('add_user', resource[:name], resource[:password])
+ if resource[:admin] == :true
+ make_user_admin()
+ end
+ end
+
+ def destroy
+ rabbitmqctl('delete_user', resource[:name])
+ end
+
+ def exists?
+ out = rabbitmqctl('list_users').split(/\n/)[1..-2].detect do |line|
+ line.match(/^#{resource[:name]}(\s+\S+|)$/)
+ end
+ end
+
+ # def password
+ # def password=()
+ def admin
+ match = rabbitmqctl('list_users').split(/\n/)[1..-2].collect do |line|
+ line.match(/^#{resource[:name]}\s+\[(administrator)?\]/)
+ end.compact.first
+ if match
+ (:true if match[1].to_s == 'administrator') || :false
+ else
+ raise Puppet::Error, "Could not match line '#{resource[:name]} (true|false)' from list_users (perhaps you are running on an older version of rabbitmq that does not support admin users?)"
+ end
+ end
+
+ def admin=(state)
+ if state == :true
+ make_user_admin()
+ else
+ rabbitmqctl('set_user_tags', resource[:name])
+ end
+ end
+
+ def make_user_admin
+ rabbitmqctl('set_user_tags', resource[:name], 'administrator')
+ end
+
+end
--- /dev/null
+Puppet::Type.type(:rabbitmq_user_permissions).provide(:default) do
+
+ def create
+ default_fail
+ end
+
+ def destroy
+ default_fail
+ end
+
+ def exists?
+ default_fail
+ end
+
+ def default_fail
+ fail('This is just the default provider for rabbitmq_user, all it does is fail')
+ end
+end
--- /dev/null
+Puppet::Type.type(:rabbitmq_user_permissions).provide(:rabbitmqctl) do
+
+ commands :rabbitmqctl => 'rabbitmqctl'
+ defaultfor :feature=> :posix
+
+ #def self.instances
+ #
+ #end
+
+ # cache users permissions
+ def self.users(name, vhost)
+ @users = {} unless @users
+ unless @users[name]
+ @users[name] = {}
+ out = rabbitmqctl('list_user_permissions', name).split(/\n/)[1..-2].each do |line|
+ if line =~ /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/
+ @users[name][$1] =
+ {:configure => $2, :read => $3, :write => $4}
+ else
+ raise Puppet::Error, "cannot parse line from list_user_permissions:#{line}"
+ end
+ end
+ end
+ @users[name][vhost]
+ end
+
+ def users(name, vhost)
+ self.class.users(name, vhost)
+ end
+
+ def should_user
+ if @should_user
+ @should_user
+ else
+ @should_user = resource[:name].split('@')[0]
+ end
+ end
+
+ def should_vhost
+ if @should_vhost
+ @should_vhost
+ else
+ @should_vhost = resource[:name].split('@')[1]
+ end
+ end
+
+ def create
+ resource[:configure_permission] ||= "''"
+ resource[:read_permission] ||= "''"
+ resource[:write_permission] ||= "''"
+ rabbitmqctl('set_permissions', '-p', should_vhost, should_user, resource[:configure_permission], resource[:read_permission], resource[:write_permission])
+ end
+
+ def destroy
+ rabbitmqctl('clear_permissions', '-p', should_vhost, should_user)
+ end
+
+ # I am implementing prefetching in exists b/c I need to be sure
+ # that the rabbitmq package is installed before I make this call.
+ def exists?
+ users(should_user, should_vhost)
+ end
+
+ def configure_permission
+ users(should_user, should_vhost)[:configure]
+ end
+
+ def configure_permission=(perm)
+ set_permissions
+ end
+
+ def read_permission
+ users(should_user, should_vhost)[:read]
+ end
+
+ def read_permission=(perm)
+ set_permissions
+ end
+
+ def write_permission
+ users(should_user, should_vhost)[:write]
+ end
+
+ def write_permission=(perm)
+ set_permissions
+ end
+
+ # implement memoization so that we only call set_permissions once
+ def set_permissions
+ unless @permissions_set
+ @permissions_set = true
+ resource[:configure_permission] ||= configure_permission
+ resource[:read_permission] ||= read_permission
+ resource[:write_permission] ||= write_permission
+ rabbitmqctl('set_permissions', '-p', should_vhost, should_user,
+ resource[:configure_permission], resource[:read_permission],
+ resource[:write_permission]
+ )
+ end
+ end
+
+end
--- /dev/null
+Puppet::Type.type(:rabbitmq_vhost).provide(:default) do
+
+ def self.instances
+ []
+ end
+
+ def create
+ default_fail
+ end
+
+ def destroy
+ default_fail
+ end
+
+ def exists?
+ default_fail
+ end
+
+ def default_fail
+ fail('This is just the default provider for rabbitmq_vhost, all it does is fail')
+ end
+end
--- /dev/null
+Puppet::Type.type(:rabbitmq_vhost).provide(:rabbitmqctl) do
+
+ commands :rabbitmqctl => 'rabbitmqctl'
+ defaultfor :feature => :posix
+
+ def self.instances
+ rabbitmqctl('list_vhosts').split(/\n/)[1..-2].map do |line|
+ if line =~ /^(\S+)$/
+ new(:name => $1)
+ else
+ raise Puppet::Error, "Cannot parse invalid user line: #{line}"
+ end
+ end
+ end
+
+ def create
+ rabbitmqctl('add_vhost', resource[:name])
+ end
+
+ def destroy
+ rabbitmqctl('delete_vhost', resource[:name])
+ end
+
+ def exists?
+ out = rabbitmqctl('list_vhosts').split(/\n/)[1..-2].detect do |line|
+ line.match(/^#{resource[:name]}$/)
+ end
+ end
+
+end
--- /dev/null
+Puppet::Type.newtype(:rabbitmq_plugin) do
+ desc 'manages rabbitmq plugins'
+
+ ensurable do
+ defaultto(:present)
+ newvalue(:present) do
+ provider.create
+ end
+ newvalue(:absent) do
+ provider.destroy
+ end
+ end
+
+ newparam(:name, :namevar => true) do
+ 'name of the plugin to enable'
+ newvalues(/^\S+$/)
+ end
+
+end
--- /dev/null
+Puppet::Type.newtype(:rabbitmq_policy) do
+ desc 'Native type for managing rabbitmq policy'
+
+ ensurable do
+ defaultto(:present)
+ newvalue(:present) do
+ provider.create
+ end
+ newvalue(:absent) do
+ provider.destroy
+ end
+ end
+
+ newparam(:name, :namevar => true) do
+ desc 'Name of policy'
+ newvalues(/^\S+$/)
+ end
+
+ newparam(:vhost) do
+ desc 'Vhost for policy'
+ newvalues(/^\S+$/)
+ end
+
+ newparam(:match) do
+ desc 'Regex match for policy'
+ end
+
+ newparam(:policy) do
+ desc 'Policy to set'
+ end
+
+ validate do
+ if self[:ensure] == :present and ! self[:policy] and ! self[:match]
+ raise ArgumentError, 'must set policy and match' unless self[:policy] and self[:match]
+ end
+ end
+
+end
+
--- /dev/null
+Puppet::Type.newtype(:rabbitmq_user) do
+ desc 'Native type for managing rabbitmq users'
+
+ ensurable do
+ defaultto(:present)
+ newvalue(:present) do
+ provider.create
+ end
+ newvalue(:absent) do
+ provider.destroy
+ end
+ end
+
+ newparam(:name, :namevar => true) do
+ desc 'Name of user'
+ newvalues(/^\S+$/)
+ end
+
+ # newproperty(:password) do
+ newparam(:password) do
+ desc 'User password to be set *on creation*'
+ end
+
+ newproperty(:admin) do
+ desc 'rather or not user should be an admin'
+ newvalues(/true|false/)
+ munge do |value|
+ # converting to_s incase its a boolean
+ value.to_s.to_sym
+ end
+ defaultto :false
+ end
+
+ validate do
+ if self[:ensure] == :present and ! self[:password]
+ raise ArgumentError, 'must set password when creating user' unless self[:password]
+ end
+ end
+
+end
--- /dev/null
+Puppet::Type.newtype(:rabbitmq_user_permissions) do
+ desc 'Type for managing rabbitmq user permissions'
+
+ ensurable do
+ defaultto(:present)
+ newvalue(:present) do
+ provider.create
+ end
+ newvalue(:absent) do
+ provider.destroy
+ end
+ end
+
+ newparam(:name, :namevar => true) do
+ 'combination of user@vhost to grant privileges to'
+ newvalues(/^\S+@\S+$/)
+ end
+
+ newproperty(:configure_permission) do
+ desc 'regexp representing configuration permissions'
+ validate do |value|
+ resource.validate_permissions(value)
+ end
+ end
+
+ newproperty(:read_permission) do
+ desc 'regexp representing read permissions'
+ validate do |value|
+ resource.validate_permissions(value)
+ end
+ end
+
+ newproperty(:write_permission) do
+ desc 'regexp representing write permissions'
+ validate do |value|
+ resource.validate_permissions(value)
+ end
+ end
+
+ autorequire(:rabbitmq_vhost) do
+ [self[:name].split('@')[1]]
+ end
+
+ autorequire(:rabbitmq_user) do
+ [self[:name].split('@')[0]]
+ end
+
+ # I may want to dissalow whitespace
+ def validate_permissions(value)
+ begin
+ Regexp.new(value)
+ rescue RegexpError
+ raise ArgumentError, "Invalid regexp #{value}"
+ end
+ end
+
+end
--- /dev/null
+Puppet::Type.newtype(:rabbitmq_vhost) do
+ desc 'manages rabbitmq vhosts'
+
+ ensurable do
+ defaultto(:present)
+ newvalue(:present) do
+ provider.create
+ end
+ newvalue(:absent) do
+ provider.destroy
+ end
+ end
+
+ newparam(:name, :namevar => true) do
+ 'name of the vhost to add'
+ newvalues(/^\S+$/)
+ end
+
+end
--- /dev/null
+# == Class: rabbitmq::config
+#
+# Sets up the rabbitmq config file
+#
+class rabbitmq::config {
+ include rabbitmq::packages
+ include concat::setup
+
+ concat { '/etc/rabbitmq/rabbitmq.config':
+ require => Package['rabbitmq-server'],
+ notify => Service['rabbitmq-server'],
+ owner => root,
+ group => $::root_group,
+ mode => '0644',
+ }
+}
--- /dev/null
+# == Class: rabbitmq
+#
+# Top level class for all things rabbitmq
+#
+class rabbitmq (
+ $cluster=false,
+ $clustermembers=[],
+ $clustercookie='',
+ $delete_guest_user=false,
+ $rabbit_num_ofiles=4096,
+ $master=''
+) {
+ include rabbitmq::config
+
+ package { 'rabbitmq-server':
+ ensure => installed,
+ }
+
+ service { 'rabbitmq-server':
+ ensure => running,
+ enable => true,
+ require => Package['rabbitmq-server']
+ }
+
+ Service['rabbitmq-server'] -> Rabbitmq_user <| |>
+ Service['rabbitmq-server'] -> Rabbitmq_vhost <| |>
+ Service['rabbitmq-server'] -> Rabbitmq_user_permissions <| |>
+
+ concat::fragment { 'rabbitmq_main_conf':
+ target => '/etc/rabbitmq/rabbitmq.config',
+ order => 00,
+ content => template('rabbitmq/rabbitmq.conf.erb'),
+ }
+
+ concat::fragment { 'rabbitmq_conf_foot':
+ target => '/etc/rabbitmq/rabbitmq.config',
+ order => 99,
+ content => "].\n"
+ }
+
+ file { '/etc/rabbitmq/rabbitmq.conf.d/':
+ ensure => directory,
+ require => Package['rabbitmq-server']
+ }
+
+ file { '/etc/rabbitmq/rabbitmq.conf.d/ulimit.conf':
+ content => template('rabbitmq/rabbitmq.ulimit.erb'),
+ require => [ Package['rabbitmq-server'], File['/etc/rabbitmq/rabbitmq.conf.d/'] ],
+ notify => Service['rabbitmq-server']
+ }
+
+ if $cluster {
+ if $clustercookie {
+ file { '/var/lib/rabbitmq':
+ ensure => directory,
+ mode => '0755',
+ owner => rabbitmq,
+ group => rabbitmq,
+ }
+
+ file { '/var/lib/rabbitmq/.erlang.cookie':
+ content => $clustercookie,
+ mode => '0500',
+ owner => rabbitmq,
+ group => rabbitmq,
+ before => Package['rabbitmq-server'],
+ notify => Service['rabbitmq-server']
+ }
+ }
+
+ if $::hostname != $master {
+ exec { 'reset_mq':
+ command => 'rabbitmqctl stop_app && rabbitmqctl reset > /var/lib/rabbitmq/.node_reset',
+ path => '/usr/bin:/bin:/usr/sbin:/sbin',
+ creates => '/var/lib/rabbitmq/.node_reset',
+ require => Package['rabbitmq-server'],
+ notify => Service['rabbitmq-server']
+ }
+ Exec['reset_mq'] -> Rabbitmq_user <| |>
+ Exec['reset_mq'] -> Rabbitmq_vhost <| |>
+ Exec['reset_mq'] -> Rabbitmq_user_permissions <| |>
+ }
+ }
+
+ if $delete_guest_user {
+ rabbitmq_user { 'guest':
+ ensure => absent,
+ provider => 'rabbitmqctl',
+ }
+ }
+
+ site::limit { 'rabbitmq_openfiles':
+ limit_user => rabbitmq,
+ limit_value => $rabbit_num_ofiles,
+ notify => Service['rabbitmq-server']
+ }
+}
--- /dev/null
+# == Class: rabbitmq::packages
+#
+# Installs all the rabbitmq software
+#
+class rabbitmq::packages {
+ $ensure = installed
+
+ package { 'rabbitmq-server':
+ ensure => $ensure,
+ require => User['rabbitmq']
+ }
+}
--- /dev/null
+[
+<% if scope.lookupvar('cluster') -%>
+{rabbit, [{cluster_nodes, ['<%= scope.lookupvar('clustermembers').to_a.flatten.join("', '") %>']}]}
+<% end -%>
--- /dev/null
+ulimit -n <%= scope.lookupvar('rabbit_num_ofiles') %>
--- /dev/null
+class rabbitmq::packages {
+ package { 'rabbitmq-server': }
+ service { 'rabbitmq-server': }
+}
+class concat::setup {}
+
+include rabbitmq::config
--- /dev/null
+class site::users::system::rabbitmq {}
+class rabbitmq::config {}
+class rabbitmq::packages {
+ package { 'rabbitmq-server': }
+}
+include rabbitmq
--- /dev/null
+class site::aptrepo::rabbitmq {}
+class site::yumrepo::rabbitmq {}
+class site::users::system::rabbitmq {
+ user { 'rabbitmq': }
+}
+include rabbitmq::packages
+