Add sw-manager --active show command
- Add a new --active option for 'show' commands to only show stages, phases, and steps that are in progress. - Refactor initialization and execution of the CLI commands to reuse common code and simplify adding new update orchestrations. - Add unit tests for all strategies and action types for the CLI which increases test coverage for shell.py from 69 to 95 percent Story: 2008137 Task: 42199 Signed-off-by: albailey <Al.Bailey@windriver.com> Change-Id: I4280ef41ba7586c822d4d39629e51b4592fd996a
This commit is contained in:
parent
2368f9128c
commit
483dc779b5
|
@ -11,76 +11,367 @@ import sys
|
|||
from nfv_client import sw_update
|
||||
|
||||
|
||||
REGISTERED_STRATEGIES = {}
|
||||
|
||||
|
||||
def register_strategy(cmd_area, strategy_name):
|
||||
"""
|
||||
Registers a parser command with an update strategy name
|
||||
|
||||
:param cmd_area: the parser command to register
|
||||
:param strategy_name: the strategy to associate with this parser
|
||||
"""
|
||||
REGISTERED_STRATEGIES[cmd_area] = strategy_name
|
||||
|
||||
|
||||
def get_strategy_name(cmd_area):
|
||||
"""
|
||||
Determines the strategy name for a parser command
|
||||
|
||||
:param cmd_area: the parser command to lookup
|
||||
:returns: the strategy name associated with the parser
|
||||
:raises: ValueError if the parser was never registered
|
||||
"""
|
||||
strategy_name = REGISTERED_STRATEGIES.get(cmd_area, None)
|
||||
if strategy_name is None:
|
||||
raise ValueError("Unknown command area, %s, given" % cmd_area)
|
||||
return strategy_name
|
||||
|
||||
|
||||
def get_extra_create_args(cmd_area, args):
|
||||
"""
|
||||
Return the extra create arguments supported by a strategy type
|
||||
|
||||
:param cmd_area: the strategy that supports additional create arguments
|
||||
:param args: the parsed arguments to extract the additional fields from
|
||||
:returns: a dictionary of additional kwargs for the create_strategy command
|
||||
:raises: ValueError if a strategy has been registered but not update here
|
||||
"""
|
||||
if 'patch-strategy' == cmd_area:
|
||||
# no additional kwargs for patch
|
||||
return {}
|
||||
elif 'upgrade-strategy' == cmd_area:
|
||||
# upgrade supports: complete_upgrade
|
||||
return {'complete_upgrade': args.complete_upgrade}
|
||||
elif 'fw-update-strategy' == cmd_area:
|
||||
# no additional kwargs for firmware update
|
||||
return {}
|
||||
elif 'kube-upgrade-strategy' == cmd_area:
|
||||
# kube upgrade supports: to_version
|
||||
return {'to_version': args.to_version}
|
||||
else:
|
||||
raise ValueError("Unknown command area, %s, given" % cmd_area)
|
||||
|
||||
|
||||
def add_list_arg(some_cmd, some_arg, some_list):
|
||||
"""
|
||||
Adds an argument to a command accepting a list of valid values.
|
||||
|
||||
:param some_cmd: a command parser object that is adding a new argument
|
||||
:param some_arg: a string indicating the new argument. ex: --foo
|
||||
:param some_list: a list of valid values for the argument.
|
||||
|
||||
The list cannot be empty. The first item in the list is the default
|
||||
"""
|
||||
default = some_list[0]
|
||||
some_cmd.add_argument(some_arg,
|
||||
default=default,
|
||||
choices=some_list,
|
||||
help='defaults to ' + default)
|
||||
|
||||
|
||||
def setup_abort_cmd(parser):
|
||||
"""
|
||||
Sets up an 'abort' command for a strategy command parser.
|
||||
|
||||
ex: sw-manager patch-strategy abort <some args>
|
||||
|
||||
:param parser: the strategy parser to add the create command to.
|
||||
"""
|
||||
abort_cmd = parser.add_parser('abort',
|
||||
help='Abort a strategy')
|
||||
abort_cmd.set_defaults(cmd='abort')
|
||||
abort_cmd.add_argument('--stage-id',
|
||||
help='stage identifier to abort')
|
||||
return abort_cmd
|
||||
|
||||
|
||||
def setup_apply_cmd(parser):
|
||||
"""
|
||||
Sets up an 'apply' command for a strategy command parser.
|
||||
|
||||
ex: sw-manager patch-strategy apply <some args>
|
||||
|
||||
:param parser: the strategy parser to register the command under
|
||||
"""
|
||||
apply_cmd = parser.add_parser('apply',
|
||||
help='Apply a strategy')
|
||||
apply_cmd.set_defaults(cmd='apply')
|
||||
apply_cmd.add_argument('--stage-id',
|
||||
default=None,
|
||||
help='stage identifier to apply')
|
||||
return apply_cmd
|
||||
|
||||
|
||||
def setup_create_cmd(parser,
|
||||
controller_types,
|
||||
storage_types,
|
||||
worker_types,
|
||||
instance_actions,
|
||||
alarm_restrictions,
|
||||
min_parallel=1,
|
||||
max_parallel=5):
|
||||
"""
|
||||
Sets up a 'create' command for a strategy command parser.
|
||||
|
||||
ex: sw-manager patch-strategy create <some args>
|
||||
|
||||
:param parser: the strategy parser to register the command under
|
||||
:param controller_types: list of the valid apply types for controller
|
||||
:param storage_types: list of the valid apply types for storage
|
||||
:param worker_types: list of the valid apply types for worker
|
||||
:param instance_actions: list of valid VM actions during worker apply
|
||||
:param alarm_restrictions: list of valid alarm restrictions
|
||||
:param min_parallel: minimum value (inclusive) for updating parallel hosts
|
||||
:param max_parallel: maximum value (inclusive) for updating parallel hosts
|
||||
|
||||
The lists cannot be empty. The first item in the lists is the default
|
||||
"""
|
||||
create_cmd = parser.add_parser('create', help='Create a strategy')
|
||||
create_cmd.set_defaults(cmd='create')
|
||||
|
||||
add_list_arg(create_cmd, '--controller-apply-type', controller_types)
|
||||
add_list_arg(create_cmd, '--storage-apply-type', storage_types)
|
||||
add_list_arg(create_cmd, '--worker-apply-type', worker_types)
|
||||
add_list_arg(create_cmd, '--instance-action', instance_actions)
|
||||
add_list_arg(create_cmd, '--alarm-restrictions', alarm_restrictions)
|
||||
create_cmd.add_argument('--max-parallel-worker-hosts',
|
||||
type=int,
|
||||
choices=range(min_parallel, max_parallel + 1),
|
||||
help='maximum worker hosts to update in parallel')
|
||||
|
||||
return create_cmd
|
||||
|
||||
|
||||
def setup_delete_cmd(parser):
|
||||
"""
|
||||
Sets up a 'delete' command for a strategy command parser.
|
||||
|
||||
ex: sw-manager patch-strategy delete <some args>
|
||||
|
||||
:param parser: the strategy parser to register the command under
|
||||
"""
|
||||
delete_cmd = parser.add_parser('delete', help='Delete a strategy')
|
||||
delete_cmd.set_defaults(cmd='delete')
|
||||
delete_cmd.add_argument('--force',
|
||||
action='store_true',
|
||||
help=argparse.SUPPRESS)
|
||||
return delete_cmd
|
||||
|
||||
|
||||
def setup_show_cmd(parser):
|
||||
"""
|
||||
Sets up a 'show' command for a strategy command parser.
|
||||
|
||||
ex: sw-manager patch-strategy show <some args>
|
||||
|
||||
:param parser: the strategy parser to register the command under
|
||||
"""
|
||||
show_cmd = parser.add_parser('show', help='Show a strategy')
|
||||
show_cmd.set_defaults(cmd='show')
|
||||
show_cmd.add_argument('--details',
|
||||
action='store_true',
|
||||
help='show strategy details')
|
||||
show_cmd.add_argument('--active',
|
||||
action='store_true',
|
||||
help='show currently active strategy step')
|
||||
return show_cmd
|
||||
|
||||
|
||||
def setup_fw_update_parser(commands):
|
||||
"""Firmware Update Strategy Commands"""
|
||||
|
||||
cmd_area = 'fw-update-strategy'
|
||||
register_strategy(cmd_area, sw_update.STRATEGY_NAME_FW_UPDATE)
|
||||
cmd_parser = commands.add_parser(cmd_area,
|
||||
help='Firmware Update Strategy')
|
||||
cmd_parser.set_defaults(cmd_area=cmd_area)
|
||||
|
||||
sub_cmds = cmd_parser.add_subparsers(title='Firmware Update Commands',
|
||||
metavar='')
|
||||
sub_cmds.required = True
|
||||
|
||||
# define the create command
|
||||
# alarm restrictions, defaults to strict
|
||||
create_strategy_cmd = setup_create_cmd(
|
||||
sub_cmds,
|
||||
[sw_update.APPLY_TYPE_IGNORE], # controller supports ignore
|
||||
[sw_update.APPLY_TYPE_IGNORE], # storage supports ignore
|
||||
[sw_update.APPLY_TYPE_SERIAL, # worker supports serial and parallel
|
||||
sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
[sw_update.INSTANCE_ACTION_STOP_START, # instance actions
|
||||
sw_update.INSTANCE_ACTION_MIGRATE],
|
||||
[sw_update.ALARM_RESTRICTIONS_STRICT, # alarm restrictions
|
||||
sw_update.ALARM_RESTRICTIONS_RELAXED],
|
||||
min_parallel=2,
|
||||
max_parallel=5 # fw update supports 2..5 workers in parallel
|
||||
)
|
||||
# There are no additional create options for firmware update
|
||||
|
||||
# define the delete command
|
||||
delete_strategy_cmd = setup_delete_cmd(sub_cmds)
|
||||
# define the apply command
|
||||
apply_strategy_cmd = setup_apply_cmd(sub_cmds)
|
||||
# define the abort command
|
||||
abort_strategy_cmd = setup_abort_cmd(sub_cmds)
|
||||
# define the show command
|
||||
show_strategy_cmd = setup_show_cmd(sub_cmds)
|
||||
|
||||
|
||||
def setup_kube_upgrade_parser(commands):
|
||||
# Kubernetes Upgrade Commands
|
||||
kube_upgrade_parser = commands.add_parser('kube-upgrade-strategy',
|
||||
help='Kubernetes Upgrade Strategy')
|
||||
kube_upgrade_parser.set_defaults(cmd_area='kube-upgrade-strategy')
|
||||
"""Kubernetes Upgrade Strategy Commands"""
|
||||
|
||||
kube_upgrade_cmds = kube_upgrade_parser.add_subparsers(
|
||||
title='Kubernetes Upgrade Commands', metavar='')
|
||||
kube_upgrade_cmds.required = True
|
||||
cmd_area = 'kube-upgrade-strategy'
|
||||
register_strategy(cmd_area, sw_update.STRATEGY_NAME_KUBE_UPGRADE)
|
||||
cmd_parser = commands.add_parser(cmd_area,
|
||||
help='Kubernetes Upgrade Strategy')
|
||||
cmd_parser.set_defaults(cmd_area=cmd_area)
|
||||
|
||||
kube_upgrade_create_strategy_cmd \
|
||||
= kube_upgrade_cmds.add_parser('create', help='Create a strategy')
|
||||
kube_upgrade_create_strategy_cmd.set_defaults(cmd='create')
|
||||
kube_upgrade_create_strategy_cmd.add_argument('--controller-apply-type',
|
||||
default=sw_update.APPLY_TYPE_SERIAL,
|
||||
choices=[sw_update.APPLY_TYPE_SERIAL, sw_update.APPLY_TYPE_IGNORE],
|
||||
help='defaults to serial')
|
||||
kube_upgrade_create_strategy_cmd.add_argument('--storage-apply-type',
|
||||
default=sw_update.APPLY_TYPE_SERIAL,
|
||||
choices=[sw_update.APPLY_TYPE_SERIAL, sw_update.APPLY_TYPE_IGNORE],
|
||||
help='defaults to serial')
|
||||
kube_upgrade_create_strategy_cmd.add_argument('--worker-apply-type',
|
||||
default=sw_update.APPLY_TYPE_SERIAL,
|
||||
choices=[sw_update.APPLY_TYPE_SERIAL,
|
||||
sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
help='defaults to serial')
|
||||
sub_cmds = cmd_parser.add_subparsers(title='Kubernetes Upgrade Commands',
|
||||
metavar='')
|
||||
sub_cmds.required = True
|
||||
|
||||
kube_upgrade_create_strategy_cmd.add_argument(
|
||||
'--max-parallel-worker-hosts', type=int, choices=range(2, 6),
|
||||
help='maximum worker hosts to update in parallel')
|
||||
# define the create command
|
||||
create_strategy_cmd = setup_create_cmd(
|
||||
sub_cmds,
|
||||
[sw_update.APPLY_TYPE_SERIAL, # controller supports serial only
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
[sw_update.APPLY_TYPE_SERIAL, # storage supports serial only
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
[sw_update.APPLY_TYPE_SERIAL, # worker supports serial and parallel
|
||||
sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
[sw_update.INSTANCE_ACTION_STOP_START, # instance actions
|
||||
sw_update.INSTANCE_ACTION_MIGRATE],
|
||||
[sw_update.ALARM_RESTRICTIONS_STRICT, # alarm restrictions
|
||||
sw_update.ALARM_RESTRICTIONS_RELAXED],
|
||||
min_parallel=2,
|
||||
max_parallel=10 # kube upgrade supports 2..10 workers in parallel
|
||||
)
|
||||
|
||||
kube_upgrade_create_strategy_cmd.add_argument('--instance-action',
|
||||
default=sw_update.INSTANCE_ACTION_STOP_START,
|
||||
choices=[sw_update.INSTANCE_ACTION_MIGRATE,
|
||||
sw_update.INSTANCE_ACTION_STOP_START],
|
||||
help='defaults to stop-start')
|
||||
# add kube specific arguments to the create command
|
||||
# The get_extra_create_args method is updated to align with these
|
||||
# kube upgrade create requires 'to-version'
|
||||
create_strategy_cmd.add_argument(
|
||||
'--to-version',
|
||||
required=True,
|
||||
help='The kubernetes version')
|
||||
|
||||
kube_upgrade_create_strategy_cmd.add_argument('--alarm-restrictions',
|
||||
default=sw_update.ALARM_RESTRICTIONS_STRICT,
|
||||
choices=[sw_update.ALARM_RESTRICTIONS_STRICT,
|
||||
sw_update.ALARM_RESTRICTIONS_RELAXED],
|
||||
help='defaults to strict')
|
||||
# define the delete command
|
||||
delete_strategy_cmd = setup_delete_cmd(sub_cmds)
|
||||
# define the apply command
|
||||
apply_strategy_cmd = setup_apply_cmd(sub_cmds)
|
||||
# define the abort command
|
||||
abort_strategy_cmd = setup_abort_cmd(sub_cmds)
|
||||
# define the show command
|
||||
show_strategy_cmd = setup_show_cmd(sub_cmds)
|
||||
|
||||
kube_upgrade_create_strategy_cmd.add_argument(
|
||||
'--to-version', required=True, help='The kubernetes version')
|
||||
|
||||
kube_upgrade_delete_strategy_cmd \
|
||||
= kube_upgrade_cmds.add_parser('delete', help='Delete a strategy')
|
||||
kube_upgrade_delete_strategy_cmd.set_defaults(cmd='delete')
|
||||
kube_upgrade_delete_strategy_cmd.add_argument(
|
||||
'--force', action='store_true', help=argparse.SUPPRESS)
|
||||
def setup_patch_parser(commands):
|
||||
"""Patch Strategy Commands"""
|
||||
|
||||
kube_upgrade_apply_strategy_cmd \
|
||||
= kube_upgrade_cmds.add_parser('apply', help='Apply a strategy')
|
||||
kube_upgrade_apply_strategy_cmd.set_defaults(cmd='apply')
|
||||
kube_upgrade_apply_strategy_cmd.add_argument(
|
||||
'--stage-id', default=None, help='stage identifier to apply')
|
||||
cmd_area = 'patch-strategy'
|
||||
register_strategy(cmd_area, sw_update.STRATEGY_NAME_SW_PATCH)
|
||||
cmd_parser = commands.add_parser(cmd_area,
|
||||
help='Patch Strategy')
|
||||
cmd_parser.set_defaults(cmd_area=cmd_area)
|
||||
|
||||
kube_upgrade_abort_strategy_cmd \
|
||||
= kube_upgrade_cmds.add_parser('abort', help='Abort a strategy')
|
||||
kube_upgrade_abort_strategy_cmd.set_defaults(cmd='abort')
|
||||
kube_upgrade_abort_strategy_cmd.add_argument(
|
||||
'--stage-id', help='stage identifier to abort')
|
||||
sub_cmds = cmd_parser.add_subparsers(title='Software Patch Commands',
|
||||
metavar='')
|
||||
sub_cmds.required = True
|
||||
|
||||
kube_upgrade_show_strategy_cmd \
|
||||
= kube_upgrade_cmds.add_parser('show', help='Show a strategy')
|
||||
kube_upgrade_show_strategy_cmd.set_defaults(cmd='show')
|
||||
kube_upgrade_show_strategy_cmd.add_argument(
|
||||
'--details', action='store_true', help='show strategy details')
|
||||
# define the create command
|
||||
# alarm restrictions, defaults to strict
|
||||
create_strategy_cmd = setup_create_cmd(
|
||||
sub_cmds,
|
||||
[sw_update.APPLY_TYPE_SERIAL, # controller supports serial
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
[sw_update.APPLY_TYPE_SERIAL, # storage supports serial and parallel
|
||||
sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
[sw_update.APPLY_TYPE_SERIAL, # worker supports serial and parallel
|
||||
sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
[sw_update.INSTANCE_ACTION_STOP_START, # instance actions
|
||||
sw_update.INSTANCE_ACTION_MIGRATE],
|
||||
[sw_update.ALARM_RESTRICTIONS_STRICT, # alarm restrictions
|
||||
sw_update.ALARM_RESTRICTIONS_RELAXED],
|
||||
min_parallel=2,
|
||||
max_parallel=100 # patch supports 2..100 workers in parallel
|
||||
)
|
||||
|
||||
# define the delete command
|
||||
delete_strategy_cmd = setup_delete_cmd(sub_cmds)
|
||||
# define the apply command
|
||||
apply_strategy_cmd = setup_apply_cmd(sub_cmds)
|
||||
# define the abort command
|
||||
abort_strategy_cmd = setup_abort_cmd(sub_cmds)
|
||||
# define the show command
|
||||
show_strategy_cmd = setup_show_cmd(sub_cmds)
|
||||
|
||||
|
||||
def setup_upgrade_parser(commands):
|
||||
"""Upgrade Strategy Commands"""
|
||||
|
||||
cmd_area = 'upgrade-strategy'
|
||||
register_strategy(cmd_area, sw_update.STRATEGY_NAME_SW_UPGRADE)
|
||||
cmd_parser = commands.add_parser(cmd_area,
|
||||
help='Upgrade Strategy')
|
||||
cmd_parser.set_defaults(cmd_area=cmd_area)
|
||||
|
||||
sub_cmds = cmd_parser.add_subparsers(title='Software Upgrade Commands',
|
||||
metavar='')
|
||||
sub_cmds.required = True
|
||||
|
||||
# define the create command
|
||||
# alarm restrictions, defaults to strict
|
||||
create_strategy_cmd = setup_create_cmd(
|
||||
sub_cmds,
|
||||
[sw_update.APPLY_TYPE_SERIAL], # hard coded to serial
|
||||
[sw_update.APPLY_TYPE_SERIAL, # storage supports serial and parallel
|
||||
sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
[sw_update.APPLY_TYPE_SERIAL, # worker supports serial and parallel
|
||||
sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
[sw_update.INSTANCE_ACTION_MIGRATE], # hardcoded to migrate
|
||||
[sw_update.ALARM_RESTRICTIONS_STRICT, # alarm restrictions
|
||||
sw_update.ALARM_RESTRICTIONS_RELAXED],
|
||||
min_parallel=2,
|
||||
max_parallel=10 # upgrade supports 2..10 workers in parallel
|
||||
)
|
||||
|
||||
# add upgrade specific arguments to the create command
|
||||
# The get_extra_create_args method is updated to align with these
|
||||
|
||||
# Disable support for --start-upgrade as it was not completed
|
||||
# create_strategy_cmd.add_argument('--start-upgrade',
|
||||
# action='store_true',
|
||||
# help=argparse.SUPPRESS)
|
||||
|
||||
create_strategy_cmd.add_argument('--complete-upgrade',
|
||||
action='store_true',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
# define the delete command
|
||||
delete_strategy_cmd = setup_delete_cmd(sub_cmds)
|
||||
# define the apply command
|
||||
apply_strategy_cmd = setup_apply_cmd(sub_cmds)
|
||||
# define the abort command
|
||||
abort_strategy_cmd = setup_abort_cmd(sub_cmds)
|
||||
# define the show command
|
||||
show_strategy_cmd = setup_show_cmd(sub_cmds)
|
||||
|
||||
|
||||
def process_main(argv=sys.argv[1:]): # pylint: disable=dangerous-default-value
|
||||
|
@ -102,201 +393,18 @@ def process_main(argv=sys.argv[1:]): # pylint: disable=dangerous-default-value
|
|||
commands = parser.add_subparsers(title='Commands', metavar='')
|
||||
commands.required = True
|
||||
|
||||
# Software Patch Commands
|
||||
sw_patch_parser = commands.add_parser('patch-strategy',
|
||||
help='Patch Strategy')
|
||||
sw_patch_parser.set_defaults(cmd_area='patch-strategy')
|
||||
# Add firmware update strategy commands
|
||||
setup_fw_update_parser(commands)
|
||||
|
||||
sw_patch_cmds = sw_patch_parser.add_subparsers(
|
||||
title='Software Patch Commands', metavar='')
|
||||
sw_patch_cmds.required = True
|
||||
|
||||
sw_patch_create_strategy_cmd \
|
||||
= sw_patch_cmds.add_parser('create', help='Create a strategy')
|
||||
sw_patch_create_strategy_cmd.set_defaults(cmd='create')
|
||||
sw_patch_create_strategy_cmd.add_argument(
|
||||
'--controller-apply-type', default=sw_update.APPLY_TYPE_SERIAL,
|
||||
choices=[sw_update.APPLY_TYPE_SERIAL, sw_update.APPLY_TYPE_IGNORE],
|
||||
help='defaults to serial')
|
||||
sw_patch_create_strategy_cmd.add_argument(
|
||||
'--storage-apply-type', default=sw_update.APPLY_TYPE_SERIAL,
|
||||
choices=[sw_update.APPLY_TYPE_SERIAL, sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
help='defaults to serial')
|
||||
sw_patch_create_strategy_cmd.add_argument(
|
||||
'--worker-apply-type', default=sw_update.APPLY_TYPE_SERIAL,
|
||||
choices=[sw_update.APPLY_TYPE_SERIAL, sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
help='defaults to serial')
|
||||
sw_patch_create_strategy_cmd.add_argument(
|
||||
'--max-parallel-worker-hosts', type=int, choices=range(2, 101),
|
||||
help='maximum worker hosts to patch in parallel')
|
||||
sw_patch_create_strategy_cmd.add_argument(
|
||||
'--instance-action', default=sw_update.INSTANCE_ACTION_STOP_START,
|
||||
choices=[sw_update.INSTANCE_ACTION_MIGRATE,
|
||||
sw_update.INSTANCE_ACTION_STOP_START],
|
||||
help='defaults to stop-start')
|
||||
sw_patch_create_strategy_cmd.add_argument(
|
||||
'--alarm-restrictions', default=sw_update.ALARM_RESTRICTIONS_STRICT,
|
||||
choices=[sw_update.ALARM_RESTRICTIONS_STRICT,
|
||||
sw_update.ALARM_RESTRICTIONS_RELAXED],
|
||||
help='defaults to strict')
|
||||
|
||||
sw_patch_delete_strategy_cmd \
|
||||
= sw_patch_cmds.add_parser('delete', help='Delete a strategy')
|
||||
sw_patch_delete_strategy_cmd.set_defaults(cmd='delete')
|
||||
sw_patch_delete_strategy_cmd.add_argument(
|
||||
'--force', action='store_true', help=argparse.SUPPRESS)
|
||||
|
||||
sw_patch_apply_strategy_cmd \
|
||||
= sw_patch_cmds.add_parser('apply', help='Apply a strategy')
|
||||
sw_patch_apply_strategy_cmd.set_defaults(cmd='apply')
|
||||
sw_patch_apply_strategy_cmd.add_argument(
|
||||
'--stage-id', default=None, help='stage identifier to apply')
|
||||
|
||||
sw_patch_abort_strategy_cmd \
|
||||
= sw_patch_cmds.add_parser('abort', help='Abort a strategy')
|
||||
sw_patch_abort_strategy_cmd.set_defaults(cmd='abort')
|
||||
sw_patch_abort_strategy_cmd.add_argument(
|
||||
'--stage-id', help='stage identifier to abort')
|
||||
|
||||
sw_patch_show_strategy_cmd \
|
||||
= sw_patch_cmds.add_parser('show', help='Show a strategy')
|
||||
sw_patch_show_strategy_cmd.set_defaults(cmd='show')
|
||||
sw_patch_show_strategy_cmd.add_argument(
|
||||
'--details', action='store_true', help='show strategy details')
|
||||
|
||||
# Software Upgrade Commands
|
||||
sw_upgrade_parser = commands.add_parser('upgrade-strategy',
|
||||
help='Upgrade Strategy')
|
||||
sw_upgrade_parser.set_defaults(cmd_area='upgrade-strategy')
|
||||
|
||||
sw_upgrade_cmds = sw_upgrade_parser.add_subparsers(
|
||||
title='Software Upgrade Commands', metavar='')
|
||||
sw_upgrade_cmds.required = True
|
||||
|
||||
sw_upgrade_create_strategy_cmd \
|
||||
= sw_upgrade_cmds.add_parser('create', help='Create a strategy')
|
||||
sw_upgrade_create_strategy_cmd.set_defaults(cmd='create')
|
||||
sw_upgrade_create_strategy_cmd.add_argument(
|
||||
'--storage-apply-type', default=sw_update.APPLY_TYPE_SERIAL,
|
||||
choices=[sw_update.APPLY_TYPE_SERIAL, sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
help='defaults to serial')
|
||||
sw_upgrade_create_strategy_cmd.add_argument(
|
||||
'--worker-apply-type', default=sw_update.APPLY_TYPE_SERIAL,
|
||||
choices=[sw_update.APPLY_TYPE_SERIAL, sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
help='defaults to serial')
|
||||
sw_upgrade_create_strategy_cmd.add_argument(
|
||||
'--max-parallel-worker-hosts', type=int, choices=range(2, 11),
|
||||
help='maximum worker hosts to upgrade in parallel')
|
||||
# Disable support for --start-upgrade as it was not completed
|
||||
# sw_upgrade_create_strategy_cmd.add_argument(
|
||||
# '--start-upgrade', action='store_true',
|
||||
# help=argparse.SUPPRESS)
|
||||
sw_upgrade_create_strategy_cmd.add_argument(
|
||||
'--complete-upgrade', action='store_true', help=argparse.SUPPRESS)
|
||||
sw_upgrade_create_strategy_cmd.add_argument(
|
||||
'--alarm-restrictions', default=sw_update.ALARM_RESTRICTIONS_STRICT,
|
||||
choices=[sw_update.ALARM_RESTRICTIONS_STRICT,
|
||||
sw_update.ALARM_RESTRICTIONS_RELAXED],
|
||||
help='defaults to strict')
|
||||
|
||||
sw_upgrade_delete_strategy_cmd \
|
||||
= sw_upgrade_cmds.add_parser('delete', help='Delete a strategy')
|
||||
sw_upgrade_delete_strategy_cmd.set_defaults(cmd='delete')
|
||||
sw_upgrade_delete_strategy_cmd.add_argument(
|
||||
'--force', action='store_true', help=argparse.SUPPRESS)
|
||||
|
||||
sw_upgrade_apply_strategy_cmd \
|
||||
= sw_upgrade_cmds.add_parser('apply', help='Apply a strategy')
|
||||
sw_upgrade_apply_strategy_cmd.set_defaults(cmd='apply')
|
||||
sw_upgrade_apply_strategy_cmd.add_argument(
|
||||
'--stage-id', default=None, help='stage identifier to apply')
|
||||
|
||||
sw_upgrade_abort_strategy_cmd \
|
||||
= sw_upgrade_cmds.add_parser('abort', help='Abort a strategy')
|
||||
sw_upgrade_abort_strategy_cmd.set_defaults(cmd='abort')
|
||||
sw_upgrade_abort_strategy_cmd.add_argument(
|
||||
'--stage-id', help='stage identifier to abort')
|
||||
|
||||
sw_upgrade_show_strategy_cmd \
|
||||
= sw_upgrade_cmds.add_parser('show', help='Show a strategy')
|
||||
sw_upgrade_show_strategy_cmd.set_defaults(cmd='show')
|
||||
sw_upgrade_show_strategy_cmd.add_argument(
|
||||
'--details', action='store_true', help='show strategy details')
|
||||
|
||||
# Firmware Update Commands
|
||||
fw_update_parser = commands.add_parser('fw-update-strategy',
|
||||
help='Firmware Update Strategy')
|
||||
fw_update_parser.set_defaults(cmd_area='fw-update-strategy')
|
||||
|
||||
fw_update_cmds = fw_update_parser.add_subparsers(
|
||||
title='Firmware Update Commands', metavar='')
|
||||
fw_update_cmds.required = True
|
||||
|
||||
fw_update_create_strategy_cmd \
|
||||
= fw_update_cmds.add_parser('create', help='Create a strategy')
|
||||
fw_update_create_strategy_cmd.set_defaults(cmd='create')
|
||||
fw_update_create_strategy_cmd.add_argument('--controller-apply-type',
|
||||
default=sw_update.APPLY_TYPE_IGNORE,
|
||||
choices=[sw_update.APPLY_TYPE_IGNORE],
|
||||
help='defaults to ignore')
|
||||
fw_update_create_strategy_cmd.add_argument('--storage-apply-type',
|
||||
default=sw_update.APPLY_TYPE_IGNORE,
|
||||
choices=[sw_update.APPLY_TYPE_IGNORE],
|
||||
help='defaults to ignore')
|
||||
fw_update_create_strategy_cmd.add_argument('--worker-apply-type',
|
||||
default=sw_update.APPLY_TYPE_SERIAL,
|
||||
choices=[sw_update.APPLY_TYPE_SERIAL,
|
||||
sw_update.APPLY_TYPE_PARALLEL,
|
||||
sw_update.APPLY_TYPE_IGNORE],
|
||||
help='defaults to serial')
|
||||
|
||||
fw_update_create_strategy_cmd.add_argument(
|
||||
'--max-parallel-worker-hosts', type=int, choices=range(2, 6),
|
||||
help='maximum worker hosts to update in parallel')
|
||||
|
||||
fw_update_create_strategy_cmd.add_argument('--instance-action',
|
||||
default=sw_update.INSTANCE_ACTION_STOP_START,
|
||||
choices=[sw_update.INSTANCE_ACTION_MIGRATE,
|
||||
sw_update.INSTANCE_ACTION_STOP_START],
|
||||
help='defaults to stop-start')
|
||||
|
||||
fw_update_create_strategy_cmd.add_argument('--alarm-restrictions',
|
||||
default=sw_update.ALARM_RESTRICTIONS_STRICT,
|
||||
choices=[sw_update.ALARM_RESTRICTIONS_STRICT,
|
||||
sw_update.ALARM_RESTRICTIONS_RELAXED],
|
||||
help='defaults to strict')
|
||||
|
||||
fw_update_delete_strategy_cmd \
|
||||
= fw_update_cmds.add_parser('delete', help='Delete a strategy')
|
||||
fw_update_delete_strategy_cmd.set_defaults(cmd='delete')
|
||||
fw_update_delete_strategy_cmd.add_argument(
|
||||
'--force', action='store_true', help=argparse.SUPPRESS)
|
||||
|
||||
fw_update_apply_strategy_cmd \
|
||||
= fw_update_cmds.add_parser('apply', help='Apply a strategy')
|
||||
fw_update_apply_strategy_cmd.set_defaults(cmd='apply')
|
||||
fw_update_apply_strategy_cmd.add_argument(
|
||||
'--stage-id', default=None, help='stage identifier to apply')
|
||||
|
||||
fw_update_abort_strategy_cmd \
|
||||
= fw_update_cmds.add_parser('abort', help='Abort a strategy')
|
||||
fw_update_abort_strategy_cmd.set_defaults(cmd='abort')
|
||||
fw_update_abort_strategy_cmd.add_argument(
|
||||
'--stage-id', help='stage identifier to abort')
|
||||
|
||||
fw_update_show_strategy_cmd \
|
||||
= fw_update_cmds.add_parser('show', help='Show a strategy')
|
||||
fw_update_show_strategy_cmd.set_defaults(cmd='show')
|
||||
fw_update_show_strategy_cmd.add_argument(
|
||||
'--details', action='store_true', help='show strategy details')
|
||||
|
||||
# Register kubernetes upgrade command parser
|
||||
# Add kubernetes upgrade strategy commands
|
||||
setup_kube_upgrade_parser(commands)
|
||||
|
||||
# Add software patch strategy commands
|
||||
setup_patch_parser(commands)
|
||||
|
||||
# Add software upgrade strategy commands
|
||||
setup_upgrade_parser(commands)
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
if args.debug:
|
||||
|
@ -362,261 +470,74 @@ def process_main(argv=sys.argv[1:]): # pylint: disable=dangerous-default-value
|
|||
print("Openstack interface not given")
|
||||
return
|
||||
|
||||
if 'patch-strategy' == args.cmd_area:
|
||||
if 'create' == args.cmd:
|
||||
sw_update.create_strategy(
|
||||
args.os_auth_url, args.os_project_name,
|
||||
args.os_project_domain_name, args.os_username, args.os_password,
|
||||
args.os_user_domain_name, args.os_region_name,
|
||||
args.os_interface,
|
||||
sw_update.STRATEGY_NAME_SW_PATCH,
|
||||
args.controller_apply_type,
|
||||
args.storage_apply_type, sw_update.APPLY_TYPE_IGNORE,
|
||||
args.worker_apply_type,
|
||||
args.max_parallel_worker_hosts,
|
||||
args.instance_action,
|
||||
args.alarm_restrictions)
|
||||
|
||||
elif 'delete' == args.cmd:
|
||||
sw_update.delete_strategy(args.os_auth_url, args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username, args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name, args.os_interface,
|
||||
sw_update.STRATEGY_NAME_SW_PATCH,
|
||||
args.force)
|
||||
|
||||
elif 'apply' == args.cmd:
|
||||
sw_update.apply_strategy(args.os_auth_url, args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username, args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name, args.os_interface,
|
||||
sw_update.STRATEGY_NAME_SW_PATCH,
|
||||
args.stage_id)
|
||||
|
||||
elif 'abort' == args.cmd:
|
||||
sw_update.abort_strategy(args.os_auth_url, args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username, args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name, args.os_interface,
|
||||
sw_update.STRATEGY_NAME_SW_PATCH,
|
||||
args.stage_id)
|
||||
|
||||
elif 'show' == args.cmd:
|
||||
sw_update.show_strategy(args.os_auth_url, args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username, args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name, args.os_interface,
|
||||
sw_update.STRATEGY_NAME_SW_PATCH,
|
||||
args.details)
|
||||
|
||||
else:
|
||||
raise ValueError("Unknown command, %s, given for patch-strategy"
|
||||
% args.cmd)
|
||||
elif 'upgrade-strategy' == args.cmd_area:
|
||||
if 'create' == args.cmd:
|
||||
sw_update.create_strategy(
|
||||
args.os_auth_url, args.os_project_name,
|
||||
args.os_project_domain_name, args.os_username, args.os_password,
|
||||
args.os_user_domain_name, args.os_region_name,
|
||||
args.os_interface,
|
||||
sw_update.STRATEGY_NAME_SW_UPGRADE,
|
||||
sw_update.APPLY_TYPE_IGNORE,
|
||||
args.storage_apply_type, sw_update.APPLY_TYPE_IGNORE,
|
||||
args.worker_apply_type,
|
||||
args.max_parallel_worker_hosts,
|
||||
None, args.alarm_restrictions,
|
||||
# start_upgrade=args.start_upgrade,
|
||||
complete_upgrade=args.complete_upgrade
|
||||
)
|
||||
|
||||
elif 'delete' == args.cmd:
|
||||
sw_update.delete_strategy(args.os_auth_url, args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username, args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name, args.os_interface,
|
||||
sw_update.STRATEGY_NAME_SW_UPGRADE,
|
||||
args.force)
|
||||
|
||||
elif 'apply' == args.cmd:
|
||||
sw_update.apply_strategy(args.os_auth_url, args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username, args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name, args.os_interface,
|
||||
sw_update.STRATEGY_NAME_SW_UPGRADE,
|
||||
args.stage_id)
|
||||
|
||||
elif 'abort' == args.cmd:
|
||||
sw_update.abort_strategy(args.os_auth_url, args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username, args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name, args.os_interface,
|
||||
sw_update.STRATEGY_NAME_SW_UPGRADE,
|
||||
args.stage_id)
|
||||
|
||||
elif 'show' == args.cmd:
|
||||
sw_update.show_strategy(args.os_auth_url, args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username, args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name, args.os_interface,
|
||||
sw_update.STRATEGY_NAME_SW_UPGRADE,
|
||||
args.details)
|
||||
|
||||
else:
|
||||
raise ValueError("Unknown command, %s, given for upgrade-strategy"
|
||||
% args.cmd)
|
||||
elif 'fw-update-strategy' == args.cmd_area:
|
||||
if 'create' == args.cmd:
|
||||
sw_update.create_strategy(
|
||||
args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
sw_update.STRATEGY_NAME_FW_UPDATE,
|
||||
args.controller_apply_type,
|
||||
args.storage_apply_type,
|
||||
sw_update.APPLY_TYPE_IGNORE,
|
||||
args.worker_apply_type,
|
||||
args.max_parallel_worker_hosts,
|
||||
args.instance_action,
|
||||
args.alarm_restrictions)
|
||||
|
||||
elif 'delete' == args.cmd:
|
||||
sw_update.delete_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
sw_update.STRATEGY_NAME_FW_UPDATE,
|
||||
args.force)
|
||||
|
||||
elif 'apply' == args.cmd:
|
||||
sw_update.apply_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
sw_update.STRATEGY_NAME_FW_UPDATE,
|
||||
args.stage_id)
|
||||
|
||||
elif 'abort' == args.cmd:
|
||||
sw_update.abort_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
sw_update.STRATEGY_NAME_FW_UPDATE,
|
||||
args.stage_id)
|
||||
|
||||
elif 'show' == args.cmd:
|
||||
sw_update.show_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
sw_update.STRATEGY_NAME_FW_UPDATE,
|
||||
args.details)
|
||||
else:
|
||||
raise ValueError("Unknown command, %s, "
|
||||
"given for fw-update-strategy"
|
||||
% args.cmd)
|
||||
elif 'kube-upgrade-strategy' == args.cmd_area:
|
||||
strategy_type = sw_update.STRATEGY_NAME_KUBE_UPGRADE
|
||||
if 'create' == args.cmd:
|
||||
sw_update.create_strategy(
|
||||
args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
strategy_type,
|
||||
args.controller_apply_type,
|
||||
args.storage_apply_type,
|
||||
sw_update.APPLY_TYPE_IGNORE,
|
||||
args.worker_apply_type,
|
||||
args.max_parallel_worker_hosts,
|
||||
args.instance_action,
|
||||
args.alarm_restrictions,
|
||||
to_version=args.to_version)
|
||||
|
||||
elif 'delete' == args.cmd:
|
||||
sw_update.delete_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
strategy_type,
|
||||
args.force)
|
||||
|
||||
elif 'apply' == args.cmd:
|
||||
sw_update.apply_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
strategy_type,
|
||||
args.stage_id)
|
||||
|
||||
elif 'abort' == args.cmd:
|
||||
sw_update.abort_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
strategy_type,
|
||||
args.stage_id)
|
||||
|
||||
elif 'show' == args.cmd:
|
||||
sw_update.show_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
strategy_type,
|
||||
args.details)
|
||||
else:
|
||||
raise ValueError("Unknown command, %s , given for %s"
|
||||
% args.cmd, args.cmd_area)
|
||||
strategy_name = get_strategy_name(args.cmd_area)
|
||||
if 'create' == args.cmd:
|
||||
extra_create_args = get_extra_create_args(args.cmd_area, args)
|
||||
sw_update.create_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
strategy_name,
|
||||
args.controller_apply_type,
|
||||
args.storage_apply_type,
|
||||
sw_update.APPLY_TYPE_IGNORE,
|
||||
args.worker_apply_type,
|
||||
args.max_parallel_worker_hosts,
|
||||
args.instance_action,
|
||||
args.alarm_restrictions,
|
||||
**extra_create_args)
|
||||
elif 'delete' == args.cmd:
|
||||
sw_update.delete_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
strategy_name,
|
||||
force=args.force)
|
||||
elif 'apply' == args.cmd:
|
||||
sw_update.apply_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
strategy_name,
|
||||
stage_id=args.stage_id)
|
||||
elif 'abort' == args.cmd:
|
||||
sw_update.abort_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
strategy_name,
|
||||
stage_id=args.stage_id)
|
||||
elif 'show' == args.cmd:
|
||||
sw_update.show_strategy(args.os_auth_url,
|
||||
args.os_project_name,
|
||||
args.os_project_domain_name,
|
||||
args.os_username,
|
||||
args.os_password,
|
||||
args.os_user_domain_name,
|
||||
args.os_region_name,
|
||||
args.os_interface,
|
||||
strategy_name,
|
||||
details=args.details,
|
||||
active=args.active)
|
||||
else:
|
||||
raise ValueError("Unknown command area, %s, given" % args.cmd_area)
|
||||
raise ValueError("Unknown command, %s, given for %s"
|
||||
% (args.cmd, args.cmd_area))
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("Keyboard Interrupt received.")
|
||||
|
|
|
@ -28,10 +28,16 @@ def _print(indent_by, field, value, remains=''):
|
|||
remains))
|
||||
|
||||
|
||||
def _display_strategy_step(strategy_step):
|
||||
def _display_strategy_step(strategy_step, active=False):
|
||||
"""
|
||||
Software Update - Display Strategy Step Information
|
||||
"""
|
||||
# If active flag is passed
|
||||
# skip steps that are not started:'initial' or completed cleanly: 'success'
|
||||
# this leaves failed and in-progress states
|
||||
if active:
|
||||
if strategy_step.result in ['initial', 'success']:
|
||||
return False
|
||||
_print(12, "step-id", strategy_step.step_id)
|
||||
_print(12, "step-name", strategy_step.step_name)
|
||||
if 0 < len(strategy_step.entity_type):
|
||||
|
@ -47,12 +53,17 @@ def _display_strategy_step(strategy_step):
|
|||
_print(12, "end-date-time", strategy_step.end_date_time)
|
||||
_print(12, "result", strategy_step.result)
|
||||
_print(12, "reason", strategy_step.reason)
|
||||
return True
|
||||
|
||||
|
||||
def _display_strategy_stage(strategy_stage, details=False):
|
||||
def _display_strategy_stage(strategy_stage, details=False, active=False):
|
||||
"""
|
||||
Software Update - Display Strategy Stage Information
|
||||
"""
|
||||
# If active flag is passed, only display a stage that is in progress
|
||||
if active:
|
||||
if not strategy_stage.inprogress:
|
||||
return False
|
||||
_print(8, "stage-id", strategy_stage.stage_id)
|
||||
_print(8, "stage-name", strategy_stage.stage_name)
|
||||
_print(8, "total-steps", strategy_stage.total_steps)
|
||||
|
@ -66,17 +77,22 @@ def _display_strategy_stage(strategy_stage, details=False):
|
|||
_print(8, "result", strategy_stage.result)
|
||||
_print(8, "reason", strategy_stage.reason)
|
||||
|
||||
if details:
|
||||
if details or active:
|
||||
print(" steps:")
|
||||
for step in strategy_stage.steps:
|
||||
_display_strategy_step(step)
|
||||
print("")
|
||||
if _display_strategy_step(step, active):
|
||||
print("")
|
||||
return True
|
||||
|
||||
|
||||
def _display_strategy_phase(strategy_phase, details=False):
|
||||
def _display_strategy_phase(strategy_phase, details=False, active=False):
|
||||
"""
|
||||
Software Update - Display Strategy Phase Information
|
||||
"""
|
||||
# If active flag is passed, only display a phase that is in progress
|
||||
if active:
|
||||
if not strategy_phase.inprogress:
|
||||
return
|
||||
print(" %s-phase:" % strategy_phase.phase_name)
|
||||
_print(4, "total-stages", strategy_phase.total_stages)
|
||||
_print(4, "current-stage", strategy_phase.current_stage)
|
||||
|
@ -92,14 +108,14 @@ def _display_strategy_phase(strategy_phase, details=False):
|
|||
_print(4, "result", strategy_phase.result)
|
||||
_print(4, "reason", strategy_phase.reason)
|
||||
|
||||
if details:
|
||||
if details or active:
|
||||
print(" stages:")
|
||||
for stage in strategy_phase.stages:
|
||||
_display_strategy_stage(stage, details)
|
||||
print("")
|
||||
if _display_strategy_stage(stage, details, active):
|
||||
print("")
|
||||
|
||||
|
||||
def _display_strategy(strategy, details=False):
|
||||
def _display_strategy(strategy, details=False, active=False):
|
||||
"""
|
||||
Software Update - Display Strategy Information
|
||||
"""
|
||||
|
@ -128,15 +144,15 @@ def _display_strategy(strategy, details=False):
|
|||
("%s%%" % strategy.current_phase_completion_percentage))
|
||||
_print(2, "state", strategy.state)
|
||||
|
||||
if details:
|
||||
if details or active:
|
||||
if 0 < strategy.build_phase.total_stages:
|
||||
_display_strategy_phase(strategy.build_phase, details)
|
||||
_display_strategy_phase(strategy.build_phase, details, active)
|
||||
|
||||
if 0 < strategy.apply_phase.total_stages:
|
||||
_display_strategy_phase(strategy.apply_phase, details)
|
||||
_display_strategy_phase(strategy.apply_phase, details, active)
|
||||
|
||||
if 0 < strategy.abort_phase.total_stages:
|
||||
_display_strategy_phase(strategy.abort_phase, details)
|
||||
_display_strategy_phase(strategy.abort_phase, details, active)
|
||||
else:
|
||||
if strategy.current_phase == strategy.build_phase.phase_name:
|
||||
if strategy.build_phase.inprogress:
|
||||
|
@ -276,7 +292,7 @@ def abort_strategy(os_auth_uri, os_project_name, os_project_domain_name,
|
|||
|
||||
def show_strategy(os_auth_uri, os_project_name, os_project_domain_name,
|
||||
os_username, os_password, os_user_domain_name, os_region_name,
|
||||
os_interface, strategy_name, details=False):
|
||||
os_interface, strategy_name, details=False, active=False):
|
||||
"""
|
||||
Software Update - Show Strategy
|
||||
"""
|
||||
|
@ -295,4 +311,4 @@ def show_strategy(os_auth_uri, os_project_name, os_project_domain_name,
|
|||
print("No strategy available")
|
||||
return
|
||||
|
||||
_display_strategy(strategy, details)
|
||||
_display_strategy(strategy, details, active)
|
||||
|
|
|
@ -89,7 +89,7 @@ function _swmanager()
|
|||
;;
|
||||
show)
|
||||
if [ "${prev}" = "${action}" ]; then
|
||||
COMPREPLY=($(compgen -W "--details" -- ${cur}))
|
||||
COMPREPLY=($(compgen -W "--details --active" -- ${cur}))
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
|
@ -160,7 +160,7 @@ function _swmanager()
|
|||
;;
|
||||
show)
|
||||
if [ "${prev}" = "${action}" ]; then
|
||||
COMPREPLY=($(compgen -W "--details" -- ${cur}))
|
||||
COMPREPLY=($(compgen -W "--details --active" -- ${cur}))
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
|
@ -237,7 +237,7 @@ function _swmanager()
|
|||
;;
|
||||
show)
|
||||
if [ "${prev}" = "${action}" ]; then
|
||||
COMPREPLY=($(compgen -W "--details" -- ${cur}))
|
||||
COMPREPLY=($(compgen -W "--details --active" -- ${cur}))
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
|
@ -319,7 +319,7 @@ function _swmanager()
|
|||
;;
|
||||
show)
|
||||
if [ "${prev}" = "${action}" ]; then
|
||||
COMPREPLY=($(compgen -W "--details" -- ${cur}))
|
||||
COMPREPLY=($(compgen -W "--details --active" -- ${cur}))
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
import copy
|
||||
import mock
|
||||
import os
|
||||
|
||||
|
@ -34,6 +35,15 @@ class TestNFVClientShell(testcase.NFVTestCase):
|
|||
mock_usage.assert_called_once()
|
||||
mock_message.assert_called_once()
|
||||
|
||||
# --- Help Cases ----
|
||||
# -h will print_help and SystemExit
|
||||
@mock.patch('argparse.ArgumentParser.print_help')
|
||||
def _test_shell_help(self, mock_help=None, shell_args=None):
|
||||
self.assertRaises(SystemExit, shell.process_main, shell_args)
|
||||
mock_help.assert_called_once()
|
||||
|
||||
|
||||
class TestNFVClientShellRobustness(TestNFVClientShell):
|
||||
# invalid arguments causes process_main to exit
|
||||
def test_shell_bad_args(self):
|
||||
shell_args = ['invalid-arg', ]
|
||||
|
@ -44,86 +54,221 @@ class TestNFVClientShell(testcase.NFVTestCase):
|
|||
shell_args = []
|
||||
self._test_shell_bad_or_empty_args(shell_args=shell_args)
|
||||
|
||||
# upgrade-strategy expects additional arguments
|
||||
def test_shell_upgrade_strategy_incomplete_args(self):
|
||||
shell_args = ['upgrade-strategy', ]
|
||||
self._test_shell_bad_or_empty_args(shell_args=shell_args)
|
||||
|
||||
# patch-strategy expects additional arguments
|
||||
def test_shell_patch_strategy_incomplete_args(self):
|
||||
shell_args = ['patch-strategy', ]
|
||||
self._test_shell_bad_or_empty_args(shell_args=shell_args)
|
||||
class StrategyMixin(object):
|
||||
|
||||
# fw-update-strategy expects additional arguments
|
||||
def test_shell_fw_update_strategy_incomplete_args(self):
|
||||
shell_args = ['fw-update-strategy', ]
|
||||
self._test_shell_bad_or_empty_args(shell_args=shell_args)
|
||||
MOCK_ENV = {
|
||||
'OS_AUTH_URL': 'FAKE_OS_AUTH_URL',
|
||||
'OS_PROJECT_NAME': 'FAKE_OS_PROJECT_NAME',
|
||||
'OS_PROJECT_DOMAIN_NAME': 'FAKE_OS_PROJECT_DOMAIN_NAME',
|
||||
'OS_USERNAME': 'FAKE_OS_USERNAME',
|
||||
'OS_PASSWORD': 'FAKE_OS_PASSWORD',
|
||||
'OS_USER_DOMAIN_NAME': 'FAKE_OS_USER_DOMAIN_NAME',
|
||||
'OS_REGION_NAME': 'FAKE_OS_REGION_NAME',
|
||||
'OS_INTERFACE': 'FAKE_OS_INTERFACE'
|
||||
}
|
||||
|
||||
# --- Help Cases ----
|
||||
# -h will print_help and SystemExit
|
||||
@mock.patch('argparse.ArgumentParser.print_help')
|
||||
def _test_shell_help(self, mock_help=None, shell_args=None):
|
||||
self.assertRaises(SystemExit, shell.process_main, shell_args)
|
||||
mock_help.assert_called_once()
|
||||
MOCK_ENV_OVERRIDES = {
|
||||
'OS_AUTH_URL': '--os-auth-url=FAKE_OS_AUTH_URL',
|
||||
'OS_PROJECT_NAME': '--os-project-name=FAKE_OS_PROJECT_NAME',
|
||||
'OS_PROJECT_DOMAIN_NAME':
|
||||
'--os-project-domain-name=FAKE_OS_PROJECT_DOMAIN_NAME',
|
||||
'OS_USERNAME': '--os-username=FAKE_OS_USERNAME',
|
||||
'OS_PASSWORD': '--os-password=FAKE_OS_PASSWORD',
|
||||
'OS_USER_DOMAIN_NAME':
|
||||
'--os-user-domain-name=FAKE_OS_USER_DOMAIN_NAME',
|
||||
'OS_REGION_NAME': '--os-region-name=FAKE_OS_REGION_NAME',
|
||||
'OS_INTERFACE': '--os-interface=FAKE_OS_INTERFACE'
|
||||
}
|
||||
|
||||
def test_shell_upgrade_strategy_help(self):
|
||||
shell_args = ['upgrade-strategy', '-h', ]
|
||||
self._test_shell_help(shell_args=shell_args)
|
||||
def set_strategy(self, strategy):
|
||||
"""Invoked by the child class setupmethod to set the strategy"""
|
||||
self.strategy = strategy
|
||||
|
||||
def test_shell_patch_strategy_help(self):
|
||||
shell_args = ['patch-strategy', '-h', ]
|
||||
self._test_shell_help(shell_args=shell_args)
|
||||
def required_create_fields(self):
|
||||
"""Override in the child class if create has required fields"""
|
||||
return []
|
||||
|
||||
def test_shell_fw_update_strategy_help(self):
|
||||
shell_args = ['fw-update-strategy', '-h', ]
|
||||
self._test_shell_help(shell_args=shell_args)
|
||||
def optional_create_fields(self):
|
||||
"""Override in the child class if create has optional fields"""
|
||||
return []
|
||||
|
||||
# -- Show commands --
|
||||
# Both patch-strategy and upgrade-strategy use the same underlying
|
||||
# sw_update class, but with different modes
|
||||
|
||||
# The strategy commands use the same underling sw_update class, but
|
||||
# but with different modes
|
||||
# Test the show commands are not invoked when env values missing
|
||||
@mock.patch('nfv_client.sw_update.show_strategy')
|
||||
def _test_shell_show_missing_env(self, mock_show=None, shell_args=None):
|
||||
shell.process_main(shell_args)
|
||||
mock_show.assert_not_called()
|
||||
|
||||
def test_shell_upgrade_strategy_show_missing_env(self):
|
||||
shell_args = ['upgrade-strategy', 'show', ]
|
||||
self._test_shell_show_missing_env(shell_args=shell_args)
|
||||
|
||||
def test_shell_patch_strategy_show_missing_env(self):
|
||||
shell_args = ['patch-strategy', 'show', ]
|
||||
self._test_shell_show_missing_env(shell_args=shell_args)
|
||||
|
||||
def test_shell_fw_update_strategy_show_missing_env(self):
|
||||
shell_args = ['fw-update-strategy', 'show', ]
|
||||
self._test_shell_show_missing_env(shell_args=shell_args)
|
||||
|
||||
# Test the show commands are invoked when env values detected
|
||||
@mock.patch.dict(os.environ,
|
||||
{'OS_AUTH_URL': 'FAKE_OS_AUTH_URL',
|
||||
'OS_PROJECT_NAME': 'FAKE_OS_PROJECT_NAME',
|
||||
'OS_PROJECT_DOMAIN_NAME': 'FAKE_OS_PROJECT_DOMAIN_NAME',
|
||||
'OS_USERNAME': 'FAKE_OS_USERNAME',
|
||||
'OS_PASSWORD': 'FAKE_OS_PASSWORD',
|
||||
'OS_USER_DOMAIN_NAME': 'FAKE_OS_USER_DOMAIN_NAME',
|
||||
'OS_REGION_NAME': 'FAKE_OS_REGION_NAME',
|
||||
'OS_INTERFACE': 'FAKE_OS_INTERFACE'
|
||||
})
|
||||
@mock.patch('nfv_client.sw_update.show_strategy')
|
||||
def _test_shell_show(self, mock_show=None, shell_args=None):
|
||||
shell.process_main(shell_args)
|
||||
with mock.patch.dict(os.environ, self.MOCK_ENV):
|
||||
shell.process_main(shell_args)
|
||||
mock_show.assert_called_once()
|
||||
|
||||
def test_shell_upgrade_strategy_show(self):
|
||||
shell_args = ['upgrade-strategy', 'show', ]
|
||||
@mock.patch('nfv_client.sw_update.show_strategy')
|
||||
def _test_shell_show_incomplete_env(self,
|
||||
mock_show=None,
|
||||
shell_args=None,
|
||||
pop_env=None,
|
||||
expect_fails=True):
|
||||
# setup a mostly complete environment
|
||||
test_env = copy.copy(self.MOCK_ENV)
|
||||
test_env.pop(pop_env)
|
||||
with mock.patch.dict(os.environ, test_env):
|
||||
shell.process_main(shell_args)
|
||||
if expect_fails:
|
||||
mock_show.assert_not_called()
|
||||
else:
|
||||
mock_show.assert_called_once()
|
||||
|
||||
def test_shell_strategy_missing_subcommand(self):
|
||||
"""Test the strategy fails with a missing subcommand"""
|
||||
shell_args = [self.strategy, ]
|
||||
self._test_shell_bad_or_empty_args(shell_args=shell_args)
|
||||
|
||||
def test_shell_strategy_invalid_subcommand(self):
|
||||
"""Test the strategy fails with an invalid subcommand"""
|
||||
shell_args = [self.strategy, 'foo']
|
||||
self._test_shell_bad_or_empty_args(shell_args=shell_args)
|
||||
|
||||
def test_shell_strategy_help(self):
|
||||
"""Test the strategy supports the help subcommand"""
|
||||
shell_args = [self.strategy, '-h', ]
|
||||
self._test_shell_help(shell_args=shell_args)
|
||||
|
||||
def test_shell_strategy_show_incomplete_env(self):
|
||||
"""Test that if any required env variable is missing, it fails"""
|
||||
shell_args = [self.strategy, 'show', ]
|
||||
for pop_env in self.MOCK_ENV.keys():
|
||||
# remove the pop_env variable from the environment
|
||||
self._test_shell_show_incomplete_env(shell_args=shell_args,
|
||||
pop_env=pop_env)
|
||||
|
||||
def test_shell_strategy_show_env_overrides(self):
|
||||
"""
|
||||
Tests that passing certain values to the CLI override the env and
|
||||
that removing that value from the env will not cause failure
|
||||
"""
|
||||
for env_val, override_val in self.MOCK_ENV_OVERRIDES.items():
|
||||
shell_args = [override_val, self.strategy, 'show', ]
|
||||
self._test_shell_show_incomplete_env(shell_args=shell_args,
|
||||
pop_env=env_val,
|
||||
expect_fails=False)
|
||||
|
||||
def test_shell_strategy_show(self):
|
||||
shell_args = [self.strategy, 'show', ]
|
||||
self._test_shell_show(shell_args=shell_args)
|
||||
|
||||
def test_shell_patch_strategy_show(self):
|
||||
shell_args = ['patch-strategy', 'show', ]
|
||||
def test_shell_strategy_show_bad_extra_arg(self):
|
||||
shell_args = [self.strategy, 'show', '--bad']
|
||||
self._test_shell_bad_or_empty_args(shell_args=shell_args)
|
||||
|
||||
def test_shell_strategy_show_debug(self):
|
||||
shell_args = ["--debug", self.strategy, 'show']
|
||||
self._test_shell_show(shell_args=shell_args)
|
||||
|
||||
def test_shell_fw_update_strategy_show(self):
|
||||
shell_args = ['fw-update-strategy', 'show', ]
|
||||
def test_shell_strategy_show_details(self):
|
||||
shell_args = [self.strategy, 'show', '--details']
|
||||
self._test_shell_show(shell_args=shell_args)
|
||||
|
||||
def test_shell_strategy_show_active(self):
|
||||
shell_args = [self.strategy, 'show', '--active']
|
||||
self._test_shell_show(shell_args=shell_args)
|
||||
|
||||
def test_shell_strategy_show_active_details(self):
|
||||
shell_args = [self.strategy, 'show', '--details', '--active']
|
||||
self._test_shell_show(shell_args=shell_args)
|
||||
|
||||
# -- Abort command --
|
||||
# Test the abort command can be invoked. Requires the env to be set
|
||||
@mock.patch('nfv_client.sw_update.abort_strategy')
|
||||
def _test_shell_abort(self, mock_abort=None, shell_args=None):
|
||||
with mock.patch.dict(os.environ, self.MOCK_ENV):
|
||||
shell.process_main(shell_args)
|
||||
mock_abort.assert_called_once()
|
||||
|
||||
def test_shell_strategy_abort(self):
|
||||
shell_args = [self.strategy, 'abort']
|
||||
self._test_shell_abort(shell_args=shell_args)
|
||||
|
||||
# -- Apply command --
|
||||
# Test the apply command can be invoked. Requires the env to be set
|
||||
@mock.patch('nfv_client.sw_update.apply_strategy')
|
||||
def _test_shell_apply(self, mock_apply=None, shell_args=None):
|
||||
with mock.patch.dict(os.environ, self.MOCK_ENV):
|
||||
shell.process_main(shell_args)
|
||||
mock_apply.assert_called_once()
|
||||
|
||||
def test_shell_strategy_apply(self):
|
||||
shell_args = [self.strategy, 'apply']
|
||||
self._test_shell_apply(shell_args=shell_args)
|
||||
|
||||
# -- Delete command --
|
||||
# Test the delete command can be invoked. Requires the env to be set
|
||||
@mock.patch('nfv_client.sw_update.delete_strategy')
|
||||
def _test_shell_delete(self, mock_delete=None, shell_args=None):
|
||||
with mock.patch.dict(os.environ, self.MOCK_ENV):
|
||||
shell.process_main(shell_args)
|
||||
mock_delete.assert_called_once()
|
||||
|
||||
def test_shell_strategy_delete(self):
|
||||
shell_args = [self.strategy, 'delete']
|
||||
self._test_shell_delete(shell_args=shell_args)
|
||||
|
||||
# -- Create command --
|
||||
# Test the create command can be invoked. Requires the env to be set
|
||||
@mock.patch('nfv_client.sw_update.create_strategy')
|
||||
def _test_shell_create(self, mock_create=None, shell_args=None):
|
||||
with mock.patch.dict(os.environ, self.MOCK_ENV):
|
||||
shell.process_main(shell_args)
|
||||
mock_create.assert_called_once()
|
||||
|
||||
# -- Create command --
|
||||
def test_shell_strategy_create(self):
|
||||
shell_args = [self.strategy, 'create']
|
||||
# create may have 'required' additional fields
|
||||
shell_args.extend(self.required_create_fields())
|
||||
self._test_shell_create(shell_args=shell_args)
|
||||
|
||||
def test_shell_strategy_create_optional(self):
|
||||
shell_args = [self.strategy, 'create']
|
||||
# create may have 'required' additional fields and optional ones
|
||||
shell_args.extend(self.required_create_fields())
|
||||
shell_args.extend(self.optional_create_fields())
|
||||
self._test_shell_create(shell_args=shell_args)
|
||||
|
||||
|
||||
class TestCLIUpgradeStrategy(TestNFVClientShell,
|
||||
StrategyMixin):
|
||||
def setUp(self):
|
||||
super(TestCLIUpgradeStrategy, self).setUp()
|
||||
self.set_strategy('upgrade-strategy')
|
||||
|
||||
|
||||
class TestCLIPatchStrategy(TestNFVClientShell,
|
||||
StrategyMixin):
|
||||
def setUp(self):
|
||||
super(TestCLIPatchStrategy, self).setUp()
|
||||
self.set_strategy('patch-strategy')
|
||||
|
||||
|
||||
class TestCLIFwUpdateStrategy(TestNFVClientShell,
|
||||
StrategyMixin):
|
||||
def setUp(self):
|
||||
super(TestCLIFwUpdateStrategy, self).setUp()
|
||||
self.set_strategy('fw-update-strategy')
|
||||
|
||||
|
||||
class TestCLIKubeUpgradeStrategy(TestNFVClientShell,
|
||||
StrategyMixin):
|
||||
def setUp(self):
|
||||
super(TestCLIKubeUpgradeStrategy, self).setUp()
|
||||
self.set_strategy('kube-upgrade-strategy')
|
||||
|
||||
def required_create_fields(self):
|
||||
"""Kube Upgrade requires a to-version for create"""
|
||||
return ['--to-version=1.2.3']
|
||||
|
|
Loading…
Reference in New Issue