Improve subcloud_get_all_with_status query efficiency

Refactor the subcloud_get_all_with_status function to
query only the endpoint_type and sync_status from the
subcloud_status table for improved efficiency.

Test Plan:
PASS: Get all subclouds with the right sync_status
PASS: Create a dcmanager strategy
- Fail if sync_status = Unknown

Story: 2011106
Task: 49893

Change-Id: Ie99abc6cb820800a632f1fd90ee7d7e0869a8312
Signed-off-by: Hugo Brito <hugo.brito@windriver.com>
This commit is contained in:
Hugo Brito 2024-04-18 16:39:01 -03:00 committed by Hugo Nicodemos
parent f30002f332
commit b6693ea74d
3 changed files with 114 additions and 117 deletions

View File

@ -402,65 +402,40 @@ class SubcloudsController(object):
if subcloud_ref is None: if subcloud_ref is None:
# List of subclouds requested # List of subclouds requested
subclouds = db_api.subcloud_get_all_with_status(context) subclouds = db_api.subcloud_get_all_with_status(context)
result = dict() result = {'subclouds': []}
result['subclouds'] = [] subcloud_dict = {}
first_time = True
subcloud_list = []
subcloud_status_list = []
# We get back a subcloud, subcloud_status pair for every for subcloud, endpoint_type, sync_status in subclouds:
# subcloud_status entry corresponding to a subcloud. (Subcloud subcloud_id = subcloud.id
# info repeats) if subcloud_id not in subcloud_dict:
# Aggregate all the sync status for each of the subcloud_dict[subcloud_id] = db_api.subcloud_db_model_to_dict(
# endpoints per subcloud into an overall sync status subcloud)
for subcloud, subcloud_status in subclouds: self._append_static_err_content(subcloud_dict[subcloud_id])
subcloud_dict = db_api.subcloud_db_model_to_dict(subcloud) subcloud_dict[subcloud_id].update(
subcloud_status_dict = db_api.subcloud_status_db_model_to_dict( {consts.SYNC_STATUS: sync_status}
subcloud_status) )
subcloud_dict.update(subcloud_status_dict) subcloud_dict[subcloud_id][consts.ENDPOINT_SYNC_STATUS] = []
self._append_static_err_content(subcloud_dict) subcloud_dict[subcloud_id][consts.ENDPOINT_SYNC_STATUS].append(
{
consts.ENDPOINT_TYPE: endpoint_type,
consts.SYNC_STATUS: sync_status
}
)
if not first_time: # If any of the endpoint sync status is out of sync, then
if subcloud_list[-1]['id'] == subcloud_dict['id']: # the subcloud sync status is out of sync
# We have a match for this subcloud id already, if sync_status != subcloud_dict[subcloud_id][consts.SYNC_STATUS]:
# check if we have a same sync_status subcloud_dict[subcloud_id][consts.SYNC_STATUS] = (
if subcloud_list[-1][consts.SYNC_STATUS] != \ dccommon_consts.SYNC_STATUS_OUT_OF_SYNC
subcloud_dict[consts.SYNC_STATUS]: )
subcloud_list[-1][consts.SYNC_STATUS] = \
dccommon_consts.SYNC_STATUS_OUT_OF_SYNC
if subcloud_status: for subcloud in subcloud_dict.values():
subcloud_status_list.append(
db_api.subcloud_endpoint_status_db_model_to_dict(
subcloud_status))
subcloud_list[-1][
consts.ENDPOINT_SYNC_STATUS] = subcloud_status_list
else:
subcloud_status_list = []
if subcloud_status:
subcloud_status_list.append(
db_api.subcloud_endpoint_status_db_model_to_dict(
subcloud_status))
subcloud_list.append(subcloud_dict)
else:
if subcloud_status:
subcloud_status_list.append(
db_api.subcloud_endpoint_status_db_model_to_dict(
subcloud_status))
subcloud_list.append(subcloud_dict)
first_time = False
for s in subcloud_list:
# This is to reduce changes on cert-mon # This is to reduce changes on cert-mon
# Overwrites the name value with region # Overwrites the name value with region
if utils.is_req_from_cert_mon_agent(request): if utils.is_req_from_cert_mon_agent(request):
s['name'] = s['region-name'] subcloud['name'] = subcloud['region-name']
result['subclouds'].append(s) result['subclouds'].append(subcloud)
return result return result
else: else:
# Single subcloud requested # Single subcloud requested

View File

@ -363,13 +363,14 @@ def subcloud_get_all_ordered_by_id(context):
@require_context @require_context
def subcloud_get_all_with_status(context): def subcloud_get_all_with_status(context):
result = model_query(context, models.Subcloud, models.SubcloudStatus). \ result = model_query(
outerjoin(models.SubcloudStatus, context,
(models.Subcloud.id == models.SubcloudStatus.subcloud_id) | models.Subcloud,
(not models.SubcloudStatus.subcloud_id)). \ models.SubcloudStatus.endpoint_type,
filter(models.Subcloud.deleted == 0). \ models.SubcloudStatus.sync_status).join(
order_by(models.Subcloud.id). \ models.SubcloudStatus,
all() models.Subcloud.id == models.SubcloudStatus.subcloud_id).filter(
models.Subcloud.deleted == 0).order_by(models.Subcloud.id).all()
return result return result

View File

@ -459,91 +459,112 @@ class SwUpdateManager(manager.Manager):
for sb in db_api.subcloud_get_for_group(context, single_group.id): for sb in db_api.subcloud_get_for_group(context, single_group.id):
statuses = db_api.subcloud_status_get_all(context, sb.id) statuses = db_api.subcloud_status_get_all(context, sb.id)
for status in statuses: for status in statuses:
subclouds.append((sb, status)) subclouds.append((sb, status.endpoint_type, status.sync_status))
else: else:
subclouds = db_api.subcloud_get_all_with_status(context) subclouds = db_api.subcloud_get_all_with_status(context)
subclouds_processed = list() subclouds_processed = list()
for subcloud, subcloud_status in subclouds: for subcloud, endpoint_type, sync_status in subclouds:
if (cloud_name and subcloud.name != cloud_name or if (
subcloud.management_state != dccommon_consts.MANAGEMENT_MANAGED): cloud_name
and subcloud.name != cloud_name
or subcloud.management_state != dccommon_consts.MANAGEMENT_MANAGED
):
# We are not updating this subcloud # We are not updating this subcloud
continue continue
if strategy_type == consts.SW_UPDATE_TYPE_UPGRADE: if strategy_type == consts.SW_UPDATE_TYPE_UPGRADE:
if subcloud.availability_status != \ if (
dccommon_consts.AVAILABILITY_ONLINE: subcloud.availability_status !=
dccommon_consts.AVAILABILITY_ONLINE
):
if not force: if not force:
continue continue
elif (subcloud_status.endpoint_type == elif (
dccommon_consts.ENDPOINT_TYPE_LOAD and endpoint_type == dccommon_consts.ENDPOINT_TYPE_LOAD
subcloud_status.sync_status == and sync_status == dccommon_consts.SYNC_STATUS_UNKNOWN
dccommon_consts.SYNC_STATUS_UNKNOWN): ):
raise exceptions.BadRequest( raise exceptions.BadRequest(
resource='strategy', resource="strategy",
msg='Upgrade sync status is unknown for one or more ' msg="Upgrade sync status is unknown for one or more "
'subclouds') "subclouds",
)
elif strategy_type == consts.SW_UPDATE_TYPE_SOFTWARE: elif strategy_type == consts.SW_UPDATE_TYPE_SOFTWARE:
if subcloud.availability_status != \ if (
dccommon_consts.AVAILABILITY_ONLINE: subcloud.availability_status !=
dccommon_consts.AVAILABILITY_ONLINE
):
if not force: if not force:
continue continue
if (subcloud_status.endpoint_type == if (
dccommon_consts.ENDPOINT_TYPE_SOFTWARE and endpoint_type == dccommon_consts.ENDPOINT_TYPE_SOFTWARE
subcloud_status.sync_status == and sync_status == dccommon_consts.SYNC_STATUS_UNKNOWN
dccommon_consts.SYNC_STATUS_UNKNOWN): ):
raise exceptions.BadRequest( raise exceptions.BadRequest(
resource='strategy', resource="strategy",
msg='Software sync status is unknown for one or more ' msg="Software sync status is unknown for one or more "
'subclouds') "subclouds",
)
elif strategy_type == consts.SW_UPDATE_TYPE_PATCH: elif strategy_type == consts.SW_UPDATE_TYPE_PATCH:
if subcloud.availability_status != \ if (
dccommon_consts.AVAILABILITY_ONLINE: subcloud.availability_status !=
dccommon_consts.AVAILABILITY_ONLINE
):
continue continue
elif (subcloud_status.endpoint_type == elif (
dccommon_consts.ENDPOINT_TYPE_PATCHING and endpoint_type == dccommon_consts.ENDPOINT_TYPE_PATCHING
subcloud_status.sync_status == and sync_status == dccommon_consts.SYNC_STATUS_UNKNOWN
dccommon_consts.SYNC_STATUS_UNKNOWN): ):
raise exceptions.BadRequest( raise exceptions.BadRequest(
resource='strategy', resource="strategy",
msg='Patching sync status is unknown for one or more ' msg="Patching sync status is unknown for one or more "
'subclouds') "subclouds",
)
elif strategy_type == consts.SW_UPDATE_TYPE_FIRMWARE: elif strategy_type == consts.SW_UPDATE_TYPE_FIRMWARE:
if subcloud.availability_status != \ if (
dccommon_consts.AVAILABILITY_ONLINE: subcloud.availability_status !=
dccommon_consts.AVAILABILITY_ONLINE
):
continue continue
elif (subcloud_status.endpoint_type == elif (
dccommon_consts.ENDPOINT_TYPE_FIRMWARE and endpoint_type == dccommon_consts.ENDPOINT_TYPE_FIRMWARE
subcloud_status.sync_status == and sync_status == dccommon_consts.SYNC_STATUS_UNKNOWN
dccommon_consts.SYNC_STATUS_UNKNOWN): ):
raise exceptions.BadRequest( raise exceptions.BadRequest(
resource='strategy', resource="strategy",
msg='Firmware sync status is unknown for one or more ' msg="Firmware sync status is unknown for one or more "
'subclouds') "subclouds",
)
elif strategy_type == consts.SW_UPDATE_TYPE_KUBERNETES: elif strategy_type == consts.SW_UPDATE_TYPE_KUBERNETES:
if subcloud.availability_status != \ if (
dccommon_consts.AVAILABILITY_ONLINE: subcloud.availability_status !=
dccommon_consts.AVAILABILITY_ONLINE
):
continue continue
elif (subcloud_status.endpoint_type == elif (
dccommon_consts.ENDPOINT_TYPE_KUBERNETES and endpoint_type == dccommon_consts.ENDPOINT_TYPE_KUBERNETES
subcloud_status.sync_status == and sync_status == dccommon_consts.SYNC_STATUS_UNKNOWN
dccommon_consts.SYNC_STATUS_UNKNOWN): ):
raise exceptions.BadRequest( raise exceptions.BadRequest(
resource='strategy', resource="strategy",
msg='Kubernetes sync status is unknown for one or more ' msg="Kubernetes sync status is unknown for one or more "
'subclouds') "subclouds",
)
elif strategy_type == consts.SW_UPDATE_TYPE_KUBE_ROOTCA_UPDATE: elif strategy_type == consts.SW_UPDATE_TYPE_KUBE_ROOTCA_UPDATE:
if subcloud.availability_status != \ if (
dccommon_consts.AVAILABILITY_ONLINE: subcloud.availability_status !=
dccommon_consts.AVAILABILITY_ONLINE
):
continue continue
elif (subcloud_status.endpoint_type == elif (
dccommon_consts.ENDPOINT_TYPE_KUBE_ROOTCA and endpoint_type == dccommon_consts.ENDPOINT_TYPE_KUBE_ROOTCA
subcloud_status.sync_status == and sync_status == dccommon_consts.SYNC_STATUS_UNKNOWN
dccommon_consts.SYNC_STATUS_UNKNOWN): ):
raise exceptions.BadRequest( raise exceptions.BadRequest(
resource='strategy', resource="strategy",
msg='Kube rootca update sync status is unknown for ' msg="Kube rootca update sync status is unknown for "
'one or more subclouds') "one or more subclouds",
)
elif strategy_type == consts.SW_UPDATE_TYPE_PRESTAGE: elif strategy_type == consts.SW_UPDATE_TYPE_PRESTAGE:
if subcloud.name not in subclouds_processed: if subcloud.name not in subclouds_processed:
# Do initial validation for subcloud # Do initial validation for subcloud