Commit a48e48ee authored by Ian Baum's avatar Ian Baum
Browse files

Merge branch 'brodock/patroni-standbycluster' into 'master'

Allow bootstrapping patroni Standby Cluster

Closes #5633

See merge request gitlab-org/omnibus-gitlab!4558
parents f30e69d9 19288135
---
title: Allow bootstrapping patroni Standby Cluster
merge_request: 4558
author:
type: added
......@@ -15,8 +15,15 @@ default['patroni']['max_timelines_history'] = 0
default['patroni']['master_start_timeout'] = 300
default['patroni']['use_pg_rewind'] = false
default['patroni']['use_slots'] = true
default['patroni']['replication_password'] = nil
default['patroni']['replication_slots'] = {}
 
# Standby cluster replication settings
default['patroni']['standby_cluster']['enable'] = false
default['patroni']['standby_cluster']['host'] = nil
default['patroni']['standby_cluster']['port'] = 5432
default['patroni']['standby_cluster']['primary_slot_name'] = nil
# Global/Universal settings
default['patroni']['name'] = node.name
default['patroni']['scope'] = 'postgresql-ha'
......
......@@ -63,6 +63,16 @@ class PatroniHelper < BaseHelper
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
 
......
......@@ -20,8 +20,8 @@ postgresql:
username: <%= account_helper.postgresql_user %>
replication:
username: <%= @postgresql_defaults['sql_replication_user'] %>
<% if @postgresql_defaults['sql_replication_password'] %>
password: <%= "md5#{@postgresql_defaults['sql_replication_password']}" %>
<% if @replication_password %>
password: <%= "#{@replication_password}" %>
<% end %>
bootstrap:
dcs: <%= patroni_helper.dynamic_settings.to_json %>
......
require 'chef_helper'
RSpec.describe PatroniHelper do
let(:chef_run) do
ChefSpec::SoloRunner.new(step_into: %w(patroni)).converge('gitlab-ee::default')
end
subject(:helper) { PatroniHelper.new(chef_run.node) }
before do
allow(Gitlab).to receive(:[]).and_call_original
end
describe '#ctl_command' do
it 'returns a full path to the ctl_command' do
expect(helper.ctl_command).to eq('/opt/gitlab/embedded/bin/patronictl')
end
end
describe '#bootstrapped?' do
before do
allow(File).to receive(:exist?).and_call_original
end
it 'returns true when patroni.dynamic.json exists in postgresql data directory' do
allow(File).to receive(:exist?).with('/var/opt/gitlab/postgresql/data/patroni.dynamic.json').and_return(true)
expect(helper.bootstrapped?).to eq(true)
end
it 'returns false when patroni.dynamic.json does not exist in postgresql data directory' do
allow(File).to receive(:exist?).with('/var/opt/gitlab/postgresql/data/patroni.dynamic.json').and_return(false)
expect(helper.bootstrapped?).to eq(false)
end
end
describe '#dynamic_settings' do
it 'returns a hash with required keys' do
expected_root_keys = PatroniHelper::DCS_ATTRIBUTES + %w[postgresql slots]
expect(helper.dynamic_settings.keys).to match_array(expected_root_keys)
end
context 'with standby cluster enabled' do
it 'includes standby cluster attributes' do
stub_gitlab_rb(
patroni: {
enable: true,
standby_cluster: {
enable: true
}
}
)
expected_root_keys = PatroniHelper::DCS_ATTRIBUTES + %w[postgresql slots standby_cluster]
expect(helper.dynamic_settings.keys).to match_array(expected_root_keys)
end
end
end
describe '#public_attributes' do
context 'when patroni is enabled' do
it 'returns a hash with required keys' do
stub_gitlab_rb(
patroni: {
enable: true
}
)
expected_patroni_keys = %w(config_dir data_dir log_dir api_address)
expect(helper.public_attributes.keys).to match_array('patroni')
expect(helper.public_attributes['patroni'].keys).to match_array(expected_patroni_keys)
end
end
context 'when patroni is disabled' do
it 'returns an empty hash' do
expect(helper.public_attributes).to be_empty
end
end
end
end
......@@ -152,11 +152,11 @@ RSpec.describe 'patroni cookbook' do
postgresql: {
username: 'test_psql_user',
sql_user: 'test_sql_user',
sql_user_password: '32596e8376077c3ef8d5cf52f15279ba',
sql_user_password: 'dbda601b8d4dc3d1697ef84dbbb8e61b',
sql_replication_user: 'test_sql_replication_user',
sql_replication_password: '5b3e5a380c8fe8f8180d396be021951a',
sql_replication_password: '48e84afb4b268128ac14f7c66fc7af42',
pgbouncer_user: 'test_pgbouncer_user',
pgbouncer_user_password: '3b244bd6e459bc406013417367587d41',
pgbouncer_user_password: '2bc94731612abb74aea7805a41dfcb09',
connect_port: 15432,
},
patroni: {
......@@ -171,6 +171,7 @@ RSpec.describe 'patroni cookbook' do
use_pg_rewind: true,
connect_address: '1.2.3.4',
connect_port: 18008,
replication_password: 'fakepassword',
replication_slots: {
'geo_secondary' => { 'type' => 'physical' }
},
......@@ -205,7 +206,7 @@ RSpec.describe 'patroni cookbook' do
},
replication: {
username: 'test_sql_replication_user',
password: 'md55b3e5a380c8fe8f8180d396be021951a'
password: 'fakepassword'
}
)
expect(cfg[:restapi][:connect_address]).to eq('1.2.3.4:18008')
......@@ -254,6 +255,70 @@ RSpec.describe 'patroni cookbook' do
end
end
 
context 'when standby cluster is enabled' do
before do
stub_gitlab_rb(
roles: %w(postgres_role),
patroni: {
enable: true,
use_pg_rewind: true,
replication_password: 'fakepassword',
standby_cluster: {
enable: true,
host: '1.2.3.4',
port: 5432,
primary_slot_name: 'geo_secondary'
}
},
postgresql: {
sql_user_password: 'a4125c87ce2572ce271cd77e0de9a0ad',
sql_replication_password: 'e64b415e9b9a34ac7ac6e53ae16ccacb',
md5_auth_cidr_addresses: '1.2.3.4/32'
}
)
end
it 'should be reflected in patroni configuration file' do
expect(chef_run).to render_file('/var/opt/gitlab/patroni/patroni.yaml').with_content { |content|
cfg = YAML.safe_load(content, permitted_classes: [Symbol], symbolize_names: true)
expect(cfg[:postgresql][:authentication]).to include(
replication: {
username: 'gitlab_replicator',
password: 'fakepassword'
}
)
expect(cfg[:bootstrap][:dcs]).to include(
standby_cluster: {
host: '1.2.3.4',
port: 5432,
primary_slot_name: 'geo_secondary'
}
)
expect(cfg[:bootstrap][:dcs][:postgresql]).to include(
use_pg_rewind: true
)
}
end
it 'should reflect into dcs config file' do
expect(chef_run).to render_file('/var/opt/gitlab/patroni/dcs.yaml').with_content { |content|
cfg = YAML.safe_load(content, permitted_classes: [Symbol], symbolize_names: true)
expect(cfg).to include(
standby_cluster: {
host: '1.2.3.4',
port: 5432,
primary_slot_name: 'geo_secondary'
}
)
expect(cfg[:postgresql]).to include(
use_pg_rewind: true
)
}
end
end
context 'when building a cluster' do
before do
stub_gitlab_rb(
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment