files/gitlab-cookbooks/patroni/libraries/patroni_helper.rb (91 lines of code) (raw):
class PatroniHelper < BaseHelper
include ShellOutHelper
DCS_ATTRIBUTES ||= %w(loop_wait ttl retry_timeout maximum_lag_on_failover max_timelines_history master_start_timeout).freeze
DCS_POSTGRESQL_ATTRIBUTES ||= %w(use_pg_rewind use_slots).freeze
attr_reader :node
def ctl_command
"#{node['package']['install-dir']}/embedded/bin/patronictl"
end
def service_name
'patroni'
end
def running?
OmnibusHelper.new(node).service_up?(service_name)
end
def bootstrapped?
File.exist?(File.join(node['postgresql']['dir'], 'data', 'patroni.dynamic.json'))
end
def scope
node['patroni']['scope']
end
def node_status
return 'not running' unless running?
cmd = "#{ctl_command} -c #{node['patroni']['dir']}/patroni.yaml list | grep #{node.name} | cut -d '|' -f 5"
do_shell_out(cmd).stdout.chomp.strip
end
def use_tls?
!!(node['patroni']['tls_certificate_file'] && node['patroni']['tls_key_file'])
end
def verify_client?
!!(node['patroni']['tls_client_mode'] && node['patroni']['tls_client_mode'] != 'none')
end
def dynamic_settings(pg_helper)
dcs = {
'postgresql' => {
'parameters' => {}
},
'slots' => {}
}
DCS_ATTRIBUTES.each do |key|
dcs[key] = node['patroni'][key]
end
DCS_POSTGRESQL_ATTRIBUTES.each do |key|
dcs['postgresql'][key] = node['patroni'][key]
end
node['patroni']['postgresql'].each do |key, value|
dcs['postgresql']['parameters'][key] = value
end
# work around to support PG12 and PG13 concurrently
if (pg_helper.database_version || pg_helper.version).major.to_i >= 13
dcs['postgresql']['parameters'].delete('wal_keep_segments')
else
dcs['postgresql']['parameters'].delete('wal_keep_size')
end
node['patroni']['replication_slots'].each do |slot_name, options|
dcs['slots'][slot_name] = parse_replication_slots_options(options)
end
if node['patroni']['standby_cluster']['enable']
dcs['standby_cluster'] = {}
node['patroni']['standby_cluster'].each do |key, value|
next if key == 'enable'
dcs['standby_cluster'][key] = value
end
end
dcs
end
def public_attributes
return {} unless node['patroni']['enable']
attributes = {
'config_dir' => node['patroni']['dir'],
'data_dir' => File.join(node['patroni']['dir'], 'data'),
'log_dir' => node['patroni']['log_directory'],
'api_address' => "#{use_tls? ? 'https' : 'http'}://#{node['patroni']['connect_address'] || '127.0.0.1'}:#{node['patroni']['port']}"
}
attributes.merge!(
'tls_verify' => node['patroni']['tls_verify'],
'ca_file' => node['patroni']['tls_ca_file'],
'verify_client' => verify_client?,
'client_cert' => node['patroni']['tls_client_certificate_file'],
'client_key' => node['patroni']['tls_client_key_file']
) if use_tls?
{
'patroni' => attributes.compact
}
end
private
# Parse replication slots attributes
#
# We currently support only physical replication
def parse_replication_slots_options(options)
return unless options['type'] == 'physical'
{
'type' => 'physical'
}
end
end