Commit 2fbae1f3 authored by rossfuhrman's avatar rossfuhrman Committed by Stan Hu

Add support for updating SAST config

Add support for updating SAST section of an existing .gitlab-ci.yml file
via the new SAST config UI.
parent 4e5c5c78
...@@ -7,7 +7,7 @@ module Security ...@@ -7,7 +7,7 @@ module Security
@project = project @project = project
@current_user = current_user @current_user = current_user
@params = params @params = params
@branch_name = @project.repository.next_branch('add-sast-config') @branch_name = @project.repository.next_branch('set-sast-config')
end end
def execute def execute
...@@ -23,10 +23,13 @@ module Security ...@@ -23,10 +23,13 @@ module Security
private private
def attributes def attributes
actions = Security::CiConfiguration::SastBuildActions.new(@project.auto_devops_enabled?, @params).generate gitlab_ci_yml = @project.repository.gitlab_ci_yml_for(@project.repository.root_ref_sha)
existing_gitlab_ci_content = YAML.safe_load(gitlab_ci_yml) if gitlab_ci_yml
actions = Security::CiConfiguration::SastBuildActions.new(@project.auto_devops_enabled?, @params, existing_gitlab_ci_content).generate
@project.repository.add_branch(@current_user, @branch_name, @project.default_branch) @project.repository.add_branch(@current_user, @branch_name, @project.default_branch)
message = _('Add .gitlab-ci.yml to enable or configure SAST') message = _('Set .gitlab-ci.yml to enable or configure SAST')
{ {
commit_message: message, commit_message: message,
...@@ -37,7 +40,7 @@ module Security ...@@ -37,7 +40,7 @@ module Security
end end
def successful_change_path 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.') description = _('Set .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 } merge_request_params = { source_branch: @branch_name, description: description }
Gitlab::Routing.url_helpers.project_new_merge_request_url(@project, merge_request: merge_request_params) Gitlab::Routing.url_helpers.project_new_merge_request_url(@project, merge_request: merge_request_params)
end end
......
---
title: Add support for updating SAST config
merge_request: 39269
author:
type: added
...@@ -3,31 +3,43 @@ ...@@ -3,31 +3,43 @@
module Security module Security
module CiConfiguration module CiConfiguration
class SastBuildActions class SastBuildActions
def initialize(auto_devops_enabled, params) def initialize(auto_devops_enabled, params, existing_gitlab_ci_content)
@auto_devops_enabled = auto_devops_enabled @auto_devops_enabled = auto_devops_enabled
@params = params @params = params
@existing_gitlab_ci_content = existing_gitlab_ci_content || {}
end end
def generate def generate
config = { action = @existing_gitlab_ci_content.present? ? 'update' : 'create'
'stages' => stages,
'variables' => parse_variables(global_variables), update_existing_content!
'sast' => sast_block,
'include' => [{ 'template' => template }] [{ action: action, file_path: '.gitlab-ci.yml', content: prepare_existing_content }]
}.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 end
private private
def stages def update_existing_content!
@existing_gitlab_ci_content['stages'] = set_stages
@existing_gitlab_ci_content['variables'] = set_variables(global_variables, @existing_gitlab_ci_content)
@existing_gitlab_ci_content['sast'] = set_sast_block
@existing_gitlab_ci_content['include'] = set_includes
@existing_gitlab_ci_content.select! { |k, v| v.present? }
@existing_gitlab_ci_content['sast'].select! { |k, v| v.present? }
end
def set_includes
includes = @existing_gitlab_ci_content['include'] || []
includes = includes.is_a?(Array) ? includes : [includes]
includes << { 'template' => template }
includes.uniq
end
def set_stages
existing_stages = @existing_gitlab_ci_content['stages'] || []
base_stages = @auto_devops_enabled ? auto_devops_stages : ['test'] base_stages = @auto_devops_enabled ? auto_devops_stages : ['test']
(base_stages + [sast_stage]).uniq (existing_stages + base_stages + [sast_stage]).uniq
end end
def auto_devops_stages def auto_devops_stages
...@@ -40,24 +52,46 @@ module Security ...@@ -40,24 +52,46 @@ module Security
end end
# We only want to write variables that are set # We only want to write variables that are set
def parse_variables(variables) def set_variables(variables, hash_to_update = {})
variables.map { |var| [var, @params[var]] } hash_to_update['variables'] ||= {}
.to_h variables.each do |k, v|
.select { |k, v| v.present? } hash_to_update['variables'][k] = @params[k]
end
hash_to_update['variables'].select { |k, v| v.present? }
end
def set_sast_block
sast_content = @existing_gitlab_ci_content['sast'] || {}
sast_content['variables'] = set_variables(sast_variables)
sast_content['stage'] = sast_stage
sast_content.select { |k, v| v.present? }
end
def prepare_existing_content
content = @existing_gitlab_ci_content.to_yaml
content = remove_document_delimeter(content)
content.prepend(sast_comment)
end
def remove_document_delimeter(content)
content.gsub(/^---\n/, '')
end end
def sast_block def sast_comment
{ <<~YAML
'variables' => parse_variables(sast_variables), # You can override the included template(s) by including variable overrides
'stage' => sast_stage, # See https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
'script' => ['/analyzer run'] # Note that environment variables can be set in several places
}.select { |k, v| v.present? } # See https://docs.gitlab.com/ee/ci/variables/#priority-of-environment-variables
YAML
end end
def template def template
return 'Auto-DevOps.gitlab-ci.yml' if @auto_devops_enabled return 'Auto-DevOps.gitlab-ci.yml' if @auto_devops_enabled
'SAST.gitlab-ci.yml' 'Security/SAST.gitlab-ci.yml'
end end
def global_variables def global_variables
......
...@@ -1410,12 +1410,6 @@ msgstr[1] "" ...@@ -1410,12 +1410,6 @@ 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 ""
...@@ -22200,6 +22194,12 @@ msgstr "" ...@@ -22200,6 +22194,12 @@ msgstr ""
msgid "Set %{epic_ref} as the parent epic." msgid "Set %{epic_ref} as the parent epic."
msgstr "" msgstr ""
msgid "Set .gitlab-ci.yml to enable or configure SAST"
msgstr ""
msgid "Set .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 "Set a default template for issue descriptions." msgid "Set a default template for issue descriptions."
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