Skip to content

Commit 8922dd2

Browse files
committed
Fixing comments and adding new disposable UPS functionality
LMCROSSITXSADEPLOY-2301
1 parent 1b06284 commit 8922dd2

2 files changed

Lines changed: 100 additions & 42 deletions

File tree

commands/deploy_command.go

Lines changed: 99 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -34,31 +34,32 @@ import (
3434
)
3535

3636
const (
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

6465
type 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

248252
func (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

secure_parameters/secure_parameters_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func TestCollectFromEnvWhenInvalidJson(t *testing.T) {
9090
}
9191
}
9292

93-
func TestCollectFromEnvWhenDuplciateNames(t *testing.T) {
93+
func TestCollectFromEnvWhenDuplicateNames(t *testing.T) {
9494
setEnv(t, "__MTA_JSON___duplicate", `{"fakeValueName":"value"}`)
9595
setEnv(t, "__MTA___duplicate", "randomValue")
9696

0 commit comments

Comments
 (0)