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:
Gerry Kopec 2020-07-23 08:06:07 -04:00
parent 8c94888424
commit 54ef00192d
4 changed files with 63 additions and 18 deletions

View File

@ -13,7 +13,7 @@
# License for the specific language governing permissions and 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
#
@ -392,6 +392,7 @@ def project_update(context, project_id, payload):
domain_ref_projects = []
parent_ref_projects = []
domain_ref_users = []
domain_ref_local_users = []
project = payload[table]
new_project_id = project.get('id')
if project_id != new_project_id:

View File

@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# 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
#
@ -90,6 +90,15 @@ class Unauthorized(DBsyncClientException):
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):
message = "NotFoundException occurred"
code = "NOTFOUND_EXCEPTION"

View File

@ -391,12 +391,21 @@ class IdentitySyncThread(SyncThread):
raise exceptions.SyncRequestTimeout
except (dbsync_exceptions.Unauthorized,
keystone_exceptions.Unauthorized) as e:
LOG.info("Request [{}] failed for {}: {}"
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_sc_clients()
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:
raise
except Exception as e:
@ -417,7 +426,11 @@ class IdentitySyncThread(SyncThread):
# Retrieve DB records of the user just created. The records is in JSON
# 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:
LOG.error("No data retrieved from master cloud for user {} to"
" 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
# 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:
LOG.error("No data retrieved from master cloud for user {} to"
" update its equivalent in subcloud.".format(user_id),
@ -584,8 +601,11 @@ class IdentitySyncThread(SyncThread):
# Retrieve DB records of the project just created.
# The records is in JSON format.
project_records = self.m_dbs_client.project_manager.\
project_detail(project_id)
try:
project_records = self.m_dbs_client.project_manager.\
project_detail(project_id)
except dbsync_exceptions.Unauthorized:
raise dbsync_exceptions.UnauthorizedMaster
if not project_records:
LOG.error("No data retrieved from master cloud for project {} to"
" 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
# format
project_records = self.m_dbs_client.project_manager.\
project_detail(project_id)
try:
project_records = self.m_dbs_client.project_manager.\
project_detail(project_id)
except dbsync_exceptions.Unauthorized:
raise dbsync_exceptions.UnauthorizedMaster
if not project_records:
LOG.error("No data retrieved from master cloud for project {} to"
" 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
# format.
role_records = self.m_dbs_client.role_manager.\
role_detail(role_id)
try:
role_records = self.m_dbs_client.role_manager.\
role_detail(role_id)
except dbsync_exceptions.Unauthorized:
raise dbsync_exceptions.UnauthorizedMaster
if not role_records:
LOG.error("No data retrieved from master cloud for role {} to"
" 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
# format
role_records = self.m_dbs_client.role_manager.\
role_detail(role_id)
try:
role_records = self.m_dbs_client.role_manager.\
role_detail(role_id)
except dbsync_exceptions.Unauthorized:
raise dbsync_exceptions.UnauthorizedMaster
if not role_records:
LOG.error("No data retrieved from master cloud for role {} to"
" 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
# is in JSON format.
revoke_event_records = self.m_dbs_client.revoke_event_manager.\
revoke_event_detail(audit_id=audit_id)
try:
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:
LOG.error("No data retrieved from master cloud for token"
" 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
# is in JSON format.
revoke_event_records = self.m_dbs_client.revoke_event_manager.\
revoke_event_detail(user_id=event_id)
try:
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:
LOG.error("No data retrieved from master cloud for token"
" revocation event with event_id {} to create its"

View File

@ -63,7 +63,7 @@ AUDIT_LOCK_NAME = 'dcorch-audit'
class SyncThread(object):
"""Manages tasks related to resource management."""
MAX_RETRY = 2
MAX_RETRY = 3
# used by the audit to cache the master resources
master_resources_dict = collections.defaultdict(dict)