Commit 710da4ce authored by Philip Cunningham's avatar Philip Cunningham Committed by Heinrich Lee Yu

Add job-level keyword for DAST configuration

parent 2029d83b
......@@ -10,7 +10,11 @@ module EE
extend ::Gitlab::Utils::Override
prepended do
attributes :secrets
attributes :dast_configuration, :secrets
entry :dast_configuration, ::Gitlab::Ci::Config::Entry::DastConfiguration,
description: 'DAST configuration for this job',
inherit: false
entry :secrets, ::Gitlab::Config::Entry::ComposableHash,
description: 'Configured secrets for this job',
......@@ -20,7 +24,7 @@ module EE
override :value
def value
super.merge({ secrets: secrets_value }.compact)
super.merge({ dast_configuration: dast_configuration_value, secrets: secrets_value }.compact)
end
end
end
......
# frozen_string_literal: true
module EE
module Gitlab
module Ci
module YamlProcessor
module Result
extend ::Gitlab::Utils::Override
override :build_attributes
def build_attributes(name)
job = jobs.fetch(name.to_sym, {})
super.deep_merge(dast_configuration: job[:dast_configuration]).compact
end
end
end
end
end
end
# frozen_string_literal: true
module Gitlab
module Ci
class Config
module Entry
##
# Entry that represents additional DAST configuration.
#
class DastConfiguration < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Configurable
include ::Gitlab::Config::Entry::Attributable
ALLOWED_KEYS = %i[site_profile scanner_profile].freeze
attributes ALLOWED_KEYS
validations do
validates :config, allowed_keys: ALLOWED_KEYS
validates :site_profile, type: String, allow_nil: true
validates :scanner_profile, type: String, allow_nil: true
end
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Ci::Config::Entry::DastConfiguration do
let(:entry) { described_class.new(config) }
shared_examples_for 'a valid entry' do
describe '#value' do
it 'returns configuration' do
expect(entry.value).to eq(config)
end
end
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
end
describe 'validation' do
context 'when both site and scanner configuration are present' do
let(:config) { { site_profile: 'Site profile', scanner_profile: 'Scanner profile' } }
it_behaves_like 'a valid entry'
end
context 'when only the site profile is present' do
let(:config) { { site_profile: 'Site profile' } }
it_behaves_like 'a valid entry'
end
context 'when only the scanner profile is present' do
let(:config) { { scanner_profile: 'Scanner profile' } }
it_behaves_like 'a valid entry'
end
context 'when no keys are present' do
let(:config) { {} }
it_behaves_like 'a valid entry'
end
context 'when entry value is not correct' do
describe '#errors' do
context 'when there is an unknown key present' do
let(:config) { { foo: 'Foo profile' } }
it 'reports error' do
expect(entry.errors) .to include 'dast configuration config contains unknown keys: foo'
end
end
end
end
end
end
......@@ -5,59 +5,87 @@ require 'spec_helper'
RSpec.describe Gitlab::Ci::Config::Entry::Job do
let(:entry) { described_class.new(config, name: :rspec) }
describe '.nodes' do
context 'when filtering all the entry/node names' do
subject { described_class.nodes.keys }
let(:result) { %i[dast_configuration secrets] }
it { is_expected.to include(*result) }
end
end
describe 'validations' do
context 'when entry value is correct' do
context 'when has secrets' do
let(:config) { { script: 'echo', secrets: { DATABASE_PASSWORD: { vault: 'production/db/password' } } } }
shared_examples_for 'a valid entry' do
before do
entry.compose!
end
before do
entry.compose!
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
it { expect(entry).to be_valid }
end
end
context 'when entry value is not correct' do
shared_examples_for 'an invalid entry' do |message|
before do
entry.compose!
end
it 'reports error', :aggregate_failures do
expect(entry).not_to be_valid
expect(entry.errors).to contain_exactly(message)
end
end
context 'when entry value is correct' do
context 'when has secrets' do
let(:config) { { script: 'echo', secrets: { DATABASE_PASSWORD: { vault: 'production/db/password' } } } }
it_behaves_like 'a valid entry'
end
context 'when has dast_configuration' do
let(:config) { { script: 'echo', dast_configuration: { site_profile: 'Site profile', scanner_profile: 'Scanner profile' } } }
it_behaves_like 'a valid entry'
end
end
context 'when entry value is not correct' do
context 'when has needs' do
context 'when needs is bridge type' do
let(:config) do
{
script: 'echo',
stage: 'test',
needs: { pipeline: 'some/project' }
}
end
it 'returns error about invalid needs type' do
expect(entry).not_to be_valid
expect(entry.errors).to contain_exactly('needs config uses invalid types: bridge')
end
let(:config) { { script: 'echo', stage: 'test', needs: { pipeline: 'some/project' } } }
it_behaves_like 'an invalid entry', 'needs config uses invalid types: bridge'
end
end
context 'when has invalid dast_configuration' do
let(:config) { { script: 'echo', dast_configuration: [] } }
it_behaves_like 'an invalid entry', 'dast_configuration config should be a hash'
end
context 'when has invalid secrets' do
let(:config) { { script: 'echo', secrets: [] } }
it 'reports error' do
expect(entry.errors)
.to include 'secrets config should be a hash'
end
it_behaves_like 'an invalid entry', 'secrets config should be a hash'
end
end
end
describe '.nodes' do
context 'when filtering all the entry/node names' do
subject(:nodes) { described_class.nodes }
describe 'dast_configuration' do
let(:config) { { script: 'echo', dast_configuration: { site_profile: 'Site profile', scanner_profile: 'Scanner profile' } } }
it 'has "secrets" node' do
expect(nodes).to have_key(:secrets)
end
before do
entry.compose!
end
it 'includes dast_profile value', :aggregate_failures do
expect(entry.errors).to be_empty
expect(entry.value[:dast_configuration]).to eq(config[:dast_configuration])
end
end
......@@ -81,7 +109,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Job do
entry.compose!
end
it 'includes secrets value' do
it 'includes secrets value', :aggregate_failures do
expect(entry.errors).to be_empty
expect(entry.value[:secrets]).to eq({
DATABASE_PASSWORD: {
......
......@@ -259,9 +259,19 @@ RSpec.describe Gitlab::Ci::YamlProcessor do
])
end
end
describe 'dast configuration' do
let(:config) do
{ build: { stage: 'build', dast_configuration: { site_profile: 'Site profile', scanner_profile: 'Scanner profile' }, script: 'test' } }
end
it 'creates a job with a valid specification' do
expect(subject.builds[0]).to include(dast_configuration: { site_profile: 'Site profile', scanner_profile: 'Scanner profile' })
end
end
end
describe 'Secrets' do
describe 'secrets' do
let(:secrets) do
{
DATABASE_PASSWORD: {
......
......@@ -14,7 +14,7 @@ module Gitlab
ALLOWED_KEYS = %i[tags script type image services start_in artifacts
cache dependencies before_script after_script
environment coverage retry parallel interruptible timeout
release secrets].freeze
release dast_configuration secrets].freeze
REQUIRED_BY_NEEDS = %i[stage].freeze
......
......@@ -148,3 +148,5 @@ module Gitlab
end
end
end
Gitlab::Ci::YamlProcessor::Result.prepend_mod_with('Gitlab::Ci::YamlProcessor::Result')
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