1- import functools
21import json
32import logging
43import os
5- import re
64import sys
75import time
86import webbrowser
4745from databricks .labs .ucx .runtime import main
4846from databricks .labs .ucx .workspace_access .base import Permissions
4947from databricks .labs .ucx .workspace_access .generic import WorkspaceObjectInfo
50- from databricks .labs .ucx .workspace_access .groups import MigratedGroup
48+ from databricks .labs .ucx .workspace_access .groups import ConfigureGroups , MigratedGroup
5149
5250TAG_STEP = "step"
5351TAG_APP = "App"
@@ -380,77 +378,10 @@ def warehouse_type(_):
380378 )
381379 warehouse_id = new_warehouse .id
382380
383- # Setting up group migration parameters
384- groups_config_args = {}
385-
386- ask_for_group = functools .partial (self ._prompts .question , validate = self ._is_valid_group_str )
387- ask_for_regex = functools .partial (self ._prompts .question , validate = self ._validate_regex )
388- while self ._prompts .confirm (
389- "Do you need to convert the workspace groups to match the account groups' name?"
390- " If the workspace groups' names match the account groups' names select no"
391- " or hit <Enter/Return>."
392- ):
393- logger .info ("Setting up group name translation" )
394- groups_config_args ["convert_group_names" ] = "yes"
395- choices = {
396- "Apply a Prefix" : "prefix" ,
397- "Apply a Suffix" : "suffix" ,
398- "Regex Substitution" : "sub" ,
399- "Regex Matching" : "match" ,
400- "Match By External ID" : "external" ,
401- "Cancel" : "cancel" ,
402- }
403- choice = self ._prompts .choice_from_dict ("Choose how to map the workspace groups:" , choices , sort = False )
404- match choice :
405- case "cancel" :
406- continue
407- case "prefix" :
408- prefix = ask_for_group ("Enter a prefix to add to the workspace group name" )
409- if not prefix :
410- continue
411- groups_config_args ["workspace_group_match_regex" ] = "^"
412- groups_config_args ["workspace_group_replace" ] = prefix
413- case "suffix" :
414- suffix = ask_for_group ("Enter a suffix to add to the workspace group name" )
415- if not suffix :
416- continue
417- groups_config_args ["workspace_group_match_regex" ] = "$"
418- groups_config_args ["workspace_group_replace" ] = suffix
419- case "sub" :
420- match_value = ask_for_regex ("Enter a regular expression for substitution" )
421- if not match_value :
422- continue
423- sub_value = ask_for_group ("Enter the substitution value" )
424- if not sub_value :
425- continue
426- groups_config_args ["workspace_group_match_regex" ] = match_value
427- groups_config_args ["workspace_group_replace" ] = sub_value
428- case "matching" :
429- ws_match_value = ask_for_regex ("Enter a regular expression to match on the workspace group" )
430- if not ws_match_value :
431- continue
432- acct_match_value = ask_for_regex ("Enter a regular expression to match on the account group" )
433- if not acct_match_value :
434- continue
435- groups_config_args ["workspace_group_match_regex" ] = ws_match_value
436- groups_config_args ["account_group_match_regex" ] = acct_match_value
437- case "external" :
438- groups_config_args ["group_match_by_external_id" ] = True
439- break
440-
441- selected_groups = self ._prompts .question (
442- "Comma-separated list of workspace group names to migrate. If not specified, we'll use all "
443- "account-level groups with matching names to workspace-level groups" ,
444- default = "<ALL>" ,
445- )
446- backup_group_prefix = ask_for_group ("Backup prefix" , default = "db-temp-" )
381+ configure_groups = ConfigureGroups (self ._prompts )
382+ configure_groups .run ()
447383 log_level = self ._prompts .question ("Log level" , default = "INFO" ).upper ()
448384 num_threads = int (self ._prompts .question ("Number of threads" , default = "8" , valid_number = True ))
449- groups_config_args ["backup_group_prefix" ] = backup_group_prefix
450- if selected_groups != "<ALL>" :
451- groups_config_args ["selected" ] = [x .strip () for x in selected_groups .split ("," )]
452- else :
453- groups_config_args ["selected" ] = None
454385
455386 # Checking for external HMS
456387 instance_profile = None
@@ -474,12 +405,12 @@ def warehouse_type(_):
474405
475406 self ._config = WorkspaceConfig (
476407 inventory_database = inventory_database ,
477- workspace_group_regex = groups_config_args . get ( " workspace_group_regex" ) ,
478- workspace_group_replace = groups_config_args . get ( " workspace_group_replace" ) ,
479- account_group_regex = groups_config_args . get ( " account_group_regex" ) ,
480- group_match_by_external_id = groups_config_args . get ( " group_match_by_external_id" ) ,
481- include_group_names = groups_config_args [ "selected" ] ,
482- renamed_group_prefix = groups_config_args [ "backup_group_prefix" ] ,
408+ workspace_group_regex = configure_groups . workspace_group_regex ,
409+ workspace_group_replace = configure_groups . workspace_group_replace ,
410+ account_group_regex = configure_groups . account_group_regex ,
411+ group_match_by_external_id = configure_groups . group_match_by_external_id ,
412+ include_group_names = configure_groups . include_group_names ,
413+ renamed_group_prefix = configure_groups . renamed_group_prefix ,
483414 warehouse_id = warehouse_id ,
484415 log_level = log_level ,
485416 num_threads = num_threads ,
@@ -643,15 +574,6 @@ def _create_debug(self, remote_wheel: str):
643574 def notebook_link (self , path : str ) -> str :
644575 return f"{ self ._ws .config .host } /#workspace{ path } "
645576
646- @staticmethod
647- def _validate_regex (regex_input : str ) -> bool :
648- try :
649- re .compile (regex_input )
650- return True
651- except re .error :
652- logger .error (f"{ regex_input } is an invalid regular expression" )
653- return False
654-
655577 def _job_settings (self , step_name : str , remote_wheel : str ):
656578 email_notifications = None
657579 if not self ._current_config .override_clusters and "@" in self ._my_username :
@@ -858,10 +780,6 @@ def _get_ext_hms_conf_from_policy(cluster_policy):
858780 spark_conf_dict [key [11 :]] = cluster_policy [key ]["value" ]
859781 return instance_profile , spark_conf_dict
860782
861- @staticmethod
862- def _is_valid_group_str (group_str : str ):
863- return group_str and not re .search (r"[\s#,+ \\<>;]" , group_str )
864-
865783 def latest_job_status (self ) -> list [dict ]:
866784 latest_status = []
867785 for step , job_id in self ._state .jobs .items ():
0 commit comments