Add Subcloud Peer group management
Group of the current managed subclouds which are supposed to be duplicated in a peer site as secondary subclouds. This commit add subcloud-peer-group CMD of create/delete/update/show/list/ list-subclouds of a subcloud-peer-group Update subcloud update --peer-group PEER_GROUP command CLI example: dcmanager subcloud update SUBCLOUD --peer-group PEER_GROUP dcmanager subcloud-peer-group add \ --peer-group-name NAME dcmanager subcloud-peer-group delete PEER_GROUP dcmanager subcloud-peer-group list dcmanager subcloud-peer-group list-subclouds PEER_GROUP dcmanager subcloud-peer-group migrate PEER_GROUP\ --sysadmin-password PASSWORD dcmanager subcloud-peer-group show PEER_GROUP dcmanager subcloud-peer-group status PEER_GROUP dcmanager subcloud-peer-group update PEER_GROUP [--peer-group-name PEER_GROUP_NAME] [--group-priority GROUP_PRIORITY] [--group-state GROUP_STATE] [--max-subcloud-rehoming MAX_SUBCLOUD_REHOMING Test Plan: 1. PASS - Create a subcloud-peer-group 2. PASS - Add a subcloud, update the peer-group-id as a existing subcloud-peer-group successfully; 3. PASS - Verify subcloud-peer-group list-subclouds can get the expected Subcloud above successfully; 4. PASS - dcmanager subcloud-peer-group update PEER_GROUP_NAME --group-priority/--group-state/--max-subcloud-rehoming of a subcloud-peer-group successfully; 5. PASS - 'dcmanager subcloud-peer-group status' and verify the status was retrieved successfully. 6. PASS - 'dcmaanger subcloud-peer-group delete' and verify the peer group is deleted successfully. 7. PASS - Test 'dcmanager subcloud-peer-group show' command 8. PASS - Test 'dcmanager subcloud-peer-group list' command 9. PASS - Test the help output of all commands and verify that the output is correct. 10.PASS - Test the commands 'dcmanager subcloud-peer-group migrate PEER_GROUP' without passing the argument and verify that it prompts for the password. Story: 2010852 Task: 48490 Task: 48491 Depends-On: I93d0808b8cf02eba0e6f687007df42e2d2ea1848 Depends-On: I5f7e8862e543d61f49a5456f989c94689db83318 Change-Id: I57ae769c179dd4e613ce4edd432692540deea678 Signed-off-by: Wang Tao <tao.wang@windriver.com>
This commit is contained in:
parent
fc1d725206
commit
04d2517df3
|
@ -46,6 +46,7 @@ class Subcloud(Resource):
|
|||
'created-at': 'created_at',
|
||||
'updated-at': 'updated_at',
|
||||
'group_id': 'group_id',
|
||||
'peer_group_id': 'peer_group_id',
|
||||
'rehome_data': 'rehome_data',
|
||||
'sync_status': 'sync_status',
|
||||
'endpoint_sync_status': 'endpoint_sync_status',
|
||||
|
@ -63,7 +64,7 @@ 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,
|
||||
rehome_data=None, region_name=None):
|
||||
peer_group_id=None, rehome_data=None, region_name=None):
|
||||
if endpoint_sync_status is None:
|
||||
endpoint_sync_status = {}
|
||||
self.manager = manager
|
||||
|
@ -86,6 +87,7 @@ class Subcloud(Resource):
|
|||
self.created_at = created_at
|
||||
self.updated_at = updated_at
|
||||
self.group_id = group_id
|
||||
self.peer_group_id = peer_group_id
|
||||
self.rehome_data = rehome_data
|
||||
self.sync_status = sync_status
|
||||
self.endpoint_sync_status = endpoint_sync_status
|
||||
|
|
|
@ -32,6 +32,7 @@ from dcmanagerclient.api.v1 import subcloud_backup_manager as sbm
|
|||
from dcmanagerclient.api.v1 import subcloud_deploy_manager as sdm
|
||||
from dcmanagerclient.api.v1 import subcloud_group_manager as gm
|
||||
from dcmanagerclient.api.v1 import subcloud_manager as sm
|
||||
from dcmanagerclient.api.v1 import subcloud_peer_group_manager as pm
|
||||
from dcmanagerclient.api.v1 import sw_patch_manager as spm
|
||||
from dcmanagerclient.api.v1 import sw_prestage_manager as spr
|
||||
from dcmanagerclient.api.v1 import sw_strategy_manager as sstm
|
||||
|
@ -100,6 +101,9 @@ class Client(object):
|
|||
self.subcloud_manager = sm.subcloud_manager(self.http_client)
|
||||
self.subcloud_group_manager = \
|
||||
gm.subcloud_group_manager(self.http_client, self.subcloud_manager)
|
||||
self.subcloud_peer_group_manager = \
|
||||
pm.subcloud_peer_group_manager(self.http_client,
|
||||
self.subcloud_manager)
|
||||
self.subcloud_backup_manager = sbm.subcloud_backup_manager(
|
||||
self.http_client)
|
||||
self.subcloud_deploy_manager = sdm.subcloud_deploy_manager(
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
# Copyright (c) 2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
import json
|
||||
|
||||
from dcmanagerclient.api import base
|
||||
from dcmanagerclient.api.base import get_json
|
||||
|
||||
BASE_URL = '/subcloud-peer-groups/'
|
||||
|
||||
|
||||
class SubcloudPeerGroup(base.Resource):
|
||||
resource_name = 'subcloud_peer_group'
|
||||
|
||||
def __init__(self,
|
||||
manager,
|
||||
peer_group_id,
|
||||
peer_group_name,
|
||||
group_priority,
|
||||
group_state,
|
||||
system_leader_id,
|
||||
system_leader_name,
|
||||
max_subcloud_rehoming,
|
||||
created_at,
|
||||
updated_at):
|
||||
self.manager = manager
|
||||
self.id = peer_group_id
|
||||
self.peer_group_name = peer_group_name
|
||||
self.group_priority = group_priority
|
||||
|
||||
self.group_state = group_state
|
||||
self.system_leader_id = system_leader_id
|
||||
self.system_leader_name = system_leader_name
|
||||
self.max_subcloud_rehoming = max_subcloud_rehoming
|
||||
self.created_at = created_at
|
||||
self.updated_at = updated_at
|
||||
|
||||
|
||||
class subcloud_peer_group_manager(base.ResourceManager):
|
||||
resource_class = SubcloudPeerGroup
|
||||
|
||||
def __init__(self, http_client, subcloud_manager):
|
||||
super(subcloud_peer_group_manager, self).__init__(http_client)
|
||||
self.subcloud_manager = subcloud_manager
|
||||
|
||||
def json_to_resource(self, json_object):
|
||||
return self.resource_class(
|
||||
self,
|
||||
peer_group_id=json_object['id'],
|
||||
peer_group_name=json_object['peer_group_name'],
|
||||
group_priority=json_object['group_priority'],
|
||||
group_state=json_object['group_state'],
|
||||
system_leader_id=json_object['system_leader_id'],
|
||||
system_leader_name=json_object['system_leader_name'],
|
||||
max_subcloud_rehoming=json_object['max_subcloud_rehoming'],
|
||||
created_at=json_object['created-at'],
|
||||
updated_at=json_object['updated-at'])
|
||||
|
||||
def _subcloud_peer_group_detail(self, url):
|
||||
resp = self.http_client.get(url)
|
||||
if resp.status_code != 200:
|
||||
self._raise_api_exception(resp)
|
||||
json_object = get_json(resp)
|
||||
resource = list()
|
||||
resource.append(self.json_to_resource(json_object))
|
||||
return resource
|
||||
|
||||
def _subcloud_peer_group_status(self, url):
|
||||
resp = self.http_client.get(url)
|
||||
if resp.status_code != 200:
|
||||
self._raise_api_exception(resp)
|
||||
json_object = get_json(resp)
|
||||
resource = list()
|
||||
resource.append(json_object)
|
||||
return resource
|
||||
|
||||
def subcloud_peer_group_create(self, url, data):
|
||||
data = json.dumps(data)
|
||||
resp = self.http_client.post(url, data)
|
||||
if resp.status_code != 200:
|
||||
self._raise_api_exception(resp)
|
||||
json_object = get_json(resp)
|
||||
resource = list()
|
||||
resource.append(self.json_to_resource(json_object))
|
||||
return resource
|
||||
|
||||
def subcloud_peer_group_list(self, url):
|
||||
resp = self.http_client.get(url)
|
||||
if resp.status_code != 200:
|
||||
self._raise_api_exception(resp)
|
||||
json_response_key = get_json(resp)
|
||||
json_objects = json_response_key['subcloud_peer_groups']
|
||||
resource = list()
|
||||
for json_object in json_objects:
|
||||
resource.append(self.json_to_resource(json_object))
|
||||
return resource
|
||||
|
||||
def subcloud_peer_group_update(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)
|
||||
resource = list()
|
||||
resource.append(self.json_to_resource(json_object))
|
||||
return resource
|
||||
|
||||
def _list_subclouds_for_subcloud_peer_group(self, url):
|
||||
resp = self.http_client.get(url)
|
||||
if resp.status_code != 200:
|
||||
self._raise_api_exception(resp)
|
||||
json_response_key = get_json(resp)
|
||||
json_objects = json_response_key['subclouds']
|
||||
resource = list()
|
||||
for json_object in json_objects:
|
||||
resource.append(
|
||||
self.subcloud_manager.json_to_resource(json_object))
|
||||
return resource
|
||||
|
||||
def subcloud_peer_group_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_response_key = get_json(resp)
|
||||
json_objects = json_response_key['subclouds']
|
||||
resource = list()
|
||||
for json_object in json_objects:
|
||||
resource.append(
|
||||
self.subcloud_manager.json_to_resource(json_object))
|
||||
return resource
|
||||
|
||||
def add_subcloud_peer_group(self, **kwargs):
|
||||
data = kwargs
|
||||
url = BASE_URL
|
||||
return self.subcloud_peer_group_create(url, data)
|
||||
|
||||
def delete_subcloud_peer_group(self, subcloud_peer_group_ref):
|
||||
url = BASE_URL + subcloud_peer_group_ref
|
||||
return self._delete(url)
|
||||
|
||||
def subcloud_peer_group_detail(self, subcloud_peer_group_ref):
|
||||
url = BASE_URL + subcloud_peer_group_ref
|
||||
return self._subcloud_peer_group_detail(url)
|
||||
|
||||
def list_subcloud_peer_groups(self):
|
||||
url = BASE_URL
|
||||
return self.subcloud_peer_group_list(url)
|
||||
|
||||
def update_subcloud_peer_group(self, subcloud_peer_group_ref, **kwargs):
|
||||
data = kwargs
|
||||
url = BASE_URL + subcloud_peer_group_ref
|
||||
return self.subcloud_peer_group_update(url, data)
|
||||
|
||||
def migrate_subcloud_peer_group(self, subcloud_peer_group_ref, **kwargs):
|
||||
data = kwargs
|
||||
url = BASE_URL + '%s/migrate' % subcloud_peer_group_ref
|
||||
return self.subcloud_peer_group_migrate(url, data)
|
||||
|
||||
def subcloud_peer_group_list_subclouds(self, subcloud_peer_group_ref):
|
||||
url = BASE_URL + '%s/subclouds' % subcloud_peer_group_ref
|
||||
return self._list_subclouds_for_subcloud_peer_group(url)
|
||||
|
||||
def subcloud_peer_group_status(self, subcloud_peer_group_ref):
|
||||
url = BASE_URL + '%s/status' % subcloud_peer_group_ref
|
||||
return self._subcloud_peer_group_status(url)
|
|
@ -76,6 +76,7 @@ def detail_format(subcloud=None):
|
|||
'management_gateway_ip',
|
||||
'systemcontroller_gateway_ip',
|
||||
'group_id',
|
||||
'peer_group_id',
|
||||
'rehome_data',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
|
@ -99,6 +100,7 @@ def detail_format(subcloud=None):
|
|||
subcloud.management_gateway_ip,
|
||||
subcloud.systemcontroller_gateway_ip,
|
||||
subcloud.group_id,
|
||||
subcloud.peer_group_id,
|
||||
subcloud.rehome_data,
|
||||
subcloud.created_at,
|
||||
subcloud.updated_at,
|
||||
|
@ -594,6 +596,11 @@ class UpdateSubcloud(base.DCManagerShowOne):
|
|||
help='YAML file containing subcloud configuration settings. '
|
||||
'Can be either a local file path or a URL.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--peer-group',
|
||||
required=False,
|
||||
help='Name or ID of subcloud peer group (for migrate).'
|
||||
)
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
|
@ -620,6 +627,8 @@ class UpdateSubcloud(base.DCManagerShowOne):
|
|||
data['management_end_ip'] = parsed_args.management_end_ip
|
||||
if parsed_args.bootstrap_address:
|
||||
data['bootstrap_address'] = parsed_args.bootstrap_address
|
||||
if parsed_args.peer_group:
|
||||
data['peer_group'] = parsed_args.peer_group
|
||||
|
||||
subcloud_network_values = [
|
||||
data.get('management_subnet'),
|
||||
|
|
|
@ -0,0 +1,365 @@
|
|||
# Copyright (c) 2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
import base64
|
||||
|
||||
from osc_lib.command import command
|
||||
|
||||
from dcmanagerclient.commands.v1 import base
|
||||
from dcmanagerclient import exceptions
|
||||
from dcmanagerclient import utils
|
||||
|
||||
|
||||
def group_format(subcloud_peer_group=None):
|
||||
columns = (
|
||||
'id',
|
||||
'peer_group_name',
|
||||
'group_priority',
|
||||
'group_state',
|
||||
'system_leader_id',
|
||||
'system_leader_name',
|
||||
'max_subcloud_rehoming',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
)
|
||||
|
||||
if subcloud_peer_group:
|
||||
data = (
|
||||
subcloud_peer_group.id,
|
||||
subcloud_peer_group.peer_group_name,
|
||||
subcloud_peer_group.group_priority,
|
||||
subcloud_peer_group.group_state,
|
||||
subcloud_peer_group.system_leader_id,
|
||||
subcloud_peer_group.system_leader_name,
|
||||
subcloud_peer_group.max_subcloud_rehoming,
|
||||
subcloud_peer_group.created_at,
|
||||
subcloud_peer_group.updated_at
|
||||
)
|
||||
|
||||
else:
|
||||
data = (('<none>',) * len(columns),)
|
||||
|
||||
return columns, data
|
||||
|
||||
|
||||
class MigrateSubcloudPeerGroup(base.DCManagerLister):
|
||||
"""Migrate subclouds in this peer group."""
|
||||
|
||||
def _get_format_function(self):
|
||||
return utils.subcloud_detail_format
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(MigrateSubcloudPeerGroup, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument(
|
||||
'group',
|
||||
help='Name or ID of the subcloud peer group to migrate.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--sysadmin-password',
|
||||
required=False,
|
||||
help='Sysadmin password of the subclouds to be configured, '
|
||||
'if not provided you will be prompted.'
|
||||
)
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
subcloud_peer_group_ref = parsed_args.group
|
||||
dcmanager_client = self.app.client_manager.subcloud_peer_group_manager
|
||||
kwargs = dict()
|
||||
|
||||
if parsed_args.sysadmin_password is not None:
|
||||
kwargs['sysadmin_password'] = base64.b64encode(
|
||||
parsed_args.sysadmin_password.encode("utf-8")).decode("utf-8")
|
||||
else:
|
||||
password = utils.prompt_for_password()
|
||||
kwargs["sysadmin_password"] = base64.b64encode(
|
||||
password.encode("utf-8")).decode("utf-8")
|
||||
|
||||
try:
|
||||
return dcmanager_client. \
|
||||
subcloud_peer_group_manager.migrate_subcloud_peer_group(
|
||||
subcloud_peer_group_ref, **kwargs)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
msg = "Unable to migrate subcloud peer group %s" % (
|
||||
subcloud_peer_group_ref)
|
||||
raise exceptions.DCManagerClientException(msg)
|
||||
|
||||
|
||||
class AddSubcloudPeerGroup(base.DCManagerShowOne):
|
||||
"""Add a new subcloud peer group."""
|
||||
|
||||
def _get_format_function(self):
|
||||
return group_format
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(AddSubcloudPeerGroup, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument(
|
||||
'--peer-group-name',
|
||||
required=True,
|
||||
help='Name for the new subcloud peer group.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--group-priority',
|
||||
required=False,
|
||||
type=int,
|
||||
default=0,
|
||||
help='Assigned priority for the group.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--group-state',
|
||||
required=False,
|
||||
choices=['enabled', 'disabled'],
|
||||
default='enabled',
|
||||
help='Administrative control of subcloud group.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--max-subcloud-rehoming',
|
||||
required=False,
|
||||
type=int,
|
||||
default=10,
|
||||
help='Maximum number of subclouds to migrate in parallel'
|
||||
)
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
dcmanager_client = self.app.client_manager.subcloud_peer_group_manager
|
||||
kwargs = dict()
|
||||
|
||||
kwargs['peer-group-name'] = parsed_args.peer_group_name
|
||||
|
||||
if parsed_args.group_priority is not None:
|
||||
kwargs['group-priority'] = parsed_args.group_priority
|
||||
|
||||
if parsed_args.group_state is not None:
|
||||
kwargs['group-state'] = parsed_args.group_state
|
||||
|
||||
if parsed_args.max_subcloud_rehoming is not None:
|
||||
kwargs['max-subcloud-rehoming'] = \
|
||||
parsed_args.max_subcloud_rehoming
|
||||
|
||||
return dcmanager_client.subcloud_peer_group_manager.\
|
||||
add_subcloud_peer_group(**kwargs)
|
||||
|
||||
|
||||
class DeleteSubcloudPeerGroup(command.Command):
|
||||
"""Delete subcloud peer group details from the database."""
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteSubcloudPeerGroup, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument(
|
||||
'group',
|
||||
help='Name or ID of the subcloud peer group to delete.'
|
||||
)
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
subcloud_peer_group_ref = parsed_args.group
|
||||
dcmanager_client = self.app.client_manager.subcloud_peer_group_manager
|
||||
try:
|
||||
dcmanager_client.subcloud_peer_group_manager.\
|
||||
delete_subcloud_peer_group(subcloud_peer_group_ref)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
msg = "Unable to delete subcloud peer group %s" % (
|
||||
subcloud_peer_group_ref)
|
||||
raise exceptions.DCManagerClientException(msg)
|
||||
|
||||
|
||||
class ShowSubcloudPeerGroup(base.DCManagerShowOne):
|
||||
"""Show the details of a subcloud peer group."""
|
||||
|
||||
def _get_format_function(self):
|
||||
return group_format
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ShowSubcloudPeerGroup, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument(
|
||||
'group',
|
||||
help='Name or ID of subcloud peer group to view the details.'
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
subcloud_peer_group_ref = parsed_args.group
|
||||
dcmanager_client = self.app.client_manager.subcloud_peer_group_manager
|
||||
return dcmanager_client.subcloud_peer_group_manager.\
|
||||
subcloud_peer_group_detail(subcloud_peer_group_ref)
|
||||
|
||||
|
||||
class ListSubcloudPeerGroup(base.DCManagerLister):
|
||||
"""List subcloud peer groups."""
|
||||
|
||||
def _get_format_function(self):
|
||||
return group_format
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListSubcloudPeerGroup, self).get_parser(prog_name)
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
dcmanager_client = self.app.client_manager.subcloud_peer_group_manager
|
||||
return dcmanager_client.subcloud_peer_group_manager.\
|
||||
list_subcloud_peer_groups()
|
||||
|
||||
|
||||
class ListSubcloudPeerGroupSubclouds(base.DCManagerLister):
|
||||
"""List subclouds referencing a subcloud peer group."""
|
||||
|
||||
def _get_format_function(self):
|
||||
return utils.subcloud_detail_format
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(ListSubcloudPeerGroupSubclouds,
|
||||
self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'group',
|
||||
help="Name or ID of subcloud peer group to list "
|
||||
"associated subclouds."
|
||||
)
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
subcloud_peer_group_ref = parsed_args.group
|
||||
dcmanager_client = self.app.client_manager.subcloud_peer_group_manager
|
||||
return dcmanager_client.subcloud_peer_group_manager. \
|
||||
subcloud_peer_group_list_subclouds(subcloud_peer_group_ref)
|
||||
|
||||
|
||||
class UpdateSubcloudPeerGroup(base.DCManagerShowOne):
|
||||
"""Update attributes of a subcloud peer group."""
|
||||
|
||||
def _get_format_function(self):
|
||||
return group_format
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UpdateSubcloudPeerGroup, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument(
|
||||
'group',
|
||||
help='Name or ID of the subcloud peer group to update.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--peer-group-name',
|
||||
required=False,
|
||||
help='Name for the new subcloud peer group.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--group-priority',
|
||||
required=False,
|
||||
type=int,
|
||||
help='Assigned priority for the peer group.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--group-state',
|
||||
required=False,
|
||||
choices=['enabled', 'disabled'],
|
||||
help='Administrative control of subcloud peer group.'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--max-subcloud-rehoming',
|
||||
required=False,
|
||||
type=int,
|
||||
help='Maximum number of subclouds to migrate in parallel'
|
||||
)
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
subcloud_peer_group_ref = parsed_args.group
|
||||
dcmanager_client = self.app.client_manager.subcloud_peer_group_manager
|
||||
kwargs = dict()
|
||||
|
||||
if parsed_args.peer_group_name is not None:
|
||||
kwargs['peer-group-name'] = parsed_args.peer_group_name
|
||||
|
||||
if parsed_args.group_priority is not None:
|
||||
kwargs['group-priority'] = parsed_args.group_priority
|
||||
|
||||
if parsed_args.group_state is not None:
|
||||
kwargs['group-state'] = parsed_args.group_state
|
||||
|
||||
if parsed_args.max_subcloud_rehoming is not None:
|
||||
kwargs['max-subcloud-rehoming'] = \
|
||||
parsed_args.max_subcloud_rehoming
|
||||
|
||||
if len(kwargs) == 0:
|
||||
error_msg = "Nothing to update"
|
||||
raise exceptions.DCManagerClientException(error_msg)
|
||||
|
||||
try:
|
||||
return dcmanager_client. \
|
||||
subcloud_peer_group_manager.update_subcloud_peer_group(
|
||||
subcloud_peer_group_ref, **kwargs)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
msg = "Unable to update subcloud peer group %s" % (
|
||||
subcloud_peer_group_ref)
|
||||
raise exceptions.DCManagerClientException(msg)
|
||||
|
||||
|
||||
def detail_status_format(subcloud_peer_group_status=None):
|
||||
# Include all the fields in peer_group_format
|
||||
# plus some additional fields
|
||||
columns = (
|
||||
'peer_group_id',
|
||||
'peer_group_name',
|
||||
'total_subclouds',
|
||||
'complete',
|
||||
'waiting_for_migrate',
|
||||
'rehoming',
|
||||
'rehome_failed',
|
||||
'managed',
|
||||
'unmanaged',
|
||||
)
|
||||
if subcloud_peer_group_status:
|
||||
data = (
|
||||
subcloud_peer_group_status['peer_group_id'],
|
||||
subcloud_peer_group_status['peer_group_name'],
|
||||
subcloud_peer_group_status['total_subclouds'],
|
||||
subcloud_peer_group_status['complete'],
|
||||
subcloud_peer_group_status['waiting_for_migrate'],
|
||||
subcloud_peer_group_status['rehoming'],
|
||||
subcloud_peer_group_status['rehome_failed'],
|
||||
subcloud_peer_group_status['managed'],
|
||||
subcloud_peer_group_status['unmanaged'],
|
||||
)
|
||||
else:
|
||||
data = (tuple('<none>' for _ in range(len(columns))),)
|
||||
return columns, data
|
||||
|
||||
|
||||
class StatusSubcloudPeerGroup(base.DCManagerShowOne):
|
||||
"""Show a summary of subcloud statuses within a peer group."""
|
||||
|
||||
def _get_format_function(self):
|
||||
return detail_status_format
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(StatusSubcloudPeerGroup, self).get_parser(prog_name)
|
||||
|
||||
parser.add_argument(
|
||||
'group',
|
||||
help='Name or ID of subcloud peer group to view the status.'
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
def _get_resources(self, parsed_args):
|
||||
subcloud_peer_group_ref = parsed_args.group
|
||||
dcmanager_client = self.app.client_manager.subcloud_peer_group_manager
|
||||
return dcmanager_client.subcloud_peer_group_manager.\
|
||||
subcloud_peer_group_status(subcloud_peer_group_ref)
|
|
@ -41,6 +41,7 @@ from dcmanagerclient.commands.v1 import subcloud_backup_manager as sbm
|
|||
from dcmanagerclient.commands.v1 import subcloud_deploy_manager as sdm
|
||||
from dcmanagerclient.commands.v1 import subcloud_group_manager as gm
|
||||
from dcmanagerclient.commands.v1 import subcloud_manager as sm
|
||||
from dcmanagerclient.commands.v1 import subcloud_peer_group_manager as pm
|
||||
from dcmanagerclient.commands.v1 import sw_patch_manager as spm
|
||||
from dcmanagerclient.commands.v1 import sw_prestage_manager as spr
|
||||
from dcmanagerclient.commands.v1 import sw_update_manager as sum
|
||||
|
@ -499,7 +500,8 @@ class DCManagerShell(app.App):
|
|||
kube_upgrade_manager=self.client,
|
||||
kube_rootca_update_manager=self.client,
|
||||
sw_prestage_manager=self.client,
|
||||
phased_subcloud_deploy_manager=self.client)
|
||||
phased_subcloud_deploy_manager=self.client,
|
||||
subcloud_peer_group_manager=self.client)
|
||||
)
|
||||
self.client_manager = ClientManager()
|
||||
|
||||
|
@ -559,6 +561,15 @@ class DCManagerShell(app.App):
|
|||
'subcloud deploy show': sdm.SubcloudDeployShow,
|
||||
'subcloud-deploy upload': sdm.DeprecatedSubcloudDeployUpload,
|
||||
'subcloud-deploy show': sdm.DeprecatedSubcloudDeployShow,
|
||||
'subcloud-peer-group add': pm.AddSubcloudPeerGroup,
|
||||
'subcloud-peer-group list': pm.ListSubcloudPeerGroup,
|
||||
'subcloud-peer-group list-subclouds':
|
||||
pm.ListSubcloudPeerGroupSubclouds,
|
||||
'subcloud-peer-group show': pm.ShowSubcloudPeerGroup,
|
||||
'subcloud-peer-group update': pm.UpdateSubcloudPeerGroup,
|
||||
'subcloud-peer-group delete': pm.DeleteSubcloudPeerGroup,
|
||||
'subcloud-peer-group migrate': pm.MigrateSubcloudPeerGroup,
|
||||
'subcloud-peer-group status': pm.StatusSubcloudPeerGroup,
|
||||
'system-peer add': sp.AddSystemPeer,
|
||||
'system-peer list': sp.ListSystemPeer,
|
||||
'system-peer show': sp.ShowSystemPeer,
|
||||
|
|
|
@ -52,6 +52,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_PEERGROUP_ID = None
|
||||
SUBCLOUD_REHOME_DATA = None
|
||||
BACKUP_STATUS = 'None'
|
||||
BACKUP_DATETIME = 'None'
|
||||
|
@ -102,6 +103,7 @@ SUBCLOUD_RESOURCE_WITH_PEERID_REHOME_DATA = api_base.Subcloud(
|
|||
management_gateway_ip=MANAGEMENT_GATEWAY_IP,
|
||||
systemcontroller_gateway_ip=SYSTEMCONTROLLER_GATEWAY_IP,
|
||||
group_id=DEFAULT_SUBCLOUD_GROUP_ID,
|
||||
peer_group_id=SUBCLOUD_PEERGROUP_ID,
|
||||
rehome_data=SUBCLOUD_REHOME_DATA,
|
||||
created_at=TIME_NOW,
|
||||
updated_at=TIME_NOW,
|
||||
|
@ -146,12 +148,14 @@ SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA = (
|
|||
MANAGEMENT_GATEWAY_IP,
|
||||
SYSTEMCONTROLLER_GATEWAY_IP,
|
||||
DEFAULT_SUBCLOUD_GROUP_ID,
|
||||
SUBCLOUD_PEERGROUP_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),)
|
||||
|
|
|
@ -255,7 +255,8 @@ class TestCLISubcloudManagerV1(base.BaseCommandTest):
|
|||
'--management-start-ip', 'sc network start ip',
|
||||
'--management-end-ip', 'subcloud network end ip',
|
||||
'--bootstrap-address', 'subcloud bootstrap address',
|
||||
'--bootstrap-values', bootstrap_file_path])
|
||||
'--bootstrap-values', bootstrap_file_path,
|
||||
'--peer-group', 'peer group'])
|
||||
self.assertEqual(
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA,
|
||||
actual_call[1])
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
# Copyright (c) 2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
import mock
|
||||
from oslo_utils import timeutils
|
||||
|
||||
from dcmanagerclient.api.v1.subcloud_peer_group_manager \
|
||||
import SubcloudPeerGroup as Peergroup
|
||||
from dcmanagerclient.commands.v1 \
|
||||
import subcloud_peer_group_manager as subcloud_peer_group_cmd
|
||||
from dcmanagerclient.exceptions import DCManagerClientException
|
||||
from dcmanagerclient.tests import base
|
||||
|
||||
FAKE_MANAGER = None
|
||||
PG_ID = "1"
|
||||
PG_NAME = "test-pg-name"
|
||||
PG_GROUP_PRIORITY = "99"
|
||||
PG_GROUP_STATE = "disabled"
|
||||
PG_MAX_SUBCLOUD_REHOMING = "10"
|
||||
PG_SYSTEM_LEADER_ID = "d9dea83f-f271-470d-9cce-44b0162a800b"
|
||||
PG_SYSTEM_LEADER_NAME = "dc-1"
|
||||
TIME_NOW = timeutils.utcnow().isoformat()
|
||||
PG_CREATED_AT = TIME_NOW
|
||||
PG_UPDATED_AT = TIME_NOW
|
||||
SubcloudPeerGroup = Peergroup(
|
||||
mock,
|
||||
PG_ID,
|
||||
PG_NAME,
|
||||
PG_GROUP_PRIORITY,
|
||||
PG_GROUP_STATE,
|
||||
PG_SYSTEM_LEADER_ID,
|
||||
PG_SYSTEM_LEADER_NAME,
|
||||
PG_MAX_SUBCLOUD_REHOMING,
|
||||
PG_CREATED_AT,
|
||||
PG_UPDATED_AT
|
||||
)
|
||||
|
||||
PG_TUPLE = (PG_ID,
|
||||
PG_NAME,
|
||||
PG_GROUP_PRIORITY,
|
||||
PG_GROUP_STATE,
|
||||
PG_SYSTEM_LEADER_ID,
|
||||
PG_SYSTEM_LEADER_NAME,
|
||||
PG_MAX_SUBCLOUD_REHOMING,
|
||||
)
|
||||
PG_TUPLE_WITH_DATE = PG_TUPLE + (PG_CREATED_AT, PG_UPDATED_AT)
|
||||
|
||||
|
||||
class TestCLISubcloudPeerGroupManager(base.BaseCommandTest):
|
||||
def setUp(self):
|
||||
super(TestCLISubcloudPeerGroupManager, self).setUp()
|
||||
# The client is the subcloud_peer_group_manager
|
||||
self.client = self.app.client_manager.subcloud_peer_group_manager
|
||||
|
||||
def test_list_subcloud_peer_groups(self):
|
||||
self.client.subcloud_peer_group_manager.\
|
||||
list_subcloud_peer_groups.return_value =\
|
||||
[SubcloudPeerGroup]
|
||||
actual_call = self.call(subcloud_peer_group_cmd.ListSubcloudPeerGroup)
|
||||
self.assertEqual([PG_TUPLE_WITH_DATE],
|
||||
actual_call[1])
|
||||
|
||||
def test_show_subcloud_peer_group(self):
|
||||
self.client.subcloud_peer_group_manager.\
|
||||
subcloud_peer_group_detail.return_value =\
|
||||
[SubcloudPeerGroup]
|
||||
actual_call = self.call(subcloud_peer_group_cmd.ShowSubcloudPeerGroup,
|
||||
app_args=[PG_ID])
|
||||
self.assertEqual(PG_TUPLE_WITH_DATE, actual_call[1])
|
||||
|
||||
def test_list_subcloud_peer_group_subclouds(self):
|
||||
self.client.subcloud_peer_group_manager.\
|
||||
subcloud_peer_group_list_subclouds.return_value = \
|
||||
[base.SUBCLOUD_RESOURCE_WITH_PEERID_REHOME_DATA]
|
||||
actual_call = self.call(
|
||||
subcloud_peer_group_cmd.ListSubcloudPeerGroupSubclouds,
|
||||
app_args=[base.ID])
|
||||
self.assertEqual([
|
||||
base.SUBCLOUD_FIELD_RESULT_LIST_WITH_PEERID_REHOME_DATA],
|
||||
actual_call[1])
|
||||
|
||||
def test_add_subcloud_peer_group(self):
|
||||
self.client.subcloud_peer_group_manager.add_subcloud_peer_group.\
|
||||
return_value = [SubcloudPeerGroup]
|
||||
actual_call1 = self.call(
|
||||
subcloud_peer_group_cmd.AddSubcloudPeerGroup, app_args=[
|
||||
'--peer-group-name', PG_NAME
|
||||
])
|
||||
|
||||
actual_call2 = self.call(
|
||||
subcloud_peer_group_cmd.AddSubcloudPeerGroup, app_args=[
|
||||
'--peer-group-name', PG_NAME,
|
||||
'--group-priority', PG_GROUP_PRIORITY,
|
||||
'--group-state', PG_GROUP_STATE,
|
||||
'--max-subcloud-rehoming', PG_MAX_SUBCLOUD_REHOMING
|
||||
])
|
||||
self.assertEqual(
|
||||
PG_TUPLE_WITH_DATE,
|
||||
actual_call1[1])
|
||||
self.assertEqual(
|
||||
PG_TUPLE_WITH_DATE,
|
||||
actual_call2[1])
|
||||
|
||||
def test_delete_subcloud_peer_group(self):
|
||||
self.call(subcloud_peer_group_cmd.DeleteSubcloudPeerGroup,
|
||||
app_args=[PG_ID])
|
||||
self.client.subcloud_peer_group_manager.delete_subcloud_peer_group.\
|
||||
assert_called_once_with(PG_ID)
|
||||
|
||||
def test_update_subcloud_peer_group(self):
|
||||
self.client.subcloud_peer_group_manager.update_subcloud_peer_group.\
|
||||
return_value = [SubcloudPeerGroup]
|
||||
actual_call = self.call(
|
||||
subcloud_peer_group_cmd.UpdateSubcloudPeerGroup,
|
||||
app_args=[
|
||||
base.ID,
|
||||
'--peer-group-name', PG_NAME,
|
||||
'--group-priority', PG_GROUP_PRIORITY,
|
||||
'--group-state', PG_GROUP_STATE,
|
||||
'--max-subcloud-rehoming', PG_MAX_SUBCLOUD_REHOMING])
|
||||
self.assertEqual(
|
||||
(PG_TUPLE_WITH_DATE),
|
||||
actual_call[1])
|
||||
|
||||
e = self.assertRaises(DCManagerClientException,
|
||||
self.call,
|
||||
subcloud_peer_group_cmd.UpdateSubcloudPeerGroup,
|
||||
app_args=[base.ID])
|
||||
self.assertTrue('Nothing to update' in str(e))
|
|
@ -120,6 +120,7 @@ def subcloud_detail_format(subcloud=None):
|
|||
'management_gateway_ip',
|
||||
'systemcontroller_gateway_ip',
|
||||
'group_id',
|
||||
'peer_group_id',
|
||||
'rehome_data',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
|
@ -143,6 +144,7 @@ def subcloud_detail_format(subcloud=None):
|
|||
subcloud.management_gateway_ip,
|
||||
subcloud.systemcontroller_gateway_ip,
|
||||
subcloud.group_id,
|
||||
subcloud.peer_group_id,
|
||||
subcloud.rehome_data,
|
||||
subcloud.created_at,
|
||||
subcloud.updated_at,
|
||||
|
|
Loading…
Reference in New Issue