Skip to content

Auth ldap backend #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/puppet/provider/graylog_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def request(method,path,params={})
begin
scheme = api_tls ? 'https' : 'http'

Puppet.debug { "#{method.upcase} request for #{scheme}://#{api_server}:#{api_port}/api/#{path} with params #{params.inspect}" }
#Puppet.debug { "#{method.upcase} request for #{scheme}://#{api_server}:#{api_port}/api/#{path} with params #{params.inspect}" }
Copy link
Member

@smortex smortex Aug 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe delete these debug statements rather than commenting them if they do not help?

(the rest looks good I think, but will be hard to test in CI).

result = HTTParty.send(
method,
"#{scheme}://#{api_server}:#{api_port}/api/#{path}",
Expand All @@ -100,14 +100,14 @@ def request(method,path,params={})
raise
end

Puppet.debug("Got result #{result.body}")
#Puppet.debug("Got result #{result.body}")
end

rescue HTTParty::ResponseError => e
Puppet.send_log(:err, "Got error response #{e.response}")
raise e
end
recursive_nil_to_undef(JSON.parse(result.body)) unless result.nil?
recursive_nil_to_undef(JSON.parse(result.body)) unless result.body.nil? || result.body.empty?
end

# Under Puppet Apply, undef in puppet-lang becomes :undef instead of nil
Expand Down
2 changes: 1 addition & 1 deletion lib/puppet/provider/graylog_api/graylog_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def self.prefetch(resources)
def self.wait_for_api(port, server)
scheme = Puppet::Provider::GraylogAPI.api_tls ? 'https' : 'http'
tls_opts = Puppet::Provider::GraylogAPI.tls_opts
Puppet.debug("Waiting for Graylog API")
#Puppet.debug("Waiting for Graylog API")
with_retries(max_tries: 60, base_sleep_seconds: 1, max_sleep_seconds: 1) do
HTTParty.head("#{scheme}://#{server}:#{port}", **tls_opts)
end
Expand Down
182 changes: 182 additions & 0 deletions lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
require_relative '../graylog_api'

Puppet::Type.type(:graylog_auth_ldap_backend).provide(:graylog_api, parent: Puppet::Provider::GraylogAPI) do

has_feature :activateable

mk_resource_methods

attr_writer :role_cache

attr_accessor :roles_map

def self.instances
if major_version < 4
fail('graylog_auth_ldap_backend type is not supported in Graylog versions older then 4.x')
end

result = get('system/authentication/services/backends')

items = result['backends'].map do |data|
# skip non ldap backends
next unless ['active-directory', 'ldap'].include?(data['config']['type'])
roles = roles_to_names(data['default_roles'])

new(
name: data['description'],
description: data['description'],
ensure: :present,
type: data['config']['type'],
system_user_dn: data['config']['system_user_dn'],
server_address: data['config']['servers'].map { |srv| "#{srv['host']}:#{srv['port']}" },
transport_security: data['config']['transport_security'],
verify_certificates: data['config']['verify_certificates'],
search_base_dn: data['config']['user_search_base'],
search_pattern: data['config']['user_search_pattern'],
name_attribute: data['config']['user_name_attribute'],
full_name_attribute: data['config']['user_full_name_attribute'],
default_roles: roles,
password_is_set: data['config']['system_user_password']['is_set'],
rest_id: data['id'],
)
end
items.compact
end

def self.prefetch(resources)
if major_version < 4
fail('graylog_auth_ldap_backend type is not supported in Graylog versions older then 4.x')
end

backends = instances
resources.keys.each do | name |
if provider = backends.find{ | bcknd | bcknd.name == name }
resources[name].provider = provider
end
end
end

def activated_insync?(current)
current == @resource[:activated]
end

def activate
params = { active_backend: @property_hash[:rest_id] }
post('system/authentication/services/configuration', params)
@property_hash[:activated] = :true
end

def deactivate
# we need to check the active backend each time, since another resource can be (de)activated in the meantime
active_backend_id = get('system/authentication/services/configuration')['configuration']['active_backend']
if !active_backend_id.nil? and @property_hash[:rest_id] == active_backend_id
post('system/authentication/services/configuration', { active_backend: nil })
end
@property_hash[:activated] = :false
end

def activated?
@property_hash[:activated]
end

def activated
active_backend_id = get('system/authentication/services/configuration')['configuration']['active_backend']
@property_hash[:activated] = (!active_backend_id.nil? and @property_hash[:rest_id] == active_backend_id).to_s.to_sym
end

def system_user_password
if @resource[:reset_password] or !@property_hash[:password_is_set]
nil
else
@resource[:system_user_password]
end
end

def flush

data = {
default_roles: self.class.roles_to_ids(@resource[:default_roles]),
description: @resource[:description],
title: @resource[:type] == :ldap ? 'LDAP' : 'Active Directory',
config: {
type: @resource[:type],
servers: @resource[:server_address].map { |uri|
a=uri.split(':')
{
host: a[0],
port: a[1],
}
},
transport_security: @resource[:transport_security],
verify_certificates: @resource[:verify_certificates],
system_user_dn: @resource[:system_user_dn],
user_search_base: @resource[:search_base_dn],
user_search_pattern: @resource[:search_pattern],
user_full_name_attribute: @resource[:full_name_attribute],
user_name_attribute: @resource[:name_attribute],
system_user_password: @resource[:system_user_password],
}
}

if @action == :destroy
# we cannot remove an active backend, so we deactivate it first
deactivate
end

if @action.nil? and type != @initial_params[:type]
# the type cannot be changed, so we remove backend first, and then create a new one
# needs to be deactivated before removal
if activated? == :true
deactivate
end
delete("system/authentication/services/backends/#{rest_id}")
response = post('system/authentication/services/backends', data)
set_rest_id_on_create(response) if respond_to?(:set_rest_id_on_create)
# and set it activated after recreation if needed
if @resource[:activated] == :true
@property_hash[:rest_id] = @rest_id
activate
end
else
simple_flush('system/authentication/services/backends', data)
if @action == :create and @resource[:activated]
# new created backends should be activated after initial creation if needed
@property_hash[:rest_id] = @rest_id
activate
end
end
end

def set_rest_id_on_create(response)
@rest_id = response['backend']['id']
end

def self.map_roles(list, key)
if !@map_roles
@map_roles = {}
get('authz/roles')['roles'].each do |role|
@map_roles[role['id']] = role['name']
end
end

result = []
list.each do |val|
if key == :name
result << @map_roles[val]
else
result << @map_roles.key(val)
end
end

result
end

def self.roles_to_names(list)
map_roles(list, :name)
end

def self.roles_to_ids(list)
map_roles(list, :id)
end

end
8 changes: 4 additions & 4 deletions lib/puppet/provider/graylog_dashboard/graylog_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ def self.instances
end

def need_to_purge_widgets?
Puppet.debug("Purge: #{resource[:purge]}")
Puppet.debug("Widgets to Purge: #{widgets_to_purge}")
#Puppet.debug("Purge: #{resource[:purge]}")
#Puppet.debug("Widgets to Purge: #{widgets_to_purge}")
resource[:purge] && widgets_to_purge.any?
end

Expand All @@ -44,7 +44,7 @@ def flush
title: resource[:name],
description: resource[:description],
})
Puppet.debug("@action = '#{@action}'")
#Puppet.debug("@action = '#{@action}'")
if @action.nil? && resource[:purge]
widgets_to_purge.each do |widget|
Puppet.notice("Purging widget '#{widget[:name]}' from Dashboard #{resource[:name]}.")
Expand All @@ -53,4 +53,4 @@ def flush
end
end

end
end
6 changes: 3 additions & 3 deletions lib/puppet/provider/graylog_dashboard_layout/graylog_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

def self.instances
dashboards = get('dashboards')['dashboards']

dashboards.map do |dashboard|
dashboard_name = dashboard['title']
widgets_data = dashboard['widgets']
Expand All @@ -26,7 +26,7 @@ def self.instances
}
end

Puppet.debug("Final Layout for '#{dashboard_name}': #{positions.inspect}")
#Puppet.debug("Final Layout for '#{dashboard_name}': #{positions.inspect}")

new(
name: dashboard_name,
Expand All @@ -53,4 +53,4 @@ def flush

put("dashboards/#{dashboard_id}/positions",{positions: positions_data})
end
end
end
4 changes: 2 additions & 2 deletions lib/puppet/provider/graylog_stream/graylog_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def self.instances
end

def self.index_set_prefix_from_id(index_set_id)
get("system/indices/index_sets/#{index_set_id}")['prefix']
get("system/indices/index_sets/#{index_set_id}")['index_prefix']
end

RULE_TYPES = %w{equals matches greater_than less_than field_presence contain always_match}
Expand Down Expand Up @@ -99,4 +99,4 @@ def index_set_id_from_prefix(index_set_prefix)
index_set['id']
end

end
end
25 changes: 21 additions & 4 deletions lib/puppet/provider/graylog_user/graylog_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,30 @@ def self.instances
results = get('users')
items = results['users'].map do |data|
next if data['username'] == 'admin' || data['external'] == true
new(
user = new(
ensure: :present,
name: data['username'],
full_name: data['full_name'],
email: data['email'],
roles: data['roles'],
permissions: data['permissions'],
timezone: data['timezone'],
session_timeout_ms: data['session_timeout_ms'],
startpage: data['startpage']
)
if major_version < 4
user.full_name = data['full_name']
else
user.first_name = data['first_name']
user.last_name = data['last_name']
end

user
end
items.compact
end

def flush
params = {
full_name: resource[:full_name],
email: resource[:email],
timezone: resource[:timezone],
session_timeout_ms: resource[:session_timeout_ms],
Expand All @@ -34,6 +40,17 @@ def flush
roles: resource[:roles]
}

if major_version < 4
params = params.merge({
full_name: resource[:full_name],
})
else
params = params.merge({
first_name: resource[:first_name],
last_name: resource[:last_name],
})
end

if @action
simple_flush('users', params.merge({
username: resource[:name],
Expand All @@ -44,4 +61,4 @@ def flush
end
end

end
end
Loading