Merge "Subcloud Name Reconfiguration"
This commit is contained in:
commit
a0dfc1adc3
|
@ -78,6 +78,7 @@ Response
|
|||
- deploy-status: deploy_status
|
||||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- region-name: region_name
|
||||
- openstack-installed: openstack_installed
|
||||
- management-state: management_state
|
||||
- systemcontroller-gateway-ip: systemcontroller_gateway_ip
|
||||
|
@ -173,6 +174,7 @@ Request Example
|
|||
- management-gateway-ip: management_gateway_ip
|
||||
- management-start-ip: management_start_ip
|
||||
- management-end-ip: management_end_ip
|
||||
- region-name: region_name
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
@ -283,6 +285,7 @@ This operation does not accept a request body.
|
|||
- deploy-status: deploy_status
|
||||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- region-name: region_name
|
||||
- openstack-installed: openstack_installed
|
||||
- management-state: management_state
|
||||
- systemcontroller-gateway-ip: systemcontroller_gateway_ip
|
||||
|
@ -314,6 +317,8 @@ Modifies a specific subcloud
|
|||
|
||||
The attributes of a subcloud which are modifiable:
|
||||
|
||||
- name
|
||||
|
||||
- description
|
||||
|
||||
- location
|
||||
|
@ -349,6 +354,7 @@ serviceUnavailable (503)
|
|||
.. rest_parameters:: parameters.yaml
|
||||
|
||||
- subcloud: subcloud_uri
|
||||
- name: subcloud_name
|
||||
- description: subcloud_description
|
||||
- location: subcloud_location
|
||||
- management-state: subcloud_management_state
|
||||
|
@ -382,6 +388,7 @@ Request Example
|
|||
- deploy-status: deploy_status
|
||||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- region-name: region_name
|
||||
- openstack-installed: openstack_installed
|
||||
- management-state: management_state
|
||||
- systemcontroller-gateway-ip: systemcontroller_gateway_ip
|
||||
|
@ -526,6 +533,7 @@ Request Example
|
|||
- deploy-status: deploy_status
|
||||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- region-name: region_name
|
||||
- openstack-installed: openstack_installed
|
||||
- management-state: management_state
|
||||
- systemcontroller-gateway-ip: systemcontroller_gateway_ip
|
||||
|
@ -857,6 +865,7 @@ This operation does not accept a request body.
|
|||
- deploy-status: deploy_status
|
||||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- region-name: region_name
|
||||
- openstack-installed: openstack_installed
|
||||
- management-state: management_state
|
||||
- systemcontroller-gateway-ip: systemcontroller_gateway_ip
|
||||
|
@ -1025,6 +1034,7 @@ Request Example
|
|||
- deploy-status: deploy_status
|
||||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- region-name: region_name
|
||||
- openstack-installed: openstack_installed
|
||||
- management-state: management_state
|
||||
- systemcontroller-gateway-ip: systemcontroller_gateway_ip
|
||||
|
@ -1136,6 +1146,7 @@ Request Example
|
|||
- deploy-status: deploy_status
|
||||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- region-name: region_name
|
||||
- openstack-installed: openstack_installed
|
||||
- management-state: management_state
|
||||
- systemcontroller-gateway-ip: systemcontroller_gateway_ip
|
||||
|
@ -1830,6 +1841,7 @@ Request Example
|
|||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- error-description: error_description
|
||||
- region-name: region_name
|
||||
- management-subnet: management_subnet
|
||||
- management-start-ip: management_start_ip
|
||||
- management-end-ip: management_end_ip
|
||||
|
@ -1897,6 +1909,7 @@ Request Example
|
|||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- error-description: error_description
|
||||
- region-name: region_name
|
||||
- management-subnet: management_subnet
|
||||
- management-start-ip: management_start_ip
|
||||
- management-end-ip: management_end_ip
|
||||
|
@ -1963,6 +1976,7 @@ Request Example
|
|||
- deploy-status: deploy_status
|
||||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- region-name: region_name
|
||||
- openstack-installed: openstack_installed
|
||||
- management-state: management_state
|
||||
- systemcontroller-gateway-ip: systemcontroller_gateway_ip
|
||||
|
@ -2036,6 +2050,7 @@ Request Example
|
|||
- deploy-status: deploy_status
|
||||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- region-name: region_name
|
||||
- openstack-installed: openstack_installed
|
||||
- management-state: management_state
|
||||
- systemcontroller-gateway-ip: systemcontroller_gateway_ip
|
||||
|
@ -2103,6 +2118,7 @@ Request Example
|
|||
- deploy-status: deploy_status
|
||||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- region-name: region_name
|
||||
- openstack-installed: openstack_installed
|
||||
- management-state: management_state
|
||||
- systemcontroller-gateway-ip: systemcontroller_gateway_ip
|
||||
|
@ -2170,6 +2186,7 @@ Request Example
|
|||
- deploy-status: deploy_status
|
||||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- region-name: region_name
|
||||
- openstack-installed: openstack_installed
|
||||
- management-state: management_state
|
||||
- systemcontroller-gateway-ip: systemcontroller_gateway_ip
|
||||
|
@ -2246,6 +2263,7 @@ Request Example
|
|||
- backup-status: backup_status
|
||||
- backup-datetime: backup_datetime
|
||||
- error-description: error_description
|
||||
- region-name: region_name
|
||||
- management-subnet: management_subnet
|
||||
- management-start-ip: management_start_ip
|
||||
- management-end-ip: management_end_ip
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"deploy-status": "aborting-install",
|
||||
"backup-status": null,
|
||||
"backup-datetime": null,
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"description": "Ottawa Site",
|
||||
"group_id": 1,
|
||||
"location": "YOW",
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"deploy-status": "complete",
|
||||
"backup-status": "complete",
|
||||
"backup-datetime": "2023-05-02 11:23:58.132134",
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"description": "Ottawa Site",
|
||||
"group_id": 1,
|
||||
"location": "YOW",
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"deploy-status": "complete",
|
||||
"backup-status": "complete",
|
||||
"backup-datetime": "2023-05-02 11:23:58.132134",
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"description": "Ottawa Site",
|
||||
"group_id": 1,
|
||||
"location": "YOW",
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"backup-status": null,
|
||||
"backup-datetime": null,
|
||||
"error-description": "No errors present",
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"management-subnet": "192.168.102.0/24",
|
||||
"management-start-ip": "192.168.102.2",
|
||||
"management-end-ip": "192.168.102.50",
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"deploy-status": "pre-install",
|
||||
"backup-status": null,
|
||||
"backup-datetime": null,
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"description": "Ottawa Site",
|
||||
"group_id": 1,
|
||||
"location": "YOW",
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"backup-status": null,
|
||||
"backup-datetime": null,
|
||||
"error-description": "No errors present",
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"management-subnet": "192.168.102.0/24",
|
||||
"management-start-ip": "192.168.102.2",
|
||||
"management-end-ip": "192.168.102.50",
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"error-description": "",
|
||||
"backup-status": "complete",
|
||||
"backup-datetime": "2022-07-08 11:23:58.132134",
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"description": "Ottawa Site",
|
||||
"group_id": 1,
|
||||
"location": "YOW",
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"error-description": "",
|
||||
"backup-status": "complete",
|
||||
"backup-datetime": "2022-07-08 11:23:58.132134",
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"description": "Ottawa Site",
|
||||
"group_id": 1,
|
||||
"location": "YOW",
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
"deploy-status": "complete",
|
||||
"backup-status": "complete",
|
||||
"backup-datetime": "2022-07-08 11:23:58.132134",
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"openstack-installed": false,
|
||||
"management-state": "managed",
|
||||
"systemcontroller-gateway-ip": "192.168.204.101",
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
"data_install": null,
|
||||
"data_upgrade": null,
|
||||
"oam_floating_ip": "192.168.101.2",
|
||||
"deploy_config_sync_status": "Deployment: configurations up-to-date"
|
||||
"deploy_config_sync_status": "Deployment: configurations up-to-date",
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"endpoint_sync_status": [
|
||||
{
|
||||
"sync_status": "in-sync",
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
"deploy-status": "complete",
|
||||
"backup-status": "complete",
|
||||
"backup-datetime": "2022-07-08 11:23:58.132134",
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"description": "Ottawa Site",
|
||||
"group_id": 1,
|
||||
"location": "YOW",
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"deploy-status": "complete",
|
||||
"backup-status": "complete",
|
||||
"backup-datetime": "2022-07-08 11:23:58.132134",
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"description": "Ottawa Site",
|
||||
"group_id": 1,
|
||||
"location": "YOW",
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
"deploy-status": "complete",
|
||||
"backup-status": "complete",
|
||||
"backup-datetime": "2022-07-08 11:23:58.132134",
|
||||
"region-name": "bbadb3e8e2ab473792c80ef09c5a12a4",
|
||||
"openstack-installed": false,
|
||||
"management-state": "managed",
|
||||
"systemcontroller-gateway-ip": "192.168.204.101",
|
||||
|
|
|
@ -13,5 +13,6 @@
|
|||
"management-gateway-ip": "192.168.205.1",
|
||||
"management-end-ip": "192.168.205.160",
|
||||
"id": 4,
|
||||
"name": "subcloud7"
|
||||
"name": "subcloud7",
|
||||
"region-name": "b098933127ed408e9ad7f6e81c587edb"
|
||||
}
|
||||
|
|
|
@ -171,6 +171,8 @@ class PhasedSubcloudDeployController(object):
|
|||
|
||||
payload = get_create_payload(request)
|
||||
|
||||
psd_common.subcloud_region_create(payload, context)
|
||||
|
||||
psd_common.pre_deploy_create(payload, context, request)
|
||||
|
||||
try:
|
||||
|
|
|
@ -201,7 +201,7 @@ class SubcloudBackupController(object):
|
|||
and request_entity.type == 'subcloud'):
|
||||
# Check the system health only if the command was issued
|
||||
# to a single subcloud to avoid huge delays.
|
||||
if not utils.is_subcloud_healthy(subcloud.name):
|
||||
if not utils.is_subcloud_healthy(subcloud.region_name):
|
||||
msg = _('Subcloud %s must be in good health for '
|
||||
'subcloud-backup create.' % subcloud.name)
|
||||
pecan.abort(400, msg)
|
||||
|
|
|
@ -404,6 +404,10 @@ class SubcloudsController(object):
|
|||
first_time = False
|
||||
|
||||
for s in subcloud_list:
|
||||
# This is to reduce changes on cert-mon
|
||||
# Overwrites the name value with region
|
||||
if utils.is_req_from_cert_mon_agent(request):
|
||||
s['name'] = s['region-name']
|
||||
result['subclouds'].append(s)
|
||||
|
||||
return result
|
||||
|
@ -421,11 +425,19 @@ class SubcloudsController(object):
|
|||
except exceptions.SubcloudNotFound:
|
||||
pecan.abort(404, _('Subcloud not found'))
|
||||
else:
|
||||
# Look up subcloud by name
|
||||
try:
|
||||
subcloud = db_api.subcloud_get_by_name(context,
|
||||
subcloud_ref)
|
||||
except exceptions.SubcloudNameNotFound:
|
||||
# This method replaces subcloud_get_by_name, since it
|
||||
# allows to lookup the subcloud either by region name
|
||||
# or subcloud name.
|
||||
# When the request comes from the cert-monitor, it is
|
||||
# based on the region name (which is UUID format).
|
||||
# Whereas, if the request comes from a client other
|
||||
# than cert-monitor, it will do the lookup based on
|
||||
# the subcloud name.
|
||||
subcloud = db_api.subcloud_get_by_name_or_region_name(
|
||||
context,
|
||||
subcloud_ref)
|
||||
except exceptions.SubcloudNameOrRegionNameNotFound:
|
||||
pecan.abort(404, _('Subcloud not found'))
|
||||
|
||||
subcloud_id = subcloud.id
|
||||
|
@ -448,6 +460,8 @@ class SubcloudsController(object):
|
|||
|
||||
self._append_static_err_content(subcloud_dict)
|
||||
|
||||
subcloud_region = subcloud.region_name
|
||||
subcloud_dict.pop('region-name')
|
||||
if detail is not None:
|
||||
oam_floating_ip = "unavailable"
|
||||
deploy_config_sync_status = "unknown"
|
||||
|
@ -455,19 +469,20 @@ class SubcloudsController(object):
|
|||
|
||||
# Get the keystone client that will be used
|
||||
# for _get_deploy_config_sync_status and _get_oam_addresses
|
||||
sc_ks_client = psd_common.get_ks_client(subcloud.name)
|
||||
sc_ks_client = psd_common.get_ks_client(subcloud_region)
|
||||
oam_addresses = self._get_oam_addresses(context,
|
||||
subcloud.name, sc_ks_client)
|
||||
subcloud_region, sc_ks_client)
|
||||
if oam_addresses is not None:
|
||||
oam_floating_ip = oam_addresses.oam_floating_ip
|
||||
|
||||
deploy_config_state = self._get_deploy_config_sync_status(
|
||||
context, subcloud.name, sc_ks_client)
|
||||
context, subcloud_region, sc_ks_client)
|
||||
if deploy_config_state is not None:
|
||||
deploy_config_sync_status = deploy_config_state
|
||||
|
||||
extra_details = {"oam_floating_ip": oam_floating_ip,
|
||||
"deploy_config_sync_status": deploy_config_sync_status}
|
||||
"deploy_config_sync_status": deploy_config_sync_status,
|
||||
"region_name": subcloud_region}
|
||||
|
||||
subcloud_dict.update(extra_details)
|
||||
return subcloud_dict
|
||||
|
@ -481,6 +496,8 @@ class SubcloudsController(object):
|
|||
restcomm.extract_credentials_for_policy())
|
||||
context = restcomm.extract_context_from_environ()
|
||||
|
||||
bootstrap_sc_name = psd_common.get_bootstrap_subcloud_name(request)
|
||||
|
||||
payload = psd_common.get_request_data(request, None,
|
||||
SUBCLOUD_ADD_GET_FILE_CONTENTS)
|
||||
|
||||
|
@ -488,10 +505,19 @@ class SubcloudsController(object):
|
|||
|
||||
psd_common.validate_secondary_parameter(payload, request)
|
||||
|
||||
# Compares to match both supplied and bootstrap name param
|
||||
# of the subcloud if migrate is on
|
||||
if payload.get('migrate') == 'true' and bootstrap_sc_name is not None:
|
||||
if bootstrap_sc_name != payload.get('name'):
|
||||
pecan.abort(400, _('subcloud name does not match the '
|
||||
'name defined in bootstrap file'))
|
||||
|
||||
# No need sysadmin_password when add a secondary subcloud
|
||||
if 'secondary' not in payload:
|
||||
psd_common.validate_sysadmin_password(payload)
|
||||
|
||||
psd_common.subcloud_region_create(payload, context)
|
||||
|
||||
psd_common.pre_deploy_create(payload, context, request)
|
||||
|
||||
try:
|
||||
|
@ -537,12 +563,21 @@ class SubcloudsController(object):
|
|||
except exceptions.SubcloudNotFound:
|
||||
pecan.abort(404, _('Subcloud not found'))
|
||||
else:
|
||||
# Look up subcloud by name
|
||||
try:
|
||||
subcloud = db_api.subcloud_get_by_name(context,
|
||||
subcloud_ref)
|
||||
except exceptions.SubcloudNameNotFound:
|
||||
pecan.abort(404, _('Subcloud not found'))
|
||||
# This method replaces subcloud_get_by_name, since it
|
||||
# allows to lookup the subcloud either by region name
|
||||
# or subcloud name.
|
||||
# When the request comes from the cert-monitor, it is
|
||||
# based on the region name (which is UUID format).
|
||||
# Whereas, if the request comes from a client other
|
||||
# than cert-monitor, it will do the lookup based on
|
||||
# the subcloud name.
|
||||
subcloud = db_api.subcloud_get_by_name_or_region_name(
|
||||
context,
|
||||
subcloud_ref)
|
||||
except exceptions.SubcloudNameOrRegionNameNotFound:
|
||||
pecan.abort(404, _('Subcloud not found'))
|
||||
|
||||
subcloud_id = subcloud.id
|
||||
|
||||
if verb is None:
|
||||
|
@ -551,6 +586,43 @@ class SubcloudsController(object):
|
|||
if not payload:
|
||||
pecan.abort(400, _('Body required'))
|
||||
|
||||
# Rename the subcloud
|
||||
new_subcloud_name = payload.get('name')
|
||||
if new_subcloud_name is not None:
|
||||
# To be renamed the subcloud must be in unmanaged and valid deploy state
|
||||
if subcloud.management_state != dccommon_consts.MANAGEMENT_UNMANAGED \
|
||||
or subcloud.deploy_status not in consts.STATES_FOR_SUBCLOUD_RENAME:
|
||||
msg = ('Subcloud %s must be unmanaged and in a valid deploy state '
|
||||
'for the subcloud rename operation.' % subcloud.name)
|
||||
|
||||
# Validates new name
|
||||
if not utils.is_subcloud_name_format_valid(new_subcloud_name):
|
||||
pecan.abort(400, _("new name must contain alphabetic characters"))
|
||||
|
||||
# Checks if new subcloud name is the same as the current subcloud
|
||||
if new_subcloud_name == subcloud.name:
|
||||
pecan.abort(400, _('Provided subcloud name %s is the same as the '
|
||||
'current subcloud %s. A different name is '
|
||||
'required to rename the subcloud' %
|
||||
(new_subcloud_name, subcloud.name)))
|
||||
|
||||
error_msg = ('Unable to rename subcloud %s with their region %s to %s' %
|
||||
(subcloud.name, subcloud.region_name, new_subcloud_name))
|
||||
try:
|
||||
LOG.info("Renaming subcloud %s to: %s\n" % (subcloud.name,
|
||||
new_subcloud_name))
|
||||
sc = self.dcmanager_rpc_client.rename_subcloud(context,
|
||||
subcloud_id,
|
||||
subcloud.name,
|
||||
new_subcloud_name)
|
||||
subcloud.name = sc['name']
|
||||
except RemoteError as e:
|
||||
LOG.error(error_msg)
|
||||
pecan.abort(422, e.value)
|
||||
except Exception:
|
||||
LOG.error(error_msg)
|
||||
pecan.abort(500, _('Unable to rename subcloud'))
|
||||
|
||||
# Check if exist any network reconfiguration parameters
|
||||
reconfigure_network = any(payload.get(value) is not None for value in (
|
||||
SUBCLOUD_MANDATORY_NETWORK_PARAMS))
|
||||
|
@ -562,6 +634,7 @@ class SubcloudsController(object):
|
|||
system_controller_mgmt_pool = psd_common.get_network_address_pool()
|
||||
# Required parameters
|
||||
payload['name'] = subcloud.name
|
||||
payload['region_name'] = subcloud.region_name
|
||||
payload['system_controller_network'] = (
|
||||
system_controller_mgmt_pool.network)
|
||||
payload['system_controller_network_prefix'] = (
|
||||
|
@ -715,7 +788,7 @@ class SubcloudsController(object):
|
|||
'Please use /v1.0/subclouds/{subcloud}/redeploy'))
|
||||
|
||||
elif verb == 'update_status':
|
||||
res = self.updatestatus(subcloud.name)
|
||||
res = self.updatestatus(subcloud.name, subcloud.region_name)
|
||||
return res
|
||||
elif verb == 'prestage':
|
||||
if utils.subcloud_is_secondary_state(subcloud.deploy_status):
|
||||
|
@ -816,10 +889,11 @@ class SubcloudsController(object):
|
|||
LOG.exception(e)
|
||||
pecan.abort(500, _('Unable to delete subcloud'))
|
||||
|
||||
def updatestatus(self, subcloud_name):
|
||||
def updatestatus(self, subcloud_name, subcloud_region):
|
||||
"""Update subcloud sync status
|
||||
|
||||
:param subcloud_name: name of the subcloud
|
||||
:param subcloud_region: name of the subcloud region
|
||||
:return: json result object for the operation on success
|
||||
"""
|
||||
|
||||
|
@ -848,7 +922,7 @@ class SubcloudsController(object):
|
|||
LOG.info('update %s set %s=%s' % (subcloud_name, endpoint, status))
|
||||
context = restcomm.extract_context_from_environ()
|
||||
self.dcmanager_state_rpc_client.update_subcloud_endpoint_status(
|
||||
context, subcloud_name, endpoint, status)
|
||||
context, subcloud_name, subcloud_region, endpoint, status)
|
||||
|
||||
result = {'result': 'OK'}
|
||||
return result
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -20,21 +20,22 @@ class Auditor(object):
|
|||
self.state_rpc_client = dcmanager_state_rpc_client
|
||||
self.endpoint_type = endpoint_type
|
||||
|
||||
def _set_subcloud_sync_status(self, sc_name, sc_sync_status):
|
||||
def _set_subcloud_sync_status(self, sc_name, sc_region, sc_sync_status):
|
||||
"""Update the sync status for endpoint."""
|
||||
self.state_rpc_client.update_subcloud_endpoint_status(
|
||||
self.context,
|
||||
subcloud_name=sc_name,
|
||||
subcloud_region=sc_region,
|
||||
endpoint_type=self.endpoint_type,
|
||||
sync_status=sc_sync_status)
|
||||
|
||||
def set_subcloud_endpoint_in_sync(self, sc_name):
|
||||
def set_subcloud_endpoint_in_sync(self, sc_name, sc_region):
|
||||
"""Set the endpoint sync status of this subcloud to be in sync"""
|
||||
self._set_subcloud_sync_status(sc_name, dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
self._set_subcloud_sync_status(sc_name, sc_region, dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
|
||||
def set_subcloud_endpoint_out_of_sync(self, sc_name):
|
||||
def set_subcloud_endpoint_out_of_sync(self, sc_name, sc_region):
|
||||
"""Set the endpoint sync status of this subcloud to be out of sync"""
|
||||
self._set_subcloud_sync_status(sc_name,
|
||||
self._set_subcloud_sync_status(sc_name, sc_region,
|
||||
dccommon_consts.SYNC_STATUS_OUT_OF_SYNC)
|
||||
|
||||
@abc.abstractmethod
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Copyright 2017 Ericsson AB.
|
||||
# Copyright (c) 2017-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2017-2023 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.
|
||||
|
@ -75,11 +75,12 @@ class FirmwareAudit(object):
|
|||
self.state_rpc_client = dcmanager_state_rpc_client
|
||||
self.audit_count = 0
|
||||
|
||||
def _update_subcloud_sync_status(self, sc_name, sc_endpoint_type,
|
||||
def _update_subcloud_sync_status(self, sc_name, sc_region, sc_endpoint_type,
|
||||
sc_status):
|
||||
self.state_rpc_client.update_subcloud_endpoint_status(
|
||||
self.context,
|
||||
subcloud_name=sc_name,
|
||||
subcloud_region=sc_region,
|
||||
endpoint_type=sc_endpoint_type,
|
||||
sync_status=sc_status)
|
||||
|
||||
|
@ -225,19 +226,20 @@ class FirmwareAudit(object):
|
|||
return False
|
||||
return True
|
||||
|
||||
def subcloud_firmware_audit(self, subcloud_name, audit_data):
|
||||
def subcloud_firmware_audit(self, subcloud_name, subcloud_region, audit_data):
|
||||
LOG.info('Triggered firmware audit for: %s.' % subcloud_name)
|
||||
if not audit_data:
|
||||
self._update_subcloud_sync_status(
|
||||
subcloud_name, dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
subcloud_name,
|
||||
subcloud_region, dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
LOG.debug('No images to audit, exiting firmware audit')
|
||||
return
|
||||
try:
|
||||
sc_os_client = OpenStackDriver(region_name=subcloud_name,
|
||||
sc_os_client = OpenStackDriver(region_name=subcloud_region,
|
||||
region_clients=None).keystone_client
|
||||
endpoint = sc_os_client.endpoint_cache.get_endpoint('sysinv')
|
||||
sysinv_client = SysinvClient(subcloud_name, sc_os_client.session,
|
||||
sysinv_client = SysinvClient(subcloud_region, sc_os_client.session,
|
||||
endpoint=endpoint)
|
||||
except (keystone_exceptions.EndpointNotFound,
|
||||
keystone_exceptions.ConnectFailure,
|
||||
|
@ -267,7 +269,8 @@ class FirmwareAudit(object):
|
|||
LOG.info("No enabled devices on the subcloud %s,"
|
||||
"exiting firmware audit" % subcloud_name)
|
||||
self._update_subcloud_sync_status(
|
||||
subcloud_name, dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
subcloud_name,
|
||||
subcloud_region, dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
return
|
||||
|
||||
|
@ -312,10 +315,12 @@ class FirmwareAudit(object):
|
|||
|
||||
if out_of_sync:
|
||||
self._update_subcloud_sync_status(
|
||||
subcloud_name, dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
subcloud_name,
|
||||
subcloud_region, dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
dccommon_consts.SYNC_STATUS_OUT_OF_SYNC)
|
||||
else:
|
||||
self._update_subcloud_sync_status(
|
||||
subcloud_name, dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
subcloud_name,
|
||||
subcloud_region, dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
LOG.info('Firmware audit completed for: %s.' % subcloud_name)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2021-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2021-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -46,20 +46,21 @@ class KubeRootcaUpdateAudit(Auditor):
|
|||
"""
|
||||
return []
|
||||
|
||||
def subcloud_audit(self, subcloud_name, region_one_audit_data):
|
||||
def subcloud_audit(self, subcloud_name, subcloud_region, region_one_audit_data):
|
||||
"""Perform an audit of kube root CA update info in a subcloud.
|
||||
|
||||
:param subcloud_name: the name of the subcloud
|
||||
:param subcloud_region: the region of the subcloud
|
||||
:param region_one_audit_data: ignored. Always an empty list
|
||||
"""
|
||||
LOG.info("Triggered %s audit for: %s" % (self.audit_type,
|
||||
subcloud_name))
|
||||
# check for a particular alarm in the subcloud
|
||||
try:
|
||||
sc_os_client = OpenStackDriver(region_name=subcloud_name,
|
||||
sc_os_client = OpenStackDriver(region_name=subcloud_region,
|
||||
region_clients=None)
|
||||
session = sc_os_client.keystone_client.session
|
||||
fm_client = FmClient(subcloud_name, session)
|
||||
fm_client = FmClient(subcloud_region, session)
|
||||
except (keystone_exceptions.EndpointNotFound,
|
||||
keystone_exceptions.ConnectFailure,
|
||||
keystone_exceptions.ConnectTimeout,
|
||||
|
@ -75,8 +76,8 @@ class KubeRootcaUpdateAudit(Auditor):
|
|||
out_of_sync = True
|
||||
break
|
||||
if out_of_sync:
|
||||
self.set_subcloud_endpoint_out_of_sync(subcloud_name)
|
||||
self.set_subcloud_endpoint_out_of_sync(subcloud_name, subcloud_region)
|
||||
else:
|
||||
self.set_subcloud_endpoint_in_sync(subcloud_name)
|
||||
self.set_subcloud_endpoint_in_sync(subcloud_name, subcloud_region)
|
||||
LOG.info("%s audit completed for: %s" % (self.audit_type,
|
||||
subcloud_name))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Copyright 2017 Ericsson AB.
|
||||
# Copyright (c) 2017-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2017-2023 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.
|
||||
|
@ -55,11 +55,12 @@ class KubernetesAudit(object):
|
|||
self.state_rpc_client = dcmanager_state_rpc_client
|
||||
self.audit_count = 0
|
||||
|
||||
def _update_subcloud_sync_status(self, sc_name, sc_endpoint_type,
|
||||
def _update_subcloud_sync_status(self, sc_name, sc_region, sc_endpoint_type,
|
||||
sc_status):
|
||||
self.state_rpc_client.update_subcloud_endpoint_status(
|
||||
self.context,
|
||||
subcloud_name=sc_name,
|
||||
subcloud_region=sc_region,
|
||||
endpoint_type=sc_endpoint_type,
|
||||
sync_status=sc_status)
|
||||
|
||||
|
@ -90,19 +91,20 @@ class KubernetesAudit(object):
|
|||
LOG.debug("RegionOne kubernetes versions: %s" % region_one_data)
|
||||
return region_one_data
|
||||
|
||||
def subcloud_kubernetes_audit(self, subcloud_name, audit_data):
|
||||
def subcloud_kubernetes_audit(self, subcloud_name, subcloud_region, audit_data):
|
||||
LOG.info('Triggered kubernetes audit for: %s' % subcloud_name)
|
||||
if not audit_data:
|
||||
self._update_subcloud_sync_status(
|
||||
subcloud_name, dccommon_consts.ENDPOINT_TYPE_KUBERNETES,
|
||||
subcloud_name,
|
||||
subcloud_region, dccommon_consts.ENDPOINT_TYPE_KUBERNETES,
|
||||
dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
LOG.debug('No region one audit data, exiting kubernetes audit')
|
||||
return
|
||||
try:
|
||||
sc_os_client = OpenStackDriver(region_name=subcloud_name,
|
||||
sc_os_client = OpenStackDriver(region_name=subcloud_region,
|
||||
region_clients=None).keystone_client
|
||||
endpoint = sc_os_client.endpoint_cache.get_endpoint('sysinv')
|
||||
sysinv_client = SysinvClient(subcloud_name, sc_os_client.session,
|
||||
sysinv_client = SysinvClient(subcloud_region, sc_os_client.session,
|
||||
endpoint=endpoint)
|
||||
except (keystone_exceptions.EndpointNotFound,
|
||||
keystone_exceptions.ConnectFailure,
|
||||
|
@ -152,10 +154,12 @@ class KubernetesAudit(object):
|
|||
|
||||
if out_of_sync:
|
||||
self._update_subcloud_sync_status(
|
||||
subcloud_name, dccommon_consts.ENDPOINT_TYPE_KUBERNETES,
|
||||
subcloud_name,
|
||||
subcloud_region, dccommon_consts.ENDPOINT_TYPE_KUBERNETES,
|
||||
dccommon_consts.SYNC_STATUS_OUT_OF_SYNC)
|
||||
else:
|
||||
self._update_subcloud_sync_status(
|
||||
subcloud_name, dccommon_consts.ENDPOINT_TYPE_KUBERNETES,
|
||||
subcloud_name,
|
||||
subcloud_region, dccommon_consts.ENDPOINT_TYPE_KUBERNETES,
|
||||
dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
LOG.info('Kubernetes audit completed for: %s' % subcloud_name)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Copyright 2017 Ericsson AB.
|
||||
# Copyright (c) 2017-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2017-2023 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.
|
||||
|
@ -62,11 +62,12 @@ class PatchAudit(object):
|
|||
self.state_rpc_client = dcmanager_state_rpc_client
|
||||
self.audit_count = 0
|
||||
|
||||
def _update_subcloud_sync_status(self, sc_name, sc_endpoint_type,
|
||||
def _update_subcloud_sync_status(self, sc_name, sc_region, sc_endpoint_type,
|
||||
sc_status):
|
||||
self.state_rpc_client.update_subcloud_endpoint_status(
|
||||
self.context,
|
||||
subcloud_name=sc_name,
|
||||
subcloud_region=sc_region,
|
||||
endpoint_type=sc_endpoint_type,
|
||||
sync_status=sc_status)
|
||||
|
||||
|
@ -132,19 +133,19 @@ class PatchAudit(object):
|
|||
return PatchAuditData(regionone_patches, applied_patch_ids,
|
||||
committed_patch_ids, regionone_software_version)
|
||||
|
||||
def subcloud_patch_audit(self, subcloud_name, audit_data, do_load_audit):
|
||||
def subcloud_patch_audit(self, subcloud_name, subcloud_region, audit_data, do_load_audit):
|
||||
LOG.info('Triggered patch audit for: %s.' % subcloud_name)
|
||||
try:
|
||||
sc_os_client = OpenStackDriver(region_name=subcloud_name,
|
||||
sc_os_client = OpenStackDriver(region_name=subcloud_region,
|
||||
region_clients=None).keystone_client
|
||||
session = sc_os_client.session
|
||||
patching_endpoint = sc_os_client.endpoint_cache.get_endpoint('patching')
|
||||
sysinv_endpoint = sc_os_client.endpoint_cache.get_endpoint('sysinv')
|
||||
patching_client = PatchingClient(
|
||||
subcloud_name, session,
|
||||
subcloud_region, session,
|
||||
endpoint=patching_endpoint)
|
||||
sysinv_client = SysinvClient(
|
||||
subcloud_name, session,
|
||||
subcloud_region, session,
|
||||
endpoint=sysinv_endpoint)
|
||||
except (keystone_exceptions.EndpointNotFound,
|
||||
keystone_exceptions.ConnectFailure,
|
||||
|
@ -227,11 +228,13 @@ class PatchAudit(object):
|
|||
|
||||
if out_of_sync:
|
||||
self._update_subcloud_sync_status(
|
||||
subcloud_name, dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
subcloud_name,
|
||||
subcloud_region, dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
dccommon_consts.SYNC_STATUS_OUT_OF_SYNC)
|
||||
else:
|
||||
self._update_subcloud_sync_status(
|
||||
subcloud_name, dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
subcloud_name,
|
||||
subcloud_region, dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
|
||||
# Check subcloud software version every other audit cycle
|
||||
|
@ -251,16 +254,19 @@ class PatchAudit(object):
|
|||
|
||||
if subcloud_software_version == audit_data.software_version:
|
||||
self._update_subcloud_sync_status(
|
||||
subcloud_name, dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
subcloud_name,
|
||||
subcloud_region, dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
else:
|
||||
self._update_subcloud_sync_status(
|
||||
subcloud_name, dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
subcloud_name,
|
||||
subcloud_region, dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
dccommon_consts.SYNC_STATUS_OUT_OF_SYNC)
|
||||
else:
|
||||
# As upgrade is still in progress, set the subcloud load
|
||||
# status as out-of-sync.
|
||||
self._update_subcloud_sync_status(
|
||||
subcloud_name, dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
subcloud_name,
|
||||
subcloud_region, dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
dccommon_consts.SYNC_STATUS_OUT_OF_SYNC)
|
||||
LOG.info('Patch audit completed for: %s.' % subcloud_name)
|
||||
|
|
|
@ -153,7 +153,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
|
|||
# Create a new greenthread for each subcloud to allow the audits
|
||||
# to be done in parallel. If there are not enough greenthreads
|
||||
# in the pool, this will block until one becomes available.
|
||||
self.subcloud_workers[subcloud.name] = \
|
||||
self.subcloud_workers[subcloud.region_name] = \
|
||||
self.thread_group_manager.start(self._do_audit_subcloud,
|
||||
subcloud,
|
||||
update_subcloud_state,
|
||||
|
@ -204,12 +204,13 @@ class SubcloudAuditWorkerManager(manager.Manager):
|
|||
'audit_fail_count for subcloud: %s' % subcloud.name)
|
||||
|
||||
def _update_subcloud_availability(self, subcloud_name,
|
||||
subcloud_region,
|
||||
availability_status=None,
|
||||
update_state_only=False,
|
||||
audit_fail_count=None):
|
||||
try:
|
||||
self.state_rpc_client.update_subcloud_availability(
|
||||
self.context, subcloud_name, availability_status,
|
||||
self.context, subcloud_name, subcloud_region, availability_status,
|
||||
update_state_only, audit_fail_count)
|
||||
LOG.info('Notifying dcmanager-state, subcloud:%s, availability:%s' %
|
||||
(subcloud_name,
|
||||
|
@ -339,7 +340,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
|
|||
db_api.subcloud_audits_end_audit(self.context,
|
||||
subcloud.id, audits_done)
|
||||
# Remove the worker for this subcloud
|
||||
self.subcloud_workers.pop(subcloud.name, None)
|
||||
self.subcloud_workers.pop(subcloud.region_name, None)
|
||||
LOG.debug("PID: %s, done auditing subcloud: %s." %
|
||||
(self.pid, subcloud.name))
|
||||
|
||||
|
@ -361,6 +362,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
|
|||
avail_status_current = subcloud.availability_status
|
||||
audit_fail_count = subcloud.audit_fail_count
|
||||
subcloud_name = subcloud.name
|
||||
subcloud_region = subcloud.region_name
|
||||
audits_done = list()
|
||||
failures = list()
|
||||
|
||||
|
@ -371,7 +373,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
|
|||
fm_client = None
|
||||
avail_to_set = dccommon_consts.AVAILABILITY_OFFLINE
|
||||
try:
|
||||
os_client = OpenStackDriver(region_name=subcloud_name,
|
||||
os_client = OpenStackDriver(region_name=subcloud_region,
|
||||
thread_name='subcloud-audit',
|
||||
region_clients=['fm', 'sysinv'])
|
||||
sysinv_client = os_client.sysinv_client
|
||||
|
@ -452,6 +454,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
|
|||
(avail_to_set, subcloud_name))
|
||||
self._update_subcloud_availability(
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
availability_status=avail_to_set,
|
||||
audit_fail_count=audit_fail_count)
|
||||
|
||||
|
@ -470,6 +473,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
|
|||
% subcloud_name)
|
||||
self._update_subcloud_availability(
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
availability_status=avail_status_current,
|
||||
update_state_only=True)
|
||||
|
||||
|
@ -488,6 +492,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
|
|||
if do_patch_audit and patch_audit_data:
|
||||
try:
|
||||
self.patch_audit.subcloud_patch_audit(subcloud_name,
|
||||
subcloud_region,
|
||||
patch_audit_data,
|
||||
do_load_audit)
|
||||
audits_done.append('patch')
|
||||
|
@ -504,6 +509,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
|
|||
if do_firmware_audit:
|
||||
try:
|
||||
self.firmware_audit.subcloud_firmware_audit(subcloud_name,
|
||||
subcloud_region,
|
||||
firmware_audit_data)
|
||||
audits_done.append('firmware')
|
||||
except Exception:
|
||||
|
@ -514,6 +520,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
|
|||
try:
|
||||
self.kubernetes_audit.subcloud_kubernetes_audit(
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
kubernetes_audit_data)
|
||||
audits_done.append('kubernetes')
|
||||
except Exception:
|
||||
|
@ -524,6 +531,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
|
|||
try:
|
||||
self.kube_rootca_update_audit.subcloud_audit(
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
kube_rootca_update_audit_data)
|
||||
audits_done.append('kube-rootca-update')
|
||||
except Exception:
|
||||
|
@ -536,7 +544,7 @@ class SubcloudAuditWorkerManager(manager.Manager):
|
|||
# audits_done to be empty:
|
||||
try:
|
||||
self._audit_subcloud_openstack_app(
|
||||
subcloud_name, sysinv_client, subcloud.openstack_installed)
|
||||
subcloud_region, sysinv_client, subcloud.openstack_installed)
|
||||
except Exception:
|
||||
LOG.exception(failmsg % (subcloud.name, 'openstack'))
|
||||
failures.append('openstack')
|
||||
|
|
|
@ -419,3 +419,9 @@ ALTERNATE_DEPLOY_PLAYBOOK_DIR = ALTERNATE_DEPLOY_FILES_DIR + '/playbooks'
|
|||
DEPLOY_PLAYBOOK_POSTFIX = 'deployment-manager.yaml'
|
||||
|
||||
SUPPORTED_UPGRADES_METADATA_FILE_PATH = '/usr/rootdirs/opt/upgrades/metadata.xml'
|
||||
|
||||
# Required for subcloud name configuration
|
||||
CERT_MON_HTTP_AGENT = 'cert-mon/1.0'
|
||||
OS_REGION_NAME = "OS_REGION_NAME"
|
||||
STATES_FOR_SUBCLOUD_RENAME = [DEPLOY_STATE_DONE,
|
||||
PRESTAGE_STATE_COMPLETE]
|
||||
|
|
|
@ -115,6 +115,18 @@ class SubcloudNameNotFound(NotFound):
|
|||
message = _("Subcloud with name %(name)s doesn't exist.")
|
||||
|
||||
|
||||
class SubcloudRegionNameNotFound(NotFound):
|
||||
message = _("Subcloud with region name %(region_name)s doesn't exist.")
|
||||
|
||||
|
||||
class SubcloudNameOrRegionNameNotFound(NotFound):
|
||||
message = _("Subcloud with name or region name %(name)s doesn't exist.")
|
||||
|
||||
|
||||
class SubcloudOrRegionNameAlreadyExists(Conflict):
|
||||
message = _("Subcloud with name or region name %(name)s already exist.")
|
||||
|
||||
|
||||
class SubcloudNotOnline(DCManagerException):
|
||||
message = _("Subcloud is not online.")
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import typing
|
|||
|
||||
import netaddr
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import uuidutils
|
||||
import pecan
|
||||
import tsconfig.tsconfig as tsc
|
||||
import yaml
|
||||
|
@ -730,7 +731,18 @@ def upload_deploy_config_file(request, payload):
|
|||
pecan.abort(400, _("No %s file uploaded" % consts.DEPLOY_CONFIG))
|
||||
|
||||
file_item.file.seek(0, os.SEEK_SET)
|
||||
contents = file_item.file.read()
|
||||
file_lines = file_item.file.readlines()
|
||||
|
||||
# Updates the OS_REGION_NAME param which is required for deployment
|
||||
contents = ""
|
||||
for line in file_lines:
|
||||
dec_line = line.decode('utf8')
|
||||
if consts.OS_REGION_NAME in dec_line:
|
||||
os_reg_item = dec_line.split(":")
|
||||
dec_line = os_reg_item[0] + ": " + payload['region_name'] + "\n"
|
||||
contents = contents + dec_line
|
||||
contents = contents.encode()
|
||||
|
||||
# the deploy config needs to upload to the override location
|
||||
fn = get_config_file_path(payload['name'], consts.DEPLOY_CONFIG)
|
||||
upload_config_file(contents, fn, consts.DEPLOY_CONFIG)
|
||||
|
@ -844,6 +856,9 @@ def add_subcloud_to_database(context, payload):
|
|||
if 'install_values' in payload:
|
||||
data_install = json.dumps(payload['install_values'])
|
||||
|
||||
LOG.info("Creating subcloud %s with region: %s", payload.get('name'),
|
||||
payload.get('region_name'))
|
||||
|
||||
subcloud = db_api.subcloud_create(
|
||||
context,
|
||||
payload['name'],
|
||||
|
@ -857,6 +872,7 @@ def add_subcloud_to_database(context, payload):
|
|||
payload['systemcontroller_gateway_address'],
|
||||
consts.DEPLOY_STATE_NONE,
|
||||
consts.ERROR_DESC_EMPTY,
|
||||
payload['region_name'],
|
||||
False,
|
||||
group_id,
|
||||
data_install=data_install)
|
||||
|
@ -1023,3 +1039,118 @@ def pre_deploy_bootstrap(context: RequestContext, payload: dict,
|
|||
# again:
|
||||
validate_system_controller_patch_status("bootstrap")
|
||||
validate_k8s_version(payload)
|
||||
|
||||
|
||||
def get_bootstrap_subcloud_name(request: pecan.Request):
|
||||
bootstrap_values = request.POST.get(consts.BOOTSTRAP_VALUES)
|
||||
bootstrap_sc_name = None
|
||||
if bootstrap_values is not None:
|
||||
bootstrap_values.file.seek(0, os.SEEK_SET)
|
||||
contents = bootstrap_values.file.read()
|
||||
data = yaml.safe_load(contents.decode('utf8'))
|
||||
bootstrap_sc_name = data.get('name')
|
||||
|
||||
return bootstrap_sc_name
|
||||
|
||||
|
||||
def get_region_value_from_subcloud(payload: dict):
|
||||
subcloud_region = None
|
||||
# It connects to the subcloud via the bootstrap-address IP and tries
|
||||
# to get the region from it
|
||||
if payload['bootstrap-address'] is not None:
|
||||
try:
|
||||
subcloud_region = utils.\
|
||||
get_region_from_subcloud_address(payload)
|
||||
LOG.info("Retrieved region value from subcloud to be migrated: %s"
|
||||
% subcloud_region)
|
||||
if subcloud_region is None:
|
||||
msg = ("Cannot find subcloud's region name from address: %s"
|
||||
% payload['bootstrap-address'])
|
||||
LOG.error(msg)
|
||||
raise exceptions.InvalidParameterValue(err=msg)
|
||||
except Exception:
|
||||
LOG.error("Unable to retrieve the region value from subcloud "
|
||||
"address %s" % payload['bootstrap-address'])
|
||||
raise
|
||||
return subcloud_region
|
||||
|
||||
|
||||
def is_migrate_scenario(payload: dict):
|
||||
migrate = False
|
||||
migrate_str = payload.get('migrate')
|
||||
|
||||
if migrate_str is not None:
|
||||
if migrate_str == "true":
|
||||
migrate = True
|
||||
return migrate
|
||||
|
||||
|
||||
def generate_subcloud_unique_region(context: RequestContext, payload: dict):
|
||||
LOG.debug("Begin generate subcloud unique region for subcloud %s"
|
||||
% payload['name'])
|
||||
|
||||
is_migrate = is_migrate_scenario(payload)
|
||||
migrate_sc_region = None
|
||||
|
||||
# If migration flag is present, tries to connect to subcloud to
|
||||
# get the region value
|
||||
if is_migrate:
|
||||
LOG.debug("The scenario matches that of the subcloud migration, "
|
||||
"therefore it will try to obtain the value of the "
|
||||
"region from subcloud %s..." % payload['name'])
|
||||
migrate_sc_region = get_region_value_from_subcloud(payload)
|
||||
else:
|
||||
LOG.debug("The scenario matches that of creating a new subcloud, "
|
||||
"so a region will be generated randomly for "
|
||||
"subcloud %s..." % payload['name'])
|
||||
while True:
|
||||
# If migrate flag is not present, creates a random region value
|
||||
if not is_migrate:
|
||||
subcloud_region = uuidutils.generate_uuid().replace("-", "")
|
||||
else:
|
||||
# In the migration/rehome scenario uses the region value
|
||||
# returned by queried subcloud
|
||||
subcloud_region = migrate_sc_region
|
||||
# Lookup region to check if exists
|
||||
try:
|
||||
db_api.subcloud_get_by_region_name(context,
|
||||
subcloud_region)
|
||||
LOG.info("Subcloud region: %s already exists. "
|
||||
"Generating new one..." % (subcloud_region))
|
||||
# In the migration scenario, it is intended to use the
|
||||
# same region that the current subcloud has, therefore
|
||||
# another region value cannot be generated.
|
||||
if is_migrate:
|
||||
LOG.error("Subcloud region to migrate: %s already exists "
|
||||
"and it is not allowed to generate a new region "
|
||||
"for a subcloud migration" % (subcloud_region))
|
||||
raise exceptions.SubcloudAlreadyExists(
|
||||
region_name=subcloud_region)
|
||||
except exceptions.SubcloudRegionNameNotFound:
|
||||
break
|
||||
except Exception:
|
||||
message = "Unable to generate subcloud region"
|
||||
LOG.error(message)
|
||||
raise
|
||||
if not is_migrate:
|
||||
LOG.info("Generated region for new subcloud %s: %s"
|
||||
% (payload.get('name'), subcloud_region))
|
||||
else:
|
||||
LOG.info("Region for subcloud %s to be migrated: %s"
|
||||
% (payload.get('name'), subcloud_region))
|
||||
return subcloud_region
|
||||
|
||||
|
||||
def subcloud_region_create(payload: dict, context: RequestContext):
|
||||
try:
|
||||
# Generates a unique region value
|
||||
payload['region_name'] = generate_subcloud_unique_region(context,
|
||||
payload)
|
||||
except Exception:
|
||||
# For logging purpose only
|
||||
msg = "Unable to generate or retrieve region value"
|
||||
if not is_migrate_scenario(payload):
|
||||
msg = "Unable to generate region value to update deploy \
|
||||
config for subcloud %s" % payload.get('name')
|
||||
LOG.exception(msg)
|
||||
pecan.abort(400, _(msg))
|
||||
|
|
|
@ -188,7 +188,7 @@ def validate_prestage(subcloud, payload):
|
|||
initial_subcloud_validate(subcloud, installed_loads, software_version)
|
||||
|
||||
subcloud_type, system_health, oam_floating_ip = \
|
||||
_get_prestage_subcloud_info(subcloud.name)
|
||||
_get_prestage_subcloud_info(subcloud)
|
||||
|
||||
if subcloud_type != consts.SYSTEM_MODE_SIMPLEX:
|
||||
raise exceptions.PrestagePreCheckFailedException(
|
||||
|
@ -287,18 +287,18 @@ def _prestage_standalone_thread(context, subcloud, payload):
|
|||
raise
|
||||
|
||||
|
||||
def _get_prestage_subcloud_info(subcloud_name):
|
||||
def _get_prestage_subcloud_info(subcloud):
|
||||
"""Retrieve prestage data from the subcloud.
|
||||
|
||||
Pull all required data here in order to minimize keystone/sysinv client
|
||||
interactions.
|
||||
"""
|
||||
try:
|
||||
os_client = OpenStackDriver(region_name=subcloud_name,
|
||||
os_client = OpenStackDriver(region_name=subcloud.region_name,
|
||||
region_clients=None)
|
||||
keystone_client = os_client.keystone_client
|
||||
endpoint = keystone_client.endpoint_cache.get_endpoint('sysinv')
|
||||
sysinv_client = SysinvClient(subcloud_name,
|
||||
sysinv_client = SysinvClient(subcloud.region_name,
|
||||
keystone_client.session,
|
||||
endpoint=endpoint)
|
||||
mode = sysinv_client.get_system().system_mode
|
||||
|
@ -309,7 +309,7 @@ def _get_prestage_subcloud_info(subcloud_name):
|
|||
except Exception as e:
|
||||
LOG.exception(e)
|
||||
raise exceptions.PrestagePreCheckFailedException(
|
||||
subcloud=subcloud_name,
|
||||
subcloud=subcloud.name,
|
||||
details="Failed to retrieve subcloud system mode and system health.")
|
||||
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ DC_MANAGER_GRPNAME = "root"
|
|||
|
||||
# Max lines output msg from logs
|
||||
MAX_LINES_MSG = 10
|
||||
REGION_VALUE_CMD = "grep " + consts.OS_REGION_NAME + " /etc/platform/openrc"
|
||||
|
||||
ABORT_UPDATE_STATUS = {
|
||||
consts.DEPLOY_STATE_INSTALLING: consts.DEPLOY_STATE_ABORTING_INSTALL,
|
||||
|
@ -552,23 +553,23 @@ def subcloud_db_list_to_dict(subclouds):
|
|||
for subcloud in subclouds]}
|
||||
|
||||
|
||||
def get_oam_addresses(subcloud_name, sc_ks_client):
|
||||
def get_oam_addresses(subcloud, sc_ks_client):
|
||||
"""Get the subclouds oam addresses"""
|
||||
|
||||
# First need to retrieve the Subcloud's Keystone session
|
||||
try:
|
||||
endpoint = sc_ks_client.endpoint_cache.get_endpoint('sysinv')
|
||||
sysinv_client = SysinvClient(subcloud_name,
|
||||
sysinv_client = SysinvClient(subcloud.region_name,
|
||||
sc_ks_client.session,
|
||||
endpoint=endpoint)
|
||||
return sysinv_client.get_oam_addresses()
|
||||
except (keystone_exceptions.EndpointNotFound, IndexError) as e:
|
||||
message = ("Identity endpoint for subcloud: %s not found. %s" %
|
||||
(subcloud_name, e))
|
||||
(subcloud.name, e))
|
||||
LOG.error(message)
|
||||
except dccommon_exceptions.OAMAddressesNotFound:
|
||||
message = ("OAM addresses for subcloud: %s not found." %
|
||||
subcloud_name)
|
||||
subcloud.name)
|
||||
LOG.error(message)
|
||||
return None
|
||||
|
||||
|
@ -596,6 +597,65 @@ def pre_check_management_affected_alarm(system_health):
|
|||
return True
|
||||
|
||||
|
||||
def is_subcloud_name_format_valid(name):
|
||||
"""Validates subcloud name format
|
||||
|
||||
Regex based on RFC 1123 subdomain validation
|
||||
|
||||
param: name = Subcloud name
|
||||
returns True if name is valid, otherwise it returns false.
|
||||
"""
|
||||
rex = r"[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*"
|
||||
|
||||
pat = re.compile(rex)
|
||||
if re.fullmatch(pat, name):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_region_from_subcloud_address(payload):
|
||||
"""Retrieves the current region from the subcloud being migrated
|
||||
|
||||
param: payload = Subcloud payload
|
||||
returns the OS_REGION_NAME value from subcloud
|
||||
"""
|
||||
cmd = [
|
||||
"sshpass",
|
||||
"-p",
|
||||
str(payload['sysadmin_password']),
|
||||
"ssh",
|
||||
"-q",
|
||||
"sysadmin@" + str(payload['bootstrap-address']),
|
||||
REGION_VALUE_CMD,
|
||||
]
|
||||
|
||||
try:
|
||||
LOG.info("Getting region value from subcloud %s" % payload['name'])
|
||||
task = subprocess.check_output(
|
||||
cmd,
|
||||
stderr=subprocess.STDOUT).decode('utf-8')
|
||||
if len(task) < 1:
|
||||
return None
|
||||
subcloud_region = str(task.split("=")[1]).strip()
|
||||
except Exception:
|
||||
LOG.error("Unable to get region value from subcloud %s"
|
||||
% payload['name'])
|
||||
raise
|
||||
|
||||
system_regions = [dccommon_consts.DEFAULT_REGION_NAME,
|
||||
dccommon_consts.SYSTEM_CONTROLLER_NAME]
|
||||
|
||||
if subcloud_region in system_regions:
|
||||
LOG.error("Invalid region value: %s" % subcloud_region)
|
||||
raise exceptions.InvalidParameterValue(
|
||||
err="Invalid region value: %s" % subcloud_region)
|
||||
|
||||
# Returns the region value from result:
|
||||
# Current systems: export OS_REGION_NAME=subcloudX
|
||||
# New systems: export OS_REGION_NAME=abcdefghhijlkmnopqrstuvqxyz12342
|
||||
return subcloud_region
|
||||
|
||||
|
||||
def find_ansible_error_msg(subcloud_name, log_file, stage=None):
|
||||
"""Find errors into ansible logs.
|
||||
|
||||
|
@ -817,15 +877,15 @@ def get_matching_iso(software_version=None):
|
|||
return None, str(e)
|
||||
|
||||
|
||||
def is_subcloud_healthy(subcloud_name):
|
||||
def is_subcloud_healthy(subcloud_region):
|
||||
|
||||
system_health = ""
|
||||
try:
|
||||
os_client = OpenStackDriver(region_name=subcloud_name,
|
||||
os_client = OpenStackDriver(region_name=subcloud_region,
|
||||
region_clients=None)
|
||||
keystone_client = os_client.keystone_client
|
||||
endpoint = keystone_client.endpoint_cache.get_endpoint('sysinv')
|
||||
sysinv_client = SysinvClient(subcloud_name,
|
||||
sysinv_client = SysinvClient(subcloud_region,
|
||||
keystone_client.session,
|
||||
endpoint=endpoint)
|
||||
system_health = sysinv_client.get_system_health()
|
||||
|
@ -1083,19 +1143,19 @@ def decode_and_normalize_passwd(input_passwd):
|
|||
return passwd
|
||||
|
||||
|
||||
def get_failure_msg(subcloud_name):
|
||||
def get_failure_msg(subcloud_region):
|
||||
try:
|
||||
os_client = OpenStackDriver(region_name=subcloud_name,
|
||||
os_client = OpenStackDriver(region_name=subcloud_region,
|
||||
region_clients=None)
|
||||
keystone_client = os_client.keystone_client
|
||||
endpoint = keystone_client.endpoint_cache.get_endpoint('sysinv')
|
||||
sysinv_client = SysinvClient(subcloud_name,
|
||||
sysinv_client = SysinvClient(subcloud_region,
|
||||
keystone_client.session,
|
||||
endpoint=endpoint)
|
||||
msg = sysinv_client.get_error_msg()
|
||||
return msg
|
||||
except Exception as e:
|
||||
LOG.exception("{}: {}".format(subcloud_name, e))
|
||||
LOG.exception("{}: {}".format(subcloud_region, e))
|
||||
return consts.ERROR_DESC_FAILED
|
||||
|
||||
|
||||
|
@ -1181,3 +1241,19 @@ def get_current_supported_upgrade_versions():
|
|||
supported_versions.append(version.strip())
|
||||
|
||||
return supported_versions
|
||||
|
||||
|
||||
# Feature: Subcloud Name Reconfiguration
|
||||
# This method is useful to determine the origin of the request
|
||||
# towards the api. The goal was to avoid any code changes in
|
||||
# the cert-monitor module, since it only needs the region reference.
|
||||
# When this method is called, the condition is applied to replace the
|
||||
# value of the "name" field with the value of the "region_name" field
|
||||
# in the response. In this way, the cert-monitor does not lose the
|
||||
# region reference in subcloud rename operation.
|
||||
def is_req_from_cert_mon_agent(request):
|
||||
ua = request.headers.get("User-Agent")
|
||||
if ua == consts.CERT_MON_HTTP_AGENT:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
|
|
@ -112,6 +112,7 @@ def subcloud_db_model_to_dict(subcloud):
|
|||
"backup-status": subcloud.backup_status,
|
||||
"backup-datetime": subcloud.backup_datetime,
|
||||
"error-description": subcloud.error_description,
|
||||
'region-name': subcloud.region_name,
|
||||
"management-subnet": subcloud.management_subnet,
|
||||
"management-start-ip": subcloud.management_start_ip,
|
||||
"management-end-ip": subcloud.management_end_ip,
|
||||
|
@ -132,14 +133,14 @@ def subcloud_create(context, name, description, location, software_version,
|
|||
management_subnet, management_gateway_ip,
|
||||
management_start_ip, management_end_ip,
|
||||
systemcontroller_gateway_ip, deploy_status, error_description,
|
||||
openstack_installed, group_id, data_install=None):
|
||||
region_name, openstack_installed, group_id, data_install=None):
|
||||
"""Create a subcloud."""
|
||||
return IMPL.subcloud_create(context, name, description, location,
|
||||
software_version,
|
||||
management_subnet, management_gateway_ip,
|
||||
management_start_ip, management_end_ip,
|
||||
systemcontroller_gateway_ip, deploy_status,
|
||||
error_description, openstack_installed, group_id,
|
||||
error_description, region_name, openstack_installed, group_id,
|
||||
data_install)
|
||||
|
||||
|
||||
|
@ -158,6 +159,16 @@ def subcloud_get_by_name(context, name) -> models.Subcloud:
|
|||
return IMPL.subcloud_get_by_name(context, name)
|
||||
|
||||
|
||||
def subcloud_get_by_region_name(context, region_name):
|
||||
"""Retrieve a subcloud by region name or raise if it does not exist."""
|
||||
return IMPL.subcloud_get_by_region_name(context, region_name)
|
||||
|
||||
|
||||
def subcloud_get_by_name_or_region_name(context, name):
|
||||
"""Retrieve a subcloud by name or region name or raise if it does not exist."""
|
||||
return IMPL.subcloud_get_by_name_or_region_name(context, name)
|
||||
|
||||
|
||||
def subcloud_get_all(context):
|
||||
"""Retrieve all subclouds."""
|
||||
return IMPL.subcloud_get_all(context)
|
||||
|
@ -174,7 +185,7 @@ def subcloud_get_all_with_status(context):
|
|||
|
||||
|
||||
def subcloud_update(context, subcloud_id, management_state=None,
|
||||
availability_status=None, software_version=None,
|
||||
availability_status=None, software_version=None, name=None,
|
||||
description=None, management_subnet=None, management_gateway_ip=None,
|
||||
management_start_ip=None, management_end_ip=None,
|
||||
location=None, audit_fail_count=None,
|
||||
|
@ -187,7 +198,7 @@ def subcloud_update(context, subcloud_id, management_state=None,
|
|||
rehome_data=None):
|
||||
"""Update a subcloud or raise if it does not exist."""
|
||||
return IMPL.subcloud_update(context, subcloud_id, management_state,
|
||||
availability_status, software_version,
|
||||
availability_status, software_version, name,
|
||||
description, management_subnet, management_gateway_ip,
|
||||
management_start_ip, management_end_ip, location,
|
||||
audit_fail_count, deploy_status, backup_status,
|
||||
|
@ -677,3 +688,7 @@ def subcloud_alarms_update(context, name, values):
|
|||
|
||||
def subcloud_alarms_delete(context, name):
|
||||
return IMPL.subcloud_alarms_delete(context, name)
|
||||
|
||||
|
||||
def subcloud_rename_alarms(context, subcloud_name, new_name):
|
||||
return IMPL.subcloud_rename_alarms(context, subcloud_name, new_name)
|
||||
|
|
|
@ -32,6 +32,7 @@ from oslo_utils import strutils
|
|||
from oslo_utils import uuidutils
|
||||
|
||||
from sqlalchemy import desc
|
||||
from sqlalchemy import or_
|
||||
from sqlalchemy.orm.exc import MultipleResultsFound
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
from sqlalchemy.orm import joinedload_all
|
||||
|
@ -317,6 +318,32 @@ def subcloud_get_by_name(context, name):
|
|||
return result
|
||||
|
||||
|
||||
@require_context
|
||||
def subcloud_get_by_region_name(context, region_name):
|
||||
result = model_query(context, models.Subcloud). \
|
||||
filter_by(deleted=0). \
|
||||
filter_by(region_name=region_name). \
|
||||
first()
|
||||
|
||||
if not result:
|
||||
raise exception.SubcloudRegionNameNotFound(region_name=region_name)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@require_context
|
||||
def subcloud_get_by_name_or_region_name(context, name):
|
||||
result = model_query(context, models.Subcloud). \
|
||||
filter_by(deleted=0). \
|
||||
filter(or_(models.Subcloud.name == name, models.Subcloud.region_name == name)). \
|
||||
first()
|
||||
|
||||
if not result:
|
||||
raise exception.SubcloudNameOrRegionNameNotFound(name=name)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@require_context
|
||||
def subcloud_get_all(context):
|
||||
return model_query(context, models.Subcloud). \
|
||||
|
@ -349,7 +376,7 @@ def subcloud_create(context, name, description, location, software_version,
|
|||
management_subnet, management_gateway_ip,
|
||||
management_start_ip, management_end_ip,
|
||||
systemcontroller_gateway_ip, deploy_status, error_description,
|
||||
openstack_installed, group_id,
|
||||
region_name, openstack_installed, group_id,
|
||||
data_install=None):
|
||||
with write_session() as session:
|
||||
subcloud_ref = models.Subcloud()
|
||||
|
@ -366,6 +393,7 @@ def subcloud_create(context, name, description, location, software_version,
|
|||
subcloud_ref.systemcontroller_gateway_ip = systemcontroller_gateway_ip
|
||||
subcloud_ref.deploy_status = deploy_status
|
||||
subcloud_ref.error_description = error_description
|
||||
subcloud_ref.region_name = region_name
|
||||
subcloud_ref.audit_fail_count = 0
|
||||
subcloud_ref.openstack_installed = openstack_installed
|
||||
subcloud_ref.group_id = group_id
|
||||
|
@ -381,7 +409,7 @@ def subcloud_create(context, name, description, location, software_version,
|
|||
@require_admin_context
|
||||
def subcloud_update(context, subcloud_id, management_state=None,
|
||||
availability_status=None, software_version=None,
|
||||
description=None, management_subnet=None,
|
||||
name=None, description=None, management_subnet=None,
|
||||
management_gateway_ip=None, management_start_ip=None,
|
||||
management_end_ip=None, location=None, audit_fail_count=None,
|
||||
deploy_status=None, backup_status=None,
|
||||
|
@ -401,6 +429,8 @@ def subcloud_update(context, subcloud_id, management_state=None,
|
|||
subcloud_ref.availability_status = availability_status
|
||||
if software_version is not None:
|
||||
subcloud_ref.software_version = software_version
|
||||
if name is not None:
|
||||
subcloud_ref.name = name
|
||||
if description is not None:
|
||||
subcloud_ref.description = description
|
||||
if management_subnet is not None:
|
||||
|
@ -1221,3 +1251,12 @@ def subcloud_alarms_delete(context, name):
|
|||
with write_session() as session:
|
||||
session.query(models.SubcloudAlarmSummary).\
|
||||
filter_by(name=name).delete()
|
||||
|
||||
|
||||
@require_admin_context
|
||||
def subcloud_rename_alarms(context, subcloud_name, new_name):
|
||||
with write_session() as session:
|
||||
result = _subcloud_alarms_get(context, subcloud_name)
|
||||
result.name = new_name
|
||||
result.save(session)
|
||||
return result
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# Copyright (c) 2023 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. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from sqlalchemy import Column, MetaData, String, Table
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
subclouds = Table('subclouds', meta, autoload=True)
|
||||
|
||||
# Add the 'region_name' column to the subclouds table.
|
||||
subclouds.create_column(Column('region_name',
|
||||
String(255)))
|
||||
|
||||
# populates region_name with name field value for existing subclouds
|
||||
if migrate_engine.name == 'postgresql':
|
||||
with migrate_engine.begin() as conn:
|
||||
conn.execute("UPDATE subclouds SET region_name = name")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
raise NotImplementedError('Database downgrade is unsupported.')
|
|
@ -148,6 +148,7 @@ class Subcloud(BASE, DCManagerBase):
|
|||
backup_status = Column(String(255))
|
||||
backup_datetime = Column(DateTime(timezone=False))
|
||||
error_description = Column(String(2048))
|
||||
region_name = Column(String(255), unique=True)
|
||||
data_upgrade = Column(String())
|
||||
management_subnet = Column(String(255))
|
||||
management_gateway_ip = Column(String(255))
|
||||
|
|
|
@ -110,6 +110,27 @@ class DCManagerService(service.Service):
|
|||
LOG.info("Handling delete_subcloud request for: %s" % subcloud_id)
|
||||
return self.subcloud_manager.delete_subcloud(context, subcloud_id)
|
||||
|
||||
@request_context
|
||||
def rename_subcloud(self, context, subcloud_id, curr_subcloud_name,
|
||||
new_subcloud_name=None):
|
||||
# Rename a subcloud
|
||||
LOG.info("Handling rename_subcloud request for: %s" %
|
||||
curr_subcloud_name)
|
||||
subcloud = self.subcloud_manager.rename_subcloud(context,
|
||||
subcloud_id,
|
||||
curr_subcloud_name,
|
||||
new_subcloud_name)
|
||||
return subcloud
|
||||
|
||||
@request_context
|
||||
def get_subcloud_name_by_region_name(self, context, subcloud_region):
|
||||
# get subcloud by region name
|
||||
LOG.debug("Handling get_subcloud_name_by_region_name request for "
|
||||
"region: %s" % subcloud_region)
|
||||
subcloud = self.subcloud_manager.get_subcloud_name_by_region_name(context,
|
||||
subcloud_region)
|
||||
return subcloud
|
||||
|
||||
@request_context
|
||||
def update_subcloud(self, context, subcloud_id, management_state=None,
|
||||
description=None, location=None,
|
||||
|
|
|
@ -179,10 +179,10 @@ class SubcloudManager(manager.Manager):
|
|||
|
||||
@staticmethod
|
||||
def _create_intermediate_ca_cert(payload):
|
||||
subcloud_name = payload["name"]
|
||||
cert_name = SubcloudManager._get_subcloud_cert_name(subcloud_name)
|
||||
subcloud_region = payload["region_name"]
|
||||
cert_name = SubcloudManager._get_subcloud_cert_name(subcloud_region)
|
||||
secret_name = SubcloudManager._get_subcloud_cert_secret_name(
|
||||
subcloud_name)
|
||||
subcloud_region)
|
||||
|
||||
cert = {
|
||||
"apiVersion": "%s/%s" % (kubeoperator.CERT_MANAGER_GROUP,
|
||||
|
@ -255,6 +255,7 @@ class SubcloudManager(manager.Manager):
|
|||
return install_command
|
||||
|
||||
def compose_bootstrap_command(self, subcloud_name,
|
||||
subcloud_region,
|
||||
ansible_subcloud_inventory_file,
|
||||
software_version=None):
|
||||
bootstrap_command = [
|
||||
|
@ -268,7 +269,7 @@ class SubcloudManager(manager.Manager):
|
|||
# which overrides to load
|
||||
bootstrap_command += [
|
||||
"-e", str("override_files_dir='%s' region_name=%s") % (
|
||||
dccommon_consts.ANSIBLE_OVERRIDES_PATH, subcloud_name),
|
||||
dccommon_consts.ANSIBLE_OVERRIDES_PATH, subcloud_region),
|
||||
"-e", "install_release_version=%s" %
|
||||
software_version if software_version else SW_VERSION]
|
||||
return bootstrap_command
|
||||
|
@ -324,7 +325,7 @@ class SubcloudManager(manager.Manager):
|
|||
subcloud_name + "_update_values.yml"]
|
||||
return subcloud_update_command
|
||||
|
||||
def compose_rehome_command(self, subcloud_name,
|
||||
def compose_rehome_command(self, subcloud_name, subcloud_region,
|
||||
ansible_subcloud_inventory_file,
|
||||
software_version):
|
||||
rehome_command = [
|
||||
|
@ -335,7 +336,7 @@ class SubcloudManager(manager.Manager):
|
|||
"--limit", subcloud_name,
|
||||
"--timeout", REHOME_PLAYBOOK_TIMEOUT,
|
||||
"-e", str("override_files_dir='%s' region_name=%s") % (
|
||||
dccommon_consts.ANSIBLE_OVERRIDES_PATH, subcloud_name)]
|
||||
dccommon_consts.ANSIBLE_OVERRIDES_PATH, subcloud_region)]
|
||||
return rehome_command
|
||||
|
||||
def migrate_subcloud(self, context, subcloud_ref, payload):
|
||||
|
@ -394,6 +395,7 @@ class SubcloudManager(manager.Manager):
|
|||
|
||||
rehome_command = self.compose_rehome_command(
|
||||
subcloud.name,
|
||||
subcloud.region_name,
|
||||
ansible_subcloud_inventory_file,
|
||||
subcloud.software_version)
|
||||
|
||||
|
@ -407,7 +409,7 @@ class SubcloudManager(manager.Manager):
|
|||
:param subcloud_id: id of the subcloud
|
||||
:param payload: subcloud configuration
|
||||
"""
|
||||
LOG.info(f"Adding subcloud {payload['name']}.")
|
||||
LOG.info(f"Adding subcloud {payload['name']} with region {payload['region_name']}.")
|
||||
|
||||
rehoming = payload.get('migrate', '').lower() == "true"
|
||||
secondary = (payload.get('secondary', '').lower() == "true")
|
||||
|
@ -653,6 +655,7 @@ class SubcloudManager(manager.Manager):
|
|||
|
||||
bootstrap_command = self.compose_bootstrap_command(
|
||||
subcloud.name,
|
||||
subcloud.region_name,
|
||||
ansible_subcloud_inventory_file,
|
||||
subcloud.software_version)
|
||||
return bootstrap_command
|
||||
|
@ -923,7 +926,7 @@ class SubcloudManager(manager.Manager):
|
|||
endpoint["id"],
|
||||
endpoint['admin_endpoint_url'],
|
||||
interface=dccommon_consts.KS_ENDPOINT_ADMIN,
|
||||
region=subcloud.name)
|
||||
region=subcloud.region_name)
|
||||
except Exception as e:
|
||||
# Keystone service must be temporarily busy, retry
|
||||
LOG.error(str(e))
|
||||
|
@ -931,11 +934,11 @@ class SubcloudManager(manager.Manager):
|
|||
endpoint["id"],
|
||||
endpoint['admin_endpoint_url'],
|
||||
interface=dccommon_consts.KS_ENDPOINT_ADMIN,
|
||||
region=subcloud.name)
|
||||
region=subcloud.region_name)
|
||||
|
||||
# Inform orchestrator that subcloud has been added
|
||||
self.dcorch_rpc_client.add_subcloud(
|
||||
context, subcloud.name, subcloud.software_version)
|
||||
context, subcloud.region_name, subcloud.software_version)
|
||||
|
||||
# create entry into alarm summary table, will get real values later
|
||||
alarm_updates = {'critical_alarms': -1,
|
||||
|
@ -1282,7 +1285,7 @@ class SubcloudManager(manager.Manager):
|
|||
def _backup_subcloud(self, context, payload, subcloud):
|
||||
try:
|
||||
# Health check validation
|
||||
if not utils.is_subcloud_healthy(subcloud.name):
|
||||
if not utils.is_subcloud_healthy(subcloud.region_name):
|
||||
db_api.subcloud_update(
|
||||
context,
|
||||
subcloud.id,
|
||||
|
@ -1442,9 +1445,9 @@ class SubcloudManager(manager.Manager):
|
|||
else:
|
||||
# Use subcloud floating IP for host reachability
|
||||
keystone_client = OpenStackDriver(
|
||||
region_name=subcloud.name,
|
||||
region_name=subcloud.region_name,
|
||||
region_clients=None).keystone_client
|
||||
oam_fip = utils.get_oam_addresses(subcloud.name, keystone_client)\
|
||||
oam_fip = utils.get_oam_addresses(subcloud, keystone_client)\
|
||||
.oam_floating_ip
|
||||
|
||||
# Add parameters used to generate inventory
|
||||
|
@ -2042,10 +2045,10 @@ class SubcloudManager(manager.Manager):
|
|||
1)
|
||||
|
||||
@staticmethod
|
||||
def _delete_subcloud_cert(subcloud_name):
|
||||
cert_name = SubcloudManager._get_subcloud_cert_name(subcloud_name)
|
||||
def _delete_subcloud_cert(subcloud_region):
|
||||
cert_name = SubcloudManager._get_subcloud_cert_name(subcloud_region)
|
||||
secret_name = SubcloudManager._get_subcloud_cert_secret_name(
|
||||
subcloud_name)
|
||||
subcloud_region)
|
||||
|
||||
kube = kubeoperator.KubeOperator()
|
||||
kube.delete_cert_manager_certificate(CERT_NAMESPACE, cert_name)
|
||||
|
@ -2059,7 +2062,7 @@ class SubcloudManager(manager.Manager):
|
|||
"""Remove subcloud details from database and inform orchestrators"""
|
||||
# Inform orchestrators that subcloud has been deleted
|
||||
try:
|
||||
self.dcorch_rpc_client.del_subcloud(context, subcloud.name)
|
||||
self.dcorch_rpc_client.del_subcloud(context, subcloud.region_name)
|
||||
except RemoteError as e:
|
||||
# TODO(kmacleod): this should be caught as explicit remote exception
|
||||
# Fix when centos/python2 is no longer supported
|
||||
|
@ -2083,8 +2086,8 @@ class SubcloudManager(manager.Manager):
|
|||
region_clients=None).keystone_client
|
||||
|
||||
# Delete keystone endpoints for subcloud
|
||||
keystone_client.delete_endpoints(subcloud.name)
|
||||
keystone_client.delete_region(subcloud.name)
|
||||
keystone_client.delete_endpoints(subcloud.region_name)
|
||||
keystone_client.delete_region(subcloud.region_name)
|
||||
|
||||
# Delete the routes to this subcloud
|
||||
self._delete_subcloud_routes(keystone_client, subcloud)
|
||||
|
@ -2100,7 +2103,7 @@ class SubcloudManager(manager.Manager):
|
|||
utils.delete_subcloud_inventory(ansible_subcloud_inventory_file)
|
||||
|
||||
# Delete the subcloud intermediate certificate
|
||||
SubcloudManager._delete_subcloud_cert(subcloud.name)
|
||||
SubcloudManager._delete_subcloud_cert(subcloud.region_name)
|
||||
|
||||
# Delete the subcloud backup path
|
||||
self._delete_subcloud_backup_data(subcloud.name)
|
||||
|
@ -2142,6 +2145,42 @@ class SubcloudManager(manager.Manager):
|
|||
if os.path.exists(install_path):
|
||||
shutil.rmtree(install_path)
|
||||
|
||||
def _rename_subcloud_ansible_files(self, cur_sc_name, new_sc_name):
|
||||
"""Renames the ansible and logs files from the given subcloud"""
|
||||
|
||||
ansible_path = dccommon_consts.ANSIBLE_OVERRIDES_PATH
|
||||
log_path = consts.DC_ANSIBLE_LOG_DIR
|
||||
|
||||
ansible_file_list = os.listdir(ansible_path)
|
||||
log_file_list = os.listdir(log_path)
|
||||
|
||||
ansible_file_list = [ansible_path + '/' + x for x in ansible_file_list]
|
||||
log_file_list = [log_path + '/' + x for x in log_file_list]
|
||||
|
||||
for cur_file in ansible_file_list + log_file_list:
|
||||
new_file = cur_file.replace(cur_sc_name, new_sc_name)
|
||||
if os.path.exists(cur_file) and new_sc_name in new_file:
|
||||
os.rename(cur_file, new_file)
|
||||
|
||||
# Gets new ansible inventory file
|
||||
ansible_inv_file = self._get_ansible_filename(new_sc_name,
|
||||
INVENTORY_FILE_POSTFIX)
|
||||
|
||||
# Updates inventory host param with the new subcloud name
|
||||
with open(ansible_inv_file, 'r') as f:
|
||||
data = yaml.safe_load(f)
|
||||
|
||||
mkey = list(data.keys())[0]
|
||||
|
||||
if mkey in data and 'hosts' in data[mkey] and \
|
||||
cur_sc_name in data[mkey]['hosts']:
|
||||
|
||||
data[mkey]['hosts'][new_sc_name] = \
|
||||
data[mkey]['hosts'].pop(cur_sc_name)
|
||||
|
||||
with open(ansible_inv_file, 'w') as f:
|
||||
yaml.dump(data, f, sort_keys=False)
|
||||
|
||||
@staticmethod
|
||||
def _delete_subcloud_backup_data(subcloud_name):
|
||||
try:
|
||||
|
@ -2208,6 +2247,62 @@ class SubcloudManager(manager.Manager):
|
|||
(subcloud.name, alarm_id))
|
||||
LOG.exception(e)
|
||||
|
||||
def rename_subcloud(self,
|
||||
context,
|
||||
subcloud_id,
|
||||
curr_subcloud_name,
|
||||
new_subcloud_name=None):
|
||||
"""Rename subcloud.
|
||||
|
||||
:param context: request context object.
|
||||
:param subcloud_id: id of subcloud to rename
|
||||
:param curr_subcloud_name: current subcloud name
|
||||
:param new_subcloud_name: new subcloud name
|
||||
"""
|
||||
try:
|
||||
subcloud = db_api.\
|
||||
subcloud_get_by_name_or_region_name(context,
|
||||
new_subcloud_name)
|
||||
except exceptions.SubcloudNameOrRegionNameNotFound:
|
||||
pass
|
||||
else:
|
||||
# If the found subcloud id is not the same as the received
|
||||
# subcloud id, it indicates that the name change does not
|
||||
# correspond to the current subcloud.
|
||||
# Therefore it is not allowed to change the name.
|
||||
if subcloud_id != subcloud.id:
|
||||
raise exceptions.SubcloudOrRegionNameAlreadyExists(
|
||||
name=new_subcloud_name)
|
||||
|
||||
# updates subcloud name
|
||||
subcloud = db_api.subcloud_update(context, subcloud_id,
|
||||
name=new_subcloud_name)
|
||||
# updates subcloud names on alarms
|
||||
db_api.subcloud_rename_alarms(context, curr_subcloud_name,
|
||||
new_subcloud_name)
|
||||
# Deletes subcloud alarms
|
||||
entity_instance_id = "subcloud=%s" % curr_subcloud_name
|
||||
self.fm_api.clear_all(entity_instance_id)
|
||||
|
||||
# Regenerate the dnsmasq host entry
|
||||
self._create_addn_hosts_dc(context)
|
||||
|
||||
# Rename related subcloud files
|
||||
self._rename_subcloud_ansible_files(curr_subcloud_name,
|
||||
new_subcloud_name)
|
||||
|
||||
return subcloud
|
||||
|
||||
def get_subcloud_name_by_region_name(self,
|
||||
context,
|
||||
subcloud_region):
|
||||
subcloud_name = None
|
||||
if subcloud_region is not None:
|
||||
sc = db_api.subcloud_get_by_region_name(context, subcloud_region)
|
||||
subcloud_name = sc.get("name")
|
||||
|
||||
return subcloud_name
|
||||
|
||||
def update_subcloud(self,
|
||||
context,
|
||||
subcloud_id,
|
||||
|
@ -2363,7 +2458,7 @@ class SubcloudManager(manager.Manager):
|
|||
# Inform orchestrator of state change
|
||||
self.dcorch_rpc_client.update_subcloud_states(
|
||||
context,
|
||||
subcloud.name,
|
||||
subcloud.region_name,
|
||||
management_state,
|
||||
subcloud.availability_status)
|
||||
|
||||
|
@ -2391,6 +2486,7 @@ class SubcloudManager(manager.Manager):
|
|||
self.state_rpc_client.update_subcloud_endpoint_status_sync(
|
||||
context,
|
||||
subcloud_name=subcloud.name,
|
||||
subcloud_region=subcloud.region_name,
|
||||
endpoint_type=None,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_UNKNOWN,
|
||||
ignore_endpoints=[dccommon_consts.ENDPOINT_TYPE_DC_CERT])
|
||||
|
@ -2399,7 +2495,7 @@ class SubcloudManager(manager.Manager):
|
|||
# Tell cert-mon to audit endpoint certificate
|
||||
LOG.info('Request certmon audit for %s' % subcloud.name)
|
||||
dc_notification = dcmanager_rpc_client.DCManagerNotifications()
|
||||
dc_notification.subcloud_managed(context, subcloud.name)
|
||||
dc_notification.subcloud_managed(context, subcloud.region_name)
|
||||
|
||||
return db_api.subcloud_db_model_to_dict(subcloud)
|
||||
|
||||
|
@ -2487,6 +2583,7 @@ class SubcloudManager(manager.Manager):
|
|||
:param update_db: whether it should update the db on success/failure
|
||||
"""
|
||||
subcloud_name = subcloud.name
|
||||
subcloud_region = subcloud.region_name
|
||||
subcloud_id = subcloud.id
|
||||
sys_controller_gw_ip = payload.get("systemcontroller_gateway_address",
|
||||
subcloud.systemcontroller_gateway_ip)
|
||||
|
@ -2509,7 +2606,7 @@ class SubcloudManager(manager.Manager):
|
|||
return
|
||||
try:
|
||||
self._update_services_endpoint(
|
||||
context, payload, subcloud_name, m_ks_client)
|
||||
context, payload, subcloud_region, m_ks_client)
|
||||
except Exception:
|
||||
LOG.exception("Failed to update subcloud %s endpoints" % subcloud_name)
|
||||
if update_db:
|
||||
|
@ -2541,7 +2638,7 @@ class SubcloudManager(manager.Manager):
|
|||
1)
|
||||
|
||||
def _update_services_endpoint(
|
||||
self, context, payload, subcloud_name, m_ks_client):
|
||||
self, context, payload, subcloud_region, m_ks_client):
|
||||
endpoint_ip = utils.get_management_start_address(payload)
|
||||
if netaddr.IPAddress(endpoint_ip).version == 6:
|
||||
endpoint_ip = f"[{endpoint_ip}]"
|
||||
|
@ -2556,7 +2653,7 @@ class SubcloudManager(manager.Manager):
|
|||
}
|
||||
|
||||
for endpoint in m_ks_client.keystone_client.endpoints.list(
|
||||
region=subcloud_name):
|
||||
region=subcloud_region):
|
||||
service_type = m_ks_client.keystone_client.services.get(
|
||||
endpoint.service_id).type
|
||||
if service_type == dccommon_consts.ENDPOINT_TYPE_PLATFORM:
|
||||
|
@ -2576,17 +2673,17 @@ class SubcloudManager(manager.Manager):
|
|||
m_ks_client.keystone_client.endpoints.update(
|
||||
endpoint, url=admin_endpoint_url)
|
||||
|
||||
LOG.info("Update services endpoint to %s in subcloud %s" % (
|
||||
endpoint_ip, subcloud_name))
|
||||
LOG.info("Update services endpoint to %s in subcloud region %s" % (
|
||||
endpoint_ip, subcloud_region))
|
||||
# Update service URLs in subcloud endpoint cache
|
||||
self.audit_rpc_client.trigger_subcloud_endpoints_update(
|
||||
context, subcloud_name, services_endpoints)
|
||||
context, subcloud_region, services_endpoints)
|
||||
self.dcorch_rpc_client.update_subcloud_endpoints(
|
||||
context, subcloud_name, services_endpoints)
|
||||
context, subcloud_region, services_endpoints)
|
||||
# Update sysinv URL in cert-mon cache
|
||||
dc_notification = dcmanager_rpc_client.DCManagerNotifications()
|
||||
dc_notification.subcloud_sysinv_endpoint_update(
|
||||
context, subcloud_name, services_endpoints.get("sysinv"))
|
||||
context, subcloud_region, services_endpoints.get("sysinv"))
|
||||
|
||||
def _create_subcloud_update_overrides_file(
|
||||
self, payload, subcloud_name, filename_suffix):
|
||||
|
@ -2630,7 +2727,7 @@ class SubcloudManager(manager.Manager):
|
|||
payload['override_values']['sc_ca_key'] = payload['sc_ca_key']
|
||||
|
||||
def update_subcloud_sync_endpoint_type(self, context,
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
endpoint_type_list,
|
||||
openstack_installed):
|
||||
operation = 'add' if openstack_installed else 'remove'
|
||||
|
@ -2646,17 +2743,17 @@ class SubcloudManager(manager.Manager):
|
|||
}
|
||||
|
||||
try:
|
||||
subcloud = db_api.subcloud_get_by_name(context, subcloud_name)
|
||||
subcloud = db_api.subcloud_get_by_region_name(context, subcloud_region)
|
||||
except Exception:
|
||||
LOG.exception("Failed to get subcloud by name: %s" % subcloud_name)
|
||||
LOG.exception("Failed to get subcloud by region name: %s" % subcloud_region)
|
||||
raise
|
||||
|
||||
try:
|
||||
# Notify dcorch to add/remove sync endpoint type list
|
||||
func_switcher[operation][0](self.context, subcloud_name,
|
||||
func_switcher[operation][0](self.context, subcloud_region,
|
||||
endpoint_type_list)
|
||||
LOG.info('Notifying dcorch, subcloud: %s new sync endpoint: %s' %
|
||||
(subcloud_name, endpoint_type_list))
|
||||
(subcloud.name, endpoint_type_list))
|
||||
|
||||
# Update subcloud status table by adding/removing openstack sync
|
||||
# endpoint types
|
||||
|
@ -2668,7 +2765,7 @@ class SubcloudManager(manager.Manager):
|
|||
openstack_installed=openstack_installed)
|
||||
except Exception:
|
||||
LOG.exception('Problem informing dcorch of subcloud sync endpoint'
|
||||
' type change, subcloud: %s' % subcloud_name)
|
||||
' type change, subcloud region: %s' % subcloud_region)
|
||||
|
||||
def handle_subcloud_operations_in_progress(self):
|
||||
"""Identify subclouds in transitory stages and update subcloud
|
||||
|
|
|
@ -156,6 +156,14 @@ class OrchThread(threading.Thread):
|
|||
@staticmethod
|
||||
def get_region_name(strategy_step):
|
||||
"""Get the region name for a strategy step"""
|
||||
if strategy_step.subcloud_id is None:
|
||||
# This is the SystemController.
|
||||
return dccommon_consts.DEFAULT_REGION_NAME
|
||||
return strategy_step.subcloud.region_name
|
||||
|
||||
@staticmethod
|
||||
def get_subcloud_name(strategy_step):
|
||||
"""Get the subcloud name for a strategy step"""
|
||||
if strategy_step.subcloud_id is None:
|
||||
# This is the SystemController.
|
||||
return dccommon_consts.DEFAULT_REGION_NAME
|
||||
|
@ -263,18 +271,18 @@ class OrchThread(threading.Thread):
|
|||
for strategy_step in strategy_steps:
|
||||
if strategy_step.state == consts.STRATEGY_STATE_COMPLETE:
|
||||
# This step is complete
|
||||
self._delete_subcloud_worker(strategy_step.subcloud.name,
|
||||
self._delete_subcloud_worker(strategy_step.subcloud.region_name,
|
||||
strategy_step.subcloud_id)
|
||||
continue
|
||||
elif strategy_step.state == consts.STRATEGY_STATE_ABORTED:
|
||||
# This step was aborted
|
||||
self._delete_subcloud_worker(strategy_step.subcloud.name,
|
||||
self._delete_subcloud_worker(strategy_step.subcloud.region_name,
|
||||
strategy_step.subcloud_id)
|
||||
abort_detected = True
|
||||
continue
|
||||
elif strategy_step.state == consts.STRATEGY_STATE_FAILED:
|
||||
failure_detected = True
|
||||
self._delete_subcloud_worker(strategy_step.subcloud.name,
|
||||
self._delete_subcloud_worker(strategy_step.subcloud.region_name,
|
||||
strategy_step.subcloud_id)
|
||||
# This step has failed and needs no further action
|
||||
if strategy_step.subcloud_id is None:
|
||||
|
@ -572,7 +580,7 @@ class OrchThread(threading.Thread):
|
|||
% (self.update_type,
|
||||
strategy_step.stage,
|
||||
strategy_step.state,
|
||||
self.get_region_name(strategy_step)))
|
||||
self.get_subcloud_name(strategy_step)))
|
||||
# Instantiate the state operator and perform the state actions
|
||||
state_operator = self.determine_state_operator(strategy_step)
|
||||
state_operator.registerStopEvent(self._stop)
|
||||
|
@ -585,7 +593,7 @@ class OrchThread(threading.Thread):
|
|||
% (self.update_type,
|
||||
strategy_step.stage,
|
||||
strategy_step.state,
|
||||
self.get_region_name(strategy_step)))
|
||||
strategy_step.subcloud.name))
|
||||
# Transition immediately to complete. Update the details to show
|
||||
# that this subcloud has been skipped
|
||||
details = self.format_update_details(None, str(ex))
|
||||
|
@ -598,7 +606,7 @@ class OrchThread(threading.Thread):
|
|||
% (self.update_type,
|
||||
strategy_step.stage,
|
||||
strategy_step.state,
|
||||
self.get_region_name(strategy_step)))
|
||||
strategy_step.subcloud.name))
|
||||
details = self.format_update_details(strategy_step.state, str(ex))
|
||||
self.strategy_step_update(strategy_step.subcloud_id,
|
||||
state=consts.STRATEGY_STATE_FAILED,
|
||||
|
|
|
@ -55,39 +55,47 @@ class BaseState(object):
|
|||
LOG.debug("Stage: %s, State: %s, Subcloud: %s, Details: %s"
|
||||
% (strategy_step.stage,
|
||||
strategy_step.state,
|
||||
self.get_region_name(strategy_step),
|
||||
self.get_subcloud_name(strategy_step),
|
||||
details))
|
||||
|
||||
def info_log(self, strategy_step, details):
|
||||
LOG.info("Stage: %s, State: %s, Subcloud: %s, Details: %s"
|
||||
% (strategy_step.stage,
|
||||
strategy_step.state,
|
||||
self.get_region_name(strategy_step),
|
||||
self.get_subcloud_name(strategy_step),
|
||||
details))
|
||||
|
||||
def warn_log(self, strategy_step, details):
|
||||
LOG.warn("Stage: %s, State: %s, Subcloud: %s, Details: %s"
|
||||
% (strategy_step.stage,
|
||||
strategy_step.state,
|
||||
self.get_region_name(strategy_step),
|
||||
self.get_subcloud_name(strategy_step),
|
||||
details))
|
||||
|
||||
def error_log(self, strategy_step, details):
|
||||
LOG.error("Stage: %s, State: %s, Subcloud: %s, Details: %s"
|
||||
% (strategy_step.stage,
|
||||
strategy_step.state,
|
||||
self.get_region_name(strategy_step),
|
||||
self.get_subcloud_name(strategy_step),
|
||||
details))
|
||||
|
||||
def exception_log(self, strategy_step, details):
|
||||
LOG.exception("Stage: %s, State: %s, Subcloud: %s, Details: %s"
|
||||
% (strategy_step.stage,
|
||||
strategy_step.state,
|
||||
self.get_region_name(strategy_step),
|
||||
self.get_subcloud_name(strategy_step),
|
||||
details))
|
||||
|
||||
@staticmethod
|
||||
def get_region_name(strategy_step):
|
||||
"""Get the region name for a strategy step"""
|
||||
if strategy_step.subcloud_id is None:
|
||||
# This is the SystemController.
|
||||
return dccommon_consts.DEFAULT_REGION_NAME
|
||||
return strategy_step.subcloud.region_name
|
||||
|
||||
@staticmethod
|
||||
def get_subcloud_name(strategy_step):
|
||||
"""Get the region name for a strategy step"""
|
||||
if strategy_step.subcloud_id is None:
|
||||
# This is the SystemController.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2020-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2020-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -33,10 +33,11 @@ class FinishingFwUpdateState(BaseState):
|
|||
% (dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
dccommon_consts.SYNC_STATUS_IN_SYNC))
|
||||
dcmanager_state_rpc_client = dcmanager_rpc_client.SubcloudStateClient()
|
||||
# The subcloud name is the same as the region in the strategy_step
|
||||
# The subcloud name may differ from the region name in the strategy_step
|
||||
dcmanager_state_rpc_client.update_subcloud_endpoint_status(
|
||||
self.context,
|
||||
subcloud_name=self.get_region_name(strategy_step),
|
||||
subcloud_name=self.get_subcloud_name(strategy_step),
|
||||
subcloud_region=self.get_region_name(strategy_step),
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2020-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2020-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -33,7 +33,7 @@ class LockHostState(BaseState):
|
|||
"""
|
||||
|
||||
# Create a sysinv client on the subcloud
|
||||
sysinv_client = self.get_sysinv_client(strategy_step.subcloud.name)
|
||||
sysinv_client = self.get_sysinv_client(strategy_step.subcloud.region_name)
|
||||
|
||||
host = sysinv_client.get_host(self.target_hostname)
|
||||
|
||||
|
@ -58,7 +58,7 @@ class LockHostState(BaseState):
|
|||
raise StrategyStoppedException()
|
||||
# query the administrative state to see if it is the new state.
|
||||
host = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).get_host(self.target_hostname)
|
||||
strategy_step.subcloud.region_name).get_host(self.target_hostname)
|
||||
if host.administrative == consts.ADMIN_LOCKED:
|
||||
msg = "Host: %s is now: %s" % (self.target_hostname,
|
||||
host.administrative)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2020-2021 Wind River Systems, Inc.
|
||||
# Copyright (c) 2020-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -61,7 +61,7 @@ class UnlockHostState(BaseState):
|
|||
"""
|
||||
|
||||
# Retrieve host from sysinv client on the subcloud
|
||||
host = self._get_host_with_retry(strategy_step.subcloud.name)
|
||||
host = self._get_host_with_retry(strategy_step.subcloud.region_name)
|
||||
|
||||
# if the host is already in the desired state, no need for action
|
||||
if self.check_host_ready(host):
|
||||
|
@ -85,7 +85,7 @@ class UnlockHostState(BaseState):
|
|||
while True:
|
||||
try:
|
||||
response = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).unlock_host(host.id)
|
||||
strategy_step.subcloud.region_name).unlock_host(host.id)
|
||||
if (response.ihost_action != 'unlock' or
|
||||
response.task != 'Unlocking'):
|
||||
raise Exception("Unable to unlock host %s"
|
||||
|
@ -113,7 +113,7 @@ class UnlockHostState(BaseState):
|
|||
try:
|
||||
# query the administrative state to see if it is the new state.
|
||||
host = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).get_host(self.target_hostname)
|
||||
strategy_step.subcloud.region_name).get_host(self.target_hostname)
|
||||
if self.check_host_ready(host):
|
||||
# Success. Break out of the loop.
|
||||
msg = "Host: %s is now: %s %s %s" % (self.target_hostname,
|
||||
|
|
|
@ -38,7 +38,7 @@ class ActivatingUpgradeState(BaseState):
|
|||
def get_upgrade_state(self, strategy_step):
|
||||
try:
|
||||
upgrades = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).get_upgrades()
|
||||
strategy_step.subcloud.region_name).get_upgrades()
|
||||
|
||||
except Exception as exception:
|
||||
self.warn_log(strategy_step,
|
||||
|
@ -86,7 +86,7 @@ class ActivatingUpgradeState(BaseState):
|
|||
|
||||
# if max retries have occurred, fail the state
|
||||
if activate_retry_counter >= self.max_failed_retries:
|
||||
error_msg = utils.get_failure_msg(strategy_step.subcloud.name)
|
||||
error_msg = utils.get_failure_msg(strategy_step.subcloud.region_name)
|
||||
db_api.subcloud_update(
|
||||
self.context, strategy_step.subcloud_id,
|
||||
error_description=error_msg[0:consts.ERROR_DESCRIPTION_LENGTH])
|
||||
|
@ -104,7 +104,7 @@ class ActivatingUpgradeState(BaseState):
|
|||
# (no upgrade found, bad host state, auth)
|
||||
try:
|
||||
self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).upgrade_activate()
|
||||
strategy_step.subcloud.region_name).upgrade_activate()
|
||||
first_activate = False # clear first activation flag
|
||||
activate_retry_counter = 0 # reset activation retries
|
||||
except Exception as exception:
|
||||
|
@ -129,7 +129,7 @@ class ActivatingUpgradeState(BaseState):
|
|||
% upgrade_state)
|
||||
try:
|
||||
self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).upgrade_activate()
|
||||
strategy_step.subcloud.region_name).upgrade_activate()
|
||||
except Exception as exception:
|
||||
self.warn_log(strategy_step,
|
||||
"Encountered exception: %s, "
|
||||
|
@ -147,7 +147,7 @@ class ActivatingUpgradeState(BaseState):
|
|||
break
|
||||
audit_counter += 1
|
||||
if audit_counter >= self.max_queries:
|
||||
error_msg = utils.get_failure_msg(strategy_step.subcloud.name)
|
||||
error_msg = utils.get_failure_msg(strategy_step.subcloud.region_name)
|
||||
db_api.subcloud_update(
|
||||
self.context, strategy_step.subcloud_id,
|
||||
error_description=error_msg[0:consts.ERROR_DESCRIPTION_LENGTH])
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2020 Wind River Systems, Inc.
|
||||
# Copyright (c) 2020-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -32,7 +32,7 @@ class DeletingLoadState(BaseState):
|
|||
Any exceptions raised by this method set the strategy to FAILED.
|
||||
"""
|
||||
# get the sysinv client for the subcloud
|
||||
sysinv_client = self.get_sysinv_client(strategy_step.subcloud.name)
|
||||
sysinv_client = self.get_sysinv_client(strategy_step.subcloud.region_name)
|
||||
current_loads = sysinv_client.get_loads()
|
||||
load_id = None
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2020-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2020-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -56,7 +56,7 @@ class FinishingPatchStrategyState(BaseState):
|
|||
"RegionOne committed_patch_ids: %s" % committed_patch_ids)
|
||||
|
||||
subcloud_patches = self.get_patching_client(
|
||||
strategy_step.subcloud.name).query()
|
||||
strategy_step.subcloud.region_name).query()
|
||||
self.debug_log(strategy_step,
|
||||
"Patches for subcloud: %s" % subcloud_patches)
|
||||
|
||||
|
@ -93,6 +93,6 @@ class FinishingPatchStrategyState(BaseState):
|
|||
self.info_log(strategy_step,
|
||||
"Committing patches %s in subcloud" % patches_to_commit)
|
||||
self.get_patching_client(
|
||||
strategy_step.subcloud.name).commit(patches_to_commit)
|
||||
strategy_step.subcloud.region_name).commit(patches_to_commit)
|
||||
|
||||
return self.next_state
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2020-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2020-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -49,13 +49,13 @@ class ImportingLoadState(BaseState):
|
|||
self.info_log(strategy_step, "Retrieving load list from subcloud...")
|
||||
# success when only one load, the active load, remains
|
||||
if len(self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).get_loads()) == 1:
|
||||
strategy_step.subcloud.region_name).get_loads()) == 1:
|
||||
msg = "Load: %s has been removed." % load_version
|
||||
self.info_log(strategy_step, msg)
|
||||
return True
|
||||
else:
|
||||
load = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).get_load(load_id)
|
||||
strategy_step.subcloud.region_name).get_load(load_id)
|
||||
if load.state == consts.IMPORTED_LOAD_STATE:
|
||||
# success when load is imported
|
||||
msg = "Load: %s is now: %s" % (load_version,
|
||||
|
@ -102,7 +102,7 @@ class ImportingLoadState(BaseState):
|
|||
load_info = {}
|
||||
# Check if the load is already imported by checking the version
|
||||
current_loads = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).get_loads()
|
||||
strategy_step.subcloud.region_name).get_loads()
|
||||
|
||||
for load in current_loads:
|
||||
if load.software_version == target_version:
|
||||
|
@ -140,12 +140,12 @@ class ImportingLoadState(BaseState):
|
|||
self.info_log(strategy_step,
|
||||
"Deleting load %s..." % load_id_to_be_deleted)
|
||||
self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).delete_load(load_id_to_be_deleted)
|
||||
strategy_step.subcloud.region_name).delete_load(load_id_to_be_deleted)
|
||||
req_info['type'] = LOAD_DELETE_REQUEST_TYPE
|
||||
self._wait_for_request_to_complete(strategy_step, req_info)
|
||||
|
||||
subcloud_type = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).get_system().system_mode
|
||||
strategy_step.subcloud.region_name).get_system().system_mode
|
||||
load_import_retry_counter = 0
|
||||
load = None
|
||||
if subcloud_type == consts.SYSTEM_MODE_SIMPLEX:
|
||||
|
@ -158,7 +158,7 @@ class ImportingLoadState(BaseState):
|
|||
target_load = {key: target_load[key] for key in creation_keys}
|
||||
try:
|
||||
load = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).import_load_metadata(target_load)
|
||||
strategy_step.subcloud.region_name).import_load_metadata(target_load)
|
||||
self.info_log(strategy_step,
|
||||
"Load: %s is now: %s" % (
|
||||
load.software_version, load.state))
|
||||
|
@ -190,7 +190,7 @@ class ImportingLoadState(BaseState):
|
|||
# Call the API. import_load blocks until the load state is 'importing'
|
||||
self.info_log(strategy_step, "Sending load import request...")
|
||||
load = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).import_load(iso_path, sig_path)
|
||||
strategy_step.subcloud.region_name).import_load(iso_path, sig_path)
|
||||
|
||||
break
|
||||
except VaultLoadMissingError:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2020, 2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2020-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -64,7 +64,7 @@ class InstallingLicenseState(BaseState):
|
|||
|
||||
# retrieve the keystone session for the subcloud and query its license
|
||||
subcloud_sysinv_client = \
|
||||
self.get_sysinv_client(strategy_step.subcloud.name)
|
||||
self.get_sysinv_client(strategy_step.subcloud.region_name)
|
||||
subcloud_license_response = subcloud_sysinv_client.get_license()
|
||||
subcloud_license = subcloud_license_response.get('content')
|
||||
subcloud_error = subcloud_license_response.get('error')
|
||||
|
|
|
@ -72,7 +72,7 @@ class MigratingDataState(BaseState):
|
|||
try:
|
||||
# query the administrative state to see if it is the new state.
|
||||
host = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).get_host(target_hostname)
|
||||
strategy_step.subcloud.region_name).get_host(target_hostname)
|
||||
if (host.administrative == consts.ADMIN_UNLOCKED and
|
||||
host.operational == consts.OPERATIONAL_ENABLED):
|
||||
# Success. Break out of the loop.
|
||||
|
@ -156,7 +156,7 @@ class MigratingDataState(BaseState):
|
|||
msg_subcloud = utils.find_ansible_error_msg(
|
||||
strategy_step.subcloud.name, log_file, consts.DEPLOY_STATE_MIGRATING_DATA)
|
||||
# Get script output in case it is available
|
||||
error_msg = utils.get_failure_msg(strategy_step.subcloud.name)
|
||||
error_msg = utils.get_failure_msg(strategy_step.subcloud.region_name)
|
||||
failure = ('%s \n%s' % (error_msg, msg_subcloud))
|
||||
db_api.subcloud_update(
|
||||
self.context, strategy_step.subcloud_id,
|
||||
|
|
|
@ -204,8 +204,8 @@ class PreCheckState(BaseState):
|
|||
if subcloud.availability_status == dccommon_consts.AVAILABILITY_ONLINE:
|
||||
subcloud_sysinv_client = None
|
||||
try:
|
||||
subcloud_sysinv_client = self.get_sysinv_client(strategy_step.subcloud.name)
|
||||
subcloud_fm_client = self.get_fm_client(strategy_step.subcloud.name)
|
||||
subcloud_sysinv_client = self.get_sysinv_client(strategy_step.subcloud.region_name)
|
||||
subcloud_fm_client = self.get_fm_client(strategy_step.subcloud.region_name)
|
||||
except Exception:
|
||||
# if getting the token times out, the orchestrator may have
|
||||
# restarted and subcloud may be offline; so will attempt
|
||||
|
@ -220,7 +220,7 @@ class PreCheckState(BaseState):
|
|||
|
||||
host = subcloud_sysinv_client.get_host("controller-0")
|
||||
subcloud_type = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).get_system().system_mode
|
||||
strategy_step.subcloud.region_name).get_system().system_mode
|
||||
|
||||
upgrades = subcloud_sysinv_client.get_upgrades()
|
||||
if subcloud_type == consts.SYSTEM_MODE_SIMPLEX:
|
||||
|
@ -324,7 +324,7 @@ class PreCheckState(BaseState):
|
|||
|
||||
all_hosts_upgraded = True
|
||||
subcloud_hosts = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).get_hosts()
|
||||
strategy_step.subcloud.region_name).get_hosts()
|
||||
for subcloud_host in subcloud_hosts:
|
||||
if(subcloud_host.software_load != target_version or
|
||||
subcloud_host.administrative == consts.ADMIN_LOCKED or
|
||||
|
|
|
@ -36,7 +36,7 @@ class StartingUpgradeState(BaseState):
|
|||
def get_upgrade_state(self, strategy_step):
|
||||
try:
|
||||
upgrades = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).get_upgrades()
|
||||
strategy_step.subcloud.region_name).get_upgrades()
|
||||
except Exception as exception:
|
||||
self.warn_log(strategy_step,
|
||||
"Encountered exception: %s, "
|
||||
|
@ -58,7 +58,7 @@ class StartingUpgradeState(BaseState):
|
|||
# Check if an existing upgrade is already in progress.
|
||||
# The list of upgrades will never contain more than one entry.
|
||||
upgrades = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).get_upgrades()
|
||||
strategy_step.subcloud.region_name).get_upgrades()
|
||||
if upgrades is not None and len(upgrades) > 0:
|
||||
for upgrade in upgrades:
|
||||
# If a previous upgrade exists (even one that failed) skip
|
||||
|
@ -79,7 +79,7 @@ class StartingUpgradeState(BaseState):
|
|||
|
||||
# This call is asynchronous and throws an exception on failure.
|
||||
self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).upgrade_start(force=force_flag)
|
||||
strategy_step.subcloud.region_name).upgrade_start(force=force_flag)
|
||||
|
||||
# Do not move to the next state until the upgrade state is correct
|
||||
counter = 0
|
||||
|
@ -96,7 +96,7 @@ class StartingUpgradeState(BaseState):
|
|||
if upgrade_state in UPGRADE_RETRY_STATES:
|
||||
retry_counter += 1
|
||||
if retry_counter >= self.max_failed_retries:
|
||||
error_msg = utils.get_failure_msg(strategy_step.subcloud.name)
|
||||
error_msg = utils.get_failure_msg(strategy_step.subcloud.region_name)
|
||||
db_api.subcloud_update(
|
||||
self.context, strategy_step.subcloud_id,
|
||||
error_description=error_msg[0:consts.ERROR_DESCRIPTION_LENGTH])
|
||||
|
@ -110,7 +110,7 @@ class StartingUpgradeState(BaseState):
|
|||
% upgrade_state)
|
||||
try:
|
||||
self.get_sysinv_client(
|
||||
strategy_step.subcloud.name).upgrade_start(force=force_flag)
|
||||
strategy_step.subcloud.region_name).upgrade_start(force=force_flag)
|
||||
except Exception as exception:
|
||||
self.warn_log(strategy_step,
|
||||
"Encountered exception: %s, "
|
||||
|
|
|
@ -48,7 +48,7 @@ class TransferCACertificateState(BaseState):
|
|||
retry_counter = 0
|
||||
while True:
|
||||
try:
|
||||
sysinv_client = self.get_sysinv_client(strategy_step.subcloud.name)
|
||||
sysinv_client = self.get_sysinv_client(strategy_step.subcloud.region_name)
|
||||
|
||||
data = {'mode': 'openldap_ca'}
|
||||
ldap_ca_cert, ldap_ca_key = utils.get_certificate_from_secret(
|
||||
|
|
|
@ -38,9 +38,9 @@ class UpgradingSimplexState(BaseState):
|
|||
subcloud_barbican_client = None
|
||||
try:
|
||||
subcloud_sysinv_client = self.get_sysinv_client(
|
||||
strategy_step.subcloud.name)
|
||||
strategy_step.subcloud.region_name)
|
||||
subcloud_barbican_client = self.get_barbican_client(
|
||||
strategy_step.subcloud.name)
|
||||
strategy_step.subcloud.region_name)
|
||||
except Exception:
|
||||
# if getting the token times out, the orchestrator may have
|
||||
# restarted and subcloud may be offline; so will attempt
|
||||
|
|
|
@ -69,6 +69,7 @@ class SubcloudStateClient(RPCClient):
|
|||
|
||||
def update_subcloud_availability(self, ctxt,
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
availability_status,
|
||||
update_state_only=False,
|
||||
audit_fail_count=None):
|
||||
|
@ -77,11 +78,13 @@ class SubcloudStateClient(RPCClient):
|
|||
ctxt,
|
||||
self.make_msg('update_subcloud_availability',
|
||||
subcloud_name=subcloud_name,
|
||||
subcloud_region=subcloud_region,
|
||||
availability_status=availability_status,
|
||||
update_state_only=update_state_only,
|
||||
audit_fail_count=audit_fail_count))
|
||||
|
||||
def update_subcloud_endpoint_status(self, ctxt, subcloud_name=None,
|
||||
subcloud_region=None,
|
||||
endpoint_type=None,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC,
|
||||
ignore_endpoints=None,
|
||||
|
@ -90,12 +93,14 @@ class SubcloudStateClient(RPCClient):
|
|||
# See below for synchronous method call
|
||||
return self.cast(ctxt, self.make_msg('update_subcloud_endpoint_status',
|
||||
subcloud_name=subcloud_name,
|
||||
subcloud_region=subcloud_region,
|
||||
endpoint_type=endpoint_type,
|
||||
sync_status=sync_status,
|
||||
ignore_endpoints=ignore_endpoints,
|
||||
alarmable=alarmable))
|
||||
|
||||
def update_subcloud_endpoint_status_sync(self, ctxt, subcloud_name=None,
|
||||
subcloud_region=None,
|
||||
endpoint_type=None,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC,
|
||||
ignore_endpoints=None,
|
||||
|
@ -103,6 +108,7 @@ class SubcloudStateClient(RPCClient):
|
|||
# Note: synchronous
|
||||
return self.call(ctxt, self.make_msg('update_subcloud_endpoint_status',
|
||||
subcloud_name=subcloud_name,
|
||||
subcloud_region=subcloud_region,
|
||||
endpoint_type=endpoint_type,
|
||||
sync_status=sync_status,
|
||||
ignore_endpoints=ignore_endpoints,
|
||||
|
@ -133,6 +139,12 @@ class ManagerClient(RPCClient):
|
|||
return self.call(ctxt, self.make_msg('delete_subcloud',
|
||||
subcloud_id=subcloud_id))
|
||||
|
||||
def rename_subcloud(self, ctxt, subcloud_id, curr_subcloud_name, new_subcloud_name=None):
|
||||
return self.call(ctxt, self.make_msg('rename_subcloud',
|
||||
subcloud_id=subcloud_id,
|
||||
curr_subcloud_name=curr_subcloud_name,
|
||||
new_subcloud_name=new_subcloud_name))
|
||||
|
||||
def update_subcloud(self, ctxt, subcloud_id, management_state=None,
|
||||
description=None, location=None, group_id=None,
|
||||
data_install=None, force=None,
|
||||
|
@ -173,13 +185,13 @@ class ManagerClient(RPCClient):
|
|||
payload=payload))
|
||||
|
||||
def update_subcloud_sync_endpoint_type(self, ctxt,
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
endpoint_type_list,
|
||||
openstack_installed):
|
||||
return self.cast(
|
||||
ctxt,
|
||||
self.make_msg('update_subcloud_sync_endpoint_type',
|
||||
subcloud_name=subcloud_name,
|
||||
subcloud_region=subcloud_region,
|
||||
endpoint_type_list=endpoint_type_list,
|
||||
openstack_installed=openstack_installed))
|
||||
|
||||
|
@ -229,6 +241,10 @@ class ManagerClient(RPCClient):
|
|||
subcloud_ref=subcloud_ref,
|
||||
payload=payload))
|
||||
|
||||
def get_subcloud_name_by_region_name(self, ctxt, subcloud_region):
|
||||
return self.call(ctxt, self.make_msg('get_subcloud_name_by_region_name',
|
||||
subcloud_region=subcloud_region))
|
||||
|
||||
|
||||
class DCManagerNotifications(RPCClient):
|
||||
"""DC Manager Notification interface to broadcast subcloud state changed
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Copyright (c) 2017-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2017-2023 Wind River Systems, Inc.
|
||||
#
|
||||
# The right to copy, distribute, modify, or otherwise make use
|
||||
# of this software may be licensed only pursuant to the terms
|
||||
|
@ -113,6 +113,7 @@ class DCManagerStateService(service.Service):
|
|||
|
||||
@request_context
|
||||
def update_subcloud_endpoint_status(self, context, subcloud_name=None,
|
||||
subcloud_region=None,
|
||||
endpoint_type=None,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC,
|
||||
alarmable=True,
|
||||
|
@ -124,7 +125,7 @@ class DCManagerStateService(service.Service):
|
|||
|
||||
self.subcloud_state_manager. \
|
||||
update_subcloud_endpoint_status(context,
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
endpoint_type,
|
||||
sync_status,
|
||||
alarmable,
|
||||
|
@ -153,6 +154,7 @@ class DCManagerStateService(service.Service):
|
|||
@request_context
|
||||
def update_subcloud_availability(self, context,
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
availability_status,
|
||||
update_state_only=False,
|
||||
audit_fail_count=None):
|
||||
|
@ -161,7 +163,7 @@ class DCManagerStateService(service.Service):
|
|||
subcloud_name)
|
||||
self.subcloud_state_manager.update_subcloud_availability(
|
||||
context,
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
availability_status,
|
||||
update_state_only,
|
||||
audit_fail_count)
|
||||
|
|
|
@ -42,9 +42,9 @@ def sync_update_subcloud_endpoint_status(func):
|
|||
"""Synchronized lock decorator for _update_subcloud_endpoint_status. """
|
||||
|
||||
def _get_lock_and_call(*args, **kwargs):
|
||||
"""Get a single fair lock per subcloud based on subcloud name. """
|
||||
"""Get a single fair lock per subcloud based on subcloud region. """
|
||||
|
||||
# subcloud name is the 3rd argument to
|
||||
# subcloud region is the 3rd argument to
|
||||
# _update_subcloud_endpoint_status()
|
||||
@utils.synchronized(args[2], external=True, fair=True)
|
||||
def _call_func(*args, **kwargs):
|
||||
|
@ -262,7 +262,7 @@ class SubcloudStateManager(manager.Manager):
|
|||
@sync_update_subcloud_endpoint_status
|
||||
def _update_subcloud_endpoint_status(
|
||||
self, context,
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
endpoint_type=None,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC,
|
||||
alarmable=True,
|
||||
|
@ -270,7 +270,7 @@ class SubcloudStateManager(manager.Manager):
|
|||
"""Update subcloud endpoint status
|
||||
|
||||
:param context: request context object
|
||||
:param subcloud_name: name of subcloud to update
|
||||
:param subcloud_region: name of subcloud region to update
|
||||
:param endpoint_type: endpoint type to update
|
||||
:param sync_status: sync status to set
|
||||
:param alarmable: controls raising an alarm if applicable
|
||||
|
@ -281,13 +281,13 @@ class SubcloudStateManager(manager.Manager):
|
|||
if ignore_endpoints is None:
|
||||
ignore_endpoints = []
|
||||
|
||||
if not subcloud_name:
|
||||
if not subcloud_region:
|
||||
raise exceptions.BadRequest(
|
||||
resource='subcloud',
|
||||
msg='Subcloud name not provided')
|
||||
msg='Subcloud region not provided')
|
||||
|
||||
try:
|
||||
subcloud = db_api.subcloud_get_by_name(context, subcloud_name)
|
||||
subcloud = db_api.subcloud_get_by_region_name(context, subcloud_region)
|
||||
except Exception as e:
|
||||
LOG.exception(e)
|
||||
raise e
|
||||
|
@ -327,12 +327,12 @@ class SubcloudStateManager(manager.Manager):
|
|||
else:
|
||||
LOG.info("Ignoring subcloud sync_status update for subcloud:%s "
|
||||
"availability:%s management:%s endpoint:%s sync:%s" %
|
||||
(subcloud_name, subcloud.availability_status,
|
||||
(subcloud.name, subcloud.availability_status,
|
||||
subcloud.management_state, endpoint_type, sync_status))
|
||||
|
||||
def update_subcloud_endpoint_status(
|
||||
self, context,
|
||||
subcloud_name=None,
|
||||
subcloud_region=None,
|
||||
endpoint_type=None,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC,
|
||||
alarmable=True,
|
||||
|
@ -340,7 +340,7 @@ class SubcloudStateManager(manager.Manager):
|
|||
"""Update subcloud endpoint status
|
||||
|
||||
:param context: request context object
|
||||
:param subcloud_name: name of subcloud to update
|
||||
:param subcloud_region: region of subcloud to update
|
||||
:param endpoint_type: endpoint type to update
|
||||
:param sync_status: sync status to set
|
||||
:param alarmable: controls raising an alarm if applicable
|
||||
|
@ -351,18 +351,18 @@ class SubcloudStateManager(manager.Manager):
|
|||
if ignore_endpoints is None:
|
||||
ignore_endpoints = []
|
||||
|
||||
if subcloud_name:
|
||||
if subcloud_region:
|
||||
self._update_subcloud_endpoint_status(
|
||||
context, subcloud_name, endpoint_type, sync_status, alarmable,
|
||||
context, subcloud_region, endpoint_type, sync_status, alarmable,
|
||||
ignore_endpoints)
|
||||
else:
|
||||
# update all subclouds
|
||||
for subcloud in db_api.subcloud_get_all(context):
|
||||
self._update_subcloud_endpoint_status(
|
||||
context, subcloud.name, endpoint_type, sync_status,
|
||||
context, subcloud.region_name, endpoint_type, sync_status,
|
||||
alarmable, ignore_endpoints)
|
||||
|
||||
def _update_subcloud_state(self, context, subcloud_name,
|
||||
def _update_subcloud_state(self, context, subcloud_name, subcloud_region,
|
||||
management_state, availability_status):
|
||||
try:
|
||||
LOG.info('Notifying dcorch, subcloud:%s management: %s, '
|
||||
|
@ -372,7 +372,7 @@ class SubcloudStateManager(manager.Manager):
|
|||
availability_status))
|
||||
|
||||
self.dcorch_rpc_client.update_subcloud_states(
|
||||
context, subcloud_name, management_state, availability_status)
|
||||
context, subcloud_region, management_state, availability_status)
|
||||
|
||||
except Exception:
|
||||
LOG.exception('Problem informing dcorch of subcloud state change,'
|
||||
|
@ -418,20 +418,21 @@ class SubcloudStateManager(manager.Manager):
|
|||
LOG.exception("Failed to raise offline alarm for subcloud: %s",
|
||||
subcloud_name)
|
||||
|
||||
def update_subcloud_availability(self, context, subcloud_name,
|
||||
def update_subcloud_availability(self, context, subcloud_region,
|
||||
availability_status,
|
||||
update_state_only=False,
|
||||
audit_fail_count=None):
|
||||
try:
|
||||
subcloud = db_api.subcloud_get_by_name(context, subcloud_name)
|
||||
subcloud = db_api.subcloud_get_by_region_name(context, subcloud_region)
|
||||
except Exception:
|
||||
LOG.exception("Failed to get subcloud by name: %s" % subcloud_name)
|
||||
LOG.exception("Failed to get subcloud by region name %s" % subcloud_region)
|
||||
raise
|
||||
|
||||
if update_state_only:
|
||||
# Nothing has changed, but we want to send a state update for this
|
||||
# subcloud as an audit. Get the most up-to-date data.
|
||||
self._update_subcloud_state(context, subcloud_name,
|
||||
self._update_subcloud_state(context, subcloud.name,
|
||||
subcloud.region_name,
|
||||
subcloud.management_state,
|
||||
availability_status)
|
||||
elif availability_status is None:
|
||||
|
@ -443,17 +444,17 @@ class SubcloudStateManager(manager.Manager):
|
|||
# slim possibility subcloud could have been deleted since
|
||||
# we found it in db, ignore this benign error.
|
||||
LOG.info('Ignoring SubcloudNotFound when attempting '
|
||||
'audit_fail_count update: %s' % subcloud_name)
|
||||
'audit_fail_count update: %s' % subcloud.name)
|
||||
return
|
||||
else:
|
||||
self._raise_or_clear_subcloud_status_alarm(subcloud_name,
|
||||
self._raise_or_clear_subcloud_status_alarm(subcloud.name,
|
||||
availability_status)
|
||||
|
||||
if availability_status == dccommon_consts.AVAILABILITY_OFFLINE:
|
||||
# Subcloud is going offline, set all endpoint statuses to
|
||||
# unknown.
|
||||
self._update_subcloud_endpoint_status(
|
||||
context, subcloud_name, endpoint_type=None,
|
||||
context, subcloud.region_name, endpoint_type=None,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_UNKNOWN)
|
||||
|
||||
try:
|
||||
|
@ -466,27 +467,28 @@ class SubcloudStateManager(manager.Manager):
|
|||
# slim possibility subcloud could have been deleted since
|
||||
# we found it in db, ignore this benign error.
|
||||
LOG.info('Ignoring SubcloudNotFound when attempting state'
|
||||
' update: %s' % subcloud_name)
|
||||
' update: %s' % subcloud.name)
|
||||
return
|
||||
|
||||
if availability_status == dccommon_consts.AVAILABILITY_ONLINE:
|
||||
# Subcloud is going online
|
||||
# Tell cert-mon to audit endpoint certificate.
|
||||
LOG.info('Request for online audit for %s' % subcloud_name)
|
||||
LOG.info('Request for online audit for %s' % subcloud.name)
|
||||
dc_notification = rpc_client.DCManagerNotifications()
|
||||
dc_notification.subcloud_online(context, subcloud_name)
|
||||
dc_notification.subcloud_online(context, subcloud.region_name)
|
||||
# Trigger all the audits for the subcloud so it can update the
|
||||
# sync status ASAP.
|
||||
self.audit_rpc_client.trigger_subcloud_audits(context,
|
||||
subcloud.id)
|
||||
|
||||
# Send dcorch a state update
|
||||
self._update_subcloud_state(context, subcloud_name,
|
||||
self._update_subcloud_state(context, subcloud.name,
|
||||
subcloud.region_name,
|
||||
updated_subcloud.management_state,
|
||||
availability_status)
|
||||
|
||||
def update_subcloud_sync_endpoint_type(self, context,
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
endpoint_type_list,
|
||||
openstack_installed):
|
||||
operation = 'add' if openstack_installed else 'remove'
|
||||
|
@ -502,17 +504,17 @@ class SubcloudStateManager(manager.Manager):
|
|||
}
|
||||
|
||||
try:
|
||||
subcloud = db_api.subcloud_get_by_name(context, subcloud_name)
|
||||
subcloud = db_api.subcloud_get_by_region_name(context, subcloud_region)
|
||||
except Exception:
|
||||
LOG.exception("Failed to get subcloud by name: %s" % subcloud_name)
|
||||
LOG.exception("Failed to get subcloud by region name: %s" % subcloud_region)
|
||||
raise
|
||||
|
||||
try:
|
||||
# Notify dcorch to add/remove sync endpoint type list
|
||||
func_switcher[operation][0](self.context, subcloud_name,
|
||||
func_switcher[operation][0](self.context, subcloud_region,
|
||||
endpoint_type_list)
|
||||
LOG.info('Notifying dcorch, subcloud: %s new sync endpoint: %s' %
|
||||
(subcloud_name, endpoint_type_list))
|
||||
(subcloud.name, endpoint_type_list))
|
||||
|
||||
# Update subcloud status table by adding/removing openstack sync
|
||||
# endpoint types
|
||||
|
@ -524,4 +526,4 @@ class SubcloudStateManager(manager.Manager):
|
|||
openstack_installed=openstack_installed)
|
||||
except Exception:
|
||||
LOG.exception('Problem informing dcorch of subcloud sync endpoint'
|
||||
' type change, subcloud: %s' % subcloud_name)
|
||||
' type change, subcloud: %s' % subcloud.name)
|
||||
|
|
|
@ -36,6 +36,29 @@ get_engine = api.get_engine
|
|||
from sqlalchemy.engine import Engine
|
||||
from sqlalchemy import event
|
||||
|
||||
SUBCLOUD_1 = {'name': 'subcloud1',
|
||||
'region_name': '2ec93dfb654846909efe61d1b39dd2ce'}
|
||||
SUBCLOUD_2 = {'name': 'subcloud2',
|
||||
'region_name': 'ca2761ee7aa34cbe8415ec9a3c86854f'}
|
||||
SUBCLOUD_3 = {'name': 'subcloud3',
|
||||
'region_name': '659e12e5f7ad411abfcd83f5cedca0bf'}
|
||||
SUBCLOUD_4 = {'name': 'subcloud4',
|
||||
'region_name': 'c25f3b0553384104b664789bd93a2ba8'}
|
||||
SUBCLOUD_5 = {'name': 'subcloud5',
|
||||
'region_name': '809581dc2d154e008480bac1f43b7aff'}
|
||||
SUBCLOUD_6 = {'name': 'subcloud6',
|
||||
'region_name': '8c60b99f3e1245b7bc5a049802ade8d2'}
|
||||
SUBCLOUD_7 = {'name': 'subcloud7',
|
||||
'region_name': '9fde6dca22fa422bb1e8cf03bedc18e4'}
|
||||
SUBCLOUD_8 = {'name': 'subcloud8',
|
||||
'region_name': 'f3cb0b109c4543fda3ed50ed5783279d'}
|
||||
SUBCLOUD_9 = {'name': 'subcloud9',
|
||||
'region_name': '1cfab1df7b444bb3bd562894d684f352'}
|
||||
SUBCLOUD_10 = {'name': 'subcloud10',
|
||||
'region_name': '6d0040199b4f4a9fb4a1f2ed4d498159'}
|
||||
SUBCLOUD_11 = {'name': 'subcloud11',
|
||||
'region_name': '169e6fc231e94959ad6ff0a66fbcb753'}
|
||||
|
||||
SUBCLOUD_SAMPLE_DATA_0 = [
|
||||
6, # id
|
||||
"subcloud-4", # name
|
||||
|
@ -63,6 +86,7 @@ SUBCLOUD_SAMPLE_DATA_0 = [
|
|||
1, # group_id
|
||||
consts.DEPLOY_STATE_DONE, # deploy_status
|
||||
consts.ERROR_DESC_EMPTY, # error_description
|
||||
SUBCLOUD_4['region_name'], # region_name
|
||||
json.dumps({'data_install': 'test data install values'}), # data_install
|
||||
]
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ from dcmanager.common import consts
|
|||
from dcmanager.db.sqlalchemy import api as db_api
|
||||
from dcmanager.rpc import client as rpc_client
|
||||
|
||||
from dcmanager.tests import base
|
||||
from dcmanager.tests.unit.api import test_root_controller as testroot
|
||||
from dcmanager.tests.unit.common import fake_subcloud
|
||||
from dcmanager.tests import utils
|
||||
|
@ -1059,7 +1060,9 @@ class TestSubcloudRestore(testroot.DCManagerApiTest):
|
|||
|
||||
test_group_id = 1
|
||||
subcloud = fake_subcloud.create_fake_subcloud(self.ctx, group_id=test_group_id)
|
||||
subcloud2 = fake_subcloud.create_fake_subcloud(self.ctx, group_id=test_group_id, name='subcloud2')
|
||||
subcloud2 = fake_subcloud.create_fake_subcloud(self.ctx, group_id=test_group_id,
|
||||
name=base.SUBCLOUD_2['name'],
|
||||
region_name=base.SUBCLOUD_2['region_name'])
|
||||
# Valid subcloud, management state is 'unmanaged'
|
||||
db_api.subcloud_update(self.ctx,
|
||||
subcloud.id,
|
||||
|
|
|
@ -239,6 +239,7 @@ class TestSubcloudGroupGet(testroot.DCManagerApiTest,
|
|||
FAKE_SUBCLOUD_DATA.get('systemcontroller_gateway_ip'),
|
||||
'deploy_status': FAKE_SUBCLOUD_DATA.get('deploy_status'),
|
||||
'error_description': FAKE_SUBCLOUD_DATA.get('error_description'),
|
||||
'region_name': FAKE_SUBCLOUD_DATA.get('region_name'),
|
||||
'openstack_installed':
|
||||
FAKE_SUBCLOUD_DATA.get('openstack_installed'),
|
||||
'group_id': FAKE_SUBCLOUD_DATA.get('group_id', 1)
|
||||
|
|
|
@ -1429,7 +1429,8 @@ class TestSubcloudAPIOther(testroot.DCManagerApiTest):
|
|||
data, headers=FAKE_HEADERS)
|
||||
|
||||
self.mock_rpc_state_client().update_subcloud_endpoint_status.\
|
||||
assert_called_once_with(mock.ANY, subcloud.name, 'dc-cert', 'in-sync')
|
||||
assert_called_once_with(mock.ANY, subcloud.name, subcloud.region_name,
|
||||
'dc-cert', 'in-sync')
|
||||
|
||||
self.assertEqual(response.status_int, 200)
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ from dcmanager.audit import subcloud_audit_manager
|
|||
from dcmanager.tests import base
|
||||
from dcmanager.tests import utils
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
|
@ -462,11 +461,14 @@ class TestFirmwareAudit(base.DCManagerTestCase):
|
|||
am.firmware_audit = fm
|
||||
firmware_audit_data = self.get_fw_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
fm.subcloud_firmware_audit(name, firmware_audit_data)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
fm.subcloud_firmware_audit(name, region, firmware_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
@ -494,11 +496,14 @@ class TestFirmwareAudit(base.DCManagerTestCase):
|
|||
am.firmware_audit = fm
|
||||
firmware_audit_data = self.get_fw_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
fm.subcloud_firmware_audit(name, firmware_audit_data)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
fm.subcloud_firmware_audit(name, region, firmware_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
@ -525,11 +530,14 @@ class TestFirmwareAudit(base.DCManagerTestCase):
|
|||
am.firmware_audit = fm
|
||||
firmware_audit_data = self.get_fw_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
fm.subcloud_firmware_audit(name, firmware_audit_data)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
fm.subcloud_firmware_audit(name, region, firmware_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
@ -556,11 +564,14 @@ class TestFirmwareAudit(base.DCManagerTestCase):
|
|||
am.firmware_audit = fm
|
||||
firmware_audit_data = self.get_fw_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
fm.subcloud_firmware_audit(name, firmware_audit_data)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
fm.subcloud_firmware_audit(name, region, firmware_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
@ -587,11 +598,14 @@ class TestFirmwareAudit(base.DCManagerTestCase):
|
|||
am.firmware_audit = fm
|
||||
firmware_audit_data = self.get_fw_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
fm.subcloud_firmware_audit(name, firmware_audit_data)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
fm.subcloud_firmware_audit(name, region, firmware_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
@ -618,11 +632,14 @@ class TestFirmwareAudit(base.DCManagerTestCase):
|
|||
am.firmware_audit = fm
|
||||
firmware_audit_data = self.get_fw_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
fm.subcloud_firmware_audit(name, firmware_audit_data)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
fm.subcloud_firmware_audit(name, region, firmware_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
@ -649,11 +666,14 @@ class TestFirmwareAudit(base.DCManagerTestCase):
|
|||
am.firmware_audit = fm
|
||||
firmware_audit_data = self.get_fw_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
fm.subcloud_firmware_audit(name, firmware_audit_data)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
fm.subcloud_firmware_audit(name, region, firmware_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
@ -680,11 +700,14 @@ class TestFirmwareAudit(base.DCManagerTestCase):
|
|||
am.firmware_audit = fm
|
||||
firmware_audit_data = self.get_fw_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
fm.subcloud_firmware_audit(name, firmware_audit_data)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
fm.subcloud_firmware_audit(name, region, firmware_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_FIRMWARE,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
|
|
@ -24,7 +24,6 @@ from dcmanager.audit import subcloud_audit_manager
|
|||
from dcmanager.tests import base
|
||||
from dcmanager.tests import utils
|
||||
|
||||
|
||||
PREVIOUS_KUBE_VERSION = 'v1.2.3'
|
||||
UPGRADED_KUBE_VERSION = 'v1.2.3-a'
|
||||
|
||||
|
@ -166,11 +165,14 @@ class TestKubernetesAudit(base.DCManagerTestCase):
|
|||
am.kubernetes_audit = audit
|
||||
kubernetes_audit_data = self.get_kube_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
audit.subcloud_kubernetes_audit(name, kubernetes_audit_data)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
audit.subcloud_kubernetes_audit(name, region, kubernetes_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_KUBERNETES,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
@ -190,15 +192,18 @@ class TestKubernetesAudit(base.DCManagerTestCase):
|
|||
]
|
||||
kubernetes_audit_data = self.get_kube_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
# return different kube versions in the subclouds
|
||||
self.kube_sysinv_client.get_kube_versions.return_value = [
|
||||
FakeKubeVersion(version=PREVIOUS_KUBE_VERSION),
|
||||
]
|
||||
audit.subcloud_kubernetes_audit(name, kubernetes_audit_data)
|
||||
audit.subcloud_kubernetes_audit(name, region, kubernetes_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_KUBERNETES,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
@ -218,15 +223,18 @@ class TestKubernetesAudit(base.DCManagerTestCase):
|
|||
]
|
||||
kubernetes_audit_data = self.get_kube_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
# return different kube versions in the subclouds
|
||||
self.kube_sysinv_client.get_kube_versions.return_value = [
|
||||
FakeKubeVersion(version=UPGRADED_KUBE_VERSION),
|
||||
]
|
||||
audit.subcloud_kubernetes_audit(name, kubernetes_audit_data)
|
||||
audit.subcloud_kubernetes_audit(name, region, kubernetes_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_KUBERNETES,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
@ -247,15 +255,18 @@ class TestKubernetesAudit(base.DCManagerTestCase):
|
|||
]
|
||||
kubernetes_audit_data = self.get_kube_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
# return same kube versions in the subclouds
|
||||
self.kube_sysinv_client.get_kube_versions.return_value = [
|
||||
FakeKubeVersion(version=UPGRADED_KUBE_VERSION),
|
||||
]
|
||||
audit.subcloud_kubernetes_audit(name, kubernetes_audit_data)
|
||||
audit.subcloud_kubernetes_audit(name, region, kubernetes_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_KUBERNETES,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
@ -282,15 +293,18 @@ class TestKubernetesAudit(base.DCManagerTestCase):
|
|||
]
|
||||
kubernetes_audit_data = self.get_kube_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
# return same kube versions in the subclouds
|
||||
self.kube_sysinv_client.get_kube_versions.return_value = [
|
||||
FakeKubeVersion(version=UPGRADED_KUBE_VERSION),
|
||||
]
|
||||
audit.subcloud_kubernetes_audit(name, kubernetes_audit_data)
|
||||
audit.subcloud_kubernetes_audit(name, region, kubernetes_audit_data)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_KUBERNETES,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2017-2022 Wind River Systems, Inc.
|
||||
# Copyright (c) 2017-2023 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. You may obtain
|
||||
# a copy of the License at
|
||||
|
@ -27,7 +27,6 @@ from dcmanager.audit import subcloud_audit_manager
|
|||
from dcmanager.tests import base
|
||||
from dcmanager.tests import utils
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
|
@ -85,7 +84,8 @@ class FakePatchingClientInSync(object):
|
|||
'repostate': 'Applied',
|
||||
'patchstate': 'Applied'},
|
||||
}
|
||||
elif self.region in ['subcloud1', 'subcloud2']:
|
||||
elif self.region in [base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['region_name']]:
|
||||
return {'DC.1': {'sw_version': '17.07',
|
||||
'repostate': 'Applied',
|
||||
'patchstate': 'Applied'},
|
||||
|
@ -117,25 +117,25 @@ class FakePatchingClientOutOfSync(object):
|
|||
'DC.2': {'sw_version': '17.07',
|
||||
'repostate': 'Applied',
|
||||
'patchstate': 'Applied'}}
|
||||
elif self.region == 'subcloud1':
|
||||
elif self.region == base.SUBCLOUD_1['region_name']:
|
||||
return {'DC.1': {'sw_version': '17.07',
|
||||
'repostate': 'Applied',
|
||||
'patchstate': 'Applied'},
|
||||
'DC.2': {'sw_version': '17.07',
|
||||
'repostate': 'Available',
|
||||
'patchstate': 'Available'}}
|
||||
elif self.region == 'subcloud2':
|
||||
elif self.region == base.SUBCLOUD_2['region_name']:
|
||||
return {'DC.1': {'sw_version': '17.07',
|
||||
'repostate': 'Applied',
|
||||
'patchstate': 'Applied'}}
|
||||
elif self.region == 'subcloud3':
|
||||
elif self.region == base.SUBCLOUD_3['region_name']:
|
||||
return {'DC.1': {'sw_version': '17.07',
|
||||
'repostate': 'Applied',
|
||||
'patchstate': 'Applied'},
|
||||
'DC.2': {'sw_version': '17.07',
|
||||
'repostate': 'Applied',
|
||||
'patchstate': 'Applied'}}
|
||||
elif self.region == 'subcloud4':
|
||||
elif self.region == base.SUBCLOUD_4['region_name']:
|
||||
return {'DC.1': {'sw_version': '17.07',
|
||||
'repostate': 'Applied',
|
||||
'patchstate': 'Applied'},
|
||||
|
@ -219,7 +219,7 @@ class FakeSysinvClientOneLoadUnmatchedSoftwareVersion(object):
|
|||
return self.upgrades
|
||||
|
||||
def get_system(self):
|
||||
if self.region == 'subcloud2':
|
||||
if self.region == base.SUBCLOUD_2['region_name']:
|
||||
return System('17.06')
|
||||
else:
|
||||
return self.system
|
||||
|
@ -238,7 +238,7 @@ class FakeSysinvClientOneLoadUpgradeInProgress(object):
|
|||
return self.loads
|
||||
|
||||
def get_upgrades(self):
|
||||
if self.region == 'subcloud2':
|
||||
if self.region == base.SUBCLOUD_2['region_name']:
|
||||
return [Upgrade('started')]
|
||||
else:
|
||||
return self.upgrades
|
||||
|
@ -302,15 +302,19 @@ class TestPatchAudit(base.DCManagerTestCase):
|
|||
do_load_audit = True
|
||||
patch_audit_data = self.get_patch_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
pm.subcloud_patch_audit(name, patch_audit_data, do_load_audit)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
pm.subcloud_patch_audit(name, region, patch_audit_data, do_load_audit)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status. \
|
||||
|
@ -336,40 +340,52 @@ class TestPatchAudit(base.DCManagerTestCase):
|
|||
do_load_audit = True
|
||||
patch_audit_data = self.get_patch_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2', 'subcloud3', 'subcloud4']:
|
||||
pm.subcloud_patch_audit(name, patch_audit_data, do_load_audit)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name'],
|
||||
base.SUBCLOUD_3['name']: base.SUBCLOUD_3['region_name'],
|
||||
base.SUBCLOUD_4['name']: base.SUBCLOUD_4['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
pm.subcloud_patch_audit(name, region, patch_audit_data, do_load_audit)
|
||||
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud1',
|
||||
subcloud_name=base.SUBCLOUD_1['name'],
|
||||
subcloud_region=base.SUBCLOUD_1['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud1',
|
||||
subcloud_name=base.SUBCLOUD_1['name'],
|
||||
subcloud_region=base.SUBCLOUD_1['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud2',
|
||||
subcloud_name=base.SUBCLOUD_2['name'],
|
||||
subcloud_region=base.SUBCLOUD_2['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud2',
|
||||
subcloud_name=base.SUBCLOUD_2['name'],
|
||||
subcloud_region=base.SUBCLOUD_2['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud3',
|
||||
subcloud_name=base.SUBCLOUD_3['name'],
|
||||
subcloud_region=base.SUBCLOUD_3['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud3',
|
||||
subcloud_name=base.SUBCLOUD_3['name'],
|
||||
subcloud_region=base.SUBCLOUD_3['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud4',
|
||||
subcloud_name=base.SUBCLOUD_4['name'],
|
||||
subcloud_region=base.SUBCLOUD_4['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud4',
|
||||
subcloud_name=base.SUBCLOUD_4['name'],
|
||||
subcloud_region=base.SUBCLOUD_4['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC),
|
||||
]
|
||||
|
@ -397,15 +413,19 @@ class TestPatchAudit(base.DCManagerTestCase):
|
|||
do_load_audit = True
|
||||
patch_audit_data = self.get_patch_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
pm.subcloud_patch_audit(name, patch_audit_data, do_load_audit)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
pm.subcloud_patch_audit(name, region, patch_audit_data, do_load_audit)
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name=name,
|
||||
subcloud_region=region,
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)]
|
||||
self.fake_dcmanager_state_api.update_subcloud_endpoint_status.\
|
||||
|
@ -431,24 +451,30 @@ class TestPatchAudit(base.DCManagerTestCase):
|
|||
do_load_audit = True
|
||||
patch_audit_data = self.get_patch_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
pm.subcloud_patch_audit(name, patch_audit_data, do_load_audit)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
pm.subcloud_patch_audit(name, region, patch_audit_data, do_load_audit)
|
||||
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud1',
|
||||
subcloud_name=base.SUBCLOUD_1['name'],
|
||||
subcloud_region=base.SUBCLOUD_1['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud1',
|
||||
subcloud_name=base.SUBCLOUD_1['name'],
|
||||
subcloud_region=base.SUBCLOUD_1['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud2',
|
||||
subcloud_name=base.SUBCLOUD_2['name'],
|
||||
subcloud_region=base.SUBCLOUD_2['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud2',
|
||||
subcloud_name=base.SUBCLOUD_2['name'],
|
||||
subcloud_region=base.SUBCLOUD_2['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC),
|
||||
]
|
||||
|
@ -475,24 +501,30 @@ class TestPatchAudit(base.DCManagerTestCase):
|
|||
do_load_audit = True
|
||||
patch_audit_data = self.get_patch_audit_data(am)
|
||||
|
||||
for name in ['subcloud1', 'subcloud2']:
|
||||
pm.subcloud_patch_audit(name, patch_audit_data, do_load_audit)
|
||||
subclouds = {base.SUBCLOUD_1['name']: base.SUBCLOUD_1['region_name'],
|
||||
base.SUBCLOUD_2['name']: base.SUBCLOUD_2['region_name']}
|
||||
for name, region in subclouds.items():
|
||||
pm.subcloud_patch_audit(name, region, patch_audit_data, do_load_audit)
|
||||
|
||||
expected_calls = [
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud1',
|
||||
subcloud_name=base.SUBCLOUD_1['name'],
|
||||
subcloud_region=base.SUBCLOUD_1['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud1',
|
||||
subcloud_name=base.SUBCLOUD_1['name'],
|
||||
subcloud_region=base.SUBCLOUD_1['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud2',
|
||||
subcloud_name=base.SUBCLOUD_2['name'],
|
||||
subcloud_region=base.SUBCLOUD_2['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_PATCHING,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC),
|
||||
mock.call(mock.ANY,
|
||||
subcloud_name='subcloud2',
|
||||
subcloud_name=base.SUBCLOUD_2['name'],
|
||||
subcloud_region=base.SUBCLOUD_2['region_name'],
|
||||
endpoint_type=dccommon_consts.ENDPOINT_TYPE_LOAD,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC),
|
||||
]
|
||||
|
|
|
@ -276,6 +276,7 @@ class TestAuditManager(base.DCManagerTestCase):
|
|||
'systemcontroller_gateway_ip': "192.168.204.101",
|
||||
'deploy_status': "not-deployed",
|
||||
'error_description': 'No errors present',
|
||||
'region_name': base.SUBCLOUD_1['region_name'],
|
||||
'openstack_installed': False,
|
||||
'group_id': 1,
|
||||
}
|
||||
|
|
|
@ -370,6 +370,7 @@ class TestAuditWorkerManager(base.DCManagerTestCase):
|
|||
'systemcontroller_gateway_ip': "192.168.204.101",
|
||||
'deploy_status': "not-deployed",
|
||||
'error_description': 'No errors present',
|
||||
'region_name': base.SUBCLOUD_1['region_name'],
|
||||
'openstack_installed': False,
|
||||
'group_id': 1,
|
||||
}
|
||||
|
@ -429,8 +430,8 @@ class TestAuditWorkerManager(base.DCManagerTestCase):
|
|||
|
||||
# Verify the subcloud was set to online
|
||||
self.fake_dcmanager_state_api.update_subcloud_availability.assert_called_with(
|
||||
mock.ANY, subcloud.name, dccommon_consts.AVAILABILITY_ONLINE,
|
||||
False, 0)
|
||||
mock.ANY, subcloud.name, subcloud.region_name,
|
||||
dccommon_consts.AVAILABILITY_ONLINE, False, 0)
|
||||
|
||||
# Verify the _update_subcloud_audit_fail_count is not called
|
||||
with mock.patch.object(wm, '_update_subcloud_audit_fail_count') as \
|
||||
|
@ -447,19 +448,19 @@ class TestAuditWorkerManager(base.DCManagerTestCase):
|
|||
|
||||
# Verify patch audit is called
|
||||
self.fake_patch_audit.subcloud_patch_audit.assert_called_with(
|
||||
subcloud.name, patch_audit_data, do_load_audit)
|
||||
subcloud.name, subcloud.region_name, patch_audit_data, do_load_audit)
|
||||
|
||||
# Verify firmware audit is called
|
||||
self.fake_firmware_audit.subcloud_firmware_audit.assert_called_with(
|
||||
subcloud.name, firmware_audit_data)
|
||||
subcloud.name, subcloud.region_name, firmware_audit_data)
|
||||
|
||||
# Verify kubernetes audit is called
|
||||
self.fake_kubernetes_audit.subcloud_kubernetes_audit.assert_called_with(
|
||||
subcloud.name, kubernetes_audit_data)
|
||||
subcloud.name, subcloud.region_name, kubernetes_audit_data)
|
||||
|
||||
# Verify kube rootca update audit is called
|
||||
self.fake_kube_rootca_update_audit.subcloud_audit.assert_called_with(
|
||||
subcloud.name, kube_rootca_update_audit_data)
|
||||
subcloud.name, subcloud.region_name, kube_rootca_update_audit_data)
|
||||
|
||||
def test_audit_subcloud_online_first_identity_sync_not_complete(self):
|
||||
|
||||
|
@ -506,8 +507,8 @@ class TestAuditWorkerManager(base.DCManagerTestCase):
|
|||
|
||||
# Verify the subcloud was set to online
|
||||
self.fake_dcmanager_state_api.update_subcloud_availability.assert_called_with(
|
||||
mock.ANY, subcloud.name, dccommon_consts.AVAILABILITY_ONLINE,
|
||||
False, 0)
|
||||
mock.ANY, subcloud.name, subcloud.region_name,
|
||||
dccommon_consts.AVAILABILITY_ONLINE, False, 0)
|
||||
|
||||
# Verify the _update_subcloud_audit_fail_count is not called
|
||||
with mock.patch.object(wm, '_update_subcloud_audit_fail_count') as \
|
||||
|
@ -573,8 +574,8 @@ class TestAuditWorkerManager(base.DCManagerTestCase):
|
|||
|
||||
# Verify the subcloud was set to online
|
||||
self.fake_dcmanager_state_api.update_subcloud_availability.assert_called_with(
|
||||
mock.ANY, subcloud.name, dccommon_consts.AVAILABILITY_ONLINE,
|
||||
False, 0)
|
||||
mock.ANY, subcloud.name, subcloud.region_name,
|
||||
dccommon_consts.AVAILABILITY_ONLINE, False, 0)
|
||||
|
||||
# Verify the _update_subcloud_audit_fail_count is not called
|
||||
with mock.patch.object(wm, '_update_subcloud_audit_fail_count') as \
|
||||
|
@ -669,8 +670,8 @@ class TestAuditWorkerManager(base.DCManagerTestCase):
|
|||
|
||||
# Verify the subcloud state was updated even though no change
|
||||
self.fake_dcmanager_state_api.update_subcloud_availability.assert_called_with(
|
||||
mock.ANY, subcloud.name, dccommon_consts.AVAILABILITY_ONLINE,
|
||||
True, None)
|
||||
mock.ANY, subcloud.name, subcloud.region_name,
|
||||
dccommon_consts.AVAILABILITY_ONLINE, True, None)
|
||||
|
||||
# Verify the _update_subcloud_audit_fail_count is not called
|
||||
with mock.patch.object(wm, '_update_subcloud_audit_fail_count') as \
|
||||
|
@ -785,19 +786,19 @@ class TestAuditWorkerManager(base.DCManagerTestCase):
|
|||
|
||||
# Verify patch audit is called only once
|
||||
self.fake_patch_audit.subcloud_patch_audit.assert_called_once_with(
|
||||
subcloud.name, mock.ANY, True)
|
||||
subcloud.name, subcloud.region_name, mock.ANY, True)
|
||||
|
||||
# Verify firmware audit is only called once
|
||||
self.fake_firmware_audit.subcloud_firmware_audit.assert_called_once_with(
|
||||
subcloud.name, mock.ANY)
|
||||
subcloud.name, subcloud.region_name, mock.ANY)
|
||||
|
||||
# Verify kubernetes audit is only called once
|
||||
self.fake_kubernetes_audit.subcloud_kubernetes_audit.assert_called_once_with(
|
||||
subcloud.name, mock.ANY)
|
||||
subcloud.name, subcloud.region_name, mock.ANY)
|
||||
|
||||
# Verify kube rootca update audit is only called once
|
||||
self.fake_kube_rootca_update_audit.subcloud_audit.assert_called_once_with(
|
||||
subcloud.name, mock.ANY)
|
||||
subcloud.name, subcloud.region_name, mock.ANY)
|
||||
|
||||
def test_audit_subcloud_offline_no_change(self):
|
||||
subcloud = self.create_subcloud_static(self.ctx, name='subcloud1')
|
||||
|
@ -1060,12 +1061,12 @@ class TestAuditWorkerManager(base.DCManagerTestCase):
|
|||
|
||||
# Verify the openstack endpoints were removed
|
||||
self.fake_dcmanager_api.update_subcloud_sync_endpoint_type.\
|
||||
assert_called_with(mock.ANY, 'subcloud1',
|
||||
assert_called_with(mock.ANY, subcloud.region_name,
|
||||
dccommon_consts.ENDPOINT_TYPES_LIST_OS, False)
|
||||
|
||||
# Verify alarm update is called
|
||||
self.fake_alarm_aggr.update_alarm_summary.assert_called_once_with(
|
||||
'subcloud1', self.fake_openstack_client.fm_client)
|
||||
subcloud.name, self.fake_openstack_client.fm_client)
|
||||
|
||||
# Verify patch audit is not called
|
||||
self.fake_patch_audit.subcloud_patch_audit.assert_not_called()
|
||||
|
@ -1122,7 +1123,7 @@ class TestAuditWorkerManager(base.DCManagerTestCase):
|
|||
|
||||
# Verify the openstack endpoints were removed
|
||||
self.fake_dcmanager_api.update_subcloud_sync_endpoint_type.\
|
||||
assert_called_with(mock.ANY, 'subcloud1',
|
||||
assert_called_with(mock.ANY, subcloud.region_name,
|
||||
dccommon_consts.ENDPOINT_TYPES_LIST_OS, False)
|
||||
|
||||
# Verify alarm update is called
|
||||
|
@ -1195,7 +1196,7 @@ class TestAuditWorkerManager(base.DCManagerTestCase):
|
|||
|
||||
# Verify patch audit is called
|
||||
self.fake_patch_audit.subcloud_patch_audit.assert_called_with(
|
||||
subcloud.name, patch_audit_data, do_load_audit)
|
||||
subcloud.name, subcloud.region_name, patch_audit_data, do_load_audit)
|
||||
|
||||
# Verify the _update_subcloud_audit_fail_count is not called
|
||||
with mock.patch.object(wm, '_update_subcloud_audit_fail_count') as \
|
||||
|
|
|
@ -9,6 +9,7 @@ import base64
|
|||
from dcmanager.common import consts
|
||||
from dcmanager.db.sqlalchemy import api as db_api
|
||||
|
||||
from dcmanager.tests import base
|
||||
from dcmanager.tests import utils
|
||||
|
||||
FAKE_TENANT = utils.UUID1
|
||||
|
@ -33,6 +34,7 @@ FAKE_SUBCLOUD_DATA = {"id": FAKE_ID,
|
|||
"systemcontroller_gateway_address": "192.168.204.101",
|
||||
"deploy_status": consts.DEPLOY_STATE_DONE,
|
||||
'error_description': consts.ERROR_DESC_EMPTY,
|
||||
'region_name': base.SUBCLOUD_1['region_name'],
|
||||
"external_oam_subnet": "10.10.10.0/24",
|
||||
"external_oam_gateway_address": "10.10.10.1",
|
||||
"external_oam_floating_address": "10.10.10.12",
|
||||
|
@ -128,6 +130,7 @@ def create_fake_subcloud(ctxt, **kwargs):
|
|||
"systemcontroller_gateway_ip": "192.168.204.101",
|
||||
'deploy_status': consts.DEPLOY_STATE_DONE,
|
||||
'error_description': consts.ERROR_DESC_EMPTY,
|
||||
'region_name': base.SUBCLOUD_1['region_name'],
|
||||
'openstack_installed': False,
|
||||
'group_id': 1,
|
||||
'data_install': 'data from install',
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
import datetime
|
||||
|
||||
from oslo_db import exception as db_exception
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from dcmanager.common import exceptions as exception
|
||||
from dcmanager.db import api as api
|
||||
|
@ -40,6 +41,7 @@ class DBAPISubcloudAuditsTest(base.DCManagerTestCase):
|
|||
'systemcontroller_gateway_ip': "192.168.204.101",
|
||||
'deploy_status': "not-deployed",
|
||||
'error_description': 'No errors present',
|
||||
'region_name': uuidutils.generate_uuid().replace("-", ""),
|
||||
'openstack_installed': False,
|
||||
'group_id': 1,
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ class DBAPISubcloudTest(base.DCManagerTestCase):
|
|||
'systemcontroller_gateway_ip': "192.168.204.101",
|
||||
'deploy_status': "not-deployed",
|
||||
'error_description': 'No errors present',
|
||||
'region_name': base.SUBCLOUD_1['region_name'],
|
||||
'openstack_installed': False,
|
||||
'group_id': 1,
|
||||
}
|
||||
|
@ -78,6 +79,7 @@ class DBAPISubcloudTest(base.DCManagerTestCase):
|
|||
'systemcontroller_gateway_address'],
|
||||
'deploy_status': "not-deployed",
|
||||
'error_description': 'No errors present',
|
||||
'region_name': data['region_name'],
|
||||
'openstack_installed': False,
|
||||
'group_id': 1,
|
||||
}
|
||||
|
@ -143,19 +145,26 @@ class DBAPISubcloudTest(base.DCManagerTestCase):
|
|||
|
||||
def test_create_multiple_subclouds(self):
|
||||
name1 = 'testname1'
|
||||
region1 = base.SUBCLOUD_1['region_name']
|
||||
name2 = 'testname2'
|
||||
region2 = base.SUBCLOUD_2['region_name']
|
||||
name3 = 'testname3'
|
||||
subcloud = self.create_subcloud_static(self.ctx, name=name1)
|
||||
region3 = base.SUBCLOUD_3['region_name']
|
||||
subcloud = self.create_subcloud_static(self.ctx,
|
||||
name=name1,
|
||||
region_name=region1)
|
||||
self.assertIsNotNone(subcloud)
|
||||
|
||||
subcloud2 = self.create_subcloud_static(self.ctx,
|
||||
name=name2,
|
||||
region_name=region2,
|
||||
management_start_ip="2.3.4.6",
|
||||
management_end_ip="2.3.4.7")
|
||||
self.assertIsNotNone(subcloud2)
|
||||
|
||||
subcloud3 = self.create_subcloud_static(self.ctx,
|
||||
name=name3,
|
||||
region_name=region3,
|
||||
management_start_ip="3.3.4.6",
|
||||
management_end_ip="3.3.4.7")
|
||||
self.assertIsNotNone(subcloud3)
|
||||
|
|
|
@ -22,6 +22,7 @@ from dcmanager.manager import service
|
|||
from dcmanager.tests import base
|
||||
from dcmanager.tests import utils
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
CONF = cfg.CONF
|
||||
FAKE_USER = utils.UUID1
|
||||
|
@ -76,9 +77,11 @@ class TestDCManagerService(base.DCManagerTestCase):
|
|||
|
||||
@mock.patch.object(service, 'SubcloudManager')
|
||||
def test_add_subcloud(self, mock_subcloud_manager):
|
||||
payload = {'name': 'testname',
|
||||
'region_name': uuidutils.generate_uuid().replace("-", "")}
|
||||
self.service_obj.init_managers()
|
||||
self.service_obj.add_subcloud(
|
||||
self.context, subcloud_id=1, payload={'name': 'testname'})
|
||||
self.context, subcloud_id=1, payload=payload)
|
||||
mock_subcloud_manager().add_subcloud.\
|
||||
assert_called_once_with(self.context, 1, mock.ANY)
|
||||
|
||||
|
|
|
@ -423,6 +423,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
"systemcontroller_gateway_ip": "192.168.204.101",
|
||||
'deploy_status': "not-deployed",
|
||||
'error_description': "No errors present",
|
||||
'region_name': base.SUBCLOUD_1['region_name'],
|
||||
'openstack_installed': False,
|
||||
'group_id': 1,
|
||||
'data_install': 'data from install',
|
||||
|
@ -501,7 +502,8 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
values['deploy_status'] = consts.DEPLOY_STATE_NONE
|
||||
|
||||
# dcmanager add_subcloud queries the data from the db
|
||||
subcloud = self.create_subcloud_static(self.ctx, name=values['name'])
|
||||
subcloud = self.create_subcloud_static(self.ctx, name=values['name'],
|
||||
region_name=values['region_name'])
|
||||
values['id'] = subcloud.id
|
||||
|
||||
mock_keystone_client().keystone_client = FakeKeystoneClient()
|
||||
|
@ -535,7 +537,8 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
values['deploy_status'] = consts.DEPLOY_STATE_NONE
|
||||
|
||||
# dcmanager add_subcloud queries the data from the db
|
||||
subcloud = self.create_subcloud_static(self.ctx, name=values['name'])
|
||||
subcloud = self.create_subcloud_static(self.ctx, name=values['name'],
|
||||
region_name=values['region_name'])
|
||||
values['id'] = subcloud.id
|
||||
|
||||
mock_keystone_client.side_effect = FakeException('boom')
|
||||
|
@ -731,6 +734,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
|
||||
# Create subcloud in DB
|
||||
subcloud = self.create_subcloud_static(self.ctx, name=payload['name'])
|
||||
payload['region_name'] = subcloud.region_name
|
||||
|
||||
# Mock return values
|
||||
mock_get_playbook_for_software_version.return_value = SW_VERSION
|
||||
|
@ -790,7 +794,8 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
sysadmin_password = values['sysadmin_password']
|
||||
|
||||
# dcmanager add_subcloud queries the data from the db
|
||||
subcloud = self.create_subcloud_static(self.ctx, name=values['name'])
|
||||
subcloud = self.create_subcloud_static(self.ctx, name=values['name'],
|
||||
region_name=values['region_name'])
|
||||
|
||||
mock_keystone_client().keystone_client = FakeKeystoneClient()
|
||||
mock_keyring.get_password.return_value = sysadmin_password
|
||||
|
@ -809,6 +814,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
mock_run_playbook.assert_called_once()
|
||||
mock_compose_rehome_command.assert_called_once_with(
|
||||
values['name'],
|
||||
values['region_name'],
|
||||
sm._get_ansible_filename(values['name'], consts.INVENTORY_FILE_POSTFIX),
|
||||
subcloud['software_version'])
|
||||
|
||||
|
@ -836,7 +842,8 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
services = FAKE_SERVICES
|
||||
|
||||
# dcmanager add_subcloud queries the data from the db
|
||||
subcloud = self.create_subcloud_static(self.ctx, name=values['name'])
|
||||
subcloud = self.create_subcloud_static(self.ctx, name=values['name'],
|
||||
region_name=values['region_name'])
|
||||
|
||||
self.fake_dcorch_api.add_subcloud.side_effect = FakeException('boom')
|
||||
mock_get_cached_regionone_data.return_value = FAKE_CACHED_REGIONONE_DATA
|
||||
|
@ -865,7 +872,8 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
services = FAKE_SERVICES
|
||||
|
||||
# dcmanager add_subcloud queries the data from the db
|
||||
subcloud = self.create_subcloud_static(self.ctx, name=values['name'])
|
||||
subcloud = self.create_subcloud_static(self.ctx, name=values['name'],
|
||||
region_name=values['region_name'])
|
||||
|
||||
self.fake_dcorch_api.add_subcloud.side_effect = FakeException('boom')
|
||||
mock_get_cached_regionone_data.return_value = FAKE_CACHED_REGIONONE_DATA
|
||||
|
@ -933,7 +941,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
location="subcloud new location")
|
||||
|
||||
fake_dcmanager_notification.subcloud_managed.assert_called_once_with(
|
||||
self.ctx, subcloud.name)
|
||||
self.ctx, subcloud.region_name)
|
||||
|
||||
# Verify subcloud was updated with correct values
|
||||
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
|
||||
|
@ -1063,7 +1071,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
data_install="install values")
|
||||
|
||||
fake_dcmanager_cermon_api.subcloud_managed.assert_called_once_with(
|
||||
self.ctx, subcloud.name)
|
||||
self.ctx, subcloud.region_name)
|
||||
|
||||
# Verify subcloud was updated with correct values
|
||||
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
|
||||
|
@ -1190,7 +1198,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
group_id=2)
|
||||
|
||||
fake_dcmanager_cermon_api.subcloud_managed.assert_called_once_with(
|
||||
self.ctx, subcloud.name)
|
||||
self.ctx, subcloud.region_name)
|
||||
|
||||
# Verify subcloud was updated with correct values
|
||||
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, subcloud.name)
|
||||
|
@ -1234,7 +1242,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
dccommon_consts.ENDPOINT_TYPE_DC_CERT]:
|
||||
# Update
|
||||
ssm.update_subcloud_endpoint_status(
|
||||
self.ctx, subcloud_name=subcloud.name,
|
||||
self.ctx, subcloud_region=subcloud.region_name,
|
||||
endpoint_type=endpoint)
|
||||
|
||||
# Verify
|
||||
|
@ -1253,7 +1261,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
dccommon_consts.ENDPOINT_TYPE_NFV,
|
||||
dccommon_consts.ENDPOINT_TYPE_DC_CERT]:
|
||||
ssm.update_subcloud_endpoint_status(
|
||||
self.ctx, subcloud_name=subcloud.name,
|
||||
self.ctx, subcloud_region=subcloud.region_name,
|
||||
endpoint_type=endpoint,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
|
||||
|
@ -1267,7 +1275,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
# Attempt to update each status to be unknown for an offline/unmanaged
|
||||
# subcloud. This is allowed.
|
||||
ssm.update_subcloud_endpoint_status(
|
||||
self.ctx, subcloud_name=subcloud.name,
|
||||
self.ctx, subcloud_region=subcloud.region_name,
|
||||
endpoint_type=None,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_UNKNOWN)
|
||||
|
||||
|
@ -1286,7 +1294,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
# Attempt to update each status to be out-of-sync for an
|
||||
# offline/unmanaged subcloud. Exclude one endpoint. This is allowed.
|
||||
ssm.update_subcloud_endpoint_status(
|
||||
self.ctx, subcloud_name=subcloud.name,
|
||||
self.ctx, subcloud_region=subcloud.region_name,
|
||||
endpoint_type=None,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC,
|
||||
ignore_endpoints=[dccommon_consts.ENDPOINT_TYPE_DC_CERT])
|
||||
|
@ -1328,7 +1336,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
dccommon_consts.ENDPOINT_TYPE_FM,
|
||||
dccommon_consts.ENDPOINT_TYPE_NFV]:
|
||||
ssm.update_subcloud_endpoint_status(
|
||||
self.ctx, subcloud_name=subcloud.name,
|
||||
self.ctx, subcloud_region=subcloud.region_name,
|
||||
endpoint_type=endpoint,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
|
||||
|
@ -1343,7 +1351,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
# online/unmanaged subcloud. This is allowed. Verify the change.
|
||||
endpoint = dccommon_consts.ENDPOINT_TYPE_DC_CERT
|
||||
ssm.update_subcloud_endpoint_status(
|
||||
self.ctx, subcloud_name=subcloud.name,
|
||||
self.ctx, subcloud_region=subcloud.region_name,
|
||||
endpoint_type=endpoint,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
|
||||
|
@ -1373,7 +1381,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
dccommon_consts.ENDPOINT_TYPE_NFV,
|
||||
dccommon_consts.ENDPOINT_TYPE_DC_CERT]:
|
||||
ssm.update_subcloud_endpoint_status(
|
||||
self.ctx, subcloud_name=subcloud.name,
|
||||
self.ctx, subcloud_region=subcloud.region_name,
|
||||
endpoint_type=endpoint,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
|
||||
|
@ -1393,11 +1401,11 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
dccommon_consts.ENDPOINT_TYPE_NFV,
|
||||
dccommon_consts.ENDPOINT_TYPE_DC_CERT]:
|
||||
ssm.update_subcloud_endpoint_status(
|
||||
self.ctx, subcloud_name=subcloud.name,
|
||||
self.ctx, subcloud_region=subcloud.region_name,
|
||||
endpoint_type=endpoint,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_OUT_OF_SYNC)
|
||||
# Verify lock was called
|
||||
mock_lock.assert_called_with(subcloud.name)
|
||||
mock_lock.assert_called_with(subcloud.region_name)
|
||||
|
||||
# Verify status was updated
|
||||
updated_subcloud_status = db_api.subcloud_status_get(
|
||||
|
@ -1436,7 +1444,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
self.assertIsNotNone(status)
|
||||
self.assertEqual(status.sync_status, dccommon_consts.SYNC_STATUS_UNKNOWN)
|
||||
|
||||
ssm.update_subcloud_availability(self.ctx, subcloud.name,
|
||||
ssm.update_subcloud_availability(self.ctx, subcloud.region_name,
|
||||
dccommon_consts.AVAILABILITY_ONLINE)
|
||||
|
||||
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, 'subcloud1')
|
||||
|
@ -1445,13 +1453,14 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
dccommon_consts.AVAILABILITY_ONLINE)
|
||||
# Verify notifying dcorch
|
||||
self.fake_dcorch_api.update_subcloud_states.assert_called_once_with(
|
||||
self.ctx, subcloud.name, updated_subcloud.management_state,
|
||||
self.ctx, subcloud.region_name, updated_subcloud.management_state,
|
||||
dccommon_consts.AVAILABILITY_ONLINE)
|
||||
# Verify triggering audits
|
||||
self.fake_dcmanager_audit_api.trigger_subcloud_audits.\
|
||||
assert_called_once_with(self.ctx, subcloud.id)
|
||||
|
||||
fake_dcmanager_cermon_api.subcloud_online.assert_called_once_with(self.ctx, subcloud.name)
|
||||
fake_dcmanager_cermon_api.subcloud_online.\
|
||||
assert_called_once_with(self.ctx, subcloud.region_name)
|
||||
|
||||
def test_update_subcloud_availability_go_online_unmanaged(self):
|
||||
# create a subcloud
|
||||
|
@ -1483,7 +1492,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
self.assertIsNotNone(status)
|
||||
self.assertEqual(status.sync_status, dccommon_consts.SYNC_STATUS_UNKNOWN)
|
||||
|
||||
ssm.update_subcloud_availability(self.ctx, subcloud.name,
|
||||
ssm.update_subcloud_availability(self.ctx, subcloud.region_name,
|
||||
dccommon_consts.AVAILABILITY_ONLINE)
|
||||
|
||||
updated_subcloud = db_api.subcloud_get_by_name(self.ctx, 'subcloud1')
|
||||
|
@ -1492,13 +1501,14 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
dccommon_consts.AVAILABILITY_ONLINE)
|
||||
# Verify notifying dcorch
|
||||
self.fake_dcorch_api.update_subcloud_states.assert_called_once_with(
|
||||
self.ctx, subcloud.name, updated_subcloud.management_state,
|
||||
self.ctx, subcloud.region_name, updated_subcloud.management_state,
|
||||
dccommon_consts.AVAILABILITY_ONLINE)
|
||||
# Verify triggering audits
|
||||
self.fake_dcmanager_audit_api.trigger_subcloud_audits.\
|
||||
assert_called_once_with(self.ctx, subcloud.id)
|
||||
|
||||
fake_dcmanager_cermon_api.subcloud_online.assert_called_once_with(self.ctx, subcloud.name)
|
||||
fake_dcmanager_cermon_api.subcloud_online.\
|
||||
assert_called_once_with(self.ctx, subcloud.region_name)
|
||||
|
||||
def test_update_subcloud_availability_go_offline(self):
|
||||
subcloud = self.create_subcloud_static(self.ctx, name='subcloud1')
|
||||
|
@ -1520,7 +1530,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
db_api.subcloud_status_create(
|
||||
self.ctx, subcloud.id, endpoint)
|
||||
ssm.update_subcloud_endpoint_status(
|
||||
self.ctx, subcloud_name=subcloud.name,
|
||||
self.ctx, subcloud_region=subcloud.region_name,
|
||||
endpoint_type=endpoint,
|
||||
sync_status=dccommon_consts.SYNC_STATUS_IN_SYNC)
|
||||
|
||||
|
@ -1531,7 +1541,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
|
||||
# Audit fails once
|
||||
audit_fail_count = 1
|
||||
ssm.update_subcloud_availability(self.ctx, subcloud.name,
|
||||
ssm.update_subcloud_availability(self.ctx, subcloud.region_name,
|
||||
availability_status=None,
|
||||
audit_fail_count=audit_fail_count)
|
||||
# Verify the subcloud availability was not updated
|
||||
|
@ -1546,7 +1556,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
|
||||
# Audit fails again
|
||||
audit_fail_count = audit_fail_count + 1
|
||||
ssm.update_subcloud_availability(self.ctx, subcloud.name,
|
||||
ssm.update_subcloud_availability(self.ctx, subcloud.region_name,
|
||||
dccommon_consts.AVAILABILITY_OFFLINE,
|
||||
audit_fail_count=audit_fail_count)
|
||||
|
||||
|
@ -1557,7 +1567,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
|
||||
# Verify notifying dcorch
|
||||
self.fake_dcorch_api.update_subcloud_states.assert_called_once_with(
|
||||
self.ctx, subcloud.name, updated_subcloud.management_state,
|
||||
self.ctx, subcloud.region_name, updated_subcloud.management_state,
|
||||
dccommon_consts.AVAILABILITY_OFFLINE)
|
||||
|
||||
# Verify all endpoint statuses set to unknown
|
||||
|
@ -1597,7 +1607,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
|
||||
# Update identity to the original status
|
||||
ssm.update_subcloud_endpoint_status(
|
||||
self.ctx, subcloud_name=subcloud.name,
|
||||
self.ctx, subcloud_region=subcloud.region_name,
|
||||
endpoint_type=endpoint,
|
||||
sync_status=original_sync_status)
|
||||
|
||||
|
@ -1607,7 +1617,7 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
|
||||
# Update identity to new status and get the count of the trigger again
|
||||
ssm.update_subcloud_endpoint_status(
|
||||
self.ctx, subcloud_name=subcloud.name,
|
||||
self.ctx, subcloud_region=subcloud.region_name,
|
||||
endpoint_type=endpoint,
|
||||
sync_status=new_sync_status)
|
||||
new_trigger_subcloud_audits = \
|
||||
|
@ -1634,13 +1644,13 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
|
||||
# Test openstack app installed
|
||||
openstack_installed = True
|
||||
sm.update_subcloud_sync_endpoint_type(self.ctx, subcloud.name,
|
||||
sm.update_subcloud_sync_endpoint_type(self.ctx, subcloud.region_name,
|
||||
endpoint_type_list,
|
||||
openstack_installed)
|
||||
|
||||
# Verify notifying dcorch to add subcloud sync endpoint type
|
||||
self.fake_dcorch_api.add_subcloud_sync_endpoint_type.\
|
||||
assert_called_once_with(self.ctx, subcloud.name,
|
||||
assert_called_once_with(self.ctx, subcloud.region_name,
|
||||
endpoint_type_list)
|
||||
|
||||
# Verify the subcloud status created for os endpoints
|
||||
|
@ -1657,12 +1667,12 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
|
||||
# Test openstack app removed
|
||||
openstack_installed = False
|
||||
sm.update_subcloud_sync_endpoint_type(self.ctx, subcloud.name,
|
||||
sm.update_subcloud_sync_endpoint_type(self.ctx, subcloud.region_name,
|
||||
endpoint_type_list,
|
||||
openstack_installed)
|
||||
# Verify notifying dcorch to remove subcloud sync endpoint type
|
||||
self.fake_dcorch_api.remove_subcloud_sync_endpoint_type.\
|
||||
assert_called_once_with(self.ctx, subcloud.name,
|
||||
assert_called_once_with(self.ctx, subcloud.region_name,
|
||||
endpoint_type_list)
|
||||
|
||||
# Verify the subcloud status is deleted for os endpoints
|
||||
|
@ -1703,8 +1713,11 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
def test_compose_bootstrap_command(self, mock_isfile):
|
||||
mock_isfile.return_value = True
|
||||
sm = subcloud_manager.SubcloudManager()
|
||||
subcloud_name = base.SUBCLOUD_1['name']
|
||||
subcloud_region = base.SUBCLOUD_1['region_name']
|
||||
bootstrap_command = sm.compose_bootstrap_command(
|
||||
'subcloud1',
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
f'{dccommon_consts.ANSIBLE_OVERRIDES_PATH}/subcloud1_inventory.yml',
|
||||
FAKE_PREVIOUS_SW_VERSION)
|
||||
self.assertEqual(
|
||||
|
@ -1715,8 +1728,9 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
subcloud_manager.ANSIBLE_SUBCLOUD_PLAYBOOK,
|
||||
FAKE_PREVIOUS_SW_VERSION),
|
||||
'-i', f'{dccommon_consts.ANSIBLE_OVERRIDES_PATH}/subcloud1_inventory.yml',
|
||||
'--limit', 'subcloud1', '-e',
|
||||
f"override_files_dir='{dccommon_consts.ANSIBLE_OVERRIDES_PATH}' region_name=subcloud1",
|
||||
'--limit', '%s' % subcloud_name, '-e',
|
||||
str("override_files_dir='%s' region_name=%s") %
|
||||
(dccommon_consts.ANSIBLE_OVERRIDES_PATH, subcloud_region),
|
||||
'-e', "install_release_version=%s" % FAKE_PREVIOUS_SW_VERSION
|
||||
]
|
||||
)
|
||||
|
@ -1746,8 +1760,12 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
def test_compose_rehome_command(self, mock_isfile):
|
||||
mock_isfile.return_value = True
|
||||
sm = subcloud_manager.SubcloudManager()
|
||||
subcloud_name = base.SUBCLOUD_1['name']
|
||||
subcloud_region = base.SUBCLOUD_1['region_name']
|
||||
|
||||
rehome_command = sm.compose_rehome_command(
|
||||
'subcloud1',
|
||||
subcloud_name,
|
||||
subcloud_region,
|
||||
f'{dccommon_consts.ANSIBLE_OVERRIDES_PATH}/subcloud1_inventory.yml',
|
||||
FAKE_PREVIOUS_SW_VERSION)
|
||||
self.assertEqual(
|
||||
|
@ -1758,10 +1776,10 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
subcloud_manager.ANSIBLE_SUBCLOUD_REHOME_PLAYBOOK,
|
||||
FAKE_PREVIOUS_SW_VERSION),
|
||||
'-i', f'{dccommon_consts.ANSIBLE_OVERRIDES_PATH}/subcloud1_inventory.yml',
|
||||
'--limit', 'subcloud1',
|
||||
'--limit', subcloud_name,
|
||||
'--timeout', subcloud_manager.REHOME_PLAYBOOK_TIMEOUT,
|
||||
'-e',
|
||||
f"override_files_dir='{dccommon_consts.ANSIBLE_OVERRIDES_PATH}' region_name=subcloud1"
|
||||
'-e', str("override_files_dir='%s' region_name=%s") %
|
||||
(dccommon_consts.ANSIBLE_OVERRIDES_PATH, subcloud_region)
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -1823,39 +1841,48 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
def test_handle_subcloud_operations_in_progress(self):
|
||||
subcloud1 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud1',
|
||||
name=base.SUBCLOUD_1['name'],
|
||||
region_name=base.SUBCLOUD_1['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_PRE_DEPLOY)
|
||||
subcloud2 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud2',
|
||||
name=base.SUBCLOUD_2['name'],
|
||||
region_name=base.SUBCLOUD_2['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_PRE_INSTALL)
|
||||
subcloud3 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud3',
|
||||
name=base.SUBCLOUD_3['name'],
|
||||
region_name=base.SUBCLOUD_3['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_INSTALLING)
|
||||
subcloud4 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud4',
|
||||
name=base.SUBCLOUD_4['name'],
|
||||
region_name=base.SUBCLOUD_4['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_BOOTSTRAPPING)
|
||||
subcloud5 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud5',
|
||||
name=base.SUBCLOUD_5['name'],
|
||||
region_name=base.SUBCLOUD_5['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_DEPLOYING)
|
||||
subcloud6 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud6',
|
||||
name=base.SUBCLOUD_6['name'],
|
||||
region_name=base.SUBCLOUD_6['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_MIGRATING_DATA)
|
||||
subcloud7 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud7',
|
||||
name=base.SUBCLOUD_7['name'],
|
||||
region_name=base.SUBCLOUD_7['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_PRE_RESTORE)
|
||||
subcloud8 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud8',
|
||||
name=base.SUBCLOUD_8['name'],
|
||||
region_name=base.SUBCLOUD_8['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_RESTORING)
|
||||
subcloud9 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud9',
|
||||
name=base.SUBCLOUD_9['name'],
|
||||
region_name=base.SUBCLOUD_9['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_NONE)
|
||||
subcloud10 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
|
@ -1940,47 +1967,58 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
def test_handle_completed_subcloud_operations(self):
|
||||
subcloud1 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud1',
|
||||
name=base.SUBCLOUD_1['name'],
|
||||
region_name=base.SUBCLOUD_1['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_CREATE_FAILED)
|
||||
subcloud2 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud2',
|
||||
name=base.SUBCLOUD_2['name'],
|
||||
region_name=base.SUBCLOUD_2['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_PRE_INSTALL_FAILED)
|
||||
subcloud3 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud3',
|
||||
name=base.SUBCLOUD_3['name'],
|
||||
region_name=base.SUBCLOUD_3['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_INSTALL_FAILED)
|
||||
subcloud4 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud4',
|
||||
name=base.SUBCLOUD_4['name'],
|
||||
region_name=base.SUBCLOUD_4['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_INSTALLED)
|
||||
subcloud5 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud5',
|
||||
name=base.SUBCLOUD_5['name'],
|
||||
region_name=base.SUBCLOUD_5['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_BOOTSTRAP_FAILED)
|
||||
subcloud6 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud6',
|
||||
name=base.SUBCLOUD_6['name'],
|
||||
region_name=base.SUBCLOUD_6['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_CONFIG_FAILED)
|
||||
subcloud7 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud7',
|
||||
name=base.SUBCLOUD_7['name'],
|
||||
region_name=base.SUBCLOUD_7['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_DATA_MIGRATION_FAILED)
|
||||
subcloud8 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud8',
|
||||
name=base.SUBCLOUD_8['name'],
|
||||
region_name=base.SUBCLOUD_8['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_MIGRATED)
|
||||
subcloud9 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud9',
|
||||
name=base.SUBCLOUD_9['name'],
|
||||
region_name=base.SUBCLOUD_9['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_RESTORE_PREP_FAILED)
|
||||
subcloud10 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud10',
|
||||
name=base.SUBCLOUD_10['name'],
|
||||
region_name=base.SUBCLOUD_10['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_RESTORE_FAILED)
|
||||
subcloud11 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
name='subcloud11',
|
||||
name=base.SUBCLOUD_11['name'],
|
||||
region_name=base.SUBCLOUD_11['region_name'],
|
||||
deploy_status=consts.DEPLOY_STATE_DONE)
|
||||
subcloud12 = self.create_subcloud_static(
|
||||
self.ctx,
|
||||
|
@ -2792,7 +2830,8 @@ class TestSubcloudManager(base.DCManagerTestCase):
|
|||
values = {
|
||||
'name': 'TestSubcloud',
|
||||
'sysadmin_password': '123',
|
||||
'secondary': 'true'
|
||||
'secondary': 'true',
|
||||
'region_name': '2ec93dfb654846909efe61d1b39dd2ce'
|
||||
}
|
||||
|
||||
# Create an instance of SubcloudManager
|
||||
|
|
|
@ -8,6 +8,7 @@ import mock
|
|||
from dccommon import consts as dccommon_consts
|
||||
from dcmanager.common import consts
|
||||
from dcmanager.db.sqlalchemy import api as db_api
|
||||
from dcmanager.tests import base
|
||||
from dcmanager.tests.unit.common import fake_strategy
|
||||
from dcmanager.tests.unit.common import fake_subcloud
|
||||
from dcmanager.tests.unit.orchestrator.states.fakes import FakeAlarm
|
||||
|
@ -520,7 +521,8 @@ class TestSwUpgradePreCheckSimplexStage(TestSwUpgradePreCheckStage):
|
|||
# and no data install values
|
||||
self.subcloud = fake_subcloud.create_fake_subcloud(
|
||||
self.ctx,
|
||||
name="subcloud2",
|
||||
name=base.SUBCLOUD_2['name'],
|
||||
region_name=base.SUBCLOUD_2['region_name'],
|
||||
data_install=None
|
||||
)
|
||||
|
||||
|
@ -604,7 +606,8 @@ class TestSwUpgradePreCheckSimplexStage(TestSwUpgradePreCheckStage):
|
|||
# availability status as "offline" and no data install values
|
||||
self.subcloud = fake_subcloud.create_fake_subcloud(
|
||||
self.ctx,
|
||||
name="subcloud2",
|
||||
name=base.SUBCLOUD_2['name'],
|
||||
region_name=base.SUBCLOUD_2['region_name'],
|
||||
data_install=None,
|
||||
deploy_status=consts.DEPLOY_STATE_INSTALL_FAILED
|
||||
)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
import mock
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from dccommon import consts as dccommon_consts
|
||||
from dccommon.drivers.openstack import vim
|
||||
|
@ -39,6 +40,7 @@ class TestFwOrchThread(TestSwUpdate):
|
|||
"systemcontroller_gateway_ip": "192.168.204.101",
|
||||
'deploy_status': "not-deployed",
|
||||
'error_description': 'No errors present',
|
||||
'region_name': uuidutils.generate_uuid().replace("-", ""),
|
||||
'openstack_installed': False,
|
||||
'group_id': group_id,
|
||||
'data_install': 'data from install',
|
||||
|
|
|
@ -17,6 +17,7 @@ import copy
|
|||
import mock
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from dccommon import consts as dccommon_consts
|
||||
from dcmanager.common import consts
|
||||
|
@ -117,6 +118,7 @@ class TestSwUpdateManager(base.DCManagerTestCase):
|
|||
"systemcontroller_gateway_ip": "192.168.204.101",
|
||||
'deploy_status': "not-deployed",
|
||||
'error_description': 'No errors present',
|
||||
'region_name': uuidutils.generate_uuid().replace("-", ""),
|
||||
'openstack_installed': False,
|
||||
'group_id': group_id,
|
||||
'data_install': 'data from install',
|
||||
|
|
|
@ -93,4 +93,5 @@ def create_subcloud_dict(data_list):
|
|||
'group_id': data_list[23],
|
||||
'deploy_status': data_list[24],
|
||||
'error_description': data_list[25],
|
||||
'data_install': data_list[26]}
|
||||
'region_name': data_list[26],
|
||||
'data_install': data_list[27]}
|
||||
|
|
|
@ -377,12 +377,12 @@ def add_identity_filter(query, value,
|
|||
|
||||
:return: Modified query.
|
||||
"""
|
||||
if strutils.is_int_like(value):
|
||||
if use_region_name:
|
||||
return query.filter_by(region_name=value)
|
||||
elif strutils.is_int_like(value):
|
||||
return query.filter_by(id=value)
|
||||
elif uuidutils.is_uuid_like(value):
|
||||
return query.filter_by(uuid=value)
|
||||
elif use_region_name:
|
||||
return query.filter_by(region_name=value)
|
||||
elif use_resource_type:
|
||||
return query.filter_by(resource_type=value)
|
||||
else:
|
||||
|
|
|
@ -87,6 +87,7 @@ class SyncThread(object):
|
|||
self.log_extra = {
|
||||
"instance": self.subcloud_name + ": "}
|
||||
self.dcmanager_state_rpc_client = dcmanager_rpc_client.SubcloudStateClient()
|
||||
self.dcmanager_rpc_client = dcmanager_rpc_client.ManagerClient()
|
||||
|
||||
self.sc_admin_session = None
|
||||
self.admin_session = None
|
||||
|
@ -298,15 +299,35 @@ class SyncThread(object):
|
|||
self.subcloud_name, sync_status, alarmable),
|
||||
extra=self.log_extra)
|
||||
|
||||
self.dcmanager_state_rpc_client.update_subcloud_endpoint_status(
|
||||
self.ctxt, self.subcloud_name,
|
||||
self.endpoint_type, sync_status,
|
||||
alarmable=alarmable)
|
||||
try:
|
||||
# This block is required to get the real subcloud name
|
||||
# dcorch uses the subcloud name as the region name.
|
||||
# The region name cannot be changed, so at this point it
|
||||
# is necessary to query the subcloud name as it is required
|
||||
# for logging purposes.
|
||||
|
||||
db_api.subcloud_sync_update(
|
||||
self.ctxt, self.subcloud_name, self.endpoint_type,
|
||||
values={'sync_status_reported': sync_status,
|
||||
'sync_status_report_time': timeutils.utcnow()})
|
||||
# Save current subcloud name (region name from dcorch DB)
|
||||
dcorch_subcloud_region = self.subcloud_name
|
||||
|
||||
# Get the subcloud name from dcmanager database supplying
|
||||
# the dcorch region name
|
||||
subcloud_name = self.dcmanager_rpc_client \
|
||||
.get_subcloud_name_by_region_name(self.ctxt,
|
||||
dcorch_subcloud_region)
|
||||
|
||||
# Updates the endpoint status supplying the subcloud name and
|
||||
# the region name
|
||||
self.dcmanager_state_rpc_client.update_subcloud_endpoint_status(
|
||||
self.ctxt, subcloud_name, dcorch_subcloud_region,
|
||||
self.endpoint_type, sync_status,
|
||||
alarmable=alarmable)
|
||||
|
||||
db_api.subcloud_sync_update(
|
||||
self.ctxt, dcorch_subcloud_region, self.endpoint_type,
|
||||
values={'sync_status_reported': sync_status,
|
||||
'sync_status_report_time': timeutils.utcnow()})
|
||||
except Exception:
|
||||
raise
|
||||
|
||||
def sync(self, engine_id):
|
||||
LOG.debug("{}: starting sync routine".format(self.subcloud_name),
|
||||
|
|
Loading…
Reference in New Issue