Commit 4dd22f47 authored by rossfuhrman's avatar rossfuhrman Committed by Stan Hu

Support writing variables to CI config

Add support for writing variables to the .gitlab-ci.yml file created
when using the SAST configuration UI
parent b829bd76
...@@ -15,17 +15,17 @@ module Projects ...@@ -15,17 +15,17 @@ module Projects
end end
def create def create
@branch_name = project.repository.next_branch("add-sast-config") result = ::Security::CiConfiguration::SastCreateService.new(project, current_user, params).execute
@commit_params = { if result[:status] == :success
commit_message: "Add .gitlab-ci.yml to enable or configure SAST", respond_to do |format|
actions: [{ action: "create", file_path: ".gitlab-ci.yml", content: gitlab_ci_yml }] format.json { render json: { message: _("success"), filePath: result[:success_path] } }
} end
else
project.repository.add_branch(current_user, @branch_name, project.default_branch) respond_to do |format|
format.json { render json: { message: _("failed"), filePath: '' } }
create_commit(::Files::MultiService, success_notice: _("The .gitlab-ci.yml has been successfully created."), end
success_path: successful_change_path, failure_path: '') end
end end
private private
...@@ -33,39 +33,6 @@ module Projects ...@@ -33,39 +33,6 @@ module Projects
def ensure_sast_configuration_enabled! def ensure_sast_configuration_enabled!
not_found unless ::Feature.enabled?(:sast_configuration_ui, project) not_found unless ::Feature.enabled?(:sast_configuration_ui, project)
end end
def successful_change_path
description = "Add .gitlab-ci.yml to enable or configure SAST security scanning 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."
merge_request_params = { source_branch: @branch_name, description: description }
project_new_merge_request_url(@project, merge_request: merge_request_params)
end
def gitlab_ci_yml
return ado_yml if project.auto_devops_enabled?
sast_yml
end
def ado_yml
<<-CI_YML.strip_heredoc
include:
- template: Auto-DevOps.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
# You can override the above template(s) by including variable overrides
# See https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
CI_YML
end
def sast_yml
<<-CI_YML.strip_heredoc
stages:
- test
include:
- template: SAST.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
# You can override the above template(s) by including variable overrides
# See https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
CI_YML
end
end end
end end
end end
# frozen_string_literal: true
module Security
module CiConfiguration
class SastCreateService < ::BaseService
def initialize(project, current_user, params)
@project = project
@current_user = current_user
@params = params
@branch_name = @project.repository.next_branch('add-sast-config')
end
def execute
result = ::Files::MultiService.new(@project, @current_user, attributes).execute
if result[:status] == :success
result[:success_path] = successful_change_path
end
result
end
private
def attributes
actions = Security::CiConfiguration::SastBuildActions.new(@project.auto_devops_enabled?, @params).generate
@project.repository.add_branch(@current_user, @branch_name, @project.default_branch)
message = _('Add .gitlab-ci.yml to enable or configure SAST')
{
commit_message: message,
branch_name: @branch_name,
start_branch: @branch_name,
actions: actions
}
end
def successful_change_path
description = _('Add .gitlab-ci.yml to enable or configure SAST security scanning 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.')
merge_request_params = { source_branch: @branch_name, description: description }
Gitlab::Routing.url_helpers.project_new_merge_request_url(@project, merge_request: merge_request_params)
end
end
end
end
---
title: Support writing variables to CI config
merge_request: 37516
author:
type: added
# frozen_string_literal: true
module Security
module CiConfiguration
class SastBuildActions
def initialize(auto_devops_enabled, params)
@auto_devops_enabled = auto_devops_enabled
@params = params
end
def generate
config = {
'stages' => stages,
'variables' => parse_variables(global_variables),
'sast' => sast_block,
'include' => [{ 'template' => template }]
}.select { |k, v| v.present? }
content = config.to_yaml
content << "# You can override the above template(s) by including variable overrides\n"
content << "# See https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings\n"
[{ action: 'create', file_path: '.gitlab-ci.yml', content: content }]
end
private
def stages
base_stages = @auto_devops_enabled ? auto_devops_stages : ['test']
(base_stages + [sast_stage]).uniq
end
def auto_devops_stages
auto_devops_template = YAML.safe_load( Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps').content )
auto_devops_template['stages']
end
def sast_stage
@params[:stage] || 'test'
end
# We only want to write variables that are set
def parse_variables(variables)
variables.map { |var| [var, @params[var]] }.to_h.compact
end
def sast_block
{
'variables' => parse_variables(sast_variables),
'stage' => sast_stage,
'script' => ['/analyzer run']
}.select { |k, v| v.present? }
end
def template
return 'Auto-DevOps.gitlab-ci.yml' if @auto_devops_enabled
'SAST.gitlab-ci.yml'
end
def global_variables
%w(
SECURE_ANALYZERS_PREFIX
)
end
def sast_variables
%w(
SAST_ANALYZER_IMAGE_TAG
SAST_EXCLUDED_PATHS
SEARCH_MAX_DEPTH
)
end
end
end
end
...@@ -82,10 +82,17 @@ RSpec.describe Projects::Security::SastConfigurationController do ...@@ -82,10 +82,17 @@ RSpec.describe Projects::Security::SastConfigurationController do
context 'with valid params' do context 'with valid params' do
it 'returns the new merge request url' do it 'returns the new merge request url' do
create_sast_configuration user: developer, project: project, params: {} params = {
secure_analyzers_prefix: 'localhost:5000/analyzers',
sast_analyzer_image_tag: '1',
sast_excluded_paths: 'docs',
stage: 'security',
search_max_depth: 11
}
create_sast_configuration user: developer, project: project, params: params
expect(json_response["message"]).to eq("success") expect(json_response["message"]).to eq("success")
expect(json_response["filePath"]).to match(/#{project_new_merge_request_url(project, {})}(.*)description(.*)source_branch/) expect(json_response["filePath"]).to match(/#{Gitlab::Routing.url_helpers.project_new_merge_request_url(project, {})}(.*)description(.*)source_branch/)
end end
end end
end end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Security::CiConfiguration::SastBuildActions do
context 'autodevops disabled' do
let(:auto_devops_enabled) { false }
context 'with no paramaters' do
let(:params) { {} }
subject(:result) { described_class.new(auto_devops_enabled, params).generate }
it 'generates the correct YML' do
expect(result.first[:content]).to eq(sast_yaml_no_params)
end
end
context 'with all parameters' do
let(:params) do
{ stage: 'security',
'SEARCH_MAX_DEPTH' => 1,
'SECURE_ANALYZERS_PREFIX' => 'localhost:5000/analyzers',
'SAST_ANALYZER_IMAGE_TAG' => 2,
'SAST_EXCLUDED_PATHS' => 'docs' }
end
subject(:result) { described_class.new(auto_devops_enabled, params).generate }
it 'generates the correct YML' do
expect(result.first[:content]).to eq(sast_yaml_all_params)
end
end
end
context 'with autodevops enabled' do
let(:auto_devops_enabled) { true }
let(:params) { { stage: 'custom stage' } }
subject(:result) { described_class.new(auto_devops_enabled, params).generate }
it 'generates the correct YML' do
expect(result.first[:content]).to eq(auto_devops_with_custom_stage)
end
end
def sast_yaml_no_params
<<-CI_YML.strip_heredoc
---
stages:
- test
sast:
stage: test
script:
- "/analyzer run"
include:
- template: SAST.gitlab-ci.yml
# You can override the above template(s) by including variable overrides
# See https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
CI_YML
end
def sast_yaml_all_params
<<-CI_YML.strip_heredoc
---
stages:
- test
- security
variables:
SECURE_ANALYZERS_PREFIX: localhost:5000/analyzers
sast:
variables:
SAST_ANALYZER_IMAGE_TAG: 2
SAST_EXCLUDED_PATHS: docs
SEARCH_MAX_DEPTH: 1
stage: security
script:
- "/analyzer run"
include:
- template: SAST.gitlab-ci.yml
# You can override the above template(s) by including variable overrides
# See https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
CI_YML
end
def auto_devops_with_custom_stage
<<-CI_YML.strip_heredoc
---
stages:
- build
- test
- deploy
- review
- dast
- staging
- canary
- production
- incremental rollout 10%
- incremental rollout 25%
- incremental rollout 50%
- incremental rollout 100%
- performance
- cleanup
- custom stage
sast:
stage: custom stage
script:
- "/analyzer run"
include:
- template: Auto-DevOps.gitlab-ci.yml
# You can override the above template(s) by including variable overrides
# See https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
CI_YML
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Security::CiConfiguration::SastCreateService do
describe '#execute' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
subject(:result) { described_class.new(project, user, params).execute }
before do
project.add_developer(user)
end
context 'with no parameters' do
let(:params) { {} }
it 'returns the path to create a new merge request' do
expect(result[:status]).to eq(:success)
expect(result[:success_path]).to match(/#{Gitlab::Routing.url_helpers.project_new_merge_request_url(project, {})}(.*)description(.*)source_branch/)
end
end
end
end
...@@ -1369,6 +1369,12 @@ msgstr[1] "" ...@@ -1369,6 +1369,12 @@ msgstr[1] ""
msgid "Add %{linkStart}assets%{linkEnd} to your Release. GitLab automatically includes read-only assets, like source code and release evidence." msgid "Add %{linkStart}assets%{linkEnd} to your Release. GitLab automatically includes read-only assets, like source code and release evidence."
msgstr "" msgstr ""
msgid "Add .gitlab-ci.yml to enable or configure SAST"
msgstr ""
msgid "Add .gitlab-ci.yml to enable or configure SAST security scanning 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 ""
msgid "Add CHANGELOG" msgid "Add CHANGELOG"
msgstr "" msgstr ""
...@@ -23670,9 +23676,6 @@ msgid_plural "The %{type} contains the following errors:" ...@@ -23670,9 +23676,6 @@ msgid_plural "The %{type} contains the following errors:"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "The .gitlab-ci.yml has been successfully created."
msgstr ""
msgid "The Advanced Global Search in GitLab is a powerful search service that saves you time. Instead of creating duplicate code and wasting time, you can now search for code within other teams that can help your own project." msgid "The Advanced Global Search in GitLab is a powerful search service that saves you time. Instead of creating duplicate code and wasting time, you can now search for code within other teams that can help your own project."
msgstr "" msgstr ""
......
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