summaryrefslogtreecommitdiff
path: root/lib/gitlab/ci/pipeline/chain/validate/external.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ci/pipeline/chain/validate/external.rb')
-rw-r--r--lib/gitlab/ci/pipeline/chain/validate/external.rb85
1 files changed, 65 insertions, 20 deletions
diff --git a/lib/gitlab/ci/pipeline/chain/validate/external.rb b/lib/gitlab/ci/pipeline/chain/validate/external.rb
index d056501a6d3..6149d2f04d7 100644
--- a/lib/gitlab/ci/pipeline/chain/validate/external.rb
+++ b/lib/gitlab/ci/pipeline/chain/validate/external.rb
@@ -10,77 +10,116 @@ module Gitlab
InvalidResponseCode = Class.new(StandardError)
- VALIDATION_REQUEST_TIMEOUT = 5
+ DEFAULT_VALIDATION_REQUEST_TIMEOUT = 5
+ ACCEPTED_STATUS = 200
+ DOT_COM_REJECTED_STATUS = 406
+ GENERAL_REJECTED_STATUS = (400..499).freeze
def perform!
+ return unless enabled?
+
pipeline_authorized = validate_external
log_message = pipeline_authorized ? 'authorized' : 'not authorized'
- Gitlab::AppLogger.info(message: "Pipeline #{log_message}", project_id: @pipeline.project.id, user_id: @pipeline.user.id)
+ Gitlab::AppLogger.info(message: "Pipeline #{log_message}", project_id: project.id, user_id: current_user.id)
error('External validation failed', drop_reason: :external_validation_failure) unless pipeline_authorized
end
def break?
- @pipeline.errors.any?
+ pipeline.errors.any?
end
private
+ def enabled?
+ return true unless Gitlab.com?
+
+ ::Feature.enabled?(:ci_external_validation_service, project, default_enabled: :yaml)
+ end
+
def validate_external
return true unless validation_service_url
# 200 - accepted
- # 4xx - not accepted
+ # 406 - not accepted on GitLab.com
+ # 4XX - not accepted for other installations
# everything else - accepted and logged
response_code = validate_service_request.code
case response_code
- when 200
+ when ACCEPTED_STATUS
true
- when 400..499
+ when rejected_status
false
else
raise InvalidResponseCode, "Unsupported response code received from Validation Service: #{response_code}"
end
rescue => ex
- Gitlab::ErrorTracking.track_exception(ex)
+ Gitlab::ErrorTracking.track_exception(ex, project_id: project.id)
true
end
+ def rejected_status
+ if Gitlab.com?
+ DOT_COM_REJECTED_STATUS
+ else
+ GENERAL_REJECTED_STATUS
+ end
+ end
+
def validate_service_request
+ headers = {
+ 'X-Gitlab-Correlation-id' => Labkit::Correlation::CorrelationId.current_id,
+ 'X-Gitlab-Token' => validation_service_token
+ }.compact
+
Gitlab::HTTP.post(
- validation_service_url, timeout: VALIDATION_REQUEST_TIMEOUT,
- body: validation_service_payload(@pipeline, @command.yaml_processor_result.stages_attributes)
+ validation_service_url, timeout: validation_service_timeout,
+ headers: headers,
+ body: validation_service_payload.to_json
)
end
+ def validation_service_timeout
+ timeout = Gitlab::CurrentSettings.external_pipeline_validation_service_timeout || ENV['EXTERNAL_VALIDATION_SERVICE_TIMEOUT'].to_i
+ return timeout if timeout > 0
+
+ DEFAULT_VALIDATION_REQUEST_TIMEOUT
+ end
+
def validation_service_url
- ENV['EXTERNAL_VALIDATION_SERVICE_URL']
+ Gitlab::CurrentSettings.external_pipeline_validation_service_url || ENV['EXTERNAL_VALIDATION_SERVICE_URL']
+ end
+
+ def validation_service_token
+ Gitlab::CurrentSettings.external_pipeline_validation_service_token || ENV['EXTERNAL_VALIDATION_SERVICE_TOKEN']
end
- def validation_service_payload(pipeline, stages_attributes)
+ def validation_service_payload
{
project: {
- id: pipeline.project.id,
- path: pipeline.project.full_path
+ id: project.id,
+ path: project.full_path,
+ created_at: project.created_at&.iso8601
},
user: {
- id: pipeline.user.id,
- username: pipeline.user.username,
- email: pipeline.user.email
+ id: current_user.id,
+ username: current_user.username,
+ email: current_user.email,
+ created_at: current_user.created_at&.iso8601
},
pipeline: {
sha: pipeline.sha,
ref: pipeline.ref,
type: pipeline.source
},
- builds: builds_validation_payload(stages_attributes)
- }.to_json
+ builds: builds_validation_payload
+ }
end
- def builds_validation_payload(stages_attributes)
- stages_attributes.map { |stage| stage[:builds] }.flatten
+ def builds_validation_payload
+ stages_attributes.flat_map { |stage| stage[:builds] }
.map(&method(:build_validation_payload))
end
@@ -97,9 +136,15 @@ module Gitlab
].flatten.compact
}
end
+
+ def stages_attributes
+ command.yaml_processor_result.stages_attributes
+ end
end
end
end
end
end
end
+
+Gitlab::Ci::Pipeline::Chain::Validate::External.prepend_if_ee('EE::Gitlab::Ci::Pipeline::Chain::Validate::External')