11import logging
2+ import os
23from collections .abc import Callable , Iterator
34from itertools import groupby
45from typing import Literal
56
7+ from databricks .sdk import WorkspaceClient
8+ from databricks .sdk .service import sql
9+
610from databricks .labs .ucx .framework .crawlers import CrawlerBase , SqlBackend
711from databricks .labs .ucx .framework .parallel import Threads
12+ from databricks .labs .ucx .workspace_access import generic , redash , scim , secrets
813from databricks .labs .ucx .workspace_access .base import Applier , Crawler , Permissions
914from databricks .labs .ucx .workspace_access .groups import GroupMigrationState
1015
@@ -19,6 +24,74 @@ def __init__(
1924 self ._crawlers = crawlers
2025 self ._appliers = appliers
2126
27+ @classmethod
28+ def factory (
29+ cls ,
30+ ws : WorkspaceClient ,
31+ sql_backend : SqlBackend ,
32+ inventory_database : str ,
33+ * ,
34+ num_threads : int | None = None ,
35+ workspace_start_path : str = "/" ,
36+ ) -> "PermissionManager" :
37+ if num_threads is None :
38+ num_threads = os .cpu_count () * 2
39+ generic_acl_listing = [
40+ generic .listing_wrapper (ws .clusters .list , "cluster_id" , "clusters" ),
41+ generic .listing_wrapper (ws .cluster_policies .list , "policy_id" , "cluster-policies" ),
42+ generic .listing_wrapper (ws .instance_pools .list , "instance_pool_id" , "instance-pools" ),
43+ generic .listing_wrapper (ws .warehouses .list , "id" , "sql/warehouses" ),
44+ generic .listing_wrapper (ws .jobs .list , "job_id" , "jobs" ),
45+ generic .listing_wrapper (ws .pipelines .list_pipelines , "pipeline_id" , "pipelines" ),
46+ generic .listing_wrapper (generic .experiments_listing (ws ), "experiment_id" , "experiments" ),
47+ generic .listing_wrapper (generic .models_listing (ws ), "id" , "registered-models" ),
48+ generic .workspace_listing (ws , num_threads = num_threads , start_path = workspace_start_path ),
49+ generic .authorization_listing (),
50+ ]
51+ redash_acl_listing = [
52+ redash .redash_listing_wrapper (ws .alerts .list , sql .ObjectTypePlural .ALERTS ),
53+ redash .redash_listing_wrapper (ws .dashboards .list , sql .ObjectTypePlural .DASHBOARDS ),
54+ redash .redash_listing_wrapper (ws .queries .list , sql .ObjectTypePlural .QUERIES ),
55+ ]
56+ generic_support = generic .GenericPermissionsSupport (ws , generic_acl_listing )
57+ sql_support = redash .SqlPermissionsSupport (ws , redash_acl_listing )
58+ secrets_support = secrets .SecretScopesSupport (ws )
59+ scim_support = scim .ScimSupport (ws )
60+ return cls (
61+ sql_backend ,
62+ inventory_database ,
63+ [generic_support , sql_support , secrets_support , scim_support ],
64+ cls ._object_type_appliers (generic_support , sql_support , secrets_support , scim_support ),
65+ )
66+
67+ @staticmethod
68+ def _object_type_appliers (generic_support , sql_support , secrets_support , scim_support ):
69+ return {
70+ # SCIM-based API
71+ "entitlements" : scim_support ,
72+ "roles" : scim_support ,
73+ # Generic Permissions API
74+ "authorization" : generic_support ,
75+ "clusters" : generic_support ,
76+ "cluster-policies" : generic_support ,
77+ "instance-pools" : generic_support ,
78+ "sql/warehouses" : generic_support ,
79+ "jobs" : generic_support ,
80+ "pipelines" : generic_support ,
81+ "experiments" : generic_support ,
82+ "registered-models" : generic_support ,
83+ "notebooks" : generic_support ,
84+ "files" : generic_support ,
85+ "directories" : generic_support ,
86+ "repos" : generic_support ,
87+ # Redash equivalent of Generic Permissions API
88+ "alerts" : sql_support ,
89+ "queries" : sql_support ,
90+ "dashboards" : sql_support ,
91+ # Secret Scope ACL API
92+ "secrets" : secrets_support ,
93+ }
94+
2295 def inventorize_permissions (self ):
2396 logger .debug ("Crawling permissions" )
2497 crawler_tasks = list (self ._get_crawler_tasks ())
0 commit comments