diff --git a/commands/base_command.go b/commands/base_command.go index b810b7e..0797b6e 100644 --- a/commands/base_command.go +++ b/commands/base_command.go @@ -36,6 +36,7 @@ const ( noRestartSubscribedAppsOpt = "no-restart-subscribed-apps" noFailOnMissingPermissionsOpt = "do-not-fail-on-missing-permissions" abortOnErrorOpt = "abort-on-error" + dependencyAwareStopOrderOpt = "dependency-aware-stop-order" retriesOpt = "retries" namespaceOpt = "namespace" ) diff --git a/commands/deploy_command.go b/commands/deploy_command.go index e54344f..1195c57 100644 --- a/commands/deploy_command.go +++ b/commands/deploy_command.go @@ -146,6 +146,7 @@ func (c *DeployCommand) GetPluginCommand() plugin.Command { util.GetShortOption(taskExecutionTimeoutOpt): "Task execution 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): "(STRATEGY: BLUE-GREEN, INCREMENTAL-BLUE-GREEN) Stop apps in a dependency-aware order during the resume phase of a blue-green deployment", }, }, } @@ -225,6 +226,7 @@ func (c *DeployCommand) defineCommandOptions(flags *flag.FlagSet) { flags.String(uploadTimeoutOpt, "", "") flags.String(taskExecutionTimeoutOpt, "", "") flags.Bool(shouldBackupPreviousVersionOpt, false, "") + flags.Bool(dependencyAwareStopOrderOpt, false, "") } func (c *DeployCommand) executeInternal(positionalArgs []string, dsHost string, flags *flag.FlagSet, cfTarget util.CloudFoundryTarget) ExecutionStatus { diff --git a/commands/deployment_strategy.go b/commands/deployment_strategy.go index fbea589..34fc4f5 100644 --- a/commands/deployment_strategy.go +++ b/commands/deployment_strategy.go @@ -24,6 +24,7 @@ type BlueGreenDeployCommandDeploymentStrategy struct { skipIdleStart bool incrementalDeploy bool shouldBackupPreviousVersion bool + dependencyAwareStopOrderOpt bool } func (b *BlueGreenDeployCommandDeploymentStrategy) CreateProcessBuilder() *util.ProcessBuilder { @@ -34,21 +35,22 @@ func (b *BlueGreenDeployCommandDeploymentStrategy) CreateProcessBuilder() *util. processBuilder.Parameter("keepOriginalAppNamesAfterDeploy", strconv.FormatBool(true)) processBuilder.Parameter("shouldApplyIncrementalInstancesUpdate", strconv.FormatBool(b.incrementalDeploy)) processBuilder.Parameter("shouldBackupPreviousVersion", strconv.FormatBool(b.shouldBackupPreviousVersion)) + processBuilder.Parameter("stopOrderIsDependencyAware", strconv.FormatBool(b.dependencyAwareStopOrderOpt)) return processBuilder } func NewDeploymentStrategy(flags *flag.FlagSet, typeProvider ProcessTypeProvider) DeploymentStrategy { if typeProvider.GetProcessType() == (blueGreenDeployCommandProcessTypeProvider{}).GetProcessType() { - return &BlueGreenDeployCommandDeploymentStrategy{GetBoolOpt(noConfirmOpt, flags), GetBoolOpt(skipIdleStart, flags), isIncrementalBlueGreen(flags), GetBoolOpt(shouldBackupPreviousVersionOpt, flags)} + return &BlueGreenDeployCommandDeploymentStrategy{GetBoolOpt(noConfirmOpt, flags), GetBoolOpt(skipIdleStart, flags), isIncrementalBlueGreen(flags), GetBoolOpt(shouldBackupPreviousVersionOpt, flags), GetBoolOpt(dependencyAwareStopOrderOpt, flags)} } strategy := GetStringOpt(strategyOpt, flags) if strategy == "default" { return &DeployCommandDeploymentStrategy{} } if GetBoolOpt(skipIdleStart, flags) { - return &BlueGreenDeployCommandDeploymentStrategy{true, true, isIncrementalBlueGreen(flags), GetBoolOpt(shouldBackupPreviousVersionOpt, flags)} + return &BlueGreenDeployCommandDeploymentStrategy{true, true, isIncrementalBlueGreen(flags), GetBoolOpt(shouldBackupPreviousVersionOpt, flags), GetBoolOpt(dependencyAwareStopOrderOpt, flags)} } - return &BlueGreenDeployCommandDeploymentStrategy{GetBoolOpt(skipTestingPhase, flags), false, isIncrementalBlueGreen(flags), GetBoolOpt(shouldBackupPreviousVersionOpt, flags)} + return &BlueGreenDeployCommandDeploymentStrategy{GetBoolOpt(skipTestingPhase, flags), false, isIncrementalBlueGreen(flags), GetBoolOpt(shouldBackupPreviousVersionOpt, flags), GetBoolOpt(dependencyAwareStopOrderOpt, flags)} } func isIncrementalBlueGreen(flags *flag.FlagSet) bool { diff --git a/commands/deployment_strategy_test.go b/commands/deployment_strategy_test.go index 179a4d4..e3aaeba 100644 --- a/commands/deployment_strategy_test.go +++ b/commands/deployment_strategy_test.go @@ -16,11 +16,12 @@ var _ = Describe("Deployment Strategy", func() { const keepOriginalNamesAfterDeploy = "keepOriginalAppNamesAfterDeploy" const skipIdleStart = "skipIdleStart" const shouldBackupPreviousVersion = "shouldBackupPreviousVersion" + const dependencyAwareStopOrderOpt = "stopOrderIsDependencyAware" var deployProcessTypeProvider = &fakes.FakeDeployCommandProcessTypeProvider{} var bgDeployProcessTypeProvider = &fakes.FakeBlueGreenCommandProcessTypeProvider{} - var createFlags = func(noConfirm bool, skipIdleStart bool, strategy string, backupPreviousVersion bool) *flag.FlagSet { + var createFlags = func(noConfirm bool, skipIdleStart bool, strategy string, backupPreviousVersion bool, dependencyAwareStopOption bool) *flag.FlagSet { flags := flag.NewFlagSet("", flag.ContinueOnError) flags.SetOutput(io.Discard) @@ -29,11 +30,12 @@ var _ = Describe("Deployment Strategy", func() { flags.Bool("skip-testing-phase", true, "") flags.Bool("skip-idle-start", skipIdleStart, "") flags.Bool("backup-previous-version", backupPreviousVersion, "") + flags.Bool("dependency-aware-stop-order", dependencyAwareStopOption, "") return flags } var testInputAndOperationProcessTypesMatch = func(provider commands.ProcessTypeProvider) { - flags := createFlags(false, false, "default", false) + flags := createFlags(false, false, "default", false, false) processBuilder := commands.NewDeploymentStrategy(flags, provider).CreateProcessBuilder() operation := processBuilder.Build() Expect(operation.ProcessType).To(Equal(provider.GetProcessType())) @@ -47,7 +49,7 @@ var _ = Describe("Deployment Strategy", func() { Context("with a blue-green deploy command and --no-confirm flag", func() { It("should build a blue-green deploy operation with the noConfirm parameter set to true", func() { - flags := createFlags(true, false, "default", false) + flags := createFlags(true, false, "default", false, false) processBuilder := commands.NewDeploymentStrategy(flags, bgDeployProcessTypeProvider).CreateProcessBuilder() operation := processBuilder.Build() @@ -58,7 +60,7 @@ var _ = Describe("Deployment Strategy", func() { Context("with a blue-green deploy command and --skip-idle-start flag", func() { It("should build a blue-green deploy operation with the skipIdleStart parameter set to true", func() { - flags := createFlags(false, true, "default", false) + flags := createFlags(false, true, "default", false, false) processBuilder := commands.NewDeploymentStrategy(flags, bgDeployProcessTypeProvider).CreateProcessBuilder() operation := processBuilder.Build() @@ -75,7 +77,7 @@ var _ = Describe("Deployment Strategy", func() { Context("with a deploy command with strategy flag set to blue-green", func() { It("should build a blue-green deploy operation", func() { - flags := createFlags(false, false, "blue-green", false) + flags := createFlags(false, false, "blue-green", false, false) processBuilder := commands.NewDeploymentStrategy(flags, deployProcessTypeProvider).CreateProcessBuilder() operation := processBuilder.Build() @@ -87,7 +89,7 @@ var _ = Describe("Deployment Strategy", func() { Context("with a deploy command with strategy flag set to blue-green and --no-confirm flag present", func() { It("should build a blue-green deploy operation with the noConfirm parameter set to true", func() { - flags := createFlags(true, false, "blue-green", false) + flags := createFlags(true, false, "blue-green", false, false) processBuilder := commands.NewDeploymentStrategy(flags, deployProcessTypeProvider).CreateProcessBuilder() operation := processBuilder.Build() @@ -100,7 +102,7 @@ var _ = Describe("Deployment Strategy", func() { Context("with a deploy command with strategy flag set to blue-green and skip-idl-start set to true", func() { It("should build a blue-green deploy operation", func() { - flags := createFlags(false, true, "blue-green", false) + flags := createFlags(false, true, "blue-green", false, false) processBuilder := commands.NewDeploymentStrategy(flags, deployProcessTypeProvider).CreateProcessBuilder() operation := processBuilder.Build() @@ -113,7 +115,7 @@ var _ = Describe("Deployment Strategy", func() { Context("with a deploy command with strategy flag set to blue-green and backup-previous-version set to true", func() { It("should build a blue-green deploy operation with set backup-previous-version flag", func() { - flags := createFlags(true, false, "blue-green", true) + flags := createFlags(true, false, "blue-green", true, false) processBuilder := commands.NewDeploymentStrategy(flags, deployProcessTypeProvider).CreateProcessBuilder() operation := processBuilder.Build() @@ -125,7 +127,7 @@ var _ = Describe("Deployment Strategy", func() { Context("with a deploy command with strategy flag set to incremental-blue-green and backup-previous-version set to true", func() { It("should build a blue-green deploy operation with set incremental-blue-green to true and backup-previous-version to true", func() { - flags := createFlags(true, false, "incremental-blue-green", true) + flags := createFlags(true, false, "incremental-blue-green", true, false) processBuilder := commands.NewDeploymentStrategy(flags, deployProcessTypeProvider).CreateProcessBuilder() operation := processBuilder.Build() @@ -138,7 +140,7 @@ var _ = Describe("Deployment Strategy", func() { Context("with a deploy command with default strategy flag and backup-previous-version flag", func() { It("should build a deploy operation without backup-previous-version flag", func() { - flags := createFlags(false, false, "default", true) + flags := createFlags(false, false, "default", true, false) processBuilder := commands.NewDeploymentStrategy(flags, deployProcessTypeProvider).CreateProcessBuilder() operation := processBuilder.Build() @@ -147,4 +149,41 @@ var _ = Describe("Deployment Strategy", func() { Expect(operation.Parameters).NotTo(HaveKey(shouldBackupPreviousVersion)) }) }) + + Context("with a deploy command with blue-green strategy flag and dependency-aware-stop-order flag set to true", func() { + It("should build a blue-green deploy operation with the dependency-aware-stop-order parameter set to true", func() { + flags := createFlags(false, false, "blue-green", true, true) + + processBuilder := commands.NewDeploymentStrategy(flags, deployProcessTypeProvider).CreateProcessBuilder() + operation := processBuilder.Build() + + Expect(operation.ProcessType).To(Equal(bgDeployProcessTypeProvider.GetProcessType())) + Expect(operation.Parameters[dependencyAwareStopOrderOpt]).To(Equal(strconv.FormatBool(true))) + }) + }) + + Context("with a deploy command with strategy flag set to incremental-blue-green and dependency-aware-stop-order set to true", func() { + It("should build a blue-green deploy operation with set incremental-blue-green to true and dependency-aware-stop-order to true", func() { + flags := createFlags(false, false, "incremental-blue-green", true, true) + + processBuilder := commands.NewDeploymentStrategy(flags, deployProcessTypeProvider).CreateProcessBuilder() + operation := processBuilder.Build() + + Expect(operation.ProcessType).To(Equal(bgDeployProcessTypeProvider.GetProcessType())) + Expect(operation.Parameters[dependencyAwareStopOrderOpt]).To(Equal(strconv.FormatBool(true))) + Expect(operation.Parameters["shouldApplyIncrementalInstancesUpdate"]).To(Equal(strconv.FormatBool(true))) + }) + }) + + Context("with a deploy command with default strategy flag and dependency-aware-stop-order flag", func() { + It("should build a deploy operation without dependency-aware-stop-order flag", func() { + flags := createFlags(false, false, "default", true, true) + + processBuilder := commands.NewDeploymentStrategy(flags, deployProcessTypeProvider).CreateProcessBuilder() + operation := processBuilder.Build() + + Expect(operation.ProcessType).To(Equal(deployProcessTypeProvider.GetProcessType())) + Expect(operation.Parameters).NotTo(HaveKey(dependencyAwareStopOrderOpt)) + }) + }) })