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 130 131
|
# frozen_string_literal: true
# Parent provider for Elasticsearch Shield/X-Pack file-based user management
# tools.
class Puppet::Provider::ElasticUserCommand < Puppet::Provider
attr_accessor :homedir
# Elasticsearch's home directory.
#
# @return String
def self.homedir
@homedir ||= case Facter.value('osfamily')
when 'OpenBSD'
'/usr/local/elasticsearch'
else
'/usr/share/elasticsearch'
end
end
# Run the user management command with specified tool arguments.
def self.command_with_path(args, configdir = nil)
options = {
combine: true,
custom_environment: {
'ES_PATH_CONF' => configdir || '/etc/elasticsearch'
},
failonfail: true
}
execute(
[command(:users_cli)] + (args.is_a?(Array) ? args : [args]),
options
)
end
# Gather local file-based users into an array of Hash objects.
def self.fetch_users
begin
output = command_with_path('list')
rescue Puppet::ExecutionFailure => e
debug("#fetch_users had an error: #{e.inspect}")
return nil
end
debug("Raw command output: #{output}")
matching_lines = output.split("\n").select do |u|
# Keep only expected "user : role1,role2" formatted lines
u[%r{^[^:]+:\s+\S+$}]
end
users = matching_lines.map do |u|
# Break into ["user ", " role1,role2"]
u.split(':').first.strip
end
users.map do |user|
{
name: user,
ensure: :present,
provider: name
}
end
end
# Fetch an array of provider objects from the the list of local users.
def self.instances
fetch_users.map do |user|
new user
end
end
# Generic prefetch boilerplate.
def self.prefetch(resources)
instances.each do |prov|
if (resource = resources[prov.name])
resource.provider = prov
end
end
end
def initialize(value = {})
super(value)
@property_flush = {}
end
# Enforce the desired state for this user on-disk.
def flush
arguments = []
case @property_flush[:ensure]
when :absent
arguments << 'userdel'
arguments << resource[:name]
else
arguments << 'useradd'
arguments << resource[:name]
arguments << '-p' << resource[:password]
end
self.class.command_with_path(arguments, resource[:configdir])
@property_hash = self.class.fetch_users.find do |u|
u[:name] == resource[:name]
end
end
# Set this provider's `:ensure` property to `:present`.
def create
@property_flush[:ensure] = :present
end
def exists?
@property_hash[:ensure] == :present
end
# Set this provider's `:ensure` property to `:absent`.
def destroy
@property_flush[:ensure] = :absent
end
# Manually set this user's password.
def passwd
self.class.command_with_path(
[
'passwd',
resource[:name],
'-p', resource[:password]
],
resource[:configdir]
)
end
end
|