Commit cd4dbd84 authored by Michael Eddington's avatar Michael Eddington Committed by Imre Farkas

Create DAST API Template

parent 2393b1eb
---
title: Add DAST API CI template
merge_request: 60546
author:
type: added
......@@ -13,14 +13,34 @@ RSpec.describe "CI YML Templates" do
with_them do
let(:content) do
<<~EOS
include:
- template: #{template_name}
concrete_build_implemented_by_a_user:
stage: test
script: do something
EOS
if template_name == 'Security/DAST-API.gitlab-ci.yml'
# The DAST-API template purposly excludes a stages
# definition.
<<~EOS
include:
- template: #{template_name}
stages:
- build
- test
- deploy
- dast
concrete_build_implemented_by_a_user:
stage: test
script: do something
EOS
else
<<~EOS
include:
- template: #{template_name}
concrete_build_implemented_by_a_user:
stage: test
script: do something
EOS
end
end
it 'is valid' do
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'DAST-API.gitlab-ci.yml' do
subject(:template) { Gitlab::Template::GitlabCiYmlTemplate.find('DAST-API') }
specify { expect(template).not_to be_nil }
describe 'the template file' do
let(:template_filename) { Rails.root.join("lib/gitlab/ci/templates/" + template.full_name) }
let(:contents) { File.read(template_filename) }
let(:production_registry) { '$SECURE_ANALYZERS_PREFIX/api-fuzzing:$DAST_API_VERSION' }
let(:staging_registry) { '$SECURE_ANALYZERS_PREFIX/api-fuzzing-src:$DAST_API_VERSION' }
# Make sure future changes to the template use the production container registry.
#
# The DAST API template is developed against a dev container registry.
# The registry is switched when releasing new versions. The difference in
# names between development and production is also quite small making it
# easy to miss during review.
it 'uses the production repository' do
expect(contents.include?(production_registry)).to be true
end
it "doesn't use the staging repository" do
expect(contents.include?(staging_registry)).to be false
end
end
describe 'the created pipeline' do
let(:default_branch) { 'master' }
let(:pipeline_branch) { default_branch }
let_it_be(:project) { create(:project, :custom_repo, files: { 'README.txt' => '' }) }
let(:user) { project.owner }
let(:service) { Ci::CreatePipelineService.new(project, user, ref: pipeline_branch ) }
let(:pipeline) { service.execute!(:push) }
let(:build_names) { pipeline.builds.pluck(:name) }
before do
allow_next_instance_of(Ci::BuildScheduleWorker) do |worker|
allow(worker).to receive(:perform).and_return(true)
end
allow(project).to receive(:default_branch).and_return(default_branch)
end
context 'when no stages' do
before do
stub_ci_pipeline_yaml_file(template.content)
end
context 'when project has no stages' do
it 'includes no jobs' do
expect(build_names).to be_empty
end
end
end
context 'when stages includes dast' do
let(:ci_pipeline_yaml) { "stages: [\"dast\"]\n" }
before do
stub_ci_pipeline_yaml_file(ci_pipeline_yaml + template.content)
end
context 'when project has no license' do
before do
create(:ci_variable, project: project, key: 'DAST_API_HAR', value: 'testing.har')
create(:ci_variable, project: project, key: 'DAST_API_TARGET_URL', value: 'http://example.com')
end
it 'includes job to display error' do
expect(build_names).to match_array(%w[dast_api])
end
end
context 'when project has Ultimate license' do
before do
stub_licensed_features(dast: true)
end
context 'by default' do
it 'includes a job' do
expect(build_names).to match_array(%w[dast_api])
end
end
context 'when DAST_API_DISABLED=1' do
before do
create(:ci_variable, project: project, key: 'DAST_API_DISABLED', value: '1')
create(:ci_variable, project: project, key: 'DAST_API_HAR', value: 'testing.har')
create(:ci_variable, project: project, key: 'DAST_API_TARGET_URL', value: 'http://example.com')
end
it 'includes no jobs' do
expect { pipeline }.to raise_error(Ci::CreatePipelineService::CreateError)
end
end
end
end
end
end
......@@ -14,12 +14,6 @@ RSpec.shared_examples 'includes dast job' do
end
end
RSpec.shared_examples 'includes dast_api job' do
it 'includes dast_api job' do
expect(build_names).to match_array(%w[dast_api])
end
end
RSpec.describe 'DAST.latest.gitlab-ci.yml' do
subject(:template) { Gitlab::Template::GitlabCiYmlTemplate.find('DAST.latest') }
......@@ -114,83 +108,6 @@ RSpec.describe 'DAST.latest.gitlab-ci.yml' do
include_examples 'includes dast job'
end
context 'when DAST_API_BETA=1' do
before do
create(:ci_variable, project: project, key: 'DAST_API_BETA', value: '1')
end
context 'when project has Ultimate license' do
let(:license) { create(:license, plan: License::ULTIMATE_PLAN) }
before do
allow(License).to receive(:current).and_return(license)
end
context 'when no specification provided' do
include_examples 'includes no jobs'
end
context 'when DAST_DISABLED=1' do
before do
create(:ci_variable, project: project, key: 'DAST_DISABLED', value: '1')
end
include_examples 'includes no jobs'
end
context 'when DAST_WEBSITE is present' do
before do
create(:ci_variable, project: project, key: 'DAST_WEBSITE', value: 'http://example.com')
end
include_examples 'includes dast job'
end
context 'when DAST_API_SPECIFICATION is present' do
before do
create(:ci_variable, project: project, key: 'DAST_API_SPECIFICATION', value: 'http://my.api/api-specification.yml')
end
include_examples 'includes dast_api job'
end
context 'when DAST_WEBSITE and DAST_API_SPECIFICATION is present' do
before do
create(:ci_variable, project: project, key: 'DAST_WEBSITE', value: 'http://example.com')
create(:ci_variable, project: project, key: 'DAST_API_SPECIFICATION', value: 'http://my.api/api-specification.yml')
end
it 'includes dast_api job' do
expect(build_names).to match_array(%w[dast_api])
end
end
context 'when DAST_API_OPENAPI is present' do
before do
create(:ci_variable, project: project, key: 'DAST_API_OPENAPI', value: 'http://my.api/api-specification.yml')
end
include_examples 'includes dast_api job'
end
context 'when DAST_API_HAR is present' do
before do
create(:ci_variable, project: project, key: 'DAST_API_HAR', value: 'http://my.api/api-specification.yml')
end
include_examples 'includes dast_api job'
end
context 'when DAST_API_POSTMAN_COLLECTION is present' do
before do
create(:ci_variable, project: project, key: 'DAST_API_POSTMAN_COLLECTION', value: 'http://my.api/api-specification.yml')
end
include_examples 'includes dast_api job'
end
end
end
context 'when project has Ultimate license' do
let(:license) { create(:license, plan: License::ULTIMATE_PLAN) }
......
# To use this template, add the following to your .gitlab-ci.yml file:
#
# include:
# template: DAST-API.gitlab-ci.yml
#
# You also need to add a `dast` stage to your `stages:` configuration. A sample configuration for DAST API:
#
# stages:
# - build
# - test
# - deploy
# - dast
# Read more about this feature here: https://docs.gitlab.com/ee/user/application_security/dast_api/index.html
# Configure the scanning tool with CI/CD variables (https://docs.gitlab.com/ee/ci/variables/README.html)
# List of variables available to configure the DAST API scanning tool:
# https://docs.gitlab.com/ee/user/application_security/dast_api/index.html#available-cicd-variables
variables:
# Setting this variable affects all Security templates
# (SAST, Dependency Scanning, ...)
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
#
DAST_API_VERSION: "1"
DAST_API_IMAGE: $SECURE_ANALYZERS_PREFIX/api-fuzzing:$DAST_API_VERSION
dast_api:
stage: dast
image: $DAST_API_IMAGE
allow_failure: true
rules:
- if: $DAST_API_DISABLED
when: never
- if: $DAST_API_DISABLED_FOR_DEFAULT_BRANCH &&
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
- if: $CI_COMMIT_BRANCH
script:
- /peach/analyzer-dast-api
artifacts:
when: always
paths:
- gl-assets
- gl-dast-api-report.json
- gl-*.log
reports:
dast: gl-dast-api-report.json
......@@ -22,9 +22,6 @@ variables:
# Setting this variable will affect all Security templates
# (SAST, Dependency Scanning, ...)
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
#
DAST_API_VERSION: "1"
DAST_API_IMAGE: $SECURE_ANALYZERS_PREFIX/api-fuzzing:$DAST_API_VERSION
dast:
stage: dast
......@@ -41,11 +38,6 @@ dast:
reports:
dast: gl-dast-report.json
rules:
- if: $DAST_API_BETA && ( $DAST_API_SPECIFICATION ||
$DAST_API_OPENAPI ||
$DAST_API_POSTMAN_COLLECTION ||
$DAST_API_HAR )
when: never
- if: $DAST_DISABLED
when: never
- if: $DAST_DISABLED_FOR_DEFAULT_BRANCH &&
......@@ -61,42 +53,4 @@ dast:
- if: $CI_COMMIT_BRANCH &&
$DAST_WEBSITE
- if: $CI_COMMIT_BRANCH &&
$DAST_API_BETA == null &&
$DAST_API_SPECIFICATION
dast_api:
stage: dast
image: $DAST_API_IMAGE
allow_failure: true
rules:
- if: $DAST_API_BETA == null
when: never
- if: $DAST_DISABLED
when: never
- if: $DAST_DISABLED_FOR_DEFAULT_BRANCH &&
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
- if: $CI_DEFAULT_BRANCH != $CI_COMMIT_REF_NAME &&
$REVIEW_DISABLED &&
$DAST_API_SPECIFICATION == null &&
$DAST_API_OPENAPI == null &&
$DAST_API_POSTMAN_COLLECTION == null &&
$DAST_API_HAR == null
when: never
- if: $DAST_API_SPECIFICATION == null &&
$DAST_API_OPENAPI == null &&
$DAST_API_POSTMAN_COLLECTION == null &&
$DAST_API_HAR == null
when: never
- if: $CI_COMMIT_BRANCH &&
$GITLAB_FEATURES =~ /\bdast\b/
script:
- /peach/analyzer-dast-api
artifacts:
when: always
paths:
- gl-assets
- gl-dast-api-report.json
- gl-*.log
reports:
dast: gl-dast-api-report.json
......@@ -22,14 +22,34 @@ RSpec.describe 'CI YML Templates' do
with_them do
let(:content) do
<<~EOS
include:
- template: #{template_name}
if template_name == 'Security/DAST-API.gitlab-ci.yml'
# The DAST-API template purposly excludes a stages
# definition.
concrete_build_implemented_by_a_user:
stage: test
script: do something
EOS
<<~EOS
include:
- template: #{template_name}
stages:
- build
- test
- deploy
- dast
concrete_build_implemented_by_a_user:
stage: test
script: do something
EOS
else
<<~EOS
include:
- template: #{template_name}
concrete_build_implemented_by_a_user:
stage: test
script: do something
EOS
end
end
it 'is valid' do
......
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