1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmq_cli'))
Puppet::Type.type(:rabbitmq_user).provide(
:rabbitmqctl,
parent: Puppet::Provider::RabbitmqCli
) do
confine feature: :posix
def initialize(value = {})
super(value)
@property_flush = {}
end
def self.instances
user_list = run_with_retries do
rabbitmqctl_list('users')
end
if user_list.split(%r{\n}).size > 0
user_list.split(%r{\n})[1..-1].map do |line|
raise Puppet::Error, "Cannot parse invalid user line: #{line}" unless line =~ %r{^(\S+)\s+\[(.*?)\]$}
user = Regexp.last_match(1)
tags = Regexp.last_match(2).split(%r{,\s*})
new(
ensure: :present,
name: user,
tags: tags
)
end
else
user_list = []
end
end
def self.prefetch(resources)
users = instances
resources.each_key do |user|
if (provider = users.find { |u| u.name == user })
resources[user].provider = provider
end
end
end
def exists?
@property_hash[:ensure] == :present
end
def create
# Fail here (rather than a validate block in the type) if password is not
# set, so that "puppet resource" still works.
raise Puppet::Error, "Password is a required parameter for rabbitmq_user (user: #{name})" if @resource[:password].nil?
rabbitmqctl('add_user', @resource[:name], @resource[:password])
tags = @resource[:tags]
tags << admin_tag if @resource[:admin] == :true
rabbitmqctl('set_user_tags', @resource[:name], tags) unless tags.empty?
@property_hash[:ensure] = :present
end
def destroy
rabbitmqctl('delete_user', @resource[:name])
@property_hash[:ensure] = :absent
end
def password=(password)
rabbitmqctl('change_password', @resource[:name], password)
end
def password; end
def check_password(password)
check_access_control = [
'rabbit_access_control:check_user_pass_login(',
%[list_to_binary("#{@resource[:name]}"), ],
%[list_to_binary("#{password}")).]
]
response = rabbitmqctl('eval', check_access_control.join)
!response.include? 'refused'
end
def tags
# do not expose the administrator tag for admins
@property_hash[:tags].reject { |tag| tag == admin_tag }
end
def tags=(tags)
@property_flush[:tags] = tags
end
def admin
usertags = get_user_tags
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?)" unless usertags
(:true if usertags.include?('administrator')) || :false
end
def admin=(state)
if state == :true
make_user_admin
else
usertags = get_user_tags
usertags.delete('administrator')
rabbitmqctl('set_user_tags', resource[:name], usertags.entries.sort)
end
end
def admin
@property_hash[:tags].include?(admin_tag) ? :true : :false
end
def admin=(state)
@property_flush[:admin] = state
end
def flush
return if @property_flush.empty?
tags = @property_flush[:tags] || @resource[:tags]
tags << admin_tag if @resource[:admin] == :true
rabbitmqctl('set_user_tags', @resource[:name], tags)
@property_flush.clear
end
private
def admin_tag
'administrator'
end
end
|