1818from databricks .labs .ucx .hive_metastore .data_objects import ExternalLocationCrawler
1919from databricks .labs .ucx .hive_metastore .mounts import Mounts
2020from databricks .labs .ucx .workspace_access .generic import WorkspaceListing
21- from databricks .labs .ucx .workspace_access .groups import (
22- GroupManager ,
23- GroupMigrationState ,
24- )
21+ from databricks .labs .ucx .workspace_access .groups import GroupManager
2522from databricks .labs .ucx .workspace_access .manager import PermissionManager
2623
2724logger = logging .getLogger (__name__ )
@@ -194,10 +191,22 @@ def crawl_permissions(cfg: WorkspaceConfig):
194191 permission_manager .inventorize_permissions ()
195192
196193
194+ @task ("assessment" )
195+ def crawl_groups (cfg : WorkspaceConfig ):
196+ """Scans all groups for the local group migration scope"""
197+ sql_backend = RuntimeBackend ()
198+ ws = WorkspaceClient (config = cfg .to_databricks_config ())
199+ group_manager = GroupManager (
200+ sql_backend , ws , cfg .inventory_database , cfg .include_group_names , cfg .renamed_group_prefix
201+ )
202+ group_manager .snapshot ()
203+
204+
197205@task (
198206 "assessment" ,
199207 depends_on = [
200208 crawl_grants ,
209+ crawl_groups ,
201210 crawl_permissions ,
202211 guess_external_locations ,
203212 assess_jobs ,
@@ -214,55 +223,29 @@ def assessment_report(_: WorkspaceConfig):
214223 dashboard _before_ all tasks have been completed, but then only already completed information is shown."""
215224
216225
217- @task ("002-apply-permissions-to-backup-groups" , depends_on = [crawl_permissions ], job_cluster = "tacl" )
218- def apply_permissions_to_backup_groups (cfg : WorkspaceConfig ):
219- """Second phase of the workspace-local group migration process. It does the following:
220- - Creates a backup of every workspace-local group, adding a prefix that can be set in the configuration
221- - Assigns the full set of permissions of the original group to the backup one
222-
223- It covers local workspace-local permissions for all entities: Legacy Table ACLs, Entitlements,
224- AWS instance profiles, Clusters, Cluster policies, Instance Pools, Databricks SQL warehouses, Delta Live
225- Tables, Jobs, MLflow experiments, MLflow registry, SQL Dashboards & Queries, SQL Alerts, Token and Password usage
226- permissions, Secret Scopes, Notebooks, Directories, Repos, Files.
227-
228- See [interactive tutorial here](https://app.getreprise.com/launch/myM3VNn/)."""
226+ @task ("migrate-groups" , depends_on = [crawl_groups ])
227+ def rename_workspace_local_groups (cfg : WorkspaceConfig ):
228+ """Renames workspace local groups by adding `ucx-renamed-` prefix."""
229+ sql_backend = RuntimeBackend ()
229230 ws = WorkspaceClient (config = cfg .to_databricks_config ())
230- group_manager = GroupManager (ws , cfg .groups )
231- group_manager .prepare_groups_in_environment ()
232- if not group_manager .has_groups ():
233- logger .info ("Skipping group migration as no groups were found." )
234- return
235-
236- backend = RuntimeBackend ()
237- permission_manager = PermissionManager .factory (
238- ws ,
239- backend ,
240- cfg .inventory_database ,
241- num_threads = cfg .num_threads ,
242- workspace_start_path = cfg .workspace_start_path ,
231+ group_manager = GroupManager (
232+ sql_backend , ws , cfg .inventory_database , cfg .include_group_names , cfg .renamed_group_prefix
243233 )
244- permission_manager .apply_group_permissions (group_manager .migration_state , destination = "backup" )
245- group_manager .migration_state .persist_migration_state (backend , cfg .inventory_database )
234+ group_manager .rename_groups ()
246235
247236
248- @task ("003-replace-workspace-local-with-account- groups" , depends_on = [apply_permissions_to_backup_groups ])
249- def replace_workspace_groups_with_account_groups (cfg : WorkspaceConfig ):
250- """Third phase of the workspace-local group migration process. It does the following:
251- - Creates an account-level group with the original name of the workspace-local one"""
237+ @task ("migrate- groups" , depends_on = [rename_workspace_local_groups ])
238+ def reflect_account_groups_on_workspace (cfg : WorkspaceConfig ):
239+ """Adds matching account groups to this workspace."""
240+ sql_backend = RuntimeBackend ()
252241 ws = WorkspaceClient (config = cfg .to_databricks_config ())
253- group_manager = GroupManager (ws , cfg .groups )
254- remote_state = GroupMigrationState ().fetch_migration_state (RuntimeBackend (), cfg .inventory_database )
255- if len (remote_state .groups ) == 0 :
256- logger .info ("Skipping group migration as no groups were found." )
257- return
258- group_manager .replace_workspace_groups_with_account_groups (remote_state )
242+ group_manager = GroupManager (
243+ sql_backend , ws , cfg .inventory_database , cfg .include_group_names , cfg .renamed_group_prefix
244+ )
245+ group_manager .reflect_account_groups_on_workspace ()
259246
260247
261- @task (
262- "004-apply-permissions-to-account-groups" ,
263- depends_on = [replace_workspace_groups_with_account_groups ],
264- job_cluster = "tacl" ,
265- )
248+ @task ("migrate-groups" , depends_on = [reflect_account_groups_on_workspace ], job_cluster = "tacl" )
266249def apply_permissions_to_account_groups (cfg : WorkspaceConfig ):
267250 """Fourth phase of the workspace-local group migration process. It does the following:
268251 - Assigns the full set of permissions of the original group to the account-level one
@@ -273,13 +256,11 @@ def apply_permissions_to_account_groups(cfg: WorkspaceConfig):
273256 permissions, Secret Scopes, Notebooks, Directories, Repos, Files.
274257
275258 See [interactive tutorial here](https://app.getreprise.com/launch/myM3VNn/)."""
276- ws = WorkspaceClient (config = cfg .to_databricks_config ())
277259 backend = RuntimeBackend ()
260+ ws = WorkspaceClient (config = cfg .to_databricks_config ())
261+ group_manager = GroupManager (backend , ws , cfg .inventory_database , cfg .include_group_names , cfg .renamed_group_prefix )
278262
279- remote_state = GroupMigrationState ().fetch_migration_state (backend , cfg .inventory_database )
280- migration_state = GroupManager .prepare_apply_permissions_to_account_groups (
281- ws , remote_state , cfg .groups .backup_group_prefix
282- )
263+ migration_state = group_manager .get_migration_state ()
283264 if len (migration_state .groups ) == 0 :
284265 logger .info ("Skipping group migration as no groups were found." )
285266 return
@@ -291,17 +272,18 @@ def apply_permissions_to_account_groups(cfg: WorkspaceConfig):
291272 num_threads = cfg .num_threads ,
292273 workspace_start_path = cfg .workspace_start_path ,
293274 )
294- permission_manager .apply_group_permissions (migration_state , destination = "account" )
275+ permission_manager .apply_group_permissions (migration_state )
295276
296277
297- @task ("005- remove-workspace-local-backup-groups" , depends_on = [apply_permissions_to_account_groups ])
278+ @task ("remove-workspace-local-backup-groups" , depends_on = [apply_permissions_to_account_groups ])
298279def delete_backup_groups (cfg : WorkspaceConfig ):
299280 """Last step of the group migration process. Removes all workspace-level backup groups, along with their
300281 permissions. Execute this workflow only after you've confirmed that workspace-local migration worked
301282 successfully for all the groups involved."""
283+ backend = RuntimeBackend ()
302284 ws = WorkspaceClient (config = cfg .to_databricks_config ())
303- group_manager = GroupManager (ws , cfg .groups )
304- group_manager .delete_backup_groups ()
285+ group_manager = GroupManager (backend , ws , cfg .inventory_database , cfg . include_group_names , cfg . renamed_group_prefix )
286+ group_manager .delete_original_workspace_groups ()
305287
306288
307289@task ("099-destroy-schema" )
0 commit comments