mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-03-03 15:02:35 +02:00
Authentication via Cloud Foundry Service Key (#1034)
This commit is contained in:
parent
72b4e36156
commit
23d7058fdd
@ -4,8 +4,8 @@
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* A SAP Cloud Platform ABAP Environment system is available.
|
||||
* On this system, a [Communication User](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/0377adea0401467f939827242c1f4014.html), a [Communication System](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/1bfe32ae08074b7186e375ab425fb114.html) and a [Communication Arrangement](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/a0771f6765f54e1c8193ad8582a32edb.html) is setup for the Communication Scenario "SAP Cloud Platform ABAP Environment - Software Component Test Integration (SAP_COM_0510)".
|
||||
A SAP Cloud Platform ABAP Environment system is available.
|
||||
On this system, a [Communication User](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/0377adea0401467f939827242c1f4014.html), a [Communication System](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/1bfe32ae08074b7186e375ab425fb114.html) and a [Communication Arrangement](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/a0771f6765f54e1c8193ad8582a32edb.html) is setup for the Communication Scenario "SAP Cloud Platform ABAP Environment - Software Component Test Integration (SAP_COM_0510)". This can be done manually through the respective applications on the SAP Cloud Platform ABAP Environment System or through creating a service key for the system on cloud foundry with the parameters {"scenario_id": "SAP_COM_0510", "type": "basic"}.
|
||||
|
||||
## ${docGenParameters}
|
||||
|
||||
@ -15,11 +15,30 @@
|
||||
|
||||
## Example
|
||||
|
||||
In the first example, the host and the credentialsId of the Communication Arrangement are directly provided.
|
||||
|
||||
```groovy
|
||||
abapEnvironmentPullGitRepo (
|
||||
host : '1234-abcd-5678-efgh-ijk.abap.eu10.hana.ondemand.com',
|
||||
repositoryName : '/DMO/GIT_REPOSITORY',
|
||||
credentialsId : "myCredentialsId",
|
||||
script : this
|
||||
host : '1234-abcd-5678-efgh-ijk.abap.eu10.hana.ondemand.com',
|
||||
repositoryName : '/DMO/GIT_REPOSITORY',
|
||||
credentialsId : 'myCredentialsId',
|
||||
script : this
|
||||
)
|
||||
```
|
||||
|
||||
In the second example, the host and credentialsId will be read from the provided cloud foundry service key of the specified service instance.
|
||||
|
||||
```groovy
|
||||
abapEnvironmentPullGitRepo (
|
||||
script: this,
|
||||
repositoryName : '/DMO/GIT_REPOSITORY',
|
||||
cloudFoundry: [
|
||||
apiEndpoint: 'https://test.server.com',
|
||||
credentialsId: 'cfCredentialsId',
|
||||
org: 'cfOrg',
|
||||
space: 'cfSpace',
|
||||
serviceInstance: 'cfServiceInstance',
|
||||
serviceKey: 'cfServiceKey',
|
||||
]
|
||||
)
|
||||
```
|
||||
|
@ -51,6 +51,9 @@ general:
|
||||
|
||||
#Steps Specific Configuration
|
||||
steps:
|
||||
abapEnvironmentPullGitRepo:
|
||||
dockerImage: 'ppiper/cf-cli'
|
||||
dockerWorkspace: '/home/piper'
|
||||
artifactSetVersion:
|
||||
timestampTemplate: '%Y%m%d%H%M%S'
|
||||
tagPrefix: 'build_'
|
||||
|
@ -14,8 +14,10 @@ import org.junit.rules.RuleChain
|
||||
import util.BasePiperTest
|
||||
import util.JenkinsCredentialsRule
|
||||
import util.JenkinsStepRule
|
||||
import util.JenkinsReadJsonRule
|
||||
import util.JenkinsLoggingRule
|
||||
import util.JenkinsReadYamlRule
|
||||
import util.JenkinsDockerExecuteRule
|
||||
import util.JenkinsShellCallRule
|
||||
import util.Rules
|
||||
|
||||
@ -26,15 +28,19 @@ public class AbapEnvironmentPullGitRepoTest extends BasePiperTest {
|
||||
private ExpectedException thrown = new ExpectedException()
|
||||
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
|
||||
private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this)
|
||||
private JenkinsDockerExecuteRule dockerExecuteRule = new JenkinsDockerExecuteRule(this)
|
||||
private JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this)
|
||||
private JenkinsReadJsonRule readJsonRule = new JenkinsReadJsonRule(this)
|
||||
private JenkinsCredentialsRule credentialsRule = new JenkinsCredentialsRule(this).withCredentials('test_credentialsId', 'user', 'password')
|
||||
|
||||
@Rule
|
||||
public RuleChain ruleChain = Rules.getCommonRules(this)
|
||||
.around(new JenkinsReadYamlRule(this))
|
||||
.around(thrown)
|
||||
.around(dockerExecuteRule)
|
||||
.around(stepRule)
|
||||
.around(loggingRule)
|
||||
.around(readJsonRule)
|
||||
.around(credentialsRule)
|
||||
.around(shellRule)
|
||||
|
||||
@ -43,18 +49,19 @@ public class AbapEnvironmentPullGitRepoTest extends BasePiperTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pullSuccessful() {
|
||||
public void pullSuccessfulCredentialsId() {
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*x-csrf-token: fetch.*/, null )
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*POST.*/, /{"d" : { "__metadata" : { "uri" : "https:\/\/example.com\/URI" } , "status" : "R", "status_descr" : "RUNNING" }}/)
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*https:\/\/example\.com.*/, /{"d" : { "__metadata" : { "uri" : "https:\/\/example.com\/URI" } , "status" : "S", "status_descr" : "SUCCESS" }}/)
|
||||
|
||||
helper.registerAllowedMethod("readFile", [String.class], {
|
||||
helper.registerAllowedMethod("readFile", [String.class], {
|
||||
/HTTP\/1.1 200 OK
|
||||
set-cookie: sap-usercontext=sap-client=100; path=\/
|
||||
content-type: application\/json; charset=utf-8
|
||||
x-csrf-token: TOKEN/
|
||||
})
|
||||
|
||||
loggingRule.expect("[abapEnvironmentPullGitRepo] Info: Using configuration: credentialsId: test_credentialsId and host: example.com")
|
||||
loggingRule.expect("[abapEnvironmentPullGitRepo] Pull Status: RUNNING")
|
||||
loggingRule.expect("[abapEnvironmentPullGitRepo] Entity URI: https://example.com/URI")
|
||||
loggingRule.expect("[abapEnvironmentPullGitRepo] Pull Status: SUCCESS")
|
||||
@ -67,12 +74,115 @@ public class AbapEnvironmentPullGitRepoTest extends BasePiperTest {
|
||||
assertThat(shellRule.shell[3], containsString(/#!\/bin\/bash rm -f headerFileAuth-1.txt headerFilePost-1.txt headerFilePoll-1.txt/))
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pullSuccessfulCloudFoundry() {
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*cf service-key.*/, 0 )
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*x-csrf-token: fetch.*/, null )
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*POST.*/, /{"d" : { "__metadata" : { "uri" : "https:\/\/example.com\/URI" } , "status" : "R", "status_descr" : "RUNNING" }}/)
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*https:\/\/example.com.*/, /{"d" : { "__metadata" : { "uri" : "https:\/\/example.com\/URI" } , "status" : "S", "status_descr" : "SUCCESS" }}/)
|
||||
|
||||
helper.registerAllowedMethod("readFile", [String.class], { input ->
|
||||
if (input.contains("response")) {
|
||||
/Getting key SK_NAME_4 for service instance D09_TEST as P2001217173...\/
|
||||
|
||||
{
|
||||
"abap": {
|
||||
"password": "password",
|
||||
"username": "user"
|
||||
},
|
||||
"url": "https:\/\/example.com"
|
||||
}/
|
||||
} else {
|
||||
/HTTP\/1.1 200 OK
|
||||
set-cookie: sap-usercontext=sap-client=100; path=\/
|
||||
content-type: application\/json; charset=utf-8
|
||||
x-csrf-token: TOKEN/
|
||||
}
|
||||
})
|
||||
|
||||
loggingRule.expect("[abapEnvironmentPullGitRepo] Info: Using Cloud Foundry service key testKey for service instance testInstance")
|
||||
loggingRule.expect("[abapEnvironmentPullGitRepo] Pull Status: RUNNING")
|
||||
loggingRule.expect("[abapEnvironmentPullGitRepo] Entity URI: https://example.com/URI")
|
||||
loggingRule.expect("[abapEnvironmentPullGitRepo] Pull Status: SUCCESS")
|
||||
|
||||
stepRule.step.abapEnvironmentPullGitRepo(
|
||||
script: nullScript,
|
||||
repositoryName: 'Z_DEMO_DM',
|
||||
cloudFoundry: [
|
||||
apiEndpoint : 'api.cloudfoundry.com',
|
||||
org : 'testOrg',
|
||||
space : 'testSpace',
|
||||
credentialsId : 'test_credentialsId',
|
||||
serviceInstance : 'testInstance',
|
||||
serviceKey : 'testKey'
|
||||
])
|
||||
|
||||
assertThat(shellRule.shell[0], containsString(/#!\/bin\/bash set +x set -e export HOME=\/home\/piper cf login -u 'user' -p 'password' -a api.cloudfoundry.com -o 'testOrg' -s 'testSpace'; cf service-key 'testInstance' 'testKey' > "response-1.txt/))
|
||||
assertThat(shellRule.shell[1], containsString(/cf logout/))
|
||||
assertThat(shellRule.shell[2], containsString(/#!\/bin\/bash rm -f response-1.txt/))
|
||||
assertThat(shellRule.shell[3], containsString(/#!\/bin\/bash curl -I -X GET https:\/\/example.com\/sap\/opu\/odata\/sap\/MANAGE_GIT_REPOSITORY\/Pull -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Accept: application\/json' -H 'x-csrf-token: fetch' -D headerFileAuth-1.txt/))
|
||||
assertThat(shellRule.shell[4], containsString(/#!\/bin\/bash curl -X POST "https:\/\/example.com\/sap\/opu\/odata\/sap\/MANAGE_GIT_REPOSITORY\/Pull" -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Accept: application\/json' -H 'Content-Type: application\/json' -H 'x-csrf-token: TOKEN' --cookie headerFileAuth-1.txt -D headerFilePost-1.txt -d '{ "sc_name": "Z_DEMO_DM" }'/))
|
||||
assertThat(shellRule.shell[5], containsString(/#!\/bin\/bash curl -X GET "https:\/\/example.com\/URI" -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Accept: application\/json' -D headerFilePoll-1.txt/))
|
||||
assertThat(shellRule.shell[6], containsString(/#!\/bin\/bash rm -f headerFileAuth-1.txt headerFilePost-1.txt headerFilePoll-1.txt/))
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pullSuccessfulCloudFoundryFlatParameters() {
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*cf service-key.*/, 0 )
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*x-csrf-token: fetch.*/, null )
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*POST.*/, /{"d" : { "__metadata" : { "uri" : "https:\/\/example.com\/URI" } , "status" : "R", "status_descr" : "RUNNING" }}/)
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*https:\/\/example.com.*/, /{"d" : { "__metadata" : { "uri" : "https:\/\/example.com\/URI" } , "status" : "S", "status_descr" : "SUCCESS" }}/)
|
||||
|
||||
helper.registerAllowedMethod("readFile", [String.class], { input ->
|
||||
if (input.contains("response")) {
|
||||
/Getting key SK_NAME_4 for service instance D09_TEST as P2001217173...\/
|
||||
|
||||
{
|
||||
"abap": {
|
||||
"password": "password",
|
||||
"username": "user"
|
||||
},
|
||||
"url": "https:\/\/example.com"
|
||||
}/
|
||||
} else {
|
||||
/HTTP\/1.1 200 OK
|
||||
set-cookie: sap-usercontext=sap-client=100; path=\/
|
||||
content-type: application\/json; charset=utf-8
|
||||
x-csrf-token: TOKEN/
|
||||
}
|
||||
})
|
||||
|
||||
loggingRule.expect("[abapEnvironmentPullGitRepo] Info: Using Cloud Foundry service key testKey for service instance testInstance")
|
||||
loggingRule.expect("[abapEnvironmentPullGitRepo] Pull Status: RUNNING")
|
||||
loggingRule.expect("[abapEnvironmentPullGitRepo] Entity URI: https://example.com/URI")
|
||||
loggingRule.expect("[abapEnvironmentPullGitRepo] Pull Status: SUCCESS")
|
||||
|
||||
stepRule.step.abapEnvironmentPullGitRepo(
|
||||
script: nullScript,
|
||||
repositoryName: 'Z_DEMO_DM',
|
||||
cfApiEndpoint : 'api.cloudfoundry.com',
|
||||
cfOrg : 'testOrg',
|
||||
cfSpace : 'testSpace',
|
||||
cfCredentialsId : 'test_credentialsId',
|
||||
cfServiceInstance : 'testInstance',
|
||||
cfServiceKey : 'testKey'
|
||||
)
|
||||
|
||||
assertThat(shellRule.shell[0], containsString(/#!\/bin\/bash set +x set -e export HOME=\/home\/piper cf login -u 'user' -p 'password' -a api.cloudfoundry.com -o 'testOrg' -s 'testSpace'; cf service-key 'testInstance' 'testKey' > "response-1.txt/))
|
||||
assertThat(shellRule.shell[1], containsString(/cf logout/))
|
||||
assertThat(shellRule.shell[2], containsString(/#!\/bin\/bash rm -f response-1.txt/))
|
||||
assertThat(shellRule.shell[3], containsString(/#!\/bin\/bash curl -I -X GET https:\/\/example.com\/sap\/opu\/odata\/sap\/MANAGE_GIT_REPOSITORY\/Pull -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Accept: application\/json' -H 'x-csrf-token: fetch' -D headerFileAuth-1.txt/))
|
||||
assertThat(shellRule.shell[4], containsString(/#!\/bin\/bash curl -X POST "https:\/\/example.com\/sap\/opu\/odata\/sap\/MANAGE_GIT_REPOSITORY\/Pull" -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Accept: application\/json' -H 'Content-Type: application\/json' -H 'x-csrf-token: TOKEN' --cookie headerFileAuth-1.txt -D headerFilePost-1.txt -d '{ "sc_name": "Z_DEMO_DM" }'/))
|
||||
assertThat(shellRule.shell[5], containsString(/#!\/bin\/bash curl -X GET "https:\/\/example.com\/URI" -H 'Authorization: Basic dXNlcjpwYXNzd29yZA==' -H 'Accept: application\/json' -D headerFilePoll-1.txt/))
|
||||
assertThat(shellRule.shell[6], containsString(/#!\/bin\/bash rm -f headerFileAuth-1.txt headerFilePost-1.txt headerFilePoll-1.txt/))
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pullFailsWhilePolling() {
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*x-csrf-token: fetch.*/, "TOKEN")
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*POST.*/, /{"d" : { "__metadata" : { "uri" : "https:\/\/example.com\/URI" } , "status" : "R", "status_descr" : "RUNNING" }}/)
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*https:\/\/example\.com.*/, /{"d" : { "__metadata" : { "uri" : "https:\/\/example.com\/URI" } , "status" : "E", "status_descr" : "ERROR" }}/)
|
||||
|
||||
|
||||
helper.registerAllowedMethod("readFile", [String.class], {
|
||||
/HTTP\/1.1 200 OK
|
||||
set-cookie: sap-usercontext=sap-client=100; path=\/
|
||||
@ -94,7 +204,7 @@ public class AbapEnvironmentPullGitRepoTest extends BasePiperTest {
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*x-csrf-token: fetch.*/, "TOKEN")
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*POST.*/, /{"d" : { "__metadata" : { "uri" : "https:\/\/example.com\/URI" } , "status" : "E", "status_descr" : "ERROR" }}/)
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*https:\/\/example\.com.*/, /{"d" : { "__metadata" : { "uri" : "https:\/\/example.com\/URI" } , "status" : "E", "status_descr" : "ERROR" }}/)
|
||||
|
||||
|
||||
helper.registerAllowedMethod("readFile", [String.class], {
|
||||
/HTTP\/1.1 200 OK
|
||||
set-cookie: sap-usercontext=sap-client=100; path=\/
|
||||
@ -114,7 +224,7 @@ public class AbapEnvironmentPullGitRepoTest extends BasePiperTest {
|
||||
public void pullWithErrorResponse() {
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*x-csrf-token: fetch.*/, "TOKEN")
|
||||
shellRule.setReturnValue(JenkinsShellCallRule.Type.REGEX, /.*POST.*/, /{"error" : { "message" : { "lang" : "en", "value": "text" } }}/)
|
||||
|
||||
|
||||
helper.registerAllowedMethod("readFile", [String.class], {
|
||||
/HTTP\/1.1 200 OK
|
||||
set-cookie: sap-usercontext=sap-client=100; path=\/
|
||||
@ -148,17 +258,10 @@ public class AbapEnvironmentPullGitRepoTest extends BasePiperTest {
|
||||
@Test
|
||||
public void checkRepositoryProvided() {
|
||||
thrown.expect(IllegalArgumentException)
|
||||
thrown.expectMessage("Repository / Software Component not provided")
|
||||
thrown.expectMessage("ERROR - NO VALUE AVAILABLE FOR repositoryName")
|
||||
stepRule.step.abapEnvironmentPullGitRepo(script: nullScript, host: 'example.com', credentialsId: 'test_credentialsId')
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkHostProvided() {
|
||||
thrown.expect(IllegalArgumentException)
|
||||
thrown.expectMessage("Host not provided")
|
||||
stepRule.step.abapEnvironmentPullGitRepo(script: nullScript, repositoryName: 'REPO', credentialsId: 'test_credentialsId')
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpHeader() {
|
||||
|
||||
|
@ -3,87 +3,170 @@ import com.sap.piper.ConfigurationHelper
|
||||
import com.sap.piper.GenerateDocumentation
|
||||
import com.sap.piper.JenkinsUtils
|
||||
import com.sap.piper.Utils
|
||||
import com.sap.piper.BashUtils
|
||||
import groovy.json.JsonSlurper
|
||||
import hudson.AbortException
|
||||
import groovy.transform.Field
|
||||
import java.util.UUID
|
||||
import java.util.regex.*
|
||||
|
||||
@Field def STEP_NAME = getClass().getName()
|
||||
@Field Set GENERAL_CONFIG_KEYS = [
|
||||
@Field Set STEP_CONFIG_KEYS = [
|
||||
/**
|
||||
* Specifies the host address of the SAP Cloud Platform ABAP Environment system
|
||||
*/
|
||||
'host',
|
||||
/**
|
||||
* Specifies the name of the Repository (Software Component) on the SAP Cloud Platform ABAP Environment system
|
||||
*/
|
||||
'repositoryName'
|
||||
]
|
||||
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
|
||||
/**
|
||||
* Jenkins CredentialsId containing the communication user and password of the communciation scenario SAP_COM_0510
|
||||
*/
|
||||
'credentialsId'
|
||||
])
|
||||
'credentialsId',
|
||||
/**
|
||||
* Specifies the name of the Repository (Software Component) on the SAP Cloud Platform ABAP Environment system
|
||||
*/
|
||||
'repositoryName',
|
||||
'cloudFoundry',
|
||||
/**
|
||||
* Cloud Foundry API endpoint.
|
||||
* @parentConfigKey cloudFoundry
|
||||
*/
|
||||
'apiEndpoint',
|
||||
'credentialsId',
|
||||
/**
|
||||
* Cloud Foundry target organization.
|
||||
* @parentConfigKey cloudFoundry
|
||||
*/
|
||||
'org',
|
||||
/**
|
||||
* Cloud Foundry target space.
|
||||
* @parentConfigKey cloudFoundry
|
||||
*/
|
||||
'space',
|
||||
/**
|
||||
* Cloud Foundry service instance, for which the service key will be created.
|
||||
* @parentConfigKey cloudFoundry
|
||||
*/
|
||||
'serviceInstance',
|
||||
/**
|
||||
* Cloud Foundry service key, which will be created.
|
||||
* @parentConfigKey cloudFoundry
|
||||
*/
|
||||
'serviceKey',
|
||||
/** @see dockerExecute */
|
||||
'dockerImage',
|
||||
/** @see dockerExecute */
|
||||
'dockerWorkspace'
|
||||
]
|
||||
@Field Set GENERAL_CONFIG_KEYS = STEP_CONFIG_KEYS
|
||||
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
|
||||
@Field Map CONFIG_KEY_COMPATIBILITY = [cloudFoundry: [apiEndpoint: 'cfApiEndpoint', credentialsId: 'cfCredentialsId', org: 'cfOrg', space: 'cfSpace', serviceInstance: 'cfServiceInstance', serviceKey: 'cfServiceKey']]
|
||||
/**
|
||||
* Pulls a Repository (Software Component) to a SAP Cloud Platform ABAP Environment system.
|
||||
*
|
||||
* This is either possible by providing the host and the credentialsId of the communication arrangement or by providing access to a service key for the communication arrangement SAP_COM_0510 on cloud foundry.
|
||||
*
|
||||
* !!! note "Git Repository and Software Component"
|
||||
* In SAP Cloud Platform ABAP Environment Git repositories are wrapped in Software Components (which are managed in the App "Manage Software Components")
|
||||
* Currently, those two names are used synonymous.
|
||||
* !!! note "User and Password"
|
||||
* In the future, we want to support the user / password creation via the create-service-key funcion of cloud foundry.
|
||||
* For this case, it is not possible to use the usual pattern with Jenkins Credentials.
|
||||
*/
|
||||
@GenerateDocumentation
|
||||
void call(Map parameters = [:]) {
|
||||
|
||||
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters, failOnError: true) {
|
||||
|
||||
def script = checkScript(this, parameters) ?: this
|
||||
|
||||
// In the future, we want to support the user / password creation via the create-service-key funcion of cloud foundry.
|
||||
// For this case, it is not possible to use the usual pattern with Jenkins Credentials.
|
||||
Map configuration = ConfigurationHelper.newInstance(this)
|
||||
.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)
|
||||
.loadStepDefaults()
|
||||
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY)
|
||||
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY)
|
||||
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName ?: env.STAGE_NAME, STEP_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY)
|
||||
.mixin(parameters, PARAMETER_KEYS, CONFIG_KEY_COMPATIBILITY)
|
||||
.collectValidationFailures()
|
||||
.withMandatoryProperty('host', 'Host not provided')
|
||||
.withMandatoryProperty('repositoryName', 'Repository / Software Component not provided')
|
||||
.withMandatoryProperty('credentialsId')
|
||||
.withMandatoryProperty('repositoryName')
|
||||
.use()
|
||||
|
||||
String authToken
|
||||
withCredentials([usernamePassword(credentialsId: configuration.credentialsId, usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) {
|
||||
String userColonPassword = "${USER}:${PASSWORD}"
|
||||
authToken = userColonPassword.bytes.encodeBase64().toString()
|
||||
}
|
||||
|
||||
String urlString = 'https://' + configuration.host + '/sap/opu/odata/sap/MANAGE_GIT_REPOSITORY/Pull'
|
||||
echo "[${STEP_NAME}] General Parameters: URL = \"${urlString}\", repositoryName = \"${configuration.repositoryName}\""
|
||||
HeaderFiles headerFiles = new HeaderFiles()
|
||||
|
||||
try {
|
||||
String urlPullEntity = triggerPull(configuration, urlString, authToken, headerFiles)
|
||||
if (urlPullEntity != null) {
|
||||
String finalStatus = pollPullStatus(urlPullEntity, authToken, headerFiles)
|
||||
if (finalStatus != 'S') {
|
||||
error "[${STEP_NAME}] Pull Failed"
|
||||
}
|
||||
} else {
|
||||
error "[${STEP_NAME}] Pull Failed"
|
||||
String userColonPassword
|
||||
String urlString
|
||||
if (configuration.credentialsId != null && configuration.host != null) {
|
||||
echo "[${STEP_NAME}] Info: Using configuration: credentialsId: $configuration.credentialsId and host: $configuration.host"
|
||||
withCredentials([usernamePassword(credentialsId: configuration.credentialsId, usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) {
|
||||
userColonPassword = "${USER}:${PASSWORD}"
|
||||
urlString = 'https://' + configuration.host + '/sap/opu/odata/sap/MANAGE_GIT_REPOSITORY/Pull'
|
||||
}
|
||||
} finally {
|
||||
workspaceCleanup(headerFiles)
|
||||
} else {
|
||||
echo "[${STEP_NAME}] Info: Using Cloud Foundry service key $configuration.cloudFoundry.serviceKey for service instance $configuration.cloudFoundry.serviceInstance"
|
||||
dockerExecute(script:script,dockerImage: configuration.dockerImage, dockerWorkspace: configuration.dockerWorkspace) {
|
||||
String jsonString = getServiceKey(configuration)
|
||||
Map responseJson = readJSON(text : jsonString)
|
||||
userColonPassword = responseJson.abap.username + ":" + responseJson.abap.password
|
||||
urlString = responseJson.url + '/sap/opu/odata/sap/MANAGE_GIT_REPOSITORY/Pull'
|
||||
}
|
||||
}
|
||||
if (userColonPassword != null && urlString != null) {
|
||||
String authToken = userColonPassword.bytes.encodeBase64().toString()
|
||||
executeAbapEnvironmentPullGitRepo(configuration, urlString, authToken)
|
||||
} else {
|
||||
error "[${STEP_NAME}] Error: Necessary parameters not available"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String triggerPull(Map configuration, String url, String authToken, HeaderFiles headerFiles) {
|
||||
private String getServiceKey(Map configuration) {
|
||||
|
||||
String responseFile = "response-${UUID.randomUUID().toString()}.txt"
|
||||
withCredentials([
|
||||
usernamePassword(credentialsId: configuration.cloudFoundry.credentialsId, passwordVariable: 'CF_PASSWORD', usernameVariable: 'CF_USERNAME')
|
||||
]) {
|
||||
bashScript =
|
||||
"""#!/bin/bash
|
||||
set +x
|
||||
set -e
|
||||
export HOME=${configuration.dockerWorkspace}
|
||||
cf login -u ${BashUtils.quoteAndEscape(CF_USERNAME)} -p ${BashUtils.quoteAndEscape(CF_PASSWORD)} -a ${configuration.cloudFoundry.apiEndpoint} -o ${BashUtils.quoteAndEscape(configuration.cloudFoundry.org)} -s ${BashUtils.quoteAndEscape(configuration.cloudFoundry.space)};
|
||||
cf service-key ${BashUtils.quoteAndEscape(configuration.cloudFoundry.serviceInstance)} ${BashUtils.quoteAndEscape(configuration.cloudFoundry.serviceKey)} > \"${responseFile}\"
|
||||
"""
|
||||
String responseString
|
||||
try {
|
||||
def status = sh returnStatus: true, script: bashScript
|
||||
if (status != 0) {
|
||||
echo "[${STEP_NAME}] Info: Could not get the service key $configuration.cloudFoundry.serviceKey for service instance $configuration.cloudFoundry.serviceInstance"
|
||||
}
|
||||
responseString = readFile(responseFile)
|
||||
} finally {
|
||||
sh "cf logout"
|
||||
sh script : """#!/bin/bash
|
||||
rm -f ${responseFile}
|
||||
"""
|
||||
}
|
||||
def p = Pattern.compile(/\{.*\}$/, Pattern.MULTILINE | Pattern.DOTALL)
|
||||
def m = responseString =~ p
|
||||
String jsonString
|
||||
if (m.find()) {
|
||||
return m[0]
|
||||
} else {
|
||||
echo "[${STEP_NAME}] Info: Could not parse the service key $configuration.cloudFoundry.serviceKey"
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private executeAbapEnvironmentPullGitRepo(Map configuration, String urlString, String authToken) {
|
||||
echo "[${STEP_NAME}] General Parameters: URL = \"${urlString}\", repositoryName = \"${configuration.repositoryName}\""
|
||||
HeaderFiles headerFiles = new HeaderFiles()
|
||||
try {
|
||||
String urlPullEntity = triggerPull(configuration, urlString, authToken, headerFiles)
|
||||
if (urlPullEntity != null) {
|
||||
String finalStatus = pollPullStatus(urlPullEntity, authToken, headerFiles)
|
||||
if (finalStatus != 'S') {
|
||||
error "[${STEP_NAME}] Pull Failed"
|
||||
}
|
||||
} else {
|
||||
error "[${STEP_NAME}] Pull Failed"
|
||||
}
|
||||
} finally {
|
||||
workspaceCleanup(headerFiles)
|
||||
}
|
||||
}
|
||||
|
||||
private String triggerPull(Map configuration, String url, String authToken, HeaderFiles headerFiles) {
|
||||
String entityUri = null
|
||||
|
||||
def xCsrfTokenScript = """#!/bin/bash
|
||||
@ -126,11 +209,9 @@ private String triggerPull(Map configuration, String url, String authToken, Head
|
||||
|
||||
echo "[${STEP_NAME}] Entity URI: ${entityUri}"
|
||||
return entityUri
|
||||
|
||||
}
|
||||
|
||||
private String pollPullStatus(String url, String authToken, HeaderFiles headerFiles) {
|
||||
|
||||
String status = "R";
|
||||
while(status == "R") {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user