diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-14 09:07:51 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-14 09:07:51 +0000 |
commit | 00b8ecb72c9f77d864aff3572f028613f45af03c (patch) | |
tree | cb8f42234547d61f2721e3fe9361e84c6a710235 /lib | |
parent | 138c61238317b2a61f387749a1f4583309675a83 (diff) | |
download | gitlab-ce-00b8ecb72c9f77d864aff3572f028613f45af03c.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/helpers.rb | 5 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/validate/external.rb | 100 |
2 files changed, 103 insertions, 2 deletions
diff --git a/lib/gitlab/ci/pipeline/chain/helpers.rb b/lib/gitlab/ci/pipeline/chain/helpers.rb index 8ccb1066575..982ecc0ff51 100644 --- a/lib/gitlab/ci/pipeline/chain/helpers.rb +++ b/lib/gitlab/ci/pipeline/chain/helpers.rb @@ -5,12 +5,13 @@ module Gitlab module Pipeline module Chain module Helpers - def error(message, config_error: false) + def error(message, config_error: false, drop_reason: nil) if config_error && command.save_incompleted + drop_reason = :config_error pipeline.yaml_errors = message - pipeline.drop!(:config_error) end + pipeline.drop!(drop_reason) if drop_reason pipeline.errors.add(:base, message) end end diff --git a/lib/gitlab/ci/pipeline/chain/validate/external.rb b/lib/gitlab/ci/pipeline/chain/validate/external.rb new file mode 100644 index 00000000000..97af42b5fd6 --- /dev/null +++ b/lib/gitlab/ci/pipeline/chain/validate/external.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +module Gitlab + module Ci + module Pipeline + module Chain + module Validate + class External < Chain::Base + include Chain::Helpers + + InvalidResponseCode = Class.new(StandardError) + + VALIDATION_REQUEST_TIMEOUT = 5 + + def perform! + error('External validation failed', drop_reason: :external_validation_failure) unless validate_external + end + + def break? + @pipeline.errors.any? + end + + private + + def validate_external + return true unless validation_service_url + + # 200 - accepted + # 4xx - not accepted + # everything else - accepted and logged + response_code = validate_service_request.code + case response_code + when 200 + true + when 400..499 + false + else + raise InvalidResponseCode, "Unsupported response code received from Validation Service: #{response_code}" + end + rescue => ex + Gitlab::Sentry.track_exception(ex) + + true + end + + def validate_service_request + Gitlab::HTTP.post( + validation_service_url, timeout: VALIDATION_REQUEST_TIMEOUT, + body: validation_service_payload(@pipeline, @command.config_processor.stages_attributes) + ) + end + + def validation_service_url + ENV['EXTERNAL_VALIDATION_SERVICE_URL'] + end + + def validation_service_payload(pipeline, stages_attributes) + { + project: { + id: pipeline.project.id, + path: pipeline.project.full_path + }, + user: { + id: pipeline.user.id, + username: pipeline.user.username, + email: pipeline.user.email + }, + pipeline: { + sha: pipeline.sha, + ref: pipeline.ref, + type: pipeline.source + }, + builds: builds_validation_payload(stages_attributes) + }.to_json + end + + def builds_validation_payload(stages_attributes) + stages_attributes.map { |stage| stage[:builds] }.flatten + .map(&method(:build_validation_payload)) + end + + def build_validation_payload(build) + { + name: build[:name], + stage: build[:stage], + image: build.dig(:options, :image, :name), + services: build.dig(:options, :services)&.map { |service| service[:name] }, + script: [ + build.dig(:options, :before_script), + build.dig(:options, :script), + build.dig(:options, :after_script) + ].flatten.compact + } + end + end + end + end + end + end +end |