Add master reauthentication for identity data sync
This fixes Issue #4 from Bug 1870999 where some subclouds failed to sync an identity resource change. This was due to unauthorized request error on the master cloud due to expired token. The current error handling only covers reauthentication of subcloud dbs client. In addition, the number of sync tries is increased from 2 to 3 to accommodate the case were data sync fails authentication on master and subcloud. Also fix exception in dcdbsync on subcloud due to uninitialized variable when handling change to project resource from dcorch audit on system controller. Change-Id: Ife8d86481a64ed841f5231a6df055028ee6597b0 Partial-Bug: 1870999 Signed-off-by: Gerry Kopec <gerry.kopec@windriver.com>
This commit is contained in:
parent
8c94888424
commit
54ef00192d
@ -13,7 +13,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2019 Wind River Systems, Inc.
|
# Copyright (c) 2019-2020 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
@ -392,6 +392,7 @@ def project_update(context, project_id, payload):
|
|||||||
domain_ref_projects = []
|
domain_ref_projects = []
|
||||||
parent_ref_projects = []
|
parent_ref_projects = []
|
||||||
domain_ref_users = []
|
domain_ref_users = []
|
||||||
|
domain_ref_local_users = []
|
||||||
project = payload[table]
|
project = payload[table]
|
||||||
new_project_id = project.get('id')
|
new_project_id = project.get('id')
|
||||||
if project_id != new_project_id:
|
if project_id != new_project_id:
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2019 Wind River Systems, Inc.
|
# Copyright (c) 2019-2020 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
@ -90,6 +90,15 @@ class Unauthorized(DBsyncClientException):
|
|||||||
self.message = message
|
self.message = message
|
||||||
|
|
||||||
|
|
||||||
|
class UnauthorizedMaster(DBsyncClientException):
|
||||||
|
message = "Unauthorized request - master resource"
|
||||||
|
code = "UNAUTHORIZED_EXCEPTION_MASTER"
|
||||||
|
|
||||||
|
def __init__(self, message=None):
|
||||||
|
if message:
|
||||||
|
self.message = message
|
||||||
|
|
||||||
|
|
||||||
class NotFound(DBsyncClientException):
|
class NotFound(DBsyncClientException):
|
||||||
message = "NotFoundException occurred"
|
message = "NotFoundException occurred"
|
||||||
code = "NOTFOUND_EXCEPTION"
|
code = "NOTFOUND_EXCEPTION"
|
||||||
|
@ -391,12 +391,21 @@ class IdentitySyncThread(SyncThread):
|
|||||||
raise exceptions.SyncRequestTimeout
|
raise exceptions.SyncRequestTimeout
|
||||||
except (dbsync_exceptions.Unauthorized,
|
except (dbsync_exceptions.Unauthorized,
|
||||||
keystone_exceptions.Unauthorized) as e:
|
keystone_exceptions.Unauthorized) as e:
|
||||||
LOG.info("Request [{}] failed for {}: {}"
|
LOG.info("Request [{} {}] failed for {}: {}"
|
||||||
.format(request.orch_job.operation_type,
|
.format(request.orch_job.operation_type,
|
||||||
|
rsrc.resource_type,
|
||||||
self.subcloud_engine.subcloud.region_name,
|
self.subcloud_engine.subcloud.region_name,
|
||||||
str(e)), extra=self.log_extra)
|
str(e)), extra=self.log_extra)
|
||||||
self.reauthenticate_sc_clients()
|
self.reauthenticate_sc_clients()
|
||||||
raise exceptions.SyncRequestFailedRetry
|
raise exceptions.SyncRequestFailedRetry
|
||||||
|
except dbsync_exceptions.UnauthorizedMaster as e:
|
||||||
|
LOG.info("Request [{} {}] failed for {}: {}"
|
||||||
|
.format(request.orch_job.operation_type,
|
||||||
|
rsrc.resource_type,
|
||||||
|
self.subcloud_engine.subcloud.region_name,
|
||||||
|
str(e)), extra=self.log_extra)
|
||||||
|
self.reauthenticate_m_dbs_client()
|
||||||
|
raise exceptions.SyncRequestFailedRetry
|
||||||
except exceptions.SyncRequestFailed:
|
except exceptions.SyncRequestFailed:
|
||||||
raise
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -417,7 +426,11 @@ class IdentitySyncThread(SyncThread):
|
|||||||
|
|
||||||
# Retrieve DB records of the user just created. The records is in JSON
|
# Retrieve DB records of the user just created. The records is in JSON
|
||||||
# format
|
# format
|
||||||
user_records = self.m_dbs_client.identity_manager.user_detail(user_id)
|
try:
|
||||||
|
user_records = self.m_dbs_client.identity_manager.\
|
||||||
|
user_detail(user_id)
|
||||||
|
except dbsync_exceptions.Unauthorized:
|
||||||
|
raise dbsync_exceptions.UnauthorizedMaster
|
||||||
if not user_records:
|
if not user_records:
|
||||||
LOG.error("No data retrieved from master cloud for user {} to"
|
LOG.error("No data retrieved from master cloud for user {} to"
|
||||||
" create its equivalent in subcloud.".format(user_id),
|
" create its equivalent in subcloud.".format(user_id),
|
||||||
@ -464,7 +477,11 @@ class IdentitySyncThread(SyncThread):
|
|||||||
|
|
||||||
# Retrieve DB records of the user. The records is in JSON
|
# Retrieve DB records of the user. The records is in JSON
|
||||||
# format
|
# format
|
||||||
user_records = self.m_dbs_client.identity_manager.user_detail(user_id)
|
try:
|
||||||
|
user_records = self.m_dbs_client.identity_manager.\
|
||||||
|
user_detail(user_id)
|
||||||
|
except dbsync_exceptions.Unauthorized:
|
||||||
|
raise dbsync_exceptions.UnauthorizedMaster
|
||||||
if not user_records:
|
if not user_records:
|
||||||
LOG.error("No data retrieved from master cloud for user {} to"
|
LOG.error("No data retrieved from master cloud for user {} to"
|
||||||
" update its equivalent in subcloud.".format(user_id),
|
" update its equivalent in subcloud.".format(user_id),
|
||||||
@ -584,8 +601,11 @@ class IdentitySyncThread(SyncThread):
|
|||||||
|
|
||||||
# Retrieve DB records of the project just created.
|
# Retrieve DB records of the project just created.
|
||||||
# The records is in JSON format.
|
# The records is in JSON format.
|
||||||
project_records = self.m_dbs_client.project_manager.\
|
try:
|
||||||
project_detail(project_id)
|
project_records = self.m_dbs_client.project_manager.\
|
||||||
|
project_detail(project_id)
|
||||||
|
except dbsync_exceptions.Unauthorized:
|
||||||
|
raise dbsync_exceptions.UnauthorizedMaster
|
||||||
if not project_records:
|
if not project_records:
|
||||||
LOG.error("No data retrieved from master cloud for project {} to"
|
LOG.error("No data retrieved from master cloud for project {} to"
|
||||||
" create its equivalent in subcloud.".format(project_id),
|
" create its equivalent in subcloud.".format(project_id),
|
||||||
@ -633,8 +653,11 @@ class IdentitySyncThread(SyncThread):
|
|||||||
|
|
||||||
# Retrieve DB records of the project. The records is in JSON
|
# Retrieve DB records of the project. The records is in JSON
|
||||||
# format
|
# format
|
||||||
project_records = self.m_dbs_client.project_manager.\
|
try:
|
||||||
project_detail(project_id)
|
project_records = self.m_dbs_client.project_manager.\
|
||||||
|
project_detail(project_id)
|
||||||
|
except dbsync_exceptions.Unauthorized:
|
||||||
|
raise dbsync_exceptions.UnauthorizedMaster
|
||||||
if not project_records:
|
if not project_records:
|
||||||
LOG.error("No data retrieved from master cloud for project {} to"
|
LOG.error("No data retrieved from master cloud for project {} to"
|
||||||
" update its equivalent in subcloud.".format(project_id),
|
" update its equivalent in subcloud.".format(project_id),
|
||||||
@ -749,8 +772,11 @@ class IdentitySyncThread(SyncThread):
|
|||||||
|
|
||||||
# Retrieve DB records of the role just created. The records is in JSON
|
# Retrieve DB records of the role just created. The records is in JSON
|
||||||
# format.
|
# format.
|
||||||
role_records = self.m_dbs_client.role_manager.\
|
try:
|
||||||
role_detail(role_id)
|
role_records = self.m_dbs_client.role_manager.\
|
||||||
|
role_detail(role_id)
|
||||||
|
except dbsync_exceptions.Unauthorized:
|
||||||
|
raise dbsync_exceptions.UnauthorizedMaster
|
||||||
if not role_records:
|
if not role_records:
|
||||||
LOG.error("No data retrieved from master cloud for role {} to"
|
LOG.error("No data retrieved from master cloud for role {} to"
|
||||||
" create its equivalent in subcloud.".format(role_id),
|
" create its equivalent in subcloud.".format(role_id),
|
||||||
@ -798,8 +824,11 @@ class IdentitySyncThread(SyncThread):
|
|||||||
|
|
||||||
# Retrieve DB records of the role. The records is in JSON
|
# Retrieve DB records of the role. The records is in JSON
|
||||||
# format
|
# format
|
||||||
role_records = self.m_dbs_client.role_manager.\
|
try:
|
||||||
role_detail(role_id)
|
role_records = self.m_dbs_client.role_manager.\
|
||||||
|
role_detail(role_id)
|
||||||
|
except dbsync_exceptions.Unauthorized:
|
||||||
|
raise dbsync_exceptions.UnauthorizedMaster
|
||||||
if not role_records:
|
if not role_records:
|
||||||
LOG.error("No data retrieved from master cloud for role {} to"
|
LOG.error("No data retrieved from master cloud for role {} to"
|
||||||
" update its equivalent in subcloud.".format(role_id),
|
" update its equivalent in subcloud.".format(role_id),
|
||||||
@ -1057,8 +1086,11 @@ class IdentitySyncThread(SyncThread):
|
|||||||
|
|
||||||
# Retrieve DB records of the revoke event just created. The records
|
# Retrieve DB records of the revoke event just created. The records
|
||||||
# is in JSON format.
|
# is in JSON format.
|
||||||
revoke_event_records = self.m_dbs_client.revoke_event_manager.\
|
try:
|
||||||
revoke_event_detail(audit_id=audit_id)
|
revoke_event_records = self.m_dbs_client.revoke_event_manager.\
|
||||||
|
revoke_event_detail(audit_id=audit_id)
|
||||||
|
except dbsync_exceptions.Unauthorized:
|
||||||
|
raise dbsync_exceptions.UnauthorizedMaster
|
||||||
if not revoke_event_records:
|
if not revoke_event_records:
|
||||||
LOG.error("No data retrieved from master cloud for token"
|
LOG.error("No data retrieved from master cloud for token"
|
||||||
" revocation event with audit_id {} to create its"
|
" revocation event with audit_id {} to create its"
|
||||||
@ -1128,8 +1160,11 @@ class IdentitySyncThread(SyncThread):
|
|||||||
|
|
||||||
# Retrieve DB records of the revoke event just created. The records
|
# Retrieve DB records of the revoke event just created. The records
|
||||||
# is in JSON format.
|
# is in JSON format.
|
||||||
revoke_event_records = self.m_dbs_client.revoke_event_manager.\
|
try:
|
||||||
revoke_event_detail(user_id=event_id)
|
revoke_event_records = self.m_dbs_client.revoke_event_manager.\
|
||||||
|
revoke_event_detail(user_id=event_id)
|
||||||
|
except dbsync_exceptions.Unauthorized:
|
||||||
|
raise dbsync_exceptions.UnauthorizedMaster
|
||||||
if not revoke_event_records:
|
if not revoke_event_records:
|
||||||
LOG.error("No data retrieved from master cloud for token"
|
LOG.error("No data retrieved from master cloud for token"
|
||||||
" revocation event with event_id {} to create its"
|
" revocation event with event_id {} to create its"
|
||||||
|
@ -63,7 +63,7 @@ AUDIT_LOCK_NAME = 'dcorch-audit'
|
|||||||
class SyncThread(object):
|
class SyncThread(object):
|
||||||
"""Manages tasks related to resource management."""
|
"""Manages tasks related to resource management."""
|
||||||
|
|
||||||
MAX_RETRY = 2
|
MAX_RETRY = 3
|
||||||
# used by the audit to cache the master resources
|
# used by the audit to cache the master resources
|
||||||
master_resources_dict = collections.defaultdict(dict)
|
master_resources_dict = collections.defaultdict(dict)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user