Commit c3e7e5c4 authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre

Merge branch...

Merge branch '202037-geo-ssh-clone-pull-redirect-to-primary-when-selective-sync-enabled-and-project-not-selected-pre2' into 'master'

Geo: proxy_git_push_ssh to proxy_git_ssh rename

See merge request gitlab-org/gitlab!28181
parents a5ff3e26 fed7955f
......@@ -82,9 +82,9 @@ module API
end
end
# git push over SSH secondary -> primary related proxying logic
# git over SSH secondary endpoints -> primary related proxying logic
#
resource 'proxy_git_push_ssh' do
resource 'proxy_git_ssh' do
format :json
# Responsible for making HTTP GET /repo.git/info/refs?service=git-receive-pack
......@@ -97,11 +97,11 @@ module API
requires :primary_repo, type: String
end
end
post 'info_refs' do
post 'info_refs_receive_pack' do
authenticate_by_gitlab_shell_token!
params.delete(:secret_token)
response = Gitlab::Geo::GitPushSSHProxy.new(params['data']).info_refs
response = Gitlab::Geo::GitSSHProxy.new(params['data']).info_refs_receive_pack
status(response.code)
response.body
end
......@@ -117,11 +117,11 @@ module API
end
requires :output, type: String, desc: 'Output from git-receive-pack'
end
post 'push' do
post 'receive_pack' do
authenticate_by_gitlab_shell_token!
params.delete(:secret_token)
response = Gitlab::Geo::GitPushSSHProxy.new(params['data']).push(params['output'])
response = Gitlab::Geo::GitSSHProxy.new(params['data']).receive_pack(params['output'])
status(response.code)
response.body
end
......
......@@ -87,8 +87,8 @@ module EE
def custom_action_api_endpoints
[
api_v4_geo_proxy_git_push_ssh_info_refs_path,
api_v4_geo_proxy_git_push_ssh_push_path
api_v4_geo_proxy_git_ssh_info_refs_receive_pack_path,
api_v4_geo_proxy_git_ssh_receive_pack_path
]
end
end
......
......@@ -20,7 +20,7 @@ module EE
override :whitelisted_routes
def whitelisted_routes
super || geo_node_update_route? || geo_proxy_git_push_ssh_route? || geo_api_route?
super || geo_node_update_route? || geo_proxy_git_ssh_route? || geo_api_route?
end
def geo_node_update_route?
......@@ -37,10 +37,12 @@ module EE
end
end
def geo_proxy_git_push_ssh_route?
def geo_proxy_git_ssh_route?
routes = ::Gitlab::Middleware::ReadOnly::API_VERSIONS.map do |version|
%W(/api/v#{version}/geo/proxy_git_push_ssh/info_refs
/api/v#{version}/geo/proxy_git_push_ssh/push)
%W(
/api/v#{version}/geo/proxy_git_ssh/info_refs_receive_pack
/api/v#{version}/geo/proxy_git_ssh/receive_pack
)
end
routes.flatten.include?(request.path)
......
......@@ -2,12 +2,11 @@
module Gitlab
module Geo
class GitPushSSHProxy
class GitSSHProxy
HTTP_READ_TIMEOUT = 60
INFO_REFS_CONTENT_TYPE = 'application/x-git-upload-pack-request'.freeze
PUSH_CONTENT_TYPE = 'application/x-git-receive-pack-request'.freeze
PUSH_ACCEPT = 'application/x-git-receive-pack-result'.freeze
RECEIVE_PACK_REQUEST_CONTENT_TYPE = 'application/x-git-receive-pack-request'.freeze
RECEIVE_PACK_RESULT_CONTENT_TYPE = 'application/x-git-receive-pack-result'.freeze
MustBeASecondaryNode = Class.new(StandardError)
......@@ -50,28 +49,29 @@ module Gitlab
@data = data
end
def info_refs
# For git push
def info_refs_receive_pack
ensure_secondary!
url = "#{primary_repo}/info/refs?service=git-receive-pack"
headers = { 'Content-Type' => INFO_REFS_CONTENT_TYPE }
resp = get(url, headers)
resp.body = remove_http_service_fragment_from(resp.body) if resp.is_a?(Net::HTTPSuccess)
resp = get(url)
resp.body = remove_receive_pack_http_service_fragment_from(resp.body) if resp.is_a?(Net::HTTPSuccess)
APIResponse.from_http_response(resp, primary_repo)
rescue => e
handle_exception(e)
end
def push(encoded_info_refs_response)
# For git push
def receive_pack(encoded_info_refs_response)
ensure_secondary!
url = "#{primary_repo}/git-receive-pack"
headers = { 'Content-Type' => PUSH_CONTENT_TYPE, 'Accept' => PUSH_ACCEPT }
headers = { 'Content-Type' => RECEIVE_PACK_REQUEST_CONTENT_TYPE, 'Accept' => RECEIVE_PACK_RESULT_CONTENT_TYPE }
info_refs_response = Base64.decode64(encoded_info_refs_response)
resp = post(url, info_refs_response, headers)
APIResponse.from_http_response(resp, primary_repo)
rescue => e
handle_exception(e)
......@@ -109,7 +109,7 @@ module Gitlab
URI.parse(primary_repo).path.gsub(%r{^\/|\.git$}, '')
end
def get(url, headers)
def get(url, headers = {})
request(url, Net::HTTP::Get, headers)
end
......@@ -130,7 +130,7 @@ module Gitlab
http.start { http.request(req) }
end
def remove_http_service_fragment_from(body)
def remove_receive_pack_http_service_fragment_from(body)
# HTTP(S) and SSH responses are very similar, except for the fragment below.
# As we're performing a git HTTP(S) request here, we'll get a HTTP(s)
# suitable git response. However, we're executing in the context of an
......@@ -139,6 +139,7 @@ module Gitlab
#
# See Downloading Data > HTTP(S) section at:
# https://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols
#
body.gsub(/\A001f# service=git-receive-pack\n0000/, '')
end
......
......@@ -355,7 +355,7 @@ describe API::Geo do
end
end
describe '/geo/proxy_git_push_ssh' do
describe '/geo/proxy_git_ssh' do
let(:secret_token) { Gitlab::Shell.secret_token }
let(:primary_repo) { 'http://localhost:3001/testuser/repo.git' }
let(:data) { { primary_repo: primary_repo, gl_id: 'key-1', gl_username: 'testuser' } }
......@@ -364,10 +364,10 @@ describe API::Geo do
stub_current_geo_node(secondary_node)
end
describe 'POST /geo/proxy_git_push_ssh/info_refs' do
describe 'POST /geo/proxy_git_ssh/info_refs_receive_pack' do
context 'with all required params missing' do
it 'responds with 400' do
post api('/geo/proxy_git_push_ssh/info_refs'), params: nil
post api('/geo/proxy_git_ssh/info_refs_receive_pack'), params: nil
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eql('secret_token is missing, data is missing, data[gl_id] is missing, data[primary_repo] is missing')
......@@ -375,15 +375,15 @@ describe API::Geo do
end
context 'with all required params' do
let(:git_push_ssh_proxy) { double(Gitlab::Geo::GitPushSSHProxy) }
let(:git_push_ssh_proxy) { double(Gitlab::Geo::GitSSHProxy) }
before do
allow(Gitlab::Geo::GitPushSSHProxy).to receive(:new).with(data).and_return(git_push_ssh_proxy)
allow(Gitlab::Geo::GitSSHProxy).to receive(:new).with(data).and_return(git_push_ssh_proxy)
end
context 'with an invalid secret_token' do
it 'responds with 401' do
post(api('/geo/proxy_git_push_ssh/info_refs'), params: { secret_token: 'invalid', data: data })
post(api('/geo/proxy_git_ssh/info_refs_receive_pack'), params: { secret_token: 'invalid', data: data })
expect(response).to have_gitlab_http_status(:unauthorized)
expect(json_response['error']).to be_nil
......@@ -392,9 +392,9 @@ describe API::Geo do
context 'where an exception occurs' do
it 'responds with 500' do
expect(git_push_ssh_proxy).to receive(:info_refs).and_raise('deliberate exception raised')
expect(git_push_ssh_proxy).to receive(:info_refs_receive_pack).and_raise('deliberate exception raised')
post api('/geo/proxy_git_push_ssh/info_refs'), params: { secret_token: secret_token, data: data }
post api('/geo/proxy_git_ssh/info_refs_receive_pack'), params: { secret_token: secret_token, data: data }
expect(response).to have_gitlab_http_status(:internal_server_error)
expect(json_response['message']).to include('RuntimeError (deliberate exception raised)')
......@@ -404,7 +404,7 @@ describe API::Geo do
context 'with a valid secret token' do
let(:http_response) { double(Net::HTTPOK, code: 200, body: 'something here') }
let(:api_response) { Gitlab::Geo::GitPushSSHProxy::APIResponse.from_http_response(http_response, primary_repo) }
let(:api_response) { Gitlab::Geo::GitSSHProxy::APIResponse.from_http_response(http_response, primary_repo) }
before do
# Mocking a real Net::HTTPSuccess is very difficult as it's not
......@@ -413,9 +413,9 @@ describe API::Geo do
end
it 'responds with 200' do
expect(git_push_ssh_proxy).to receive(:info_refs).and_return(api_response)
expect(git_push_ssh_proxy).to receive(:info_refs_receive_pack).and_return(api_response)
post api('/geo/proxy_git_push_ssh/info_refs'), params: { secret_token: secret_token, data: data }
post api('/geo/proxy_git_ssh/info_refs_receive_pack'), params: { secret_token: secret_token, data: data }
expect(response).to have_gitlab_http_status(:ok)
expect(Base64.decode64(json_response['result'])).to eql('something here')
......@@ -424,10 +424,10 @@ describe API::Geo do
end
end
describe 'POST /geo/proxy_git_push_ssh/push' do
describe 'POST /geo/proxy_git_ssh/receive_pack' do
context 'with all required params missing' do
it 'responds with 400' do
post api('/geo/proxy_git_push_ssh/push'), params: nil
post api('/geo/proxy_git_ssh/receive_pack'), params: nil
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eql('secret_token is missing, data is missing, data[gl_id] is missing, data[primary_repo] is missing, output is missing')
......@@ -436,15 +436,15 @@ describe API::Geo do
context 'with all required params' do
let(:output) { Base64.encode64('info_refs content') }
let(:git_push_ssh_proxy) { double(Gitlab::Geo::GitPushSSHProxy) }
let(:git_push_ssh_proxy) { double(Gitlab::Geo::GitSSHProxy) }
before do
allow(Gitlab::Geo::GitPushSSHProxy).to receive(:new).with(data).and_return(git_push_ssh_proxy)
allow(Gitlab::Geo::GitSSHProxy).to receive(:new).with(data).and_return(git_push_ssh_proxy)
end
context 'with an invalid secret_token' do
it 'responds with 401' do
post(api('/geo/proxy_git_push_ssh/push'), params: { secret_token: 'invalid', data: data, output: output })
post(api('/geo/proxy_git_ssh/receive_pack'), params: { secret_token: 'invalid', data: data, output: output })
expect(response).to have_gitlab_http_status(:unauthorized)
expect(json_response['error']).to be_nil
......@@ -453,8 +453,8 @@ describe API::Geo do
context 'where an exception occurs' do
it 'responds with 500' do
expect(git_push_ssh_proxy).to receive(:push).and_raise('deliberate exception raised')
post api('/geo/proxy_git_push_ssh/push'), params: { secret_token: secret_token, data: data, output: output }
expect(git_push_ssh_proxy).to receive(:receive_pack).and_raise('deliberate exception raised')
post api('/geo/proxy_git_ssh/receive_pack'), params: { secret_token: secret_token, data: data, output: output }
expect(response).to have_gitlab_http_status(:internal_server_error)
expect(json_response['message']).to include('RuntimeError (deliberate exception raised)')
......@@ -464,7 +464,7 @@ describe API::Geo do
context 'with a valid secret token' do
let(:http_response) { double(Net::HTTPCreated, code: 201, body: 'something here', class: Net::HTTPCreated) }
let(:api_response) { Gitlab::Geo::GitPushSSHProxy::APIResponse.from_http_response(http_response, primary_repo) }
let(:api_response) { Gitlab::Geo::GitSSHProxy::APIResponse.from_http_response(http_response, primary_repo) }
before do
# Mocking a real Net::HTTPSuccess is very difficult as it's not
......@@ -473,9 +473,9 @@ describe API::Geo do
end
it 'responds with 201' do
expect(git_push_ssh_proxy).to receive(:push).with(output).and_return(api_response)
expect(git_push_ssh_proxy).to receive(:receive_pack).with(output).and_return(api_response)
post api('/geo/proxy_git_push_ssh/push'), params: { secret_token: secret_token, data: data, output: output }
post api('/geo/proxy_git_ssh/receive_pack'), params: { secret_token: secret_token, data: data, output: output }
expect(response).to have_gitlab_http_status(:created)
expect(Base64.decode64(json_response['result'])).to eql('something here')
......
......@@ -32,7 +32,7 @@ RSpec.shared_examples 'a read-only GitLab instance' do
{
'action' => 'geo_proxy_to_primary',
'data' => {
'api_endpoints' => %w{/api/v4/geo/proxy_git_push_ssh/info_refs /api/v4/geo/proxy_git_push_ssh/push},
'api_endpoints' => %w{/api/v4/geo/proxy_git_ssh/info_refs_receive_pack /api/v4/geo/proxy_git_ssh/receive_pack},
'primary_repo' => primary_repo_url
}
}
......
......@@ -10,7 +10,7 @@ module Gitlab
# {
# 'action' => 'geo_proxy_to_primary',
# 'data' => {
# 'api_endpoints' => %w{geo/proxy_git_push_ssh/info_refs geo/proxy_git_push_ssh/push},
# 'api_endpoints' => %w{geo/proxy_git_ssh/info_refs_receive_pack geo/proxy_git_ssh/receive_pack},
# 'gl_username' => user.username,
# 'primary_repo' => geo_primary_http_url_to_repo(project_or_wiki)
# }
......
......@@ -582,7 +582,7 @@ describe API::Internal::Base do
{
'action' => 'geo_proxy_to_primary',
'data' => {
'api_endpoints' => %w{geo/proxy_git_push_ssh/info_refs geo/proxy_git_push_ssh/push},
'api_endpoints' => %w{geo/proxy_git_ssh/info_refs_receive_pack geo/proxy_git_ssh/receive_pack},
'gl_username' => 'testuser',
'primary_repo' => 'http://localhost:3000/testuser/repo.git'
}
......
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