201 lines
7.6 KiB
Ruby
201 lines
7.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module API
|
|
module Terraform
|
|
module Modules
|
|
module V1
|
|
class ProjectPackages < ::API::Base
|
|
include ::API::Helpers::Authentication
|
|
|
|
helpers ::API::Helpers::PackagesHelpers
|
|
helpers ::API::Helpers::Packages::BasicAuthHelpers
|
|
|
|
feature_category :package_registry
|
|
urgency :low
|
|
|
|
after_validation do
|
|
require_packages_enabled!
|
|
end
|
|
|
|
helpers do
|
|
params :terraform_get do
|
|
optional 'terraform-get', type: String, values: %w[1], desc: 'Terraform get redirection flag'
|
|
end
|
|
|
|
def present_package_file
|
|
authorize_read_package!(authorized_user_project)
|
|
|
|
if declared_params[:'terraform-get'] == '1'
|
|
header 'X-Terraform-Get', "#{request.url.split('?').first}?archive=tgz"
|
|
return no_content!
|
|
end
|
|
|
|
package = ::Packages::TerraformModule::PackagesFinder
|
|
.new(authorized_user_project, finder_params)
|
|
.execute
|
|
.first
|
|
|
|
not_found! unless package
|
|
|
|
track_package_event('pull_package', :terraform_module, project: authorized_user_project,
|
|
namespace: authorized_user_project.namespace)
|
|
|
|
present_package_file!(package.installable_package_files.first)
|
|
end
|
|
|
|
def finder_params
|
|
{ package_name: package_name }.tap do |finder_params|
|
|
finder_params[:package_version] = params[:module_version] if params.key?(:module_version)
|
|
end
|
|
end
|
|
|
|
def package_name
|
|
"#{params[:module_name]}/#{params[:module_system]}"
|
|
end
|
|
|
|
def authorize_workhorse_params
|
|
{
|
|
subject: authorized_user_project,
|
|
maximum_size: authorized_user_project.actual_limits.terraform_module_max_file_size,
|
|
use_final_store_path: true
|
|
}
|
|
end
|
|
end
|
|
|
|
params do
|
|
requires :id, types: [String, Integer], allow_blank: false, desc: 'The ID or full path of a project'
|
|
with(type: String, allow_blank: false, regexp: API::NO_SLASH_URL_PART_REGEX) do
|
|
requires :module_name, desc: 'Module name', documentation: { example: 'infra-registry' }
|
|
requires :module_system, desc: 'Module system', documentation: { example: 'aws' }
|
|
end
|
|
end
|
|
|
|
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
|
|
namespace ':id/packages/terraform/modules/:module_name/:module_system' do
|
|
authenticate_with do |accept|
|
|
accept.token_types(
|
|
:personal_access_token_with_username,
|
|
:deploy_token_with_username,
|
|
:job_token_with_username
|
|
).sent_through(:http_basic_auth)
|
|
end
|
|
|
|
desc 'Download the latest version of a module' do
|
|
detail 'This feature was introduced in GitLab 16.7'
|
|
success code: 204
|
|
failure [
|
|
{ code: 401, message: 'Unauthorized' },
|
|
{ code: 403, message: 'Forbidden' },
|
|
{ code: 404, message: 'Not found' }
|
|
]
|
|
tags %w[terraform_registry]
|
|
end
|
|
params do
|
|
use :terraform_get
|
|
end
|
|
get do
|
|
present_package_file
|
|
end
|
|
|
|
params do
|
|
requires :module_version, type: String, allow_blank: false, desc: 'Module version',
|
|
regexp: Gitlab::Regex.semver_regex
|
|
end
|
|
namespace '*module_version' do
|
|
desc 'Download a specific version of a module' do
|
|
detail 'This feature was introduced in GitLab 16.7'
|
|
success code: 204
|
|
failure [
|
|
{ code: 401, message: 'Unauthorized' },
|
|
{ code: 403, message: 'Forbidden' },
|
|
{ code: 404, message: 'Not found' }
|
|
]
|
|
tags %w[terraform_registry]
|
|
end
|
|
params do
|
|
use :terraform_get
|
|
end
|
|
get format: false do
|
|
present_package_file
|
|
end
|
|
|
|
namespace :file do
|
|
authenticate_with do |accept|
|
|
accept.token_types(:deploy_token).sent_through(:http_deploy_token_header)
|
|
accept.token_types(:job_token).sent_through(:http_job_token_header)
|
|
accept.token_types(:personal_access_token).sent_through(:http_private_token_header)
|
|
end
|
|
|
|
desc 'Workhorse authorize Terraform Module package file' do
|
|
detail 'This feature was introduced in GitLab 13.11'
|
|
success code: 200
|
|
failure [
|
|
{ code: 403, message: 'Forbidden' }
|
|
]
|
|
tags %w[terraform_registry]
|
|
end
|
|
|
|
put :authorize do
|
|
authorize_workhorse!(**authorize_workhorse_params)
|
|
end
|
|
|
|
desc 'Upload Terraform Module package file' do
|
|
detail 'This feature was introduced in GitLab 13.11'
|
|
success code: 201
|
|
failure [
|
|
{ code: 400, message: 'Invalid file' },
|
|
{ code: 401, message: 'Unauthorized' },
|
|
{ code: 403, message: 'Forbidden' },
|
|
{ code: 404, message: 'Not found' }
|
|
]
|
|
consumes %w[multipart/form-data]
|
|
tags %w[terraform_registry]
|
|
end
|
|
|
|
params do
|
|
requires :file, type: ::API::Validations::Types::WorkhorseFile,
|
|
desc: 'The package file to be published (generated by Multipart middleware)',
|
|
documentation: { type: 'file' }
|
|
end
|
|
|
|
put do
|
|
authorize_upload!(authorized_user_project)
|
|
|
|
bad_request!('File is too large') if authorized_user_project.actual_limits.exceeded?(
|
|
:terraform_module_max_file_size, params[:file].size
|
|
)
|
|
|
|
create_package_file_params = {
|
|
module_name: params['module_name'],
|
|
module_system: params['module_system'],
|
|
module_version: params['module_version'],
|
|
file: params['file'],
|
|
build: current_authenticated_job
|
|
}
|
|
|
|
result = ::Packages::TerraformModule::CreatePackageService
|
|
.new(authorized_user_project, current_user, create_package_file_params)
|
|
.execute
|
|
|
|
render_api_error!(result.message, result.reason) if result.error?
|
|
|
|
track_package_event('push_package', :terraform_module, project: authorized_user_project,
|
|
namespace: authorized_user_project.namespace)
|
|
|
|
created!
|
|
rescue ObjectStorage::RemoteStoreError => e
|
|
Gitlab::ErrorTracking.track_exception(e,
|
|
extra: { file_name: params[:file_name], project_id: authorized_user_project.id })
|
|
|
|
forbidden!
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|