Merge "Create software-deploy-strategy command"

This commit is contained in:
Zuul 2024-02-20 21:37:20 +00:00 committed by Gerrit Code Review
commit 76029da32b
5 changed files with 307 additions and 110 deletions

View File

@ -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 = \

View File

@ -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"]
)

View File

@ -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

View File

@ -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,
}

View File

@ -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, [])