mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-18 05:18:24 +02:00
Merge branch 'master' into whitesourceExecuteScan
This commit is contained in:
commit
b1b480a7e1
@ -1,2 +1,2 @@
|
||||
# Test case configuration
|
||||
referenceAppRepoUrl: "https://github.com/sap/cloud-s4-sdk-book"
|
||||
referenceAppRepoUrl: "https://github.com/piper-validation/cloud-s4-sdk-book"
|
||||
|
@ -1,2 +1,2 @@
|
||||
# Test case configuration
|
||||
referenceAppRepoUrl: "https://github.com/sap/cloud-s4-sdk-book"
|
||||
referenceAppRepoUrl: "https://github.com/piper-validation/cloud-s4-sdk-book"
|
||||
|
9
documentation/docs/steps/piperPublishWarnings.md
Normal file
9
documentation/docs/steps/piperPublishWarnings.md
Normal file
@ -0,0 +1,9 @@
|
||||
# ${docGenStepName}
|
||||
|
||||
## ${docGenDescription}
|
||||
|
||||
## ${docGenParameters}
|
||||
|
||||
## ${docGenConfiguration}
|
||||
|
||||
## ${docJenkinsPluginDependencies}
|
9
documentation/docs/steps/tmsUpload.md
Normal file
9
documentation/docs/steps/tmsUpload.md
Normal file
@ -0,0 +1,9 @@
|
||||
# ${docGenStepName}
|
||||
|
||||
## ${docGenDescription}
|
||||
|
||||
## ${docGenParameters}
|
||||
|
||||
## ${docGenConfiguration}
|
||||
|
||||
## ${docJenkinsPluginDependencies}
|
@ -37,6 +37,7 @@ nav:
|
||||
- pipelineStashFiles: steps/pipelineStashFiles.md
|
||||
- pipelineStashFilesAfterBuild: steps/pipelineStashFilesAfterBuild.md
|
||||
- pipelineStashFilesBeforeBuild: steps/pipelineStashFilesBeforeBuild.md
|
||||
- piperPublishWarnings: steps/piperPublishWarnings.md
|
||||
- prepareDefaultValues: steps/prepareDefaultValues.md
|
||||
- seleniumExecuteTests: steps/seleniumExecuteTests.md
|
||||
- setupCommonPipelineEnvironment: steps/setupCommonPipelineEnvironment.md
|
||||
|
@ -450,6 +450,14 @@ steps:
|
||||
tests: ''
|
||||
noDefaultExludes:
|
||||
- 'git'
|
||||
piperPublishWarnings:
|
||||
parserId: piper
|
||||
parserName: Piper
|
||||
parserPattern: '\[(INFO|WARNING|ERROR)\] (.*) \(([^) ]*)\/([^) ]*)\)'
|
||||
parserScript: 'return builder.guessSeverity(matcher.group(1)).setMessage(matcher.group(2)).setModuleName(matcher.group(3)).setType(matcher.group(4)).buildOptional()'
|
||||
recordIssuesSettings:
|
||||
blameDisabled: true
|
||||
enabledForFailure: true
|
||||
seleniumExecuteTests:
|
||||
buildTool: 'npm'
|
||||
containerPortMappings:
|
||||
@ -534,6 +542,10 @@ steps:
|
||||
active: false
|
||||
checkChangeInDevelopment:
|
||||
failIfStatusIsNotInDevelopment: true
|
||||
tmsUpload:
|
||||
namedUser: 'Piper-Pipeline'
|
||||
stashContent:
|
||||
- 'buildResult'
|
||||
transportRequestCreate:
|
||||
developmentSystemId: null
|
||||
verbose: false
|
||||
|
@ -1,10 +1,14 @@
|
||||
package com.sap.piper
|
||||
|
||||
import com.cloudbees.groovy.cps.NonCPS
|
||||
import jenkins.model.Jenkins
|
||||
import org.jenkinsci.plugins.workflow.steps.MissingContextVariableException
|
||||
|
||||
import hudson.tasks.junit.TestResultAction
|
||||
|
||||
import jenkins.model.Jenkins
|
||||
|
||||
import org.apache.commons.io.IOUtils
|
||||
import org.jenkinsci.plugins.workflow.steps.MissingContextVariableException
|
||||
|
||||
@API
|
||||
@NonCPS
|
||||
static def isPluginActive(pluginId) {
|
||||
@ -19,6 +23,32 @@ static boolean hasTestFailures(build){
|
||||
return action && action.getFailCount() != 0
|
||||
}
|
||||
|
||||
boolean addWarningsNGParser(String id, String name, String regex, String script, String example = ''){
|
||||
def classLoader = this.getClass().getClassLoader()
|
||||
// usage of class loader to avoid plugin dependency for other use cases of JenkinsUtils class
|
||||
def parserConfig = classLoader.loadClass('io.jenkins.plugins.analysis.warnings.groovy.ParserConfiguration', true)?.getInstance()
|
||||
|
||||
if(parserConfig.contains(id)){
|
||||
return false
|
||||
}else{
|
||||
parserConfig.setParsers(
|
||||
parserConfig.getParsers().plus(
|
||||
classLoader.loadClass('io.jenkins.plugins.analysis.warnings.groovy.GroovyParser', true)?.newInstance(id, name, regex, script, example)
|
||||
)
|
||||
)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@NonCPS
|
||||
static String getFullBuildLog(currentBuild) {
|
||||
Reader reader = currentBuild.getRawBuild().getLogReader()
|
||||
String logContent = IOUtils.toString(reader);
|
||||
reader.close();
|
||||
reader = null
|
||||
return logContent
|
||||
}
|
||||
|
||||
def nodeAvailable() {
|
||||
try {
|
||||
sh "echo 'Node is available!'"
|
||||
@ -74,3 +104,7 @@ String getIssueCommentTriggerAction() {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
def getJobStartedByUserId() {
|
||||
return getRawBuild().getCause(hudson.model.Cause.UserIdCause.class)?.getUserId()
|
||||
}
|
||||
|
137
src/com/sap/piper/integration/TransportManagementService.groovy
Normal file
137
src/com/sap/piper/integration/TransportManagementService.groovy
Normal file
@ -0,0 +1,137 @@
|
||||
package com.sap.piper.integration
|
||||
|
||||
import com.sap.piper.JsonUtils
|
||||
|
||||
class TransportManagementService implements Serializable {
|
||||
|
||||
final Script script
|
||||
final Map config
|
||||
|
||||
def jsonUtils = new JsonUtils()
|
||||
|
||||
TransportManagementService(Script script, Map config) {
|
||||
this.script = script
|
||||
this.config = config
|
||||
}
|
||||
|
||||
def authentication(String uaaUrl, String oauthClientId, String oauthClientSecret) {
|
||||
echo("OAuth Token retrieval started.")
|
||||
|
||||
if (config.verbose) {
|
||||
echo("UAA-URL: '${uaaUrl}', ClientId: '${oauthClientId}''")
|
||||
}
|
||||
|
||||
def encodedUsernameColonPassword = "${oauthClientId}:${oauthClientSecret}".bytes.encodeBase64().toString()
|
||||
def urlEncodedFormData = "grant_type=password&" +
|
||||
"username=${urlEncodeAndReplaceSpace(oauthClientId)}&" +
|
||||
"password=${urlEncodeAndReplaceSpace(oauthClientSecret)}"
|
||||
|
||||
def parameters = [
|
||||
url : "${uaaUrl}/oauth/token/?grant_type=client_credentials&response_type=token",
|
||||
httpMode : "POST",
|
||||
requestBody : urlEncodedFormData,
|
||||
customHeaders: [
|
||||
[
|
||||
maskValue: false,
|
||||
name : 'Content-Type',
|
||||
value : 'application/x-www-form-urlencoded'
|
||||
],
|
||||
[
|
||||
maskValue: true,
|
||||
name : 'authorization',
|
||||
value : "Basic ${encodedUsernameColonPassword}"
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
def response = sendApiRequest(parameters)
|
||||
echo("OAuth Token retrieved successfully.")
|
||||
|
||||
return jsonUtils.jsonStringToGroovyObject(response).access_token
|
||||
|
||||
}
|
||||
|
||||
|
||||
def uploadFile(String url, String token, String file, String namedUser) {
|
||||
|
||||
echo("File upload started.")
|
||||
|
||||
if (config.verbose) {
|
||||
echo("URL: '${url}', File: '${file}'")
|
||||
}
|
||||
|
||||
script.sh """#!/bin/sh -e
|
||||
curl -H 'Authorization: Bearer ${token}' -F 'file=@${file}' -F 'namedUser=${namedUser}' -o responseFileUpload.txt --fail '${url}/v2/files/upload'
|
||||
"""
|
||||
|
||||
def responseContent = script.readFile("responseFileUpload.txt")
|
||||
|
||||
if (config.verbose) {
|
||||
echo("${responseContent}")
|
||||
}
|
||||
|
||||
echo("File upload successful.")
|
||||
|
||||
return jsonUtils.jsonStringToGroovyObject(responseContent)
|
||||
|
||||
}
|
||||
|
||||
|
||||
def uploadFileToNode(String url, String token, String nodeName, int fileId, String description, String namedUser) {
|
||||
|
||||
echo("Node upload started.")
|
||||
|
||||
if (config.verbose) {
|
||||
echo("URL: '${url}', NodeName: '${nodeName}', FileId: '${fileId}''")
|
||||
}
|
||||
|
||||
def bodyMap = [nodeName: nodeName, contentType: 'MTA', description: description, storageType: 'FILE', namedUser: namedUser, entries: [[uri: fileId]]]
|
||||
|
||||
def parameters = [
|
||||
url : "${url}/v2/nodes/upload",
|
||||
httpMode : "POST",
|
||||
contentType : 'APPLICATION_JSON',
|
||||
requestBody : jsonUtils.groovyObjectToPrettyJsonString(bodyMap),
|
||||
customHeaders: [
|
||||
[
|
||||
maskValue: true,
|
||||
name : 'authorization',
|
||||
value : "Bearer ${token}"
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
def response = sendApiRequest(parameters)
|
||||
echo("Node upload successful.")
|
||||
|
||||
return jsonUtils.jsonStringToGroovyObject(response)
|
||||
|
||||
}
|
||||
|
||||
private sendApiRequest(parameters) {
|
||||
def defaultParameters = [
|
||||
acceptType : 'APPLICATION_JSON',
|
||||
quiet : !config.verbose,
|
||||
consoleLogResponseBody: !config.verbose,
|
||||
ignoreSslErrors : true,
|
||||
validResponseCodes : "100:399"
|
||||
]
|
||||
|
||||
def response = script.httpRequest(defaultParameters + parameters)
|
||||
|
||||
if (config.verbose) {
|
||||
echo("Received response '${response.content}' with status ${response.status}.")
|
||||
}
|
||||
|
||||
return response.content
|
||||
}
|
||||
|
||||
private echo(message) {
|
||||
script.echo "[${getClass().getSimpleName()}] ${message}"
|
||||
}
|
||||
|
||||
private static String urlEncodeAndReplaceSpace(String data) {
|
||||
return URLEncoder.encode(data, "UTF-8").replace('%20', '+')
|
||||
}
|
||||
|
||||
}
|
85
test/groovy/PiperPublishWarningsTest.groovy
Normal file
85
test/groovy/PiperPublishWarningsTest.groovy
Normal file
@ -0,0 +1,85 @@
|
||||
#!groovy
|
||||
package steps
|
||||
|
||||
import com.sap.piper.JenkinsUtils
|
||||
|
||||
import static org.hamcrest.Matchers.allOf
|
||||
import static org.hamcrest.Matchers.any
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
import static org.hamcrest.Matchers.hasItem
|
||||
import static org.hamcrest.Matchers.hasEntry
|
||||
import static org.hamcrest.Matchers.hasKey
|
||||
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.RuleChain
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
import util.BasePiperTest
|
||||
import util.Rules
|
||||
import util.JenkinsLoggingRule
|
||||
import util.JenkinsReadYamlRule
|
||||
import util.JenkinsStepRule
|
||||
import util.JenkinsShellCallRule
|
||||
|
||||
import static com.lesfurets.jenkins.unit.MethodSignature.method
|
||||
|
||||
class PiperPublishWarningsTest extends BasePiperTest {
|
||||
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this)
|
||||
private JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this)
|
||||
|
||||
def warningsParserSettings
|
||||
def groovyScriptParserSettings
|
||||
def warningsPluginOptions
|
||||
|
||||
@Rule
|
||||
public RuleChain ruleChain = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(loggingRule)
|
||||
.around(shellRule)
|
||||
.around(stepRule)
|
||||
|
||||
@Before
|
||||
void init() throws Exception {
|
||||
warningsParserSettings = [:]
|
||||
groovyScriptParserSettings = [:]
|
||||
warningsPluginOptions = [:]
|
||||
|
||||
// add handler for generic step call
|
||||
helper.registerAllowedMethod("writeFile", [Map.class], null)
|
||||
helper.registerAllowedMethod("recordIssues", [Map.class], {
|
||||
parameters -> warningsPluginOptions = parameters
|
||||
})
|
||||
helper.registerAllowedMethod("groovyScript", [Map.class], {
|
||||
parameters -> groovyScriptParserSettings = parameters
|
||||
})
|
||||
JenkinsUtils.metaClass.addWarningsNGParser = { String s1, String s2, String s3, String s4 ->
|
||||
warningsParserSettings = [id: s1, name: s2, regex: s3, script: s4]
|
||||
return true
|
||||
}
|
||||
JenkinsUtils.metaClass.static.getFullBuildLog = { def currentBuild -> return ""}
|
||||
JenkinsUtils.metaClass.static.isPluginActive = { id -> return true}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPublishWarnings() throws Exception {
|
||||
stepRule.step.piperPublishWarnings(script: nullScript)
|
||||
// asserts
|
||||
assertThat(loggingRule.log, containsString('[piperPublishWarnings] Added warnings-ng plugin parser \'Piper\' configuration.'))
|
||||
assertThat(warningsParserSettings, hasEntry('id', 'piper'))
|
||||
assertThat(warningsParserSettings, hasEntry('name', 'Piper'))
|
||||
assertThat(warningsParserSettings, hasEntry('regex', '\\[(INFO|WARNING|ERROR)\\] (.*) \\(([^) ]*)\\/([^) ]*)\\)'))
|
||||
assertThat(warningsParserSettings, hasKey('script'))
|
||||
assertThat(warningsPluginOptions, allOf(
|
||||
hasEntry('enabledForFailure', true),
|
||||
hasEntry('blameDisabled', true)
|
||||
))
|
||||
assertThat(warningsPluginOptions, hasKey('tools'))
|
||||
|
||||
assertThat(groovyScriptParserSettings, hasEntry('parserId', 'piper'))
|
||||
assertThat(groovyScriptParserSettings, hasEntry('pattern', 'build.log'))
|
||||
}
|
||||
}
|
182
test/groovy/TmsUploadTest.groovy
Normal file
182
test/groovy/TmsUploadTest.groovy
Normal file
@ -0,0 +1,182 @@
|
||||
import com.sap.piper.JenkinsUtils
|
||||
import com.sap.piper.integration.TransportManagementService
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.containsString
|
||||
import static org.hamcrest.Matchers.is
|
||||
import static org.hamcrest.Matchers.not
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
public class TmsUploadTest extends BasePiperTest {
|
||||
|
||||
private ExpectedException thrown = new ExpectedException()
|
||||
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this)
|
||||
private JenkinsEnvironmentRule envRule = new JenkinsEnvironmentRule(this)
|
||||
|
||||
def tmsStub
|
||||
def jenkinsUtilsStub
|
||||
def calledTmsMethodsWithArgs = []
|
||||
def uri = "https://dummy-url.com"
|
||||
def uaaUrl = "https://oauth.com"
|
||||
def oauthClientId = "myClientId"
|
||||
def oauthClientSecret = "myClientSecret"
|
||||
def serviceKeyContent = """{
|
||||
"uri": "${uri}",
|
||||
"uaa": {
|
||||
"clientid": "${oauthClientId}",
|
||||
"clientsecret": "${oauthClientSecret}",
|
||||
"url": "${uaaUrl}"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
class JenkinsUtilsMock extends JenkinsUtils {
|
||||
def userId
|
||||
|
||||
JenkinsUtilsMock(userId) {
|
||||
this.userId = userId
|
||||
}
|
||||
|
||||
def getJobStartedByUserId(){
|
||||
return this.userId
|
||||
}
|
||||
}
|
||||
|
||||
@Rule
|
||||
public RuleChain ruleChain = Rules.getCommonRules(this)
|
||||
.around(thrown)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(stepRule)
|
||||
.around(loggingRule)
|
||||
.around(envRule)
|
||||
.around(new JenkinsCredentialsRule(this)
|
||||
.withCredentials('TMS_ServiceKey', serviceKeyContent))
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
tmsStub = mockTransportManagementService()
|
||||
helper.registerAllowedMethod("unstash", [String.class], { s -> return [s] })
|
||||
}
|
||||
|
||||
@After
|
||||
void tearDown() {
|
||||
calledTmsMethodsWithArgs.clear()
|
||||
}
|
||||
|
||||
@Test
|
||||
public void minimalConfig__isSuccessful() {
|
||||
jenkinsUtilsStub = new JenkinsUtilsMock("Test User")
|
||||
binding.workspace = "."
|
||||
envRule.env.gitCommitId = "testCommitId"
|
||||
|
||||
stepRule.step.tmsUpload(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
jenkinsUtilsStub: jenkinsUtilsStub,
|
||||
transportManagementService: tmsStub,
|
||||
mtaPath: 'dummy.mtar',
|
||||
nodeName: 'myNode',
|
||||
credentialsId: 'TMS_ServiceKey'
|
||||
)
|
||||
|
||||
assertThat(calledTmsMethodsWithArgs[0], is("authentication('${uaaUrl}', '${oauthClientId}', '${oauthClientSecret}')"))
|
||||
assertThat(calledTmsMethodsWithArgs[1], is("uploadFile('${uri}', 'myToken', './dummy.mtar', 'Test User')"))
|
||||
assertThat(calledTmsMethodsWithArgs[2], is("uploadFileToNode('${uri}', 'myToken', 'myNode', '1234', 'Git CommitId: testCommitId')"))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] File './dummy.mtar' successfully uploaded to Node 'myNode' (Id: '1000')."))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] Corresponding Transport Request: 'Git CommitId: testCommitId' (Id: '2000')"))
|
||||
assertThat(loggingRule.log, not(containsString("[TransportManagementService] CredentialsId: 'TMS_ServiceKey'")))
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verboseMode__yieldsMoreEchos() {
|
||||
jenkinsUtilsStub = new JenkinsUtilsMock("Test User")
|
||||
binding.workspace = "."
|
||||
envRule.env.gitCommitId = "testCommitId"
|
||||
|
||||
stepRule.step.tmsUpload(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
jenkinsUtilsStub: jenkinsUtilsStub,
|
||||
transportManagementService: tmsStub,
|
||||
mtaPath: 'dummy.mtar',
|
||||
nodeName: 'myNode',
|
||||
credentialsId: 'TMS_ServiceKey',
|
||||
verbose: true
|
||||
)
|
||||
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] CredentialsId: 'TMS_ServiceKey'"))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] Node name: 'myNode'"))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] MTA path: 'dummy.mtar'"))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] Named user: 'Test User'"))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] UAA URL: '${uaaUrl}'"))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] TMS URL: '${uri}'"))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] ClientId: '${oauthClientId}'"))
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noUserAvailableInCurrentBuild__usesDefaultUser() {
|
||||
jenkinsUtilsStub = new JenkinsUtilsMock(null)
|
||||
binding.workspace = "."
|
||||
envRule.env.gitCommitId = "testCommitId"
|
||||
|
||||
stepRule.step.tmsUpload(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
jenkinsUtilsStub: jenkinsUtilsStub,
|
||||
transportManagementService: tmsStub,
|
||||
mtaPath: 'dummy.mtar',
|
||||
nodeName: 'myNode',
|
||||
credentialsId: 'TMS_ServiceKey'
|
||||
)
|
||||
|
||||
assertThat(calledTmsMethodsWithArgs[1], is("uploadFile('${uri}', 'myToken', './dummy.mtar', 'Piper-Pipeline')"))
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addCustomDescription__descriptionChanged() {
|
||||
jenkinsUtilsStub = new JenkinsUtilsMock("Test User")
|
||||
binding.workspace = "."
|
||||
envRule.env.gitCommitId = "testCommitId"
|
||||
|
||||
stepRule.step.tmsUpload(
|
||||
script: nullScript,
|
||||
juStabUtils: utils,
|
||||
jenkinsUtilsStub: jenkinsUtilsStub,
|
||||
transportManagementService: tmsStub,
|
||||
mtaPath: 'dummy.mtar',
|
||||
nodeName: 'myNode',
|
||||
credentialsId: 'TMS_ServiceKey',
|
||||
customDescription: 'My custom description for testing.'
|
||||
)
|
||||
|
||||
assertThat(calledTmsMethodsWithArgs[2], is("uploadFileToNode('${uri}', 'myToken', 'myNode', '1234', 'My custom description for testing.')"))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] Corresponding Transport Request: 'My custom description for testing.' (Id: '2000')"))
|
||||
}
|
||||
|
||||
def mockTransportManagementService() {
|
||||
return new TransportManagementService(nullScript, [:]) {
|
||||
def authentication(String uaaUrl, String oauthClientId, String oauthClientSecret) {
|
||||
calledTmsMethodsWithArgs << "authentication('${uaaUrl}', '${oauthClientId}', '${oauthClientSecret}')"
|
||||
return "myToken"
|
||||
}
|
||||
|
||||
def uploadFile(String url, String token, String file, String namedUser) {
|
||||
calledTmsMethodsWithArgs << "uploadFile('${url}', '${token}', '${file}', '${namedUser}')"
|
||||
return [fileId: 1234, fileName: file]
|
||||
}
|
||||
|
||||
def uploadFileToNode(String url, String token, String nodeName, int fileId, String description, String namedUser) {
|
||||
calledTmsMethodsWithArgs << "uploadFileToNode('${url}', '${token}', '${nodeName}', '${fileId}', '${description}')"
|
||||
return [transportRequestDescription: description, transportRequestId: 2000, queueEntries: [nodeName: 'myNode', nodeId: 1000]]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ import org.jenkinsci.plugins.workflow.steps.MissingContextVariableException
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.ExpectedException
|
||||
import org.junit.rules.RuleChain
|
||||
import util.BasePiperTest
|
||||
import util.JenkinsLoggingRule
|
||||
@ -33,6 +32,8 @@ class JenkinsUtilsTest extends BasePiperTest {
|
||||
|
||||
Map triggerCause
|
||||
|
||||
String userId
|
||||
|
||||
|
||||
@Before
|
||||
void init() throws Exception {
|
||||
@ -60,7 +61,15 @@ class JenkinsUtilsTest extends BasePiperTest {
|
||||
return parentMock
|
||||
}
|
||||
def getCause(type) {
|
||||
return triggerCause
|
||||
if (type == hudson.model.Cause.UserIdCause.class){
|
||||
def userIdCause = new hudson.model.Cause.UserIdCause()
|
||||
userIdCause.metaClass.getUserId = {
|
||||
return userId
|
||||
}
|
||||
return userIdCause
|
||||
} else {
|
||||
return triggerCause
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -109,4 +118,16 @@ class JenkinsUtilsTest extends BasePiperTest {
|
||||
]
|
||||
assertThat(jenkinsUtils.getIssueCommentTriggerAction(), isEmptyOrNullString())
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetUserId() {
|
||||
userId = 'Test User'
|
||||
assertThat(jenkinsUtils.getJobStartedByUserId(), is('Test User'))
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetUserIdNoUser() {
|
||||
userId = null
|
||||
assertThat(jenkinsUtils.getJobStartedByUserId(), isEmptyOrNullString())
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,181 @@
|
||||
package com.sap.piper.integration
|
||||
|
||||
import hudson.AbortException
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.Ignore
|
||||
import org.junit.rules.ExpectedException
|
||||
import org.junit.rules.RuleChain
|
||||
import util.*
|
||||
|
||||
import static org.hamcrest.Matchers.*
|
||||
import static org.junit.Assert.assertThat
|
||||
|
||||
class TransportManagementServiceTest extends BasePiperTest {
|
||||
private ExpectedException thrown = ExpectedException.none()
|
||||
private JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this)
|
||||
private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this)
|
||||
|
||||
@Rule
|
||||
public RuleChain rules = Rules
|
||||
.getCommonRules(this)
|
||||
.around(new JenkinsErrorRule(this))
|
||||
.around(new JenkinsReadJsonRule(this))
|
||||
.around(shellRule)
|
||||
.around(loggingRule)
|
||||
.around(new JenkinsReadFileRule(this, 'test/resources/TransportManagementService'))
|
||||
.around(thrown)
|
||||
|
||||
@Test
|
||||
void retrieveOAuthToken__successfully() {
|
||||
Map requestParams
|
||||
helper.registerAllowedMethod('httpRequest', [Map.class], { m ->
|
||||
requestParams = m
|
||||
return [content: '{ "access_token": "myOAuthToken" }']
|
||||
})
|
||||
|
||||
def uaaUrl = 'http://dummy.com/oauth'
|
||||
def clientId = 'myId'
|
||||
def clientSecret = 'mySecret'
|
||||
|
||||
def tms = new TransportManagementService(nullScript, [:])
|
||||
def token = tms.authentication(uaaUrl, clientId, clientSecret)
|
||||
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] OAuth Token retrieval started."))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] OAuth Token retrieved successfully."))
|
||||
assertThat(token, is('myOAuthToken'))
|
||||
assertThat(requestParams, hasEntry('url', "${uaaUrl}/oauth/token/?grant_type=client_credentials&response_type=token"))
|
||||
assertThat(requestParams, hasEntry('requestBody', "grant_type=password&username=${clientId}&password=${clientSecret}".toString()))
|
||||
assertThat(requestParams.customHeaders[1].value, is("Basic ${"${clientId}:${clientSecret}".bytes.encodeBase64()}"))
|
||||
}
|
||||
|
||||
@Test
|
||||
void retrieveOAuthToken__inVerboseMode__yieldsMoreEchos() {
|
||||
Map requestParams
|
||||
helper.registerAllowedMethod('httpRequest', [Map.class], { m ->
|
||||
requestParams = m
|
||||
return [content: '{ "access_token": "myOAuthToken" }', status: 200]
|
||||
})
|
||||
|
||||
def uaaUrl = 'http://dummy.com/oauth'
|
||||
def clientId = 'myId'
|
||||
def clientSecret = 'mySecret'
|
||||
|
||||
def tms = new TransportManagementService(nullScript, [verbose: true])
|
||||
tms.authentication(uaaUrl, clientId, clientSecret)
|
||||
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] OAuth Token retrieval started."))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] UAA-URL: '${uaaUrl}', ClientId: '${clientId}'"))
|
||||
assertThat(loggingRule.log, containsString("Received response '{ \"access_token\": \"myOAuthToken\" }' with status 200."))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] OAuth Token retrieved successfully."))
|
||||
}
|
||||
|
||||
@Test
|
||||
void uploadFile__successfully() {
|
||||
|
||||
def url = 'http://dummy.com/oauth'
|
||||
def token = 'myToken'
|
||||
def file = 'myFile.mtar'
|
||||
def namedUser = 'myUser'
|
||||
|
||||
def tms = new TransportManagementService(nullScript, [:])
|
||||
def responseDetails = tms.uploadFile(url, token, file, namedUser)
|
||||
|
||||
def oAuthShellCall = shellRule.shell[0]
|
||||
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] File upload started."))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] File upload successful."))
|
||||
assertThat(oAuthShellCall, startsWith("#!/bin/sh -e "))
|
||||
assertThat(oAuthShellCall, endsWith("curl -H 'Authorization: Bearer ${token}' -F 'file=@${file}' -F 'namedUser=${namedUser}' -o responseFileUpload.txt --fail '${url}/v2/files/upload'"))
|
||||
assertThat(responseDetails, hasEntry("fileId", 1234))
|
||||
}
|
||||
|
||||
@Ignore
|
||||
void uploadFile__withHttpErrorResponse__throwsError() {
|
||||
|
||||
def url = 'http://dummy.com/oauth'
|
||||
def token = 'myWrongToken'
|
||||
def file = 'myFile.mtar'
|
||||
def namedUser = 'myUser'
|
||||
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, ".* curl .*", {throw new AbortException()})
|
||||
|
||||
thrown.expect(AbortException.class)
|
||||
|
||||
def tms = new TransportManagementService(nullScript, [:])
|
||||
tms.uploadFile(url, token, file, namedUser)
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void uploadFile__inVerboseMode__yieldsMoreEchos() {
|
||||
|
||||
def url = 'http://dummy.com/oauth'
|
||||
def token = 'myToken'
|
||||
def file = 'myFile.mtar'
|
||||
def namedUser = 'myUser'
|
||||
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, ".* curl .*", '200')
|
||||
|
||||
def tms = new TransportManagementService(nullScript, [verbose: true])
|
||||
tms.uploadFile(url, token, file, namedUser)
|
||||
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] File upload started."))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] URL: '${url}', File: '${file}'"))
|
||||
assertThat(loggingRule.log, containsString("\"fileId\": 1234"))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] File upload successful."))
|
||||
}
|
||||
|
||||
@Test
|
||||
void uploadFileToNode__successfully() {
|
||||
Map requestParams
|
||||
helper.registerAllowedMethod('httpRequest', [Map.class], { m ->
|
||||
requestParams = m
|
||||
return [content: '{ "upload": "success" }']
|
||||
})
|
||||
|
||||
def url = 'http://dummy.com/oauth'
|
||||
def token = 'myToken'
|
||||
def nodeName = 'myNode'
|
||||
def fileId = 1234
|
||||
def description = "My description."
|
||||
def namedUser = 'myUser'
|
||||
|
||||
def tms = new TransportManagementService(nullScript, [:])
|
||||
def responseDetails = tms.uploadFileToNode(url, token, nodeName, fileId, description, namedUser)
|
||||
|
||||
def bodyRegEx = /^\{\s+"nodeName":\s+"myNode",\s+"contentType":\s+"MTA",\s+"description":\s+"My\s+description.",\s+"storageType":\s+"FILE",\s+"namedUser":\s+"myUser",\s+"entries":\s+\[\s+\{\s+"uri":\s+1234\s+}\s+]\s+}$/
|
||||
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] Node upload started."))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] Node upload successful."))
|
||||
assertThat(requestParams, hasEntry('url', "${url}/v2/nodes/upload"))
|
||||
assert requestParams.requestBody ==~ bodyRegEx
|
||||
assertThat(requestParams.customHeaders[0].value, is("Bearer ${token}"))
|
||||
assertThat(responseDetails, hasEntry("upload", "success"))
|
||||
}
|
||||
|
||||
@Test
|
||||
void uploadFileToNode__inVerboseMode__yieldsMoreEchos() {
|
||||
Map requestParams
|
||||
helper.registerAllowedMethod('httpRequest', [Map.class], { m ->
|
||||
requestParams = m
|
||||
return [content: '{ "upload": "success" }']
|
||||
})
|
||||
|
||||
def url = 'http://dummy.com/oauth'
|
||||
def token = 'myToken'
|
||||
def nodeName = 'myNode'
|
||||
def fileId = 1234
|
||||
def description = "My description."
|
||||
def namedUser = 'myUser'
|
||||
|
||||
def tms = new TransportManagementService(nullScript, [verbose: true])
|
||||
tms.uploadFileToNode(url, token, nodeName, fileId, description, namedUser)
|
||||
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] Node upload started."))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] URL: '${url}', NodeName: '${nodeName}', FileId: '${fileId}'"))
|
||||
assertThat(loggingRule.log, containsString("\"upload\": \"success\""))
|
||||
assertThat(loggingRule.log, containsString("[TransportManagementService] Node upload successful."))
|
||||
}
|
||||
|
||||
}
|
@ -37,13 +37,14 @@ class PiperPipelineStagePostTest extends BasePiperTest {
|
||||
helper.registerAllowedMethod('influxWriteData', [Map.class], {m -> stepsCalled.add('influxWriteData')})
|
||||
helper.registerAllowedMethod('slackSendNotification', [Map.class], {m -> stepsCalled.add('slackSendNotification')})
|
||||
helper.registerAllowedMethod('mailSendNotification', [Map.class], {m -> stepsCalled.add('mailSendNotification')})
|
||||
helper.registerAllowedMethod('piperPublishWarnings', [Map.class], {m -> stepsCalled.add('piperPublishWarnings')})
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPostDefault() {
|
||||
jsr.step.piperPipelineStagePost(script: nullScript, juStabUtils: utils)
|
||||
|
||||
assertThat(stepsCalled, hasItems('influxWriteData','mailSendNotification'))
|
||||
assertThat(stepsCalled, hasItems('influxWriteData','mailSendNotification','piperPublishWarnings'))
|
||||
assertThat(stepsCalled, not(hasItems('slackSendNotification')))
|
||||
}
|
||||
|
||||
@ -53,7 +54,7 @@ class PiperPipelineStagePostTest extends BasePiperTest {
|
||||
|
||||
jsr.step.piperPipelineStagePost(script: nullScript, juStabUtils: utils)
|
||||
|
||||
assertThat(stepsCalled, hasItems('influxWriteData','mailSendNotification'))
|
||||
assertThat(stepsCalled, hasItems('influxWriteData','mailSendNotification','piperPublishWarnings'))
|
||||
assertThat(stepsCalled, not(hasItems('slackSendNotification')))
|
||||
}
|
||||
|
||||
@ -63,6 +64,6 @@ class PiperPipelineStagePostTest extends BasePiperTest {
|
||||
|
||||
jsr.step.piperPipelineStagePost(script: nullScript, juStabUtils: utils)
|
||||
|
||||
assertThat(stepsCalled, hasItems('influxWriteData','mailSendNotification','slackSendNotification'))
|
||||
assertThat(stepsCalled, hasItems('influxWriteData','mailSendNotification','slackSendNotification','piperPublishWarnings'))
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,11 @@ class CommandLineMatcher extends BaseMatcher {
|
||||
return this
|
||||
}
|
||||
|
||||
CommandLineMatcher hasSnippet(String snippet) {
|
||||
this.args.add(snippet)
|
||||
return this
|
||||
}
|
||||
|
||||
CommandLineMatcher hasArgument(String arg) {
|
||||
this.args.add(arg)
|
||||
return this
|
||||
@ -58,7 +63,7 @@ class CommandLineMatcher extends BaseMatcher {
|
||||
|
||||
for (String arg : args) {
|
||||
if (!cmd.matches(/.*[\s]*${arg}[\s]*.*/)) {
|
||||
hint = "A command line having argument '${arg}'."
|
||||
hint = "A command line having argument/snippet '${arg}'."
|
||||
matches = false
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ class JenkinsFileExistsRule implements TestRule {
|
||||
void evaluate() throws Throwable {
|
||||
|
||||
testInstance.helper.registerAllowedMethod('fileExists', [String.class], {s -> return s in existingFiles})
|
||||
testInstance.helper.registerAllowedMethod('fileExists', [Map.class], {m -> return m.file in existingFiles})
|
||||
|
||||
base.evaluate()
|
||||
}
|
||||
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"access_token": "myOAuthToken"
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"fileId": 1234
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"upload": "success"
|
||||
}
|
@ -48,5 +48,6 @@ void call(Map parameters = [:]) {
|
||||
}
|
||||
}
|
||||
mailSendNotification script: script
|
||||
piperPublishWarnings script: script
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ import static com.sap.piper.Prerequisites.checkScript
|
||||
'healthExecuteCheck',
|
||||
/** For Neo use-cases: Performs deployment to Neo landscape. */
|
||||
'neoDeploy',
|
||||
/** For TMS use-cases: Performs upload to Transport Management Service node*/
|
||||
'tmsUpload',
|
||||
/** Publishes release information to GitHub. */
|
||||
'githubPublishRelease',
|
||||
]
|
||||
@ -60,6 +62,12 @@ void call(Map parameters = [:]) {
|
||||
}
|
||||
}
|
||||
|
||||
if (config.tmsUpload) {
|
||||
durationMeasure(script: script, measurementName: 'upload_release_tms_duration') {
|
||||
tmsUpload script: script
|
||||
}
|
||||
}
|
||||
|
||||
if (config.healthExecuteCheck) {
|
||||
healthExecuteCheck script: script
|
||||
}
|
||||
|
96
vars/piperPublishWarnings.groovy
Normal file
96
vars/piperPublishWarnings.groovy
Normal file
@ -0,0 +1,96 @@
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.GenerateDocumentation
|
||||
import com.sap.piper.JenkinsUtils
|
||||
import com.sap.piper.Utils
|
||||
|
||||
import groovy.transform.Field
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
@Field List PLUGIN_ID_LIST = ['warnings-ng']
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = []
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
|
||||
/**
|
||||
* The id of the Groovy script parser. If the id is not present in the current Jenkins configuration it is created.
|
||||
*/
|
||||
'parserId',
|
||||
/**
|
||||
* The display name for the warnings parsed by the parser.
|
||||
* Only considered if a new parser is created.
|
||||
*/
|
||||
'parserName',
|
||||
/**
|
||||
* The pattern used to parse the log file.
|
||||
* Only considered if a new parser is created.
|
||||
*/
|
||||
'parserPattern',
|
||||
/**
|
||||
* The script used to parse the matches produced by the pattern into issues.
|
||||
* Only considered if a new parser is created.
|
||||
* see https://github.com/jenkinsci/analysis-model/blob/master/src/main/java/edu/hm/hafner/analysis/IssueBuilder.java
|
||||
*/
|
||||
'parserScript',
|
||||
/**
|
||||
* Settings that are passed to the recordIssues step of the warnings-ng plugin.
|
||||
* see https://github.com/jenkinsci/warnings-ng-plugin/blob/master/doc/Documentation.md#configuration
|
||||
*/
|
||||
'recordIssuesSettings'
|
||||
])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus([])
|
||||
|
||||
/**
|
||||
* This step scans the current build log for messages produces by the Piper library steps and publishes them on the Jenkins job run as *Piper warnings* via the warnings-ng plugin.
|
||||
*
|
||||
* The default parser detects log entries with the following pattern: `[<SEVERITY>] <MESSAGE> (<LIBRARY>/<STEP>)`
|
||||
*/
|
||||
@GenerateDocumentation
|
||||
void call(Map parameters = [:]) {
|
||||
handlePipelineStepErrors (stepName: STEP_NAME, stepParameters: parameters, allowBuildFailure: true) {
|
||||
|
||||
final script = checkScript(this, parameters) ?: this
|
||||
|
||||
for(String id : PLUGIN_ID_LIST){
|
||||
if (!JenkinsUtils.isPluginActive(id)) {
|
||||
error("[ERROR][${STEP_NAME}] The step requires the plugin '${id}' to be installed and activated in the Jenkins.")
|
||||
}
|
||||
}
|
||||
|
||||
// load default & individual configuration
|
||||
Map configuration = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName ?: env.STAGE_NAME, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
.use()
|
||||
// report to SWA
|
||||
new Utils().pushToSWA([
|
||||
step: STEP_NAME,
|
||||
stepParamKey1: 'scriptMissing',
|
||||
stepParam1: parameters?.script == null
|
||||
], configuration)
|
||||
|
||||
// add Piper Notifications parser to config if missing
|
||||
if(new JenkinsUtils().addWarningsNGParser(
|
||||
configuration.parserId,
|
||||
configuration.parserName,
|
||||
configuration.parserPattern,
|
||||
configuration.parserScript
|
||||
)){
|
||||
echo "[${STEP_NAME}] Added warnings-ng plugin parser '${configuration.parserName}' configuration."
|
||||
}
|
||||
|
||||
writeFile file: 'build.log', text: JenkinsUtils.getFullBuildLog(script.currentBuild)
|
||||
// parse log for Piper Notifications
|
||||
recordIssues(
|
||||
configuration.recordIssuesSettings.plus([
|
||||
tools: [groovyScript(
|
||||
parserId: configuration.parserId,
|
||||
pattern: 'build.log'
|
||||
)]
|
||||
])
|
||||
)
|
||||
}
|
||||
}
|
131
vars/tmsUpload.groovy
Normal file
131
vars/tmsUpload.groovy
Normal file
@ -0,0 +1,131 @@
|
||||
import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.GenerateDocumentation
|
||||
import com.sap.piper.JenkinsUtils
|
||||
import com.sap.piper.JsonUtils
|
||||
import com.sap.piper.Utils
|
||||
import com.sap.piper.integration.TransportManagementService
|
||||
import groovy.transform.Field
|
||||
|
||||
import static com.sap.piper.Prerequisites.checkScript
|
||||
|
||||
@Field String STEP_NAME = getClass().getName()
|
||||
|
||||
@Field Set GENERAL_CONFIG_KEYS = [
|
||||
/**
|
||||
* Print more detailed information into the log.
|
||||
* @possibleValues `true`, `false`
|
||||
*/
|
||||
'verbose'
|
||||
]
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
|
||||
/**
|
||||
* If specific stashes should be considered, their names need to be passed via the parameter `stashContent`.
|
||||
*/
|
||||
'stashContent',
|
||||
/**
|
||||
* Defines the path to *.mtar for the upload to the Transport Management Service.
|
||||
*/
|
||||
'mtaPath',
|
||||
/**
|
||||
* Defines the name of the node to which the *.mtar file should be uploaded.
|
||||
*/
|
||||
'nodeName',
|
||||
/**
|
||||
* Credentials to be used for the file and node uploads to the Transport Management Service.
|
||||
*/
|
||||
'credentialsId',
|
||||
/**
|
||||
* Can be used as the description of a transport request. Will overwrite the default. (Default: Corresponding Git Commit-ID)
|
||||
*/
|
||||
'customDescription'
|
||||
])
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
|
||||
/**
|
||||
* This step allows you to upload an MTA file (multi-target application archive) into a TMS (SAP Cloud Platform Transport Management Service) landscape for further TMS-controlled distribution through a TMS-configured landscape.
|
||||
* TMS lets you manage transports between SAP Cloud Platform accounts in Neo and Cloud Foundry, such as from DEV to TEST and PROD accounts.
|
||||
* For more information, see [official documentation of Transport Management Service](https://help.sap.com/viewer/p/TRANSPORT_MANAGEMENT_SERVICE)
|
||||
*
|
||||
* !!! note "Prerequisites"
|
||||
* * You have subscribed to and set up TMS, as described in [Setup and Configuration of SAP Cloud Platform Transport Management](https://help.sap.com/viewer/7f7160ec0d8546c6b3eab72fb5ad6fd8/Cloud/en-US/66fd7283c62f48adb23c56fb48c84a60.html), which includes the configuration of a node to be used for uploading an MTA file.
|
||||
* * A corresponding service key has been created, as described in [Set Up the Environment to Transport Content Archives directly in an Application](https://help.sap.com/viewer/7f7160ec0d8546c6b3eab72fb5ad6fd8/Cloud/en-US/8d9490792ed14f1bbf8a6ac08a6bca64.html). This service key (JSON) must be stored as a secret text within the Jenkins secure store.
|
||||
*
|
||||
*/
|
||||
@GenerateDocumentation
|
||||
void call(Map parameters = [:]) {
|
||||
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
def utils = parameters.juStabUtils ?: new Utils()
|
||||
def jenkinsUtils = parameters.jenkinsUtilsStub ?: new JenkinsUtils()
|
||||
|
||||
// load default & individual configuration
|
||||
Map config = ConfigurationHelper.newInstance(this)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
|
||||
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName ?: env.STAGE_NAME, STEP_CONFIG_KEYS)
|
||||
.mixin(parameters, PARAMETER_KEYS)
|
||||
//mandatory parameters
|
||||
.withMandatoryProperty('mtaPath')
|
||||
.withMandatoryProperty('nodeName')
|
||||
.withMandatoryProperty('credentialsId')
|
||||
.use()
|
||||
|
||||
// telemetry reporting
|
||||
new Utils().pushToSWA([
|
||||
step : STEP_NAME,
|
||||
stepParamKey1: 'scriptMissing',
|
||||
stepParam1 : parameters?.script == null
|
||||
], config)
|
||||
|
||||
def jsonUtilsObject = new JsonUtils()
|
||||
|
||||
// make sure that all relevant descriptors, are available in workspace
|
||||
utils.unstashAll(config.stashContent)
|
||||
// make sure that for further execution whole workspace, e.g. also downloaded artifacts are considered
|
||||
config.stashContent = []
|
||||
|
||||
def customDescription = config.customDescription ? "${config.customDescription}" : "Git CommitId: ${script.commonPipelineEnvironment.getGitCommitId()}"
|
||||
def description = customDescription
|
||||
|
||||
def namedUser = jenkinsUtils.getJobStartedByUserId() ?: config.namedUser
|
||||
|
||||
def nodeName = config.nodeName
|
||||
def mtaPath = config.mtaPath
|
||||
|
||||
if (config.verbose) {
|
||||
echo "[TransportManagementService] CredentialsId: '${config.credentialsId}'"
|
||||
echo "[TransportManagementService] Node name: '${nodeName}'"
|
||||
echo "[TransportManagementService] MTA path: '${mtaPath}'"
|
||||
echo "[TransportManagementService] Named user: '${namedUser}'"
|
||||
}
|
||||
|
||||
def tms = parameters.transportManagementService ?: new TransportManagementService(script, config)
|
||||
|
||||
withCredentials([string(credentialsId: config.credentialsId, variable: 'tmsServiceKeyJSON')]) {
|
||||
|
||||
def tmsServiceKey = jsonUtilsObject.jsonStringToGroovyObject(tmsServiceKeyJSON)
|
||||
|
||||
def clientId = tmsServiceKey.uaa.clientid
|
||||
def clientSecret = tmsServiceKey.uaa.clientsecret
|
||||
def uaaUrl = tmsServiceKey.uaa.url
|
||||
def uri = tmsServiceKey.uri
|
||||
|
||||
if (config.verbose) {
|
||||
echo "[TransportManagementService] UAA URL: '${uaaUrl}'"
|
||||
echo "[TransportManagementService] TMS URL: '${uri}'"
|
||||
echo "[TransportManagementService] ClientId: '${clientId}'"
|
||||
}
|
||||
|
||||
def token = tms.authentication(uaaUrl, clientId, clientSecret)
|
||||
def fileUploadResponse = tms.uploadFile(uri, token, "${workspace}/${mtaPath}", namedUser)
|
||||
def uploadFileToNodeResponse = tms.uploadFileToNode(uri, token, nodeName, fileUploadResponse.fileId, description, namedUser)
|
||||
|
||||
echo "[TransportManagementService] File '${fileUploadResponse.fileName}' successfully uploaded to Node '${uploadFileToNodeResponse.queueEntries.nodeName}' (Id: '${uploadFileToNodeResponse.queueEntries.nodeId}')."
|
||||
echo "[TransportManagementService] Corresponding Transport Request: '${uploadFileToNodeResponse.transportRequestDescription}' (Id: '${uploadFileToNodeResponse.transportRequestId}')"
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user