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