summaryrefslogtreecommitdiff
path: root/lib/api/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'lib/api/helpers')
-rw-r--r--lib/api/helpers/caching.rb107
-rw-r--r--lib/api/helpers/groups_helpers.rb4
-rw-r--r--lib/api/helpers/integrations_helpers.rb (renamed from lib/api/helpers/services_helpers.rb)16
-rw-r--r--lib/api/helpers/projects_helpers.rb2
-rw-r--r--lib/api/helpers/runner.rb4
-rw-r--r--lib/api/helpers/snippets_helpers.rb18
6 files changed, 45 insertions, 106 deletions
diff --git a/lib/api/helpers/caching.rb b/lib/api/helpers/caching.rb
index f24ac7302c1..f567d85443f 100644
--- a/lib/api/helpers/caching.rb
+++ b/lib/api/helpers/caching.rb
@@ -8,18 +8,15 @@
module API
module Helpers
module Caching
- # @return [ActiveSupport::Duration]
- DEFAULT_EXPIRY = 1.day
-
+ include Gitlab::Cache::Helpers
# @return [Hash]
DEFAULT_CACHE_OPTIONS = {
- race_condition_ttl: 5.seconds
+ race_condition_ttl: 5.seconds,
+ version: 1
}.freeze
- # @return [ActiveSupport::Cache::Store]
- def cache
- Rails.cache
- end
+ # @return [Array]
+ PAGINATION_HEADERS = %w[X-Per-Page X-Page X-Next-Page X-Prev-Page Link X-Total X-Total-Pages].freeze
# This is functionally equivalent to the standard `#present` used in
# Grape endpoints, but the JSON for the object, or for each object of
@@ -45,7 +42,7 @@ module API
# @param expires_in [ActiveSupport::Duration, Integer] an expiry time for the cache entry
# @param presenter_args [Hash] keyword arguments to be passed to the entity
# @return [Gitlab::Json::PrecompiledJson]
- def present_cached(obj_or_collection, with:, cache_context: -> (_) { current_user&.cache_key }, expires_in: DEFAULT_EXPIRY, **presenter_args)
+ def present_cached(obj_or_collection, with:, cache_context: -> (_) { current_user&.cache_key }, expires_in: Gitlab::Cache::Helpers::DEFAULT_EXPIRY, **presenter_args)
json =
if obj_or_collection.is_a?(Enumerable)
cached_collection(
@@ -79,15 +76,22 @@ module API
# @param key [Object] any object that can be converted into a cache key
# @param expires_in [ActiveSupport::Duration, Integer] an expiry time for the cache entry
# @return [Gitlab::Json::PrecompiledJson]
- def cache_action(key, **cache_opts)
- json = cache.fetch(key, **apply_default_cache_options(cache_opts)) do
+ def cache_action(key, **custom_cache_opts)
+ cache_opts = apply_default_cache_options(custom_cache_opts)
+
+ json, cached_headers = cache.fetch(key, **cache_opts) do
response = yield
- if response.is_a?(Gitlab::Json::PrecompiledJson)
- response.to_s
- else
- Gitlab::Json.dump(response.as_json)
- end
+ cached_body = response.is_a?(Gitlab::Json::PrecompiledJson) ? response.to_s : Gitlab::Json.dump(response.as_json)
+ cached_headers = header.slice(*PAGINATION_HEADERS)
+
+ [cached_body, cached_headers]
+ end
+
+ cached_headers.each do |key, value|
+ next if header.key?(key)
+
+ header key, value
end
body Gitlab::Json::PrecompiledJson.new(json)
@@ -120,77 +124,6 @@ module API
def apply_default_cache_options(opts = {})
DEFAULT_CACHE_OPTIONS.merge(opts)
end
-
- # Optionally uses a `Proc` to add context to a cache key
- #
- # @param object [Object] must respond to #cache_key
- # @param context [Proc] a proc that will be called with the object as an argument, and which should return a
- # string or array of strings to be combined into the cache key
- # @return [String]
- def contextual_cache_key(object, context)
- return object.cache_key if context.nil?
-
- [object.cache_key, context.call(object)].flatten.join(":")
- end
-
- # Used for fetching or rendering a single object
- #
- # @param object [Object] the object to render
- # @param presenter [Grape::Entity]
- # @param presenter_args [Hash] keyword arguments to be passed to the entity
- # @param context [Proc]
- # @param expires_in [ActiveSupport::Duration, Integer] an expiry time for the cache entry
- # @return [String]
- def cached_object(object, presenter:, presenter_args:, context:, expires_in:)
- cache.fetch(contextual_cache_key(object, context), expires_in: expires_in) do
- Gitlab::Json.dump(presenter.represent(object, **presenter_args).as_json)
- end
- end
-
- # Used for fetching or rendering multiple objects
- #
- # @param objects [Enumerable<Object>] the objects to render
- # @param presenter [Grape::Entity]
- # @param presenter_args [Hash] keyword arguments to be passed to the entity
- # @param context [Proc]
- # @param expires_in [ActiveSupport::Duration, Integer] an expiry time for the cache entry
- # @return [Array<String>]
- def cached_collection(collection, presenter:, presenter_args:, context:, expires_in:)
- json = fetch_multi(collection, context: context, expires_in: expires_in) do |obj|
- Gitlab::Json.dump(presenter.represent(obj, **presenter_args).as_json)
- end
-
- json.values
- end
-
- # An adapted version of ActiveSupport::Cache::Store#fetch_multi.
- #
- # The original method only provides the missing key to the block,
- # not the missing object, so we have to create a map of cache keys
- # to the objects to allow us to pass the object to the missing value
- # block.
- #
- # The result is that this is functionally identical to `#fetch`.
- def fetch_multi(*objs, context:, **kwargs)
- objs.flatten!
- map = multi_key_map(objs, context: context)
-
- # TODO: `contextual_cache_key` should be constructed based on the guideline https://docs.gitlab.com/ee/development/redis.html#multi-key-commands.
- Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands do
- cache.fetch_multi(*map.keys, **kwargs) do |key|
- yield map[key]
- end
- end
- end
-
- # @param objects [Enumerable<Object>] objects which _must_ respond to `#cache_key`
- # @param context [Proc] a proc that can be called to help generate each cache key
- # @return [Hash]
- def multi_key_map(objects, context:)
- objects.index_by do |object|
- contextual_cache_key(object, context)
- end
- end
end
end
end
diff --git a/lib/api/helpers/groups_helpers.rb b/lib/api/helpers/groups_helpers.rb
index 5c5109f3d21..e38213532ba 100644
--- a/lib/api/helpers/groups_helpers.rb
+++ b/lib/api/helpers/groups_helpers.rb
@@ -30,6 +30,10 @@ module API
params :optional_params_ee do
end
+ params :optional_update_params do
+ optional :prevent_sharing_groups_outside_hierarchy, type: Boolean, desc: 'Prevent sharing groups within this namespace with any groups outside the namespace. Only available on top-level groups.'
+ end
+
params :optional_update_params_ee do
end
diff --git a/lib/api/helpers/services_helpers.rb b/lib/api/helpers/integrations_helpers.rb
index ca13ea0789a..06539772568 100644
--- a/lib/api/helpers/services_helpers.rb
+++ b/lib/api/helpers/integrations_helpers.rb
@@ -6,7 +6,7 @@ module API
#
# The data structures inside this model are returned using class methods,
# allowing EE to extend them where necessary.
- module ServicesHelpers
+ module IntegrationsHelpers
def self.chat_notification_settings
[
{
@@ -159,7 +159,7 @@ module API
].freeze
end
- def self.services
+ def self.integrations
{
'asana' => [
{
@@ -772,7 +772,7 @@ module API
}
end
- def self.service_classes
+ def self.integration_classes
[
::Integrations::Asana,
::Integrations::Assembla,
@@ -799,24 +799,24 @@ module API
::Integrations::Packagist,
::Integrations::PipelinesEmail,
::Integrations::Pivotaltracker,
+ ::Integrations::Prometheus,
::Integrations::Pushover,
::Integrations::Redmine,
::Integrations::Slack,
::Integrations::SlackSlashCommands,
::Integrations::Teamcity,
- ::Integrations::Youtrack,
- ::PrometheusService
+ ::Integrations::Youtrack
]
end
- def self.development_service_classes
+ def self.development_integration_classes
[
::Integrations::MockCi,
- ::MockMonitoringService
+ ::Integrations::MockMonitoring
]
end
end
end
end
-API::Helpers::ServicesHelpers.prepend_mod_with('API::Helpers::ServicesHelpers')
+API::Helpers::IntegrationsHelpers.prepend_mod_with('API::Helpers::IntegrationsHelpers')
diff --git a/lib/api/helpers/projects_helpers.rb b/lib/api/helpers/projects_helpers.rb
index 69a83043617..272452bd8db 100644
--- a/lib/api/helpers/projects_helpers.rb
+++ b/lib/api/helpers/projects_helpers.rb
@@ -66,6 +66,7 @@ module API
optional :autoclose_referenced_issues, type: Boolean, desc: 'Flag indication if referenced issues auto-closing is enabled'
optional :repository_storage, type: String, desc: 'Which storage shard the repository is on. Available only to admins'
optional :packages_enabled, type: Boolean, desc: 'Enable project packages feature'
+ optional :squash_option, type: String, values: %w(never always default_on default_off), desc: 'Squash default for project. One of `never`, `always`, `default_on`, or `default_off`.'
end
params :optional_project_params_ee do
@@ -145,6 +146,7 @@ module API
:request_access_enabled,
:resolve_outdated_diff_discussions,
:restrict_user_defined_variables,
+ :squash_option,
:shared_runners_enabled,
:snippets_access_level,
:tag_list,
diff --git a/lib/api/helpers/runner.rb b/lib/api/helpers/runner.rb
index 9ec9b5e1e35..a022d1a56ac 100644
--- a/lib/api/helpers/runner.rb
+++ b/lib/api/helpers/runner.rb
@@ -14,6 +14,10 @@ module API
ActiveSupport::SecurityUtils.secure_compare(params[:token], Gitlab::CurrentSettings.runners_registration_token)
end
+ def runner_registrar_valid?(type)
+ Feature.disabled?(:runner_registration_control) || Gitlab::CurrentSettings.valid_runner_registrars.include?(type)
+ end
+
def authenticate_runner!
forbidden! unless current_runner
diff --git a/lib/api/helpers/snippets_helpers.rb b/lib/api/helpers/snippets_helpers.rb
index 42f56680ded..2d8c761101a 100644
--- a/lib/api/helpers/snippets_helpers.rb
+++ b/lib/api/helpers/snippets_helpers.rb
@@ -72,22 +72,18 @@ module API
end
def process_create_params(args)
- with_api_params do |api_params|
- args[:snippet_actions] = args.delete(:files)&.map do |file|
- file[:action] = :create
- file.symbolize_keys
- end
-
- args.merge(api_params)
+ args[:snippet_actions] = args.delete(:files)&.map do |file|
+ file[:action] = :create
+ file.symbolize_keys
end
+
+ args
end
def process_update_params(args)
- with_api_params do |api_params|
- args[:snippet_actions] = args.delete(:files)&.map(&:symbolize_keys)
+ args[:snippet_actions] = args.delete(:files)&.map(&:symbolize_keys)
- args.merge(api_params)
- end
+ args
end
def validate_params_for_multiple_files(snippet)