From f3f4c741bea0513cdad77ebedf44552628f21e6d Mon Sep 17 00:00:00 2001 From: Christopher Fenner Date: Sun, 11 Aug 2019 22:42:34 +0200 Subject: [PATCH] sonarExecuteScan: add custom certificate support (#819) * feat(sonar): load TLS certificates * allow verbose property * handle whitespaces * cleanup * disable default verbosity on wget * correct test file name * add test case for custom certificates * import StandardCharsets * change cleanup * correct pull-request provider name * correct pull-request provider name * correct pull-request provider name --- resources/default_pipeline_environment.yml | 2 +- ...est.groovy => SonarExecuteScanTest.groovy} | 19 +++++- vars/sonarExecuteScan.groovy | 58 ++++++++++++++++--- 3 files changed, 70 insertions(+), 9 deletions(-) rename test/groovy/{SonarExecuteTest.groovy => SonarExecuteScanTest.groovy} (91%) diff --git a/resources/default_pipeline_environment.yml b/resources/default_pipeline_environment.yml index 654340790..f12bdd7fd 100644 --- a/resources/default_pipeline_environment.yml +++ b/resources/default_pipeline_environment.yml @@ -501,7 +501,7 @@ steps: dockerImage: 'maven:3.5-jdk-8' instance: 'SonarCloud' options: [] - pullRequestProvider: 'github' + pullRequestProvider: 'GitHub' sonarScannerDownloadUrl: 'https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.3.0.1492-linux.zip' testsPublishResults: failOnError: false diff --git a/test/groovy/SonarExecuteTest.groovy b/test/groovy/SonarExecuteScanTest.groovy similarity index 91% rename from test/groovy/SonarExecuteTest.groovy rename to test/groovy/SonarExecuteScanTest.groovy index 70c96d0f7..b40ca7e8b 100644 --- a/test/groovy/SonarExecuteTest.groovy +++ b/test/groovy/SonarExecuteScanTest.groovy @@ -146,7 +146,7 @@ class SonarExecuteScanTest extends BasePiperTest { containsString('-Dsonar.pullrequest.key=42'), containsString('-Dsonar.pullrequest.base=master'), containsString('-Dsonar.pullrequest.branch=feature/anything'), - containsString('-Dsonar.pullrequest.provider=github'), + containsString('-Dsonar.pullrequest.provider=GitHub'), containsString('-Dsonar.pullrequest.github.repository=testOrg/testRepo') ))) assertJobStatusSuccess() @@ -234,4 +234,21 @@ class SonarExecuteScanTest extends BasePiperTest { assertThat(jscr.shell, hasItem(containsString('-Dsonar.organization=TestOrg-github'))) assertJobStatusSuccess() } + + @Test + void testWithCustomTlsCertificates() throws Exception { + jsr.step.sonarExecuteScan( + script: nullScript, + juStabUtils: utils, + customTlsCertificateLinks: [ + 'http://url.to/my.cert' + ] + ) + // asserts + assertThat(jscr.shell, allOf( + hasItem(containsString('wget --directory-prefix .certificates/ --no-verbose http://url.to/my.cert')), + hasItem(containsString('keytool -import -noprompt -storepass changeit -keystore .sonar-scanner/jre/lib/security/cacerts -alias \'my.cert\' -file \'.certificates/my.cert\'')) + )) + assertJobStatusSuccess() + } } diff --git a/vars/sonarExecuteScan.groovy b/vars/sonarExecuteScan.groovy index ecd2fc03c..e590d2097 100644 --- a/vars/sonarExecuteScan.groovy +++ b/vars/sonarExecuteScan.groovy @@ -7,6 +7,8 @@ import static com.sap.piper.Prerequisites.checkScript import groovy.transform.Field import groovy.text.SimpleTemplateEngine +import java.nio.charset.StandardCharsets + @Field String STEP_NAME = getClass().getName() @Field Set GENERAL_CONFIG_KEYS = [ @@ -40,8 +42,17 @@ import groovy.text.SimpleTemplateEngine * @possibleValues Jenkins credential id */ 'sonarTokenCredentialsId', + /** + * Print more detailed information into the log. + * @possibleValues `true`, `false` + */ + 'verbose' ] @Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([ + /** + * List containing download links of custom TLS certificates. This is required to ensure trusted connections to instances with custom certificates. + */ + 'customTlsCertificateLinks', /** * Pull-Request voting only: * Disables the pull-request decoration with inline comments. @@ -110,14 +121,20 @@ void call(Map parameters = [:]) { def worker = { config -> withSonarQubeEnv(config.instance) { - loadSonarScanner(config) + try{ + loadSonarScanner(config) - if(config.organization) config.options.add("sonar.organization=${config.organization}") - if(config.projectVersion) config.options.add("sonar.projectVersion=${config.projectVersion}") - // prefix options - config.options = config.options.collect { it.startsWith('-D') ? it : "-D${it}" } + loadCertificates(config) - sh "PATH=\$PATH:${env.WORKSPACE}/.sonar-scanner/bin sonar-scanner ${config.options.join(' ')}" + if(config.organization) config.options.add("sonar.organization=${config.organization}") + if(config.projectVersion) config.options.add("sonar.projectVersion=${config.projectVersion}") + // prefix options + config.options = config.options.collect { it.startsWith('-D') ? it : "-D${it}" } + + sh "PATH=\$PATH:${env.WORKSPACE}/.sonar-scanner/bin sonar-scanner ${config.options.join(' ')}" + }finally{ + sh 'rm -rf .sonar-scanner .certificates .scannerwork' + } } } @@ -158,7 +175,7 @@ void call(Map parameters = [:]) { config.options.add("sonar.pullrequest.branch=${env.BRANCH_NAME}") config.options.add("sonar.pullrequest.provider=${config.pullRequestProvider}") switch(config.pullRequestProvider){ - case 'github': + case 'GitHub': config.options.add("sonar.pullrequest.github.repository=${config.githubOrg}/${config.githubRepo}") break default: error "Pull-Request provider '${config.pullRequestProvider}' is not supported!" @@ -191,3 +208,30 @@ private void loadSonarScanner(config){ mv ${foldername} .sonar-scanner """ } + +private void loadCertificates(Map config) { + String certificateFolder = '.certificates/' + List wgetOptions = [ + "--directory-prefix ${certificateFolder}" + ] + List keytoolOptions = [ + '-import', + '-noprompt', + '-storepass changeit', + '-keystore .sonar-scanner/jre/lib/security/cacerts' + ] + if (config.customTlsCertificateLinks){ + if(config.verbose){ + wgetOptions.push('--verbose') + keytoolOptions.push('-v') + }else{ + wgetOptions.push('--no-verbose') + } + config.customTlsCertificateLinks.each { url -> + def filename = new File(url).getName() + filename = URLDecoder.decode(filename, StandardCharsets.UTF_8.name()) + sh "wget ${wgetOptions.join(' ')} ${url}" + sh "keytool ${keytoolOptions.join(' ')} -alias '${filename}' -file '${certificateFolder}${filename}'" + } + } +}