2021-01-03 14:25:43 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
module BulkImports
|
|
|
|
module Clients
|
2021-09-04 01:27:46 +05:30
|
|
|
class HTTP
|
2021-11-18 22:05:49 +05:30
|
|
|
include Gitlab::Utils::StrongMemoize
|
|
|
|
|
2021-04-29 21:17:54 +05:30
|
|
|
API_VERSION = 'v4'
|
|
|
|
DEFAULT_PAGE = 1
|
|
|
|
DEFAULT_PER_PAGE = 30
|
2021-01-03 14:25:43 +05:30
|
|
|
|
2021-09-30 23:02:18 +05:30
|
|
|
def initialize(url:, token:, page: DEFAULT_PAGE, per_page: DEFAULT_PER_PAGE, api_version: API_VERSION)
|
|
|
|
@url = url
|
2021-01-03 14:25:43 +05:30
|
|
|
@token = token&.strip
|
|
|
|
@page = page
|
|
|
|
@per_page = per_page
|
|
|
|
@api_version = api_version
|
2021-09-30 23:02:18 +05:30
|
|
|
@compatible_instance_version = false
|
2021-01-03 14:25:43 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def get(resource, query = {})
|
2021-09-04 01:27:46 +05:30
|
|
|
request(:get, resource, query: query.reverse_merge(request_query))
|
2021-01-29 00:20:46 +05:30
|
|
|
end
|
|
|
|
|
2021-06-08 01:23:25 +05:30
|
|
|
def post(resource, body = {})
|
2021-09-04 01:27:46 +05:30
|
|
|
request(:post, resource, body: body)
|
|
|
|
end
|
|
|
|
|
|
|
|
def head(resource)
|
|
|
|
request(:head, resource)
|
|
|
|
end
|
|
|
|
|
|
|
|
def stream(resource, &block)
|
|
|
|
request(:get, resource, stream_body: true, &block)
|
2021-06-08 01:23:25 +05:30
|
|
|
end
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
def each_page(method, resource, query = {}, &block)
|
2022-08-27 11:52:29 +05:30
|
|
|
return to_enum(__method__, method, resource, query) unless block
|
2021-01-29 00:20:46 +05:30
|
|
|
|
|
|
|
next_page = @page
|
2021-01-03 14:25:43 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
while next_page
|
|
|
|
@page = next_page.to_i
|
|
|
|
|
|
|
|
response = self.public_send(method, resource, query) # rubocop: disable GitlabSecurity/PublicSend
|
|
|
|
collection = response.parsed_response
|
|
|
|
next_page = response.headers['x-next-page'].presence
|
|
|
|
|
|
|
|
yield collection
|
|
|
|
end
|
2021-01-03 14:25:43 +05:30
|
|
|
end
|
|
|
|
|
2021-09-04 01:27:46 +05:30
|
|
|
def resource_url(resource)
|
|
|
|
Gitlab::Utils.append_path(api_url, resource)
|
|
|
|
end
|
|
|
|
|
2021-11-18 22:05:49 +05:30
|
|
|
def instance_version
|
|
|
|
strong_memoize(:instance_version) do
|
2023-01-13 00:05:48 +05:30
|
|
|
response = begin
|
|
|
|
with_error_handling do
|
|
|
|
Gitlab::HTTP.get(resource_url(:version), default_options)
|
|
|
|
end
|
|
|
|
rescue BulkImports::NetworkError
|
|
|
|
# `version` endpoint is not available, try `metadata` endpoint instead
|
|
|
|
with_error_handling do
|
|
|
|
Gitlab::HTTP.get(resource_url(:metadata), default_options)
|
|
|
|
end
|
2021-11-18 22:05:49 +05:30
|
|
|
end
|
2021-09-30 23:02:18 +05:30
|
|
|
|
2021-11-18 22:05:49 +05:30
|
|
|
Gitlab::VersionInfo.parse(response.parsed_response['version'])
|
2021-09-30 23:02:18 +05:30
|
|
|
end
|
2021-11-18 22:05:49 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def compatible_for_project_migration?
|
|
|
|
instance_version >= BulkImport.min_gl_version_for_project_migration
|
|
|
|
end
|
2021-09-30 23:02:18 +05:30
|
|
|
|
2021-11-18 22:05:49 +05:30
|
|
|
private
|
|
|
|
|
|
|
|
def validate_instance_version!
|
|
|
|
return if @compatible_instance_version
|
2021-09-30 23:02:18 +05:30
|
|
|
|
2021-11-18 22:05:49 +05:30
|
|
|
if instance_version.major < BulkImport::MIN_MAJOR_VERSION
|
2021-09-30 23:02:18 +05:30
|
|
|
raise ::BulkImports::Error.unsupported_gitlab_version
|
|
|
|
else
|
|
|
|
@compatible_instance_version = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-09-04 01:27:46 +05:30
|
|
|
# rubocop:disable GitlabSecurity/PublicSend
|
|
|
|
def request(method, resource, options = {}, &block)
|
2021-09-30 23:02:18 +05:30
|
|
|
validate_instance_version!
|
|
|
|
|
2021-09-04 01:27:46 +05:30
|
|
|
with_error_handling do
|
|
|
|
Gitlab::HTTP.public_send(
|
|
|
|
method,
|
|
|
|
resource_url(resource),
|
|
|
|
request_options(options),
|
|
|
|
&block
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
# rubocop:enable GitlabSecurity/PublicSend
|
|
|
|
|
|
|
|
def request_options(options)
|
|
|
|
default_options.merge(options)
|
|
|
|
end
|
|
|
|
|
|
|
|
def default_options
|
|
|
|
{
|
2022-08-27 11:52:29 +05:30
|
|
|
headers: { 'Content-Type' => 'application/json' },
|
|
|
|
query: request_query,
|
|
|
|
follow_redirects: true,
|
|
|
|
resend_on_redirect: false,
|
|
|
|
limit: 2
|
2021-09-04 01:27:46 +05:30
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
def request_query
|
|
|
|
{
|
|
|
|
page: @page,
|
2022-08-27 11:52:29 +05:30
|
|
|
per_page: @per_page,
|
|
|
|
private_token: @token
|
2021-01-03 14:25:43 +05:30
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def with_error_handling
|
|
|
|
response = yield
|
|
|
|
|
2022-05-07 20:08:51 +05:30
|
|
|
raise ::BulkImports::NetworkError.new("Unsuccessful response #{response.code} from #{response.request.path.path}. Body: #{response.parsed_response}", response: response) unless response.success?
|
2021-01-03 14:25:43 +05:30
|
|
|
|
|
|
|
response
|
|
|
|
rescue *Gitlab::HTTP::HTTP_ERRORS => e
|
2021-11-18 22:05:49 +05:30
|
|
|
raise ::BulkImports::NetworkError, e
|
2021-01-03 14:25:43 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def api_url
|
2021-09-30 23:02:18 +05:30
|
|
|
Gitlab::Utils.append_path(@url, "/api/#{@api_version}")
|
2021-01-03 14:25:43 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|