@@ -34,31 +34,32 @@ import (
3434)
3535
3636const (
37- extDescriptorsOpt = "e"
38- timeoutOpt = "t"
39- versionRuleOpt = "version-rule"
40- noStartOpt = "no-start"
41- deleteServiceKeysOpt = "delete-service-keys"
42- keepFilesOpt = "keep-files"
43- skipOwnershipValidationOpt = "skip-ownership-validation"
44- moduleOpt = "m"
45- resourceOpt = "r"
46- allModulesOpt = "all-modules"
47- allResourcesOpt = "all-resources"
48- strategyOpt = "strategy"
49- skipTestingPhase = "skip-testing-phase"
50- skipIdleStart = "skip-idle-start"
51- startTimeoutOpt = "apps-start-timeout"
52- stageTimeoutOpt = "apps-stage-timeout"
53- uploadTimeoutOpt = "apps-upload-timeout"
54- taskExecutionTimeoutOpt = "apps-task-execution-timeout"
55- applyNamespaceAppNamesOpt = "apply-namespace-app-names"
56- applyNamespaceServiceNamesOpt = "apply-namespace-service-names"
57- applyNamespaceAppRoutesOpt = "apply-namespace-app-routes"
58- applyNamespaceAsSuffix = "apply-namespace-as-suffix"
59- maxNamespaceSize = 36
60- shouldBackupPreviousVersionOpt = "backup-previous-version"
61- requireSecureParameters = "require-secure-parameters"
37+ extDescriptorsOpt = "e"
38+ timeoutOpt = "t"
39+ versionRuleOpt = "version-rule"
40+ noStartOpt = "no-start"
41+ deleteServiceKeysOpt = "delete-service-keys"
42+ keepFilesOpt = "keep-files"
43+ skipOwnershipValidationOpt = "skip-ownership-validation"
44+ moduleOpt = "m"
45+ resourceOpt = "r"
46+ allModulesOpt = "all-modules"
47+ allResourcesOpt = "all-resources"
48+ strategyOpt = "strategy"
49+ skipTestingPhase = "skip-testing-phase"
50+ skipIdleStart = "skip-idle-start"
51+ startTimeoutOpt = "apps-start-timeout"
52+ stageTimeoutOpt = "apps-stage-timeout"
53+ uploadTimeoutOpt = "apps-upload-timeout"
54+ taskExecutionTimeoutOpt = "apps-task-execution-timeout"
55+ applyNamespaceAppNamesOpt = "apply-namespace-app-names"
56+ applyNamespaceServiceNamesOpt = "apply-namespace-service-names"
57+ applyNamespaceAppRoutesOpt = "apply-namespace-app-routes"
58+ applyNamespaceAsSuffix = "apply-namespace-as-suffix"
59+ maxNamespaceSize = 36
60+ shouldBackupPreviousVersionOpt = "backup-previous-version"
61+ requireSecureParameters = "require-secure-parameters"
62+ disposableUserProvidedServiceOpt = "disposable-user-provided-service"
6263)
6364
6465type listFlag struct {
@@ -118,13 +119,13 @@ func (c *DeployCommand) GetPluginCommand() plugin.Command {
118119 UsageDetails : plugin.Usage {
119120 Usage : `Deploy a multi-target app archive
120121
121- cf deploy MTA [-e EXT_DESCRIPTOR[,...]] [-t TIMEOUT] [--version-rule VERSION_RULE] [-u URL] [-f] [--retries RETRIES] [--no-start] [--namespace NAMESPACE] [--apply-namespace-app-names true/false] [--apply-namespace-service-names true/false] [--apply-namespace-app-routes true/false] [--apply-namespace-as-suffix true/false ] [--delete-services] [--delete-service-keys] [--delete-service-brokers] [--keep-files] [--no-restart-subscribed-apps] [--do-not-fail-on-missing-permissions] [--abort-on-error] [--strategy STRATEGY] [--skip-testing-phase] [--skip-idle-start] [--require-secure-parameters] [--apps-start-timeout TIMEOUT] [--apps-stage-timeout TIMEOUT] [--apps-upload-timeout TIMEOUT] [--apps-task-execution-timeout TIMEOUT]
122+ cf deploy MTA [-e EXT_DESCRIPTOR[,...]] [-t TIMEOUT] [--version-rule VERSION_RULE] [-u URL] [-f] [--retries RETRIES] [--no-start] [--namespace NAMESPACE] [--apply-namespace-app-names true/false] [--apply-namespace-service-names true/false] [--apply-namespace-app-routes true/false] [--apply-namespace-as-suffix true/false ] [--delete-services] [--delete-service-keys] [--delete-service-brokers] [--keep-files] [--no-restart-subscribed-apps] [--do-not-fail-on-missing-permissions] [--abort-on-error] [--strategy STRATEGY] [--skip-testing-phase] [--skip-idle-start] [--require-secure-parameters] [--disposable-user-provided-service] [-- apps-start-timeout TIMEOUT] [--apps-stage-timeout TIMEOUT] [--apps-upload-timeout TIMEOUT] [--apps-task-execution-timeout TIMEOUT]
122123
123124 Perform action on an active deploy operation
124125 cf deploy -i OPERATION_ID -a ACTION [-u URL]
125126
126127 Deploy a multi-target app archive referenced by a remote URL
127- <write MTA archive URL to STDOUT> | cf deploy [-e EXT_DESCRIPTOR[,...]] [-t TIMEOUT] [--version-rule VERSION_RULE] [-u MTA_CONTROLLER_URL] [--retries RETRIES] [--no-start] [--namespace NAMESPACE] [--apply-namespace-app-names true/false] [--apply-namespace-service-names true/false] [--apply-namespace-app-routes true/false] [--apply-namespace-as-suffix true/false ] [--delete-services] [--delete-service-keys] [--delete-service-brokers] [--keep-files] [--no-restart-subscribed-apps] [--do-not-fail-on-missing-permissions] [--abort-on-error] [--strategy STRATEGY] [--skip-testing-phase] [--skip-idle-start] [require-secure-parameters] [--apps-start-timeout TIMEOUT] [--apps-stage-timeout TIMEOUT] [--apps-upload-timeout TIMEOUT] [--apps-task-execution-timeout TIMEOUT]` + util .UploadEnvHelpText ,
128+ <write MTA archive URL to STDOUT> | cf deploy [-e EXT_DESCRIPTOR[,...]] [-t TIMEOUT] [--version-rule VERSION_RULE] [-u MTA_CONTROLLER_URL] [--retries RETRIES] [--no-start] [--namespace NAMESPACE] [--apply-namespace-app-names true/false] [--apply-namespace-service-names true/false] [--apply-namespace-app-routes true/false] [--apply-namespace-as-suffix true/false ] [--delete-services] [--delete-service-keys] [--delete-service-brokers] [--keep-files] [--no-restart-subscribed-apps] [--do-not-fail-on-missing-permissions] [--abort-on-error] [--strategy STRATEGY] [--skip-testing-phase] [--skip-idle-start] [require-secure-parameters] [--disposable-user-provided-service] [-- apps-start-timeout TIMEOUT] [--apps-stage-timeout TIMEOUT] [--apps-upload-timeout TIMEOUT] [--apps-task-execution-timeout TIMEOUT]` + util .UploadEnvHelpText ,
128129
129130 Options : map [string ]string {
130131 extDescriptorsOpt : "Extension descriptors" ,
@@ -161,6 +162,7 @@ func (c *DeployCommand) GetPluginCommand() plugin.Command {
161162 util .GetShortOption (shouldBackupPreviousVersionOpt ): "(EXPERIMENTAL) (STRATEGY: BLUE-GREEN, INCREMENTAL-BLUE-GREEN) Backup previous version of applications, use new cli command \" rollback-mta\" to rollback to the previous version" ,
162163 util .GetShortOption (dependencyAwareStopOrderOpt ): "(EXPERIMENTAL) (STRATEGY: BLUE-GREEN, INCREMENTAL-BLUE-GREEN) Stop apps in a dependency-aware order during the resume phase of a blue-green deployment" ,
163164 util .GetShortOption (requireSecureParameters ): "(EXPERIMENTAL) Pass secrets to the deploy service in a secure way" ,
165+ util .GetShortOption (disposableUserProvidedServiceOpt ): "Deploy when --require-secure-parameters flag is active for disposable UPS to be created and then deleted at the of the operation" ,
164166 },
165167 },
166168 }
@@ -187,6 +189,7 @@ func deployProcessParametersSetter() ProcessParametersSetter {
187189 processBuilder .Parameter ("appsUploadTimeout" , GetStringOpt (uploadTimeoutOpt , flags ))
188190 processBuilder .Parameter ("appsTaskExecutionTimeout" , GetStringOpt (taskExecutionTimeoutOpt , flags ))
189191 processBuilder .Parameter ("isSecurityEnabled" , strconv .FormatBool (GetBoolOpt (requireSecureParameters , flags )))
192+ processBuilder .Parameter ("isDisposableUserProvidedServiceEnabled" , strconv .FormatBool (GetBoolOpt (disposableUserProvidedServiceOpt , flags )))
190193
191194 var lastSetValue string = ""
192195 for i := 0 ; i < len (os .Args ); i ++ {
@@ -243,6 +246,7 @@ func (c *DeployCommand) defineCommandOptions(flags *flag.FlagSet) {
243246 flags .Bool (shouldBackupPreviousVersionOpt , false , "" )
244247 flags .Bool (dependencyAwareStopOrderOpt , false , "" )
245248 flags .Bool (requireSecureParameters , false , "" )
249+ flags .Bool (disposableUserProvidedServiceOpt , false , "" )
246250}
247251
248252func (c * DeployCommand ) executeInternal (positionalArgs []string , dsHost string , flags * flag.FlagSet , cfTarget util.CloudFoundryTarget ) ExecutionStatus {
@@ -277,6 +281,7 @@ func (c *DeployCommand) executeInternal(positionalArgs []string, dsHost string,
277281 var uploadedArchivePartIds []string
278282 var uploadStatus ExecutionStatus
279283 var mtaId string
284+ var disposableUserProvidedServiceName string
280285
281286 // Check SLMP metadata
282287 // TODO: ensure session
@@ -353,18 +358,36 @@ func (c *DeployCommand) executeInternal(positionalArgs []string, dsHost string,
353358 return Failure
354359 }
355360
356- userProvidedServiceName := getUpsName (mtaId , namespace )
361+ if GetBoolOpt (disposableUserProvidedServiceOpt , flags ) {
362+ disposableUserProvidedServiceName , err = getRandomisedUpsName (mtaId , namespace )
363+ if err != nil {
364+ ui .Failed ("Failed to create disposable user-provided service name: %v" , err )
365+ return Failure
366+ }
357367
358- isUpsCreated , _ , err := c .validateUpsExistsOrElseCreateIt ( userProvidedServiceName , "v1" )
359- if err != nil {
360- ui .Failed ("Could not ensure user-provided service %s: %v" , userProvidedServiceName , err )
361- return Failure
362- }
368+ isDisposableUpsCreated , _ , err := c .createDisposableUps ( disposableUserProvidedServiceName )
369+ if err != nil {
370+ ui .Failed ("Could not ensure disposable user-provided service %s: %v" , disposableUserProvidedServiceName , err )
371+ return Failure
372+ }
363373
364- if isUpsCreated {
365- ui .Say ("Created user-provided service %s for secure parameters." , terminal .EntityNameColor (userProvidedServiceName ))
374+ if isDisposableUpsCreated {
375+ ui .Say ("Created disposable user-provided service %s for secure parameters. Will be automatically deleted at the end of the operation!" , terminal .EntityNameColor (disposableUserProvidedServiceName ))
376+ }
366377 } else {
367- ui .Say ("Using existing user-provided service %s for secure parameters." , terminal .EntityNameColor (userProvidedServiceName ))
378+ userProvidedServiceName := getUpsName (mtaId , namespace )
379+
380+ isUpsCreated , _ , err := c .validateUpsExistsOrElseCreateIt (userProvidedServiceName )
381+ if err != nil {
382+ ui .Failed ("Could not ensure user-provided service %s: %v" , userProvidedServiceName , err )
383+ return Failure
384+ }
385+
386+ if isUpsCreated {
387+ ui .Say ("Created user-provided service %s for secure parameters." , terminal .EntityNameColor (userProvidedServiceName ))
388+ } else {
389+ ui .Say ("Using existing user-provided service %s for secure parameters." , terminal .EntityNameColor (userProvidedServiceName ))
390+ }
368391 }
369392
370393 schemaVer := descriptor .SchemaVersion
@@ -422,6 +445,7 @@ func (c *DeployCommand) executeInternal(positionalArgs []string, dsHost string,
422445 processBuilder .Parameter ("appArchiveId" , strings .Join (uploadedArchivePartIds , "," ))
423446 processBuilder .Parameter ("mtaExtDescriptorId" , strings .Join (uploadedExtDescriptorIDs , "," ))
424447 processBuilder .Parameter ("mtaId" , mtaId )
448+ processBuilder .Parameter ("disposableUserProvidedServiceName" , disposableUserProvidedServiceName )
425449 setModulesAndResourcesListParameters (modulesList , resourcesList , processBuilder , mtaElementsCalculator )
426450 c .setProcessParameters (flags , processBuilder )
427451
@@ -437,18 +461,32 @@ func (c *DeployCommand) executeInternal(positionalArgs []string, dsHost string,
437461 return executionMonitor .Monitor ()
438462}
439463
440- func getUpsName (mtaID , namespace string ) string {
464+ func getUpsName (mtaId , namespace string ) string {
441465 if strings .TrimSpace (namespace ) == "" {
442- return "__mta-secure-" + mtaID
466+ return "__mta-secure-" + mtaId
443467 }
444- return "__mta-secure-" + mtaID + "-" + namespace
468+ return "__mta-secure-" + mtaId + "-" + namespace
445469}
446470
447- func (c * DeployCommand ) validateUpsExistsOrElseCreateIt (userProvidedServiceName , keyID string ) (upsCreatedByTheCli bool , encryptionKeyResult string , err error ) {
471+ func getRandomisedUpsName (mtaId , namespace string ) (disposableUpsName string , err error ) {
472+ randomisedPart , err := getRandomEncryptionKey ()
473+ if err != nil {
474+ return "" , err
475+ }
476+ resultSuffix := randomisedPart [:7 ]
477+
478+ if strings .TrimSpace (namespace ) == "" {
479+ return "__mta-secure-" + mtaId + "-" + resultSuffix , nil
480+ }
481+ return "__mta-secure-" + mtaId + "-" + namespace + "-" + resultSuffix , nil
482+ }
483+
484+ func (c * DeployCommand ) validateUpsExistsOrElseCreateIt (userProvidedServiceName string ) (upsCreatedByTheCli bool , encryptionKeyResult string , err error ) {
448485 doesUpsExist , err := c .doesUpsExist (userProvidedServiceName )
449486 if err != nil {
450487 return false , "" , fmt .Errorf ("Check if the UPS exists: %w" , err )
451488 }
489+
452490 if doesUpsExist {
453491 return false , "" , nil
454492 }
@@ -460,7 +498,27 @@ func (c *DeployCommand) validateUpsExistsOrElseCreateIt(userProvidedServiceName,
460498
461499 upsCredentials := map [string ]string {
462500 "encryptionKey" : encryptionKey ,
463- "keyId" : keyID ,
501+ }
502+
503+ jsonBody , err := json .Marshal (upsCredentials )
504+ if err != nil {
505+ return false , "" , fmt .Errorf ("Error while creating JSON credentials for UPS service: %w" , err )
506+ }
507+
508+ if _ , err := c .cliConnection .CliCommand ("create-user-provided-service" , userProvidedServiceName , "-p" , string (jsonBody )); err != nil {
509+ return false , "" , fmt .Errorf ("Command cf cups %s has failed: %w" , userProvidedServiceName , err )
510+ }
511+ return true , encryptionKey , nil
512+ }
513+
514+ func (c * DeployCommand ) createDisposableUps (userProvidedServiceName string ) (upsCreatedByTheCli bool , encryptionKeyResult string , err error ) {
515+ encryptionKey , err := getRandomEncryptionKey ()
516+ if err != nil {
517+ return false , "" , fmt .Errorf ("Error while generating AES-256 encryption key: %w" , err )
518+ }
519+
520+ upsCredentials := map [string ]string {
521+ "encryptionKey" : encryptionKey ,
464522 }
465523 jsonBody , _ := json .Marshal (upsCredentials )
466524
0 commit comments