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 (129 lines) | stat: -rw-r--r-- 3,360 bytes parent folder | download
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