From da6dcf23ba3a47d6a16b3bb82e98f8c3adb134e6 Mon Sep 17 00:00:00 2001 From: Hugo Brito Date: Thu, 8 Feb 2024 10:12:44 -0300 Subject: [PATCH] Create software-deploy-strategy command Added a new command: dcmanager software-deploy-strategy to manage software orchestration. This command requires a --release-id parameter for specifying the release to deploy. Test Plan: 1. Verify that command software-deploy-strategy create without --release-id option fails 2. Verify that command software-deploy-strategy create --release-id is processed successfully 3. Verify that command software-deploy-strategy show/delete/abort/apply is processed successfully. Story: 2010676 Task: 49548 Depends-On: https://review.opendev.org/c/starlingx/distcloud/+/908538 Change-Id: I389bac227833b5f63e19a136d0f13b75f9fb8866 Signed-off-by: Hugo Brito --- .../dcmanagerclient/api/v1/client.py | 4 +- .../api/v1/sw_deploy_manager.py | 16 ++ .../commands/v1/sw_deploy_manager.py | 95 ++++++++ .../dcmanagerclient/shell.py | 224 +++++++++--------- .../tests/v1/test_sw_deploy_manager.py | 78 ++++++ 5 files changed, 307 insertions(+), 110 deletions(-) create mode 100644 distributedcloud-client/dcmanagerclient/api/v1/sw_deploy_manager.py create mode 100644 distributedcloud-client/dcmanagerclient/commands/v1/sw_deploy_manager.py create mode 100644 distributedcloud-client/dcmanagerclient/tests/v1/test_sw_deploy_manager.py diff --git a/distributedcloud-client/dcmanagerclient/api/v1/client.py b/distributedcloud-client/dcmanagerclient/api/v1/client.py index b4f701d..0c219b1 100644 --- a/distributedcloud-client/dcmanagerclient/api/v1/client.py +++ b/distributedcloud-client/dcmanagerclient/api/v1/client.py @@ -1,7 +1,7 @@ # Copyright 2014 - Mirantis, Inc. # Copyright 2015 - StackStorm, Inc. # Copyright 2016 - Ericsson AB. -# Copyright (c) 2017-2023 Wind River Systems, Inc. +# Copyright (c) 2017-2024 Wind River Systems, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ from dcmanagerclient.api.v1 import subcloud_deploy_manager as sdm from dcmanagerclient.api.v1 import subcloud_group_manager as gm from dcmanagerclient.api.v1 import subcloud_manager as sm from dcmanagerclient.api.v1 import subcloud_peer_group_manager as pm +from dcmanagerclient.api.v1 import sw_deploy_manager as swdm from dcmanagerclient.api.v1 import sw_patch_manager as spm from dcmanagerclient.api.v1 import sw_prestage_manager as spr from dcmanagerclient.api.v1 import sw_strategy_manager as sstm @@ -118,6 +119,7 @@ class Client(object): self.kube_rootca_update_manager = \ krum.kube_rootca_update_manager(self.http_client) self.kube_upgrade_manager = kupm.kube_upgrade_manager(self.http_client) + self.sw_deploy_manager = swdm.SwDeployManager(self.http_client) self.sw_patch_manager = spm.sw_patch_manager(self.http_client) self.sw_prestage_manager = spr.sw_prestage_manager(self.http_client) self.sw_update_options_manager = \ diff --git a/distributedcloud-client/dcmanagerclient/api/v1/sw_deploy_manager.py b/distributedcloud-client/dcmanagerclient/api/v1/sw_deploy_manager.py new file mode 100644 index 0000000..0218cde --- /dev/null +++ b/distributedcloud-client/dcmanagerclient/api/v1/sw_deploy_manager.py @@ -0,0 +1,16 @@ +# +# Copyright (c) 2024 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +from dcmanagerclient.api.v1.sw_update_manager import sw_update_manager + +SW_UPDATE_TYPE_USM = "software" + + +class SwDeployManager(sw_update_manager): + def __init__(self, http_client): + super().__init__( + http_client, update_type=SW_UPDATE_TYPE_USM, extra_args=["release"] + ) diff --git a/distributedcloud-client/dcmanagerclient/commands/v1/sw_deploy_manager.py b/distributedcloud-client/dcmanagerclient/commands/v1/sw_deploy_manager.py new file mode 100644 index 0000000..2ee3a7c --- /dev/null +++ b/distributedcloud-client/dcmanagerclient/commands/v1/sw_deploy_manager.py @@ -0,0 +1,95 @@ +# +# Copyright (c) 2024 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +from dcmanagerclient.commands.v1 import sw_update_manager + +RELEASE_FIELD = -3 + + +class SwDeployManagerMixin(object): + """This Mixin provides the manager used for software deploy releases.""" + + def get_sw_update_manager(self): + dcmanager_client = self.app.client_manager.sw_deploy_manager + return dcmanager_client.sw_deploy_manager + + def custom_format_function(self, sw_update_strategy=None): + original_fmt_func = super()._get_format_function() + columns, data = original_fmt_func(sw_update_strategy) + release_id = "" + if sw_update_strategy and sw_update_strategy.extra_args: + release_id = sw_update_strategy.extra_args.get("release_id") + + # Insert the 'release_id' field before the 'state', + # 'created_at' and 'updated_at' fields + columns = columns[:RELEASE_FIELD] + ( + "release_id",) + columns[RELEASE_FIELD:] + data = data[:RELEASE_FIELD] + (release_id,) + data[RELEASE_FIELD:] + return columns, data + + def _get_format_function(self): + return self.custom_format_function + + +class CreateSwDeployStrategy( + SwDeployManagerMixin, sw_update_manager.CreateSwUpdateStrategy +): + """Create a software deploy strategy.""" + + def add_force_argument(self, parser): + parser.add_argument( + "--force", + required=False, + action="store_true", + help="Skip checking the subcloud for management affecting alarms.", + ) + + def get_parser(self, prog_name): + parser = super(CreateSwDeployStrategy, self).get_parser(prog_name) + + parser.add_argument( + "--release-id", + required=True, + help="The release to be deployed.", + ) + + return parser + + def process_custom_params(self, parsed_args, kwargs_dict): + """Updates kwargs dictionary from parsed_args for patching""" + kwargs_dict["release_id"] = parsed_args.release_id + + # override validate_force_params defined in CreateSwUpdateStrategy + def validate_force_params(self, parsed_args): + pass + + +class ShowSwDeployStrategy( + SwDeployManagerMixin, sw_update_manager.ShowSwUpdateStrategy +): + """Show the details of a software deploy strategy for a subcloud.""" + pass + + +class DeleteSwDeployStrategy( + SwDeployManagerMixin, sw_update_manager.DeleteSwUpdateStrategy +): + """Delete software deploy strategy from the database.""" + pass + + +class ApplySwDeployStrategy( + SwDeployManagerMixin, sw_update_manager.ApplySwUpdateStrategy +): + """Apply a software deploy strategy.""" + pass + + +class AbortSwDeployStrategy( + SwDeployManagerMixin, sw_update_manager.AbortSwUpdateStrategy +): + """Abort a software deploy strategy.""" + pass diff --git a/distributedcloud-client/dcmanagerclient/shell.py b/distributedcloud-client/dcmanagerclient/shell.py index d852365..4e824a9 100644 --- a/distributedcloud-client/dcmanagerclient/shell.py +++ b/distributedcloud-client/dcmanagerclient/shell.py @@ -18,20 +18,18 @@ Command-line interface to the DC Manager APIs """ +import argparse import logging import os import sys -from dcmanagerclient import __version__ as dcmanager_version -from dcmanagerclient.api import client -from dcmanagerclient import exceptions - from cliff import app from cliff import commandmanager -from cliff import help +from cliff import help as cliff_help from osc_lib.command import command -import argparse +from dcmanagerclient import __version__ as dcmanager_version +from dcmanagerclient.api import client from dcmanagerclient.commands.v1 import alarm_manager as am from dcmanagerclient.commands.v1 import fw_update_manager as fum from dcmanagerclient.commands.v1 import kube_rootca_update_manager as krum @@ -43,12 +41,14 @@ from dcmanagerclient.commands.v1 import subcloud_deploy_manager as sdm from dcmanagerclient.commands.v1 import subcloud_group_manager as gm from dcmanagerclient.commands.v1 import subcloud_manager as sm from dcmanagerclient.commands.v1 import subcloud_peer_group_manager as pm +from dcmanagerclient.commands.v1 import sw_deploy_manager as swdm from dcmanagerclient.commands.v1 import sw_patch_manager as spm from dcmanagerclient.commands.v1 import sw_prestage_manager as spr -from dcmanagerclient.commands.v1 import sw_update_manager as sum +from dcmanagerclient.commands.v1 import sw_update_manager as swum from dcmanagerclient.commands.v1 import sw_update_options_manager as suom from dcmanagerclient.commands.v1 import sw_upgrade_manager as supm from dcmanagerclient.commands.v1 import system_peer_manager as sp +from dcmanagerclient import exceptions LOG = logging.getLogger(__name__) @@ -81,7 +81,7 @@ class OpenStackHelpFormatter(argparse.HelpFormatter): super(OpenStackHelpFormatter, self).start_section(heading) -class HelpCommand(help.HelpCommand): +class HelpCommand(cliff_help.HelpCommand): """print detailed help for another command Provide a custom action so the help command without @@ -498,6 +498,7 @@ class DCManagerShell(app.App): strategy_step_manager=self.client, sw_update_options_manager=self.client, sw_upgrade_manager=self.client, + sw_deploy_manager=self.client, kube_upgrade_manager=self.client, kube_rootca_update_manager=self.client, sw_prestage_manager=self.client, @@ -528,109 +529,114 @@ class DCManagerShell(app.App): @staticmethod def _get_commands_v1(): return { - 'bash-completion': BashCompletionCommand, - 'subcloud add': sm.AddSubcloud, - 'subcloud delete': sm.DeleteSubcloud, - 'subcloud list': sm.ListSubcloud, - 'subcloud show': sm.ShowSubcloud, - 'subcloud errors': sm.ShowSubcloudError, - 'subcloud unmanage': sm.UnmanageSubcloud, - 'subcloud manage': sm.ManageSubcloud, - 'subcloud update': sm.UpdateSubcloud, - 'subcloud reconfig': sm.ReconfigSubcloud, - 'subcloud reinstall': sm.ReinstallSubcloud, - 'subcloud redeploy': sm.RedeploySubcloud, - 'subcloud restore': sm.RestoreSubcloud, - 'subcloud prestage': sm.PrestageSubcloud, - 'subcloud-backup create': sbm.CreateSubcloudBackup, - 'subcloud-backup delete': sbm.DeleteSubcloudBackup, - 'subcloud-backup restore': sbm.RestoreSubcloudBackup, - 'subcloud-group add': gm.AddSubcloudGroup, - 'subcloud-group delete': gm.DeleteSubcloudGroup, - 'subcloud-group list': gm.ListSubcloudGroup, - 'subcloud-group list-subclouds': gm.ListSubcloudGroupSubclouds, - 'subcloud-group show': gm.ShowSubcloudGroup, - 'subcloud-group update': gm.UpdateSubcloudGroup, - 'subcloud deploy abort': psdm.AbortPhasedSubcloudDeploy, - 'subcloud deploy create': psdm.CreatePhasedSubcloudDeploy, - 'subcloud deploy bootstrap': psdm.BootstrapPhasedSubcloudDeploy, - 'subcloud deploy config': psdm.ConfigPhasedSubcloudDeploy, - 'subcloud deploy install': psdm.InstallPhasedSubcloudDeploy, - 'subcloud deploy complete': psdm.CompletePhasedSubcloudDeploy, - 'subcloud deploy resume': psdm.PhasedSubcloudDeployResume, - 'subcloud deploy upload': sdm.SubcloudDeployUpload, - 'subcloud deploy show': sdm.SubcloudDeployShow, - 'subcloud deploy delete': sdm.SubcloudDeployDelete, - 'subcloud-deploy upload': sdm.DeprecatedSubcloudDeployUpload, - 'subcloud-deploy show': sdm.DeprecatedSubcloudDeployShow, - 'subcloud-peer-group add': pm.AddSubcloudPeerGroup, - 'subcloud-peer-group list': pm.ListSubcloudPeerGroup, - 'subcloud-peer-group list-subclouds': - pm.ListSubcloudPeerGroupSubclouds, - 'subcloud-peer-group show': pm.ShowSubcloudPeerGroup, - 'subcloud-peer-group update': pm.UpdateSubcloudPeerGroup, - 'subcloud-peer-group delete': pm.DeleteSubcloudPeerGroup, - 'subcloud-peer-group migrate': pm.MigrateSubcloudPeerGroup, - 'subcloud-peer-group status': pm.StatusSubcloudPeerGroup, - 'system-peer add': sp.AddSystemPeer, - 'system-peer list': sp.ListSystemPeer, - 'system-peer show': sp.ShowSystemPeer, - 'system-peer update': sp.UpdateSystemPeer, - 'system-peer delete': sp.DeleteSystemPeer, - 'system-peer list-subcloud-peer-groups': - sp.ListSystemPeerSubcloudPeerGroups, - 'peer-group-association add': pgam.AddPeerGroupAssociation, - 'peer-group-association list': pgam.ListPeerGroupAssociation, - 'peer-group-association show': pgam.ShowPeerGroupAssociation, - 'peer-group-association sync': pgam.SyncPeerGroupAssociation, - 'peer-group-association update': pgam.UpdatePeerGroupAssociation, - 'peer-group-association delete': pgam.DeletePeerGroupAssociation, - 'alarm summary': am.ListAlarmSummary, - 'fw-update-strategy create': fum.CreateFwUpdateStrategy, - 'fw-update-strategy delete': fum.DeleteFwUpdateStrategy, - 'fw-update-strategy apply': fum.ApplyFwUpdateStrategy, - 'fw-update-strategy abort': fum.AbortFwUpdateStrategy, - 'fw-update-strategy show': fum.ShowFwUpdateStrategy, - 'kube-rootca-update-strategy create': - krum.CreateKubeRootcaUpdateStrategy, - 'kube-rootca-update-strategy delete': - krum.DeleteKubeRootcaUpdateStrategy, - 'kube-rootca-update-strategy apply': - krum.ApplyKubeRootcaUpdateStrategy, - 'kube-rootca-update-strategy abort': + "alarm summary": am.ListAlarmSummary, + "bash-completion": BashCompletionCommand, + "fw-update-strategy abort": fum.AbortFwUpdateStrategy, + "fw-update-strategy apply": fum.ApplyFwUpdateStrategy, + "fw-update-strategy create": fum.CreateFwUpdateStrategy, + "fw-update-strategy delete": fum.DeleteFwUpdateStrategy, + "fw-update-strategy show": fum.ShowFwUpdateStrategy, + "kube-rootca-update-strategy abort": krum.AbortKubeRootcaUpdateStrategy, - 'kube-rootca-update-strategy show': + "kube-rootca-update-strategy apply": + krum.ApplyKubeRootcaUpdateStrategy, + "kube-rootca-update-strategy create": + krum.CreateKubeRootcaUpdateStrategy, + "kube-rootca-update-strategy delete": + krum.DeleteKubeRootcaUpdateStrategy, + "kube-rootca-update-strategy show": krum.ShowKubeRootcaUpdateStrategy, - 'kube-upgrade-strategy create': kupm.CreateKubeUpgradeStrategy, - 'kube-upgrade-strategy delete': kupm.DeleteKubeUpgradeStrategy, - 'kube-upgrade-strategy apply': kupm.ApplyKubeUpgradeStrategy, - 'kube-upgrade-strategy abort': kupm.AbortKubeUpgradeStrategy, - 'kube-upgrade-strategy show': kupm.ShowKubeUpgradeStrategy, - 'patch-strategy create': spm.CreatePatchUpdateStrategy, - 'patch-strategy delete': spm.DeletePatchUpdateStrategy, - 'patch-strategy apply': spm.ApplyPatchUpdateStrategy, - 'patch-strategy abort': spm.AbortPatchUpdateStrategy, - 'patch-strategy show': spm.ShowPatchUpdateStrategy, - 'prestage-strategy create': spr.CreateSwPrestageStrategy, - 'prestage-strategy delete': spr.DeleteSwPrestageStrategy, - 'prestage-strategy apply': spr.ApplySwPrestageStrategy, - 'prestage-strategy abort': spr.AbortSwPrestageStrategy, - 'prestage-strategy show': spr.ShowSwPrestageStrategy, - 'strategy-step list': sum.ListSwUpdateStrategyStep, - 'strategy-step show': sum.ShowSwUpdateStrategyStep, - 'patch-strategy-config update': suom.UpdateSwUpdateOptions, - 'patch-strategy-config list': suom.ListSwUpdateOptions, - 'patch-strategy-config show': suom.ShowSwUpdateOptions, - 'patch-strategy-config delete': suom.DeleteSwUpdateOptions, - 'strategy-config update': suom.UpdateSwUpdateOptions, - 'strategy-config list': suom.ListSwUpdateOptions, - 'strategy-config show': suom.ShowSwUpdateOptions, - 'strategy-config delete': suom.DeleteSwUpdateOptions, - 'upgrade-strategy create': supm.CreateSwUpgradeStrategy, - 'upgrade-strategy delete': supm.DeleteSwUpgradeStrategy, - 'upgrade-strategy apply': supm.ApplySwUpgradeStrategy, - 'upgrade-strategy abort': supm.AbortSwUpgradeStrategy, - 'upgrade-strategy show': supm.ShowSwUpgradeStrategy, + "kube-upgrade-strategy abort": kupm.AbortKubeUpgradeStrategy, + "kube-upgrade-strategy apply": kupm.ApplyKubeUpgradeStrategy, + "kube-upgrade-strategy create": kupm.CreateKubeUpgradeStrategy, + "kube-upgrade-strategy delete": kupm.DeleteKubeUpgradeStrategy, + "kube-upgrade-strategy show": kupm.ShowKubeUpgradeStrategy, + "patch-strategy abort": spm.AbortPatchUpdateStrategy, + "patch-strategy apply": spm.ApplyPatchUpdateStrategy, + "patch-strategy create": spm.CreatePatchUpdateStrategy, + "patch-strategy delete": spm.DeletePatchUpdateStrategy, + "patch-strategy show": spm.ShowPatchUpdateStrategy, + "patch-strategy-config delete": suom.DeleteSwUpdateOptions, + "patch-strategy-config list": suom.ListSwUpdateOptions, + "patch-strategy-config show": suom.ShowSwUpdateOptions, + "patch-strategy-config update": suom.UpdateSwUpdateOptions, + "peer-group-association add": pgam.AddPeerGroupAssociation, + "peer-group-association delete": pgam.DeletePeerGroupAssociation, + "peer-group-association list": pgam.ListPeerGroupAssociation, + "peer-group-association show": pgam.ShowPeerGroupAssociation, + "peer-group-association sync": pgam.SyncPeerGroupAssociation, + "peer-group-association update": pgam.UpdatePeerGroupAssociation, + "prestage-strategy abort": spr.AbortSwPrestageStrategy, + "prestage-strategy apply": spr.ApplySwPrestageStrategy, + "prestage-strategy create": spr.CreateSwPrestageStrategy, + "prestage-strategy delete": spr.DeleteSwPrestageStrategy, + "prestage-strategy show": spr.ShowSwPrestageStrategy, + "software-deploy-strategy abort": swdm.AbortSwDeployStrategy, + "software-deploy-strategy apply": swdm.ApplySwDeployStrategy, + "software-deploy-strategy create": swdm.CreateSwDeployStrategy, + "software-deploy-strategy delete": swdm.DeleteSwDeployStrategy, + "software-deploy-strategy show": swdm.ShowSwDeployStrategy, + "strategy-step list": swum.ListSwUpdateStrategyStep, + "strategy-step show": swum.ShowSwUpdateStrategyStep, + "strategy-config delete": suom.DeleteSwUpdateOptions, + "strategy-config list": suom.ListSwUpdateOptions, + "strategy-config show": suom.ShowSwUpdateOptions, + "strategy-config update": suom.UpdateSwUpdateOptions, + "subcloud add": sm.AddSubcloud, + "subcloud delete": sm.DeleteSubcloud, + "subcloud deploy abort": psdm.AbortPhasedSubcloudDeploy, + "subcloud deploy bootstrap": psdm.BootstrapPhasedSubcloudDeploy, + "subcloud deploy complete": psdm.CompletePhasedSubcloudDeploy, + "subcloud deploy config": psdm.ConfigPhasedSubcloudDeploy, + "subcloud deploy create": psdm.CreatePhasedSubcloudDeploy, + "subcloud deploy delete": sdm.SubcloudDeployDelete, + "subcloud deploy install": psdm.InstallPhasedSubcloudDeploy, + "subcloud deploy resume": psdm.PhasedSubcloudDeployResume, + "subcloud deploy show": sdm.SubcloudDeployShow, + "subcloud deploy upload": sdm.SubcloudDeployUpload, + "subcloud errors": sm.ShowSubcloudError, + "subcloud list": sm.ListSubcloud, + "subcloud manage": sm.ManageSubcloud, + "subcloud reconfig": sm.ReconfigSubcloud, + "subcloud redeploy": sm.RedeploySubcloud, + "subcloud reinstall": sm.ReinstallSubcloud, + "subcloud restore": sm.RestoreSubcloud, + "subcloud show": sm.ShowSubcloud, + "subcloud prestage": sm.PrestageSubcloud, + "subcloud unmanage": sm.UnmanageSubcloud, + "subcloud update": sm.UpdateSubcloud, + "subcloud-backup create": sbm.CreateSubcloudBackup, + "subcloud-backup delete": sbm.DeleteSubcloudBackup, + "subcloud-backup restore": sbm.RestoreSubcloudBackup, + "subcloud-deploy show": sdm.DeprecatedSubcloudDeployShow, + "subcloud-deploy upload": sdm.DeprecatedSubcloudDeployUpload, + "subcloud-group add": gm.AddSubcloudGroup, + "subcloud-group delete": gm.DeleteSubcloudGroup, + "subcloud-group list": gm.ListSubcloudGroup, + "subcloud-group list-subclouds": gm.ListSubcloudGroupSubclouds, + "subcloud-group show": gm.ShowSubcloudGroup, + "subcloud-group update": gm.UpdateSubcloudGroup, + "subcloud-peer-group add": pm.AddSubcloudPeerGroup, + "subcloud-peer-group delete": pm.DeleteSubcloudPeerGroup, + "subcloud-peer-group list": pm.ListSubcloudPeerGroup, + "subcloud-peer-group list-subclouds": + pm.ListSubcloudPeerGroupSubclouds, + "subcloud-peer-group migrate": pm.MigrateSubcloudPeerGroup, + "subcloud-peer-group show": pm.ShowSubcloudPeerGroup, + "subcloud-peer-group status": pm.StatusSubcloudPeerGroup, + "subcloud-peer-group update": pm.UpdateSubcloudPeerGroup, + "system-peer add": sp.AddSystemPeer, + "system-peer delete": sp.DeleteSystemPeer, + "system-peer list": sp.ListSystemPeer, + "system-peer list-subcloud-peer-groups": + sp.ListSystemPeerSubcloudPeerGroups, + "system-peer show": sp.ShowSystemPeer, + "system-peer update": sp.UpdateSystemPeer, + "upgrade-strategy abort": supm.AbortSwUpgradeStrategy, + "upgrade-strategy apply": supm.ApplySwUpgradeStrategy, + "upgrade-strategy create": supm.CreateSwUpgradeStrategy, + "upgrade-strategy delete": supm.DeleteSwUpgradeStrategy, + "upgrade-strategy show": supm.ShowSwUpgradeStrategy, } diff --git a/distributedcloud-client/dcmanagerclient/tests/v1/test_sw_deploy_manager.py b/distributedcloud-client/dcmanagerclient/tests/v1/test_sw_deploy_manager.py new file mode 100644 index 0000000..a4820f1 --- /dev/null +++ b/distributedcloud-client/dcmanagerclient/tests/v1/test_sw_deploy_manager.py @@ -0,0 +1,78 @@ +# +# Copyright (c) 2024 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +from dcmanagerclient.commands.v1 import sw_deploy_manager as cli_cmd +from dcmanagerclient.tests import base +from dcmanagerclient.tests.v1.mixins import UpdateStrategyMixin +from dcmanagerclient.tests.v1 import utils + + +class TestSwDeployStrategy(UpdateStrategyMixin, base.BaseCommandTest): + + def setUp(self): + super().setUp() + + # Increase results_length due to the 'upload only' field + self.results_length += 1 + + self.sw_update_manager = ( + self.app.client_manager.sw_deploy_manager.sw_deploy_manager + ) + self.create_command = cli_cmd.CreateSwDeployStrategy + self.show_command = cli_cmd.ShowSwDeployStrategy + self.delete_command = cli_cmd.DeleteSwDeployStrategy + self.apply_command = cli_cmd.ApplySwDeployStrategy + self.abort_command = cli_cmd.AbortSwDeployStrategy + + def test_create_strategy(self): + """Test deploy strategy should be created with --release-id""" + + # prepare mixin attributes + manager_to_test = self.sw_update_manager + expected_strategy_type = manager_to_test.update_type + + # mock the result of the API call + strategy = utils.make_strategy( + strategy_type=expected_strategy_type, extra_args={ + "release_id": "stx-24.09.1"} + ) + + # mock that there is no pre-existing strategy + manager_to_test.create_sw_update_strategy.return_value = strategy + + # invoke the backend method for the CLI. + # Returns a tuple of field descriptions, and a second tuple of values + fields, results = self.call( + self.create_command, ["--release-id", "stx-24.09.1"]) + + # results is a tuple of expected length + self.assertEqual(len(results), self.results_length) + # result tuple values are + # - strategy type + # - subcloud apply type + # - max parallel subclouds + # - stop on failure + # - release_id + # - state + # - created_at + # - updated_at + + self.assertEqual(results[0], expected_strategy_type) + self.assertEqual(fields[-4], "release_id") + self.assertEqual(results[-4], "stx-24.09.1") + + def test_create_strategy_without_release_id(self): + """Test deploy strategy should not be created without --release-id""" + + # prepare mixin attributes + manager_to_test = self.sw_update_manager + + # mock that there is no pre-existing strategy + manager_to_test.create_sw_update_strategy.return_value = None + + # invoke the backend method for the CLI. + # Returns a tuple of field descriptions, and a second tuple of values + self.assertRaises(SystemExit, self.call, self.create_command, [])