1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
# 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
|