diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-12-19 12:10:52 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-12-19 12:10:52 +0300 |
commit | 17295c75a1a28df78f719e0098dd31fe45ce0446 (patch) | |
tree | 0544bd2f74e72e45b4a62ff68a4736c26a02a832 /lib | |
parent | 6c2b987064064500b42da924d86d43473bfd2b7f (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/terraform/modules/v1/project_packages.rb | 215 | ||||
-rw-r--r-- | lib/feature/definition.rb | 16 | ||||
-rw-r--r-- | lib/feature/shared.rb | 63 | ||||
-rw-r--r-- | lib/gitlab/database_importers/work_items/hierarchy_restrictions_importer.rb | 5 | ||||
-rw-r--r-- | lib/gitlab/quick_actions/issuable_actions.rb | 8 | ||||
-rw-r--r-- | lib/gitlab/usage_data_counters/quick_action_activity_unique_counter.rb | 2 |
6 files changed, 212 insertions, 97 deletions
diff --git a/lib/api/terraform/modules/v1/project_packages.rb b/lib/api/terraform/modules/v1/project_packages.rb index 07dfddefefc..ff330b8479f 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[: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! + end + end end end end diff --git a/lib/feature/definition.rb b/lib/feature/definition.rb index af60fb95c53..14848f22f83 100644 --- a/lib/feature/definition.rb +++ b/lib/feature/definition.rb @@ -49,23 +49,27 @@ module Feature end unless type.present? - raise Feature::InvalidFeatureFlagError, "Feature flag '#{name}' is missing type. Ensure to update #{path}" + raise Feature::InvalidFeatureFlagError, "Feature flag '#{name}' is missing `type`. Ensure to update #{path}" end unless Definition::TYPES.include?(type.to_sym) raise Feature::InvalidFeatureFlagError, "Feature flag '#{name}' type '#{type}' is invalid. Ensure to update #{path}" end - unless File.basename(path, ".yml") == name + if File.basename(path, ".yml") != name || File.basename(File.dirname(path)) != type raise Feature::InvalidFeatureFlagError, "Feature flag '#{name}' has an invalid path: '#{path}'. Ensure to update #{path}" end - unless File.basename(File.dirname(path)) == type - raise Feature::InvalidFeatureFlagError, "Feature flag '#{name}' has an invalid type: '#{path}'. Ensure to update #{path}" - end + validate_default_enabled! + end + def validate_default_enabled! if default_enabled.nil? - raise Feature::InvalidFeatureFlagError, "Feature flag '#{name}' is missing default_enabled. Ensure to update #{path}" + raise Feature::InvalidFeatureFlagError, "Feature flag '#{name}' is missing `default_enabled`. Ensure to update #{path}" + end + + if default_enabled && !Definition::TYPES.dig(type.to_sym, :can_be_default_enabled) + raise Feature::InvalidFeatureFlagError, "Feature flag '#{name}' cannot have `default_enabled` set to `true`. Ensure to update #{path}" end end diff --git a/lib/feature/shared.rb b/lib/feature/shared.rb index d801070ff1a..fcce2642ef6 100644 --- a/lib/feature/shared.rb +++ b/lib/feature/shared.rb @@ -8,21 +8,39 @@ module Feature module Shared # optional: defines if a on-disk definition is required for this feature flag type # rollout_issue: defines if `bin/feature-flag` asks for rollout issue - # default_enabled: defines a default state of a feature flag when created by `bin/feature-flag` - # ee_only: defines that a feature flag can only be created in a context of EE + # can_be_default_enabled: whether the flag can have `default_enabled` set to `true` or not # deprecated: defines if a feature flag type that is deprecated and to be removed, # the deprecated types are hidden from all interfaces # example: usage being shown when exception is raised TYPES = { - development: { - description: 'Short lived, used to enable unfinished code to be deployed', + gitlab_com_derisk: { + description: 'Short lived, used to de-risk GitLab.com deployments', + optional: false, + rollout_issue: true, + can_be_default_enabled: false, + example: <<-EOS + Feature.enabled?(:my_feature_flag, project, type: :gitlab_com_derisk) + push_frontend_feature_flag(:my_feature_flag, project) + EOS + }, + wip: { + description: 'Used to hide unfinished code from anyone', + optional: false, + rollout_issue: false, + can_be_default_enabled: false, + example: <<-EOS + Feature.enabled?(:my_feature_flag, project, type: :wip) + push_frontend_feature_flag(:my_feature_flag, project) + EOS + }, + beta: { + description: "Use when we aren't confident about scaling/supporting a feature, " \ + "or when it isn't complete enough for an MVC", optional: false, rollout_issue: true, - ee_only: false, - default_enabled: false, + can_be_default_enabled: true, example: <<-EOS - Feature.enabled?(:my_feature_flag, project) - Feature.enabled?(:my_feature_flag, project, type: :development) + Feature.enabled?(:my_feature_flag, project, type: :beta) push_frontend_feature_flag(:my_feature_flag, project) EOS }, @@ -30,27 +48,17 @@ module Feature description: "Long-lived feature flags that control operational aspects of GitLab's behavior", optional: false, rollout_issue: true, - ee_only: false, - default_enabled: false, + can_be_default_enabled: true, example: <<-EOS Feature.enabled?(:my_ops_flag, type: :ops) push_frontend_feature_flag(:my_ops_flag, project, type: :ops) EOS }, - undefined: { - description: "Feature flags that are undefined in GitLab codebase (should not be used)", - optional: true, - rollout_issue: false, - ee_only: false, - default_enabled: false, - example: '' - }, experiment: { description: 'Short lived, used specifically to run A/B/n experiments.', optional: true, rollout_issue: true, - ee_only: false, - default_enabled: false, + can_be_default_enabled: false, example: <<-EOS experiment(:my_experiment, project: project, actor: current_user) { ...variant code... } EOS @@ -59,12 +67,22 @@ module Feature description: "Feature flags for controlling Sidekiq workers behavior (e.g. deferring jobs)", optional: true, rollout_issue: false, - ee_only: false, - default_enabled: false, + can_be_default_enabled: false, example: '<<-EOS Feature.enabled?(:"defer_sidekiq_jobs:AuthorizedProjectsWorker", type: :worker, default_enabled_if_undefined: false) EOS' + }, + undefined: { + description: "Feature flags that are undefined in GitLab codebase (should not be used)", + optional: true, + rollout_issue: false, + can_be_default_enabled: false, + example: '' + }, + development: { + deprecated: true, + can_be_default_enabled: true } }.freeze @@ -72,6 +90,7 @@ module Feature # This is done to ease the file comparison PARAMS = %i[ name + feature_issue_url introduced_by_url rollout_issue_url milestone diff --git a/lib/gitlab/database_importers/work_items/hierarchy_restrictions_importer.rb b/lib/gitlab/database_importers/work_items/hierarchy_restrictions_importer.rb index 4e3b685c06c..ec0d9c3f36e 100644 --- a/lib/gitlab/database_importers/work_items/hierarchy_restrictions_importer.rb +++ b/lib/gitlab/database_importers/work_items/hierarchy_restrictions_importer.rb @@ -66,7 +66,10 @@ module Gitlab def self.find_or_create_type(name) type = ::WorkItems::Type.find_by_name_and_namespace_id(name, nil) - return type if type + if type + type.clear_reactive_cache! + return type + end Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter.upsert_types ::WorkItems::Type.find_by_name_and_namespace_id(name, nil) diff --git a/lib/gitlab/quick_actions/issuable_actions.rb b/lib/gitlab/quick_actions/issuable_actions.rb index 2f7fa89019e..e4b195767ea 100644 --- a/lib/gitlab/quick_actions/issuable_actions.rb +++ b/lib/gitlab/quick_actions/issuable_actions.rb @@ -197,12 +197,12 @@ module Gitlab @updates[:subscription_event] = 'unsubscribe' end - desc { _('Toggle emoji award') } + desc { _('Toggle emoji reaction') } explanation do |name| - _("Toggles :%{name}: emoji award.") % { name: name } if name + _("Toggles :%{name}: emoji reaction.") % { name: name } if name end execution_message do |name| - _("Toggled :%{name}: emoji award.") % { name: name } if name + _("Toggled :%{name}: emoji reaction.") % { name: name } if name end params ':emoji:' types ::Issuable @@ -213,7 +213,7 @@ module Gitlab match = emoji_param.match(Banzai::Filter::EmojiFilter.emoji_pattern) match[1] if match end - command :award, :react do |name| + command :react, :award do |name| if name && quick_action_target.user_can_award?(current_user) @updates[:emoji_award] = name end diff --git a/lib/gitlab/usage_data_counters/quick_action_activity_unique_counter.rb b/lib/gitlab/usage_data_counters/quick_action_activity_unique_counter.rb index 557179ad57a..2e92afb5439 100644 --- a/lib/gitlab/usage_data_counters/quick_action_activity_unique_counter.rb +++ b/lib/gitlab/usage_data_counters/quick_action_activity_unique_counter.rb @@ -19,6 +19,8 @@ module Gitlab def prepare_name(name, args) case name + when 'react' + 'award' when 'assign' event_name_for_assign(args) when 'copy_metadata' |