From ca0cc107febe79689537e520b140a10ff7151dcd Mon Sep 17 00:00:00 2001 From: vkalapov <87693906+vkalapov@users.noreply.github.com> Date: Fri, 17 Apr 2026 17:20:08 +0300 Subject: [PATCH] Add service parameter timeouts --- commands/blue_green_deploy_command.go | 5 +++- commands/deploy_command.go | 18 ++++++++++--- commands/deploy_command_test.go | 39 +++++++++++++++++++++++++++ commands/rollback_mta_command.go | 11 +++++++- 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/commands/blue_green_deploy_command.go b/commands/blue_green_deploy_command.go index a40b0d9..c26e7ef 100644 --- a/commands/blue_green_deploy_command.go +++ b/commands/blue_green_deploy_command.go @@ -33,7 +33,7 @@ func (c *BlueGreenDeployCommand) GetPluginCommand() plugin.Command { HelpText: "Deploy a multi-target app using blue-green deployment", UsageDetails: plugin.Usage{ Usage: `Deploy a multi-target app using blue-green deployment - cf bg-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] [--no-confirm] [--skip-idle-start] [--do-not-fail-on-missing-permissions] [--abort-on-error] [--apps-start-timeout TIMEOUT] [--apps-stage-timeout TIMEOUT] [--apps-upload-timeout TIMEOUT] [--apps-task-execution-timeout TIMEOUT] + cf bg-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] [--no-confirm] [--skip-idle-start] [--do-not-fail-on-missing-permissions] [--abort-on-error] [--apps-start-timeout TIMEOUT] [--apps-stage-timeout TIMEOUT] [--apps-upload-timeout TIMEOUT] [--apps-task-execution-timeout TIMEOUT] [--services-create-service-timeout TIMEOUT] [--services-bind-service-timeout TIMEOUT] [--services-create-service-key-timeout TIMEOUT] Perform action on an active deploy operation cf deploy -i OPERATION_ID -a ACTION [-u URL] ` + util.UploadEnvHelpText, @@ -63,6 +63,9 @@ func (c *BlueGreenDeployCommand) GetPluginCommand() plugin.Command { util.GetShortOption(stageTimeoutOpt): "Stage app timeout in seconds", util.GetShortOption(uploadTimeoutOpt): "Upload app timeout in seconds", util.GetShortOption(taskExecutionTimeoutOpt): "Task execution timeout in seconds", + util.GetShortOption(servicesCreateServiceTimeoutOpt): "Create service timeout in seconds", + util.GetShortOption(servicesBindServiceTimeoutOpt): "Bind service timeout in seconds", + util.GetShortOption(servicesCreateServiceKeyTimeoutOpt): "Create service key timeout in seconds", util.CombineFullAndShortParameters(startTimeoutOpt, timeoutOpt): "Start app timeout in seconds", util.GetShortOption(shouldBackupPreviousVersionOpt): "(EXPERIMENTAL) Backup previous version of applications, use new cli command \"rollback-mta\" to rollback to the previous version", }, diff --git a/commands/deploy_command.go b/commands/deploy_command.go index 0baf06b..d4c572e 100644 --- a/commands/deploy_command.go +++ b/commands/deploy_command.go @@ -50,6 +50,9 @@ const ( stageTimeoutOpt = "apps-stage-timeout" uploadTimeoutOpt = "apps-upload-timeout" taskExecutionTimeoutOpt = "apps-task-execution-timeout" + servicesCreateServiceTimeoutOpt = "services-create-service-timeout" + servicesBindServiceTimeoutOpt = "services-bind-service-timeout" + servicesCreateServiceKeyTimeoutOpt = "services-create-service-key-timeout" applyNamespaceAppNamesOpt = "apply-namespace-app-names" applyNamespaceServiceNamesOpt = "apply-namespace-service-names" applyNamespaceAppRoutesOpt = "apply-namespace-app-routes" @@ -117,13 +120,13 @@ func (c *DeployCommand) GetPluginCommand() plugin.Command { UsageDetails: plugin.Usage{ Usage: `Deploy a multi-target app archive - 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] + 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] [--services-create-service-timeout TIMEOUT] [--services-bind-service-timeout TIMEOUT] [--services-create-service-key-timeout TIMEOUT] Perform action on an active deploy operation cf deploy -i OPERATION_ID -a ACTION [-u URL] Deploy a multi-target app archive referenced by a remote URL - | 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, + | 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] [--services-create-service-timeout TIMEOUT] [--services-bind-service-timeout TIMEOUT] [--services-create-service-key-timeout TIMEOUT]` + util.UploadEnvHelpText, Options: map[string]string{ extDescriptorsOpt: "Extension descriptors", @@ -156,6 +159,9 @@ func (c *DeployCommand) GetPluginCommand() plugin.Command { util.GetShortOption(stageTimeoutOpt): "Stage app timeout in seconds", util.GetShortOption(uploadTimeoutOpt): "Upload app timeout in seconds", util.GetShortOption(taskExecutionTimeoutOpt): "Task execution timeout in seconds", + util.GetShortOption(servicesCreateServiceTimeoutOpt): "Create service timeout in seconds", + util.GetShortOption(servicesBindServiceTimeoutOpt): "Bind service timeout in seconds", + util.GetShortOption(servicesCreateServiceKeyTimeoutOpt): "Create service key timeout in seconds", util.CombineFullAndShortParameters(startTimeoutOpt, timeoutOpt): "Start app timeout in seconds", 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", 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", @@ -186,6 +192,9 @@ func deployProcessParametersSetter() ProcessParametersSetter { processBuilder.Parameter("appsStageTimeout", GetStringOpt(stageTimeoutOpt, flags)) processBuilder.Parameter("appsUploadTimeout", GetStringOpt(uploadTimeoutOpt, flags)) processBuilder.Parameter("appsTaskExecutionTimeout", GetStringOpt(taskExecutionTimeoutOpt, flags)) + processBuilder.Parameter("servicesCreateServiceTimeout", GetStringOpt(servicesCreateServiceTimeoutOpt, flags)) + processBuilder.Parameter("servicesBindServiceTimeout", GetStringOpt(servicesBindServiceTimeoutOpt, flags)) + processBuilder.Parameter("servicesCreateServiceKeyTimeout", GetStringOpt(servicesCreateServiceKeyTimeoutOpt, flags)) processBuilder.Parameter("isSecurityEnabled", strconv.FormatBool(GetBoolOpt(requireSecureParameters, flags))) processBuilder.Parameter("isDisposableUserProvidedServiceEnabled", strconv.FormatBool(GetBoolOpt(disposableUserProvidedServiceOpt, flags))) @@ -241,6 +250,9 @@ func (c *DeployCommand) defineCommandOptions(flags *flag.FlagSet) { flags.String(stageTimeoutOpt, "", "") flags.String(uploadTimeoutOpt, "", "") flags.String(taskExecutionTimeoutOpt, "", "") + flags.String(servicesCreateServiceTimeoutOpt, "", "") + flags.String(servicesBindServiceTimeoutOpt, "", "") + flags.String(servicesCreateServiceKeyTimeoutOpt, "", "") flags.Bool(shouldBackupPreviousVersionOpt, false, "") flags.Bool(dependencyAwareStopOrderOpt, false, "") flags.Bool(requireSecureParameters, false, "") @@ -791,7 +803,7 @@ func (deployCommandFlagsValidator) ValidateParsedFlags(flags *flag.FlagSet) erro err = fmt.Errorf("Invalid value for namespace. The namespace cannot be more than %d symbols.", maxNamespaceSize) return } - case timeoutOpt, startTimeoutOpt, stageTimeoutOpt, uploadTimeoutOpt, taskExecutionTimeoutOpt: + case timeoutOpt, startTimeoutOpt, stageTimeoutOpt, uploadTimeoutOpt, taskExecutionTimeoutOpt, servicesCreateServiceTimeoutOpt, servicesBindServiceTimeoutOpt, servicesCreateServiceKeyTimeoutOpt: if e := ValidateTimeoutOption(f.Name, flags, 259200); e != nil { err = e return diff --git a/commands/deploy_command_test.go b/commands/deploy_command_test.go index a3888f6..6c1ea40 100644 --- a/commands/deploy_command_test.go +++ b/commands/deploy_command_test.go @@ -359,6 +359,45 @@ var _ = Describe("DeployCommand", func() { }) }) + // service timeout flags with invalid values - error + Context("with an invalid services-create-service-timeout value", func() { + It("should print incorrect usage and exit with a non-zero status", func() { + output, status := oc.CaptureOutputAndStatus(func() int { + return command.Execute([]string{mtaArchivePath, "--services-create-service-timeout", "abc"}).ToInt() + }) + ex.ExpectFailure(status, output, "Invalid value for services-create-service-timeout: abc") + }) + }) + + Context("with an invalid services-bind-service-timeout value", func() { + It("should print incorrect usage and exit with a non-zero status", func() { + output, status := oc.CaptureOutputAndStatus(func() int { + return command.Execute([]string{mtaArchivePath, "--services-bind-service-timeout", "-1"}).ToInt() + }) + ex.ExpectFailure(status, output, "Invalid value for services-bind-service-timeout: -1") + }) + }) + + Context("with an invalid services-create-service-key-timeout value", func() { + It("should print incorrect usage and exit with a non-zero status", func() { + output, status := oc.CaptureOutputAndStatus(func() int { + return command.Execute([]string{mtaArchivePath, "--services-create-service-key-timeout", "999999999"}).ToInt() + }) + ex.ExpectFailure(status, output, "Invalid value for services-create-service-key-timeout: 999999999") + }) + }) + + // service timeout flags with valid values should be accepted as known flags + Context("with unknown flags and a valid services-create-service-timeout flag", func() { + It("should report only the unknown flags", func() { + output, status := oc.CaptureOutputAndStatus(func() int { + return command.Execute([]string{mtaArchivePath, "--nonValidFlag", "--services-create-service-timeout", "500", "-notAValidOne"}).ToInt() + }) + ex.ExpectFailure(status, output, "Incorrect usage. Unknown or wrong flags: --nonValidFlag, -notAValidOne") + Expect(cliConnection.CliCommandArgsForCall(0)).To(Equal([]string{"help", name})) + }) + }) + // strategy flag set to invalid deployment strategy - error Context("with strategy flag set to an invalid deployment strategy", func() { It("should print the available strategies and exit with a non-zero status", func() { diff --git a/commands/rollback_mta_command.go b/commands/rollback_mta_command.go index 3ec365c..77579c2 100644 --- a/commands/rollback_mta_command.go +++ b/commands/rollback_mta_command.go @@ -36,7 +36,7 @@ func (c *RollbackMtaCommand) GetPluginCommand() plugin.Command { HelpText: "(EXPERIMENTAL) Rollback of a multi-target app works only if [--backup-previous-version] flag was used during blue-green deployment and backup applications exists in the space", UsageDetails: plugin.Usage{ Usage: `Rollback of a multi-target app - cf rollback-mta MTA_ID [-t TIMEOUT] [-f] [--retries RETRIES] [--namespace NAMESPACE] [--do-not-fail-on-missing-permissions] [--abort-on-error] [--apps-start-timeout TIMEOUT] [--apps-stage-timeout TIMEOUT] [--apps-upload-timeout TIMEOUT] [--apps-task-execution-timeout TIMEOUT] + cf rollback-mta MTA_ID [-t TIMEOUT] [-f] [--retries RETRIES] [--namespace NAMESPACE] [--do-not-fail-on-missing-permissions] [--abort-on-error] [--apps-start-timeout TIMEOUT] [--apps-stage-timeout TIMEOUT] [--apps-upload-timeout TIMEOUT] [--apps-task-execution-timeout TIMEOUT] [--services-create-service-timeout TIMEOUT] [--services-bind-service-timeout TIMEOUT] [--services-create-service-key-timeout TIMEOUT] Perform action on an active deploy operation cf rollback-mta -i OPERATION_ID -a ACTION [-u URL]` + util.BaseEnvHelpText, @@ -54,6 +54,9 @@ func (c *RollbackMtaCommand) GetPluginCommand() plugin.Command { util.GetShortOption(stageTimeoutOpt): "Stage app timeout in seconds", util.GetShortOption(uploadTimeoutOpt): "Upload app timeout in seconds", util.GetShortOption(taskExecutionTimeoutOpt): "Task execution timeout in seconds", + util.GetShortOption(servicesCreateServiceTimeoutOpt): "Create service timeout in seconds", + util.GetShortOption(servicesBindServiceTimeoutOpt): "Bind service timeout in seconds", + util.GetShortOption(servicesCreateServiceKeyTimeoutOpt): "Create service key timeout in seconds", util.CombineFullAndShortParameters(startTimeoutOpt, timeoutOpt): "Start app timeout in seconds", }, }, @@ -74,6 +77,9 @@ func (c *RollbackMtaCommand) defineCommandOptions(flags *flag.FlagSet) { flags.String(stageTimeoutOpt, "", "") flags.String(uploadTimeoutOpt, "", "") flags.String(taskExecutionTimeoutOpt, "", "") + flags.String(servicesCreateServiceTimeoutOpt, "", "") + flags.String(servicesBindServiceTimeoutOpt, "", "") + flags.String(servicesCreateServiceKeyTimeoutOpt, "", "") } func (c *RollbackMtaCommand) executeInternal(positionalArgs []string, dsHost string, flags *flag.FlagSet, cfTarget util.CloudFoundryTarget) ExecutionStatus { @@ -143,6 +149,9 @@ func (c *RollbackMtaCommand) executeInternal(positionalArgs []string, dsHost str processBuilder.Parameter("appsStageTimeout", GetStringOpt(stageTimeoutOpt, flags)) processBuilder.Parameter("appsUploadTimeout", GetStringOpt(uploadTimeoutOpt, flags)) processBuilder.Parameter("appsTaskExecutionTimeout", GetStringOpt(taskExecutionTimeoutOpt, flags)) + processBuilder.Parameter("servicesCreateServiceTimeout", GetStringOpt(servicesCreateServiceTimeoutOpt, flags)) + processBuilder.Parameter("servicesBindServiceTimeout", GetStringOpt(servicesBindServiceTimeoutOpt, flags)) + processBuilder.Parameter("servicesCreateServiceKeyTimeout", GetStringOpt(servicesCreateServiceKeyTimeoutOpt, flags)) operation := processBuilder.Build() // Create the new process