Graphql for enabling SAST IaC via Config UI
Added Graphql endpoint for enabling SAST IaC via Config UI and corresponding backend code. Changelog: added
This commit is contained in:
parent
9e34f9716b
commit
c1c14e635c
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Mutations
|
||||
module Security
|
||||
module CiConfiguration
|
||||
class ConfigureSastIac < BaseSecurityAnalyzer
|
||||
graphql_name 'ConfigureSastIac'
|
||||
description <<~DESC
|
||||
Enable SAST IaC for a project in a new or
|
||||
modified `.gitlab-ci.yml` file in a new branch. The new
|
||||
branch and a URL to create a merge request are a part of the
|
||||
response.
|
||||
DESC
|
||||
|
||||
def configure_analyzer(project, **_args)
|
||||
::Security::CiConfiguration::SastIacCreateService.new(project, current_user).execute
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -16,6 +16,7 @@ class MutationType < BaseObject
|
|||
mount_mutation Mutations::AlertManagement::HttpIntegration::ResetToken
|
||||
mount_mutation Mutations::AlertManagement::HttpIntegration::Destroy
|
||||
mount_mutation Mutations::Security::CiConfiguration::ConfigureSast
|
||||
mount_mutation Mutations::Security::CiConfiguration::ConfigureSastIac
|
||||
mount_mutation Mutations::Security::CiConfiguration::ConfigureSecretDetection
|
||||
mount_mutation Mutations::AlertManagement::PrometheusIntegration::Create
|
||||
mount_mutation Mutations::AlertManagement::PrometheusIntegration::Update
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Security
|
||||
module CiConfiguration
|
||||
class SastIacCreateService < ::Security::CiConfiguration::BaseCreateService
|
||||
private
|
||||
|
||||
def action
|
||||
Security::CiConfiguration::SastIacBuildAction.new(project.auto_devops_enabled?, existing_gitlab_ci_content).generate
|
||||
end
|
||||
|
||||
def next_branch
|
||||
'set-sast-iac-config'
|
||||
end
|
||||
|
||||
def message
|
||||
_('Configure SAST IaC in `.gitlab-ci.yml`, creating this file if it does not already exist')
|
||||
end
|
||||
|
||||
def description
|
||||
_('Configure SAST IaC in `.gitlab-ci.yml` using the GitLab managed template. You can [add variable overrides](https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings) to customize SAST IaC settings.')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1009,6 +1009,31 @@ Input type: `ConfigureSastInput`
|
|||
| <a id="mutationconfiguresasterrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
|
||||
| <a id="mutationconfiguresastsuccesspath"></a>`successPath` | [`String`](#string) | Redirect path to use when the response is successful. |
|
||||
|
||||
### `Mutation.configureSastIac`
|
||||
|
||||
Enable SAST IaC for a project in a new or
|
||||
modified `.gitlab-ci.yml` file in a new branch. The new
|
||||
branch and a URL to create a merge request are a part of the
|
||||
response.
|
||||
|
||||
Input type: `ConfigureSastIacInput`
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationconfiguresastiacclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationconfiguresastiacprojectpath"></a>`projectPath` | [`ID!`](#id) | Full path of the project. |
|
||||
|
||||
#### Fields
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="mutationconfiguresastiacbranch"></a>`branch` | [`String`](#string) | Branch that has the new/modified `.gitlab-ci.yml` file. |
|
||||
| <a id="mutationconfiguresastiacclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
|
||||
| <a id="mutationconfiguresastiacerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
|
||||
| <a id="mutationconfiguresastiacsuccesspath"></a>`successPath` | [`String`](#string) | Redirect path to use when the response is successful. |
|
||||
|
||||
### `Mutation.configureSecretDetection`
|
||||
|
||||
Configure Secret Detection for a project by enabling Secret Detection
|
||||
|
|
19
lib/security/ci_configuration/sast_iac_build_action.rb
Normal file
19
lib/security/ci_configuration/sast_iac_build_action.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Security
|
||||
module CiConfiguration
|
||||
class SastIacBuildAction < BaseBuildAction
|
||||
private
|
||||
|
||||
def update_existing_content!
|
||||
@existing_gitlab_ci_content['include'] = generate_includes
|
||||
end
|
||||
|
||||
def template
|
||||
return 'Auto-DevOps.gitlab-ci.yml' if @auto_devops_enabled
|
||||
|
||||
'Security/SAST-IaC.latest.gitlab-ci.yml'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -8677,6 +8677,12 @@ msgstr ""
|
|||
msgid "Configure Prometheus"
|
||||
msgstr ""
|
||||
|
||||
msgid "Configure SAST IaC in `.gitlab-ci.yml` using the GitLab managed template. You can [add variable overrides](https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings) to customize SAST IaC settings."
|
||||
msgstr ""
|
||||
|
||||
msgid "Configure SAST IaC in `.gitlab-ci.yml`, creating this file if it does not already exist"
|
||||
msgstr ""
|
||||
|
||||
msgid "Configure SAST in `.gitlab-ci.yml` using the GitLab managed template. You can [add variable overrides](https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings) to customize SAST settings."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Mutations::Security::CiConfiguration::ConfigureSastIac do
|
||||
include GraphqlHelpers
|
||||
|
||||
let(:service) { ::Security::CiConfiguration::SastIacCreateService }
|
||||
|
||||
subject { resolve(described_class, args: { project_path: project.full_path }, ctx: { current_user: user }) }
|
||||
|
||||
include_examples 'graphql mutations security ci configuration'
|
||||
end
|
163
spec/lib/security/ci_configuration/sast_iac_build_action_spec.rb
Normal file
163
spec/lib/security/ci_configuration/sast_iac_build_action_spec.rb
Normal file
|
@ -0,0 +1,163 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Security::CiConfiguration::SastIacBuildAction do
|
||||
subject(:result) { described_class.new(auto_devops_enabled, gitlab_ci_content).generate }
|
||||
|
||||
let(:params) { {} }
|
||||
|
||||
context 'with existing .gitlab-ci.yml' do
|
||||
let(:auto_devops_enabled) { false }
|
||||
|
||||
context 'sast iac has not been included' do
|
||||
let(:expected_yml) do
|
||||
<<-CI_YML.strip_heredoc
|
||||
# You can override the included template(s) by including variable overrides
|
||||
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
|
||||
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
|
||||
# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
|
||||
# Note that environment variables can be set in several places
|
||||
# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
|
||||
stages:
|
||||
- test
|
||||
- security
|
||||
variables:
|
||||
RANDOM: make sure this persists
|
||||
include:
|
||||
- template: existing.yml
|
||||
- template: Security/SAST-IaC.latest.gitlab-ci.yml
|
||||
CI_YML
|
||||
end
|
||||
|
||||
context 'template includes are an array' do
|
||||
let(:gitlab_ci_content) do
|
||||
{ "stages" => %w(test security),
|
||||
"variables" => { "RANDOM" => "make sure this persists" },
|
||||
"include" => [{ "template" => "existing.yml" }] }
|
||||
end
|
||||
|
||||
it 'generates the correct YML' do
|
||||
expect(result[:action]).to eq('update')
|
||||
expect(result[:content]).to eq(expected_yml)
|
||||
end
|
||||
end
|
||||
|
||||
context 'template include is not an array' do
|
||||
let(:gitlab_ci_content) do
|
||||
{ "stages" => %w(test security),
|
||||
"variables" => { "RANDOM" => "make sure this persists" },
|
||||
"include" => { "template" => "existing.yml" } }
|
||||
end
|
||||
|
||||
it 'generates the correct YML' do
|
||||
expect(result[:action]).to eq('update')
|
||||
expect(result[:content]).to eq(expected_yml)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'secret_detection has been included' do
|
||||
let(:expected_yml) do
|
||||
<<-CI_YML.strip_heredoc
|
||||
# You can override the included template(s) by including variable overrides
|
||||
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
|
||||
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
|
||||
# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
|
||||
# Note that environment variables can be set in several places
|
||||
# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
|
||||
stages:
|
||||
- test
|
||||
variables:
|
||||
RANDOM: make sure this persists
|
||||
include:
|
||||
- template: Security/SAST-IaC.latest.gitlab-ci.yml
|
||||
CI_YML
|
||||
end
|
||||
|
||||
context 'secret_detection template include are an array' do
|
||||
let(:gitlab_ci_content) do
|
||||
{ "stages" => %w(test),
|
||||
"variables" => { "RANDOM" => "make sure this persists" },
|
||||
"include" => [{ "template" => "Security/SAST-IaC.latest.gitlab-ci.yml" }] }
|
||||
end
|
||||
|
||||
it 'generates the correct YML' do
|
||||
expect(result[:action]).to eq('update')
|
||||
expect(result[:content]).to eq(expected_yml)
|
||||
end
|
||||
end
|
||||
|
||||
context 'secret_detection template include is not an array' do
|
||||
let(:gitlab_ci_content) do
|
||||
{ "stages" => %w(test),
|
||||
"variables" => { "RANDOM" => "make sure this persists" },
|
||||
"include" => { "template" => "Security/SAST-IaC.latest.gitlab-ci.yml" } }
|
||||
end
|
||||
|
||||
it 'generates the correct YML' do
|
||||
expect(result[:action]).to eq('update')
|
||||
expect(result[:content]).to eq(expected_yml)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with no .gitlab-ci.yml' do
|
||||
let(:gitlab_ci_content) { nil }
|
||||
|
||||
context 'autodevops disabled' do
|
||||
let(:auto_devops_enabled) { false }
|
||||
let(:expected_yml) do
|
||||
<<-CI_YML.strip_heredoc
|
||||
# You can override the included template(s) by including variable overrides
|
||||
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
|
||||
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
|
||||
# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
|
||||
# Note that environment variables can be set in several places
|
||||
# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
|
||||
include:
|
||||
- template: Security/SAST-IaC.latest.gitlab-ci.yml
|
||||
CI_YML
|
||||
end
|
||||
|
||||
it 'generates the correct YML' do
|
||||
expect(result[:action]).to eq('create')
|
||||
expect(result[:content]).to eq(expected_yml)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with autodevops enabled' do
|
||||
let(:auto_devops_enabled) { true }
|
||||
let(:expected_yml) do
|
||||
<<-CI_YML.strip_heredoc
|
||||
# You can override the included template(s) by including variable overrides
|
||||
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
|
||||
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
|
||||
# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
|
||||
# Note that environment variables can be set in several places
|
||||
# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
|
||||
include:
|
||||
- template: Auto-DevOps.gitlab-ci.yml
|
||||
CI_YML
|
||||
end
|
||||
|
||||
before do
|
||||
allow_next_instance_of(described_class) do |sast_iac_build_actions|
|
||||
allow(sast_iac_build_actions).to receive(:auto_devops_stages).and_return(fast_auto_devops_stages)
|
||||
end
|
||||
end
|
||||
|
||||
it 'generates the correct YML' do
|
||||
expect(result[:action]).to eq('create')
|
||||
expect(result[:content]).to eq(expected_yml)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# stubbing this method allows this spec file to use fast_spec_helper
|
||||
def fast_auto_devops_stages
|
||||
auto_devops_template = YAML.safe_load( File.read('lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml') )
|
||||
auto_devops_template['stages']
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'ConfigureSastIac' do
|
||||
include GraphqlHelpers
|
||||
|
||||
let_it_be(:project) { create(:project, :test_repo) }
|
||||
|
||||
let(:variables) { { project_path: project.full_path } }
|
||||
let(:mutation) { graphql_mutation(:configure_sast_iac, variables) }
|
||||
let(:mutation_response) { graphql_mutation_response(:configureSastIac) }
|
||||
|
||||
context 'when authorized' do
|
||||
let_it_be(:user) { project.owner }
|
||||
|
||||
it 'creates a branch with sast iac configured' do
|
||||
post_graphql_mutation(mutation, current_user: user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:success)
|
||||
expect(mutation_response['errors']).to be_empty
|
||||
expect(mutation_response['branch']).not_to be_empty
|
||||
expect(mutation_response['successPath']).not_to be_empty
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Security::CiConfiguration::SastIacCreateService, :snowplow do
|
||||
subject(:result) { described_class.new(project, user).execute }
|
||||
|
||||
let(:branch_name) { 'set-sast-iac-config-1' }
|
||||
|
||||
let(:snowplow_event) do
|
||||
{
|
||||
category: 'Security::CiConfiguration::SastIacCreateService',
|
||||
action: 'create',
|
||||
label: ''
|
||||
}
|
||||
end
|
||||
|
||||
include_examples 'services security ci configuration create service', true
|
||||
end
|
Loading…
Reference in a new issue