File: rabbitmqctl.rb

package info (click to toggle)
puppet-module-puppetlabs-rabbitmq 8.5.0-10
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,192 kB
  • sloc: ruby: 5,227; sh: 10; makefile: 4
file content (125 lines) | stat: -rw-r--r-- 3,255 bytes parent folder | download | duplicates (4)
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
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

    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
      )
    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