Skip to content
Snippets Groups Projects
Commit cdc3e822 authored by DJ Mountney's avatar DJ Mountney
Browse files

Merge branch '5573-geo-remove-fdw-related-config-from-omnibus' into 'master'

Geo - Remove support for FDW

Closes #5573

See merge request gitlab-org/omnibus-gitlab!4491
parents 82d4b98b 23fbd188
No related branches found
No related tags found
No related merge requests found
Showing
with 43 additions and 667 deletions
---
title: Remove Foreign Data Wrapper support for Geo
merge_request: 4491
author:
type: removed
Loading
Loading
@@ -738,13 +738,6 @@ Log in to your **primary** node, executing the following:
sudo SKIP_POST_DEPLOYMENT_MIGRATIONS=true gitlab-ctl reconfigure
```
 
NOTE: **Note:**
After this step you can get an outdated FDW remote schema on your
secondary nodes. While it is not important to worry about at this
point, you can check out the
[Geo troubleshooting documentation](https://docs.gitlab.com/ee/administration/geo/replication/troubleshooting.html#geo-database-has-an-outdated-fdw-remote-schema-error)
to resolve this.
1. Hot reload `puma` (or `unicorn`) and `sidekiq` services
 
```shell
Loading
Loading
@@ -801,13 +794,6 @@ the update on the **primary** node:
sudo gitlab-rake db:migrate
```
 
On each **secondary**, ensure the FDW tables are up-to-date.
1. Wait for the **primary** migrations to finish.
1. Wait for the **primary** migrations to replicate. You can find "Data
replication lag" for each node listed on `Admin Area > Geo`.
After updating all nodes (both **primary** and all **secondaries**), check their status:
 
- Verify Geo configuration and dependencies
Loading
Loading
Loading
Loading
@@ -2220,7 +2220,6 @@ gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = nil
# geo_secondary['db_sslcompression'] = 0
# geo_secondary['db_sslrootcert'] = nil
# geo_secondary['db_sslca'] = nil
# geo_secondary['db_fdw'] = true
 
################################################################################
## GitLab Geo Secondary Tracking Database (EE only)
Loading
Loading
Loading
Loading
@@ -55,7 +55,7 @@ default['gitlab']['geo-secondary']['db_sslmode'] = nil
default['gitlab']['geo-secondary']['db_sslcompression'] = 0
default['gitlab']['geo-secondary']['db_sslrootcert'] = nil
default['gitlab']['geo-secondary']['db_sslca'] = nil
default['gitlab']['geo-secondary']['db_fdw'] = true
default['gitlab']['geo-secondary']['db_fdw'] = nil
 
###
# Geo: PostgreSQL (Tracking database)
Loading
Loading
Loading
Loading
@@ -31,18 +31,4 @@ class FdwHelper
def fdw_port
node['gitlab']['gitlab-rails']['db_port']
end
def pg_hba_entries
entries = []
node['postgresql']['md5_auth_cidr_addresses'].each do |cidr|
entries.push({
type: 'host',
database: fdw_dbname,
user: fdw_user,
cidr: cidr,
method: 'md5'
})
end
entries
end
end unless defined?(FdwHelper) # Prevent reloading in chefspec: https://github.com/sethvargo/chefspec/issues/562#issuecomment-74120922
Loading
Loading
@@ -131,9 +131,6 @@ geo_pg_user = node['gitlab']['geo-postgresql']['sql_user']
geo_pg_user_password = node['gitlab']['geo-postgresql']['sql_user_password']
geo_database_name = node['gitlab']['geo-secondary']['db_database']
 
# set custom pg_hba entries at the secondary postgres for FDW compatibility
node.default['postgresql']['custom_pg_hba_entries']['fdw'] = fdw_helper.pg_hba_entries if fdw_helper.fdw_enabled?
if node['gitlab']['geo-postgresql']['enable']
postgresql_user geo_pg_user do
password "md5#{geo_pg_user_password}" unless geo_pg_user_password.nil?
Loading
Loading
@@ -155,32 +152,13 @@ if node['gitlab']['geo-postgresql']['enable']
action :enable
end
 
postgresql_schema 'gitlab_secondary' do
database geo_database_name
owner geo_pg_user
helper geo_pg_helper
action :create
only_if { fdw_helper.fdw_enabled? && !fdw_helper.fdw_password.nil? }
end
postgresql_fdw 'gitlab_secondary' do
db_name geo_database_name
external_host fdw_helper.fdw_host
external_port fdw_helper.fdw_port
external_name fdw_helper.fdw_dbname
helper geo_pg_helper
action :create
only_if { fdw_helper.fdw_enabled? && !fdw_helper.fdw_password.nil? }
end
postgresql_fdw_user_mapping 'gitlab_secondary' do
db_user geo_pg_user
db_name geo_database_name
external_user fdw_helper.fdw_user
external_password fdw_helper.fdw_password
helper geo_pg_helper
action :create
only_if { fdw_helper.fdw_enabled? && !fdw_helper.fdw_password.nil? }
action :delete
end
 
ruby_block 'warn pending geo-postgresql restart' do
Loading
Loading
Loading
Loading
@@ -7,48 +7,23 @@ property :external_port, Integer
property :external_name, String
property :helper, default: PgHelper.new(node)
 
action :create do
postgresql_query "enable postgres_fdw extension on #{new_resource.db_name}" do
query "CREATE EXTENSION IF NOT EXISTS postgres_fdw;"
db_name new_resource.db_name
helper new_resource.helper
not_if do
new_resource.helper.is_offline_or_readonly? ||
new_resource.helper.extension_enabled?('postgres_fdw', new_resource.db_name)
end
end
postgresql_query "create fdw #{new_resource.server_name} on #{new_resource.db_name}" do
query "CREATE SERVER #{new_resource.server_name} FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host '#{new_resource.external_host}', port '#{new_resource.external_port}', dbname '#{new_resource.external_name}');"
action :delete do
postgresql_query "drop fdw #{new_resource.server_name} on #{new_resource.db_name}" do
query "DROP SERVER #{new_resource.server_name} CASCADE;"
db_name new_resource.db_name
helper new_resource.helper
 
not_if do
new_resource.helper.is_offline_or_readonly? ||
new_resource.helper.fdw_server_exists?(new_resource.server_name, new_resource.db_name)
end
not_if { new_resource.helper.is_offline_or_readonly? || !new_resource.helper.fdw_server_exists?(new_resource.server_name, new_resource.db_name) }
end
 
postgresql_query "update fdw #{new_resource.server_name} on #{new_resource.db_name}" do
query "ALTER SERVER #{new_resource.server_name} OPTIONS (SET host '#{new_resource.external_host}', SET port '#{new_resource.external_port}', SET dbname '#{new_resource.external_name}');"
postgresql_query "drop postgres_fdw extension on #{new_resource.db_name}" do
query "DROP EXTENSION IF EXISTS postgres_fdw;"
db_name new_resource.db_name
helper new_resource.helper
 
not_if do
new_resource.helper.is_offline_or_readonly? ||
!new_resource.helper.fdw_server_exists?(new_resource.server_name, new_resource.db_name) ||
!new_resource.helper.fdw_server_options_changed?(new_resource.server_name, new_resource.db_name, host: new_resource.external_host, port: new_resource.external_port, dbname: new_resource.external_name)
!new_resource.helper.extension_enabled?('postgres_fdw', new_resource.db_name)
end
end
end
action :delete do
postgresql_query "drop fdw #{new_resource.server_name} on #{new_resource.db_name}" do
query "DROP SERVER #{new_resource.server_name} CASCADE;"
db_name new_resource.db_name
helper new_resource.helper
not_if { new_resource.helper.is_offline_or_readonly? || !new_resource.helper.fdw_server_exists?(new_resource.server_name, new_resource.db_name) }
end
end
resource_name :postgresql_fdw_user_mapping
property :server_name, String, name_property: true
property :db_user, String
property :db_name, String
property :external_user, String
property :external_password, String
property :helper, default: PgHelper.new(node)
action :create do
postgresql_query "create mapping for #{new_resource.db_user} at #{new_resource.server_name}" do
query "CREATE USER MAPPING FOR #{new_resource.db_user} SERVER #{new_resource.server_name} OPTIONS (user '#{new_resource.external_user}', password '#{new_resource.external_password}');"
db_name new_resource.db_name
helper new_resource.helper
not_if do
new_resource.helper.is_offline_or_readonly? ||
!new_resource.helper.fdw_server_exists?(new_resource.server_name, new_resource.db_name) ||
new_resource.helper.fdw_user_mapping_exists?(new_resource.db_user, new_resource.server_name, new_resource.db_name)
end
end
postgresql_query "update mapping for #{new_resource.db_user} at #{new_resource.server_name}" do
query "ALTER USER MAPPING FOR #{new_resource.db_user} SERVER #{new_resource.server_name} OPTIONS (#{new_resource.helper.fdw_user_mapping_update_options(new_resource)});"
db_name new_resource.db_name
helper new_resource.helper
not_if do
new_resource.helper.is_offline_or_readonly? ||
!new_resource.helper.fdw_server_exists?(new_resource.server_name, new_resource.db_name) ||
!new_resource.helper.fdw_user_mapping_exists?(new_resource.db_user, new_resource.server_name, new_resource.db_name) ||
!new_resource.helper.fdw_user_mapping_changed?(new_resource.db_user, new_resource.server_name, new_resource.db_name, user: new_resource.external_user, password: new_resource.external_password)
end
end
postgresql_query "grant usage on foreign server #{new_resource.server_name} to #{new_resource.db_user}" do
query "GRANT USAGE ON FOREIGN SERVER #{new_resource.server_name} TO #{new_resource.db_user};"
db_name new_resource.db_name
helper new_resource.helper
not_if do
new_resource.helper.is_offline_or_readonly? ||
!new_resource.helper.fdw_server_exists?(new_resource.server_name, new_resource.db_name) ||
new_resource.helper.fdw_user_has_server_privilege?(new_resource.db_user, new_resource.server_name, new_resource.db_name, 'USAGE')
end
end
end
Loading
Loading
@@ -107,56 +107,3 @@ pgbouncer_user 'rails' do
action :create
end
```
### postgresql_fdw
Creates a FOREIGN DATA WRAPPER ([FDW]) [connection][FDW-CONNECTION] in PostgreSQL to another PostgreSQL instance
#### properties
* `server_name` (name property): The identifier that will be used in PostgreSQL to refer to this connection
* `db_host`: The host of the remote instance
* `db_port`: The port of the remote instance
* `db_name`: The database name of the remote instance
#### example
Create a Foreign Data Wrapper connection with an external PostgreSQL instance
```ruby
postgresql_fdw 'gitlab_secondary' do
db_host '10.0.0.1'
db_port 5432
db_name 'otherdb'
action :create
end
```
### postgresql_fdw_user_mapping
Creates a user mapping for a local user to be able to connect to a remote database as a remote user.
This is how loca user can interact with an external [FDW] configured instance.
#### properties
* `server_name` (name property): The identifier that will be used in PostgreSQL to refer to this connection
* `db_user`: The local user that will be mapped to a remote one
* `db_name`: The local database name where the mapping will happen
* `external_user`: The remote user that will be mapped to the local one
* `external_password`: The password for the remote user, that local database will use to connect
* `helper`: The helper object for interacting with the running database. Default: PgHelper.new(node)
```ruby
postgresql_fdw_user_mapping 'gitlab_secondary' do
db_user 'user'
db_name 'database'
external_user 'remoteuser'
external_password 'remotepassword'
action :create
end
```
[FDW]: https://www.postgresql.org/docs/11/postgres-fdw.html
[FDW-CONNECTION]: https://www.postgresql.org/docs/11/sql-createserver.html
Loading
Loading
@@ -380,8 +380,8 @@ default['gitlab']['gitlab-rails']['db_sslkey'] = nil
default['gitlab']['gitlab-rails']['db_sslca'] = nil
default['gitlab']['gitlab-rails']['db_prepared_statements'] = false
default['gitlab']['gitlab-rails']['db_statements_limit'] = 1000
default['gitlab']['gitlab-rails']['db_fdw'] = nil
default['gitlab']['gitlab-rails']['db_statement_timeout'] = nil
default['gitlab']['gitlab-rails']['db_fdw'] = nil
 
default['gitlab']['gitlab-rails']['redis_host'] = "127.0.0.1"
default['gitlab']['gitlab-rails']['redis_port'] = nil
Loading
Loading
Loading
Loading
@@ -126,62 +126,6 @@ class BasePgHelper < BaseHelper
"| grep -x #{server_name}"])
end
 
def fdw_user_mapping_exists?(user, server_name, db_name)
psql_cmd(["-d '#{db_name}'",
%(-c "select usename from pg_user_mappings where srvname='#{server_name}'" -tA),
"| grep -x #{user}"])
end
def fdw_user_has_server_privilege?(user, server_name, db_name, permission)
psql_cmd(["-d '#{db_name}'",
%(-c "select has_server_privilege('#{user}', '#{server_name}', '#{permission}');" -tA),
"| grep -x t"])
end
def fdw_server_options_changed?(server_name, db_name, options = {})
options = stringify_hash_values(options)
raw_content = psql_query(db_name, "SELECT srvoptions FROM pg_foreign_server WHERE srvname='#{server_name}'")
server_options = parse_pghash(raw_content)
# return whether options is not a subset of server_options
# this allows us to ignore additional params on server and look only to the ones informed in the method
!(options <= server_options)
end
def fdw_user_mapping_changed?(user, server_name, db_name, options = {})
current_options = fdw_user_mapping_current_options(user, server_name, db_name)
# return whether options is not a subset of current_options
# this allows us to ignore additional params on server and look only to the ones informed in the method
!(options <= current_options)
end
# Returns the desired FDW user mapping options, not including parentheses
#
# `resource` must respond to FDW user mapping properties:
# db_user
# server_name
# db_name
# external_user
# external_password
def fdw_user_mapping_update_options(resource)
has_password = fdw_external_password_exists?(resource.db_user, resource.server_name, resource.db_name)
password_action = has_password ? 'SET' : 'ADD'
"SET user '#{resource.external_user}', #{password_action} password '#{resource.external_password}'"
end
# Returns whether the user mapping has a password set
def fdw_external_password_exists?(user, server_name, db_name)
fdw_user_mapping_current_options(user, server_name, db_name).key?(:password)
end
def fdw_user_mapping_current_options(user, server_name, db_name)
raw_content = psql_query(db_name, "SELECT umoptions FROM pg_user_mappings WHERE srvname='#{server_name}' AND usename='#{user}'")
parse_pghash(raw_content)
end
def user_hashed_password(db_user)
db_user_safe = db_user.scan(/[a-z_][a-z0-9_-]*[$]?/).first
psql_query('template1', "SELECT passwd FROM pg_shadow WHERE usename='#{db_user_safe}'")
Loading
Loading
Loading
Loading
@@ -23,6 +23,5 @@ production:
load_balancing: <%= @db_load_balancing.to_json %>
prepared_statements: <%= @db_prepared_statements %>
statement_limit: <%= @db_statements_limit %>
fdw: <%= @db_fdw %>
variables:
statement_timeout: <%= @db_statement_timeout %>
Loading
Loading
@@ -53,6 +53,24 @@ module Gitlab
deprecation: '13.3',
removal: '14.0',
note: "Read-only mode is repository specific and always enabled after suspected data loss. See https://docs.gitlab.com/ee/administration/gitaly/praefect.html#read-only-mode"
},
{
config_keys: %w(gitlab geo-secondary db_fdw),
deprecation: '13.3',
removal: '14.0',
note: "Geo does not require Foreign Data Wrapper (FDW) to be configured to replicate data."
},
{
config_keys: %w(gitlab geo-postgresql fdw_external_user),
deprecation: '13.3',
removal: '14.0',
note: "Geo does not require Foreign Data Wrapper (FDW) to be configured to replicate data."
},
{
config_keys: %w(gitlab geo-postgresql fdw_external_password),
deprecation: '13.3',
removal: '14.0',
note: "Geo does not require Foreign Data Wrapper (FDW) to be configured to replicate data."
}
]
 
Loading
Loading
require_relative '../../../../files/gitlab-cookbooks/gitlab-ee/libraries/fdw_helper.rb'
require 'chef_helper'
RSpec.describe FdwHelper do
let(:chef_run) { converge_config(is_ee: true) }
subject { described_class.new(chef_run.node) }
before do
allow(Gitlab).to receive(:[]).and_call_original
end
describe '#pg_hba_entries' do
before do
stub_gitlab_rb(
geo_postgresql: {
enable: true,
sql_user: 'mygeodbuser'
},
geo_secondary: {
enable: true,
db_database: 'gitlab_geodb',
db_fdw: true
},
gitlab_rails: {
db_host: '10.0.0.1',
db_port: 5430,
db_username: 'mydbuser',
db_database: 'gitlab_myorg',
db_password: 'custompass'
},
postgresql: {
md5_auth_cidr_addresses: %w(10.0.0.1/32 10.0.0.2/32)
}
)
end
it 'returns array of hashes with expected keys' do
pg_hba_entries = [
{
type: 'host',
database: 'gitlab_myorg',
user: 'mydbuser',
cidr: '10.0.0.1/32',
method: 'md5'
},
{
type: 'host',
database: 'gitlab_myorg',
user: 'mydbuser',
cidr: '10.0.0.2/32',
method: 'md5'
}
]
expect(subject.pg_hba_entries).to eq(pg_hba_entries)
end
end
end
Loading
Loading
@@ -184,13 +184,6 @@ RSpec.describe 'geo postgresql 9.2' do
end
end
end
it 'does not create foreign table mapping' do
expect(chef_run).not_to create_postgresql_schema('gitlab_secondary')
expect(chef_run).not_to create_postgresql_fdw('gitlab_secondary')
expect(chef_run).not_to create_postgresql_fdw_user_mapping('gitlab_secondary')
expect(chef_run).not_to run_execute('refresh foreign table definition')
end
end
 
context 'when a SQL user password is set' do
Loading
Loading
@@ -525,15 +518,12 @@ RSpec.describe 'geo postgresql 9.6' do
ChefSpec::SoloRunner.new(step_into: %w(runit_service)).converge('gitlab-ee::default')
end
 
it 'does not setup foreign table mapping' do
expect(chef_run).not_to create_postgresql_schema('gitlab_secondary')
expect(chef_run).not_to create_postgresql_fdw('gitlab_secondary')
expect(chef_run).not_to create_postgresql_fdw_user_mapping('gitlab_secondary')
expect(chef_run).not_to run_execute('refresh foreign table definition')
it 'deletes the postgresql fdw server in the geo-postgresql database' do
expect(chef_run).to delete_postgresql_fdw('gitlab_secondary')
end
end
 
context 'FDW support' do
context 'FDW is enabled' do
cached(:chef_run) do
RSpec::Mocks.with_temporary_scope do
stub_gitlab_rb(
Loading
Loading
@@ -542,7 +532,8 @@ RSpec.describe 'geo postgresql 9.6' do
sql_user: 'mygeodbuser'
},
geo_secondary: {
db_database: 'gitlab_geodb'
db_database: 'gitlab_geodb',
db_fdw: true
},
gitlab_rails: {
db_host: '10.0.0.1',
Loading
Loading
@@ -559,16 +550,7 @@ RSpec.describe 'geo postgresql 9.6' do
ChefSpec::SoloRunner.new(step_into: %w(runit_service)).converge('gitlab-ee::default')
end
 
it 'creates gitlab_secondary schema' do
params = {
schema: 'gitlab_secondary',
database: 'gitlab_geodb',
owner: 'mygeodbuser'
}
expect(chef_run).to create_postgresql_schema('gitlab_secondary').with(params)
end
it 'creates a postgresql fdw connection in the geo-postgresql database' do
it 'deletes the postgresql fdw server in the geo-postgresql database' do
params = {
db_name: 'gitlab_geodb',
external_host: '10.0.0.1',
Loading
Loading
@@ -576,45 +558,7 @@ RSpec.describe 'geo postgresql 9.6' do
external_name: 'gitlab_myorg'
}
 
expect(chef_run).to create_postgresql_fdw('gitlab_secondary').with(params)
end
it 'creates a postgresql fdw user mapping in the geo-postgresql database' do
params = {
db_user: 'mygeodbuser',
db_name: 'gitlab_geodb',
external_user: 'mydbuser',
external_password: 'custompass'
}
expect(chef_run).to create_postgresql_fdw_user_mapping('gitlab_secondary').with(params)
end
context 'when a custom external FDW user is used' do
let(:chef_run) do
stub_gitlab_rb(
geo_postgresql: {
enable: true,
sql_user: 'mygeodbuser',
fdw_external_user: 'fdw_user',
fdw_external_password: 'my-fdw-password'
},
geo_secondary: {
db_database: 'gitlab_geodb',
}
)
ChefSpec::SoloRunner.new(step_into: %w(runit_service)).converge('gitlab-ee::default')
end
it 'creates a mapping with custom external user' do
params = {
db_user: 'mygeodbuser',
db_name: 'gitlab_geodb',
external_user: 'fdw_user',
external_password: 'my-fdw-password'
}
expect(chef_run).to create_postgresql_fdw_user_mapping('gitlab_secondary').with(params)
end
expect(chef_run).to delete_postgresql_fdw('gitlab_secondary').with(params)
end
 
context 'when secondary database is not managed' do
Loading
Loading
@@ -649,10 +593,8 @@ RSpec.describe 'geo postgresql 9.6' do
ChefSpec::SoloRunner.new(step_into: %w(runit_service)).converge('gitlab-ee::default')
end
 
it 'creates foreign table mapping' do
expect(chef_run).to create_postgresql_schema('gitlab_secondary')
expect(chef_run).to create_postgresql_fdw('gitlab_secondary')
expect(chef_run).to create_postgresql_fdw_user_mapping('gitlab_secondary')
it 'deletes the postgresql fdw server in the geo-postgresql database' do
expect(chef_run).to delete_postgresql_fdw('gitlab_secondary')
end
end
end
Loading
Loading
require 'chef_helper'
RSpec.describe 'postgresql_fdw' do
let(:runner) do
ChefSpec::SoloRunner.new(step_into: %w(postgresql_fdw))
end
context 'create' do
let(:chef_run) { runner.converge('test_gitlab_ee::postgresql_fdw_create') }
context 'service is online' do
before do
allow_any_instance_of(PgHelper).to receive(:is_offline_or_readonly?).and_return(false)
end
describe 'postgres_fdw extension' do
context 'enabled already' do
it 'does not attempt to enable extension' do
allow_any_instance_of(PgHelper).to receive(:extension_enabled?).and_call_original
allow_any_instance_of(PgHelper).to receive(:extension_enabled?).with('postgres_fdw', 'foobar').and_return(true)
expect(chef_run).not_to run_postgresql_query('enable postgres_fdw extension on foobar')
end
end
context 'not enabled already' do
before do
allow_any_instance_of(PgHelper).to receive(:extension_enabled?).and_call_original
allow_any_instance_of(PgHelper).to receive(:extension_enabled?).with('postgres_fdw', 'foobar').and_return(false)
end
it 'enables extension' do
expect(chef_run).to run_postgresql_query('enable postgres_fdw extension on foobar').with(
db_name: 'foobar',
query: 'CREATE EXTENSION IF NOT EXISTS postgres_fdw;'
)
end
end
end
describe 'fdw server' do
describe 'creation' do
context 'does not exist already' do
before do
allow_any_instance_of(PgHelper).to receive(:fdw_server_exists?).and_return(false)
end
it 'creates fdw server' do
expect(chef_run).to run_postgresql_query('create fdw gitlab_secondary on foobar').with(
query: "CREATE SERVER gitlab_secondary FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host '127.0.0.1', port '1234', dbname 'lorem');",
db_name: 'foobar'
)
end
end
context 'exist already' do
before do
allow_any_instance_of(PgHelper).to receive(:fdw_server_exists?).and_return(true)
end
it 'does not create fdw server' do
expect(chef_run).not_to run_postgresql_query('create fdw gitlab_secondary on foobar')
end
end
end
describe 'update' do
context 'when options are changed' do
before do
allow_any_instance_of(PgHelper).to receive(:fdw_server_options_changed?).and_return(true)
allow_any_instance_of(PgHelper).to receive(:fdw_server_exists?).and_return(true)
end
it 'updates fdw server' do
expect(chef_run).to run_postgresql_query('update fdw gitlab_secondary on foobar').with(
query: "ALTER SERVER gitlab_secondary OPTIONS (SET host '127.0.0.1', SET port '1234', SET dbname 'lorem');",
db_name: 'foobar'
)
end
end
context 'when options are not changed' do
before do
allow_any_instance_of(PgHelper).to receive(:fdw_server_options_changed?).and_return(false)
end
it 'does not update fdw server' do
expect(chef_run).not_to run_postgresql_query('update fdw gitlab_secondary on foobar')
end
end
end
end
end
context 'service is offline' do
before do
allow_any_instance_of(PgHelper).to receive(:is_offline_or_readonly?).and_return(true)
end
it 'does not attempt to enable extension' do
expect(chef_run).not_to run_postgresql_query('enable postgres_fdw extension on foobar')
end
it 'does not create fdw server' do
expect(chef_run).not_to run_postgresql_query('create fdw gitlab_secondary on foobar')
end
it 'does not update fdw server' do
expect(chef_run).not_to run_postgresql_query('update fdw gitlab_secondary on foobar')
end
end
end
context 'delete' do
let(:chef_run) { runner.converge('test_gitlab_ee::postgresql_fdw_delete') }
context 'service is online' do
before do
allow_any_instance_of(PgHelper).to receive(:is_offline_or_readonly?).and_return(false)
allow_any_instance_of(PgHelper).to receive(:fdw_server_exists?).and_return(true)
end
it 'drops fdw server' do
expect(chef_run).to run_postgresql_query('drop fdw gitlab_secondary on foobar').with(
query: "DROP SERVER gitlab_secondary CASCADE;",
db_name: 'foobar'
)
end
end
context 'service is offline' do
before do
allow_any_instance_of(PgHelper).to receive(:is_offline_or_readonly?).and_return(false)
end
it 'does not attempt to drop fdw server' do
expect(chef_run).not_to run_postgresql_query('drop fdw gitlab_secondary on foobar')
end
end
context 'fdw server does not exist' do
before do
allow_any_instance_of(PgHelper).to receive(:is_offline_or_readonly?).and_return(false)
end
it 'does not attempt to drop fdw server' do
expect(chef_run).not_to run_postgresql_query('drop fdw gitlab_secondary on foobar')
end
end
end
end
require 'chef_helper'
RSpec.describe 'postgresql_fdw_user_mapping' do
let(:runner) do
ChefSpec::SoloRunner.new(step_into: %w(postgresql_fdw_user_mapping))
end
context 'create' do
let(:chef_run) { runner.converge('test_gitlab_ee::postgresql_fdw_user_mapping_create') }
context 'service is online' do
before do
allow_any_instance_of(PgHelper).to receive(:is_offline_or_readonly?).and_return(false)
end
describe 'postgres_fdw mapping' do
describe 'creation' do
context 'fdw server exists and mapping does not exist already' do
before do
allow_any_instance_of(PgHelper).to receive(:fdw_server_exists?).and_return(true)
allow_any_instance_of(PgHelper).to receive(:fdw_user_mapping_exists?).and_return(false)
end
it 'creates mapping' do
expect(chef_run).to run_postgresql_query('create mapping for randomuser at gitlab_secondary').with(
query: "CREATE USER MAPPING FOR randomuser SERVER gitlab_secondary OPTIONS (user 'externaluser', password 'externalpassword');",
db_name: 'foobar'
)
end
end
context 'fdw server exists and mapping exist already' do
before do
allow_any_instance_of(PgHelper).to receive(:fdw_server_exists?).and_return(true)
allow_any_instance_of(PgHelper).to receive(:fdw_user_mapping_exists?).and_return(true)
end
it 'does not create mapping' do
expect(chef_run).not_to run_postgresql_query('create mapping for randomuser at gitlab_secondary')
end
end
end
describe 'update' do
context 'fdw server and mapping exists and mapping changed' do
before do
allow_any_instance_of(PgHelper).to receive(:fdw_server_exists?).and_return(true)
allow_any_instance_of(PgHelper).to receive(:fdw_user_mapping_exists?).and_return(true)
allow_any_instance_of(PgHelper).to receive(:fdw_user_mapping_changed?).and_return(true)
end
it 'updates mapping' do
expect(chef_run).to run_postgresql_query('update mapping for randomuser at gitlab_secondary').with(
query: "ALTER USER MAPPING FOR randomuser SERVER gitlab_secondary OPTIONS (SET user 'externaluser', ADD password 'externalpassword');",
db_name: 'foobar'
)
end
end
context 'fdw server and mapping exists but mapping not changed' do
before do
allow_any_instance_of(PgHelper).to receive(:fdw_server_exists?).and_return(true)
allow_any_instance_of(PgHelper).to receive(:fdw_user_mapping_exists?).and_return(true)
allow_any_instance_of(PgHelper).to receive(:fdw_user_mapping_changed?).and_return(false)
end
it 'does not update mapping' do
expect(chef_run).not_to run_postgresql_query('update mapping for randomuser at gitlab_secondary')
end
end
end
end
describe 'usage privilege' do
context 'fdw server exists and user does not have server privilege' do
before do
allow_any_instance_of(PgHelper).to receive(:fdw_server_exists?).and_return(true)
allow_any_instance_of(PgHelper).to receive(:fdw_user_has_server_privilege?).and_return(false)
end
it 'grants usage privileges correctly' do
expect(chef_run).to run_postgresql_query('grant usage on foreign server gitlab_secondary to randomuser').with(
query: 'GRANT USAGE ON FOREIGN SERVER gitlab_secondary TO randomuser;',
db_name: 'foobar'
)
end
end
context 'fdw server exists and user already has server privilege' do
before do
allow_any_instance_of(PgHelper).to receive(:fdw_server_exists?).and_return(true)
allow_any_instance_of(PgHelper).to receive(:fdw_user_has_server_privilege?).and_return(true)
end
it 'does not attempt to grant usage privileges' do
expect(chef_run).not_to run_postgresql_query('grant usage on foreign server gitlab_secondary to randomuser')
end
end
end
end
context 'service is offline' do
before do
allow_any_instance_of(PgHelper).to receive(:is_offline_or_readonly?).and_return(true)
end
it 'does not create mapping' do
expect(chef_run).not_to run_postgresql_query('create mapping for randomuser at gitlab_secondary')
end
it 'does not update mapping' do
expect(chef_run).not_to run_postgresql_query('update mapping for randomuser at gitlab_secondary')
end
it 'does not attempt to grant usage privileges' do
expect(chef_run).not_to run_postgresql_query('grant usage on foreign server gitlab_secondary to randomuser')
end
end
end
end
Loading
Loading
@@ -2350,8 +2350,7 @@ RSpec.describe 'gitlab::gitlab-rails' do
'db_prepared_statements' => false,
'db_sslcompression' => 0,
'db_sslcert' => nil,
'db_sslkey' => nil,
'db_fdw' => nil
'db_sslkey' => nil
)
)
end
Loading
Loading
@@ -2472,20 +2471,6 @@ RSpec.describe 'gitlab::gitlab-rails' do
end
end
 
context 'when fdw is specified' do
before do
stub_gitlab_rb(gitlab_rails: { db_fdw: true })
end
it 'uses provided value in database.yml' do
expect(chef_run).to create_templatesymlink('Create a database.yml and create a symlink to Rails root').with_variables(
hash_including(
'db_fdw' => true
)
)
end
end
context 'when SSL certificate and key for DB is specified' do
before do
stub_gitlab_rb(
Loading
Loading
postgresql_fdw 'gitlab_secondary' do
db_name 'foobar'
external_host '127.0.0.1'
external_port 1234
external_name 'lorem'
end
postgresql_fdw 'gitlab_secondary' do
db_name 'foobar'
external_host '127.0.0.1'
external_port 1234
external_name 'lorem'
action :delete
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment