diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/helpers/members_helpers.rb | 2 | ||||
-rw-r--r-- | lib/api/helpers/rate_limiter.rb | 5 | ||||
-rw-r--r-- | lib/api/users.rb | 6 | ||||
-rw-r--r-- | lib/gitlab.rb | 50 | ||||
-rw-r--r-- | lib/gitlab/application_rate_limiter.rb | 1 | ||||
-rw-r--r-- | lib/gitlab/experimentation.rb | 8 | ||||
-rw-r--r-- | lib/gitlab/metrics/samplers/action_cable_sampler.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/metrics/samplers/base_sampler.rb | 14 | ||||
-rw-r--r-- | lib/gitlab/metrics/samplers/ruby_sampler.rb | 4 | ||||
-rw-r--r-- | lib/gitlab_edition.rb | 50 |
10 files changed, 84 insertions, 60 deletions
diff --git a/lib/api/helpers/members_helpers.rb b/lib/api/helpers/members_helpers.rb index c2710be6c03..6c20993431d 100644 --- a/lib/api/helpers/members_helpers.rb +++ b/lib/api/helpers/members_helpers.rb @@ -50,7 +50,7 @@ module API end def find_all_members_for_group(group) - GroupMembersFinder.new(group).execute + GroupMembersFinder.new(group, current_user).execute(include_relations: [:inherited, :direct, :shared_from_groups]) end def present_members(members) diff --git a/lib/api/helpers/rate_limiter.rb b/lib/api/helpers/rate_limiter.rb index 7d87c74097d..0ad4f089907 100644 --- a/lib/api/helpers/rate_limiter.rb +++ b/lib/api/helpers/rate_limiter.rb @@ -10,6 +10,7 @@ module API # See app/controllers/concerns/check_rate_limit.rb for Rails controllers version module RateLimiter def check_rate_limit!(key, scope:, **options) + return if bypass_header_set? return unless rate_limiter.throttled?(key, scope: scope, **options) rate_limiter.log_request(request, "#{key}_request_limit".to_sym, current_user) @@ -24,6 +25,10 @@ module API def rate_limiter ::Gitlab::ApplicationRateLimiter end + + def bypass_header_set? + ::Gitlab::Throttle.bypass_header.present? && request.get_header(Gitlab::Throttle.bypass_header) == '1' + end end end end diff --git a/lib/api/users.rb b/lib/api/users.rb index ce0a0e9b502..efecc7593d0 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -142,11 +142,15 @@ module API get ":id", feature_category: :users do forbidden!('Not authorized!') unless current_user + if Feature.enabled?(:rate_limit_user_by_id_endpoint, type: :development) + check_rate_limit! :users_get_by_id, scope: current_user unless current_user.admin? + end + user = User.find_by(id: params[:id]) not_found!('User') unless user && can?(current_user, :read_user, user) - opts = { with: current_user&.admin? ? Entities::UserDetailsWithAdmin : Entities::User, current_user: current_user } + opts = { with: current_user.admin? ? Entities::UserDetailsWithAdmin : Entities::User, current_user: current_user } user, opts = with_custom_attributes(user, opts) present user, opts diff --git a/lib/gitlab.rb b/lib/gitlab.rb index d93d7acbaad..2449554d3c0 100644 --- a/lib/gitlab.rb +++ b/lib/gitlab.rb @@ -1,10 +1,15 @@ # frozen_string_literal: true require 'pathname' +require 'forwardable' + +require_relative 'gitlab_edition' module Gitlab - def self.root - Pathname.new(File.expand_path('..', __dir__)) + class << self + extend Forwardable + + def_delegators :GitlabEdition, :root, :extensions, :ee?, :ee, :jh?, :jh end def self.version_info @@ -89,47 +94,6 @@ module Gitlab Rails.env.development? || Rails.env.test? end - def self.extensions - if jh? - %w[ee jh] - elsif ee? - %w[ee] - else - %w[] - end - end - - def self.ee? - @is_ee ||= - # We use this method when the Rails environment is not loaded. This - # means that checking the presence of the License class could result in - # this method returning `false`, even for an EE installation. - # - # The `FOSS_ONLY` is always `string` or `nil` - # Thus the nil or empty string will result - # in using default value: false - # - # The behavior needs to be synchronised with - # config/helpers/is_ee_env.js - root.join('ee/app/models/license.rb').exist? && - !%w[true 1].include?(ENV['FOSS_ONLY'].to_s) - end - - def self.jh? - @is_jh ||= - ee? && - root.join('jh').exist? && - !%w[true 1].include?(ENV['EE_ONLY'].to_s) - end - - def self.ee - yield if ee? - end - - def self.jh - yield if jh? - end - def self.http_proxy_env? HTTP_PROXY_ENV_VARS.any? { |name| ENV[name] } end diff --git a/lib/gitlab/application_rate_limiter.rb b/lib/gitlab/application_rate_limiter.rb index fb90ad9e275..5125d566524 100644 --- a/lib/gitlab/application_rate_limiter.rb +++ b/lib/gitlab/application_rate_limiter.rb @@ -49,6 +49,7 @@ module Gitlab group_testing_hook: { threshold: 5, interval: 1.minute }, profile_add_new_email: { threshold: 5, interval: 1.minute }, web_hook_calls: { interval: 1.minute }, + users_get_by_id: { threshold: 10, interval: 1.minute }, profile_resend_email_confirmation: { threshold: 5, interval: 1.minute }, update_environment_canary_ingress: { threshold: 1, interval: 1.minute }, auto_rollback_deployment: { threshold: 1, interval: 3.minutes } diff --git a/lib/gitlab/experimentation.rb b/lib/gitlab/experimentation.rb index 4cc653bec43..7edda290204 100644 --- a/lib/gitlab/experimentation.rb +++ b/lib/gitlab/experimentation.rb @@ -30,14 +30,6 @@ module Gitlab module Experimentation EXPERIMENTS = { - remove_known_trial_form_fields_welcoming: { - tracking_category: 'Growth::Conversion::Experiment::RemoveKnownTrialFormFieldsWelcoming', - rollout_strategy: :user - }, - remove_known_trial_form_fields_noneditable: { - tracking_category: 'Growth::Conversion::Experiment::RemoveKnownTrialFormFieldsNoneditable', - rollout_strategy: :user - } }.freeze class << self diff --git a/lib/gitlab/metrics/samplers/action_cable_sampler.rb b/lib/gitlab/metrics/samplers/action_cable_sampler.rb index adce3030d0d..1f50371cae9 100644 --- a/lib/gitlab/metrics/samplers/action_cable_sampler.rb +++ b/lib/gitlab/metrics/samplers/action_cable_sampler.rb @@ -6,8 +6,8 @@ module Gitlab class ActionCableSampler < BaseSampler DEFAULT_SAMPLING_INTERVAL_SECONDS = 5 - def initialize(interval = nil, action_cable: ::ActionCable.server) - super(interval) + def initialize(action_cable: ::ActionCable.server, **options) + super(**options) @action_cable = action_cable end diff --git a/lib/gitlab/metrics/samplers/base_sampler.rb b/lib/gitlab/metrics/samplers/base_sampler.rb index 52d80c3c27e..b2a9de21145 100644 --- a/lib/gitlab/metrics/samplers/base_sampler.rb +++ b/lib/gitlab/metrics/samplers/base_sampler.rb @@ -9,7 +9,10 @@ module Gitlab attr_reader :interval # interval - The sampling interval in seconds. - def initialize(interval = nil) + # warmup - When true, takes a single sample eagerly before entering the sampling loop. + # This can be useful to ensure that all metrics files exist after `start` returns, + # since prometheus-client-mmap creates them lazily upon first access. + def initialize(interval: nil, logger: Logger.new($stdout), warmup: false, **options) interval ||= ENV[interval_env_key]&.to_i interval ||= self.class::DEFAULT_SAMPLING_INTERVAL_SECONDS interval_half = interval.to_f / 2 @@ -17,13 +20,16 @@ module Gitlab @interval = interval @interval_steps = (-interval_half..interval_half).step(0.1).to_a - super() + @logger = logger + @warmup = warmup + + super(**options) end def safe_sample sample rescue StandardError => e - ::Gitlab::AppLogger.warn("#{self.class}: #{e}, stopping") + @logger.warn("#{self.class}: #{e}, stopping") stop end @@ -63,6 +69,8 @@ module Gitlab def start_working @running = true + safe_sample if @warmup + true end diff --git a/lib/gitlab/metrics/samplers/ruby_sampler.rb b/lib/gitlab/metrics/samplers/ruby_sampler.rb index b1c5e9800da..d71ee671b8d 100644 --- a/lib/gitlab/metrics/samplers/ruby_sampler.rb +++ b/lib/gitlab/metrics/samplers/ruby_sampler.rb @@ -7,12 +7,12 @@ module Gitlab DEFAULT_SAMPLING_INTERVAL_SECONDS = 60 GC_REPORT_BUCKETS = [0.01, 0.05, 0.1, 0.2, 0.3, 0.5, 1].freeze - def initialize(*) + def initialize(...) GC::Profiler.clear metrics[:process_start_time_seconds].set(labels, Time.now.to_i) - super + super(...) end def metrics diff --git a/lib/gitlab_edition.rb b/lib/gitlab_edition.rb new file mode 100644 index 00000000000..6eb6b52c357 --- /dev/null +++ b/lib/gitlab_edition.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'pathname' + +module GitlabEdition + def self.root + Pathname.new(File.expand_path('..', __dir__)) + end + + def self.extensions + if jh? + %w[ee jh] + elsif ee? + %w[ee] + else + %w[] + end + end + + def self.ee? + @is_ee ||= + # We use this method when the Rails environment is not loaded. This + # means that checking the presence of the License class could result in + # this method returning `false`, even for an EE installation. + # + # The `FOSS_ONLY` is always `string` or `nil` + # Thus the nil or empty string will result + # in using default value: false + # + # The behavior needs to be synchronised with + # config/helpers/is_ee_env.js + root.join('ee/app/models/license.rb').exist? && + !%w[true 1].include?(ENV['FOSS_ONLY'].to_s) + end + + def self.jh? + @is_jh ||= + ee? && + root.join('jh').exist? && + !%w[true 1].include?(ENV['EE_ONLY'].to_s) + end + + def self.ee + yield if ee? + end + + def self.jh + yield if jh? + end +end |