2019-03-12 16:48:35 +02:00
|
|
|
import com.sap.piper.GenerateDocumentation
|
|
|
|
import com.sap.piper.CloudPlatform
|
|
|
|
import com.sap.piper.DeploymentType
|
|
|
|
import com.sap.piper.ConfigurationHelper
|
|
|
|
import com.sap.piper.Utils
|
|
|
|
import com.sap.piper.JenkinsUtils
|
2020-07-01 17:28:50 +02:00
|
|
|
import com.sap.piper.k8s.ContainerMap
|
2019-03-12 16:48:35 +02:00
|
|
|
|
|
|
|
import groovy.transform.Field
|
|
|
|
|
|
|
|
import static com.sap.piper.Prerequisites.checkScript
|
|
|
|
|
|
|
|
@Field String STEP_NAME = getClass().getName()
|
|
|
|
|
|
|
|
@Field Set GENERAL_CONFIG_KEYS = [
|
2020-07-01 17:28:50 +02:00
|
|
|
/** Defines the targets to deploy on Cloud Foundry.*/
|
2019-03-12 16:48:35 +02:00
|
|
|
'cfTargets',
|
|
|
|
/** Defines the targets to deploy on neo.*/
|
2020-07-01 17:28:50 +02:00
|
|
|
'neoTargets',
|
|
|
|
/** Executes the deployments in parallel.*/
|
|
|
|
'parallelExecution'
|
2019-03-12 16:48:35 +02:00
|
|
|
]
|
|
|
|
|
2020-07-01 17:28:50 +02:00
|
|
|
@Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
|
|
|
|
/**
|
|
|
|
* Defines Cloud Foundry service instances to create as part of the deployment.
|
|
|
|
* This is a _list_ of _objects_ with the following properties each:
|
|
|
|
* - apiEndpoint
|
|
|
|
* - credentialsId
|
|
|
|
* - serviceManifest
|
|
|
|
* - manifestVariablesFiles
|
|
|
|
* - org
|
|
|
|
* - space
|
|
|
|
*/
|
|
|
|
'cfCreateServices'
|
|
|
|
])
|
2019-03-12 16:48:35 +02:00
|
|
|
|
2020-07-01 17:28:50 +02:00
|
|
|
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus([
|
2019-03-12 16:48:35 +02:00
|
|
|
/** Defines the deployment type.*/
|
|
|
|
'enableZeroDowntimeDeployment',
|
2020-06-24 10:56:36 +02:00
|
|
|
/** The source file to deploy to SAP Cloud Platform.*/
|
2019-03-12 16:48:35 +02:00
|
|
|
'source'
|
|
|
|
])
|
|
|
|
|
2020-07-01 17:28:50 +02:00
|
|
|
@Field Map CONFIG_KEY_COMPATIBILITY = [parallelExecution: 'features/parallelTestExecution']
|
|
|
|
|
2019-03-12 16:48:35 +02:00
|
|
|
/**
|
2020-06-24 10:56:36 +02:00
|
|
|
* Deploys an application to multiple platforms (Cloud Foundry, SAP Cloud Platform) or to multiple instances of multiple platforms or the same platform.
|
2019-03-12 16:48:35 +02:00
|
|
|
*/
|
|
|
|
@GenerateDocumentation
|
|
|
|
void call(parameters = [:]) {
|
|
|
|
|
|
|
|
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
|
|
|
|
|
|
|
|
def script = checkScript(this, parameters) ?: this
|
|
|
|
def utils = parameters.utils ?: new Utils()
|
|
|
|
def jenkinsUtils = parameters.jenkinsUtils ?: new JenkinsUtils()
|
2020-07-01 16:08:12 +02:00
|
|
|
def stageName = parameters.stage ?: env.STAGE_NAME
|
2019-03-12 16:48:35 +02:00
|
|
|
|
|
|
|
ConfigurationHelper configHelper = ConfigurationHelper.newInstance(this)
|
|
|
|
.loadStepDefaults()
|
2020-07-01 17:28:50 +02:00
|
|
|
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY)
|
|
|
|
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName?:env.STAGE_NAME, STEP_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY)
|
|
|
|
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY)
|
2019-03-12 16:48:35 +02:00
|
|
|
.mixin(parameters, PARAMETER_KEYS)
|
|
|
|
|
|
|
|
Map config = configHelper.use()
|
|
|
|
|
|
|
|
configHelper
|
|
|
|
.withMandatoryProperty('source', null, { config.neoTargets })
|
|
|
|
|
|
|
|
utils.pushToSWA([
|
2020-07-01 17:28:50 +02:00
|
|
|
step : STEP_NAME,
|
2020-06-24 10:56:36 +02:00
|
|
|
stepParamKey1: 'enableZeroDowntimeDeployment',
|
2020-07-01 17:28:50 +02:00
|
|
|
stepParam1 : config.enableZeroDowntimeDeployment
|
2019-03-12 16:48:35 +02:00
|
|
|
], config)
|
|
|
|
|
|
|
|
def index = 1
|
|
|
|
def deployments = [:]
|
|
|
|
|
2020-07-01 17:28:50 +02:00
|
|
|
if (config.cfCreateServices) {
|
|
|
|
def createServices = [:]
|
|
|
|
for (int i = 0; i < config.cfCreateServices.size(); i++) {
|
|
|
|
Map createServicesConfig = config.cfCreateServices[i]
|
|
|
|
createServices["Service Creation ${i + 1}"] = {
|
|
|
|
cloudFoundryCreateService(
|
|
|
|
script: script,
|
|
|
|
cloudFoundry: [
|
|
|
|
apiEndpoint : createServicesConfig.apiEndpoint,
|
|
|
|
credentialsId : createServicesConfig.credentialsId,
|
|
|
|
serviceManifest : createServicesConfig.serviceManifest,
|
|
|
|
manifestVariablesFiles: createServicesConfig.manifestVariablesFiles,
|
|
|
|
org : createServicesConfig.org,
|
|
|
|
space : createServicesConfig.space
|
|
|
|
]
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
runClosures(config, createServices, "cloudFoundryCreateService")
|
|
|
|
}
|
|
|
|
|
2019-03-12 16:48:35 +02:00
|
|
|
if (config.cfTargets) {
|
|
|
|
|
2020-06-24 10:56:36 +02:00
|
|
|
def deploymentType = DeploymentType.selectFor(CloudPlatform.CLOUD_FOUNDRY, config.enableZeroDowntimeDeployment).toString()
|
|
|
|
def deployTool = script.commonPipelineEnvironment.configuration.isMta ? 'mtaDeployPlugin' : 'cf_native'
|
2019-03-12 16:48:35 +02:00
|
|
|
|
2020-07-01 16:08:12 +02:00
|
|
|
// An isolated workspace is only required when using blue-green deployment with multiple cfTargets,
|
|
|
|
// since the cloudFoundryDeploy step might edit the manifest.yml file in that case.
|
|
|
|
Boolean runInIsolatedWorkspace = config.cfTargets.size() > 1 && deploymentType == "blue-green"
|
|
|
|
|
2019-03-12 16:48:35 +02:00
|
|
|
for (int i = 0; i < config.cfTargets.size(); i++) {
|
|
|
|
|
|
|
|
def target = config.cfTargets[i]
|
|
|
|
|
|
|
|
Closure deployment = {
|
2020-07-01 16:08:12 +02:00
|
|
|
Utils deploymentUtils = new Utils()
|
|
|
|
if (runInIsolatedWorkspace) {
|
|
|
|
deploymentUtils.unstashStageFiles(script, stageName)
|
|
|
|
}
|
2019-03-12 16:48:35 +02:00
|
|
|
|
|
|
|
cloudFoundryDeploy(
|
|
|
|
script: script,
|
|
|
|
juStabUtils: utils,
|
|
|
|
jenkinsUtilsStub: jenkinsUtils,
|
|
|
|
deployType: deploymentType,
|
|
|
|
cloudFoundry: target,
|
|
|
|
mtaPath: script.commonPipelineEnvironment.mtarFilePath,
|
|
|
|
deployTool: deployTool
|
|
|
|
)
|
2020-07-01 16:08:12 +02:00
|
|
|
if (runInIsolatedWorkspace) {
|
|
|
|
deploymentUtils.stashStageFiles(script, stageName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (runInIsolatedWorkspace){
|
|
|
|
deployments["Deployment ${index}"] = {
|
|
|
|
if (env.POD_NAME) {
|
|
|
|
dockerExecuteOnKubernetes(script: script, containerMap: ContainerMap.instance.getMap().get(stageName) ?: [:]) {
|
|
|
|
deployment.call()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
node(env.NODE_NAME) {
|
|
|
|
deployment.call()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
deployments.put("Deployment ${index}", deployment)
|
2019-03-12 16:48:35 +02:00
|
|
|
}
|
|
|
|
index++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config.neoTargets) {
|
|
|
|
|
2020-06-24 10:56:36 +02:00
|
|
|
def deploymentType = DeploymentType.selectFor(CloudPlatform.NEO, config.enableZeroDowntimeDeployment).toString()
|
2019-03-12 16:48:35 +02:00
|
|
|
|
|
|
|
for (int i = 0; i < config.neoTargets.size(); i++) {
|
|
|
|
|
|
|
|
def target = config.neoTargets[i]
|
|
|
|
|
|
|
|
Closure deployment = {
|
|
|
|
|
2020-07-01 17:28:50 +02:00
|
|
|
neoDeploy(
|
2019-03-12 16:48:35 +02:00
|
|
|
script: script,
|
2020-06-24 10:56:36 +02:00
|
|
|
warAction: deploymentType,
|
2019-03-12 16:48:35 +02:00
|
|
|
source: config.source,
|
|
|
|
neo: target
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
2020-06-24 10:56:36 +02:00
|
|
|
deployments.put("Deployment ${index}", deployment)
|
2019-03-12 16:48:35 +02:00
|
|
|
index++
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!config.cfTargets && !config.neoTargets) {
|
|
|
|
error "Deployment skipped because no targets defined!"
|
|
|
|
}
|
|
|
|
|
2020-07-01 17:28:50 +02:00
|
|
|
runClosures(config, deployments, "deployments")
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def runClosures(Map config, Map toRun, String label = "closures") {
|
|
|
|
echo "Executing $label"
|
|
|
|
if (config.parallelExecution) {
|
|
|
|
echo "Executing $label in parallel"
|
|
|
|
parallel toRun
|
|
|
|
} else {
|
|
|
|
echo "Executing $label in sequence"
|
|
|
|
def closuresToRun = toRun.values().asList()
|
|
|
|
for (int i = 0; i < closuresToRun.size(); i++) {
|
|
|
|
(closuresToRun[i] as Closure)()
|
2019-03-12 16:48:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|