Commit 3e0ef776 authored by Michael Kozono's avatar Michael Kozono

Merge branch '223254-remove-fdw-code' into 'master'

Geo - Remove support for Foreign Data Wrapper

See merge request gitlab-org/gitlab!38718
parents 03ce0e54 8dc60d67
......@@ -257,7 +257,6 @@ Performance/Count:
Exclude:
- 'app/helpers/groups_helper.rb'
- 'app/services/merge_requests/add_context_service.rb'
- 'ee/lib/gitlab/geo/fdw.rb'
- 'ee/lib/gitlab/graphql/aggregations/epics/epic_node.rb'
- 'ee/spec/controllers/projects/feature_flags_controller_spec.rb'
- 'ee/spec/requests/api/feature_flags_spec.rb'
......
......@@ -8,7 +8,6 @@ production:
username: git
password: "secure password"
host: localhost
fdw: true
#
# Development specific
......@@ -20,7 +19,6 @@ development:
username: postgres
password: "secure password"
host: localhost
fdw: true
#
# Staging specific
......@@ -32,7 +30,6 @@ staging:
username: git
password: "secure password"
host: localhost
fdw: true
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
......@@ -44,4 +41,3 @@ test: &test
username: postgres
password:
host: localhost
fdw: true
# frozen_string_literal: true
class Geo::BaseFdw < Geo::TrackingBase
self.abstract_class = true
end
---
title: 'Geo: Remove support for Foreign Data Wrapper'
merge_request: 38718
author:
type: removed
# frozen_string_literal: true
module Gitlab
module Geo
class Fdw
DEFAULT_SCHEMA = 'public'
FOREIGN_SERVER = 'gitlab_secondary'
FOREIGN_SCHEMA = 'gitlab_secondary'
class << self
# Return if FDW is enabled for this instance
#
# @return [Boolean] whether FDW is enabled
def enabled?
return false unless fdw_capable?
# FDW is enabled by default, disable it by setting `fdw: false` in config/database_geo.yml
value = Rails.configuration.geo_database['fdw']
value.nil? ? true : value
end
def disabled?
!enabled?
end
# Return full table name with foreign schema
#
# @param [String] table_name
def foreign_table_name(table_name)
FOREIGN_SCHEMA + ".#{table_name}"
end
# Number of existing tables
#
# @return [Integer] number of tables
def foreign_schema_tables_count
Gitlab::Geo.cache_value(:geo_fdw_count_tables) do
sql = <<~SQL
SELECT COUNT(*)
FROM information_schema.foreign_tables
WHERE foreign_table_schema = '#{FOREIGN_SCHEMA}'
AND foreign_table_name NOT LIKE 'pg_%'
SQL
::Geo::TrackingBase.connection.execute(sql).first.fetch('count').to_i
end
end
private
def fdw_capable?
has_foreign_server? && has_foreign_schema? && foreign_schema_tables_count > 0
rescue ::Geo::TrackingBase::SecondaryNotConfigured
false
end
# Check if there is at least one foreign server configured
#
# @return [Boolean] whether any foreign server exists
def has_foreign_server?
::Geo::TrackingBase.connection.execute(
"SELECT 1 FROM pg_foreign_server"
).count > 0
end
def has_foreign_schema?
Gitlab::Geo.cache_value(:geo_FOREIGN_SCHEMA_exist) do
sql = <<~SQL
SELECT 1
FROM information_schema.schemata
WHERE schema_name='#{FOREIGN_SCHEMA}'
SQL
::Geo::TrackingBase.connection.execute(sql).count > 0
end
end
# Check if foreign schema has exact the same tables and fields defined on secondary database
#
# @return [Boolean] whether schemas match and are not empty
def foreign_schema_tables_match?
Gitlab::Geo.cache_value(:geo_foreign_schema_tables_match) do
gitlab_schema_tables = retrieve_gitlab_schema_tables.to_set
foreign_schema_tables = retrieve_foreign_schema_tables.to_set
gitlab_schema_tables.present? && (gitlab_schema_tables == foreign_schema_tables)
end
end
def retrieve_foreign_schema_tables
retrieve_schema_tables(::Geo::TrackingBase, Rails.configuration.geo_database['database'], FOREIGN_SCHEMA).to_a
end
def retrieve_gitlab_schema_tables
retrieve_schema_tables(ActiveRecord::Base, ActiveRecord::Base.connection_config[:database], DEFAULT_SCHEMA).to_a
end
def retrieve_schema_tables(adapter, database, schema)
sql = <<~SQL
SELECT table_name, column_name, data_type
FROM information_schema.columns
WHERE table_catalog = '#{database}'
AND table_schema = '#{schema}'
AND table_name NOT LIKE 'pg_%'
ORDER BY table_name, column_name, data_type
SQL
adapter.connection.select_all(sql)
end
end
end
end
end
......@@ -135,16 +135,6 @@ namespace :geo do
task purge: [:environment] do
Gitlab::Geo::DatabaseTasks::Test.purge
end
desc 'GitLab | Geo | DB | Test | Refresh Foreign Tables definition for test environment'
task refresh_foreign_tables: [:environment] do
old_env = ActiveRecord::Tasks::DatabaseTasks.env
ActiveRecord::Tasks::DatabaseTasks.env = 'test'
ns['geo:db:refresh_foreign_tables'].invoke
ActiveRecord::Tasks::DatabaseTasks.env = old_env
end
end
end
......
......@@ -34,7 +34,7 @@ RSpec.describe 'admin Geo Projects', :js, :geo do
end
end
describe 'searching for a geo project', :geo_fdw do
describe 'searching for a geo project' do
it 'filters out projects with the search term' do
fill_in :name, with: synced_registry.project.name
find('#project-filter-form-field').native.send_keys(:enter)
......@@ -51,7 +51,7 @@ RSpec.describe 'admin Geo Projects', :js, :geo do
end
end
describe 'with no registries', :geo_fdw do
describe 'with no registries' do
it 'shows empty state' do
fill_in :name, with: 'asdfasdf'
find('#project-filter-form-field').native.send_keys(:enter)
......@@ -90,7 +90,7 @@ RSpec.describe 'admin Geo Projects', :js, :geo do
end
end
describe 'searching for a geo project', :geo_fdw do
describe 'searching for a geo project' do
it 'finds the project with the same name' do
fill_in :name, with: sync_pending_registry.project.name
find('#project-filter-form-field').native.send_keys(:enter)
......
......@@ -24,7 +24,7 @@ RSpec.describe 'admin Geo Uploads', :js, :geo do
end
end
describe 'searching for a geo upload', :geo_fdw do
describe 'searching for a geo upload' do
it 'filters out uploads with the search term' do
fill_in :name, with: synced_registry.file
find('#project-filter-form-field').native.send_keys(:enter)
......@@ -38,7 +38,7 @@ RSpec.describe 'admin Geo Uploads', :js, :geo do
end
end
describe 'with no registries', :geo_fdw do
describe 'with no registries' do
it 'shows empty state' do
fill_in :name, with: 'asdfasdf'
find('#project-filter-form-field').native.send_keys(:enter)
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Geo::Fdw, :geo do
describe '.enabled?' do
it 'returns false when Geo secondary database is not configured' do
allow(Gitlab::Geo).to receive(:geo_database_configured?).and_return(false)
expect(described_class.enabled?).to eq false
end
it 'returns false when foreign server does not exist' do
drop_foreign_server
expect(described_class.enabled?).to eq false
end
it 'returns false when foreign server exists but foreign schema does not exist' do
drop_foreign_schema
expect(described_class.enabled?).to eq false
end
it 'returns false when foreign server and schema exists but foreign tables are empty' do
drop_foreign_schema
create_foreign_schema
expect(described_class.enabled?).to eq false
end
it 'returns false when fdw is disabled in `config/database_geo.yml`' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => false)
expect(described_class.enabled?).to be_falsey
end
it 'returns true when fdw is set in `config/database_geo.yml`' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => true)
expect(described_class.enabled?).to be_truthy
end
it 'returns true when fdw is nil in `config/database_geo.yml`' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => nil)
expect(described_class.enabled?).to be_truthy
end
it 'returns true with a functional fdw environment' do
expect(described_class.enabled?).to be_truthy
end
end
describe '.disabled?' do
it 'returns true when foreign server does not exist' do
drop_foreign_server
expect(described_class.disabled?).to eq true
end
it 'returns true when foreign server exists but foreign schema does not exist' do
drop_foreign_schema
expect(described_class.disabled?).to eq true
end
it 'returns true when foreign server and schema exists but foreign tables are empty' do
drop_foreign_schema
create_foreign_schema
expect(described_class.disabled?).to eq true
end
it 'returns true when fdw is disabled in `config/database_geo.yml`' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => false)
expect(described_class.disabled?).to eq true
end
it 'returns true when Geo secondary database is not configured' do
allow(Gitlab::Geo).to receive(:geo_database_configured?).and_return(false)
expect(described_class.disabled?).to eq true
end
it 'returns false when fdw is set in `config/database_geo.yml`' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => true)
expect(described_class.disabled?).to eq false
end
it 'returns false when fdw is nil in `config/database_geo.yml`' do
allow(Rails.configuration).to receive(:geo_database).and_return('fdw' => nil)
expect(described_class.disabled?).to eq false
end
it 'returns false with a functional fdw environment' do
expect(described_class.disabled?).to eq false
end
end
describe '.foreign_schema_tables_count' do
before do
drop_foreign_schema
create_foreign_schema
end
it 'returns the number of tables in the foreign schema' do
create_foreign_table(:gitlab_test)
expect(described_class.foreign_schema_tables_count).to eq(1)
end
it 'excludes tables that start with `pg_`' do
create_foreign_table(:pg_gitlab_test)
expect(described_class.foreign_schema_tables_count).to eq(0)
end
end
def with_foreign_connection
Geo::TrackingBase.connection
end
def drop_foreign_server
with_foreign_connection.execute <<-SQL
DROP SERVER IF EXISTS #{described_class::FOREIGN_SERVER} CASCADE
SQL
end
def drop_foreign_schema
with_foreign_connection.execute <<-SQL
DROP SCHEMA IF EXISTS #{described_class::FOREIGN_SCHEMA} CASCADE
SQL
end
def create_foreign_schema
with_foreign_connection.execute <<-SQL
CREATE SCHEMA IF NOT EXISTS #{described_class::FOREIGN_SCHEMA}
SQL
with_foreign_connection.execute <<-SQL
GRANT USAGE ON FOREIGN SERVER #{described_class::FOREIGN_SERVER} TO current_user
SQL
end
def create_foreign_table(table_name)
with_foreign_connection.execute <<-SQL
CREATE FOREIGN TABLE IF NOT EXISTS #{described_class::FOREIGN_SCHEMA}.#{table_name} (
id int
) SERVER #{described_class::FOREIGN_SERVER}
SQL
end
end
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Geo::UploadRegistry, :geo, :geo_fdw do
RSpec.describe Geo::UploadRegistry, :geo do
include EE::GeoHelpers
let!(:failed) { create(:geo_upload_registry, :failed) }
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe GeoNodeStatus, :geo, :geo_fdw do
RSpec.describe GeoNodeStatus, :geo do
include ::EE::GeoHelpers
let!(:primary) { create(:geo_node, :primary) }
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe API::GeoNodes, :request_store, :geo_fdw, :prometheus, api: true do
RSpec.describe API::GeoNodes, :request_store, :geo, :prometheus, api: true do
include ApiHelpers
include ::EE::GeoHelpers
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe API::GeoReplication, :request_store, :geo, :geo_fdw, api: true do
RSpec.describe API::GeoReplication, :request_store, :geo, api: true do
include ApiHelpers
include ::EE::GeoHelpers
......
......@@ -24,16 +24,4 @@ RSpec.configure do |config|
config.around(:each, :geo_tracking_db) do |example|
example.run if Gitlab::Geo.geo_database_configured?
end
config.around(:each, :geo_fdw) do |example|
if Gitlab::Geo::Fdw.enabled? && Gitlab::Geo.geo_database_configured?
# Disable transactions because a foreign table can't see changes
# inside a transaction of a different connection.
self.class.use_transactional_tests = false
example.run
delete_from_all_tables!(except: deletion_except_tables)
end
end
end
......@@ -302,7 +302,7 @@ RSpec.describe 'geo rake tasks', :geo do
end
end
describe 'geo:status', :geo_fdw do
describe 'geo:status' do
context 'without a valid license' do
before do
stub_licensed_features(geo: false)
......
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