diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2024-01-16 13:42:19 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2024-01-16 13:42:19 +0300 |
commit | 84d1bd786125c1c14a3ba5f63e38a4cc736a9027 (patch) | |
tree | f550fa965f507077e20dbb6d61a8269a99ef7107 /lib/api/terraform/modules | |
parent | 3a105e36e689f7b75482236712f1a47fd5a76814 (diff) |
Add latest changes from gitlab-org/gitlab@16-8-stable-eev16.8.0-rc42
Diffstat (limited to 'lib/api/terraform/modules')
-rw-r--r-- | lib/api/terraform/modules/v1/namespace_packages.rb (renamed from lib/api/terraform/modules/v1/packages.rb) | 65 | ||||
-rw-r--r-- | lib/api/terraform/modules/v1/project_packages.rb | 215 |
2 files changed, 190 insertions, 90 deletions
diff --git a/lib/api/terraform/modules/v1/packages.rb b/lib/api/terraform/modules/v1/namespace_packages.rb index 9e82a849c98..1999fc42aba 100644 --- a/lib/api/terraform/modules/v1/packages.rb +++ b/lib/api/terraform/modules/v1/namespace_packages.rb @@ -4,7 +4,7 @@ module API module Terraform module Modules module V1 - class Packages < ::API::Base + class NamespacePackages < ::API::Base include ::API::Helpers::Authentication helpers ::API::Helpers::PackagesHelpers helpers ::API::Helpers::Packages::BasicAuthHelpers @@ -29,8 +29,10 @@ module API end helpers do + include ::Gitlab::Utils::StrongMemoize + params :module_name do - requires :module_name, type: String, desc: "", regexp: API::NO_SLASH_URL_PART_REGEX + requires :module_name, type: String, desc: '', regexp: API::NO_SLASH_URL_PART_REGEX requires :module_system, type: String, regexp: API::NO_SLASH_URL_PART_REGEX end @@ -39,10 +41,9 @@ module API end def module_namespace - strong_memoize(:module_namespace) do - find_namespace(params[:module_namespace]) - end + find_namespace(params[:module_namespace]) end + strong_memoize_attr :module_namespace def finder_params { @@ -55,26 +56,23 @@ module API end def packages - strong_memoize(:packages) do - ::Packages::GroupPackagesFinder.new( - current_user, - module_namespace, - finder_params - ).execute - end + ::Packages::GroupPackagesFinder.new( + current_user, + module_namespace, + finder_params + ).execute end + strong_memoize_attr :packages def package - strong_memoize(:package) do - packages.first - end + packages.first end + strong_memoize_attr :package def package_file - strong_memoize(:package_file) do - package.installable_package_files.first - end + package.installable_package_files.first end + strong_memoize_attr :package_file end params do @@ -82,7 +80,8 @@ module API includes :module_name end - namespace 'packages/terraform/modules/v1/:module_namespace/:module_name/:module_system', requirements: TERRAFORM_MODULE_REQUIREMENTS do + namespace 'packages/terraform/modules/v1/:module_namespace/:module_name/:module_system', + requirements: TERRAFORM_MODULE_REQUIREMENTS do authenticate_with do |accept| accept.token_types(:personal_access_token, :deploy_token, :job_token) .sent_through(:http_bearer_token) @@ -118,7 +117,9 @@ module API get 'download' do latest_version = packages.order_version.last&.version - render_api_error!({ error: "No version found for #{params[:module_name]} module" }, :not_found) if latest_version.nil? + if latest_version.nil? + render_api_error!({ error: "No version found for #{params[:module_name]} module" }, :not_found) + end download_path = api_v4_packages_terraform_modules_v1_module_version_download_path( { @@ -145,7 +146,9 @@ module API get do latest_package = packages.order_version.last - render_api_error!({ error: "No version found for #{params[:module_name]} module" }, :not_found) if latest_package&.version.nil? + if latest_package&.version.nil? + render_api_error!({ error: "No version found for #{params[:module_name]} module" }, :not_found) + end presenter = ::Terraform::ModuleVersionPresenter.new(latest_package, params[:module_system]) present presenter, with: ::API::Entities::Terraform::ModuleVersion @@ -181,13 +184,18 @@ module API jwt_token = Gitlab::TerraformRegistryToken.from_token(token_from_namespace_inheritable).encoded end - header 'X-Terraform-Get', module_file_path.sub(%r{module_version/file$}, "#{params[:module_version]}/file?token=#{jwt_token}&archive=tgz") + header 'X-Terraform-Get', + module_file_path.sub( + %r{module_version/file$}, + "#{params[:module_version]}/file?token=#{jwt_token}&archive=tgz" + ) status :no_content end namespace 'file' do authenticate_with do |accept| - accept.token_types(:deploy_token_from_jwt, :job_token_from_jwt, :personal_access_token_from_jwt).sent_through(:token_param) + accept.token_types(:deploy_token_from_jwt, :job_token_from_jwt, :personal_access_token_from_jwt) + .sent_through(:token_param) end desc 'Download specific version of a module' do @@ -200,9 +208,14 @@ module API tags %w[terraform_registry] end get do - track_package_event('pull_package', :terraform_module, project: package.project, namespace: module_namespace) - - present_carrierwave_file!(package_file.file) + track_package_event( + 'pull_package', + :terraform_module, + project: package.project, + namespace: module_namespace + ) + + present_package_file!(package_file) end end diff --git a/lib/api/terraform/modules/v1/project_packages.rb b/lib/api/terraform/modules/v1/project_packages.rb index 07dfddefefc..c0a84c7b36c 100644 --- a/lib/api/terraform/modules/v1/project_packages.rb +++ b/lib/api/terraform/modules/v1/project_packages.rb @@ -16,87 +16,174 @@ module API require_packages_enabled! end - params do - requires :id, type: String, desc: 'The ID or full path of a project' - requires :module_name, type: String, desc: "", regexp: API::NO_SLASH_URL_PART_REGEX - requires :module_system, type: String, regexp: API::NO_SLASH_URL_PART_REGEX - requires :module_version, type: String, desc: 'Module version', regexp: Gitlab::Regex.semver_regex - end + helpers do + params :terraform_get do + optional 'terraform-get', type: String, values: %w[1], desc: 'Terraform get redirection flag' + end - resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do - namespace ':id/packages/terraform/modules/:module_name/:module_system/*module_version/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) + 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 - 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] + 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 + end - put 'authorize' do - authorize_workhorse!( - subject: authorized_user_project, - maximum_size: authorized_user_project.actual_limits.terraform_module_max_file_size - ) + 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 'Upload Terraform Module package file' do - detail 'This feature was introduced in GitLab 13.11' - success code: 201 + desc 'Download the latest version of a module' do + detail 'This feature was introduced in GitLab 16.7' + success code: 204 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' } + use :terraform_get + end + get do + present_package_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[:http_status]) if result[:status] == :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! + 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!( + subject: authorized_user_project, + maximum_size: authorized_user_project.actual_limits.terraform_module_max_file_size + ) + 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 |