Commit e5f9ccee authored by Ash McKenzie's avatar Ash McKenzie

Add GitPushSSHProxy.inform_client_message

b82f5aa5
parent 15976edf
......@@ -37,8 +37,9 @@ module EE
payload = {
'action' => 'geo_proxy_to_primary',
'data' => {
'api_endpoints' => [api_v4_geo_proxy_git_push_ssh_info_refs_path, api_v4_geo_proxy_git_push_ssh_push_path],
'primary_repo' => geo_primary_http_url_to_repo(project_or_wiki)
'info_message' => proxying_to_primary_message,
'api_endpoints' => custom_action_api_endpoints,
'primary_repo' => primary_http_repo_url
}
}
......@@ -63,6 +64,25 @@ module EE
geo_primary_http_url_to_repo(project_or_wiki)
end
end
def primary_http_repo_url
geo_primary_http_url_to_repo(project_or_wiki)
end
def primary_ssh_url_to_repo
geo_primary_ssh_url_to_repo(project_or_wiki)
end
def proxying_to_primary_message
::Gitlab::Geo::GitPushSSHProxy.inform_client_message(primary_ssh_url_to_repo)
end
def custom_action_api_endpoints
[
api_v4_geo_proxy_git_push_ssh_info_refs_path,
api_v4_geo_proxy_git_push_ssh_push_path
]
end
end
end
end
......@@ -11,10 +11,49 @@ module Gitlab
MustBeASecondaryNode = Class.new(StandardError)
class APIResponse
attr_reader :code, :body
def initialize(code, body)
@code = code
@body = body
end
def self.from_http_response(response, primary_repo)
success = response.is_a?(Net::HTTPSuccess)
body = response.body.to_s
if success
result = Base64.encode64(body)
else
message = failed_message(body, primary_repo)
end
new(response.code.to_i, status: success, message: message, result: result)
end
def self.failed_message(str, primary_repo)
"Failed to contact primary #{primary_repo}\nError: #{str}"
end
end
class FailedAPIResponse < APIResponse
def self.from_exception(ex_message, primary_repo, code: 500)
new(code.to_i,
status: false,
message: failed_message(ex_message, primary_repo),
result: nil)
end
end
def initialize(data)
@data = data
end
def self.inform_client_message(primary_repo_ssh)
"You're pushing to a Geo secondary.\nWe'll help you by proxying this request to the primary: #{primary_repo_ssh}"
end
def info_refs
ensure_secondary!
......
......@@ -27,6 +27,7 @@ describe Gitlab::Geo::GitPushSSHProxy, :geo do
end
let(:primary_repo_http) { geo_primary_http_url_to_repo(project) }
let(:primary_repo_ssh) { geo_primary_ssh_url_to_repo(project) }
let(:data) do
{
......@@ -35,78 +36,83 @@ describe Gitlab::Geo::GitPushSSHProxy, :geo do
}
end
subject { described_class.new(data) }
before do
stub_current_geo_node(current_node)
allow(Gitlab::Geo::BaseRequest).to receive(:new).and_return(base_request)
allow(base_request).to receive(:authorization).and_return('secret')
describe '.inform_client_message' do
it 'returns a message, with the ssh address' do
expect(described_class.inform_client_message(primary_repo_ssh)).to eql("You're pushing to a Geo secondary.\nWe'll help you by proxying this request to the primary: #{primary_repo_ssh}")
end
end
describe '#info_refs' do
context 'against primary node' do
let(:current_node) { primary_node }
context 'instance methods' do
subject { described_class.new(data) }
it 'raises an exception' do
expect do
subject.info_refs
end.to raise_error(described_class::MustBeASecondaryNode, 'Node is not a secondary or there is no primary Geo node')
end
before do
stub_current_geo_node(current_node)
allow(Gitlab::Geo::BaseRequest).to receive(:new).and_return(base_request)
allow(base_request).to receive(:authorization).and_return('secret')
end
context 'against secondary node' do
let(:current_node) { secondary_node }
describe '#info_refs' do
context 'against primary node' do
let(:current_node) { primary_node }
let(:full_info_refs_url) { "#{primary_repo_http}/info/refs?service=git-receive-pack" }
let(:info_refs_headers) { base_headers.merge('Content-Type' => 'application/x-git-upload-pack-request') }
let(:info_refs_http_body_full) do
"001f# service=git-receive-pack
0000#{info_refs_body_short}"
it 'raises an exception' do
expect do
subject.info_refs
end.to raise_error(described_class::MustBeASecondaryNode, 'Node is not a secondary or there is no primary Geo node')
end
end
before do
stub_request(:get, full_info_refs_url).to_return(status: 200, body: info_refs_http_body_full, headers: info_refs_headers)
end
context 'against secondary node' do
let(:current_node) { secondary_node }
it 'returns a Net::HTTPOK' do
expect(subject.info_refs).to be_a(Net::HTTPOK)
end
let(:full_info_refs_url) { "#{primary_repo_http}/info/refs?service=git-receive-pack" }
let(:info_refs_headers) { base_headers.merge('Content-Type' => 'application/x-git-upload-pack-request') }
let(:info_refs_http_body_full) { "001f# service=git-receive-pack\n0000#{info_refs_body_short}" }
it 'returns a modified body' do
expect(subject.info_refs.body).to eql(info_refs_body_short)
end
end
end
before do
stub_request(:get, full_info_refs_url).to_return(status: 200, body: info_refs_http_body_full, headers: info_refs_headers)
end
describe '#push' do
context 'against primary node' do
let(:current_node) { primary_node }
it 'returns a Net::HTTPOK' do
expect(subject.info_refs).to be_a(Net::HTTPOK)
end
it 'raises an exception' do
expect do
subject.push(info_refs_body_short)
end.to raise_error(described_class::MustBeASecondaryNode)
it 'returns a modified body' do
expect(subject.info_refs.body).to eql(info_refs_body_short)
end
end
end
context 'against secondary node' do
let(:current_node) { secondary_node }
describe '#push' do
context 'against primary node' do
let(:current_node) { primary_node }
let(:full_git_receive_pack_url) { "#{primary_repo_http}/git-receive-pack" }
let(:push_headers) do
base_headers.merge(
'Content-Type' => 'application/x-git-receive-pack-request',
'Accept' => 'application/x-git-receive-pack-result'
)
it 'raises an exception' do
expect do
subject.push(info_refs_body_short)
end.to raise_error(described_class::MustBeASecondaryNode)
end
end
before do
stub_request(:post, full_git_receive_pack_url).to_return(status: 201, body: info_refs_body_short, headers: push_headers)
end
context 'against secondary node' do
let(:current_node) { secondary_node }
let(:full_git_receive_pack_url) { "#{primary_repo_http}/git-receive-pack" }
let(:push_headers) do
base_headers.merge(
'Content-Type' => 'application/x-git-receive-pack-request',
'Accept' => 'application/x-git-receive-pack-result'
)
end
before do
stub_request(:post, full_git_receive_pack_url).to_return(status: 201, body: info_refs_body_short, headers: push_headers)
end
it 'returns a Net::HTTPCreated' do
expect(subject.push(info_refs_body_short)).to be_a(Net::HTTPCreated)
it 'returns a Net::HTTPCreated' do
expect(subject.push(info_refs_body_short)).to be_a(Net::HTTPCreated)
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