Skip to content

Commit 9157b72

Browse files
authored
Handle PermisssionDenied exception so that a new dashboard is created. (#4209)
## Changes Integration test for invalid dashboard is failining on PermissionDenied which we currently do not handle. Add a handler for PermissionDenied so that the older one is ignored and a new dashboard is creted. ### Linked issues Resolves #4208 ### Functionality - [x] handle older dangling dashboard ### Tests - [x] existing test
1 parent 66dafd8 commit 9157b72

File tree

1 file changed

+36
-19
lines changed

1 file changed

+36
-19
lines changed

src/databricks/labs/ucx/install.py

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -619,31 +619,48 @@ def _handle_existing_dashboard(self, dashboard_id: str, display_name: str, paren
619619
str | None :
620620
The dashboard id. If None, the dashboard will be recreated.
621621
"""
622-
if "-" in dashboard_id:
623-
logger.info(f"Upgrading dashboard to Lakeview: {display_name} ({dashboard_id})")
624-
try:
625-
self._ws.dashboards.delete(dashboard_id=dashboard_id)
626-
except BadRequest:
627-
logger.warning(f"Cannot delete dashboard: {display_name} ({dashboard_id})")
628-
return None # Recreate the dashboard if upgrading from Redash
622+
if self._is_redash_dashboard(dashboard_id):
623+
self._upgrade_redash_dashboard(dashboard_id, display_name)
629624
try:
630625
dashboard = self._ws.lakeview.get(dashboard_id)
631-
if dashboard.lifecycle_state is None:
632-
raise NotFound(f"Dashboard life cycle state: {display_name} ({dashboard_id})")
633-
if dashboard.lifecycle_state == LifecycleState.TRASHED:
634-
logger.info(f"Recreating trashed dashboard: {display_name} ({dashboard_id})")
626+
if self._is_trashed_dashboard(dashboard, display_name, dashboard_id):
635627
return None # Recreate the dashboard if it is trashed (manually)
636628
except (NotFound, InvalidParameterValue):
637-
logger.info(f"Recovering invalid dashboard: {display_name} ({dashboard_id})")
638-
try:
639-
dashboard_path = f"{parent_path}/{display_name}.lvdash.json"
640-
self._ws.workspace.delete(dashboard_path) # Cannot recreate dashboard if file still exists
641-
logger.debug(f"Deleted dangling dashboard {display_name} ({dashboard_id}): {dashboard_path}")
642-
except NotFound:
643-
pass
644-
return None # Recreate the dashboard if it's reference is corrupted (manually)
629+
self._recover_invalid_dashboard(dashboard_id, display_name, parent_path)
630+
return None
631+
except PermissionDenied:
632+
logger.warning(f"Cannot access dashboard {display_name} ({dashboard_id}), permission denied")
633+
return None # Create a new dashboard if permission is denied.
645634
return dashboard_id # Update the existing dashboard
646635

636+
def _is_redash_dashboard(self, dashboard_id: str) -> bool:
637+
"""Check if the dashboard is a Redash dashboard"""
638+
return "-" in dashboard_id
639+
640+
def _upgrade_redash_dashboard(self, dashboard_id: str, display_name: str) -> None:
641+
logger.info(f"Upgrading dashboard to Lakeview: {display_name} ({dashboard_id})")
642+
try:
643+
self._ws.dashboards.delete(dashboard_id=dashboard_id)
644+
except BadRequest:
645+
logger.warning(f"Cannot delete dashboard: {display_name} ({dashboard_id})")
646+
647+
def _is_trashed_dashboard(self, dashboard, display_name: str, dashboard_id: str) -> bool:
648+
if dashboard.lifecycle_state is None:
649+
raise NotFound(f"Dashboard life cycle state: {display_name} ({dashboard_id})")
650+
if dashboard.lifecycle_state == LifecycleState.TRASHED:
651+
logger.info(f"Recreating trashed dashboard: {display_name} ({dashboard_id})")
652+
return True
653+
return False
654+
655+
def _recover_invalid_dashboard(self, dashboard_id: str, display_name: str, parent_path: str) -> None:
656+
logger.info(f"Recovering invalid dashboard: {display_name} ({dashboard_id})")
657+
try:
658+
dashboard_path = f"{parent_path}/{display_name}.lvdash.json"
659+
self._ws.workspace.delete(dashboard_path) # Cannot recreate dashboard if file still exists
660+
logger.debug(f"Deleted dangling dashboard {display_name} ({dashboard_id}): {dashboard_path}")
661+
except NotFound:
662+
pass
663+
647664
# InternalError and DeadlineExceeded are retried because of Lakeview internal issues
648665
# These issues have been reported to and are resolved by the Lakeview team
649666
# Keeping the retry for resilience

0 commit comments

Comments
 (0)