Display prestage status and versions in subcloud list
The prestage release can be either the previous or current release for a subcloud. Checking the prestage release individually on thousands of subclouds is impractical. Therefore, a new column called "prestage versions" is added to the output of the "dcmanager subcloud list' command. Besides, decoupling prestage status from deploy status. This commit also introduces the following changes: - 'backup datetime' column removal and addition of 'prestage status' column to 'dcmanager subcloud list' output. - 'dcmanager subcloud show' and similar commands now display 'prestage status' and 'prestage versions' columns in their output. - New '-d/--detail' option is added to 'dcmanager subcloud list' to display all columns of the subclouds. - '-c/--column' option of 'dcmanager subcloud list' can be used to specify the column(s) of the subclouds. eg. -c column1 -c column2 ... Test plan: PASS: Verify the correct "prestage status" and "prestage versions" output of the "dcmanager subcloud list" command. PASS: Verify the correct output of the new arguments -d/--detail and -c/--column. Depends-On: https://review.opendev.org/c/starlingx/distcloud/+/904541 Story: 2010611 Task: 49369 Change-Id: I8d127220fcd705dca542afeca2ac8f19f20172a1 Signed-off-by: lzhu1 <li.zhu@windriver.com>
This commit is contained in:
parent
c9e03caa9d
commit
eb4e7eeeb0
|
@ -1,5 +1,5 @@
|
|||
# Copyright (c) 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.
|
||||
|
@ -53,6 +53,8 @@ class Subcloud(Resource):
|
|||
'backup-status': 'backup_status',
|
||||
'backup-datetime': 'backup_datetime',
|
||||
'prestage-software-version': 'prestage_software_version',
|
||||
'prestage-status': 'prestage_status',
|
||||
'prestage-versions': 'prestage_versions',
|
||||
'region-name': 'region_name'
|
||||
}
|
||||
|
||||
|
@ -64,7 +66,8 @@ class Subcloud(Resource):
|
|||
group_id, sync_status="unknown", endpoint_sync_status=None,
|
||||
backup_status=None, backup_datetime=None,
|
||||
error_description=None, prestage_software_version=None,
|
||||
peer_group_id=None, rehome_data=None, region_name=None):
|
||||
peer_group_id=None, rehome_data=None, region_name=None,
|
||||
prestage_status=None, prestage_versions=None):
|
||||
if endpoint_sync_status is None:
|
||||
endpoint_sync_status = {}
|
||||
self.manager = manager
|
||||
|
@ -95,6 +98,8 @@ class Subcloud(Resource):
|
|||
self.backup_datetime = backup_datetime
|
||||
self.prestage_software_version = prestage_software_version
|
||||
self.region_name = region_name
|
||||
self.prestage_status = prestage_status
|
||||
self.prestage_versions = prestage_versions
|
||||
|
||||
@classmethod
|
||||
def from_payload(cls, manager, payload):
|
||||
|
|
|
@ -39,7 +39,7 @@ def format(subcloud=None):
|
|||
'deploy status',
|
||||
'sync',
|
||||
'backup status',
|
||||
'backup datetime'
|
||||
'prestage status'
|
||||
)
|
||||
|
||||
if subcloud:
|
||||
|
@ -51,7 +51,7 @@ def format(subcloud=None):
|
|||
subcloud.deploy_status,
|
||||
subcloud.sync_status,
|
||||
subcloud.backup_status,
|
||||
subcloud.backup_datetime,
|
||||
subcloud.prestage_status
|
||||
)
|
||||
|
||||
else:
|
||||
|
@ -60,7 +60,7 @@ def format(subcloud=None):
|
|||
return columns, data
|
||||
|
||||
|
||||
def detail_format(subcloud=None):
|
||||
def basic_detail_format(subcloud=None):
|
||||
columns = (
|
||||
'id',
|
||||
'name',
|
||||
|
@ -80,7 +80,9 @@ def detail_format(subcloud=None):
|
|||
'created_at',
|
||||
'updated_at',
|
||||
'backup_status',
|
||||
'backup_datetime'
|
||||
'backup_datetime',
|
||||
'prestage_status',
|
||||
'prestage_versions'
|
||||
)
|
||||
|
||||
if subcloud:
|
||||
|
@ -103,9 +105,21 @@ def detail_format(subcloud=None):
|
|||
subcloud.created_at,
|
||||
subcloud.updated_at,
|
||||
subcloud.backup_status,
|
||||
subcloud.backup_datetime
|
||||
subcloud.backup_datetime,
|
||||
subcloud.prestage_status,
|
||||
subcloud.prestage_versions
|
||||
)
|
||||
|
||||
else:
|
||||
data = (tuple('<none>' for _ in range(len(columns))),)
|
||||
|
||||
return columns, data
|
||||
|
||||
|
||||
def detail_format(subcloud=None):
|
||||
columns, data = basic_detail_format(subcloud)
|
||||
|
||||
if subcloud:
|
||||
for _listitem, sync_status in enumerate(subcloud.endpoint_sync_status):
|
||||
added_field = (sync_status['endpoint_type'] +
|
||||
"_sync_status",)
|
||||
|
@ -117,10 +131,6 @@ def detail_format(subcloud=None):
|
|||
columns += ('oam_floating_ip',)
|
||||
data += (subcloud.oam_floating_ip,)
|
||||
|
||||
if subcloud.prestage_software_version:
|
||||
columns += ('prestage_software_version',)
|
||||
data += (subcloud.prestage_software_version,)
|
||||
|
||||
if subcloud.deploy_config_sync_status != "unknown":
|
||||
columns += ('deploy_config_sync_status',)
|
||||
data += (subcloud.deploy_config_sync_status,)
|
||||
|
@ -128,6 +138,33 @@ def detail_format(subcloud=None):
|
|||
if subcloud.region_name is not None:
|
||||
columns += ('region_name',)
|
||||
data += (subcloud.region_name,)
|
||||
|
||||
return columns, data
|
||||
|
||||
|
||||
def detail_prestage_format(subcloud=None):
|
||||
columns, data = detail_format(subcloud)
|
||||
|
||||
if subcloud and subcloud.prestage_software_version:
|
||||
columns += ('prestage_software_version',)
|
||||
data += (subcloud.prestage_software_version,)
|
||||
|
||||
return columns, data
|
||||
|
||||
|
||||
def detail_list_format(subcloud=None):
|
||||
columns, data = basic_detail_format(subcloud)
|
||||
|
||||
# Find the index of 'deploy_status' in the tuple
|
||||
deploy_status_index = columns.index('deploy_status')
|
||||
|
||||
# Insert "sync" field after 'deploy_status'
|
||||
columns = columns[:deploy_status_index + 1] + ("sync",) + \
|
||||
columns[deploy_status_index + 1:]
|
||||
|
||||
if subcloud:
|
||||
data = data[:deploy_status_index + 1] + (subcloud.sync_status,) + \
|
||||
data[deploy_status_index + 1:]
|
||||
else:
|
||||
data = (tuple('<none>' for _ in range(len(columns))),)
|
||||
|
||||
|
@ -306,8 +343,18 @@ class AddSubcloud(base.DCManagerShowOne):
|
|||
class ListSubcloud(base.DCManagerLister):
|
||||
"""List subclouds."""
|
||||
|
||||
def __init__(self, app, app_args):
|
||||
super(ListSubcloud, self).__init__(app, app_args)
|
||||
# Set a flag to indicate displaying a basic column list or
|
||||
# a list with customized or all columns
|
||||
self.show_basic_list = True
|
||||
|
||||
def _validate_parsed_args(self, parsed_args):
|
||||
self.show_basic_list = \
|
||||
False if parsed_args.columns or parsed_args.detail else True
|
||||
|
||||
def _get_format_function(self):
|
||||
return format
|
||||
return format if self.show_basic_list else detail_list_format
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListSubcloud, self).get_parser(prog_name)
|
||||
|
@ -317,6 +364,12 @@ class ListSubcloud(base.DCManagerLister):
|
|||
action='store_true',
|
||||
help='List all subclouds include "secondary" state subclouds'
|
||||
)
|
||||
parser.add_argument(
|
||||
'-d', '--detail',
|
||||
required=False,
|
||||
action='store_true',
|
||||
help="List all columns of the subclouds"
|
||||
)
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
|
@ -894,7 +947,7 @@ class PrestageSubcloud(base.DCManagerShowOne):
|
|||
"""Prestage a subcloud."""
|
||||
|
||||
def _get_format_function(self):
|
||||
return detail_format
|
||||
return detail_prestage_format
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(PrestageSubcloud, self).get_parser(prog_name)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Copyright 2013 - Mirantis, Inc.
|
||||
# Copyright 2016 - Ericsson AB.
|
||||
# Copyright (c) 2017-2021 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.
|
||||
|
@ -56,6 +56,9 @@ SUBCLOUD_PEERGROUP_ID = None
|
|||
SUBCLOUD_REHOME_DATA = None
|
||||
BACKUP_STATUS = 'None'
|
||||
BACKUP_DATETIME = 'None'
|
||||
PRESTAGE_STATUS = 'None'
|
||||
PRESTAGE_VERSIONS = None
|
||||
SYNC = None
|
||||
|
||||
# Useful for subcloud name configuration
|
||||
NAME_SC2 = "subcloud2"
|
||||
|
@ -84,7 +87,9 @@ SUBCLOUD_RESOURCE = api_base.Subcloud(
|
|||
updated_at=TIME_NOW,
|
||||
group_id=DEFAULT_SUBCLOUD_GROUP_ID,
|
||||
backup_status=BACKUP_STATUS,
|
||||
backup_datetime=BACKUP_DATETIME)
|
||||
backup_datetime=BACKUP_DATETIME,
|
||||
prestage_status=PRESTAGE_STATUS,
|
||||
prestage_versions=PRESTAGE_VERSIONS)
|
||||
|
||||
# Subcloud CLI resource object with peerid rehome data
|
||||
SUBCLOUD_RESOURCE_WITH_PEERID = api_base.Subcloud(
|
||||
|
@ -107,7 +112,35 @@ SUBCLOUD_RESOURCE_WITH_PEERID = api_base.Subcloud(
|
|||
created_at=TIME_NOW,
|
||||
updated_at=TIME_NOW,
|
||||
backup_status=BACKUP_STATUS,
|
||||
backup_datetime=BACKUP_DATETIME)
|
||||
backup_datetime=BACKUP_DATETIME,
|
||||
prestage_status=PRESTAGE_STATUS,
|
||||
prestage_versions=PRESTAGE_VERSIONS)
|
||||
|
||||
# Subcloud CLI resource object with all list fields
|
||||
SUBCLOUD_RESOURCE_WITH_ALL_LIST_FIELDS = api_base.Subcloud(
|
||||
mock,
|
||||
subcloud_id=ID,
|
||||
name=NAME,
|
||||
description=DESCRIPTION,
|
||||
location=LOCATION,
|
||||
software_version=SOFTWARE_VERSION,
|
||||
management_state=MANAGEMENT_STATE,
|
||||
availability_status=AVAILABILITY_STATUS,
|
||||
deploy_status=DEPLOY_STATUS,
|
||||
sync_status=SYNC,
|
||||
management_subnet=MANAGEMENT_SUBNET,
|
||||
management_start_ip=MANAGEMENT_START_IP,
|
||||
management_end_ip=MANAGEMENT_END_IP,
|
||||
management_gateway_ip=MANAGEMENT_GATEWAY_IP,
|
||||
systemcontroller_gateway_ip=SYSTEMCONTROLLER_GATEWAY_IP,
|
||||
group_id=DEFAULT_SUBCLOUD_GROUP_ID,
|
||||
peer_group_id=SUBCLOUD_PEERGROUP_ID,
|
||||
created_at=TIME_NOW,
|
||||
updated_at=TIME_NOW,
|
||||
backup_status=BACKUP_STATUS,
|
||||
backup_datetime=BACKUP_DATETIME,
|
||||
prestage_status=PRESTAGE_STATUS,
|
||||
prestage_versions=PRESTAGE_VERSIONS)
|
||||
|
||||
# Subcloud result values returned from various API calls (e.g. subcloud show)
|
||||
SUBCLOUD_FIELD_RESULT_LIST = (
|
||||
|
@ -151,13 +184,26 @@ SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID = (
|
|||
TIME_NOW,
|
||||
TIME_NOW,
|
||||
BACKUP_STATUS,
|
||||
BACKUP_DATETIME
|
||||
BACKUP_DATETIME,
|
||||
PRESTAGE_STATUS,
|
||||
PRESTAGE_VERSIONS
|
||||
)
|
||||
|
||||
EMPTY_SUBCLOUD_FIELD_RESULT = (('<none>',) * len(SUBCLOUD_FIELD_RESULT_LIST),)
|
||||
EMPTY_SUBCLOUD_FIELD_RESULT_WITH_PEERID_REHOME_DATA = \
|
||||
(('<none>',) * len(SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID),)
|
||||
|
||||
# Create subcloud all fields based on SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID
|
||||
# and add an additional "sync" field
|
||||
DEPLOY_STATUS_IDX = SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID.index(DEPLOY_STATUS)
|
||||
SUBCLOUD_ALL_FIELDS_RESULT_LIST = \
|
||||
SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID[:DEPLOY_STATUS_IDX + 1] + \
|
||||
(SYNC,) + \
|
||||
SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID[DEPLOY_STATUS_IDX + 1:]
|
||||
|
||||
EMPTY_SUBCLOUD_ALL_FIELDS_RESULT = \
|
||||
(('<none>',) * len(SUBCLOUD_ALL_FIELDS_RESULT_LIST),)
|
||||
|
||||
# Subcloud result values returned from subcloud list command
|
||||
SUBCLOUD_LIST_RESULT = (
|
||||
ID,
|
||||
|
@ -167,7 +213,7 @@ SUBCLOUD_LIST_RESULT = (
|
|||
DEPLOY_STATUS,
|
||||
SYNC_STATUS,
|
||||
BACKUP_STATUS,
|
||||
BACKUP_DATETIME
|
||||
PRESTAGE_STATUS
|
||||
)
|
||||
|
||||
EMPTY_SUBCLOUD_LIST_RESULT = (('<none>',) * len(SUBCLOUD_LIST_RESULT),)
|
||||
|
@ -187,7 +233,9 @@ FAKE_BOOTSTRAP_VALUES = {
|
|||
'backup_status': BACKUP_STATUS,
|
||||
'backup_datetime': BACKUP_DATETIME,
|
||||
'backup_status': BACKUP_STATUS,
|
||||
'backup_datetime': BACKUP_DATETIME
|
||||
'backup_datetime': BACKUP_DATETIME,
|
||||
'prestage_status': PRESTAGE_STATUS,
|
||||
'prestage_versions': PRESTAGE_VERSIONS
|
||||
}
|
||||
|
||||
FAKE_INSTALL_VALUES = {
|
||||
|
@ -268,12 +316,13 @@ class BaseCommandTest(testtools.TestCase):
|
|||
super(BaseCommandTest, self).setUp()
|
||||
self.app = mock.Mock()
|
||||
self.client = self.app.client_manager.subcloud_manager
|
||||
self.parsed_args = None
|
||||
|
||||
def call(self, command, app_args=None, prog_name=''):
|
||||
if app_args is None:
|
||||
app_args = []
|
||||
cmd = command(self.app, app_args)
|
||||
|
||||
parsed_args = cmd.get_parser(prog_name).parse_args(app_args)
|
||||
self.parsed_args = cmd.get_parser(prog_name).parse_args(app_args)
|
||||
|
||||
return cmd.take_action(parsed_args)
|
||||
return cmd.take_action(self.parsed_args)
|
||||
|
|
|
@ -40,6 +40,30 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
self.assertEqual(base.EMPTY_SUBCLOUD_LIST_RESULT,
|
||||
actual_call[1])
|
||||
|
||||
def test_list_subclouds_with_all_fields(self):
|
||||
self.client.subcloud_manager.list_subclouds.return_value = \
|
||||
[base.SUBCLOUD_RESOURCE_WITH_ALL_LIST_FIELDS]
|
||||
actual_call = self.call(subcloud_cmd.ListSubcloud, app_args=['-d'])
|
||||
self.assertEqual([base.SUBCLOUD_ALL_FIELDS_RESULT_LIST],
|
||||
actual_call[1])
|
||||
|
||||
def test_list_subclouds_with_all_empty_fields(self):
|
||||
self.client.subcloud_manager.list_subclouds.return_value = []
|
||||
actual_call = self.call(subcloud_cmd.ListSubcloud,
|
||||
app_args=['--detail'])
|
||||
self.assertEqual(base.EMPTY_SUBCLOUD_ALL_FIELDS_RESULT,
|
||||
actual_call[1])
|
||||
|
||||
def test_list_subclouds_with_specified_columns(self):
|
||||
self.client.subcloud_manager.list_subclouds.return_value = \
|
||||
[base.SUBCLOUD_RESOURCE_WITH_ALL_LIST_FIELDS]
|
||||
self.call(subcloud_cmd.ListSubcloud,
|
||||
app_args=['-c', 'name',
|
||||
'-c', 'prestage_status',
|
||||
'-c', 'prestage_versions'])
|
||||
self.assertEqual(self.parsed_args.columns,
|
||||
['name', 'prestage_status', 'prestage_versions'])
|
||||
|
||||
def test_delete_subcloud_with_subcloud_id(self):
|
||||
self.call(subcloud_cmd.DeleteSubcloud, app_args=[base.ID])
|
||||
self.client.subcloud_manager.delete_subcloud.\
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Copyright 2016 - Ericsson AB
|
||||
# Copyright 2015 - Huawei Technologies Co. Ltd
|
||||
# Copyright 2015 - StackStorm, Inc.
|
||||
# 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.
|
||||
|
@ -124,7 +124,9 @@ def subcloud_detail_format(subcloud=None):
|
|||
'created_at',
|
||||
'updated_at',
|
||||
'backup_status',
|
||||
'backup_datetime'
|
||||
'backup_datetime',
|
||||
'prestage_status',
|
||||
'prestage_versions'
|
||||
)
|
||||
|
||||
if subcloud:
|
||||
|
@ -147,7 +149,9 @@ def subcloud_detail_format(subcloud=None):
|
|||
subcloud.created_at,
|
||||
subcloud.updated_at,
|
||||
subcloud.backup_status,
|
||||
subcloud.backup_datetime
|
||||
subcloud.backup_datetime,
|
||||
subcloud.prestage_status,
|
||||
subcloud.prestage_versions
|
||||
)
|
||||
|
||||
for _listitem, sync_status in enumerate(subcloud.endpoint_sync_status):
|
||||
|
|
Loading…
Reference in New Issue