Commit f1181394 authored by Sean McGivern's avatar Sean McGivern

Merge branch '3131-make-selective-replication-work-right' into 'master'

Geo: Make selective replication work right

Closes #3131

See merge request !2649
parents 64c15df3 a5e9840a
......@@ -108,6 +108,12 @@ class GeoNode < ActiveRecord::Base
end
end
def projects_include?(project_id)
return true if restricted_project_ids.nil?
restricted_project_ids.include?(project_id)
end
def restricted_project_ids
return unless namespaces.presence
......
......@@ -8,6 +8,8 @@ module Geo
def execute
@projects.each do |project|
next unless Gitlab::Geo.current_node&.projects_include?(project['id'].to_i)
GeoWikiRepositoryUpdateWorker.perform_async(project['id'], project['clone_url'])
end
end
......
......@@ -58,6 +58,8 @@ module API
post 'receive_events' do
authenticate_by_gitlab_geo_token!
require_node_to_be_enabled!
check_node_restricted_project_ids!
required_attributes! %w(event_name)
case params['event_name']
......@@ -109,6 +111,14 @@ module API
def require_node_to_be_secondary!
forbidden! 'Geo node is not secondary node.' unless Gitlab::Geo.current_node&.secondary?
end
def check_node_restricted_project_ids!
return unless params.key?(:project_id)
unless Gitlab::Geo.current_node&.projects_include?(params[:project_id].to_i)
not_found!
end
end
end
end
end
......@@ -98,9 +98,8 @@ module Gitlab
def can_replay?(event_log)
return true if event_log.project_id.nil?
return true if Gitlab::Geo.current_node.restricted_project_ids.nil?
Gitlab::Geo.current_node.restricted_project_ids.include?(event_log.project_id)
Gitlab::Geo.current_node&.projects_include?(event_log.project_id)
end
def handle_repository_update(updated_event)
......
......@@ -317,6 +317,32 @@ describe GeoNode, type: :model do
end
end
describe '#projects_include?' do
let(:unsynced_project) { create(:project) }
it 'returns true without namespace restrictions' do
expect(node.projects_include?(unsynced_project.id)).to eq true
end
context 'with namespace restrictions' do
let(:synced_group) { create(:group) }
before do
node.update_attribute(:namespaces, [synced_group])
end
it 'returns true when project belongs to one of the namespaces' do
project_in_synced_group = create(:project, group: synced_group)
expect(node.projects_include?(project_in_synced_group.id)).to eq true
end
it 'returns false when project does not belong to one of the namespaces' do
expect(node.projects_include?(unsynced_project.id)).to eq false
end
end
end
describe '#restricted_project_ids' do
context 'without namespace restriction' do
it 'returns nil' do
......
......@@ -49,6 +49,42 @@ describe API::Geo do
end
end
describe 'POST /geo/receive_events when node has namespace restrictions' do
let(:synced_group) { create(:group) }
let(:secondary_node) { create(:geo_node, namespaces: [synced_group]) }
let(:push_payload) do
{
'event_name' => 'push',
'project' => {
'git_ssh_url' => 'git@example.com:mike/diaspora.git'
}
}
end
before(:each) do
allow(Gitlab::Geo).to receive(:current_node) { secondary_node }
allow_any_instance_of(::Geo::ScheduleRepoUpdateService).to receive(:execute)
allow_any_instance_of(::Geo::ScheduleRepoFetchService).to receive(:execute)
end
it 'responds with not found for projects that do not belong to selected namespaces to replicate' do
unsynced_project = create(:project)
post api('/geo/receive_events'), push_payload.merge('project_id' => unsynced_project.id), geo_token_header
expect(response).to have_http_status(404)
end
it 'responds with success for projects that belong to selected namespaces to replicate' do
project_in_synced_group = create(:project, group: synced_group)
post api('/geo/receive_events'), push_payload.merge('project_id' => project_in_synced_group.id), geo_token_header
expect(response).to have_http_status(201)
end
end
describe 'POST /geo/receive_events key events' do
before do
allow_any_instance_of(::Geo::ScheduleKeyChangeService).to receive(:execute)
......
require 'spec_helper'
describe Geo::ScheduleWikiRepoUpdateService do
describe '#execute' do
let(:group) { create(:group) }
let(:project_1) { create(:project) }
let(:project_2) { create(:project, group: group) }
let(:projects) do
[
{ 'id' => project_1.id, 'clone_url' => 'git@example.com:mike/diaspora.git' },
{ 'id' => project_2.id, 'clone_url' => 'git@example.com:asd/vim.git' }
]
end
subject { described_class.new(projects) }
it "enqueues a batch of IDs of wiki's projects to have their wiki repositories updated" do
create(:geo_node, :current)
expect(GeoWikiRepositoryUpdateWorker).to receive(:perform_async)
.once.with(project_1.id, 'git@example.com:mike/diaspora.git').and_return(spy)
expect(GeoWikiRepositoryUpdateWorker).to receive(:perform_async)
.once.with(project_2.id, 'git@example.com:asd/vim.git').and_return(spy)
subject.execute
end
context 'when node has namespace restrictions' do
it "does not enqueue IDs of wiki's projects that do not belong to selected namespaces to replicate" do
create(:geo_node, :current, namespaces: [group])
expect(GeoWikiRepositoryUpdateWorker).not_to receive(:perform_async)
.with(project_1.id, 'git@example.com:mike/diaspora.git')
expect(GeoWikiRepositoryUpdateWorker).to receive(:perform_async)
.once.with(project_2.id, 'git@example.com:asd/vim.git').and_return(spy)
subject.execute
end
end
end
end
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