github.com/xgoffin/jenkins-library@v1.154.0/vars/multicloudDeploy.groovy (about) 1 import com.sap.piper.GenerateDocumentation 2 import com.sap.piper.CloudPlatform 3 import com.sap.piper.DeploymentType 4 import com.sap.piper.ConfigurationHelper 5 import com.sap.piper.Utils 6 import com.sap.piper.JenkinsUtils 7 import com.sap.piper.k8s.ContainerMap 8 9 import groovy.transform.Field 10 11 import static com.sap.piper.Prerequisites.checkScript 12 13 @Field String STEP_NAME = getClass().getName() 14 15 @Field Set GENERAL_CONFIG_KEYS = [ 16 /** Defines the targets to deploy on Cloud Foundry.*/ 17 'cfTargets', 18 /** Defines the targets to deploy on neo.*/ 19 'neoTargets', 20 /** Executes the deployments in parallel.*/ 21 'parallelExecution' 22 ] 23 24 @Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([ 25 /** 26 * Defines Cloud Foundry service instances to create as part of the deployment. 27 * This is a _list_ of _objects_ with the following properties each: 28 * - apiEndpoint 29 * - credentialsId 30 * - serviceManifest 31 * - manifestVariablesFiles 32 * - org 33 * - space 34 */ 35 'cfCreateServices', 36 /** Defines the deployment type.*/ 37 'enableZeroDowntimeDeployment', 38 ]) 39 40 @Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus([ 41 /** The source file to deploy to SAP Cloud Platform.*/ 42 'source', 43 /** Closure which is executed before calling the deployment steps.*/ 44 'preDeploymentHook' 45 ]) 46 47 @Field Map CONFIG_KEY_COMPATIBILITY = [parallelExecution: 'features/parallelTestExecution'] 48 49 /** 50 * Deploys an application to multiple platforms (Cloud Foundry, SAP Cloud Platform) or to multiple instances of multiple platforms or the same platform. 51 */ 52 @GenerateDocumentation 53 void call(parameters = [:]) { 54 55 handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) { 56 57 def script = checkScript(this, parameters) ?: this 58 def utils = parameters.utils ?: new Utils() 59 def jenkinsUtils = parameters.jenkinsUtils ?: new JenkinsUtils() 60 String stageName = parameters.stage ?: env.STAGE_NAME 61 62 ConfigurationHelper configHelper = ConfigurationHelper.newInstance(this) 63 .loadStepDefaults([:], stageName) 64 .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY) 65 .mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY) 66 .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS, CONFIG_KEY_COMPATIBILITY) 67 .mixin(parameters, PARAMETER_KEYS) 68 69 Map config = configHelper.use() 70 71 utils.pushToSWA([ 72 step : STEP_NAME, 73 stepParamKey1: 'enableZeroDowntimeDeployment', 74 stepParam1 : config.enableZeroDowntimeDeployment 75 ], config) 76 77 def index = 1 78 def deployments = [:] 79 80 if (config.cfCreateServices) { 81 def createServices = [:] 82 for (int i = 0; i < config.cfCreateServices.size(); i++) { 83 Map createServicesConfig = config.cfCreateServices[i] 84 createServices["Service Creation ${i + 1}"] = { 85 cloudFoundryCreateService( 86 script: script, 87 cloudFoundry: [ 88 apiEndpoint : createServicesConfig.apiEndpoint, 89 credentialsId : createServicesConfig.credentialsId, 90 serviceManifest : createServicesConfig.serviceManifest, 91 manifestVariablesFiles: createServicesConfig.manifestVariablesFiles, 92 org : createServicesConfig.org, 93 space : createServicesConfig.space 94 ] 95 ) 96 } 97 } 98 runClosures(script, createServices, config.parallelExecution, "cloudFoundryCreateService") 99 } 100 101 if (config.cfTargets) { 102 103 def deploymentType = DeploymentType.selectFor(CloudPlatform.CLOUD_FOUNDRY, config.enableZeroDowntimeDeployment).toString() 104 105 // An isolated workspace is required when using blue-green deployment with multiple cfTargets, 106 // since the cloudFoundryDeploy step might edit the manifest.yml file in that case. 107 // It is also required in case of parallel execution and use of mtaExtensionCredentials, since the 108 // credentials are inserted in the mtaExtensionDescriptor file. 109 Boolean runInIsolatedWorkspace = config.cfTargets.size() > 1 && (deploymentType == "blue-green" || config.parallelExecution) 110 111 for (int i = 0; i < config.cfTargets.size(); i++) { 112 113 def target = config.cfTargets[i] 114 115 Closure deployment = { 116 Utils deploymentUtils = new Utils() 117 if (runInIsolatedWorkspace) { 118 deploymentUtils.unstashStageFiles(script, stageName) 119 } 120 121 if (config.preDeploymentHook) { 122 config.preDeploymentHook.call() 123 } 124 125 cloudFoundryDeploy( 126 script: script, 127 juStabUtils: utils, 128 jenkinsUtilsStub: jenkinsUtils, 129 deployType: deploymentType, 130 cloudFoundry: target, 131 mtaExtensionDescriptor: target.mtaExtensionDescriptor, 132 mtaExtensionCredentials: target.mtaExtensionCredentials 133 ) 134 if (runInIsolatedWorkspace) { 135 deploymentUtils.stashStageFiles(script, stageName) 136 } 137 } 138 if (runInIsolatedWorkspace){ 139 deployments["Deployment ${index}"] = { 140 if (env.POD_NAME) { 141 dockerExecuteOnKubernetes(script: script, containerMap: ContainerMap.instance.getMap().get(stageName) ?: [:]) { 142 deployment.call() 143 } 144 } else { 145 node(env.NODE_NAME) { 146 deployment.call() 147 } 148 } 149 } 150 } else { 151 deployments.put("Deployment ${index}", deployment) 152 } 153 index++ 154 } 155 } 156 157 if (config.neoTargets) { 158 159 def deploymentType = DeploymentType.selectFor(CloudPlatform.NEO, config.enableZeroDowntimeDeployment).toString() 160 161 for (int i = 0; i < config.neoTargets.size(); i++) { 162 163 def target = config.neoTargets[i] 164 165 Closure deployment = { 166 if (config.preDeploymentHook) { 167 config.preDeploymentHook.call() 168 } 169 170 neoDeploy( 171 script: script, 172 warAction: deploymentType, 173 source: config.source, 174 neo: target 175 ) 176 177 } 178 deployments.put("Deployment ${index}", deployment) 179 index++ 180 } 181 } 182 183 if (!config.cfTargets && !config.neoTargets) { 184 error "Deployment skipped because no targets defined!" 185 } 186 187 runClosures(script, deployments, config.parallelExecution, "deployments") 188 } 189 }