From f391a19dfa381929d671c8c39eef7930c10eb116 Mon Sep 17 00:00:00 2001 From: Johan De Wit Date: Tue, 29 Nov 2022 14:18:06 +0100 Subject: [PATCH 1/7] add system autentication ldap backend --- lib/puppet/provider/graylog_api.rb | 2 +- .../graylog_auth_ldap_backend/graylog_api.rb | 159 ++++++++++++++++++ .../provider/graylog_user/graylog_api.rb | 25 ++- lib/puppet/type/graylog_auth_ldap_backend.rb | 134 +++++++++++++++ lib/puppet/type/graylog_user.rb | 32 ++-- 5 files changed, 336 insertions(+), 16 deletions(-) create mode 100644 lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb create mode 100644 lib/puppet/type/graylog_auth_ldap_backend.rb diff --git a/lib/puppet/provider/graylog_api.rb b/lib/puppet/provider/graylog_api.rb index 7b76785..6a8e41c 100644 --- a/lib/puppet/provider/graylog_api.rb +++ b/lib/puppet/provider/graylog_api.rb @@ -107,7 +107,7 @@ def request(method,path,params={}) 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 diff --git a/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb b/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb new file mode 100644 index 0000000..af2f974 --- /dev/null +++ b/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb @@ -0,0 +1,159 @@ +require_relative '../graylog_api' + +Puppet::Type.type(:graylog_auth_ldap_backend).provide(:graylog_api, parent: Puppet::Provider::GraylogAPI) do + + mk_resource_methods + + attr_writer :role_cache + + attr_accessor :active_backend_id + attr_accessor :roles_map + + def self.instances + if major_version < 4 + fail('graylog_oauth_ldap_bckend type is not supported in Graylog versions older then 4.x') + end + + get_active_backend_id + 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']) + su_password = @resource[:system_user_password] if (data['config']['system_user_password']['is_set'] and !@resource[:reset_password]) + + new( + name: data['description'], + description: data['description'], + ensure: :present, + enabled: data['id'] == @active_backend_id, + 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'], + system_user_password: su_password, + rest_id: data['id'], + ) + end + items.compact + end + + def flush + Puppet.debug("THE RESOURCE contains #{resource.methods}") + active_backend_id = self.class.get_active_backend_id + roles = self.class.roles_to_ids(resource[:default_roles]) + Puppet.send_log(:info, "FLUSH: PUPPET: #{resource[:description]}: #{resource[:default_roles]}") + Puppet.send_log(:info, "FLUSH: TO GRAYLOG: #{resource[:description]}: #{roles}") + data = { + default_roles: 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], + } + } + + #Puppet.debug("Reset password?: #{@resource[:reset_password]}") + #if resource[:reset_password] or not password_is_set + # Puppet.debug("THE PASSWORD NEEDS TO BE SET (action = #{@action} - forced_reset: #{@resource[:reset_password]} - pw set: #{password_is_set}") + # data[:config] = data[:config].merge({ + # system_user_password: resource[:system_user_password], + # }) + #end + + if @action == :destroy and rest_id.eql? active_backend_id + # we need to deactivate this backend before removal. Otherwise we get the following error: + # {"type":"ApiError","message":"Authentication service backend <638a2eeca065b64a660fb724> is still in use"} + post('system/authentication/services/configuration', {active_backend: nil}) + end + simple_flush('system/authentication/services/backends', data) + + if @action != :create + params = nil + if resource[:enabled] and @action != :destroy + # Only one active backend is allowed. When multiple resources have enabled => true + # the last one in the catlogue will be the active one. + # When an activa backend is removed, this will also deactivate that backend. This could lead + # to no active backends. + # When enabled => false, we set the active backend to 'null', but only if it is the active backend + # We cannot ganrantuee that we have an active backend, by the nature of the api calls. + if rest_id != active_backend_id + params = { + active_backend: rest_id + } + Puppet.send_log(:info, "FLUSH: GRAYLOG: Activating ldap backend with id: #{rest_id}") + end + else + if rest_id == active_backend_id + params = { + active_backend: nil + } + Puppet.send_log(:info, "FLUSH: GRAYLOG: Deactivating ldap backend with id: #{rest_id}") + end + end + + if params + post('system/authentication/services/configuration', params) + end + end + end + + def self.get_active_backend_id + @active_backend_id = get('system/authentication/services/configuration')['configuration']['active_backend'] + 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 diff --git a/lib/puppet/provider/graylog_user/graylog_api.rb b/lib/puppet/provider/graylog_user/graylog_api.rb index 64b4bdb..0310181 100644 --- a/lib/puppet/provider/graylog_user/graylog_api.rb +++ b/lib/puppet/provider/graylog_user/graylog_api.rb @@ -8,10 +8,9 @@ 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'], @@ -19,13 +18,20 @@ def self.instances 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], @@ -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], @@ -44,4 +61,4 @@ def flush end end -end \ No newline at end of file +end diff --git a/lib/puppet/type/graylog_auth_ldap_backend.rb b/lib/puppet/type/graylog_auth_ldap_backend.rb new file mode 100644 index 0000000..933988b --- /dev/null +++ b/lib/puppet/type/graylog_auth_ldap_backend.rb @@ -0,0 +1,134 @@ +require 'puppet/property/boolean' + +Puppet::Type.newtype(:graylog_auth_ldap_backend) do + + desc <<-END_OF_DOC + @summary Configures ldap system authentication backend. + + Configures ldap system authentication backends, including the mapping mapping of users + and Graylog Roles. Any custom graylog_role type should also be configured. + + @see graylog_role + + @example + graylog_auth_ldap_backend{ 'company ldap': + ensure => present, + enabled => true, + type => 'ldap', + system_user_dn => 'CN=Graylog,OU=ServiceAccounts,DC=example,DC=com', + system_user_password => $password, + reset_password => false, + server_address => ['ldap://1.2.3.4:389/'], + transport_security => 'none', + verify_certificates => false, + search_base_dn => 'OU=People,DC=example,DC=com', + search_pattern => '(&(objectClass=person)(uid={0}))', + name_attribute => 'userPrincipalName', + full_name_attribute => 'displayName', + default_roles => ['Reader'], + } + END_OF_DOC + + ensurable + + newparam(:description) do + desc 'Destinctive name of the authosrisation backend. Will be placed in the description field' + isnamevar + end + + newparam(:reset_password, boolean: true, parent: Puppet::Property::Boolean) do + desc "Whether to reset the password with the value of system_password" + defaultto(false) + end + + newparam(:enabled, boolean: true, parent: Puppet::Property::Boolean) do + desc "Whether to activate this ldap uthentication backend. Only one backend should be enabled" + end + + newproperty(:system_user_dn) do + desc "Username to bind to LDAP server as." + isrequired + end + + newproperty(:system_user_password) do + desc "Password to bind to LDAP server with." + sensitive true + end + + newproperty(:server_address, array_matching: :all) do + desc "List of LDAP servers, consisting of servername and port." + isrequired + end + + newproperty(:transport_security) do + desc "Which transport security to use, can be one of 'none', 'tls', 'start_tls'" + defaultto('tls') + newvalues('none', 'tls', 'start_tls') + end + + newproperty(:verify_certificates, boolean: true, parent: Puppet::Property::Boolean) do + desc "Whether to automatically trust all certificates when using StartTLS or LDAPS." + defaultto(false) + end + + newproperty(:type) do + desc "The type of the authorisation backend, can be one of 'active-directory', 'ldap'" + isrequired + newvalues('ldap', 'active-directory') + end + + newproperty(:search_base_dn) do + desc "The search base for user lookups." + isrequired + end + + newproperty(:search_pattern) do + desc "The LDAP filter for user lookups." + isrequired + end + + newproperty(:default_roles, array_matching: :all) do + desc "The default roles users are mapped to." + defaultto(['Reader']) + end + + newproperty(:name_attribute) do + desc "The attribute for the user display name." + isrequired + end + + newproperty(:full_name_attribute) do + desc "The attribute for full user name." + isrequired + end + + newproperty(:rest_id) do + desc "Read-only rest_id of the ldap authentication backend resource" + + def retrieve + current_value = nil + current_value = @resource.rest_id if @resource.rest_id + end + + validate do |val| + fail "type is read-only" + end + end + + newproperty(:password_is_set, boolean: true, parent: Puppet::Property::Boolean) do + desc "Read-only: flag indicating if a system user password is set or not" + + def retrieve + current_value = false + current_value = @resource.password_is_set if @resource.password_is_set + end + + validate do |val| + fail "type is read-only" + end + end + + autorequire('graylog_api') {'api'} + # is there a way to exclude predefined roles ? + autorequire('graylog_role') { self[:default_roles] } +end diff --git a/lib/puppet/type/graylog_user.rb b/lib/puppet/type/graylog_user.rb index 1f50bc6..846ebda 100644 --- a/lib/puppet/type/graylog_user.rb +++ b/lib/puppet/type/graylog_user.rb @@ -3,29 +3,29 @@ desc <<-END_OF_DOC @summary Creates a internal user - + A user definition. Note that the admin user is built-in an cannot be changed. - + @example graylog_user { 'test': password => 'B1GnbfoNp9PND6ihXfZFjg', full_name => 'Test user', - email => 'foo@bar', + email => 'foo@bar', roles => [ - 'Reader' + 'Reader' ] } END_OF_DOC - + ensurable - + newparam(:name) do - desc 'The name of the user' + desc 'The name of the user' end - + newparam(:password) do desc 'User password' - sensitive + sensitive end newproperty(:email) do @@ -33,10 +33,20 @@ isrequired end + # this proerty is only available in 3.x or older newproperty(:full_name) do desc 'Full name of the user' isrequired - end + end + + # next to ptoperties are onlu available in +4.x + newproperty(:last_name) do + desc 'Last name of the user' + end + + newproperty(:first_name) do + desc 'first name of the user' + end newproperty(:roles, :array_matching => :all) do desc 'User roles' @@ -62,4 +72,4 @@ end autorequire('graylog_api') {'api'} - end \ No newline at end of file + end From 51cd5acc17e18f517cd311d9300d8a1fcfe72b3d Mon Sep 17 00:00:00 2001 From: Johan De Wit Date: Tue, 7 Mar 2023 13:51:24 +0100 Subject: [PATCH 2/7] implement prefetch and flush --- .../graylog_auth_ldap_backend/graylog_api.rb | 107 ++++++++++++------ lib/puppet/type/graylog_auth_ldap_backend.rb | 8 +- 2 files changed, 75 insertions(+), 40 deletions(-) diff --git a/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb b/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb index af2f974..bd288f5 100644 --- a/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb +++ b/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb @@ -9,9 +9,10 @@ attr_accessor :active_backend_id attr_accessor :roles_map + # self.instances used by puppet resource only def self.instances if major_version < 4 - fail('graylog_oauth_ldap_bckend type is not supported in Graylog versions older then 4.x') + fail('graylog_auth_ldap_backend type is not supported in Graylog versions older then 4.x') end get_active_backend_id @@ -21,13 +22,13 @@ def self.instances # skip non ldap backends next unless ['active-directory', 'ldap'].include?(data['config']['type']) roles = roles_to_names(data['default_roles']) - su_password = @resource[:system_user_password] if (data['config']['system_user_password']['is_set'] and !@resource[:reset_password]) - new( + # initializes the @property_hash + data = new( name: data['description'], description: data['description'], ensure: :present, - enabled: data['id'] == @active_backend_id, + enabled: data['id'] == get_active_backend_id, type: data['config']['type'], system_user_dn: data['config']['system_user_dn'], server_address: data['config']['servers'].map { |srv| "#{srv['host']}:#{srv['port']}" }, @@ -39,51 +40,85 @@ def self.instances full_name_attribute: data['config']['user_full_name_attribute'], default_roles: roles, password_is_set: data['config']['system_user_password']['is_set'], - system_user_password: su_password, rest_id: data['id'], ) + data end + #Puppet.debug("self.instances: #{items[0].methods}") + #Puppet.debug("self.instances: #{items[0].pretty_print_instance_variables}") + #Puppet.debug("self.instances: #{items[0].initial_params}") + #Puppet.debug("self.instances: #{@property_hash}") items.compact end + # and self.prefetch used by puppet apply and agent + # resources parameter is + 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 + + # get all instances found on the system + backends = instances + resources.keys.each do | name | + if provider = backends.find{ | bcknd | bcknd.name == name } + Puppet.debug("Prefetching graylog_api resources for graylog_auth_ldap_backend[#{name}]") + resources[name].provider = provider + #Puppet.debug("self.prefetch: #{resources[name].methods}") + #Puppet.debug("self.prefetch: #{resources[name].pretty_print_instance_variables}") + #Puppet.debug("self.prefetch: #{resources[name].original_parameters}") + #Puppet.debug("self.prefetch: #{resources[name].managed}") + end + end + end + + #def enabled + #Puppet.debug("In enabled prop -> setting to #{@resource[:enabled] and @active_backend_id == @resource[:rest_id]}") + #@property_hash[:enabled] = @resource[:enabled] and @active_backend_id == @resource[:rest_id] + #end + + def system_user_password + Puppet.debug("system_user_pasword getter: #{@resource}") + Puppet.debug("system_user_pasword getter: #{@property_hash}") + if @resource[:reset_password] or !@property_hash[:password_is_set] + @property_hash[:system_user_password] = nil + else + @property_hash[:system_user_password] = @resource[:system_user_password] + end + end + def flush - Puppet.debug("THE RESOURCE contains #{resource.methods}") - active_backend_id = self.class.get_active_backend_id - roles = self.class.roles_to_ids(resource[:default_roles]) - Puppet.send_log(:info, "FLUSH: PUPPET: #{resource[:description]}: #{resource[:default_roles]}") - Puppet.send_log(:info, "FLUSH: TO GRAYLOG: #{resource[:description]}: #{roles}") + Puppet.debug("Flushing graylog_api resources for graylog_auth_ldap_backend with properties: #{@property_hash}") + # we translate the resource properties to the api call data struct + # data = { - default_roles: roles, - description: resource[:description], - title: resource[:type] == 'ldap' ? 'LDAP' : 'Active Directory', + default_roles: self.class.roles_to_ids(@property_hash[:default_roles]), + description: @property_hash[:description], + title: @property_hash[:type] == 'ldap' ? 'LDAP' : 'Active Directory', config: { - type: resource[:type], - servers: resource[:server_address].map { |uri| + type: @property_hash[:type], + servers: @property_hash[: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], + transport_security: @property_hash[:transport_security], + verify_certificates: @property_hash[:verify_certificates], + system_user_dn: @property_hash[:system_user_dn], + user_search_base: @property_hash[:search_base_dn], + user_search_pattern: @property_hash[:search_pattern], + user_full_name_attribute: @property_hash[:full_name_attribute], + user_name_attribute: @property_hash[:name_attribute], + system_user_password: @property_hash[:system_user_password], } } - #Puppet.debug("Reset password?: #{@resource[:reset_password]}") - #if resource[:reset_password] or not password_is_set - # Puppet.debug("THE PASSWORD NEEDS TO BE SET (action = #{@action} - forced_reset: #{@resource[:reset_password]} - pw set: #{password_is_set}") - # data[:config] = data[:config].merge({ - # system_user_password: resource[:system_user_password], - # }) - #end + Puppet.debug("The data set before flusing #{data}") + Puppet.debug("@action => #{@action} - @resource[:enabled] => #{@resource[:enabled]} - @property_hash[:enabled] => #{@property_hash[:enabled]}") - if @action == :destroy and rest_id.eql? active_backend_id + if @action == :destroy and @property_hash[:rest_id].eql? @active_backend_id # we need to deactivate this backend before removal. Otherwise we get the following error: # {"type":"ApiError","message":"Authentication service backend <638a2eeca065b64a660fb724> is still in use"} post('system/authentication/services/configuration', {active_backend: nil}) @@ -92,25 +127,25 @@ def flush if @action != :create params = nil - if resource[:enabled] and @action != :destroy + if @property_hash[:enabled] and @action != :destroy # Only one active backend is allowed. When multiple resources have enabled => true # the last one in the catlogue will be the active one. # When an activa backend is removed, this will also deactivate that backend. This could lead # to no active backends. # When enabled => false, we set the active backend to 'null', but only if it is the active backend # We cannot ganrantuee that we have an active backend, by the nature of the api calls. - if rest_id != active_backend_id + if @property_hash[:rest_id] != @active_backend_id params = { - active_backend: rest_id + active_backend: @property_hash[:rest_id] } - Puppet.send_log(:info, "FLUSH: GRAYLOG: Activating ldap backend with id: #{rest_id}") + Puppet.send_log(:info, "FLUSH: GRAYLOG: Activating ldap backend with id: #{@property_hash[:rest_id]}") end else - if rest_id == active_backend_id + if @property_hash[:rest_id] == @active_backend_id params = { active_backend: nil } - Puppet.send_log(:info, "FLUSH: GRAYLOG: Deactivating ldap backend with id: #{rest_id}") + Puppet.send_log(:info, "FLUSH: GRAYLOG: Deactivating ldap backend with id: #{@property_hash[:rest_id]}") end end diff --git a/lib/puppet/type/graylog_auth_ldap_backend.rb b/lib/puppet/type/graylog_auth_ldap_backend.rb index 933988b..95404eb 100644 --- a/lib/puppet/type/graylog_auth_ldap_backend.rb +++ b/lib/puppet/type/graylog_auth_ldap_backend.rb @@ -42,7 +42,7 @@ end newparam(:enabled, boolean: true, parent: Puppet::Property::Boolean) do - desc "Whether to activate this ldap uthentication backend. Only one backend should be enabled" + desc "Whether to activate this ldap authentication backend. Only one backend should be enabled" end newproperty(:system_user_dn) do @@ -50,7 +50,7 @@ isrequired end - newproperty(:system_user_password) do + newparam(:system_user_password) do desc "Password to bind to LDAP server with." sensitive true end @@ -102,7 +102,7 @@ isrequired end - newproperty(:rest_id) do + newparam(:rest_id) do desc "Read-only rest_id of the ldap authentication backend resource" def retrieve @@ -115,7 +115,7 @@ def retrieve end end - newproperty(:password_is_set, boolean: true, parent: Puppet::Property::Boolean) do + newparam(:password_is_set, boolean: true, parent: Puppet::Property::Boolean) do desc "Read-only: flag indicating if a system user password is set or not" def retrieve From 57fcdb66efc9d647f307c5727028302a21a44679 Mon Sep 17 00:00:00 2001 From: Johan De Wit Date: Thu, 9 Mar 2023 15:03:20 +0100 Subject: [PATCH 3/7] diable debug to reduce output --- lib/puppet/provider/graylog_api.rb | 4 +- .../provider/graylog_api/graylog_api.rb | 2 +- .../graylog_auth_ldap_backend/graylog_api.rb | 100 +++++++++++------- .../provider/graylog_dashboard/graylog_api.rb | 8 +- .../graylog_dashboard_layout/graylog_api.rb | 6 +- lib/puppet/type/graylog_auth_ldap_backend.rb | 9 +- 6 files changed, 74 insertions(+), 55 deletions(-) diff --git a/lib/puppet/provider/graylog_api.rb b/lib/puppet/provider/graylog_api.rb index 6a8e41c..87851ff 100644 --- a/lib/puppet/provider/graylog_api.rb +++ b/lib/puppet/provider/graylog_api.rb @@ -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}" } result = HTTParty.send( method, "#{scheme}://#{api_server}:#{api_port}/api/#{path}", @@ -100,7 +100,7 @@ def request(method,path,params={}) raise end - Puppet.debug("Got result #{result.body}") + #Puppet.debug("Got result #{result.body}") end rescue HTTParty::ResponseError => e diff --git a/lib/puppet/provider/graylog_api/graylog_api.rb b/lib/puppet/provider/graylog_api/graylog_api.rb index 1e8af35..3a84f37 100644 --- a/lib/puppet/provider/graylog_api/graylog_api.rb +++ b/lib/puppet/provider/graylog_api/graylog_api.rb @@ -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 diff --git a/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb b/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb index bd288f5..ec0441c 100644 --- a/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb +++ b/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb @@ -6,29 +6,41 @@ attr_writer :role_cache - attr_accessor :active_backend_id attr_accessor :roles_map + @active_backend_id = nil + + def self.active_backend_id + @active_backend_id + end + + def self.active_backend_id=(value) + @active_backend_id = value + end + # self.instances used by puppet resource only def self.instances if major_version < 4 fail('graylog_auth_ldap_backend type is not supported in Graylog versions older then 4.x') end - get_active_backend_id result = get('system/authentication/services/backends') + self.get_active_backend_id 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']) + Puppet.debug("In instances: data[id] = #{data['id']} and backend = #{@active_backend_id}") + #Puppet.debug("In instances: data[id] = #{data['id']} and backend = #{@active_backend_id.nil?}") + Puppet.debug("In instances: enabled: #{(!@active_backend_id.nil? and data['id'] == @active_backend_id)}") # initializes the @property_hash - data = new( + new( name: data['description'], description: data['description'], ensure: :present, - enabled: data['id'] == get_active_backend_id, + enabled: (!@active_backend_id.nil? and data['id'] == @active_backend_id), type: data['config']['type'], system_user_dn: data['config']['system_user_dn'], server_address: data['config']['servers'].map { |srv| "#{srv['host']}:#{srv['port']}" }, @@ -42,17 +54,11 @@ def self.instances password_is_set: data['config']['system_user_password']['is_set'], rest_id: data['id'], ) - data end - #Puppet.debug("self.instances: #{items[0].methods}") - #Puppet.debug("self.instances: #{items[0].pretty_print_instance_variables}") - #Puppet.debug("self.instances: #{items[0].initial_params}") - #Puppet.debug("self.instances: #{@property_hash}") items.compact end # and self.prefetch used by puppet apply and agent - # resources parameter is def self.prefetch(resources) if major_version < 4 fail('graylog_auth_ldap_backend type is not supported in Graylog versions older then 4.x') @@ -62,61 +68,68 @@ def self.prefetch(resources) backends = instances resources.keys.each do | name | if provider = backends.find{ | bcknd | bcknd.name == name } - Puppet.debug("Prefetching graylog_api resources for graylog_auth_ldap_backend[#{name}]") resources[name].provider = provider - #Puppet.debug("self.prefetch: #{resources[name].methods}") - #Puppet.debug("self.prefetch: #{resources[name].pretty_print_instance_variables}") - #Puppet.debug("self.prefetch: #{resources[name].original_parameters}") - #Puppet.debug("self.prefetch: #{resources[name].managed}") end end end - #def enabled - #Puppet.debug("In enabled prop -> setting to #{@resource[:enabled] and @active_backend_id == @resource[:rest_id]}") - #@property_hash[:enabled] = @resource[:enabled] and @active_backend_id == @resource[:rest_id] - #end +# def enabled +# active_id = get('system/authentication/services/configuration')['configuration']['active_backend'] +# e = !active_id.nil? and @resource['rest_id'] == active_id +# Puppet.debug("In enabled getter: returning #{e}") +# Puppet.debug("In enabled getter: @active_id #{active_id}i and @active_backend_id = #{self.active_backend_id}") +# Puppet.debug("and the resource in catlogue sets enable to #{resource[:enabled]}") +# @property_hash[:enabled] = !active_id.nil? and @resource['rest_id'] == active_id +# Puppet.debug("and the resource_hash is #{@resource.to_hash}") +# Puppet.debug("and the property-hash is #{@property_hash}") +# e +# end def system_user_password - Puppet.debug("system_user_pasword getter: #{@resource}") - Puppet.debug("system_user_pasword getter: #{@property_hash}") + Puppet.debug("In getter System_User_Password resource is #{@resource.to_hash}") + Puppet.debug("In getter System_User_Password property_hash is #{@property_hash}") + Puppet.debug("In getter System_User_Password") if @resource[:reset_password] or !@property_hash[:password_is_set] - @property_hash[:system_user_password] = nil + nil else - @property_hash[:system_user_password] = @resource[:system_user_password] + @resource[:system_user_password] end end def flush Puppet.debug("Flushing graylog_api resources for graylog_auth_ldap_backend with properties: #{@property_hash}") + Puppet.debug("Flushing graylog_api resources for graylog_auth_ldap_backend with catalogue data: #{@resource.to_hash}") + Puppet.debug("In Flush: active backend = #{@active_backend_id}") + #Puppet.debug("Flushing graylog_api resources for graylog_auth_ldap_backend with methods: #{@resource.methods}") # we translate the resource properties to the api call data struct # + data = { - default_roles: self.class.roles_to_ids(@property_hash[:default_roles]), - description: @property_hash[:description], - title: @property_hash[:type] == 'ldap' ? 'LDAP' : 'Active Directory', + default_roles: self.class.roles_to_ids(@resource[:default_roles]), + description: @resource[:description], + title: @resource[:type] == 'ldap' ? 'LDAP' : 'Active Directory', config: { - type: @property_hash[:type], - servers: @property_hash[:server_address].map { |uri| + type: @resource[:type], + servers: @resource[:server_address].map { |uri| a=uri.split(':') { host: a[0], port: a[1], } }, - transport_security: @property_hash[:transport_security], - verify_certificates: @property_hash[:verify_certificates], - system_user_dn: @property_hash[:system_user_dn], - user_search_base: @property_hash[:search_base_dn], - user_search_pattern: @property_hash[:search_pattern], - user_full_name_attribute: @property_hash[:full_name_attribute], - user_name_attribute: @property_hash[:name_attribute], - system_user_password: @property_hash[:system_user_password], + 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], } } - Puppet.debug("The data set before flusing #{data}") - Puppet.debug("@action => #{@action} - @resource[:enabled] => #{@resource[:enabled]} - @property_hash[:enabled] => #{@property_hash[:enabled]}") + Puppet.debug("In FLUSH: rest_id = #{@property_hash[:rest_id]} and backend = #{@active_backend_id.nil?}") + Puppet.debug("@action => #{@action} - @resource[:enabled] => #{@resource[:enabled]} - @property_hash[:enabled] => #{@property_hash[:enabled]} - Active_backend = #{@active_backend_id}") if @action == :destroy and @property_hash[:rest_id].eql? @active_backend_id # we need to deactivate this backend before removal. Otherwise we get the following error: @@ -127,14 +140,14 @@ def flush if @action != :create params = nil - if @property_hash[:enabled] and @action != :destroy + if @resource[:enabled] and @action != :destroy # Only one active backend is allowed. When multiple resources have enabled => true # the last one in the catlogue will be the active one. # When an activa backend is removed, this will also deactivate that backend. This could lead # to no active backends. # When enabled => false, we set the active backend to 'null', but only if it is the active backend # We cannot ganrantuee that we have an active backend, by the nature of the api calls. - if @property_hash[:rest_id] != @active_backend_id + if @active_backend_id.nil? or @property_hash[:rest_id] != @active_backend_id params = { active_backend: @property_hash[:rest_id] } @@ -156,7 +169,12 @@ def flush end def self.get_active_backend_id - @active_backend_id = get('system/authentication/services/configuration')['configuration']['active_backend'] + if !@active_backend_id + Puppet.debug('In get_active_backend_id - executing Api Call') + @active_backend_id = get('system/authentication/services/configuration')['configuration']['active_backend'] + end + Puppet.debug("In get_active_backend_id - Api Call result #{@active_backend_id}") + @active_backend_id end def set_rest_id_on_create(response) diff --git a/lib/puppet/provider/graylog_dashboard/graylog_api.rb b/lib/puppet/provider/graylog_dashboard/graylog_api.rb index 8213a90..72c1846 100644 --- a/lib/puppet/provider/graylog_dashboard/graylog_api.rb +++ b/lib/puppet/provider/graylog_dashboard/graylog_api.rb @@ -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 @@ -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]}.") @@ -53,4 +53,4 @@ def flush end end -end \ No newline at end of file +end diff --git a/lib/puppet/provider/graylog_dashboard_layout/graylog_api.rb b/lib/puppet/provider/graylog_dashboard_layout/graylog_api.rb index f7e73cf..70e88b9 100644 --- a/lib/puppet/provider/graylog_dashboard_layout/graylog_api.rb +++ b/lib/puppet/provider/graylog_dashboard_layout/graylog_api.rb @@ -6,7 +6,7 @@ def self.instances dashboards = get('dashboards')['dashboards'] - + dashboards.map do |dashboard| dashboard_name = dashboard['title'] widgets_data = dashboard['widgets'] @@ -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, @@ -53,4 +53,4 @@ def flush put("dashboards/#{dashboard_id}/positions",{positions: positions_data}) end -end \ No newline at end of file +end diff --git a/lib/puppet/type/graylog_auth_ldap_backend.rb b/lib/puppet/type/graylog_auth_ldap_backend.rb index 95404eb..d2615db 100644 --- a/lib/puppet/type/graylog_auth_ldap_backend.rb +++ b/lib/puppet/type/graylog_auth_ldap_backend.rb @@ -32,17 +32,18 @@ ensurable newparam(:description) do - desc 'Destinctive name of the authosrisation backend. Will be placed in the description field' + desc 'Destinctive name of the authorisation backend. Will be placed in the description field' isnamevar end - newparam(:reset_password, boolean: true, parent: Puppet::Property::Boolean) do + newproperty(:reset_password, boolean: true, parent: Puppet::Property::Boolean) do desc "Whether to reset the password with the value of system_password" defaultto(false) end - newparam(:enabled, boolean: true, parent: Puppet::Property::Boolean) do + newproperty(:enabled, boolean: true, parent: Puppet::Property::Boolean) do desc "Whether to activate this ldap authentication backend. Only one backend should be enabled" + defaultto(false) end newproperty(:system_user_dn) do @@ -50,7 +51,7 @@ isrequired end - newparam(:system_user_password) do + newproperty(:system_user_password) do desc "Password to bind to LDAP server with." sensitive true end From 7c47044224f10a2a78256af99d47ad60d12d16ab Mon Sep 17 00:00:00 2001 From: Johan De Wit Date: Fri, 17 Mar 2023 10:51:24 +0100 Subject: [PATCH 4/7] rename enabled to active --- .../graylog_auth_ldap_backend/graylog_api.rb | 139 +++++++----------- lib/puppet/type/graylog_auth_ldap_backend.rb | 76 +++++++--- 2 files changed, 109 insertions(+), 106 deletions(-) diff --git a/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb b/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb index ec0441c..4cf95fc 100644 --- a/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb +++ b/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb @@ -2,45 +2,32 @@ Puppet::Type.type(:graylog_auth_ldap_backend).provide(:graylog_api, parent: Puppet::Provider::GraylogAPI) do + has_feature :activateable + has_feature :recreatable + mk_resource_methods attr_writer :role_cache attr_accessor :roles_map - @active_backend_id = nil - - def self.active_backend_id - @active_backend_id - end - - def self.active_backend_id=(value) - @active_backend_id = value - end - - # self.instances used by puppet resource only def self.instances + Puppet.debug('In provider 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') - self.get_active_backend_id 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']) - Puppet.debug("In instances: data[id] = #{data['id']} and backend = #{@active_backend_id}") - #Puppet.debug("In instances: data[id] = #{data['id']} and backend = #{@active_backend_id.nil?}") - Puppet.debug("In instances: enabled: #{(!@active_backend_id.nil? and data['id'] == @active_backend_id)}") - # initializes the @property_hash new( name: data['description'], description: data['description'], ensure: :present, - enabled: (!@active_backend_id.nil? and data['id'] == @active_backend_id), type: data['config']['type'], system_user_dn: data['config']['system_user_dn'], server_address: data['config']['servers'].map { |srv| "#{srv['host']}:#{srv['port']}" }, @@ -58,13 +45,11 @@ def self.instances items.compact end - # and self.prefetch used by puppet apply and agent 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 - # get all instances found on the system backends = instances resources.keys.each do | name | if provider = backends.find{ | bcknd | bcknd.name == name } @@ -73,22 +58,35 @@ def self.prefetch(resources) end end -# def enabled -# active_id = get('system/authentication/services/configuration')['configuration']['active_backend'] -# e = !active_id.nil? and @resource['rest_id'] == active_id -# Puppet.debug("In enabled getter: returning #{e}") -# Puppet.debug("In enabled getter: @active_id #{active_id}i and @active_backend_id = #{self.active_backend_id}") -# Puppet.debug("and the resource in catlogue sets enable to #{resource[:enabled]}") -# @property_hash[:enabled] = !active_id.nil? and @resource['rest_id'] == active_id -# Puppet.debug("and the resource_hash is #{@resource.to_hash}") -# Puppet.debug("and the property-hash is #{@property_hash}") -# e -# 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 - Puppet.debug("In getter System_User_Password resource is #{@resource.to_hash}") - Puppet.debug("In getter System_User_Password property_hash is #{@property_hash}") - Puppet.debug("In getter System_User_Password") if @resource[:reset_password] or !@property_hash[:password_is_set] nil else @@ -96,13 +94,30 @@ def system_user_password end end + def type + Puppet.debug('In provider getter type') + @property_hash[:type] + end + + def type_insync?(current) + Puppet.debug('In provider type_insync?') + current == @resource[:type] + end + + def recreate + # whenever the type is switched, we need to remove the old and recreate + # class org.graylog.security.authservice.backend.AutoValue_LDAPAuthServiceBackendConfig cannot be cast to class + # org.graylog.security.authservice.backend.ADAuthServiceBackendConfig + + Puppet.debug('In provider recreate') + end + def flush - Puppet.debug("Flushing graylog_api resources for graylog_auth_ldap_backend with properties: #{@property_hash}") - Puppet.debug("Flushing graylog_api resources for graylog_auth_ldap_backend with catalogue data: #{@resource.to_hash}") - Puppet.debug("In Flush: active backend = #{@active_backend_id}") - #Puppet.debug("Flushing graylog_api resources for graylog_auth_ldap_backend with methods: #{@resource.methods}") - # we translate the resource properties to the api call data struct - # + Puppet.debug('In provider flush') + if @action == :destroy + # we cannot remove an active backend, so we deactivate it first + deactivate + end data = { default_roles: self.class.roles_to_ids(@resource[:default_roles]), @@ -128,53 +143,7 @@ def flush } } - Puppet.debug("In FLUSH: rest_id = #{@property_hash[:rest_id]} and backend = #{@active_backend_id.nil?}") - Puppet.debug("@action => #{@action} - @resource[:enabled] => #{@resource[:enabled]} - @property_hash[:enabled] => #{@property_hash[:enabled]} - Active_backend = #{@active_backend_id}") - - if @action == :destroy and @property_hash[:rest_id].eql? @active_backend_id - # we need to deactivate this backend before removal. Otherwise we get the following error: - # {"type":"ApiError","message":"Authentication service backend <638a2eeca065b64a660fb724> is still in use"} - post('system/authentication/services/configuration', {active_backend: nil}) - end simple_flush('system/authentication/services/backends', data) - - if @action != :create - params = nil - if @resource[:enabled] and @action != :destroy - # Only one active backend is allowed. When multiple resources have enabled => true - # the last one in the catlogue will be the active one. - # When an activa backend is removed, this will also deactivate that backend. This could lead - # to no active backends. - # When enabled => false, we set the active backend to 'null', but only if it is the active backend - # We cannot ganrantuee that we have an active backend, by the nature of the api calls. - if @active_backend_id.nil? or @property_hash[:rest_id] != @active_backend_id - params = { - active_backend: @property_hash[:rest_id] - } - Puppet.send_log(:info, "FLUSH: GRAYLOG: Activating ldap backend with id: #{@property_hash[:rest_id]}") - end - else - if @property_hash[:rest_id] == @active_backend_id - params = { - active_backend: nil - } - Puppet.send_log(:info, "FLUSH: GRAYLOG: Deactivating ldap backend with id: #{@property_hash[:rest_id]}") - end - end - - if params - post('system/authentication/services/configuration', params) - end - end - end - - def self.get_active_backend_id - if !@active_backend_id - Puppet.debug('In get_active_backend_id - executing Api Call') - @active_backend_id = get('system/authentication/services/configuration')['configuration']['active_backend'] - end - Puppet.debug("In get_active_backend_id - Api Call result #{@active_backend_id}") - @active_backend_id end def set_rest_id_on_create(response) diff --git a/lib/puppet/type/graylog_auth_ldap_backend.rb b/lib/puppet/type/graylog_auth_ldap_backend.rb index d2615db..0c3c7a4 100644 --- a/lib/puppet/type/graylog_auth_ldap_backend.rb +++ b/lib/puppet/type/graylog_auth_ldap_backend.rb @@ -3,20 +3,20 @@ Puppet::Type.newtype(:graylog_auth_ldap_backend) do desc <<-END_OF_DOC - @summary Configures ldap system authentication backend. + @summary Configures ldap/active directory system authentication backend. - Configures ldap system authentication backends, including the mapping mapping of users - and Graylog Roles. Any custom graylog_role type should also be configured. + Configures a ldap and/or active directory system authentication backends, including the mapping mapping of users + and Graylog Roles. Any custom graylog_role type should also be managed by puppet. @see graylog_role @example graylog_auth_ldap_backend{ 'company ldap': ensure => present, - enabled => true, + activated => true, type => 'ldap', system_user_dn => 'CN=Graylog,OU=ServiceAccounts,DC=example,DC=com', - system_user_password => $password, + system_user_password => 'secret pasword', reset_password => false, server_address => ['ldap://1.2.3.4:389/'], transport_security => 'none', @@ -29,25 +29,65 @@ } END_OF_DOC + feature :activateable, "The provider can activate and deactivate the backend.", :methods => [:activate, :deactivate, :activated?] + feature :recreateable, "The provider can recreate (remove/create) the backend.", :methods => [:recreate] + ensurable newparam(:description) do - desc 'Destinctive name of the authorisation backend. Will be placed in the description field' + desc 'Distinctive name of the authorisation backend. Will be placed in the description field.' isnamevar end - newproperty(:reset_password, boolean: true, parent: Puppet::Property::Boolean) do - desc "Whether to reset the password with the value of system_password" + newparam(:reset_password, boolean: true, parent: Puppet::Property::Boolean) do + desc "Whether to reset the password with the value of system_password." defaultto(false) end - newproperty(:enabled, boolean: true, parent: Puppet::Property::Boolean) do - desc "Whether to activate this ldap authentication backend. Only one backend should be enabled" - defaultto(false) + newproperty(:type, :required_features => :activateable) do + desc "The type of the authorisation backend, can be one of 'active-directory', 'ldap'" + isrequired + + newvalues('ldap', :event => :backend_recreate) do + Puppet.debug('in type property - value ldap') + provider.recreate + end + + newvalues('active-directory', :event => :backend_recreate) do + Puppet.debug('in type property - value active-directory') + provider.recreate + end + + def insync?(current) + return provider.type_insync?(current) if provider.respond_to?(:type_insync?) + super(current) + end + end + + newproperty(:activated, :required_features => :activateable) do + desc <<-END_OF_DOC + Whether to activate this ldap authentication backend. Only one backend should be enabled. + If multipple backends are activated, the last one applied will win. + END_OF_DOC + + isrequired + + newvalue(:true, :event => :backend_activated) do + provider.activate + end + + newvalue(:false, :event => :backend_deactivated) do + provider.deactivate + end + + def insync?(current) + return provider.activated_insync?(current) if provider.respond_to?(:activated_insync?) + super(current) + end end newproperty(:system_user_dn) do - desc "Username to bind to LDAP server as." + desc "Username to bind to the LDAP server." isrequired end @@ -62,7 +102,7 @@ end newproperty(:transport_security) do - desc "Which transport security to use, can be one of 'none', 'tls', 'start_tls'" + desc "The transport security to use, can be one of 'none', 'tls', 'start_tls'" defaultto('tls') newvalues('none', 'tls', 'start_tls') end @@ -72,12 +112,6 @@ defaultto(false) end - newproperty(:type) do - desc "The type of the authorisation backend, can be one of 'active-directory', 'ldap'" - isrequired - newvalues('ldap', 'active-directory') - end - newproperty(:search_base_dn) do desc "The search base for user lookups." isrequired @@ -104,7 +138,7 @@ end newparam(:rest_id) do - desc "Read-only rest_id of the ldap authentication backend resource" + desc "Read-only rest_id of the ldap authentication backend resource." def retrieve current_value = nil @@ -117,7 +151,7 @@ def retrieve end newparam(:password_is_set, boolean: true, parent: Puppet::Property::Boolean) do - desc "Read-only: flag indicating if a system user password is set or not" + desc "Read-only: flag indicating if the system user password is set or not" def retrieve current_value = false From 64611e026d61ce1ab73fbaba49449c5f047ceba1 Mon Sep 17 00:00:00 2001 From: Johan De Wit Date: Wed, 22 Mar 2023 08:46:13 +0100 Subject: [PATCH 5/7] fixes (de)activation and changing the type of the backend --- .../graylog_auth_ldap_backend/graylog_api.rb | 55 ++++++++++--------- lib/puppet/type/graylog_auth_ldap_backend.rb | 18 +----- 2 files changed, 30 insertions(+), 43 deletions(-) diff --git a/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb b/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb index 4cf95fc..e91b09e 100644 --- a/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb +++ b/lib/puppet/provider/graylog_auth_ldap_backend/graylog_api.rb @@ -3,7 +3,6 @@ Puppet::Type.type(:graylog_auth_ldap_backend).provide(:graylog_api, parent: Puppet::Provider::GraylogAPI) do has_feature :activateable - has_feature :recreatable mk_resource_methods @@ -12,7 +11,6 @@ attr_accessor :roles_map def self.instances - Puppet.debug('In provider self.instances') if major_version < 4 fail('graylog_auth_ldap_backend type is not supported in Graylog versions older then 4.x') end @@ -94,35 +92,12 @@ def system_user_password end end - def type - Puppet.debug('In provider getter type') - @property_hash[:type] - end - - def type_insync?(current) - Puppet.debug('In provider type_insync?') - current == @resource[:type] - end - - def recreate - # whenever the type is switched, we need to remove the old and recreate - # class org.graylog.security.authservice.backend.AutoValue_LDAPAuthServiceBackendConfig cannot be cast to class - # org.graylog.security.authservice.backend.ADAuthServiceBackendConfig - - Puppet.debug('In provider recreate') - end - def flush - Puppet.debug('In provider flush') - if @action == :destroy - # we cannot remove an active backend, so we deactivate it first - deactivate - end data = { default_roles: self.class.roles_to_ids(@resource[:default_roles]), description: @resource[:description], - title: @resource[:type] == 'ldap' ? 'LDAP' : 'Active Directory', + title: @resource[:type] == :ldap ? 'LDAP' : 'Active Directory', config: { type: @resource[:type], servers: @resource[:server_address].map { |uri| @@ -143,7 +118,33 @@ def flush } } - simple_flush('system/authentication/services/backends', data) + 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) diff --git a/lib/puppet/type/graylog_auth_ldap_backend.rb b/lib/puppet/type/graylog_auth_ldap_backend.rb index 0c3c7a4..8cfe015 100644 --- a/lib/puppet/type/graylog_auth_ldap_backend.rb +++ b/lib/puppet/type/graylog_auth_ldap_backend.rb @@ -30,7 +30,6 @@ END_OF_DOC feature :activateable, "The provider can activate and deactivate the backend.", :methods => [:activate, :deactivate, :activated?] - feature :recreateable, "The provider can recreate (remove/create) the backend.", :methods => [:recreate] ensurable @@ -44,24 +43,11 @@ defaultto(false) end - newproperty(:type, :required_features => :activateable) do + newproperty(:type) do desc "The type of the authorisation backend, can be one of 'active-directory', 'ldap'" isrequired - newvalues('ldap', :event => :backend_recreate) do - Puppet.debug('in type property - value ldap') - provider.recreate - end - - newvalues('active-directory', :event => :backend_recreate) do - Puppet.debug('in type property - value active-directory') - provider.recreate - end - - def insync?(current) - return provider.type_insync?(current) if provider.respond_to?(:type_insync?) - super(current) - end + newvalues('ldap', 'active-directory') end newproperty(:activated, :required_features => :activateable) do From 93f8842100a8dd9a7cf6c04e969663c0aa189597 Mon Sep 17 00:00:00 2001 From: Johan De Wit Date: Wed, 2 Aug 2023 09:49:07 +0200 Subject: [PATCH 6/7] add new match option in pipeline stages --- types/pipeline/stage.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/pipeline/stage.pp b/types/pipeline/stage.pp index 499f57a..e7690d9 100644 --- a/types/pipeline/stage.pp +++ b/types/pipeline/stage.pp @@ -1,4 +1,4 @@ type Graylog_api::Pipeline::Stage = Struct[{ - match => Enum['all','either'], + match => Enum['all', 'either', 'pass'], rules => Array[String,1], }] From beddbd674768a175f090147118108aede03c1dd6 Mon Sep 17 00:00:00 2001 From: Johan De Wit Date: Wed, 10 Jan 2024 11:54:41 +0100 Subject: [PATCH 7/7] Update graylog_api.rb Adjust renamed field in struct --- lib/puppet/provider/graylog_stream/graylog_api.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/puppet/provider/graylog_stream/graylog_api.rb b/lib/puppet/provider/graylog_stream/graylog_api.rb index 3860520..bdab1c9 100644 --- a/lib/puppet/provider/graylog_stream/graylog_api.rb +++ b/lib/puppet/provider/graylog_stream/graylog_api.rb @@ -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} @@ -99,4 +99,4 @@ def index_set_id_from_prefix(index_set_prefix) index_set['id'] end -end \ No newline at end of file +end