Commit c37b441f authored by charlie ablett's avatar charlie ablett

Merge branch '330713-add-new-report-type-ci' into 'master'

Add new security job artifact report cluster image scanning

See merge request gitlab-org/gitlab!64611
parents 5bcd609d 2dbab45a
......@@ -33,6 +33,7 @@ module Ci
secret_detection: 'gl-secret-detection-report.json',
dependency_scanning: 'gl-dependency-scanning-report.json',
container_scanning: 'gl-container-scanning-report.json',
cluster_image_scanning: 'gl-cluster-image-scanning-report.json',
dast: 'gl-dast-report.json',
license_scanning: 'gl-license-scanning-report.json',
performance: 'performance.json',
......@@ -71,6 +72,7 @@ module Ci
secret_detection: :raw,
dependency_scanning: :raw,
container_scanning: :raw,
cluster_image_scanning: :raw,
dast: :raw,
license_scanning: :raw,
......@@ -108,6 +110,7 @@ module Ci
sast
secret_detection
requirements
cluster_image_scanning
].freeze
TYPE_AND_FORMAT_PAIRS = INTERNAL_TYPES.merge(REPORT_TYPES).freeze
......@@ -212,7 +215,8 @@ module Ci
coverage_fuzzing: 23, ## EE-specific
browser_performance: 24, ## EE-specific
load_performance: 25, ## EE-specific
api_fuzzing: 26 ## EE-specific
api_fuzzing: 26, ## EE-specific
cluster_image_scanning: 27 ## EE-specific
}
# `file_location` indicates where actual files are stored.
......
......@@ -14682,6 +14682,7 @@ Iteration ID wildcard values.
| <a id="jobartifactfiletypearchive"></a>`ARCHIVE` | ARCHIVE job artifact file type. |
| <a id="jobartifactfiletypebrowser_performance"></a>`BROWSER_PERFORMANCE` | BROWSER PERFORMANCE job artifact file type. |
| <a id="jobartifactfiletypecluster_applications"></a>`CLUSTER_APPLICATIONS` | CLUSTER APPLICATIONS job artifact file type. |
| <a id="jobartifactfiletypecluster_image_scanning"></a>`CLUSTER_IMAGE_SCANNING` | CLUSTER IMAGE SCANNING job artifact file type. |
| <a id="jobartifactfiletypecobertura"></a>`COBERTURA` | COBERTURA job artifact file type. |
| <a id="jobartifactfiletypecodequality"></a>`CODEQUALITY` | CODE QUALITY job artifact file type. |
| <a id="jobartifactfiletypecontainer_scanning"></a>`CONTAINER_SCANNING` | CONTAINER SCANNING job artifact file type. |
......
......@@ -3064,6 +3064,18 @@ as artifacts.
The collected coverage fuzzing report uploads to GitLab as an artifact and is summarized in merge
requests and the pipeline view. It's also used to provide data for security dashboards.
##### `artifacts:reports:cluster_image_scanning` **(ULTIMATE)**
> - Introduced in GitLab 14.1.
> - Requires GitLab Runner 14.1 and above.
The `cluster_image_scanning` report collects `CLUSTER_IMAGE_SCANNING` vulnerabilities
as artifacts.
The collected `CLUSTER_IMAGE_SCANNING` report uploads to GitLab as an artifact and
is summarized in the pipeline view. It's also used to provide data for security
dashboards.
##### `artifacts:reports:dast` **(ULTIMATE)**
> - Introduced in GitLab 11.5.
......
......@@ -16,7 +16,7 @@ module Types
def self.resolve_type(object, context)
case object[:report_type]
when 'container_scanning'
when 'container_scanning', 'cluster_image_scanning'
VulnerabilityLocation::ContainerScanningType
when 'dependency_scanning'
VulnerabilityLocation::DependencyScanningType
......
......@@ -16,6 +16,7 @@ module EE
secret_detection: :secret_detection,
dependency_scanning: :dependency_scanning,
container_scanning: :container_scanning,
cluster_image_scanning: :cluster_image_scanning,
dast: :dast,
coverage_fuzzing: :coverage_fuzzing,
api_fuzzing: :api_fuzzing
......
......@@ -15,11 +15,12 @@ module EE
# See https://gitlab.com/gitlab-org/gitlab/-/issues/297472
after_destroy :log_geo_deleted_event
SECURITY_REPORT_FILE_TYPES = %w[sast secret_detection dependency_scanning container_scanning dast coverage_fuzzing api_fuzzing].freeze
SECURITY_REPORT_FILE_TYPES = %w[sast secret_detection dependency_scanning container_scanning cluster_image_scanning dast coverage_fuzzing api_fuzzing].freeze
LICENSE_SCANNING_REPORT_FILE_TYPES = %w[license_scanning].freeze
DEPENDENCY_LIST_REPORT_FILE_TYPES = %w[dependency_scanning].freeze
METRICS_REPORT_FILE_TYPES = %w[metrics].freeze
CONTAINER_SCANNING_REPORT_TYPES = %w[container_scanning].freeze
CLUSTER_IMAGE_SCANNING_REPORT_TYPES = %w[cluster_image_scanning].freeze
DAST_REPORT_TYPES = %w[dast].freeze
REQUIREMENTS_REPORT_FILE_TYPES = %w[requirements].freeze
COVERAGE_FUZZING_REPORT_TYPES = %w[coverage_fuzzing].freeze
......@@ -44,6 +45,10 @@ module EE
with_file_types(CONTAINER_SCANNING_REPORT_TYPES)
end
scope :cluster_image_scanning_reports, -> do
with_file_types(CLUSTER_IMAGE_SCANNING_REPORT_TYPES)
end
scope :dast_reports, -> do
with_file_types(DAST_REPORT_TYPES)
end
......
......@@ -46,6 +46,7 @@ module EE
secret_detection: %i[secret_detection],
dependency_scanning: %i[dependency_scanning],
container_scanning: %i[container_scanning],
cluster_image_scanning: %i[cluster_image_scanning],
dast: %i[dast],
performance: %i[merge_request_performance_metrics],
browser_performance: %i[merge_request_performance_metrics],
......
......@@ -332,6 +332,7 @@ module EE
feature_available?(:secret_detection) ||
feature_available?(:dependency_scanning) ||
feature_available?(:container_scanning) ||
feature_available?(:cluster_image_scanning) ||
feature_available?(:dast) ||
feature_available?(:coverage_fuzzing) ||
feature_available?(:api_fuzzing)
......
......@@ -144,6 +144,7 @@ class License < ApplicationRecord
api_fuzzing
auto_rollback
cilium_alerts
cluster_image_scanning
external_status_checks
container_scanning
coverage_fuzzing
......
......@@ -12,6 +12,7 @@ module EE
license_scanning: ::Gitlab::Ci::Parsers::LicenseCompliance::LicenseScanning,
dependency_scanning: ::Gitlab::Ci::Parsers::Security::DependencyScanning,
container_scanning: ::Gitlab::Ci::Parsers::Security::ContainerScanning,
cluster_image_scanning: ::Gitlab::Ci::Parsers::Security::ContainerScanning,
dast: ::Gitlab::Ci::Parsers::Security::Dast,
sast: ::Gitlab::Ci::Parsers::Security::Sast,
api_fuzzing: ::Gitlab::Ci::Parsers::Security::Dast,
......
......@@ -25,7 +25,7 @@ module Gitlab
end
def standard_vulnerability?(category)
(valid_categories.keys - ['container_scanning']).include?(category)
(valid_categories.keys - %w[container_scanning cluster_image_scanning]).include?(category)
end
end
end
......
......@@ -6,7 +6,7 @@ FactoryBot.define do
failure_reason { Ci::Build.failure_reasons[:protected_environment_failure] }
end
%i[api_fuzzing codequality container_scanning dast dependency_scanning license_scanning performance browser_performance load_performance sast secret_detection coverage_fuzzing].each do |report_type|
%i[api_fuzzing codequality container_scanning cluster_image_scanning dast dependency_scanning license_scanning performance browser_performance load_performance sast secret_detection coverage_fuzzing].each do |report_type|
trait "legacy_#{report_type}".to_sym do
success
artifacts
......@@ -84,6 +84,18 @@ FactoryBot.define do
end
end
trait :cluster_image_scanning_feature_branch do
after(:build) do |build|
build.job_artifacts << create(:ee_ci_job_artifact, :cluster_image_scanning_feature_branch, job: build)
end
end
trait :corrupted_cluster_image_scanning_report do
after(:build) do |build|
build.job_artifacts << create(:ee_ci_job_artifact, :corrupted_cluster_image_scanning_report, job: build)
end
end
trait :dependency_scanning_feature_branch do
after(:build) do |build|
build.job_artifacts << create(:ee_ci_job_artifact, :dependency_scanning_feature_branch, job: build)
......
......@@ -299,6 +299,16 @@ FactoryBot.define do
end
end
trait :cluster_image_scanning do
file_format { :raw }
file_type { :cluster_image_scanning }
after(:build) do |artifact, _|
artifact.file = fixture_file_upload(
Rails.root.join('ee/spec/fixtures/security_reports/master/gl-cluster-image-scanning-report.json'), 'application/json')
end
end
trait :common_security_report do
file_format { :raw }
file_type { :dependency_scanning }
......@@ -339,6 +349,26 @@ FactoryBot.define do
end
end
trait :cluster_image_scanning_feature_branch do
file_format { :raw }
file_type { :cluster_image_scanning }
after(:build) do |artifact, _|
artifact.file = fixture_file_upload(
Rails.root.join('ee/spec/fixtures/security_reports/feature-branch/gl-cluster-image-scanning-report.json'), 'application/json')
end
end
trait :corrupted_cluster_image_scanning_report do
file_format { :raw }
file_type { :cluster_image_scanning }
after(:build) do |artifact, _|
artifact.file = fixture_file_upload(
Rails.root.join('spec/fixtures/trace/sample_trace'), 'application/json')
end
end
trait :metrics do
file_format { :gzip }
file_type { :metrics }
......
......@@ -2,7 +2,7 @@
FactoryBot.define do
factory :ee_ci_pipeline, class: 'Ci::Pipeline', parent: :ci_pipeline do
%i[api_fuzzing browser_performance codequality container_scanning coverage_fuzzing dast dependency_list dependency_scanning license_scanning load_performance sast secret_detection].each do |report_type|
%i[api_fuzzing browser_performance codequality container_scanning cluster_image_scanning coverage_fuzzing dast dependency_list dependency_scanning license_scanning load_performance sast secret_detection].each do |report_type|
trait "with_#{report_type}_report".to_sym do
status { :success }
......@@ -28,6 +28,22 @@ FactoryBot.define do
end
end
trait :with_cluster_image_scanning_feature_branch do
status { :success }
after(:build) do |pipeline, evaluator|
pipeline.builds << build(:ee_ci_build, :cluster_image_scanning_feature_branch, pipeline: pipeline, project: pipeline.project)
end
end
trait :with_corrupted_cluster_image_scanning_report do
status { :success }
after(:build) do |pipeline, evaluator|
pipeline.builds << build(:ee_ci_build, :corrupted_cluster_image_scanning_report, pipeline: pipeline, project: pipeline.project)
end
end
trait :with_dependency_scanning_feature_branch do
status { :success }
......
......@@ -52,6 +52,10 @@ FactoryBot.define do
category { 'container_scanning' }
end
trait :cluster_image_scanning do
category { 'cluster_image_scanning' }
end
trait :dast do
category { 'dast' }
end
......
{
"version": "2.4",
"vulnerabilities": [
{
"id": "e987fa54ff94e1d0e716814861459d2eb10bd27a0ba8ca243428669d8885ce68",
"category": "cluster_image_scanning",
"message": "CVE-2017-15650 in musl",
"description": "musl:1.1.18-r3 is affected by CVE-2017-15650",
"cve": "alpine:v3.7:musl:CVE-2017-15650",
"severity": "High",
"confidence": "Unknown",
"solution": "Upgrade musl from 1.1.18-r3 to 1.1.18-r4",
"scanner": {
"id": "starboard",
"name": "Starboard"
},
"location": {
"dependency": {
"package": {
"name": "musl"
},
"version": "1.1.18-r3"
},
"operating_system": "alpine:v3.7",
"image": "registry.gitlab.com/bikebilly/auto-devops-10-6/feature-branch:e7315ba964febb11bac8f5cd6ec433db8a3a1583"
},
"identifiers": [
{
"type": "cve",
"name": "CVE-2017-15650",
"value": "CVE-2017-15650",
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15650"
}
],
"links": [
{
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15650"
}
]
}
],
"remediations": [],
"scan": {
"scanner": {
"id": "starboard",
"name": "Starboard",
"url": "https://github.com/aquasecurity/starboard",
"vendor": {
"name": "GitLab"
},
"version": "2.1.4"
},
"type": "cluster_image_scanning",
"status": "success"
}
}
{
"version": "2.3",
"vulnerabilities": [
{
"category": "cluster_image_scanning",
"message": "CVE-2017-18269 in glibc",
"description": "An SSE2-optimized memmove implementation for i386 in sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S in the GNU C Library (aka glibc or libc6) 2.21 through 2.27 does not correctly perform the overlapping memory check if the source memory range spans the middle of the address space, resulting in corrupt data being produced by the copy operation. This may disclose information to context-dependent attackers, or result in a denial of service, or, possibly, code execution.",
"cve": "debian:9:glibc:CVE-2017-18269",
"severity": "Critical",
"confidence": "Unknown",
"solution": "Upgrade glibc from 2.24-11+deb9u3 to 2.24-11+deb9u4",
"scanner": {
"id": "starboard",
"name": "Starboard"
},
"location": {
"dependency": {
"package": {
"name": "glibc"
},
"version": "2.24-11+deb9u3"
},
"operating_system": "debian:9",
"image": "registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256:bc09fe2e0721dfaeee79364115aeedf2174cce0947b9ae5fe7c33312ee019a4e"
},
"identifiers": [
{
"type": "cve",
"name": "CVE-2017-18269",
"value": "CVE-2017-18269",
"url": "https://security-tracker.debian.org/tracker/CVE-2017-18269"
}
],
"links": [
{
"url": "https://security-tracker.debian.org/tracker/CVE-2017-18269"
}
]
},
{
"category": "cluster_image_scanning",
"message": "CVE-2017-16997 in glibc",
"description": "elf/dl-load.c in the GNU C Library (aka glibc or libc6) 2.19 through 2.26 mishandles RPATH and RUNPATH containing $ORIGIN for a privileged (setuid or AT_SECURE) program, which allows local users to gain privileges via a Trojan horse library in the current working directory, related to the fillin_rpath and decompose_rpath functions. This is associated with misinterpretion of an empty RPATH/RUNPATH token as the \"./\" directory. NOTE: this configuration of RPATH/RUNPATH for a privileged program is apparently very uncommon; most likely, no such program is shipped with any common Linux distribution.",
"cve": "debian:9:glibc:CVE-2017-16997",
"severity": "Critical",
"confidence": "Unknown",
"solution": "Upgrade glibc from 2.24-11+deb9u3 to 2.24-11+deb9u4",
"scanner": {
"id": "starboard",
"name": "Starboard"
},
"location": {
"dependency": {
"package": {
"name": "glibc"
},
"version": "2.24-11+deb9u3"
},
"operating_system": "debian:9",
"image": "registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256:bc09fe2e0721dfaeee79364115aeedf2174cce0947b9ae5fe7c33312ee019a4e"
},
"identifiers": [
{
"type": "cve",
"name": "CVE-2017-16997",
"value": "CVE-2017-16997",
"url": "https://security-tracker.debian.org/tracker/CVE-2017-16997"
}
],
"links": [
{
"url": "https://security-tracker.debian.org/tracker/CVE-2017-16997"
}
]
}
],
"remediations": [],
"scan": {
"scanner": {
"id": "starboard",
"name": "Starboard",
"url": "https://github.com/aquasecurity/starboard",
"vendor": {
"name": "GitLab"
},
"version": "0.10.0"
},
"type": "cluster_image_scanning",
"status": "success"
}
}
......@@ -39,6 +39,15 @@ RSpec.describe Gitlab::Vulnerabilities::Parser do
end
end
context 'with cluster image scanning as category' do
it 'returns a Scanning Vulnerability' do
params[:category] = 'cluster_image_scanning'
expect(subject).to be_a(Gitlab::Vulnerabilities::ContainerScanningVulnerability)
expect(subject.target_branch).to eq('master')
end
end
context 'with an invalid category' do
it 'raises an exception' do
params[:category] = 'foo'
......
......@@ -109,7 +109,7 @@ RSpec.describe Ci::Pipeline do
subject { pipeline.security_reports }
before do
stub_licensed_features(sast: true, dependency_scanning: true, container_scanning: true)
stub_licensed_features(sast: true, dependency_scanning: true, container_scanning: true, cluster_image_scanning: true)
end
context 'when pipeline has multiple builds with security reports' do
......@@ -119,12 +119,16 @@ RSpec.describe Ci::Pipeline do
let(:build_ds_2) { create(:ci_build, :success, name: 'ds_2', pipeline: pipeline, project: project) }
let(:build_cs_1) { create(:ci_build, :success, name: 'cs_1', pipeline: pipeline, project: project) }
let(:build_cs_2) { create(:ci_build, :success, name: 'cs_2', pipeline: pipeline, project: project) }
let(:build_cis_1) { create(:ci_build, :success, name: 'cis_1', pipeline: pipeline, project: project) }
let(:build_cis_2) { create(:ci_build, :success, name: 'cis_2', pipeline: pipeline, project: project) }
let!(:sast1_artifact) { create(:ee_ci_job_artifact, :sast, job: build_sast_1, project: project) }
let!(:sast2_artifact) { create(:ee_ci_job_artifact, :sast, job: build_sast_2, project: project) }
let!(:ds1_artifact) { create(:ee_ci_job_artifact, :dependency_scanning, job: build_ds_1, project: project) }
let!(:ds2_artifact) { create(:ee_ci_job_artifact, :dependency_scanning, job: build_ds_2, project: project) }
let!(:cs1_artifact) { create(:ee_ci_job_artifact, :container_scanning, job: build_cs_1, project: project) }
let!(:cs2_artifact) { create(:ee_ci_job_artifact, :container_scanning, job: build_cs_2, project: project) }
let!(:cis1_artifact) { create(:ee_ci_job_artifact, :cluster_image_scanning, job: build_cis_1, project: project) }
let!(:cis2_artifact) { create(:ee_ci_job_artifact, :cluster_image_scanning, job: build_cis_2, project: project) }
it 'assigns pipeline to the reports' do
expect(subject.pipeline).to eq(pipeline)
......@@ -132,12 +136,13 @@ RSpec.describe Ci::Pipeline do
end
it 'returns security reports with collected data grouped as expected' do
expect(subject.reports.keys).to contain_exactly('sast', 'dependency_scanning', 'container_scanning')
expect(subject.reports.keys).to contain_exactly('sast', 'dependency_scanning', 'container_scanning', 'cluster_image_scanning')
# for each of report categories, we have merged 2 reports with the same data (fixture)
expect(subject.get_report('sast', sast1_artifact).findings.size).to eq(5)
expect(subject.get_report('dependency_scanning', ds1_artifact).findings.size).to eq(4)
expect(subject.get_report('container_scanning', cs1_artifact).findings.size).to eq(8)
expect(subject.get_report('cluster_image_scanning', cis1_artifact).findings.size).to eq(2)
end
context 'when builds are retried' do
......@@ -147,6 +152,7 @@ RSpec.describe Ci::Pipeline do
expect(subject.get_report('sast', sast1_artifact).findings.size).to eq(5)
expect(subject.get_report('dependency_scanning', ds1_artifact).findings.size).to eq(4)
expect(subject.get_report('container_scanning', cs1_artifact).findings.size).to eq(8)
expect(subject.get_report('cluster_image_scanning', cis1_artifact).findings.size).to eq(2)
end
end
......@@ -535,18 +541,22 @@ RSpec.describe Ci::Pipeline do
where(:pipeline_status, :build_types, :expected_status) do
[
[:blocked, [:container_scanning], false],
[:blocked, [:cluster_image_scanning], false],
[:blocked, [:license_scan_v2_1, :container_scanning], true],
[:blocked, [:license_scan_v2_1], true],
[:blocked, [], false],
[:failed, [:container_scanning], false],
[:failed, [:cluster_image_scanning], false],
[:failed, [:license_scan_v2_1, :container_scanning], true],
[:failed, [:license_scan_v2_1], true],
[:failed, [], false],
[:running, [:container_scanning], false],
[:running, [:cluster_image_scanning], false],
[:running, [:license_scan_v2_1, :container_scanning], true],
[:running, [:license_scan_v2_1], true],
[:running, [], false],
[:success, [:container_scanning], false],
[:success, [:cluster_image_scanning], false],
[:success, [:license_scan_v2_1, :container_scanning], true],
[:success, [:license_scan_v2_1], true],
[:success, [], false]
......
......@@ -31,6 +31,14 @@ RSpec.describe Ci::JobArtifact do
it { is_expected.to eq([artifact]) }
end
describe '.cluster_image_scanning_reports' do
subject { Ci::JobArtifact.cluster_image_scanning_reports }
let_it_be(:artifact) { create(:ee_ci_job_artifact, :cluster_image_scanning) }
it { is_expected.to eq([artifact]) }
end
describe '.metrics_reports' do
subject { Ci::JobArtifact.metrics_reports }
......@@ -226,13 +234,14 @@ RSpec.describe Ci::JobArtifact do
context 'for different types' do
where(:file_type, :security_report?) do
:performance | false
:sast | true
:secret_detection | true
:dependency_scanning | true
:container_scanning | true
:dast | true
:coverage_fuzzing | true
:performance | false
:sast | true
:secret_detection | true
:dependency_scanning | true
:container_scanning | true
:cluster_image_scanning | true
:dast | true
:coverage_fuzzing | true
end
with_them do
......
......@@ -1314,7 +1314,7 @@ RSpec.describe Namespace do
subject { namespace.store_security_reports_available? }
context 'when at least one security report feature is enabled' do
where(report_type: [:sast, :secret_detection, :dast, :dependency_scanning, :container_scanning])
where(report_type: [:sast, :secret_detection, :dast, :dependency_scanning, :container_scanning, :cluster_image_scanning])
with_them do
before do
......
......@@ -110,6 +110,45 @@ RSpec.describe 'Query.vulnerabilities.location' do
end
end
context 'when the vulnerability was found by a cluster image scan' do
let_it_be(:vulnerability) do
create(:vulnerability, project: project, report_type: :cluster_image_scanning)
end
let_it_be(:metadata) do
{
location: {
image: 'vulnerable_image',
operating_system: 'vulnerable_os',
dependency: {
version: '6.6.6',
package: {
name: 'vulnerable_container'
}
}
}
}
end
let_it_be(:finding) do
create(
:vulnerabilities_finding,
vulnerability: vulnerability,
raw_metadata: metadata.to_json
)
end
it 'returns a container location' do
location = subject.first['location']
expect(location['__typename']).to eq('VulnerabilityLocationContainerScanning')
expect(location['image']).to eq('vulnerable_image')
expect(location['operatingSystem']).to eq('vulnerable_os')
expect(location['dependency']['version']).to eq('6.6.6')
expect(location['dependency']['package']['name']).to eq('vulnerable_container')
end
end
context 'when the vulnerability was found by a dependency scan' do
let_it_be(:vulnerability) do
create(:vulnerability, project: project, report_type: :dependency_scanning)
......
......@@ -56,7 +56,7 @@ RSpec.describe StoreSecurityReportsWorker do
end
context 'when at least one security report feature is enabled' do
where(report_type: [:sast, :dast, :dependency_scanning, :container_scanning])
where(report_type: [:sast, :dast, :dependency_scanning, :container_scanning, :cluster_image_scanning])
with_them do
before do
......
......@@ -15,7 +15,7 @@ module Gitlab
%i[junit codequality sast secret_detection dependency_scanning container_scanning
dast performance browser_performance load_performance license_scanning metrics lsif
dotenv cobertura terraform accessibility cluster_applications
requirements coverage_fuzzing api_fuzzing].freeze
requirements coverage_fuzzing api_fuzzing cluster_image_scanning].freeze
attributes ALLOWED_KEYS
......@@ -32,6 +32,7 @@ module Gitlab
validates :secret_detection, array_of_strings_or_string: true
validates :dependency_scanning, array_of_strings_or_string: true
validates :container_scanning, array_of_strings_or_string: true
validates :cluster_image_scanning, array_of_strings_or_string: true
validates :dast, array_of_strings_or_string: true
validates :performance, array_of_strings_or_string: true
validates :browser_performance, array_of_strings_or_string: true
......
......@@ -508,6 +508,14 @@ FactoryBot.define do
end
end
trait :cluster_image_scanning do
options do
{
artifacts: { reports: { cluster_image_scanning: 'gl-cluster-image-scanning-report.json' } }
}
end
end
trait :license_scanning do
options do
{
......
......@@ -40,6 +40,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Reports do
:secret_detection | 'gl-secret-detection-report.json'
:dependency_scanning | 'gl-dependency-scanning-report.json'
:container_scanning | 'gl-container-scanning-report.json'
:cluster_image_scanning | 'gl-cluster-image-scanning-report.json'
:dast | 'gl-dast-report.json'
:license_scanning | 'gl-license-scanning-report.json'
:performance | 'performance.json'
......
......@@ -39,7 +39,7 @@ RSpec.describe Ci::RetryBuildService do
erased_at auto_canceled_by job_artifacts job_artifacts_archive
job_artifacts_metadata job_artifacts_trace job_artifacts_junit
job_artifacts_sast job_artifacts_secret_detection job_artifacts_dependency_scanning
job_artifacts_container_scanning job_artifacts_dast
job_artifacts_container_scanning job_artifacts_cluster_image_scanning job_artifacts_dast
job_artifacts_license_scanning
job_artifacts_performance job_artifacts_browser_performance job_artifacts_load_performance
job_artifacts_lsif job_artifacts_terraform job_artifacts_cluster_applications
......
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