Add subcloud secondary status support and migration
Add "subcloud migrate" to rehome a 'secondary' state subcloud. Update "dcmanager subcloud add --secondary" command Update "dcmanager subcloud update --bootstrap-address --bootstrap-values" to save data for day-2's rehome/migrate purpose. Update "dcmanager list subcloud --all" include show 'secondary/secondary-failed' subclouds Update result of "subcloud show", add rehome_data section. Usage: dcmanager subcloud add --secondary --bootstrap-address IP --bootstrap-values [yaml file] dcmanager subcloud update SUBCLOUD --bootstrap-address IP --bootstrap-values [yaml file] dcmanager subcloud list --all dcmanager subcloud show SUBCLOUD dcmanager subcloud migrate SUBCLOUD --sysadmin-password PASSWORD Test Plan: 1. PASS - Verify that the dcmanager help subcloud migrate shows the correct help message; 2. PASS - Run 'dcmanager subcloud add --secondary' and verify that the correct API call is made; 3. PASS - Run 'dcmanager subcloud update --bootstrap-address --bootstrap-values' and verify that the correct API call is made; 4. PASS - Run 'dcmanager subcloud migrate' and verify that the correct API call is made; 5. PASS - Verify that the subcloud name/id parameter is required. Story: 2010852 Task: 48489 Task: 48504 Depends-On: I9a308a4e2cc5057091ba195c4d05e9d1eb4a950c Change-Id: Idd10267370dd2cd562c6eacc0d24c47cf68e9fd5 Signed-off-by: Wang Tao <tao.wang@windriver.com>
This commit is contained in:
parent
b6723b8f67
commit
a8b8077983
|
@ -46,6 +46,7 @@ class Subcloud(Resource):
|
|||
'created-at': 'created_at',
|
||||
'updated-at': 'updated_at',
|
||||
'group_id': 'group_id',
|
||||
'rehome_data': 'rehome_data',
|
||||
'sync_status': 'sync_status',
|
||||
'endpoint_sync_status': 'endpoint_sync_status',
|
||||
'backup-status': 'backup_status',
|
||||
|
@ -60,7 +61,8 @@ class Subcloud(Resource):
|
|||
systemcontroller_gateway_ip, created_at, updated_at,
|
||||
group_id, sync_status="unknown", endpoint_sync_status=None,
|
||||
backup_status=None, backup_datetime=None,
|
||||
error_description=None, prestage_software_version=None):
|
||||
error_description=None, prestage_software_version=None,
|
||||
rehome_data=None):
|
||||
if endpoint_sync_status is None:
|
||||
endpoint_sync_status = {}
|
||||
self.manager = manager
|
||||
|
@ -83,6 +85,7 @@ class Subcloud(Resource):
|
|||
self.created_at = created_at
|
||||
self.updated_at = updated_at
|
||||
self.group_id = group_id
|
||||
self.rehome_data = rehome_data
|
||||
self.sync_status = sync_status
|
||||
self.endpoint_sync_status = endpoint_sync_status
|
||||
self.backup_status = backup_status
|
||||
|
|
|
@ -105,6 +105,16 @@ class subcloud_manager(base.ResourceManager):
|
|||
resource.append(self.json_to_resource(json_object))
|
||||
return resource
|
||||
|
||||
def subcloud_migrate(self, url, data):
|
||||
data = json.dumps(data)
|
||||
resp = self.http_client.patch(url, data)
|
||||
if resp.status_code != 200:
|
||||
self._raise_api_exception(resp)
|
||||
json_object = get_json(resp)
|
||||
subcloud = self.resource_class.from_payload(self, json_object)
|
||||
resource = [subcloud]
|
||||
return resource
|
||||
|
||||
def _subcloud_prestage(self, url, data):
|
||||
data = json.dumps(data)
|
||||
resp = self.http_client.patch(url, data)
|
||||
|
@ -190,3 +200,8 @@ class subcloud_manager(base.ResourceManager):
|
|||
data = kwargs.get('data')
|
||||
url = '/subclouds/%s/redeploy' % subcloud_ref
|
||||
return self.subcloud_redeploy(url, files, data)
|
||||
|
||||
def migrate_subcloud(self, subcloud_ref, **kwargs):
|
||||
data = kwargs.get('data')
|
||||
url = '/subclouds/%s/migrate' % subcloud_ref
|
||||
return self.subcloud_migrate(url, data)
|
||||
|
|
|
@ -71,6 +71,7 @@ def detail_format(subcloud=None):
|
|||
'management_gateway_ip',
|
||||
'systemcontroller_gateway_ip',
|
||||
'group_id',
|
||||
'rehome_data',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'backup_status',
|
||||
|
@ -93,6 +94,7 @@ def detail_format(subcloud=None):
|
|||
subcloud.management_gateway_ip,
|
||||
subcloud.systemcontroller_gateway_ip,
|
||||
subcloud.group_id,
|
||||
subcloud.rehome_data,
|
||||
subcloud.created_at,
|
||||
subcloud.updated_at,
|
||||
subcloud.backup_status,
|
||||
|
@ -194,6 +196,14 @@ class AddSubcloud(base.DCManagerShowOne):
|
|||
'the subcloud with. If not specified, the current software '
|
||||
'release of the system controller will be used.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--secondary',
|
||||
required=False,
|
||||
action='store_true',
|
||||
help='A flag indicating if this subcloud is a placeholder '
|
||||
'for incoming subcloud rehoming.'
|
||||
)
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
|
@ -223,20 +233,27 @@ class AddSubcloud(base.DCManagerShowOne):
|
|||
error_msg = "migrate with deploy-config is not allowed"
|
||||
raise exceptions.DCManagerClientException(error_msg)
|
||||
|
||||
if parsed_args.secondary:
|
||||
error_msg = "secondary with deploy-config is not allowed"
|
||||
raise exceptions.DCManagerClientException(error_msg)
|
||||
|
||||
if not os.path.isfile(parsed_args.deploy_config):
|
||||
error_msg = "deploy-config does not exist: %s" % \
|
||||
parsed_args.deploy_config
|
||||
raise exceptions.DCManagerClientException(error_msg)
|
||||
files['deploy_config'] = parsed_args.deploy_config
|
||||
|
||||
# Prompt the user for the subcloud's password if it isn't provided
|
||||
if parsed_args.sysadmin_password is not None:
|
||||
data['sysadmin_password'] = base64.b64encode(
|
||||
parsed_args.sysadmin_password.encode("utf-8"))
|
||||
else:
|
||||
password = utils.prompt_for_password()
|
||||
data["sysadmin_password"] = base64.b64encode(
|
||||
password.encode("utf-8"))
|
||||
# To add a secondary subcloud,
|
||||
# do not need sysadmin_password
|
||||
if not parsed_args.secondary:
|
||||
# Prompt the user for the subcloud's password if it isn't provided
|
||||
if parsed_args.sysadmin_password is not None:
|
||||
data['sysadmin_password'] = base64.b64encode(
|
||||
parsed_args.sysadmin_password.encode("utf-8"))
|
||||
else:
|
||||
password = utils.prompt_for_password()
|
||||
data["sysadmin_password"] = base64.b64encode(
|
||||
password.encode("utf-8"))
|
||||
|
||||
if parsed_args.install_values is not None:
|
||||
if parsed_args.bmc_password is not None:
|
||||
|
@ -256,6 +273,9 @@ class AddSubcloud(base.DCManagerShowOne):
|
|||
if parsed_args.release is not None:
|
||||
data['release'] = parsed_args.release
|
||||
|
||||
if parsed_args.secondary:
|
||||
data['secondary'] = 'true'
|
||||
|
||||
return dcmanager_client.subcloud_manager.add_subcloud(files=files,
|
||||
data=data)
|
||||
|
||||
|
@ -268,11 +288,26 @@ class ListSubcloud(base.DCManagerLister):
|
|||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListSubcloud, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'--all',
|
||||
required=False,
|
||||
action='store_true',
|
||||
help='List all subclouds include "secondary" state subclouds'
|
||||
)
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
dcmanager_client = self.app.client_manager.subcloud_manager
|
||||
return dcmanager_client.subcloud_manager.list_subclouds()
|
||||
subclouds = dcmanager_client.subcloud_manager.list_subclouds()
|
||||
|
||||
# for '--all' parameter, show all subclouds.
|
||||
# for no parameter, hidden all 'secondary/secondary-failed'
|
||||
# state subclouds.
|
||||
if parsed_args.all:
|
||||
return subclouds
|
||||
filtered_subclouds = [s for s in subclouds if s.deploy_status not in
|
||||
('secondary', 'secondary-failed')]
|
||||
return filtered_subclouds
|
||||
|
||||
|
||||
class ShowSubcloud(base.DCManagerShowOne):
|
||||
|
@ -503,6 +538,12 @@ class UpdateSubcloud(base.DCManagerShowOne):
|
|||
'provided you will be prompted. This parameter is only'
|
||||
' valid if the --install-values are specified.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--bootstrap-values',
|
||||
required=False,
|
||||
help='YAML file containing subcloud configuration settings. '
|
||||
'Can be either a local file path or a URL.'
|
||||
)
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
|
@ -535,6 +576,7 @@ class UpdateSubcloud(base.DCManagerShowOne):
|
|||
data.get('management_end_ip'),
|
||||
data.get('bootstrap_address')
|
||||
]
|
||||
|
||||
# Semantic check if the required arguments for updating admin network
|
||||
if all(value is not None for value in subcloud_network_values):
|
||||
# Prompt the user for the subcloud's password if it isn't provided
|
||||
|
@ -545,8 +587,14 @@ class UpdateSubcloud(base.DCManagerShowOne):
|
|||
password = utils.prompt_for_password()
|
||||
data["sysadmin_password"] = base64.b64encode(
|
||||
password.encode("utf-8"))
|
||||
# Not all network values exist
|
||||
elif any(value is not None for value in subcloud_network_values):
|
||||
# For subcloud network reconfiguration
|
||||
# If any management_* presents, need all
|
||||
# management_subnet/management_gateway_ip/
|
||||
# management_start_ip/management_end_ip/bootstrap_address
|
||||
# presents.
|
||||
elif any(value is not None and value != parsed_args.bootstrap_address
|
||||
for value in subcloud_network_values):
|
||||
# Not all network values exist
|
||||
error_msg = (
|
||||
"For subcloud network reconfiguration request all the "
|
||||
"following parameters are necessary: --management-subnet, "
|
||||
|
@ -569,7 +617,15 @@ class UpdateSubcloud(base.DCManagerShowOne):
|
|||
data["bmc_password"] = base64.b64encode(
|
||||
password.encode("utf-8"))
|
||||
|
||||
if not data:
|
||||
# Update the bootstrap values from yaml file
|
||||
if parsed_args.bootstrap_values:
|
||||
if not os.path.isfile(parsed_args.bootstrap_values):
|
||||
error_msg = "bootstrap-values does not exist: %s" % \
|
||||
parsed_args.bootstrap_values
|
||||
raise exceptions.DCManagerClientException(error_msg)
|
||||
files['bootstrap_values'] = parsed_args.bootstrap_values
|
||||
|
||||
if not (data or files):
|
||||
error_msg = "Nothing to update"
|
||||
raise exceptions.DCManagerClientException(error_msg)
|
||||
|
||||
|
@ -977,3 +1033,46 @@ class PrestageSubcloud(base.DCManagerShowOne):
|
|||
print(e)
|
||||
error_msg = "Unable to prestage subcloud %s" % (subcloud_ref)
|
||||
raise exceptions.DCManagerClientException(error_msg)
|
||||
|
||||
|
||||
class MigrateSubcloud(base.DCManagerShowOne):
|
||||
"""Migrate a secondary status subcloud."""
|
||||
def _get_format_function(self):
|
||||
return detail_format
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(MigrateSubcloud, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument(
|
||||
'subcloud',
|
||||
help='Name or ID of the subcloud to migrate.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--sysadmin-password',
|
||||
required=False,
|
||||
help='sysadmin password of the subcloud to be configured, '
|
||||
'if not provided you will be prompted.'
|
||||
)
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
subcloud_ref = parsed_args.subcloud
|
||||
dcmanager_client = self.app.client_manager.subcloud_manager
|
||||
data = dict()
|
||||
if parsed_args.sysadmin_password is not None:
|
||||
data['sysadmin_password'] = base64.b64encode(
|
||||
parsed_args.sysadmin_password.encode("utf-8")).decode("utf-8")
|
||||
else:
|
||||
password = utils.prompt_for_password()
|
||||
data["sysadmin_password"] = base64.b64encode(
|
||||
password.encode("utf-8")).decode("utf-8")
|
||||
|
||||
try:
|
||||
return dcmanager_client.subcloud_manager.migrate_subcloud(
|
||||
subcloud_ref=subcloud_ref, data=data)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
error_msg = "Unable to migrate subcloud %s" % (subcloud_ref)
|
||||
raise exceptions.DCManagerClientException(error_msg)
|
||||
|
|
|
@ -536,6 +536,7 @@ class DCManagerShell(app.App):
|
|||
'subcloud redeploy': sm.RedeploySubcloud,
|
||||
'subcloud restore': sm.RestoreSubcloud,
|
||||
'subcloud prestage': sm.PrestageSubcloud,
|
||||
'subcloud migrate': sm.MigrateSubcloud,
|
||||
'subcloud-backup create': sbm.CreateSubcloudBackup,
|
||||
'subcloud-backup delete': sbm.DeleteSubcloudBackup,
|
||||
'subcloud-backup restore': sbm.RestoreSubcloudBackup,
|
||||
|
|
|
@ -51,6 +51,7 @@ EXTERNAL_OAM_GATEWAY_ADDRESS = "10.10.10.1"
|
|||
EXTERNAL_OAM_FLOATING_ADDRESS = "10.10.10.12"
|
||||
DEFAULT_SUBCLOUD_GROUP_ID = '1'
|
||||
DEPLOY_CONFIG_SYNC_STATUS = 'Deployment: configurations up-to-date'
|
||||
SUBCLOUD_REHOME_DATA = None
|
||||
BACKUP_STATUS = 'None'
|
||||
BACKUP_DATETIME = 'None'
|
||||
|
||||
|
@ -77,6 +78,29 @@ SUBCLOUD_RESOURCE = api_base.Subcloud(
|
|||
backup_status=BACKUP_STATUS,
|
||||
backup_datetime=BACKUP_DATETIME)
|
||||
|
||||
# Subcloud CLI resource object with peerid rehome data
|
||||
SUBCLOUD_RESOURCE_WITH_PEERID_REHOME_DATA = 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,
|
||||
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,
|
||||
rehome_data=SUBCLOUD_REHOME_DATA,
|
||||
created_at=TIME_NOW,
|
||||
updated_at=TIME_NOW,
|
||||
backup_status=BACKUP_STATUS,
|
||||
backup_datetime=BACKUP_DATETIME)
|
||||
|
||||
# Subcloud result values returned from various API calls (e.g. subcloud show)
|
||||
SUBCLOUD_FIELD_RESULT_LIST = (
|
||||
ID,
|
||||
|
@ -99,7 +123,31 @@ SUBCLOUD_FIELD_RESULT_LIST = (
|
|||
BACKUP_DATETIME
|
||||
)
|
||||
|
||||
# Subcloud result values returned from various API calls (e.g. subcloud show)
|
||||
SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA = (
|
||||
ID,
|
||||
NAME,
|
||||
DESCRIPTION,
|
||||
LOCATION,
|
||||
SOFTWARE_VERSION,
|
||||
MANAGEMENT_STATE,
|
||||
AVAILABILITY_STATUS,
|
||||
DEPLOY_STATUS,
|
||||
MANAGEMENT_SUBNET,
|
||||
MANAGEMENT_START_IP,
|
||||
MANAGEMENT_END_IP,
|
||||
MANAGEMENT_GATEWAY_IP,
|
||||
SYSTEMCONTROLLER_GATEWAY_IP,
|
||||
DEFAULT_SUBCLOUD_GROUP_ID,
|
||||
SUBCLOUD_REHOME_DATA,
|
||||
TIME_NOW,
|
||||
TIME_NOW,
|
||||
BACKUP_STATUS,
|
||||
BACKUP_DATETIME
|
||||
)
|
||||
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_REHOME_DATA),)
|
||||
|
||||
# Subcloud result values returned from subcloud list command
|
||||
SUBCLOUD_LIST_RESULT = (
|
||||
|
|
|
@ -44,7 +44,9 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
'--deploy-config', config_file_path,
|
||||
'--release', base.SOFTWARE_VERSION,
|
||||
])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_subcloud_deploy_bootstrap(self):
|
||||
self.client.subcloud_deploy_bootstrap.return_value = [
|
||||
|
@ -59,7 +61,9 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
'--bootstrap-address', base.BOOTSTRAP_ADDRESS,
|
||||
'--bootstrap-values', bootstrap_file_path,
|
||||
])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_install_subcloud(self):
|
||||
self.client.subcloud_deploy_install.return_value = [
|
||||
|
@ -72,7 +76,9 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
cmd.InstallPhasedSubcloudDeploy, app_args=[
|
||||
base.NAME, '--install-values', file_path,
|
||||
])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_install_subcloud_with_release(self):
|
||||
self.client.subcloud_deploy_install.return_value = [
|
||||
|
@ -87,7 +93,9 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
'--install-values', file_path,
|
||||
'--release', base.SOFTWARE_VERSION,
|
||||
])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_install_subcloud_without_install_values(self):
|
||||
self.client.subcloud_deploy_install.return_value = [
|
||||
|
@ -96,7 +104,9 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
actual_call = self.call(
|
||||
cmd.InstallPhasedSubcloudDeploy, app_args=[base.NAME])
|
||||
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_install_file_does_not_exist(self):
|
||||
self.client.subcloud_deploy_install.return_value = [
|
||||
|
@ -122,7 +132,9 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
actual_call = self.call(
|
||||
cmd.ConfigPhasedSubcloudDeploy,
|
||||
app_args=[base.NAME, '--deploy-config', file_path])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_configure_file_does_not_exist(self):
|
||||
self.client.subcloud_deploy_config.return_value = [
|
||||
|
@ -144,7 +156,9 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
actual_call = self.call(
|
||||
cmd.CompletePhasedSubcloudDeploy,
|
||||
app_args=[base.NAME])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_abort_subcloud(self):
|
||||
self.client.subcloud_deploy_abort.return_value = [
|
||||
|
@ -152,7 +166,9 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
actual_call = self.call(
|
||||
cmd.AbortPhasedSubcloudDeploy,
|
||||
app_args=[base.NAME])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_subcloud_deploy_resume_all_parameters(self):
|
||||
self.client.subcloud_deploy_resume.return_value = [
|
||||
|
@ -175,7 +191,9 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
'--deploy-config', config_file_path,
|
||||
'--release', base.SOFTWARE_VERSION,
|
||||
])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_subcloud_deploy_resume_missing_files(self):
|
||||
self.client.subcloud_deploy_resume.return_value = [
|
||||
|
@ -225,7 +243,9 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
actual_call = self.call(
|
||||
cmd.PhasedSubcloudDeployResume,
|
||||
app_args=[base.NAME])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_subcloud_deploy_resume_no_files_only_release(self):
|
||||
self.client.subcloud_deploy_resume.return_value = [
|
||||
|
@ -236,4 +256,6 @@ class TestCLIPhasedSubcloudDeployManagerV1(base.BaseCommandTest):
|
|||
base.NAME,
|
||||
'--release', base.SOFTWARE_VERSION,
|
||||
])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
|
|
@ -84,8 +84,9 @@ class TestCLISubcloudGroupManagerV1(base.BaseCommandTest):
|
|||
app_args=[ID])
|
||||
self.client.subcloud_group_manager.subcloud_group_list_subclouds.\
|
||||
assert_called_once_with(ID)
|
||||
self.assertEqual([base.SUBCLOUD_FIELD_RESULT_LIST],
|
||||
actual_call[1])
|
||||
self.assertEqual([
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA],
|
||||
actual_call[1])
|
||||
|
||||
def test_delete_subcloud_group_by_id(self):
|
||||
self.call(subcloud_group_cmd.DeleteSubcloudGroup, app_args=[ID])
|
||||
|
|
|
@ -53,8 +53,9 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
self.client.subcloud_manager.subcloud_detail.\
|
||||
return_value = [base.SUBCLOUD_RESOURCE]
|
||||
actual_call = self.call(subcloud_cmd.ShowSubcloud, app_args=[base.ID])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST,
|
||||
actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_show_subcloud_with_additional_detail(self):
|
||||
SUBCLOUD_WITH_ADDITIONAL_DETAIL = copy.copy(base.SUBCLOUD_RESOURCE)
|
||||
|
@ -66,16 +67,18 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
return_value = [SUBCLOUD_WITH_ADDITIONAL_DETAIL]
|
||||
actual_call = self.call(subcloud_cmd.ShowSubcloud,
|
||||
app_args=[base.ID, '--detail'])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST +
|
||||
(base.EXTERNAL_OAM_FLOATING_ADDRESS,
|
||||
base.DEPLOY_CONFIG_SYNC_STATUS),
|
||||
actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA +
|
||||
(base.EXTERNAL_OAM_FLOATING_ADDRESS,
|
||||
base.DEPLOY_CONFIG_SYNC_STATUS),
|
||||
actual_call[1])
|
||||
|
||||
def test_show_subcloud_negative(self):
|
||||
self.client.subcloud_manager.subcloud_detail.return_value = []
|
||||
actual_call = self.call(subcloud_cmd.ShowSubcloud, app_args=[base.ID])
|
||||
self.assertEqual(base.EMPTY_SUBCLOUD_FIELD_RESULT,
|
||||
actual_call[1])
|
||||
self.assertEqual(
|
||||
base.EMPTY_SUBCLOUD_FIELD_RESULT_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
@mock.patch('getpass.getpass', return_value='testpassword')
|
||||
def test_add_subcloud(self, getpass):
|
||||
|
@ -98,8 +101,12 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
'--bootstrap-values', file_path,
|
||||
'--release', base.SOFTWARE_VERSION,
|
||||
])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call1[1])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call2[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call1[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call2[1])
|
||||
|
||||
@mock.patch('getpass.getpass', return_value='testpassword')
|
||||
def test_add_migrate_subcloud(self, getpass):
|
||||
|
@ -115,7 +122,9 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
'--bootstrap-values', file_path,
|
||||
'--migrate',
|
||||
])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
@mock.patch('getpass.getpass', return_value='testpassword')
|
||||
def test_add_migrate_subcloud_with_deploy_config(self, getpass):
|
||||
|
@ -142,7 +151,9 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
return_value = [base.SUBCLOUD_RESOURCE]
|
||||
actual_call = self.call(
|
||||
subcloud_cmd.UnmanageSubcloud, app_args=[base.ID])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_unmanage_subcloud_without_subcloud_id(self):
|
||||
self.assertRaises(SystemExit, self.call,
|
||||
|
@ -153,7 +164,9 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
return_value = [base.SUBCLOUD_RESOURCE]
|
||||
actual_call = self.call(
|
||||
subcloud_cmd.ManageSubcloud, app_args=[base.ID])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
def test_manage_subcloud_without_subcloud_id(self):
|
||||
self.assertRaises(SystemExit, self.call,
|
||||
|
@ -162,18 +175,24 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
def test_update_subcloud(self):
|
||||
self.client.subcloud_manager.update_subcloud.\
|
||||
return_value = [base.SUBCLOUD_RESOURCE]
|
||||
actual_call = self.call(
|
||||
subcloud_cmd.UpdateSubcloud,
|
||||
app_args=[base.ID,
|
||||
'--description', 'subcloud description',
|
||||
'--location', 'subcloud location',
|
||||
'--sysadmin-password', 'testpassword',
|
||||
'--management-subnet', 'subcloud network subnet',
|
||||
'--management-gateway-ip', 'subcloud network gateway ip',
|
||||
'--management-start-ip', 'sc network start ip',
|
||||
'--management-end-ip', 'subcloud network end ip',
|
||||
'--bootstrap-address', 'subcloud bootstrap address'])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
with tempfile.NamedTemporaryFile(mode='w') as f_bootstrap:
|
||||
bootstrap_file_path = os.path.abspath(f_bootstrap.name)
|
||||
actual_call = self.call(
|
||||
subcloud_cmd.UpdateSubcloud,
|
||||
app_args=[
|
||||
base.ID,
|
||||
'--description', 'subcloud description',
|
||||
'--location', 'subcloud location',
|
||||
'--sysadmin-password', 'testpassword',
|
||||
'--management-subnet', 'subcloud network subnet',
|
||||
'--management-gateway-ip', 'subcloud network gateway ip',
|
||||
'--management-start-ip', 'sc network start ip',
|
||||
'--management-end-ip', 'subcloud network end ip',
|
||||
'--bootstrap-address', 'subcloud bootstrap address',
|
||||
'--bootstrap-values', bootstrap_file_path])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
@mock.patch('getpass.getpass', return_value='testpassword')
|
||||
def test_success_reconfigure_subcloud(self, getpass):
|
||||
|
@ -189,7 +208,8 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
app_args=[base.ID,
|
||||
'--deploy-config', file_path])
|
||||
|
||||
expected_result = list(base.SUBCLOUD_FIELD_RESULT_LIST)
|
||||
expected_result = list(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA)
|
||||
expected_result[7] = base.DEPLOY_STATE_PRE_DEPLOY
|
||||
|
||||
self.assertEqual(tuple(expected_result), actual_call[1])
|
||||
|
@ -221,7 +241,9 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
actual_call = self.call(
|
||||
subcloud_cmd.ReinstallSubcloud,
|
||||
app_args=[base.ID, '--bootstrap-values', file_path])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
@mock.patch('getpass.getpass', return_value='testpassword')
|
||||
@mock.patch('six.moves.input', return_value='reinstall')
|
||||
|
@ -245,8 +267,12 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
'--bootstrap-values', file_path,
|
||||
'--release', base.SOFTWARE_VERSION,
|
||||
])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call1[1])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call2[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call1[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call2[1])
|
||||
|
||||
@mock.patch('getpass.getpass', return_value='testpassword')
|
||||
@mock.patch('six.moves.input', return_value='reinstall')
|
||||
|
@ -288,7 +314,9 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
'--deploy-config', config_file_path,
|
||||
'--release', base.SOFTWARE_VERSION,
|
||||
])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
@mock.patch('getpass.getpass', return_value='testpassword')
|
||||
@mock.patch('six.moves.input', return_value='redeploy')
|
||||
|
@ -298,7 +326,9 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
actual_call = self.call(
|
||||
subcloud_cmd.RedeploySubcloud,
|
||||
app_args=[base.ID])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST, actual_call[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
||||
@mock.patch('getpass.getpass', return_value='testpassword')
|
||||
@mock.patch('six.moves.input', return_value='redeploy')
|
||||
|
@ -355,8 +385,9 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
app_args=[base.ID,
|
||||
'--sysadmin-password', 'testpassword',
|
||||
'--force'])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST,
|
||||
actual_call_without_release[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call_without_release[1])
|
||||
|
||||
def test_prestage_without_subcloudID(self):
|
||||
self.assertRaises(SystemExit, self.call,
|
||||
|
@ -374,6 +405,49 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
'--sysadmin-password', 'testpassword',
|
||||
'--force',
|
||||
'--release', base.SOFTWARE_VERSION])
|
||||
self.assertEqual(base.SUBCLOUD_FIELD_RESULT_LIST +
|
||||
(base.SOFTWARE_VERSION,),
|
||||
actual_call_with_release[1])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA +
|
||||
(base.SOFTWARE_VERSION,),
|
||||
actual_call_with_release[1])
|
||||
|
||||
def test_migrate_subcloud(self):
|
||||
self.client.subcloud_manager.migrate_subcloud. \
|
||||
return_value = [base.SUBCLOUD_RESOURCE]
|
||||
actual_call_without_release = self.call(
|
||||
subcloud_cmd.MigrateSubcloud,
|
||||
app_args=[base.ID,
|
||||
'--sysadmin-password', 'testpassword'])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call_without_release[1])
|
||||
self.assertRaises(SystemExit, self.call,
|
||||
subcloud_cmd.MigrateSubcloud, app_args=[])
|
||||
|
||||
def test_add_secondary_subcloud(self):
|
||||
self.client.subcloud_manager.add_subcloud.\
|
||||
return_value = [base.SUBCLOUD_RESOURCE]
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode='w') as f_bootstrap:
|
||||
bootstrap_file_path = os.path.abspath(f_bootstrap.name)
|
||||
actual_call = self.call(
|
||||
subcloud_cmd.AddSubcloud,
|
||||
app_args=[
|
||||
'--bootstrap-address', base.BOOTSTRAP_ADDRESS,
|
||||
'--bootstrap-values', bootstrap_file_path,
|
||||
'--sysadmin-password', 'testpassword',
|
||||
'--secondary',
|
||||
])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
with tempfile.NamedTemporaryFile() as f_config:
|
||||
config_file_path = os.path.abspath(f_config.name)
|
||||
self.assertRaises(
|
||||
DCManagerClientException, self.call,
|
||||
subcloud_cmd.AddSubcloud, app_args=[
|
||||
'--bootstrap-address', base.BOOTSTRAP_ADDRESS,
|
||||
'--bootstrap-values', bootstrap_file_path,
|
||||
'--sysadmin-password', 'testpassword',
|
||||
'--deploy-config', config_file_path,
|
||||
'--secondary'
|
||||
])
|
||||
|
|
|
@ -120,6 +120,7 @@ def subcloud_detail_format(subcloud=None):
|
|||
'management_gateway_ip',
|
||||
'systemcontroller_gateway_ip',
|
||||
'group_id',
|
||||
'rehome_data',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'backup_status',
|
||||
|
@ -142,6 +143,7 @@ def subcloud_detail_format(subcloud=None):
|
|||
subcloud.management_gateway_ip,
|
||||
subcloud.systemcontroller_gateway_ip,
|
||||
subcloud.group_id,
|
||||
subcloud.rehome_data,
|
||||
subcloud.created_at,
|
||||
subcloud.updated_at,
|
||||
subcloud.backup_status,
|
||||
|
|
Loading…
Reference in New Issue