Commit 92c42c90 authored by Shinya Maeda's avatar Shinya Maeda

Merge branch 'ci-secrets-missing-vault-server' into 'master'

Fail job that has CI secrets but Vault server configuration is missing

See merge request gitlab-org/gitlab!37785
parents 7a718503 cdb300b6
...@@ -23,7 +23,8 @@ module CommitStatusEnums ...@@ -23,7 +23,8 @@ module CommitStatusEnums
downstream_bridge_project_not_found: 1_002, downstream_bridge_project_not_found: 1_002,
invalid_bridge_trigger: 1_003, invalid_bridge_trigger: 1_003,
bridge_pipeline_is_child_pipeline: 1_006, bridge_pipeline_is_child_pipeline: 1_006,
downstream_pipeline_creation_failed: 1_007 downstream_pipeline_creation_failed: 1_007,
secrets_provider_not_found: 1_008
} }
end end
end end
......
...@@ -19,7 +19,8 @@ class CommitStatusPresenter < Gitlab::View::Presenter::Delegated ...@@ -19,7 +19,8 @@ class CommitStatusPresenter < Gitlab::View::Presenter::Delegated
downstream_bridge_project_not_found: 'This job could not be executed because downstream bridge project could not be found', downstream_bridge_project_not_found: 'This job could not be executed because downstream bridge project could not be found',
insufficient_bridge_permissions: 'This job could not be executed because of insufficient permissions to create a downstream pipeline', insufficient_bridge_permissions: 'This job could not be executed because of insufficient permissions to create a downstream pipeline',
bridge_pipeline_is_child_pipeline: 'This job belongs to a child pipeline and cannot create further child pipelines', bridge_pipeline_is_child_pipeline: 'This job belongs to a child pipeline and cannot create further child pipelines',
downstream_pipeline_creation_failed: 'The downstream pipeline could not be created' downstream_pipeline_creation_failed: 'The downstream pipeline could not be created',
secrets_provider_not_found: 'The secrets provider can not be found'
}.freeze }.freeze
private_constant :CALLOUT_FAILURE_MESSAGES private_constant :CALLOUT_FAILURE_MESSAGES
......
...@@ -107,23 +107,15 @@ module Ci ...@@ -107,23 +107,15 @@ module Ci
build.runner_id = runner.id build.runner_id = runner.id
build.runner_session_attributes = params[:session] if params[:session].present? build.runner_session_attributes = params[:session] if params[:session].present?
unless build.has_valid_build_dependencies? failure_reason, _ = pre_assign_runner_checks.find { |_, check| check.call(build, params) }
build.drop!(:missing_dependency_failure)
return false
end
unless build.supported_runner?(params.dig(:info, :features))
build.drop!(:runner_unsupported)
return false
end
if build.archived? if failure_reason
build.drop!(:archived_failure) build.drop!(failure_reason)
return false else
build.run!
end end
build.run! !failure_reason
true
end end
def scheduler_failure!(build) def scheduler_failure!(build)
...@@ -238,6 +230,14 @@ module Ci ...@@ -238,6 +230,14 @@ module Ci
def job_queue_duration_seconds def job_queue_duration_seconds
@job_queue_duration_seconds ||= Gitlab::Metrics.histogram(:job_queue_duration_seconds, 'Request handling execution time', {}, JOB_QUEUE_DURATION_SECONDS_BUCKETS) @job_queue_duration_seconds ||= Gitlab::Metrics.histogram(:job_queue_duration_seconds, 'Request handling execution time', {}, JOB_QUEUE_DURATION_SECONDS_BUCKETS)
end end
def pre_assign_runner_checks
{
missing_dependency_failure: -> (build, _) { !build.has_valid_build_dependencies? },
runner_unsupported: -> (build, params) { !build.supported_runner?(params.dig(:info, :features)) },
archived_failure: -> (build, _) { build.archived? }
}
end
end end
end end
......
...@@ -148,8 +148,22 @@ module EE ...@@ -148,8 +148,22 @@ module EE
super + ee_runner_required_feature_names super + ee_runner_required_feature_names
end end
def secrets_provider?
variable_value('VAULT_SERVER_URL').present?
end
def variable_value(key)
variables_hash[key]
end
private private
def variables_hash
@variables_hash ||= variables.map do |variable|
[variable[:key], variable[:value]]
end.to_h
end
def parse_security_artifact_blob(security_report, blob) def parse_security_artifact_blob(security_report, blob)
report_clone = security_report.clone_as_blank report_clone = security_report.clone_as_blank
::Gitlab::Ci::Parsers.fabricate!(security_report.type).parse!(blob, report_clone) ::Gitlab::Ci::Parsers.fabricate!(security_report.type).parse!(blob, report_clone)
......
...@@ -27,16 +27,6 @@ module EE ...@@ -27,16 +27,6 @@ module EE
} }
} }
end end
def variable_value(key)
variables_hash[key]
end
def variables_hash
@variables_hash ||= variables.map do |variable|
[variable[:key], variable[:value]]
end.to_h
end
end end
end end
end end
...@@ -8,6 +8,7 @@ module EE ...@@ -8,6 +8,7 @@ module EE
# and be included in the `RegisterJobService` service # and be included in the `RegisterJobService` service
module RegisterJobService module RegisterJobService
extend ActiveSupport::Concern extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override
def execute(params = {}) def execute(params = {})
db_all_caught_up = ::Gitlab::Database::LoadBalancing::Sticking.all_caught_up?(:runner, runner.id) db_all_caught_up = ::Gitlab::Database::LoadBalancing::Sticking.all_caught_up?(:runner, runner.id)
...@@ -71,6 +72,13 @@ module EE ...@@ -71,6 +72,13 @@ module EE
def shared_runner_build_limits_feature_enabled? def shared_runner_build_limits_feature_enabled?
ENV['DISABLE_SHARED_RUNNER_BUILD_MINUTES_LIMIT'].to_s != 'true' ENV['DISABLE_SHARED_RUNNER_BUILD_MINUTES_LIMIT'].to_s != 'true'
end end
override :pre_assign_runner_checks
def pre_assign_runner_checks
super.merge({
secrets_provider_not_found: -> (build, _) { build.ci_secrets_management_available? && build.secrets? && !build.secrets_provider? }
})
end
end end
end end
end end
...@@ -188,5 +188,68 @@ RSpec.describe Ci::RegisterJobService do ...@@ -188,5 +188,68 @@ RSpec.describe Ci::RegisterJobService do
end end
end end
end end
context 'secrets' do
let(:params) { { info: { features: { vault_secrets: true } } } }
subject(:service) { described_class.new(shared_runner) }
before do
stub_licensed_features(ci_secrets_management: true)
end
context 'when build has secrets defined' do
before do
pending_build.update!(
secrets: {
DATABASE_PASSWORD: {
vault: {
engine: { name: 'kv-v2', path: 'kv-v2' },
path: 'production/db',
field: 'password'
}
}
}
)
end
context 'when there is no Vault server provided' do
it 'does not pick the build and drops the build' do
result = service.execute(params).build
aggregate_failures do
expect(result).to be_nil
expect(pending_build.reload).to be_failed
expect(pending_build.failure_reason).to eq('secrets_provider_not_found')
expect(pending_build).to be_secrets_provider_not_found
end
end
end
context 'when there is Vault server provided' do
it 'picks the build' do
create(:ci_variable, project: project, key: 'VAULT_SERVER_URL', value: 'https://vault.example.com')
build = service.execute(params).build
aggregate_failures do
expect(build).not_to be_nil
expect(build).to be_running
end
end
end
end
context 'when build has no secrets defined' do
it 'picks the build' do
build = service.execute(params).build
aggregate_failures do
expect(build).not_to be_nil
expect(build).to be_running
end
end
end
end
end end
end end
...@@ -24,7 +24,8 @@ module Gitlab ...@@ -24,7 +24,8 @@ module Gitlab
downstream_bridge_project_not_found: 'downstream project could not be found', downstream_bridge_project_not_found: 'downstream project could not be found',
insufficient_bridge_permissions: 'no permissions to trigger downstream pipeline', insufficient_bridge_permissions: 'no permissions to trigger downstream pipeline',
bridge_pipeline_is_child_pipeline: 'creation of child pipeline not allowed from another child pipeline', bridge_pipeline_is_child_pipeline: 'creation of child pipeline not allowed from another child pipeline',
downstream_pipeline_creation_failed: 'downstream pipeline can not be created' downstream_pipeline_creation_failed: 'downstream pipeline can not be created',
secrets_provider_not_found: 'secrets provider can not be found'
}.freeze }.freeze
private_constant :REASONS private_constant :REASONS
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment