summaryrefslogtreecommitdiff
path: root/lib/api/ci
diff options
context:
space:
mode:
Diffstat (limited to 'lib/api/ci')
-rw-r--r--lib/api/ci/helpers/runner.rb41
-rw-r--r--lib/api/ci/jobs.rb2
-rw-r--r--lib/api/ci/pipeline_schedules.rb1
-rw-r--r--lib/api/ci/pipelines.rb14
-rw-r--r--lib/api/ci/resource_groups.rb15
-rw-r--r--lib/api/ci/runner.rb19
-rw-r--r--lib/api/ci/runners.rb1
-rw-r--r--lib/api/ci/secure_files.rb8
-rw-r--r--lib/api/ci/triggers.rb1
-rw-r--r--lib/api/ci/variables.rb2
10 files changed, 79 insertions, 25 deletions
diff --git a/lib/api/ci/helpers/runner.rb b/lib/api/ci/helpers/runner.rb
index 173cfc9a59a..72e36d95dc5 100644
--- a/lib/api/ci/helpers/runner.rb
+++ b/lib/api/ci/helpers/runner.rb
@@ -53,7 +53,7 @@ module API
# https://gitlab.com/gitlab-org/gitlab/-/issues/327703
forbidden! unless job
- forbidden! unless job_token_valid?(job)
+ forbidden! unless job.valid_token?(job_token)
forbidden!('Project has been deleted!') if job.project.nil? || job.project.pending_delete?
forbidden!('Job has been erased!') if job.erased?
@@ -77,6 +77,12 @@ module API
job
end
+ def authenticate_job_via_dependent_job!
+ forbidden! unless current_authenticated_job
+ forbidden! unless current_job
+ forbidden! unless can?(current_authenticated_job.user, :read_build, current_job)
+ end
+
def current_job
id = params[:id]
@@ -91,9 +97,28 @@ module API
end
end
- def job_token_valid?(job)
- token = (params[JOB_TOKEN_PARAM] || env[JOB_TOKEN_HEADER]).to_s
- token && job.valid_token?(token)
+ # TODO: Replace this with `#current_authenticated_job from API::Helpers`
+ # after the feature flag `ci_authenticate_running_job_token_for_artifacts`
+ # is removed.
+ #
+ # For the time being, this needs to be overridden because the API
+ # GET api/v4/jobs/:id/artifacts
+ # needs to allow requests using token whose job is not running.
+ #
+ # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83713#note_942368526
+ def current_authenticated_job
+ strong_memoize(:current_authenticated_job) do
+ ::Ci::AuthJobFinder.new(token: job_token).execute
+ end
+ end
+
+ # The token used by runner to authenticate a request.
+ # In most cases, the runner uses the token belonging to the requested job.
+ # However, when requesting for job artifacts, the runner would use
+ # the token that belongs to downstream jobs that depend on the job that owns
+ # the artifacts.
+ def job_token
+ @job_token ||= (params[JOB_TOKEN_PARAM] || env[JOB_TOKEN_HEADER]).to_s
end
def job_forbidden!(job, reason)
@@ -111,11 +136,19 @@ module API
# noop: overridden in EE
end
+ def log_artifact_size(artifact)
+ Gitlab::ApplicationContext.push(artifact: artifact)
+ end
+
private
def get_runner_config_from_request
{ config: attributes_for_keys(%w(gpus), params.dig('info', 'config')) }
end
+
+ def request_using_running_job_token?
+ current_job.present? && current_authenticated_job.present? && current_job != current_authenticated_job
+ end
end
end
end
diff --git a/lib/api/ci/jobs.rb b/lib/api/ci/jobs.rb
index 86897eb61ae..04999b5fb44 100644
--- a/lib/api/ci/jobs.rb
+++ b/lib/api/ci/jobs.rb
@@ -190,7 +190,7 @@ module API
detail 'Retrieves a list of agents for the given job token'
end
route_setting :authentication, job_token_allowed: true
- get '/allowed_agents', feature_category: :kubernetes_management do
+ get '/allowed_agents', urgency: :low, feature_category: :kubernetes_management do
validate_current_authenticated_job
status 200
diff --git a/lib/api/ci/pipeline_schedules.rb b/lib/api/ci/pipeline_schedules.rb
index 6030fe86f00..4b522f37524 100644
--- a/lib/api/ci/pipeline_schedules.rb
+++ b/lib/api/ci/pipeline_schedules.rb
@@ -8,6 +8,7 @@ module API
before { authenticate! }
feature_category :continuous_integration
+ urgency :low
params do
requires :id, type: String, desc: 'The ID of a project'
diff --git a/lib/api/ci/pipelines.rb b/lib/api/ci/pipelines.rb
index 8d2c58dabdf..4253a9eb4d7 100644
--- a/lib/api/ci/pipelines.rb
+++ b/lib/api/ci/pipelines.rb
@@ -51,7 +51,7 @@ module API
desc: 'Sort pipelines'
optional :source, type: String, values: ::Ci::Pipeline.sources.keys
end
- get ':id/pipelines', feature_category: :continuous_integration do
+ get ':id/pipelines', urgency: :low, feature_category: :continuous_integration do
authorize! :read_pipeline, user_project
authorize! :read_build, user_project
@@ -67,7 +67,7 @@ module API
requires :ref, type: String, desc: 'Reference'
optional :variables, Array, desc: 'Array of variables available in the pipeline'
end
- post ':id/pipeline', feature_category: :continuous_integration do
+ post ':id/pipeline', urgency: :low, feature_category: :continuous_integration do
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/20711')
authorize! :create_pipeline, user_project
@@ -94,7 +94,7 @@ module API
params do
optional :ref, type: String, desc: 'branch ref of pipeline'
end
- get ':id/pipelines/latest', feature_category: :continuous_integration do
+ get ':id/pipelines/latest', urgency: :low, feature_category: :continuous_integration do
authorize! :read_pipeline, latest_pipeline
present latest_pipeline, with: Entities::Ci::Pipeline
@@ -107,7 +107,7 @@ module API
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
- get ':id/pipelines/:pipeline_id', feature_category: :continuous_integration do
+ get ':id/pipelines/:pipeline_id', urgency: :low, feature_category: :continuous_integration do
authorize! :read_pipeline, pipeline
present pipeline, with: Entities::Ci::Pipeline
@@ -205,7 +205,7 @@ module API
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
- delete ':id/pipelines/:pipeline_id', feature_category: :continuous_integration do
+ delete ':id/pipelines/:pipeline_id', urgency: :low, feature_category: :continuous_integration do
authorize! :destroy_pipeline, pipeline
destroy_conditionally!(pipeline) do
@@ -220,7 +220,7 @@ module API
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
- post ':id/pipelines/:pipeline_id/retry', feature_category: :continuous_integration do
+ post ':id/pipelines/:pipeline_id/retry', urgency: :low, feature_category: :continuous_integration do
authorize! :update_pipeline, pipeline
response = pipeline.retry_failed(current_user)
@@ -239,7 +239,7 @@ module API
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
- post ':id/pipelines/:pipeline_id/cancel', feature_category: :continuous_integration do
+ post ':id/pipelines/:pipeline_id/cancel', urgency: :low, feature_category: :continuous_integration do
authorize! :update_pipeline, pipeline
pipeline.cancel_running
diff --git a/lib/api/ci/resource_groups.rb b/lib/api/ci/resource_groups.rb
index 616bec499d4..e3fd887475a 100644
--- a/lib/api/ci/resource_groups.rb
+++ b/lib/api/ci/resource_groups.rb
@@ -3,14 +3,29 @@
module API
module Ci
class ResourceGroups < ::API::Base
+ include PaginationParams
+
before { authenticate! }
feature_category :continuous_delivery
+ urgency :low
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: ::API::API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
+ desc 'Get all resource groups for this project' do
+ success Entities::Ci::ResourceGroup
+ end
+ params do
+ use :pagination
+ end
+ get ':id/resource_groups' do
+ authorize! :read_resource_group, user_project
+
+ present paginate(user_project.resource_groups), with: Entities::Ci::ResourceGroup
+ end
+
desc 'Get a single resource group' do
success Entities::Ci::ResourceGroup
end
diff --git a/lib/api/ci/runner.rb b/lib/api/ci/runner.rb
index 0e3b295396b..4381309fb9e 100644
--- a/lib/api/ci/runner.rb
+++ b/lib/api/ci/runner.rb
@@ -29,7 +29,7 @@ module API
mutually_exclusive :maintainer_note, :maintainer_note
mutually_exclusive :active, :paused
end
- post '/', feature_category: :runner do
+ post '/', urgency: :low, feature_category: :runner do
attributes = attributes_for_keys(%i[description maintainer_note maintenance_note active paused locked run_untagged tag_list access_level maximum_timeout])
.merge(get_runner_details_from_request)
@@ -54,7 +54,7 @@ module API
params do
requires :token, type: String, desc: %q(Runner's authentication token)
end
- delete '/', feature_category: :runner do
+ delete '/', urgency: :low, feature_category: :runner do
authenticate_runner!
destroy_conditionally!(current_runner) { ::Ci::Runners::UnregisterRunnerService.new(current_runner, params[:token]).execute }
@@ -66,7 +66,7 @@ module API
params do
requires :token, type: String, desc: %q(Runner's authentication token)
end
- post '/verify', feature_category: :runner do
+ post '/verify', urgency: :low, feature_category: :runner do
authenticate_runner!
status 200
body "200"
@@ -78,7 +78,7 @@ module API
params do
requires :token, type: String, desc: 'The current authentication token of the runner'
end
- post '/reset_authentication_token', feature_category: :runner do
+ post '/reset_authentication_token', urgency: :low, feature_category: :runner do
authenticate_runner!
current_runner.reset_token!
@@ -212,7 +212,7 @@ module API
requires :id, type: Integer, desc: %q(Job's ID)
optional :token, type: String, desc: %q(Job's authentication token)
end
- patch '/:id/trace', urgency: :default, feature_category: :continuous_integration do
+ patch '/:id/trace', urgency: :low, feature_category: :continuous_integration do
job = authenticate_job!(heartbeat_runner: true)
error!('400 Missing header Content-Range', 400) unless request.headers.key?('Content-Range')
@@ -305,6 +305,7 @@ module API
result = ::Ci::JobArtifacts::CreateService.new(job).execute(artifacts, params, metadata_file: metadata)
if result[:status] == :success
+ log_artifact_size(result[:artifact])
status :created
body "201"
else
@@ -323,9 +324,13 @@ module API
optional :direct_download, default: false, type: Boolean, desc: %q(Perform direct download from remote storage instead of proxying artifacts)
end
get '/:id/artifacts', feature_category: :build_artifacts do
- job = authenticate_job!(require_running: false)
+ if request_using_running_job_token?
+ authenticate_job_via_dependent_job!
+ else
+ authenticate_job!(require_running: false)
+ end
- present_carrierwave_file!(job.artifacts_file, supports_direct_download: params[:direct_download])
+ present_carrierwave_file!(current_job.artifacts_file, supports_direct_download: params[:direct_download])
end
end
end
diff --git a/lib/api/ci/runners.rb b/lib/api/ci/runners.rb
index 3c9e887e751..7863cfd1e79 100644
--- a/lib/api/ci/runners.rb
+++ b/lib/api/ci/runners.rb
@@ -8,6 +8,7 @@ module API
before { authenticate! }
feature_category :runner
+ urgency :low
resource :runners do
desc 'Get runners available for user' do
diff --git a/lib/api/ci/secure_files.rb b/lib/api/ci/secure_files.rb
index ee39bdfd90c..6c7f502b428 100644
--- a/lib/api/ci/secure_files.rb
+++ b/lib/api/ci/secure_files.rb
@@ -62,13 +62,11 @@ module API
params do
requires :name, type: String, desc: 'The name of the file'
requires :file, types: [Rack::Multipart::UploadedFile, ::API::Validations::Types::WorkhorseFile], desc: 'The secure file to be uploaded'
- optional :permissions, type: String, desc: 'The file permissions', default: 'read_only', values: %w[read_only read_write execute]
end
route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: true
post ':id/secure_files' do
secure_file = user_project.secure_files.new(
- name: params[:name],
- permissions: params[:permissions] || :read_only
+ name: params[:name]
)
secure_file.file = params[:file]
@@ -96,11 +94,11 @@ module API
helpers do
def feature_flag_enabled?
- service_unavailable! unless Feature.enabled?(:ci_secure_files, user_project, default_enabled: :yaml)
+ service_unavailable! unless Feature.enabled?(:ci_secure_files, user_project)
end
def read_only_feature_flag_enabled?
- service_unavailable! if Feature.enabled?(:ci_secure_files_read_only, user_project, type: :ops, default_enabled: :yaml)
+ service_unavailable! if Feature.enabled?(:ci_secure_files_read_only, user_project, type: :ops)
end
end
end
diff --git a/lib/api/ci/triggers.rb b/lib/api/ci/triggers.rb
index ae89b475ef8..c49f1c9e9e1 100644
--- a/lib/api/ci/triggers.rb
+++ b/lib/api/ci/triggers.rb
@@ -8,6 +8,7 @@ module API
HTTP_GITLAB_EVENT_HEADER = "HTTP_#{::Gitlab::WebHooks::GITLAB_EVENT_HEADER}".underscore.upcase
feature_category :continuous_integration
+ urgency :low
params do
requires :id, type: String, desc: 'The ID of a project'
diff --git a/lib/api/ci/variables.rb b/lib/api/ci/variables.rb
index ec9951aba0d..f9707960b9d 100644
--- a/lib/api/ci/variables.rb
+++ b/lib/api/ci/variables.rb
@@ -35,7 +35,7 @@ module API
requires :key, type: String, desc: 'The key of the variable'
end
# rubocop: disable CodeReuse/ActiveRecord
- get ':id/variables/:key' do
+ get ':id/variables/:key', urgency: :low do
variable = find_variable(user_project, params)
not_found!('Variable') unless variable