Revert "Update 3rdparty rabbitmq module"
[mirror/dsa-puppet.git] / 3rdparty / modules / rabbitmq / lib / puppet / provider / rabbitmq_user / rabbitmqctl.rb
index 9eab0dd..da37886 100644 (file)
+require 'puppet'
+require 'set'
 require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmqctl'))
-Puppet::Type.type(:rabbitmq_user).provide(
-  :rabbitmqctl,
-  parent: Puppet::Provider::Rabbitmqctl
-) do
-  has_command(:rabbitmqctl, 'rabbitmqctl') do
-    environment HOME: '/tmp'
-  end
-
-  confine feature: :posix
+Puppet::Type.type(:rabbitmq_user).provide(:rabbitmqctl, :parent => Puppet::Provider::Rabbitmqctl) do
 
-  def initialize(value = {})
-    super(value)
-    @property_flush = {}
+  if Puppet::PUPPETVERSION.to_f < 3
+    commands :rabbitmqctl => 'rabbitmqctl'
+  else
+     has_command(:rabbitmqctl, 'rabbitmqctl') do
+       environment :HOME => "/tmp"
+     end
   end
 
+  defaultfor :feature => :posix
+
   def self.instances
-    user_list = run_with_retries do
+    self.run_with_retries {
       rabbitmqctl('-q', 'list_users')
-    end
-
-    user_list.split(%r{\n}).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
-      )
+    }.split(/\n/).collect do |line|
+      if line =~ /^(\S+)(\s+\[.*?\]|)$/
+        new(:name => $1)
+      else
+        raise Puppet::Error, "Cannot parse invalid user line: #{line}"
+      end
     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
+  def create
+    rabbitmqctl('add_user', resource[:name], resource[:password])
+    if resource[:admin] == :true
+      make_user_admin()
+    end
+    if ! resource[:tags].empty?
+      set_user_tags(resource[:tags])
     end
   end
 
-  def exists?
-    @property_hash[:ensure] == :present
+  def change_password
+    rabbitmqctl('change_password', resource[:name], resource[:password])
   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])
+  def password
+    nil
+  end
 
-    tags = @resource[:tags]
-    tags << admin_tag if @resource[:admin] == :true
-    rabbitmqctl('set_user_tags', @resource[:name], tags) unless tags.empty?
 
-    @property_hash[:ensure] = :present
+  def check_password
+    response = rabbitmqctl('eval', 'rabbit_access_control:check_user_pass_login(list_to_binary("' + resource[:name] + '"), list_to_binary("' + resource[:password] +'")).')
+    if response.include? 'refused'
+        false
+    else
+        true
+    end
   end
 
   def destroy
-    rabbitmqctl('delete_user', @resource[:name])
-    @property_hash[:ensure] = :absent
+    rabbitmqctl('delete_user', resource[:name])
   end
 
-  def password=(password)
-    rabbitmqctl('change_password', @resource[:name], password)
+  def exists?
+    self.class.run_with_retries {
+      rabbitmqctl('-q', 'list_users')
+    }.split(/\n/).detect do |line|
+      line.match(/^#{Regexp.escape(resource[:name])}(\s+(\[.*?\]|\S+)|)$/)
+    end
   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
+    tags = get_user_tags
     # do not expose the administrator tag for admins
-    @property_hash[:tags].reject { |tag| tag == admin_tag }
+    if resource[:admin] == :true
+      tags.delete('administrator')
+    end
+    tags.entries.sort
   end
 
+
   def tags=(tags)
-    @property_flush[:tags] = tags
+    if ! tags.nil?
+      set_user_tags(tags)
+    end
   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
+    if usertags = get_user_tags
+      (:true if usertags.include?('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
+      make_user_admin()
     else
       usertags = get_user_tags
       usertags.delete('administrator')
@@ -105,25 +100,27 @@ Puppet::Type.type(:rabbitmq_user).provide(
     end
   end
 
-  def admin
-    @property_hash[:tags].include?(admin_tag) ? :true : :false
-  end
-
-  def admin=(state)
-    @property_flush[:admin] = state
+  def set_user_tags(tags)
+    is_admin = get_user_tags().member?("administrator") \
+               || resource[:admin] == :true
+    usertags = Set.new(tags)
+    if is_admin
+      usertags.add("administrator")
+    end
+    rabbitmqctl('set_user_tags', resource[:name], usertags.entries.sort)
   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
+  def make_user_admin
+    usertags = get_user_tags
+    usertags.add('administrator')
+    rabbitmqctl('set_user_tags', resource[:name], usertags.entries.sort)
   end
 
   private
-
-  def admin_tag
-    'administrator'
+  def get_user_tags
+    match = rabbitmqctl('-q', 'list_users').split(/\n/).collect do |line|
+      line.match(/^#{Regexp.escape(resource[:name])}\s+\[(.*?)\]/)
+    end.compact.first
+    Set.new(match[1].split(' ').map{|x| x.gsub(/,$/, '')}) if match
   end
 end